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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Unity中的半透明阴影

發布時間:2024/1/8 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Unity中的半透明阴影 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Unity中的半透明陰影

在Unity中渲染半透明陰影可以使用Unity提供的dither texture。在這之前,先考慮一般半透明物體的渲染流程:

  • 設置render queue為Transparent,這樣不透明的物體會先渲染,然后位于被不透明物體遮擋的透明物體就可以不必渲染,減少開銷
  • 設置render type為Transparent,便于一些replacement操作
  • 設置blend mode,例如fade是srcBlend = SrcAlpha,dstBlend = OneMinusSrcAlpha,而Transparent是srcBlend = One,dstBlend = OneMinusSrcAlpha
  • 關閉深度寫入,zwrite = false

Unity中的半透明陰影本質上是不透明的,只是對dither texture進行采樣,根據采樣的結果,clip掉一些fragment,使得shadow caster過程中只有一部分陰影信息會被繪制到shadowmap上。Unity builtin shaders提供的參考寫法如下:

struct Interpolators {UNITY_VPOS_TYPE vpos : VPOS;... };float4 MyShadowFragmentProgram (Interpolators i) : SV_TARGET {...half alphaRef = tex3D(_DitherMaskLOD, float3(vpos.xy*0.25,alpha*0.9375)).a;clip(dither - 0.01);... }

vpos表示的是當前像素在screen space下的坐標,_DitherMaskLOD是一個尺寸為4×4×16的3D紋理,這個可以從frame debug中看出:

這個紋理長啥樣呢?我們可以寫一個shader手動把它輸出:

Shader "Custom/TextureViewShader" {Properties{}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{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;};sampler3D _DitherMaskLOD;v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = v.uv;return o;}fixed4 frag (v2f i) : SV_Target{// sample the texturei.uv *= 16;fixed4 col = tex3D(_DitherMaskLOD, float3(i.uv, floor(i.uv.x) * 0.0625)).a;return col;}ENDCG}} }

從frame debug可知紋理是alpha8格式,因而只需輸出alpha通道值:

由于_DitherMaskLOD紋理是4×4×16的,我們實際上在v方向也重復了16次,因此真正的紋理長這樣:

可以看出,該紋理從4×4的全黑像素開始,隨著維度z的增加,黑色像素每次減少1個,直至最后全部變成4×4的全白像素。通過這個規律,不難理解前面代碼tex3D的采樣坐標z的寫法為alpha*0.9375。alpha表示透明度,0為完全透明1為完全不透明,而0.9375實際上就是15/16。這就是說在0的情況下采樣的3D紋理是純黑像素,會被clip掉,不會產生陰影;而1的情況下采樣的3D紋理是全白像素,會完全產生陰影,就仿佛跟不透明物體一樣。

最后再看一下這個vpos*0.25是干啥的。vpos表示的是pixel在screen space下的坐標,x和y取值范圍類似[0, screenWidth],[0, screenHeight]。乘以0.25的系數就是對取值范圍進行縮放處理,換言之就是將_DitherMaskLOD紋理進行放大,使其更明顯??梢钥聪虏煌s放比例的效果對比:

最后提一點的是,由于半透明的物體,render queue設置為transparent,所以在平行光繪制陰影前的depth pass階段,是不會把半透明物體的深度信息寫入depth buffer的,不過在shadow caster階段,半透明陰影的信息還是正常繪制到shadowmap中的。這些都可以從frame debug中看出來:

如果你覺得我的文章有幫助,歡迎關注我的微信公眾號(大齡社畜的游戲開發之路-

總結

以上是生活随笔為你收集整理的Unity中的半透明阴影的全部內容,希望文章能夠幫你解決所遇到的問題。

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