Esempio n. 1
0
    /// <summary>
    /// 初期化
    /// </summary>
    protected virtual void Initialize()
    {
        particleNum = (particleMax / THREAD_NUM_X) * THREAD_NUM_X;
        emitNum     = (emitMax / THREAD_NUM_X) * THREAD_NUM_X;
        //Debug.Log("particleNum " + particleNum + " emitNum " + emitNum + " THREAD_NUM_X " + THREAD_NUM_X);

        particleBuffer       = new ComputeBuffer(particleNum, Marshal.SizeOf(typeof(T)), ComputeBufferType.Default);
        particleActiveBuffer = new ComputeBuffer(particleNum, Marshal.SizeOf(typeof(int)), ComputeBufferType.Append);
        particleActiveBuffer.SetCounterValue(0);
        particlePoolBuffer = new ComputeBuffer(particleNum, Marshal.SizeOf(typeof(int)), ComputeBufferType.Append);
        particlePoolBuffer.SetCounterValue(0);
        particleActiveCountBuffer = new ComputeBuffer(4, Marshal.SizeOf(typeof(int)), ComputeBufferType.IndirectArguments);
        particlePoolCountBuffer   = new ComputeBuffer(4, Marshal.SizeOf(typeof(int)), ComputeBufferType.IndirectArguments);
        particlePoolCountBuffer.SetData(particleCounts);

        initKernel   = cs.FindKernel("Init");
        emitKernel   = cs.FindKernel("Emit");
        updateKernel = cs.FindKernel("Update");

        cspropid_Particles    = ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._Particles);
        cspropid_DeadList     = ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._DeadList);
        cspropid_ActiveList   = ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._ActiveList);
        cspropid_ParticlePool = ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._ParticlePool);
        cspropid_EmitNum      = ShaderDefines.GetIntPropertyID(ShaderDefines.IntID._EmitNum);

        //Debug.Log("initKernel " + initKernel + " emitKernel " + emitKernel + " updateKernel " + updateKernel);

        cs.SetBuffer(initKernel, cspropid_Particles, particleBuffer);
        cs.SetBuffer(initKernel, cspropid_DeadList, particlePoolBuffer);
        cs.Dispatch(initKernel, particleNum / THREAD_NUM_X, 1, 1);

        isInitialized = true;
    }
Esempio n. 2
0
    // パーティクルの発生処理
    public void EmitParticle(Vector3 _position)
    {
        // 使用できるパーティクル数を取得
        ComputeBuffer.CopyCount(m_particlePoolBuffer, m_particlePoolCountsBuffer, 0);
        m_particlePoolCountsBuffer.GetData(m_particleCounts);
        m_particlePoolNum = m_particleCounts[0];

        // エミット数未満ならエミット処理をしない
        if (m_particleCounts[0] < m_numEmitParticles)
        {
            return;
        }

        // 変数を設定
        _computeShader.SetFloat(ShaderDefines.GetFloatPropertyID(ShaderDefines.FloatID._elapsedTime), Time.time);
        _computeShader.SetVector(ShaderDefines.GetVectorPropertyID(ShaderDefines.VectorID._position), _position);
        _computeShader.SetVector(ShaderDefines.GetVectorPropertyID(ShaderDefines.VectorID._range), _range);
        _computeShader.SetVector(ShaderDefines.GetVectorPropertyID(ShaderDefines.VectorID._minVelocity), _minVelocity);
        _computeShader.SetVector(ShaderDefines.GetVectorPropertyID(ShaderDefines.VectorID._maxVelocity), _maxVelocity);
        _computeShader.SetFloat(ShaderDefines.GetFloatPropertyID(ShaderDefines.FloatID._startScale), _startScale);
        _computeShader.SetFloat(ShaderDefines.GetFloatPropertyID(ShaderDefines.FloatID._endScale), _endScale);
        _computeShader.SetVector(ShaderDefines.GetVectorPropertyID(ShaderDefines.VectorID._color), _color);
        _computeShader.SetFloat(ShaderDefines.GetFloatPropertyID(ShaderDefines.FloatID._lifeTime), _lifeTime);

        // バッファを設定
        _computeShader.SetBuffer(m_emitKernel, ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._particlePoolBuffer), m_particlePoolBuffer);
        _computeShader.SetBuffer(m_emitKernel, ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._particlesBuffer), m_particlesBuffer);

        // エミットカーネルを実行
        _computeShader.Dispatch(m_emitKernel, m_numEmitParticles / THREAD_NUM_X, 1, 1);
    }
Esempio n. 3
0
    // 初期化処理
    private void Initialize()
    {
        // パーティクル数をスレッド数の倍数にする
        m_numParticles = Mathf.CeilToInt(_numMaxParticles / (float)THREAD_NUM_X) * THREAD_NUM_X;

        // エミット数をスレッド数の倍数にする
        m_numEmitParticles = Mathf.CeilToInt(_numMaxEmitParticles / (float)THREAD_NUM_X) * THREAD_NUM_X;

        // バッファを生成
        m_particlesBuffer            = new ComputeBuffer(m_numParticles, Marshal.SizeOf(typeof(GPUParticleData)), ComputeBufferType.Default);
        m_activeParticlesBuffer      = new ComputeBuffer(m_numParticles, Marshal.SizeOf(typeof(int)), ComputeBufferType.Append);
        m_particlePoolBuffer         = new ComputeBuffer(m_numParticles, Marshal.SizeOf(typeof(int)), ComputeBufferType.Append);
        m_activeParticleCountsBuffer = new ComputeBuffer(4, Marshal.SizeOf(typeof(int)), ComputeBufferType.IndirectArguments);
        m_particlePoolCountsBuffer   = new ComputeBuffer(4, Marshal.SizeOf(typeof(int)), ComputeBufferType.IndirectArguments);

        // バッファにデータを渡す
        m_activeParticleCountsBuffer.SetData(m_particleCounts);
        m_particlePoolCountsBuffer.SetData(m_particleCounts);

        // カーネルを設定
        m_initKernel   = _computeShader.FindKernel("Init");
        m_emitKernel   = _computeShader.FindKernel("Emit");
        m_updateKernel = _computeShader.FindKernel("Update");

        // 変数を設定
        _computeShader.SetFloat(ShaderDefines.GetFloatPropertyID(ShaderDefines.FloatID._gravity), _gravity);

        // バッファを設定
        _computeShader.SetBuffer(m_initKernel, ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._particlesBuffer), m_particlesBuffer);
        _computeShader.SetBuffer(m_initKernel, ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._deadParticlesBuffer), m_particlePoolBuffer);

        // 初期化カーネルを実行
        _computeShader.Dispatch(m_initKernel, m_numParticles / THREAD_NUM_X, 1, 1);
    }
Esempio n. 4
0
    // public関数
    #region public method
    public void PutFootsteps(Vector3 _position)
    {
        // バッファを設定
        _computeShader.SetBuffer(m_putKernel, ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._verticesBuffer), m_verticesBuffer);

        // 変数を設定
        _computeShader.SetVector(ShaderDefines.GetVectorPropertyID(ShaderDefines.VectorID._playerPosition), new Vector2(_position.x, _position.z));

        // カーネルの実行
        _computeShader.Dispatch(m_putKernel, m_numThreadGroups * m_numThreadGroups, 1, 1);
    }
Esempio n. 5
0
    // シェーダーの値の設定
    private void SetMaterialParam()
    {
        // テクスチャを設定
        _shaderMaterial.SetTexture(ShaderDefines.GetTexturePropertyID(ShaderDefines.TextureID._mainTexture), _texture);

        // バッファを設定
        _shaderMaterial.SetBuffer(ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._meshIndicesBuffer), m_meshIndicesBuffer);
        _shaderMaterial.SetBuffer(ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._meshVertexDatasBuffer), m_meshVertexDatasBuffer);
        _shaderMaterial.SetBuffer(ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._particlesBuffer), m_particlesBuffer);

        // パスを設定
        _shaderMaterial.SetPass(0);
    }
Esempio n. 6
0
    // 描画処理
    private void OnRenderObjectInternal()
    {
        // カリングを行うか判定
        if (_isCulling)
        {
            // カメラを取得
            Camera cam = Camera.current;

            // カメラが存在するか判定
            if (!m_cameraDatas.ContainsKey(cam))
            {
                // このフレームは登録だけ
                m_cameraDatas[cam] = null;
            }
            else
            {
                // カメラのカリングデータを取得
                CullingData data = m_cameraDatas[cam];

                // カリングデータが存在するか判定
                if (data != null)
                {
                    // シェーダーの値の設定
                    SetMaterialParam();

                    // バッファを設定
                    _shaderMaterial.SetBuffer(ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._inViewParticlesBuffer), data.GetInViewParticlesBuffer());

                    // キーワードを有効化
                    _shaderMaterial.EnableKeyword("GPUPARTICLE_CULLING_ON");

                    // 描画処理
                    Graphics.DrawProceduralIndirect(MeshTopology.Triangles, data.GetInViewCountsBuffer());
                }
            }
        }
        else
        {
            // シェーダーの値の設定
            SetMaterialParam();

            // バッファを設定
            _shaderMaterial.SetBuffer(ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._activeParticlesBuffer), m_activeParticlesBuffer);

            // キーワードを無効化
            _shaderMaterial.DisableKeyword("GPUPARTICLE_CULLING_ON");

            // 描画処理
            Graphics.DrawProceduralIndirect(MeshTopology.Triangles, m_activeCountBuffer);
        }
    }
Esempio n. 7
0
    // 地形描画
    void RenderTerrain()
    {
        // テクスチャを設定
        _shaderMaterial.SetTexture(ShaderDefines.GetTexturePropertyID(ShaderDefines.TextureID._mainTexture), _texture);

        // 変数を設定
        _shaderMaterial.SetInt(ShaderDefines.GetIntPropertyID(ShaderDefines.IntID._numVertices), _numVertices);
        _shaderMaterial.SetFloat(ShaderDefines.GetFloatPropertyID(ShaderDefines.FloatID._height), _height);

        // バッファの設定
        _shaderMaterial.SetBuffer(ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._verticesBuffer), m_verticesBuffer);

        // 描画処理
        Graphics.DrawMeshInstancedIndirect(_mesh, 0, _shaderMaterial, new Bounds(Vector3.zero, new Vector3(1000.0f, 1000.0f, 1000.0f)), m_argsBuffer);
    }
Esempio n. 8
0
    // 頂点の計算
    void CalculateVertex()
    {
        // バッファを設定
        _computeShader.SetBuffer(m_calculateKernel, ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._verticesBuffer), m_verticesBuffer);

        // 変数を設定
        _computeShader.SetFloat(ShaderDefines.GetFloatPropertyID(ShaderDefines.FloatID._fieldSize), FIELD_SIZE);
        _computeShader.SetInt(ShaderDefines.GetIntPropertyID(ShaderDefines.IntID._numVertices), _numVertices);
        _computeShader.SetFloat(ShaderDefines.GetFloatPropertyID(ShaderDefines.FloatID._distance), m_distance);
        _computeShader.SetFloat(ShaderDefines.GetFloatPropertyID(ShaderDefines.FloatID._height), _height);
        _computeShader.SetFloat(ShaderDefines.GetFloatPropertyID(ShaderDefines.FloatID._smoothness), _smoothness * _numVertices);
        _computeShader.SetVector(ShaderDefines.GetVectorPropertyID(ShaderDefines.VectorID._offset), new Vector2(_offsetX, _offsetY));

        // カーネルの実行
        _computeShader.Dispatch(m_calculateKernel, m_numThreadGroups, 1, m_numThreadGroups);
    }
Esempio n. 9
0
    // パーティクルの更新処理
    private void UpdateParticle()
    {
        // バッファのカウンターをリセット
        m_activeParticlesBuffer.SetCounterValue(0);

        // 変数を設定
        _computeShader.SetFloat(ShaderDefines.GetFloatPropertyID(ShaderDefines.FloatID._deltaTime), Time.deltaTime);

        // バッファを設定
        _computeShader.SetBuffer(m_updateKernel, ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._particlesBuffer), m_particlesBuffer);
        _computeShader.SetBuffer(m_updateKernel, ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._deadParticlesBuffer), m_particlePoolBuffer);
        _computeShader.SetBuffer(m_updateKernel, ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._activeParticlesBuffer), m_activeParticlesBuffer);

        // 更新カーネルを実行
        _computeShader.Dispatch(m_updateKernel, m_numParticles / THREAD_NUM_X, 1, 1);

        // 使用中のパーティクル数を取得
        ComputeBuffer.CopyCount(m_activeParticlesBuffer, m_activeParticleCountsBuffer, 0);
    }
Esempio n. 10
0
        // 更新処理
        public void Update(ComputeShader _computeShader, Camera _camera, int _numParticles, ComputeBuffer _particlesBuffer, ComputeBuffer _activeParticlesBuffer)
        {
            // 視錘台カリングを行うカーネル
            int kernel = _computeShader.FindKernel("FrustumCulling");

            // 視錘台の計算
            CalculateFrustumPlanes(_camera.projectionMatrix * _camera.worldToCameraMatrix, ref m_planes);

            // 視錘台の法線を分解
            for (int i = 0; i < 4; i++)
            {
                Debug.DrawRay(_camera.transform.position, m_planes[i].normal * 10f, Color.yellow);
                m_normalsFloat[i + 0] = m_planes[i].normal.x;
                m_normalsFloat[i + 4] = m_planes[i].normal.y;
                m_normalsFloat[i + 8] = m_planes[i].normal.z;
            }

            // バッファのカウンターをリセット
            m_inViewParticlesBuffer.SetCounterValue(0);

            // カメラの座標
            Vector3 cameraPosition = _camera.transform.position;

            // 変数を設定
            _computeShader.SetInt(ShaderDefines.GetIntPropertyID(ShaderDefines.IntID._numParticles), _numParticles);
            _computeShader.SetFloats(ShaderDefines.GetVectorPropertyID(ShaderDefines.VectorID._cameraPosition), cameraPosition.x, cameraPosition.y, cameraPosition.z);
            _computeShader.SetFloats(ShaderDefines.GetVectorPropertyID(ShaderDefines.VectorID._cameraFrustumNormals), m_normalsFloat);

            // バッファを設定
            _computeShader.SetBuffer(kernel, ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._particlesBuffer), _particlesBuffer);
            _computeShader.SetBuffer(kernel, ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._activeParticlesBuffer), _activeParticlesBuffer);
            _computeShader.SetBuffer(kernel, ShaderDefines.GetBufferPropertyID(ShaderDefines.BufferID._inViewParticlesBuffer), m_inViewParticlesBuffer);

            // カーネルを実行
            _computeShader.Dispatch(kernel, Mathf.CeilToInt((float)_activeParticlesBuffer.count / NUM_THREAD_X), 1, 1);

            // バッファにデータを渡す
            m_inViewCountsBuffer.SetData(m_inViewCounts);

            // 視界内のパーティクル数を取得
            ComputeBuffer.CopyCount(m_inViewParticlesBuffer, m_inViewCountsBuffer, 4);
        }