当前位置:   article > 正文

unity urp管线扫光效果_unity 电子围栏效果

unity 电子围栏效果

urp管线下实现扫光效果

基本思路,还是根据深度还原世界坐标(以下简称world_pos),根据坐标的xyz判断是否在一些范围内,然后进行基于xyz两个坐标轴进行扫光

这里进行一个扩展,让扫光可以沿着任一方向进行,

就是传入一个旋转变换矩阵,对world_pos进行变换,然后判断aabb盒,这样就可以实现非xyz轴方向的扫光效果

运行效果如下:

可以沿任意方向扫光

代码如下:

shader:

  1. Shader "lsc/screen_scan_shader"
  2. {
  3. Properties
  4. {
  5. _MainTex("Texture", 2D) = "white" {}
  6. _scan_brush("Texture", 2D) = "white" {}
  7. }
  8. SubShader
  9. {
  10. // No culling or depth
  11. Cull Off ZWrite Off ZTest Always
  12. Pass
  13. {
  14. HLSLPROGRAM
  15. #pragma vertex vert
  16. #pragma fragment frag
  17. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
  18. //sampler2D _CameraDepthTexture;
  19. float4x4 _mtx_view_inv;
  20. float4x4 _mtx_proj_inv;
  21. //float4x4 _mtx_clip_to_world;
  22. TEXTURE2D_X_FLOAT(_CameraDepthTexture);
  23. SAMPLER(sampler_CameraDepthTexture);
  24. //扫光参数
  25. float4 _scan_color;
  26. float4 _scan_box_min;
  27. float4 _scan_box_max;
  28. float4x4 _scan_box_world_mtx;
  29. TEXTURE2D_X_FLOAT(_scan_brush);
  30. SAMPLER(sampler_LinearClamp);
  31. struct appdata
  32. {
  33. float4 vertex : POSITION;
  34. float2 uv : TEXCOORD0;
  35. };
  36. struct v2f
  37. {
  38. float2 uv : TEXCOORD0;
  39. float4 vertex : SV_POSITION;
  40. float4 screen_space : TEXCOORD1;
  41. };
  42. float4 cal_world_pos_by_dep(float ndc_dep, float2 screen_space, out float4 view_pos)
  43. {
  44. // 取出非线性深度与视深度
  45. float linearDepthZ = LinearEyeDepth(ndc_dep, _ZBufferParams);
  46. // 屏幕转ndc
  47. float4 ndc_pos;
  48. ndc_pos.xy = screen_space * 2.0 - 1.0;
  49. ndc_pos.zw = float2(ndc_dep, 1);
  50. // 添加齐次因子
  51. ndc_pos = ndc_pos * linearDepthZ;
  52. // 转成观察与世界坐标
  53. view_pos = mul(_mtx_proj_inv, ndc_pos);
  54. float4 world_pos = mul(_mtx_view_inv, float4(view_pos.xyz, 1));
  55. return world_pos;
  56. }
  57. int is_in_box(float3 pos)
  58. {
  59. //todo : need option
  60. if (pos.x <= _scan_box_max.x &&
  61. pos.y <= _scan_box_max.y &&
  62. pos.z <= _scan_box_max.z &&
  63. pos.x >= _scan_box_min.x &&
  64. pos.y >= _scan_box_min.y &&
  65. pos.z >= _scan_box_min.z
  66. )
  67. return 1;
  68. return 0;
  69. }
  70. v2f vert (appdata v)
  71. {
  72. v2f o;
  73. o.vertex = TransformObjectToHClip(v.vertex);
  74. o.uv = v.uv;
  75. // 计算屏幕空间坐标(含齐次因子)
  76. o.screen_space = ComputeScreenPos(o.vertex);
  77. return o;
  78. }
  79. sampler2D _MainTex;
  80. float4 frag (v2f i) : SV_Target
  81. {
  82. float4 col = tex2D(_MainTex, i.uv);
  83. // 插值后的屏幕坐标去除齐次因子
  84. float2 screen_space = i.screen_space.xy / i.screen_space.w;
  85. // 取出非线性深度
  86. float org_depth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_CameraDepthTexture, screen_space).x;
  87. // 计算世界坐标
  88. float4 view_pos;
  89. float4 world_pos = cal_world_pos_by_dep(org_depth, screen_space, view_pos);
  90. //转换到包围盒的旋转平移空间
  91. float4 box_space_pos = mul(_scan_box_world_mtx, float4(world_pos.xyz, 1));
  92. int in_box = is_in_box(box_space_pos.xyz);
  93. float2 brush_uv = float2(
  94. abs(box_space_pos.x - _scan_box_min.x) / (_scan_box_max.x - _scan_box_min.x),
  95. abs(box_space_pos.z - _scan_box_min.z) / (_scan_box_max.z - _scan_box_min.z)
  96. );
  97. // 从纹理中采样渐变效果,或者也可以用xz坐标计算生成简单的渐变效果
  98. float4 scan_brush = SAMPLE_TEXTURE2D_X(_scan_brush, sampler_LinearClamp, brush_uv).x;
  99. float scan_scale = scan_brush.r * brush_uv.x * brush_uv.y;
  100. col.xyz = _scan_color.xyz * in_box * scan_scale + col.xyz;
  101. //float tmp = world_pos.y;
  102. //col.xyz = float3(tmp, tmp, tmp);
  103. return col;
  104. }
  105. ENDHLSL
  106. }
  107. }
  108. }

render feature pass c#代码

  1. using UnityEngine;
  2. using UnityEngine.Rendering;
  3. using UnityEngine.Rendering.Universal;
  4. public class ScreenScanRenderPassFeature : ScriptableRendererFeature
  5. {
  6. class CustomRenderPass : ScriptableRenderPass
  7. {
  8. public Material screen_scan_material = null;
  9. public RenderTargetIdentifier render_target_color;
  10. public RenderTargetHandle temp_render_target;
  11. // This method is called before executing the render pass.
  12. // It can be used to configure render targets and their clear state. Also to create temporary render target textures.
  13. // When empty this render pass will render to the active camera render target.
  14. // You should never call CommandBuffer.SetRenderTarget. Instead call <c>ConfigureTarget</c> and <c>ConfigureClear</c>.
  15. // The render pipeline will ensure target setup and clearing happens in a performant manner.
  16. public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
  17. {
  18. }
  19. // Here you can implement the rendering logic.
  20. // Use <c>ScriptableRenderContext</c> to issue drawing commands or execute command buffers
  21. // https://docs.unity3d.com/ScriptReference/Rendering.ScriptableRenderContext.html
  22. // You don't have to call ScriptableRenderContext.submit, the render pipeline will call it at specific points in the pipeline.
  23. public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
  24. {
  25. //Debug.Log("Execute fog pass");
  26. if (!screen_scan_material)
  27. return;
  28. {
  29. Camera cam = renderingData.cameraData.camera;
  30. var mtx_view_inv = cam.worldToCameraMatrix.inverse;
  31. var mtx_proj_inv = cam.projectionMatrix.inverse;
  32. screen_scan_material.SetMatrix("_mtx_view_inv", mtx_view_inv);
  33. screen_scan_material.SetMatrix("_mtx_proj_inv", mtx_proj_inv);
  34. }
  35. // scan box
  36. {
  37. Vector4 box_min = new Vector4(-15, -1000, -50, 0);
  38. Vector4 box_max = new Vector4(15, 1000, 50, 0);
  39. screen_scan_material.SetVector("_scan_box_min", box_min);
  40. screen_scan_material.SetVector("_scan_box_max", box_max);
  41. screen_scan_material.SetVector("_scan_color", new Vector4(179.0f/255.0f, 224.0f / 255.0f, 230.0f / 255.0f, 1.0f));
  42. Matrix4x4 box_mtx = Matrix4x4.identity;
  43. //box_mtx = Matrix4x4.Rotate(Quaternion.Euler(0, 45 + 30 * Time.time, 0)) * Matrix4x4.Translate(new Vector3(-400, 0, -380));
  44. box_mtx = Matrix4x4.Rotate(Quaternion.Euler(0, 45 - 30 * Time.time, 0)) * Matrix4x4.Translate(new Vector3(-400, 0, -380));
  45. screen_scan_material.SetMatrix("_scan_box_world_mtx", box_mtx);
  46. }
  47. const string CommandBufferTag = "screen scan Pass";
  48. var cmd = CommandBufferPool.Get(CommandBufferTag);
  49. RenderTextureDescriptor opaqueDesc = renderingData.cameraData.cameraTargetDescriptor;
  50. opaqueDesc.depthBufferBits = 0;
  51. cmd.GetTemporaryRT(temp_render_target.id, opaqueDesc);
  52. // 通过材质,将计算结果存入临时缓冲区
  53. cmd.Blit(render_target_color, temp_render_target.Identifier(), screen_scan_material);
  54. // 再从临时缓冲区存入主纹理
  55. cmd.Blit(temp_render_target.Identifier(), render_target_color);
  56. // 执行命令缓冲区
  57. context.ExecuteCommandBuffer(cmd);
  58. // 释放命令缓存
  59. CommandBufferPool.Release(cmd);
  60. // 释放临时RT
  61. cmd.ReleaseTemporaryRT(temp_render_target.id);
  62. }
  63. // Cleanup any allocated resources that were created during the execution of this render pass.
  64. public override void OnCameraCleanup(CommandBuffer cmd)
  65. {
  66. }
  67. }
  68. CustomRenderPass m_ScriptablePass;
  69. public Material screen_scan_material = null;
  70. /// <inheritdoc/>
  71. public override void Create()
  72. {
  73. m_ScriptablePass = new CustomRenderPass();
  74. // Configures where the render pass should be injected.
  75. m_ScriptablePass.renderPassEvent = RenderPassEvent.AfterRenderingOpaques;
  76. }
  77. // Here you can inject one or multiple render passes in the renderer.
  78. // This method is called when setting up the renderer once per-camera.
  79. public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
  80. {
  81. m_ScriptablePass.render_target_color = renderer.cameraColorTarget;
  82. m_ScriptablePass.screen_scan_material = screen_scan_material;
  83. renderer.EnqueuePass(m_ScriptablePass);
  84. }
  85. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/109456
推荐阅读
相关标签
  

闽ICP备14008679号