這篇文章主要介紹了Unity中如何實現(xiàn)仿真絲襪渲染,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
創(chuàng)新互聯(lián)建站長期為數(shù)千家客戶提供的網(wǎng)站建設(shè)服務(wù),團隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為巴中企業(yè)提供專業(yè)的成都網(wǎng)站設(shè)計、網(wǎng)站制作、外貿(mào)營銷網(wǎng)站建設(shè),巴中網(wǎng)站改版等技術(shù)服務(wù)。擁有10年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。
既然基于PBR,新建一個Surface Shader文件,然后依據(jù)需求稍微刪改一下:
Shader "Custom/NewSurfaceShader" { Properties { _NormalTex("Normal", 2D) = "bump"{} _Smoothness("Smoothness", Range(0,1)) = 0.5 } SubShader { Tags { "RenderType"="Opaque" } CGPROGRAM #pragma surface surf Standard fullforwardshadows #pragma target 3.0 sampler2D _NormalTex; struct Input { float2 uv_NormalTex; }; half _Smoothness; fixed4 _Color; void surf (Input IN, inout SurfaceOutputStandard o) { o.Albedo = 1; o.Normal = UnpackNormal(tex2D(_NormalTex, IN.uv_NormalTex)); o.Metallic = 0; o.Smoothness = _Smoothness; o.Alpha = 1; } ENDCG } FallBack "Diffuse" }
刪除了金屬度等一些不需要的屬性,加入了法線。
我們就以此為基礎(chǔ),開始我們的絲襪探索之旅吧。
對絲襪纖維的密集程度定義一個屬性 疏密度(Density),取值范圍0(幾乎沒有纖維)到 1(完全被纖維覆蓋)。依據(jù)疏密度提供顏色給Albedo通道,疏密度越高顯現(xiàn)更多絲襪顏色,越低則顯現(xiàn)皮膚顏色。
計算疏密度需要三部步驟:
丹尼爾值對整體疏密度的影響。
受絲襪良好彈性影響,需要一張灰度貼圖來控制不同區(qū)域的拉伸程度,拉伸越大疏密度越低。
受觀察者視線的影響,絲襪平面與觀察者視線角度越小時,疏密度越大。稱其為邊緣度影響。
對于這幾點,我們定義幾個屬性:
Properties{ _Denier("Denier", Range(5,120)) = 25.0 _DenierTex("Density Texture", 2D) = "black"{} [Enum(Strong,6,Normal,12,Weak,20)] _RimPower("Rim Power", float) = 12 _SkinTint("Skin Color Tint", Color) = (1,0.9,0.8,1) _SkinTex("Skin Color", 2D) = "white" {} _StockingTint("Stocking Color Tint", Color) = (1,1,1,1) _StockingTex("Stocking Color", 2D) = "white"{} }
float denier = (_Denier - 5) / 115; float density = denier * (1 - tex2D(_DenierTex, IN.uv_DenierTex));
將_Denier的數(shù)值進行歸一化(Normalize)。_DenierTex是一張灰度貼圖,越淡的地方表示絲襪被拉伸的程度越高,其纖維越稀疏相應(yīng)會顯示更多皮膚顏色。兩者相乘。
如示例,一般情況下認為膝蓋部分和大腿越靠根部的地方會拉扯的更加厲害。
_Denier一般只在沒有_DenierTex貼圖的情況下做調(diào)整用,使用_DenierTex時請保證_Denier值為最大(120)以正確還原貼圖的效果。
有一種很常見的被稱為 Rim Lighting 的效果,簡單來說就是模型邊緣的內(nèi)發(fā)光效果,簡單來說就是模型邊緣的內(nèi)發(fā)光效果,我們可以參考其中計算邊緣程度的代碼。相關(guān)代碼在Unity官方文檔的Surface Shader examples中就可以找到。
根據(jù)自己的需求改寫:
float rim = pow(1 - dot(normalize(IN.viewDir), o.Normal), _RimPower / 10);
通過點乘(dot)計算視線方向和法線方向的數(shù)量積。視線方向與法線方向完全相反時,即絲襪最中心的部分,取得值為1;而最側(cè)邊視線方向與法線方向垂直時,取得值為0。因為我們定義的是邊緣度,所以應(yīng)該是越靠邊緣值越大,用1與其相減獲得正確的數(shù)值。最后對數(shù)值進行了(_RimPower / 10)次方,實際應(yīng)用時,依據(jù)效果調(diào)整_RimPower,使邊緣度更符合現(xiàn)實的情況。
首先需要計算出皮膚顏色(SkinColor)和 絲襪顏色(StockingColor),很簡單不多解釋。
float4 skinColor = tex2D(_SkinTex, IN.uv_SkinTex) * _SkinTint; float4 stockingColor = tex2D(_StockingTex, IN.uv_StockingTex) * _StockingTint;
依據(jù)疏密度對這兩個顏色進行簡單的混合,疏密度越高顯現(xiàn)更多絲襪顏色,越低則顯現(xiàn)皮膚顏色,很簡單的lerp即可。
lerp(skinColor, stockingColor, density);
Shader "Custom/Stocking" { Properties{ _Denier("Denier", Range(5,120)) = 25.0 _DenierTex("Density Texture", 2D) = "black"{} [Enum(Strong,6,Normal,12,Weak,20)] _RimPower("Rim Power", float) = 12 _SkinTint("Skin Color Tint", Color) = (1,0.9,0.8,1) _SkinTex("Skin Color", 2D) = "white" {} _StockingTint("Stocking Color Tint", Color) = (1,1,1,1) _StockingTex("Stocking Color", 2D) = "white"{} _NormalTex("Normal", 2D) = "bump"{} _Smoothness("Smoothness", Range(0,1)) = 0.1 } SubShader{ Tags{ "RenderType" = "Opaque" } CGPROGRAM #pragma surface surf Standard fullforwardshadows #pragma target 3.0 struct Input { float2 uv_SkinTex; float2 uv_StockingTex; float2 uv_DenierTex; float2 uv_NormalTex; float3 viewDir; }; float _RimPower; float _Denier; float _Smoothness; float4 _SkinTint; float4 _StockingTint; sampler2D _DenierTex; sampler2D _SkinTex; sampler2D _StockingTex; sampler2D _NormalTex; void surf(Input IN, inout SurfaceOutputStandard o) { o.Normal = UnpackNormal(tex2D(_NormalTex, IN.uv_NormalTex)); float4 skinColor = tex2D(_SkinTex, IN.uv_SkinTex) * _SkinTint; float4 stockingColor = tex2D(_StockingTex, IN.uv_StockingTex) * _StockingTint; float rim = pow(1 - dot(normalize(IN.viewDir), o.Normal), _RimPower / 10); float denier = (_Denier - 5) / 115; float density = max(rim, (denier * (1 - tex2D(_DenierTex, IN.uv_DenierTex)))); o.Albedo = lerp(skinColor, stockingColor, density); o.Metallic = 0; o.Smoothness = _Smoothness; } ENDCG } FallBack "Diffuse" }
SSSSS你可能不知道,但是SSS你應(yīng)該聽過,就是常說的3S材質(zhì)。這個是在Github上找到的,利用屏幕空間實現(xiàn)的SSS效果。
最后使用Unity官方的Post Processing Stack對畫面進行調(diào)整也必不可少的。
鏈接:
Custom Phase Screen-Space Subsurface Scattering
Post Processing Stack
感謝你能夠認真閱讀完這篇文章,希望小編分享的“Unity中如何實現(xiàn)仿真絲襪渲染”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!