Unity3D ShaderLab 物体相交
物體相交
- 物體相交
- 思路
- 實(shí)現(xiàn)
- 效果
物體相交
利用深度圖來(lái)做效果,不提供數(shù)學(xué)原理,只提供Shader腳本實(shí)現(xiàn)。
思路
已知需要渲染物體的深度信息,通過(guò)與_CameraDepthTexture紋理中的深度值進(jìn)行一些計(jì)算或者判定即可完成相交的效果。
計(jì)算方式:在視圖(View)坐標(biāo)系下,假設(shè)物體深度值為eyeZeyeZeyeZ,深度緩存中的深度值為sceneZsceneZsceneZ,相交寬度為IntersectionWidthIntersectionWidthIntersectionWidth;通過(guò)abs(eyeZ?sceneZ)/InstersectionWidthabs(eyeZ - sceneZ)/InstersectionWidthabs(eyeZ?sceneZ)/InstersectionWidth可以得到[0,n][0, n][0,n]的一個(gè)值,將[0,n][0, n][0,n]截?cái)嗟?span id="ozvdkddzhkzd" class="katex--inline">[0,1][0, 1][0,1],最后使用lerp函數(shù)實(shí)現(xiàn)一個(gè)過(guò)渡。
_CameraDepthTexture紋理記錄的是NDC空間下的深度信息,因此需要轉(zhuǎn)到視圖(View)空間下。
實(shí)現(xiàn)
Shader "Hidden/IntersectionHighlight" {Properties{_IntersectionColor("Intersection Color", Color) = (1,1,0,0)_IntersectionWidth("Intersection Width", Range(0, 2)) = 0.1}SubShader{Pass{// 關(guān)閉深度寫入, 否則渲染會(huì)出現(xiàn)問(wèn)題ZWrite Off// 關(guān)閉背面剔除, 渲染雙面Cull Off// 開blend, 在片段后會(huì)進(jìn)行blend混合Blend SrcAlpha OneTags {"RenderType" = "Opaque"}CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float4 vertex : SV_POSITION;float2 uv : TEXCOORD0;float4 screenPos : TEXCOORD1;float eyeZ : TEXCOORD2;};// 深度緩存圖sampler2D _CameraDepthTexture;// 相交顏色fixed4 _IntersectionColor;// 相交寬度float _IntersectionWidth;v2f vert (appdata v){v2f o;// o.vertex為裁剪空間中的點(diǎn)o.vertex = UnityObjectToClipPos(v.vertex);// 返回齊次坐標(biāo)系下的點(diǎn), 范圍是[0, w]; 其中,w不是viewport的width (ps: 需要與tex2Dproj函數(shù)配套使用)o.screenPos = ComputeScreenPos(o.vertex);// 將v.vertex與model和view矩陣相乘, 得到相機(jī)到物體的z坐標(biāo), 為view坐標(biāo)系下COMPUTE_EYEDEPTH(o.eyeZ);return o;}fixed4 frag(v2f i) : SV_Target{// UNITY_PROJ_COORD(a)應(yīng)該是預(yù)留的一個(gè)接口, 官方解釋為大部分平臺(tái)將返回入?yún)⒅?/span>// SAMPLE_DEPTH_TEXTURE_PROJ(tex, uv)內(nèi)部調(diào)用tex2Dproj(tex, uv), tex2Dproj會(huì)將(uv = uv / w)// LinearEyeDepth(depth)將返回depth在view坐標(biāo)系下的表示, 源碼中的_ZBufferParams是相機(jī)中far和near兩個(gè)參數(shù)表達(dá)式的結(jié)果值float screenZ = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenPos)));// 相交計(jì)算, abs(物體的深度值 - 深度緩存的深度值) / 長(zhǎng)度 => [0, n]的范圍 => saturate限制到[0, 1]float diff = saturate(abs(i.eyeZ - screenZ) / (_IntersectionWidth / 2));// (0.0 -> 1.0) => (最亮 -> 最暗), diff => colorreturn lerp(_IntersectionColor, float4(0.0, 0.0, 0.0, 0.0), diff);}ENDCG}} }效果
總結(jié)
以上是生活随笔為你收集整理的Unity3D ShaderLab 物体相交的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 大厂的产品经理是怎样进行产品迭代的
- 下一篇: 产品经理必知的数据指标