溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

ShaderLab學(xué)習(xí)小結(jié)(十五)法線貼圖的簡(jiǎn)單Shader

發(fā)布時(shí)間:2020-06-12 08:51:57 來源:網(wǎng)絡(luò) 閱讀:6503 作者:lreach 欄目:游戲開發(fā)

目標(biāo):賦予材質(zhì)法線貼圖,并能響應(yīng)光照的變化,體現(xiàn)出凹凸感。
場(chǎng)景中只有一個(gè)主平行光
找了一張法線貼圖(網(wǎng)上蕩的)
ShaderLab學(xué)習(xí)小結(jié)(十五)法線貼圖的簡(jiǎn)單Shader
在unity里別忘了把這張圖設(shè)為normalmap
ShaderLab學(xué)習(xí)小結(jié)(十五)法線貼圖的簡(jiǎn)單Shader
先看一下,如果只是作為普通貼圖,賦在Diffuse材質(zhì)上是啥效果
ShaderLab學(xué)習(xí)小結(jié)(十五)法線貼圖的簡(jiǎn)單Shader
ShaderLab學(xué)習(xí)小結(jié)(十五)法線貼圖的簡(jiǎn)單Shader
轉(zhuǎn)動(dòng)平行光,看看有啥變化
ShaderLab學(xué)習(xí)小結(jié)(十五)法線貼圖的簡(jiǎn)單Shader
如上圖,只是普通的貼圖,隨著平行光的轉(zhuǎn)動(dòng)全體變暗變亮,沒有凹凸可言,平面就是平面
那就要編個(gè)shader來實(shí)現(xiàn)這張法線貼圖的價(jià)值了

Shader "Custom/TestBumpShader" {
    Properties {
        _NormalMap("Bump", 2D)=""{}      //1.
    }
    SubShader {
        pass{
            Tags{"LightMode"="ForwardBase"}     //2.
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "unitycg.cginc"
            #include "lighting.cginc"
            sampler2D _NormalMap;
            struct v2f{                                        //3.
                float4 pos:POSITION;
                float2 uv:TEXCOORD0;
                float3 lightdir:TEXCOORD1;
                float3 wpos:TEXCOORD2;
            };
            v2f vert(appdata_tan v)
            {
                v2f o;
                o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
                o.wpos=mul(unity_ObjectToWorld, v.vertex).xyz;
                o.uv=v.texcoord.xy;

                //4.
                TANGENT_SPACE_ROTATION;
                float3 objLight=ObjSpaceLightDir(v.vertex);
                o.lightdir=mul(rotation,objLight);
                return o;
            }
            fixed4 frag(v2f IN):COLOR
            {
                float3 N =normalize(UnpackNormal(tex2D(_NormalMap,IN.uv)));   //5.
                float3 L = normalize(IN.lightdir);
                float ndotl=saturate(dot(N,L));
                fixed4 col = _LightColor0*ndotl;

                col+=UNITY_LIGHTMODEL_AMBIENT;
                return col;
            }
            ENDCG
        }
    }
}

按照代碼里的注釋位置

1

_NormalMap("Bump", 2D)=""{}      //1.

定義一個(gè)貼圖,當(dāng)然,下面的CG程序中要聲明一下

2

法線貼圖就必然涉及到光照,還是用forwardbase吧

3

struct v2f{                                        //3.
                float4 pos:POSITION;
                float2 uv:TEXCOORD0;
                float3 lightdir:TEXCOORD1;
                float3 wpos:TEXCOORD2;
            };

結(jié)構(gòu)體中定義一個(gè)uv對(duì)應(yīng)紋理,一個(gè)lightdir是光照方向,一個(gè)wpos是世界坐標(biāo)

4

世界坐標(biāo)的計(jì)算和uv值的獲取就不說了,以前有,代碼里也有
為了使法線貼圖產(chǎn)生作用,要在切線空間中進(jìn)行計(jì)算,這里要把光照向量L轉(zhuǎn)到切線空間

TANGENT_SPACE_ROTATION;
float3 objLight=ObjSpaceLightDir(v.vertex);
o.lightdir=mul(rotation,objLight);

這里的TANGENT_SPACE_ROTATION定義在unitycg.cginc中

// Declares 3x3 matrix 'rotation', filled with tangent space basis
#define TANGENT_SPACE_ROTATION \
    float3 binormal = cross( normalize(v.normal), normalize(v.tangent.xyz) ) * v.tangent.w; \
    float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal )

所以前面忘說的一點(diǎn)就是vert函數(shù)的參數(shù)不用appdata_base了,而改用appdata_tan,因?yàn)門ANGENT_SPACE_ROTATION中用到了v.tangent,這個(gè)在appdata_base中是沒有的。
然后用這里的這個(gè)rotation去變換模型坐標(biāo)空間中的光照方向,將其變換到切線空間中,得到我們要用的光照向量

5

float3 N =normalize(UnpackNormal(tex2D(_NormalMap,IN.uv)));   //5.

這里要用unpacknormal函數(shù)來通過法線貼圖計(jì)算法線,而不是根據(jù)物體的坐標(biāo)值計(jì)算
這個(gè)UnpackNormal也是定義在unitycg.cginc中
看到網(wǎng)上有人的解釋:

//將材質(zhì)貼圖對(duì)應(yīng)的法線 繪制在一張貼圖上
//將貼圖對(duì)應(yīng)點(diǎn)的單位法線向量信息float3(x,y,z) 儲(chǔ)存在圖對(duì)應(yīng)的顏色里color(r,g,b)里
//其中x,y,z分別對(duì)應(yīng)r,g,b
//單位法線向量 float3(x,y,z),x,y,z的取值范圍是 [-1,1]
//在法線貼圖中被壓縮在顏色的范圍[0,1]中,所以需要轉(zhuǎn)換

原因我也不太明,還在學(xué)習(xí)中,反正先當(dāng)固定用法記吧
再用這個(gè)處理后的法線向量和光向量進(jìn)行漫反射計(jì)算就得出最終顏色。
我們看下效果:
ShaderLab學(xué)習(xí)小結(jié)(十五)法線貼圖的簡(jiǎn)單Shader
可以看到明暗變化顯出凹凸,而不是平面了,其實(shí)模型還是平面,這就是視覺欺騙吧。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI