文章目录
- 前言
- 一、交接处高亮 原理
- 1、 我们先用一个球作为能量罩、一个Cube 和 一个 椭球 作为与能量罩交接的物体
- 2、 这是我们目前场景的深度图
- 3、使能量罩为 半透明渲染队列 且 关闭深度写入 不渲染深度图
- 二、交接处高亮 实现
- 1、得到深度图
- 2、在片元着色器中,对深度图进行纹理采样
- 3、得到深度图 观察空间下的Z值
- 4、得到 深度图 观察空间Z值 和 能量罩观察空间Z值 的 差值
- 5、用1 - depth得到反色
- 6、在属性面板定义一个参数用于控制高亮范围
- 6、在属性面板定义一个Color用于控制高亮颜色
- 请添加图片描述
- 三、测试代码
前言
在之前的文章中,我们实现了 深度图 和 抓屏 的使用。我们用这些功能来实现一下能量罩效果。
-
Unity中URP下使用屏幕坐标采样深度图
-
Unity中URP下抓屏的 开启 和 使用
一、交接处高亮 原理
1、 我们先用一个球作为能量罩、一个Cube 和 一个 椭球 作为与能量罩交接的物体
2、 这是我们目前场景的深度图
- 我们要实现交接处高亮,使用交接外面的部分,是实现不了的
- 因为,用深度图观察空间下的Z值 和 物体能量罩的观察空间Z轴,得到外面的部分 和 之前的是一致的
- 所以,我们得用 深度图 和 能量罩的观察空间Z轴,来得到 交接处高亮
3、使能量罩为 半透明渲染队列 且 关闭深度写入 不渲染深度图
- 这样能量罩就不被深度图渲染了
- 我们就可以使用 深度图观察空间下的Z值 和 能量罩的观察空间Z值 得到 交接的内部区域了
二、交接处高亮 实现
1、得到深度图
- 申明 深度图 纹理 和 深度图采样器
TEXTURE2D(_CameraDepthTexture);SAMPLER(sampler_CameraDepthTexture);
2、在片元着色器中,对深度图进行纹理采样
float2 uv = i.positionCS.xy/ _ScreenParams.xy;
float4 cameraDepthTex = SAMPLE_TEXTURE2D(_CameraDepthTexture,sampler_CameraDepthTexture,uv);
3、得到深度图 观察空间下的Z值
float depthTex = LinearEyeDepth(cameraDepthTex,_ZBufferParams);
4、得到 深度图 观察空间Z值 和 能量罩观察空间Z值 的 差值
- 由于观察空间是右手坐标系。所以该Z值是负值。
- 能量罩观察空间Z值,需要在顶点着色器中提前计算好,从顶点着色器传入片元着色器
- 差值 = 用深度图观察空间Z值 + 能量罩观察空间Z值
float4 depth = depthTex + i.positionVS.z;
5、用1 - depth得到反色
float4 highLight = 1 - depth;
6、在属性面板定义一个参数用于控制高亮范围
- 相乘节省性能
highLight *= _HighLightFade;
- 指数效果更佳
highLight = pow(highLight,_HighLightFade);
6、在属性面板定义一个Color用于控制高亮颜色
highLight *= _HighLightColor;
三、测试代码
Shader "MyShader/URP/P4_3"
{Properties {_HighLightColor("HighLightColor",Color) = (0,0,0,0)_HighLightFade("HighLight",Float) = 1.0}SubShader{Tags{//告诉引擎,该Shader只用于 URP 渲染管线"RenderPipeline"="UniversalPipeline"//渲染类型"RenderType"="Transparent"//渲染队列"Queue"="Transparent"}//Blend One OneZWrite OffPass{Name "Unlit"HLSLPROGRAM#pragma vertex vert#pragma fragment frag// Pragmas#pragma target 2.0// Includes#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"CBUFFER_START(UnityPerMaterial)half4 _HighLightColor;half _HighLightFade;CBUFFER_ENDTEXTURE2D(_CameraDepthTexture);SAMPLER(sampler_CameraDepthTexture);//struct appdata//顶点着色器的输入struct Attributes{float3 positionOS : POSITION;float2 uv : TEXCOORD0;};//struct v2f//片元着色器的输入struct Varyings{float4 positionCS : SV_POSITION;float2 uv : TEXCOORD0;float4 screenPos : TEXCOORD1;float3 positionVS : TEXCOORD2;};//v2f vert(Attributes v)//顶点着色器Varyings vert(Attributes v){Varyings o = (Varyings)0;float3 positionWS = TransformObjectToWorld(v.positionOS);o.positionVS = TransformWorldToView(positionWS);o.positionCS = TransformWViewToHClip(o.positionVS);o.screenPos = ComputeScreenPos(o.positionCS);return o;}//fixed4 frag(v2f i) : SV_TARGET//片元着色器half4 frag(Varyings i) : SV_TARGET{//深度图//float2 uv = i.screenPos.xy / i.screenPos.w;float2 uv = i.positionCS.xy/ _ScreenParams.xy;float4 cameraDepthTex = SAMPLE_TEXTURE2D(_CameraDepthTexture,sampler_CameraDepthTexture,uv);float depthTex = LinearEyeDepth(cameraDepthTex,_ZBufferParams);float depth = depthTex + i.positionVS.z;float4 highLight = 1 - depth;highLight = pow(highLight,_HighLightFade);highLight *= _HighLightColor;return highLight;}ENDHLSL}}
}