Unity3D ShaderLab 内发光防护罩
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                Unity3D ShaderLab 内发光防护罩
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                內發光防護罩
- 內發光防護罩
- 思路
- 內輪廓發光效果
- 相交效果
 
- 缺陷
- 內輪廓發光缺陷
- 缺陷解決方案
- 相交效果缺陷
- 缺陷解決方案
 
- 實現
- 效果
 
內發光防護罩
1、利用模型法線和視角方向得到內輪廓發光效果。
 2、利用深度圖來做與其他物體相交效果。
思路
內輪廓發光效果
只需要知道模型每個三角面的法向量和相機到三角面頂點的向量,通過1.0 - dot(normal, viewDir)就能得到外輪廓發光效果。
相交效果
已知需要渲染物體的深度信息,通過與_CameraDepthTexture紋理中的深度值進行一些計算或者判定即可完成相交的效果。
缺陷
內輪廓發光缺陷
在Unity3D的Cube中,此方案將存在缺陷;是由于面之間的法向量互相垂直導致。
缺陷解決方案
相交效果缺陷
不同視角方向會存在_CameraDepthTexture深度值為0的情況,從而導致斷層或者其他問題。
缺陷解決方案
目前未想到使用深度圖對應的解決方案。可以考慮使用其他方式解決,例如:不使用深度圖,傳入一個法向量和面原點解決。
實現
Shader "Hidden/ForceField" {Properties{_MainColor("Main Color", Color) = (1,1,1,1)_RimPower("Rim Power", Range(0, 1)) = 1_IntersectionPower("Intersect Power", Range(0, 1)) = 0}SubShader{Pass{// 關閉深度寫入ZWrite Off// 關閉剔除Cull Off// 開個blend Blend SrcAlpha One// 渲染隊列Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;};struct v2f{float4 vertex : SV_POSITION;float3 worldNormal : TEXCOORD0;float3 worldViewDir : TEXCOORD1;float4 screenPos : TEXCOORD2;float4 eyeZ : TEXCOORD3;};// 深度圖sampler2D _CameraDepthTexture;// 護罩顏色fixed4 _MainColor;// 輪廓強度float _RimPower;// 相交長度float _IntersectionPower;v2f vert (appdata v){v2f o;// vertex模型頂點轉裁剪坐標系o.vertex = UnityObjectToClipPos(v.vertex);// normal模型法線轉世界坐標系o.worldNormal = normalize(UnityObjectToWorldDir(v.normal));// 獲得世界坐標系中 模型頂點 -> 相機頂點 的向量o.worldViewDir = normalize(UnityWorldSpaceViewDir(mul(unity_ObjectToWorld, 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{// dot(worldNormal, worldViewDir)兩個向量的夾角越大, 值越小(cos(t)函數)// 1.0 - saturate(abs(dot(i.worldNormal, i.worldViewDir)))得到了反向顏色值, 也就是夾角越小, 值越大(1-cos(t))float rim = pow(1.0 - saturate(abs(dot(i.worldNormal, i.worldViewDir))), _RimPower) * 0.5;// 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)));// 相交計算, saturate(1.0 - abs(物體的深度值 - 深度緩存的深度值)) => saturate限制到[0, 1]float intersect = saturate(1.0 - abs(i.eyeZ - screenZ)) * _IntersectionPower;// 取兩者中的最大return max(rim, intersect) * _MainColor;}ENDCG}} }效果
總結
以上是生活随笔為你收集整理的Unity3D ShaderLab 内发光防护罩的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 产品经理必知的数据指标
- 下一篇: 数据分析万能公式
