Example #1
0
        public static void ConvertParticleToBender(MenuCommand cmd)
        {
            ParticleSystem ps = (ParticleSystem)cmd.context;

            if (!ps.gameObject.GetComponent <GrassBender>())
            {
                GrassBender bender = ps.gameObject.AddComponent <GrassBender>();

                bender.benderType     = GrassBenderBase.BenderType.ParticleSystem;
                bender.particleSystem = ps.GetComponent <ParticleSystem>();

                GrassBenderBase.ValidateParticleSystem(bender);
            }
        }
            // Here you can implement the rendering logic.
            // Use <c>ScriptableRenderContext</c> to issue drawing commands or execute command buffers
            // https://docs.unity3d.com/ScriptReference/Rendering.ScriptableRenderContext.html
            // You don't have to call ScriptableRenderContext.submit, the render pipeline will call it at specific points in the pipeline.
            public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
            {
                var cmd = CommandBufferPool.Get(profilerSampler.name);

                renderBounds   = StylizedGrassRenderer.Instance.bounds;
                frustrumPlanes = GeometryUtility.CalculateFrustumPlanes(StylizedGrassRenderer.Instance.renderCam);

                using (new ProfilingScope(cmd, profilerSampler))
                {
                    foreach (KeyValuePair <int, List <GrassBender> > layer in StylizedGrassRenderer.GrassBenders)
                    {
                        foreach (GrassBender b in layer.Value)
                        {
                            if (b.enabled == false)
                            {
                                continue;
                            }

                            props.SetVector("_Params", new Vector4(b.strength, b.heightOffset, b.pushStrength, b.scaleMultiplier));

                            if (b.benderType == GrassBenderBase.BenderType.Trail)
                            {
                                if (!b.trailRenderer)
                                {
                                    continue;
                                }

                                if (!b.trailRenderer.emitting)
                                {
                                    continue;
                                }

                                if (!GeometryUtility.TestPlanesAABB(frustrumPlanes, b.trailRenderer.bounds))
                                {
                                    continue;
                                }

                                m_TrailRenderer = b.trailRenderer;
                                m_TrailRenderer.SetPropertyBlock(props);

                                //Trail
                                m_TrailRenderer.emitting             = b.gameObject.activeInHierarchy;
                                m_TrailRenderer.generateLightingData = true;
                                m_TrailRenderer.widthMultiplier      = b.trailRadius;
                                m_TrailRenderer.time = b.trailLifetime;
                                m_TrailRenderer.minVertexDistance = b.trailAccuracy;
                                m_TrailRenderer.widthCurve        = b.widthOverLifetime;
                                m_TrailRenderer.colorGradient     = GrassBenderBase.GetGradient(b.strengthOverLifetime);

                                //If disabled, temporarly enable in order to bake mesh
                                trailEnabled = m_TrailRenderer.enabled ? true : false;
                                if (!trailEnabled)
                                {
                                    m_TrailRenderer.enabled = true;
                                }

                                if (b.bakedMesh == null)
                                {
                                    b.bakedMesh = new Mesh();
                                }
                                m_TrailRenderer.BakeMesh(b.bakedMesh, renderingData.cameraData.camera, false);

                                cmd.DrawMesh(b.bakedMesh, Matrix4x4.identity, GrassBenderBase.TrailMaterial, 0, 0, props);

                                //Note: Faster, but crashed when trails are disabled (Case 1200430)
                                //cmd.DrawRenderer(m_TrailRenderer, GrassBenderBase.TrailMaterial, 0, 0);

                                if (!trailEnabled)
                                {
                                    m_TrailRenderer.enabled = false;
                                }

                                //trailMesh.Clear();
                            }
                            if (b.benderType == GrassBenderBase.BenderType.ParticleSystem)
                            {
                                if (!b.particleSystem)
                                {
                                    continue;
                                }

                                if (!GeometryUtility.TestPlanesAABB(frustrumPlanes, b.particleRenderer.bounds))
                                {
                                    continue;
                                }

                                m_ParticleRenderer = b.particleRenderer;
                                m_ParticleRenderer.SetPropertyBlock(props);

                                var grad = b.particleSystem.colorOverLifetime;
                                grad.enabled = true;
                                grad.color   = GrassBenderBase.GetGradient(b.strengthOverLifetime);
                                bool localSpace = b.particleSystem.main.simulationSpace == ParticleSystemSimulationSpace.Local;

                                //Note: DrawRenderes with particle systems appear to be broken. Only renders to scene cam when it redraws. Bake the mesh down and render it instead.
                                //Todo: Create repo project and file bug report.
                                //cmd.DrawRenderer(m_ParticleRenderer, m_Material, 0, 0);
                                if (!b.bakedMesh)
                                {
                                    b.bakedMesh = new Mesh();
                                }
                                m_ParticleRenderer.BakeMesh(b.bakedMesh, renderingData.cameraData.camera);

                                cmd.DrawMesh(b.bakedMesh, localSpace ? m_ParticleRenderer.localToWorldMatrix : Matrix4x4.identity, GrassBenderBase.MeshMaterial, 0, b.alphaBlending ? 1 : 0, props);

                                //Also draw particle trails
                                if (b.hasParticleTrails)
                                {
                                    if (!b.particleTrailMesh)
                                    {
                                        b.particleTrailMesh = new Mesh();
                                    }

                                    m_ParticleRenderer.BakeTrailsMesh(b.particleTrailMesh, renderingData.cameraData.camera);
                                    cmd.DrawMesh(b.particleTrailMesh, m_ParticleRenderer.localToWorldMatrix, GrassBenderBase.TrailMaterial, 1, 0, props);
                                    //cmd.DrawRenderer(m_ParticleRenderer, GrassBenderBase.TrailMaterial, 1, 0);
                                }
                            }
                            if (b.benderType == GrassBenderBase.BenderType.Mesh)
                            {
                                if (!b.meshRenderer)
                                {
                                    continue;
                                }

                                if (!GeometryUtility.TestPlanesAABB(frustrumPlanes, b.meshRenderer.bounds))
                                {
                                    continue;
                                }

                                m_MeshRenderer = b.meshRenderer;
                                m_MeshRenderer.SetPropertyBlock(props);

                                cmd.DrawRenderer(m_MeshRenderer, GrassBenderBase.MeshMaterial, 0, b.alphaBlending ? 1 : 0);
                            }
                        }
                    }

                    //Mask edges of bend area, avoids streaking at edges
                    if (enableEdgeMasking)
                    {
                        cmd.SetGlobalTexture("_BendMapInput", BuiltinRenderTextureType.CurrentActive);
                        cmd.Blit(BuiltinRenderTextureType.CurrentActive, bendVectorID, m_MaskMat);
                        cmd.SetGlobalTexture(StylizedGrassRenderer.VECTOR_MAP_PARAM, bendVectorID);
                    }
                }
                context.ExecuteCommandBuffer(cmd);
                CommandBufferPool.Release(cmd);
            }
        public override void OnInspectorGUI()
        {
            if (StylizedGrassRenderer.Instance == null)
            {
                EditorGUILayout.HelpBox("No Stylized Grass Renderer is active in the scene", MessageType.Warning);
            }

            serializedObject.Update();

            EditorGUI.BeginChangeCheck();

            EditorGUILayout.PropertyField(benderType);

            if (benderType.intValue == (int)GrassBenderBase.BenderType.Mesh)
            {
                using (new EditorGUILayout.HorizontalScope())
                {
                    EditorGUILayout.PropertyField(meshRenderer);

                    using (new EditorGUI.DisabledGroupScope(bender.meshRenderer ? bender.meshRenderer.gameObject == bender.gameObject : false))
                    {
                        if (GUILayout.Button("This", EditorStyles.miniButton, GUILayout.MaxWidth(75f)))
                        {
                            MeshRenderer meshRend = bender.GetComponent <MeshRenderer>();
                            if (meshRend)
                            {
                                meshRenderer.objectReferenceValue = meshRend;
                            }
                            MeshFilter mf = bender.GetComponent <MeshFilter>();
                            if (mf)
                            {
                                bender.meshFilter = mf;
                            }
                        }
                    }
                }

                EditorGUILayout.Space();

                StylizedGrassGUI.ParameterGroup.DrawHeader(new GUIContent("Mesh"));
                using (new EditorGUILayout.VerticalScope(StylizedGrassGUI.ParameterGroup.Section))
                {
                    EditorGUILayout.PropertyField(alphaBlending);
                    EditorGUILayout.PropertyField(scaleMultiplier);
                }
            }

            if (benderType.intValue == (int)GrassBenderBase.BenderType.Trail)
            {
                using (new EditorGUILayout.HorizontalScope())
                {
                    EditorGUILayout.PropertyField(trailRenderer);

                    using (new EditorGUI.DisabledGroupScope(bender.trailRenderer ? bender.trailRenderer.gameObject == bender.gameObject : false))
                    {
                        if (GUILayout.Button("This", EditorStyles.miniButton, GUILayout.MaxWidth(75f)))
                        {
                            TrailRenderer trailRend = bender.GetComponent <TrailRenderer>();
                            if (trailRend)
                            {
                                trailRenderer.objectReferenceValue = trailRend;
                            }
                        }
                    }
                }

                EditorGUILayout.Space();

                StylizedGrassGUI.ParameterGroup.DrawHeader(new GUIContent("Trail"));
                using (new EditorGUILayout.VerticalScope(StylizedGrassGUI.ParameterGroup.Section))
                {
                    EditorGUILayout.PropertyField(trailLifetime);
                    EditorGUILayout.PropertyField(trailRadius);

                    EditorGUI.BeginChangeCheck();
                    EditorGUILayout.PropertyField(strengthOverLifetime);
                    if (EditorGUI.EndChangeCheck())
                    {
                        bender.strengthGradient = GrassBenderBase.GetGradient(bender.strengthOverLifetime);
                    }
                    EditorGUILayout.PropertyField(widthOverLifetime);
                }
            }

            if (benderType.intValue == (int)GrassBenderBase.BenderType.ParticleSystem)
            {
                GrassBenderBase.ValidateParticleSystem(bender);

                using (new EditorGUILayout.HorizontalScope())
                {
                    EditorGUILayout.PropertyField(particleSystem);

                    using (new EditorGUI.DisabledGroupScope(bender.particleSystem ? bender.particleSystem.gameObject == bender.gameObject : false))
                    {
                        if (GUILayout.Button("This", EditorStyles.miniButton, GUILayout.MaxWidth(75f)))
                        {
                            ParticleSystem ps = bender.GetComponent <ParticleSystem>();
                            if (ps)
                            {
                                particleSystem.objectReferenceValue = ps;
                            }
                        }
                    }
                }

                EditorGUILayout.Space();

                StylizedGrassGUI.ParameterGroup.DrawHeader(new GUIContent("Particle System"));
                using (new EditorGUILayout.VerticalScope(StylizedGrassGUI.ParameterGroup.Section))
                {
                    EditorGUILayout.PropertyField(alphaBlending);
                    EditorGUI.BeginChangeCheck();
                    EditorGUILayout.PropertyField(strengthOverLifetime);
                    if (EditorGUI.EndChangeCheck())
                    {
                        bender.strengthGradient = GrassBenderBase.GetGradient(bender.strengthOverLifetime);
                    }
                }
            }

            EditorGUILayout.Space();

            StylizedGrassGUI.ParameterGroup.DrawHeader(new GUIContent("Settings"));
            using (new EditorGUILayout.VerticalScope(StylizedGrassGUI.ParameterGroup.Section))
            {
                using (new EditorGUILayout.HorizontalScope())
                {
                    EditorGUILayout.PrefixLabel(new GUIContent("Sorting layer", "Higher sorting layers are drawn on top of lower layers. Use this to control which benders draw over others"));
                    EditorGUI.BeginChangeCheck();
                    m_layer = GUILayout.Toolbar(m_layer, new string[] { "0", "1", "2", "3" }, GUILayout.Height(20f));
                    if (EditorGUI.EndChangeCheck())
                    {
                        bender.SwitchLayer(m_layer);
                    }
                    m_layer = bender.sortingLayer;
                }
                EditorGUILayout.PropertyField(heightOffset);
                EditorGUILayout.PropertyField(strength);
                EditorGUILayout.PropertyField(pushStrength);
            }

            if (EditorGUI.EndChangeCheck())
            {
                if (benderType.intValue != m_benderType)
                {
                    bender.SwitchBenderType((GrassBenderBase.BenderType)benderType.intValue);
                }
                m_benderType = benderType.intValue;

                //bender.UpdateTrail();
                //bender.UpdateMesh();

                serializedObject.ApplyModifiedProperties();
            }

            //base.OnInspectorGUI();
        }