Unity3D ShaderLab 内发光防护罩
生活随笔
收集整理的這篇文章主要介紹了
Unity3D ShaderLab 内发光防护罩
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
內(nèi)發(fā)光防護(hù)罩
- 內(nèi)發(fā)光防護(hù)罩
- 思路
- 內(nèi)輪廓發(fā)光效果
- 相交效果
- 缺陷
- 內(nèi)輪廓發(fā)光缺陷
- 缺陷解決方案
- 相交效果缺陷
- 缺陷解決方案
- 實(shí)現(xiàn)
- 效果
內(nèi)發(fā)光防護(hù)罩
1、利用模型法線和視角方向得到內(nèi)輪廓發(fā)光效果。
2、利用深度圖來(lái)做與其他物體相交效果。
思路
內(nèi)輪廓發(fā)光效果
只需要知道模型每個(gè)三角面的法向量和相機(jī)到三角面頂點(diǎn)的向量,通過(guò)1.0 - dot(normal, viewDir)就能得到外輪廓發(fā)光效果。
相交效果
已知需要渲染物體的深度信息,通過(guò)與_CameraDepthTexture紋理中的深度值進(jìn)行一些計(jì)算或者判定即可完成相交的效果。
缺陷
內(nèi)輪廓發(fā)光缺陷
在Unity3D的Cube中,此方案將存在缺陷;是由于面之間的法向量互相垂直導(dǎo)致。
缺陷解決方案
相交效果缺陷
不同視角方向會(huì)存在_CameraDepthTexture深度值為0的情況,從而導(dǎo)致斷層或者其他問(wèn)題。
缺陷解決方案
目前未想到使用深度圖對(duì)應(yīng)的解決方案。可以考慮使用其他方式解決,例如:不使用深度圖,傳入一個(gè)法向量和面原點(diǎn)解決。
實(shí)現(xiàn)
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{// 關(guān)閉深度寫(xiě)入ZWrite Off// 關(guān)閉剔除Cull Off// 開(kāi)個(gè)blend Blend SrcAlpha One// 渲染隊(duì)列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;// 護(hù)罩顏色fixed4 _MainColor;// 輪廓強(qiáng)度float _RimPower;// 相交長(zhǎng)度float _IntersectionPower;v2f vert (appdata v){v2f o;// vertex模型頂點(diǎn)轉(zhuǎn)裁剪坐標(biāo)系o.vertex = UnityObjectToClipPos(v.vertex);// normal模型法線轉(zhuǎn)世界坐標(biāo)系o.worldNormal = normalize(UnityObjectToWorldDir(v.normal));// 獲得世界坐標(biāo)系中 模型頂點(diǎn) -> 相機(jī)頂點(diǎn) 的向量o.worldViewDir = normalize(UnityWorldSpaceViewDir(mul(unity_ObjectToWorld, 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{// dot(worldNormal, worldViewDir)兩個(gè)向量的夾角越大, 值越小(cos(t)函數(shù))// 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)應(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ì)算, saturate(1.0 - abs(物體的深度值 - 深度緩存的深度值)) => saturate限制到[0, 1]float intersect = saturate(1.0 - abs(i.eyeZ - screenZ)) * _IntersectionPower;// 取兩者中的最大return max(rim, intersect) * _MainColor;}ENDCG}} }效果
總結(jié)
以上是生活随笔為你收集整理的Unity3D ShaderLab 内发光防护罩的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 产品经理必知的数据指标
- 下一篇: 数据分析万能公式