赞
踩
2021HDRP模糊效果Demo git参考:
GitHub - alelievr/HDRP-Custom-Passes: A bunch of custom passes made for HDRP
1、创建HDRP项目
2、创建CustomPass物体
新增2个FullScreenCustomPass
创建一个OutlineH材质球和OutlineH着色器,将OutlineH着色器拖拽给OutlineH材质球,OutlineH着色器代码如下:
- Shader "Hidden/OutlineH"
- {
- Properties{
- _BlurScale("BlurScale", float) = 1
- }
- HLSLINCLUDE
-
- #pragma vertex Vert
-
- #pragma target 4.5
- #pragma only_renderers d3d11 playstation xboxone vulkan metal switch
-
- #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassCommon.hlsl"
-
- float _BlurScale;
-
- float2 ClampUVs(float2 uv)
- {
- uv = clamp(uv, 0, _RTHandleScale.xy - _ScreenSize.zw * 2); // clamp UV to 1 pixel to avoid bleeding
- return uv;
- }
-
- float2 GetSampleUVs(Varyings varyings)
- {
- float depth = LoadCameraDepth(varyings.positionCS.xy);
- PositionInputs posInput = GetPositionInput(varyings.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
- return posInput.positionNDC.xy * _RTHandleScale.xy;
- }
-
- float4 FullScreenPass(Varyings varyings) : SV_Target
- {
- UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(varyings);
-
- float depth = LoadCameraDepth(varyings.positionCS.xy);
- PositionInputs posInput = GetPositionInput(varyings.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
- float4 color = float4(0.0, 0.0, 0.0, 0.0);
-
- // Load the camera color buffer at the mip 0 if we're not at the before rendering injection point
- if (_CustomPassInjectionPoint != CUSTOMPASSINJECTIONPOINT_BEFORE_RENDERING)
- color = float4(CustomPassSampleCameraColor(posInput.positionNDC.xy, 0), 1);
-
- //UV获取方式,varyings.positionCS.xy * _ScreenSize.zw为NDC坐标,_RTHandleScale.xy是对NDC坐标进行一个缩放获取uv
- //float2 uv = ClampUVs(varyings.positionCS.xy * _ScreenSize.zw * _RTHandleScale.xy);
-
- //横向模糊(需要起另一个CustomPass处理纵向模糊)
- float3 sumColor = 0;
- float weight[3] = { 0.4026, 0.2442, 0.0545 };
-
- sumColor = color.rgb * weight[0];
- for (int i = 1; i < 3; i++)
- {
- //注意因为采样坐标是用NDC坐标,故float2(_BlurScale * i, 0) * _ScreenSize.zw是获取一个NDC坐标系上的增量(偏移值) 进行对周围横向或纵向像素采样!
- sumColor += CustomPassSampleCameraColor(posInput.positionNDC.xy + float2(_BlurScale * i, 0) * _ScreenSize.zw, 0).rgb * weight[i];
- sumColor += CustomPassSampleCameraColor(posInput.positionNDC.xy + float2(_BlurScale * -i, 0) * _ScreenSize.zw, 0).rgb * weight[i];
- }
-
- return float4(sumColor, 1);
- }
-
- ENDHLSL
-
- SubShader
- {
- Pass
- {
- Name "Custom Pass 0"
-
- ZWrite On
- ZTest Always
- Blend SrcAlpha OneMinusSrcAlpha
- Cull Off
-
- HLSLPROGRAM
- #pragma fragment FullScreenPass
- ENDHLSL
- }
- }
- Fallback Off
- }
这一个材质效果是进行一次横向模糊,将结果缓存在CustomPass的缓冲区,默认是Camera(即直接输出到屏幕 但它还是会做一次混合的 仔细看Shader就能发现 Blend SrcAlpha OneMinusSrcAlpha)
新建一个OutlineV材质球和着色器,着色器代码:
- Shader "Hidden/OutlineV"
- {
- Properties{
- _BlurScale("BlurScale", float) = 1
- }
- HLSLINCLUDE
-
- #pragma vertex Vert
-
- #pragma target 4.5
- #pragma only_renderers d3d11 playstation xboxone vulkan metal switch
-
- #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassCommon.hlsl"
-
- float _BlurScale;
-
- float2 ClampUVs(float2 uv)
- {
- uv = clamp(uv, 0, _RTHandleScale.xy - _ScreenSize.zw * 2); // clamp UV to 1 pixel to avoid bleeding
- return uv;
- }
-
- float2 GetSampleUVs(Varyings varyings)
- {
- float depth = LoadCameraDepth(varyings.positionCS.xy);
- PositionInputs posInput = GetPositionInput(varyings.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
- return posInput.positionNDC.xy * _RTHandleScale.xy;
- }
-
- float4 FullScreenPass(Varyings varyings) : SV_Target
- {
- UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(varyings);
-
- float depth = LoadCameraDepth(varyings.positionCS.xy);
- PositionInputs posInput = GetPositionInput(varyings.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
- float4 color = float4(0.0, 0.0, 0.0, 0.0);
-
-
- //纵向从CustomPass(上一个横向模糊处理后的图片采样,即CustomColor缓冲区) 使用的是uv
- // float4 SampleCustomColor(float2 uv);
- // float4 LoadCustomColor(uint2 pixelCoords);
-
- //UV获取方式,varyings.positionCS.xy * _ScreenSize.zw为NDC坐标,_RTHandleScale.xy是对NDC坐标进行一个缩放获取uv
- float2 uv = ClampUVs(varyings.positionCS.xy * _ScreenSize.zw * _RTHandleScale.xy);
-
- // Load the camera color buffer at the mip 0 if we're not at the before rendering injection point
- if (_CustomPassInjectionPoint != CUSTOMPASSINJECTIONPOINT_BEFORE_RENDERING)
- color = SampleCustomColor(uv);
-
-
-
- //纵向向模糊
- float3 sumColor = 0;
- float weight[3] = { 0.4026, 0.2442, 0.0545 };
-
- sumColor = color.rgb * weight[0];
- for (int i = 1; i < 3; i++)
- {
- //注意采用使用的是UV坐标,因此float2(0, _BlurScale * i) * _ScreenSize.zw * _RTHandleScale.xy获取UV坐标增量(偏移值)
- sumColor += SampleCustomColor(uv + float2(0, _BlurScale * i) * _ScreenSize.zw * _RTHandleScale.xy).rgb * weight[i];
- sumColor += SampleCustomColor(uv + float2(0, _BlurScale * -i) * _ScreenSize.zw * _RTHandleScale.xy).rgb * weight[i];
- }
-
- return float4(sumColor, 1);
- }
-
- ENDHLSL
-
- SubShader
- {
- Pass
- {
- Name "Custom Pass 0"
-
- ZWrite On
- ZTest Always
- Blend SrcAlpha OneMinusSrcAlpha
- Cull Off
-
- HLSLPROGRAM
- #pragma fragment FullScreenPass
- ENDHLSL
- }
- }
- Fallback Off
- }
注意看选中的是Camera,第二次采样的是CustomPass的图片(第一次横向模糊输出的图片)对它进行了一个纵向模糊,然后输出到Camera。
代码很简单,比较难理解的是第一个横向模糊shader是使用
CustomPassSampleCameraColor(posInput.positionNDC.xy, 0) 获取了一个float3,其中采样坐标是NDC坐标。
第二个纵向模糊shader是使用
SampleCustomColor(uv) 获取float4 它是从CustomPass缓存的图片采样的,必须先进行横向模糊输出custom后 才能进行纵向模糊 ,当然你也可以反过来,使用先纵向后横向,但肯定是最后一个进行的模糊要是从Custom来获取上一次的处理结果,而不能再去使用CustomPassSampleCameraColor,因为这个看英文就知道它就是从摄像机缓存获取图片,这个就是当前渲染到的屏幕图而已。
重点内容是:
UV获取方式:varyings.positionCS.xy * _ScreenSize.zw为NDC坐标,_RTHandleScale.xy是对NDC坐标进行一个缩放获取uv
即 uv = varyings.positionCS.xy * _ScreenSize.zw * _RTHandleScale.xy);
uv = clamp(uv, 0, _RTHandleScale.xy - _ScreenSize.zw * 2); // clamp UV to 1 pixel to avoid bleeding
对uv进行clamp处理是将uv约束在1个像素范围以内,这个不太懂了。
其中NDC坐标系是用 varyings.positionCS.xy * _ScreenSize.zw 获取的,当你想做偏移float2(1,0)时,只要将这个float2(1,0)理解成positionCS.xy即可。
positonCS是Homogenous clip spaces(同质剪辑空间)裁剪空间?
_ScreenSize.zw是一个能让裁剪空间缩放回NDC坐标系的缩放系数?
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。