예제 #1
0
        internal void Update()
        {
            if (!SystemComp.enabled || SystemComp.ParticleCount == 0)
            {
                return;
            }

            //TODO: How to cache more of this?
            m_cacheMaterial.CopyPropertiesFromMaterial(_material);

            switch (RenderMode)
            {
            case GeometryRenderMode.Billboard:
                m_cacheMaterial.EnableKeyword("TC_BILLBOARD");
                m_cacheMaterial.DisableKeyword("TC_BILLBOARD_STRETCHED");
                m_cacheMaterial.DisableKeyword("TC_MESH");
                break;

            case GeometryRenderMode.StretchedBillboard:
            case GeometryRenderMode.TailStretchBillboard:
                m_cacheMaterial.DisableKeyword("TC_BILLBOARD");
                m_cacheMaterial.EnableKeyword("TC_BILLBOARD_STRETCHED");
                m_cacheMaterial.DisableKeyword("TC_MESH");
                break;

            case GeometryRenderMode.Mesh:
                m_cacheMaterial.DisableKeyword("TC_BILLBOARD");
                m_cacheMaterial.DisableKeyword("TC_BILLBOARD_STRETCHED");
                m_cacheMaterial.EnableKeyword("TC_MESH");
                break;
            }

            //enable sprite uv animation keyword
            if (spriteSheetAnimation)
            {
                m_cacheMaterial.EnableKeyword("TC_UV_SPRITE_ANIM");
                m_cacheMaterial.DisableKeyword("TC_UV_NORMAL");
            }
            else
            {
                m_cacheMaterial.EnableKeyword("TC_UV_NORMAL");
                m_cacheMaterial.DisableKeyword("TC_UV_SPRITE_ANIM");
            }

            Color tint = TintColor;

            if (tint != curTintColor)
            {
                curTintColor = tint;
                UpdateColourOverLifetime();
            }

            m_cacheMaterial.SetBuffer("particlesRead", Manager.GetParticlesBuffer());
            m_cacheMaterial.SetTexture(SID._ColTex, colourOverLifetimeTexture);

            if (Emitter.DoSizeOverLifetime)
            {
                m_cacheMaterial.SetTexture(SID._LifetimeTexture, Emitter.SizeOverLifetimeTexture);
            }

            UpdateTailUv();

            //Update render state
            if (m_prevRenderMode != RenderMode)
            {
                BuildBuffer();
                m_prevRenderMode = RenderMode;
            }
            else if (RenderMode == GeometryRenderMode.Mesh && Mesh != m_prevRenderModeMesh)
            {
                m_prevRenderModeMesh = Mesh;
                BuildBuffer();
            }

            Matrix4x4 m;
            Transform systTransform = SystemComp.transform;

            switch (Manager.SimulationSpace)
            {
            case Space.Local:
                m = Matrix4x4.TRS(systTransform.position, systTransform.rotation, Vector3.one);
                break;

            case Space.Parent:
                m = Matrix4x4.TRS(ParentPosition, systTransform.parent.rotation, Vector3.one);
                break;

            case Space.LocalWithScale:
                m = Matrix4x4.TRS(systTransform.position, systTransform.rotation, systTransform.localScale);
                break;

            default:
                m = Matrix4x4.identity;
                break;
            }

            m_cacheMaterial.SetMatrix(SID._MatrixM, m);

            //TODO: Combine into one vector
            m_cacheMaterial.SetFloat(SID._MaxSpeed, 1.0f / maxSpeed);

            bool hasColourOverLife = colourGradientMode == ParticleColourGradientMode.OverLifetime;

            m_cacheMaterial.SetFloat(SID._ColourSpeed, hasColourOverLife ? 0 : 1);

            //TODO: Combine into float?
            float gl = glow + 1.0f;

            m_cacheMaterial.SetVector(SID._Glow, new Vector4(gl, gl, gl, 1.0f));

            if (spriteSheetAnimation)
            {
                m_cacheMaterial.SetVector("_SpriteAnimSize", new Vector4(spriteSheetColumns, spriteSheetRows, 1.0f / spriteSheetColumns, 1.0f / spriteSheetRows));
                m_cacheMaterial.SetFloat("_Cycles", spriteSheetCycles);
            }

            m_cacheMaterial.SetVector("_LifeMinMax", new Vector4(Emitter.Energy.Min, Emitter.Energy.Max));

            switch (RenderMode)
            {
            case GeometryRenderMode.Billboard:
            case GeometryRenderMode.StretchedBillboard:
                //TODO: Combine into vector
                m_cacheMaterial.SetFloat(SID._SpeedScale, SpeedScale);
                m_cacheMaterial.SetFloat(SID._LengthScale, LengthScale - 1.0f);
                m_particleMesh = TCParticleGlobalManager.GlobalQuad;
                break;

            case GeometryRenderMode.TailStretchBillboard:
                m_cacheMaterial.SetFloat(SID._SpeedScale, SpeedScale);
                m_cacheMaterial.SetFloat(SID._LengthScale, LengthScale - 1.0f);
                m_particleMesh = m_tailStretchMesh;
                break;

            case GeometryRenderMode.Mesh:
                m_particleMesh = _mesh;
                break;
            }

            m_cacheMaterial.SetFloat(SID._BufferOffset, Emitter.Offset);
            m_cacheMaterial.SetFloat(SID._MaxParticles, Manager.MaxParticles);

            //TODO: How to do submeshes?
            m_argsData[0] = m_particleMesh.GetIndexCount(0);
            m_argsData[1] = (uint)SystemComp.ParticleCount;
            m_argsData[2] = 0;
            m_argsData[3] = 0;
            m_argsData[4] = 0;
            m_argsBuffer.SetData(m_argsData);

            //Reset flag for next frame
            isVisible = false;
        }
예제 #2
0
        public void FillCommandBuffer(CommandBuffer cmd)
        {
            if (!ShouldRender())
            {
                return;
            }

            InitProperties();

            m_cacheMaterial.CopyPropertiesFromMaterial(_material);

            bool hasColourOverLife = colourGradientMode == ParticleColourGradientMode.OverLifetime;

            switch (RenderMode)
            {
            case GeometryRenderMode.Billboard:
                s_keywords[0] = "TC_BILLBOARD";
                break;

            case GeometryRenderMode.StretchedBillboard:
            case GeometryRenderMode.TailStretchBillboard:
                s_keywords[0] = "TC_BILLBOARD_STRETCHED";
                break;

            case GeometryRenderMode.Mesh:
                s_keywords[0] = "TC_MESH";

                break;
            }

            s_keywords[1] = spriteSheetAnimation ? "TC_UV_SPRITE_ANIM" : "TC_UV_NORMAL";
            m_cacheMaterial.shaderKeywords = s_keywords;

            if (TintColor != curTintColor)
            {
                curTintColor = TintColor;
                UpdateColourOverLifetime();
            }

            m_cacheMaterial.SetBuffer("particlesRead", Manager.particles);
            m_cacheMaterial.SetTexture(s_colTex, colourOverLifetimeTexture);

            if (PartEmitter.DoSizeOverLifetime)
            {
                m_cacheMaterial.SetTexture(s_lifetimeTex, PartEmitter.SizeOverLifetimeTexture);
            }

            UpdateTailUv();

            //Update render state
            if (m_prevRenderMode != RenderMode)
            {
                BuildBuffer();
                m_prevRenderMode = RenderMode;
            }
            else if (RenderMode == GeometryRenderMode.Mesh && (Mesh != m_prevMesh || _material.shader != m_prevShader))
            {
                m_prevMesh   = Mesh;
                m_prevShader = _material.shader;
                BuildBuffer();
            }

            Matrix4x4 m;

            switch (Manager.SimulationSpace)
            {
            case Space.Local:
                m = Matrix4x4.TRS(Transform.position, Transform.rotation, Vector3.one);
                break;

            case Space.Parent:
                m = Matrix4x4.TRS(ParentPosition, Transform.parent.rotation, Vector3.one);
                break;

            case Space.LocalWithScale:
                m = Matrix4x4.TRS(Transform.position, Transform.rotation, Transform.localScale);
                break;

            default:
                m = Matrix4x4.identity;
                break;
            }

            Matrix4x4 v = Camera.current.worldToCameraMatrix;

            m_cacheMaterial.SetMatrix(s_matrixM, m);
            m_cacheMaterial.SetMatrix(s_matrixV, v);


            m_cacheMaterial.SetFloat(s_maxSpeed, 1.0f / maxSpeed);
            m_cacheMaterial.SetFloat(s_colourSpeed, hasColourOverLife ? 0 : 1);

            float gl = glow + 1.0f;

            m_cacheMaterial.SetVector(s_glow, new Vector4(gl, gl, gl, 1.0f));

            ComputeBuffer setPointsBuffer = null;

            switch (RenderMode)
            {
            case GeometryRenderMode.Point:
            case GeometryRenderMode.Billboard:
            case GeometryRenderMode.StretchedBillboard:
                setPointsBuffer = m_bufferPoints;
                break;

            case GeometryRenderMode.TailStretchBillboard:
                setPointsBuffer = m_bufferPointsTail;
                break;

            case GeometryRenderMode.Mesh:
                setPointsBuffer = m_meshPointsBuffer;
                break;
            }

            m_cacheMaterial.SetBuffer("bufPoints", setPointsBuffer);

            if (RenderMode == GeometryRenderMode.Mesh)
            {
                if (m_useNormals)
                {
                    m_cacheMaterial.SetBuffer("bufNormals", m_normalsBuffer);
                }
            }

            if (isPixelSize)
            {
                var pixelMult = Mathf.Max(1.0f / Screen.width, 1.0f / Screen.height);
                if (Camera.current.orthographic)
                {
                    pixelMult *= Camera.current.orthographicSize * 2.0f;
                }

                m_cacheMaterial.SetVector(s_pixelMult, new Vector4(pixelMult, Camera.current.orthographic ? 0.0f : 1.0f));
            }
            else
            {
                m_cacheMaterial.SetVector(s_pixelMult, new Vector4(1.0f, 0.0f));
            }

            if (spriteSheetAnimation)
            {
                m_cacheMaterial.SetVector("_SpriteAnimSize",
                                          new Vector4(spriteSheetColumns, spriteSheetRows, 1.0f / spriteSheetColumns, 1.0f / spriteSheetRows));
                m_cacheMaterial.SetFloat("_Cycles", spriteSheetCycles);
            }

            m_cacheMaterial.SetVector("_LifeMinMax", new Vector4(PartEmitter.Energy.Min, PartEmitter.Energy.Max));

            switch (RenderMode)
            {
            case GeometryRenderMode.StretchedBillboard:
                m_cacheMaterial.SetBuffer("stretchBuffer", m_stretchBuffer);
                m_cacheMaterial.SetFloat(s_speedScale, SpeedScale);
                m_cacheMaterial.SetFloat(s_lengthScale, LengthScale - 1.0f);
                m_cacheMaterial.SetFloat(s_billboardFlip, 1.0f);
                break;

            case GeometryRenderMode.TailStretchBillboard:
                m_cacheMaterial.SetBuffer("stretchBuffer", m_stretchBufferTail);
                m_cacheMaterial.SetFloat(s_speedScale, SpeedScale);
                m_cacheMaterial.SetFloat(s_lengthScale, LengthScale - 1.0f);
                m_cacheMaterial.SetFloat(s_billboardFlip, -1.0f);
                break;


            case GeometryRenderMode.Mesh:
                m_cacheMaterial.SetBuffer("uvs", m_uvsBuffer);
                break;
            }


            m_cacheMaterial.SetInt(s_bufferOffset, Manager.Offset);
            m_cacheMaterial.SetInt(s_maxParticles, Manager.MaxParticles);

            for (int i = 0; i < m_cacheMaterial.passCount; ++i)
            {
                RenderPass(i, cmd);
            }
        }