Unity3D ShaderLab 物体相交
生活随笔
收集整理的這篇文章主要介紹了
Unity3D ShaderLab 物体相交
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
物體相交
- 物體相交
- 思路
- 實現
- 效果
物體相交
利用深度圖來做效果,不提供數學原理,只提供Shader腳本實現。
思路
已知需要渲染物體的深度信息,通過與_CameraDepthTexture紋理中的深度值進行一些計算或者判定即可完成相交的效果。
計算方式:在視圖(View)坐標系下,假設物體深度值為eyeZeyeZeyeZ,深度緩存中的深度值為sceneZsceneZsceneZ,相交寬度為IntersectionWidthIntersectionWidthIntersectionWidth;通過abs(eyeZ?sceneZ)/InstersectionWidthabs(eyeZ - sceneZ)/InstersectionWidthabs(eyeZ?sceneZ)/InstersectionWidth可以得到[0,n][0, n][0,n]的一個值,將[0,n][0, n][0,n]截斷到[0,1][0, 1][0,1],最后使用lerp函數實現一個過渡。
_CameraDepthTexture紋理記錄的是NDC空間下的深度信息,因此需要轉到視圖(View)空間下。
實現
Shader "Hidden/IntersectionHighlight" {Properties{_IntersectionColor("Intersection Color", Color) = (1,1,0,0)_IntersectionWidth("Intersection Width", Range(0, 2)) = 0.1}SubShader{Pass{// 關閉深度寫入, 否則渲染會出現問題ZWrite Off// 關閉背面剔除, 渲染雙面Cull Off// 開blend, 在片段后會進行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為裁剪空間中的點o.vertex = UnityObjectToClipPos(v.vertex);// 返回齊次坐標系下的點, 范圍是[0, w]; 其中,w不是viewport的width (ps: 需要與tex2Dproj函數配套使用)o.screenPos = ComputeScreenPos(o.vertex);// 將v.vertex與model和view矩陣相乘, 得到相機到物體的z坐標, 為view坐標系下COMPUTE_EYEDEPTH(o.eyeZ);return o;}fixed4 frag(v2f i) : SV_Target{// UNITY_PROJ_COORD(a)應該是預留的一個接口, 官方解釋為大部分平臺將返回入參值// SAMPLE_DEPTH_TEXTURE_PROJ(tex, uv)內部調用tex2Dproj(tex, uv), tex2Dproj會將(uv = uv / w)// LinearEyeDepth(depth)將返回depth在view坐標系下的表示, 源碼中的_ZBufferParams是相機中far和near兩個參數表達式的結果值float screenZ = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenPos)));// 相交計算, abs(物體的深度值 - 深度緩存的深度值) / 長度 => [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}} }效果
總結
以上是生活随笔為你收集整理的Unity3D ShaderLab 物体相交的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大厂的产品经理是怎样进行产品迭代的
- 下一篇: 产品经理必知的数据指标