unity里standard pbr(一)


關注forwardbase下的

standard.shader

#pragma vertex vertBase
#pragma fragment fragBase
#include "UnityStandardCoreForward.cginc"

跟蹤到UnityStandardCoreForward.cginc

#if UNITY_STANDARD_SIMPLE
#include "UnityStandardCoreForwardSimple.cginc"
VertexOutputBaseSimple vertBase (VertexInput v) { return vertForwardBaseSimple(v); }
VertexOutputForwardAddSimple vertAdd (VertexInput v) { return vertForwardAddSimple(v); }
half4 fragBase (VertexOutputBaseSimple i) : SV_Target { return fragForwardBaseSimpleInternal(i); }
half4 fragAdd (VertexOutputForwardAddSimple i) : SV_Target { return fragForwardAddSimpleInternal(i); }
#else
#include "UnityStandardCore.cginc"
VertexOutputForwardBase vertBase (VertexInput v) { return vertForwardBase(v); }
VertexOutputForwardAdd vertAdd (VertexInput v) { return vertForwardAdd(v); }
half4 fragBase (VertexOutputForwardBase i) : SV_Target { return fragForwardBaseInternal(i); }
half4 fragAdd (VertexOutputForwardAdd i) : SV_Target { return fragForwardAddInternal(i); }
#endif

 

UNITY_STANDARD_SIMPLE開關是簡化版意思,進下邊的分支

頂點着色器 vertForwardBase

先看輸出

struct VertexOutputForwardBase
{
    float4 pos                          : SV_POSITION;
    float4 tex                          : TEXCOORD0;
    half3 eyeVec                        : TEXCOORD1;
    half4 tangentToWorldAndParallax[3]  : TEXCOORD2;    // [3x3:tangentToWorld | 1x3:viewDirForParallax]
    half4 ambientOrLightmapUV           : TEXCOORD5;    // SH or Lightmap UV
    SHADOW_COORDS(6)
    UNITY_FOG_COORDS(7)

    // next ones would not fit into SM2.0 limits, but they are always for SM3.0+
    #if UNITY_REQUIRE_FRAG_WORLDPOS
        float3 posWorld                 : TEXCOORD8;
    #endif

    #if UNITY_OPTIMIZE_TEXCUBELOD
        #if UNITY_REQUIRE_FRAG_WORLDPOS
            half3 reflUVW               : TEXCOORD9;
        #else
            half3 reflUVW               : TEXCOORD8;
        #endif
    #endif

    UNITY_VERTEX_OUTPUT_STEREO
};
UNITY_REQUIRE_FRAG_WORLDPOS要不要worldpos,要
reflUVW是用來做反射的,要
UNITY_VERTEX_OUTPUT_STEREO 是用來做實例化的,不要
簡化成

struct VertexOutputForwardBase
{
    float4 pos                          : SV_POSITION;
    float4 tex                          : TEXCOORD0;
    half3 eyeVec                        : TEXCOORD1;
    half4 tangentToWorldAndParallax[3]  : TEXCOORD2;    // [3x3:tangentToWorld | 1x3:viewDirForParallax]
    half4 ambientOrLightmapUV           : TEXCOORD5;    // SH or Lightmap UV
    SHADOW_COORDS(6)
    UNITY_FOG_COORDS(7)
    float3 posWorld                     : TEXCOORD8;
    half3 reflUVW                       : TEXCOORD9;
};
再來看頂點着色器
VertexOutputForwardBase vertForwardBase (VertexInput v)
{
    VertexOutputForwardBase o;
    UNITY_SETUP_INSTANCE_ID(v);
    UNITY_INITIALIZE_OUTPUT(VertexOutputForwardBase, o);
    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

    float4 posWorld = mul(unity_ObjectToWorld, v.vertex);
    #if UNITY_REQUIRE_FRAG_WORLDPOS
        o.posWorld = posWorld.xyz;
    #endif
    o.pos = UnityObjectToClipPos(v.vertex);

    o.tex = TexCoords(v);
    o.eyeVec = NormalizePerVertexNormal(posWorld.xyz - _WorldSpaceCameraPos);
    float3 normalWorld = UnityObjectToWorldNormal(v.normal);
    #ifdef _TANGENT_TO_WORLD
        float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);

        float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w);
        o.tangentToWorldAndParallax[0].xyz = tangentToWorld[0];
        o.tangentToWorldAndParallax[1].xyz = tangentToWorld[1];
        o.tangentToWorldAndParallax[2].xyz = tangentToWorld[2];
    #else
        o.tangentToWorldAndParallax[0].xyz = 0;
        o.tangentToWorldAndParallax[1].xyz = 0;
        o.tangentToWorldAndParallax[2].xyz = normalWorld;
    #endif
    //We need this for shadow receving
    TRANSFER_SHADOW(o);

    o.ambientOrLightmapUV = VertexGIForward(v, posWorld, normalWorld);

    #ifdef _PARALLAXMAP
        TANGENT_SPACE_ROTATION;
        half3 viewDirForParallax = mul (rotation, ObjSpaceViewDir(v.vertex));
        o.tangentToWorldAndParallax[0].w = viewDirForParallax.x;
        o.tangentToWorldAndParallax[1].w = viewDirForParallax.y;
        o.tangentToWorldAndParallax[2].w = viewDirForParallax.z;
    #endif

    #if UNITY_OPTIMIZE_TEXCUBELOD
        o.reflUVW       = reflect(o.eyeVec, normalWorld);
    #endif

    UNITY_TRANSFER_FOG(o,o.pos);
    return o;
}

 

UNITY_SETUP_INSTANCE_ID是instance用的,不要
UNITY_INITIALIZE_OUTPUT啥也沒干,不要
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO不要
NormalizePerVertexNormal相等於什么都沒做
_TANGENT_TO_WORLD是切線空間和世界空間轉換矩陣 保留
o.ambientOrLightmapUV = VertexGIForward(v, posWorld, normalWorld);
因為打算用pbr來做角色,沒有lightmap,所以這兒等於

 

o.ambientOrLightmapUV = 0 ;
_PARALLAXMAP視差貼圖,不用
去掉分支后代碼如下

VertexOutputForwardBase vertForwardBase (VertexInput v)
{
    VertexOutputForwardBase o;
    float4 posWorld = mul(unity_ObjectToWorld, v.vertex);
    o.posWorld = posWorld.xyz;
    o.pos = UnityObjectToClipPos(v.vertex);
    o.tex = TexCoords(v);
    o.eyeVec = NormalizePerVertexNormal(posWorld.xyz - _WorldSpaceCameraPos);
    float3 normalWorld = UnityObjectToWorldNormal(v.normal);
	float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);

	float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w);
	o.tangentToWorldAndParallax[0].xyz = tangentToWorld[0];
	o.tangentToWorldAndParallax[1].xyz = tangentToWorld[1];
	o.tangentToWorldAndParallax[2].xyz = tangentToWorld[2];
    //We need this for shadow receving
    TRANSFER_SHADOW(o);
    o.ambientOrLightmapUV = 0;
	o.reflUVW       = reflect(o.eyeVec, normalWorld);
    UNITY_TRANSFER_FOG(o,o.pos);
    return o;
}

 至此頂點着色器完事,下篇開始像素着色器

 
 
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM