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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Unity3D ShaderLab 内发光防护罩

發布時間:2025/3/15 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Unity3D ShaderLab 内发光防护罩 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

內發光防護罩

  • 內發光防護罩
    • 思路
      • 內輪廓發光效果
      • 相交效果
    • 缺陷
      • 內輪廓發光缺陷
      • 缺陷解決方案
      • 相交效果缺陷
      • 缺陷解決方案
    • 實現
    • 效果

內發光防護罩

1、利用模型法線和視角方向得到內輪廓發光效果。
2、利用深度圖來做與其他物體相交效果。

思路

內輪廓發光效果

只需要知道模型每個三角面的法向量和相機到三角面頂點的向量,通過1.0 - dot(normal, viewDir)就能得到外輪廓發光效果。

相交效果

已知需要渲染物體的深度信息,通過與_CameraDepthTexture紋理中的深度值進行一些計算或者判定即可完成相交的效果。

缺陷

內輪廓發光缺陷

在Unity3D的Cube中,此方案將存在缺陷;是由于面之間的法向量互相垂直導致。

缺陷解決方案

  • 修改模型的法線向量,取各面法向量總和的均值。(可能會導致其他Pass渲染異常)
  • 使用后處理解決,一般能夠完美的解決;會帶來額外的渲染性能開銷。
  • 相交效果缺陷

    不同視角方向會存在_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 内发光防护罩的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。