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(); }