日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Unity3D ShaderLab 内发光防护罩

發(fā)布時(shí)間:2025/3/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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ì)導(dǎo)致其他Pass渲染異常)
  • 使用后處理解決,一般能夠完美的解決;會(huì)帶來(lái)額外的渲染性能開(kāi)銷。
  • 相交效果缺陷

    不同視角方向會(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)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。