GrassDisplacementRenderFeature.cs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. // vr: https://forum.unity.com/threads/released-lux-urp-essentials.712619/page-17#post-6474737
  2. using UnityEngine;
  3. using UnityEngine.Experimental.Rendering;
  4. using UnityEngine.Rendering;
  5. namespace Lux_SRP_GrassDisplacement
  6. {
  7. public class GrassDisplacementRenderFeature : UnityEngine.Rendering.Universal.ScriptableRendererFeature
  8. {
  9. [System.Serializable]
  10. public enum RTDisplacementSize {
  11. _128 = 128,
  12. _256 = 256,
  13. _512 = 512,
  14. _1024 = 1024
  15. }
  16. [System.Serializable]
  17. public class GrassDisplacementSettings
  18. {
  19. public RTDisplacementSize Resolution = RTDisplacementSize._256;
  20. public float Size = 20.0f;
  21. public bool ShiftRenderTex = false;
  22. //public bool SinglePassInstancing = false;
  23. }
  24. public GrassDisplacementSettings settings = new GrassDisplacementSettings();
  25. GrassDisplacementPass m_GrassDisplacementPass;
  26. public override void Create()
  27. {
  28. m_GrassDisplacementPass = new GrassDisplacementPass();
  29. m_GrassDisplacementPass.renderPassEvent = UnityEngine.Rendering.Universal.RenderPassEvent.BeforeRenderingShadows;
  30. // Apply settings
  31. m_GrassDisplacementPass.m_Resolution = (int)settings.Resolution;
  32. m_GrassDisplacementPass.m_Size = settings.Size;
  33. m_GrassDisplacementPass.m_ShiftRenderTex = settings.ShiftRenderTex;
  34. //m_GrassDisplacementPass.m_SinglePassInstancing = settings.SinglePassInstancing;
  35. }
  36. public override void AddRenderPasses(UnityEngine.Rendering.Universal.ScriptableRenderer renderer, ref UnityEngine.Rendering.Universal.RenderingData renderingData)
  37. {
  38. renderer.EnqueuePass(m_GrassDisplacementPass);
  39. }
  40. }
  41. // ---------------------------------------------------------
  42. // The Pass
  43. public class GrassDisplacementPass : UnityEngine.Rendering.Universal.ScriptableRenderPass
  44. {
  45. private const string ProfilerTag = "Render Lux Grass Displacement FX";
  46. private static ProfilingSampler m_ProfilingSampler = new ProfilingSampler(ProfilerTag);
  47. ShaderTagId m_GrassDisplacementFXShaderTag = new ShaderTagId("LuxGrassDisplacementFX");
  48. private SinglePassStereoMode m_StereoRenderingMode;
  49. // There is no 0.5 in 8bit colors...
  50. Color m_ClearColor = new Color(127.0f/255.0f, 127.0f/255.0f,1,1);
  51. // In case of XR enabled this most likely will be an array
  52. UnityEngine.Rendering.Universal.RenderTargetHandle m_GrassDisplacementFX = UnityEngine.Rendering.Universal.RenderTargetHandle.CameraTarget;
  53. private Matrix4x4 projectionMatrix;
  54. private Matrix4x4 worldToCameraMatrix;
  55. public float m_Size = 20.0f;
  56. public int m_Resolution = 256;
  57. public bool m_ShiftRenderTex = false;
  58. //public bool m_SinglePassInstancing = false;
  59. private float stepSize;
  60. private float oneOverStepSize;
  61. private Vector4 posSize = Vector4.zero;
  62. private static int DisplacementTexPosSizePID = Shader.PropertyToID("_Lux_DisplacementPosition");
  63. private FilteringSettings transparentFilterSettings { get; set; }
  64. public GrassDisplacementPass()
  65. {
  66. m_GrassDisplacementFX.Init("_Lux_DisplacementRT");
  67. transparentFilterSettings = new FilteringSettings(RenderQueueRange.transparent);
  68. }
  69. public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
  70. {
  71. cameraTextureDescriptor.depthBufferBits = 0;
  72. cameraTextureDescriptor.width = m_Resolution;
  73. cameraTextureDescriptor.height = m_Resolution;
  74. cameraTextureDescriptor.colorFormat = RenderTextureFormat.Default;
  75. // XR: force our RT to be always 2D
  76. cameraTextureDescriptor.dimension = TextureDimension.Tex2D;
  77. cmd.GetTemporaryRT(m_GrassDisplacementFX.id, cameraTextureDescriptor, FilterMode.Bilinear);
  78. ConfigureTarget(m_GrassDisplacementFX.Identifier());
  79. ConfigureClear(ClearFlag.Color, m_ClearColor);
  80. // Set up all constants
  81. stepSize = m_Size / (float)m_Resolution;
  82. oneOverStepSize = 1.0f / stepSize;
  83. var halfSize = m_Size * 0.5f;
  84. projectionMatrix = Matrix4x4.Ortho(-halfSize, halfSize, -halfSize, halfSize, 0.1f, 80.0f);
  85. projectionMatrix = GL.GetGPUProjectionMatrix(projectionMatrix, false);
  86. worldToCameraMatrix.SetRow(0, new Vector4(1,0,0,0) ); //last is x pos
  87. worldToCameraMatrix.SetRow(1, new Vector4(0,0,1,0) ); //last is z pos
  88. worldToCameraMatrix.SetRow(2, new Vector4(0,1,0,0) ); //last is y pos
  89. worldToCameraMatrix.SetRow(3, new Vector4(0,0,0,1) );
  90. }
  91. public override void Execute(ScriptableRenderContext context, ref UnityEngine.Rendering.Universal.RenderingData renderingData)
  92. {
  93. CommandBuffer cmd = CommandBufferPool.Get(ProfilerTag);
  94. using (new ProfilingScope(cmd, m_ProfilingSampler))
  95. {
  96. context.ExecuteCommandBuffer(cmd);
  97. cmd.Clear();
  98. var drawSettings = CreateDrawingSettings(m_GrassDisplacementFXShaderTag, ref renderingData, SortingCriteria.CommonTransparent);
  99. var filteringSettings = transparentFilterSettings;
  100. var camera = renderingData.cameraData.camera;
  101. var cameraTransform = camera.transform;
  102. var cameraPos = cameraTransform.position;
  103. #if ENABLE_VR && ENABLE_XR_MODULE
  104. var isStereoEnabled = renderingData.cameraData.xr.enabled; //isStereoEnabled; //
  105. if (isStereoEnabled) {
  106. m_StereoRenderingMode = XRSettings.stereoRenderingMode;
  107. cmd.SetSinglePassStereo(SinglePassStereoMode.None);
  108. }
  109. #endif
  110. // Push cameraPos forward – if enabled
  111. var camForward = cameraTransform.forward;
  112. // unstable
  113. // cameraPos.x += camForward.x * m_Size * 0.5f;
  114. // cameraPos.z += camForward.z * m_Size * 0.5f;
  115. if (m_ShiftRenderTex) {
  116. var t_camForward = new Vector2(camForward.x, camForward.z);
  117. t_camForward.Normalize();
  118. // still rather unstable...
  119. cameraPos.x += t_camForward.x * m_Size * 0.33f;
  120. cameraPos.z += t_camForward.y * m_Size * 0.33f;
  121. }
  122. // Store original Camera matrices
  123. var worldToCameraMatrixOrig = camera.worldToCameraMatrix;
  124. var projectionMatrixOrig = camera.projectionMatrix;
  125. // Quantize movement to fit texel size of RT – this stabilzes the final visual result
  126. Vector2 positionRT = Vector2.zero; // bad
  127. positionRT.x = Mathf.Floor(cameraPos.x * oneOverStepSize) * stepSize;
  128. positionRT.y = Mathf.Floor(cameraPos.z * oneOverStepSize) * stepSize;
  129. // Update the custom worldToCameraMatrix – we only have to update the translation/position
  130. worldToCameraMatrix.SetColumn(3, new Vector4(-positionRT.x, -positionRT.y, -cameraPos.y - 40.0f, 1) );
  131. cmd.SetViewProjectionMatrices(worldToCameraMatrix, projectionMatrix);
  132. // ---------------------------------------------------------
  133. // Calc and set grass shader params
  134. posSize.x = positionRT.x - m_Size * 0.5f;
  135. posSize.y = positionRT.y - m_Size * 0.5f;
  136. posSize.z = 1.0f / m_Size ;
  137. cmd.SetGlobalVector(DisplacementTexPosSizePID, posSize );
  138. // ---------------------------------------------------------
  139. // Call execute
  140. context.ExecuteCommandBuffer(cmd);
  141. context.DrawRenderers(renderingData.cullResults, ref drawSettings, ref filteringSettings);
  142. // ---------------------------------------------------------
  143. // Restore Camera matrices
  144. cmd.Clear();
  145. cmd.SetViewProjectionMatrices(worldToCameraMatrixOrig, projectionMatrixOrig);
  146. #if ENABLE_VR && ENABLE_XR_MODULE
  147. if (isStereoEnabled) {
  148. cmd.SetSinglePassStereo(m_StereoRenderingMode);
  149. }
  150. #endif
  151. }
  152. // ---------------------------------------------------------
  153. // Call execute a 2nd time
  154. context.ExecuteCommandBuffer(cmd);
  155. CommandBufferPool.Release(cmd);
  156. }
  157. public override void OnCameraCleanup(CommandBuffer cmd)
  158. {
  159. cmd.ReleaseTemporaryRT(m_GrassDisplacementFX.id);
  160. }
  161. }
  162. }