# XDRender(Unity)_ ObjPass_ Shadermode shadermode structure organization

XDRender(Unity)_ObjPass_ShaderMode (1) ShaderMode structure organization

catalogue

preface

This belongs to xdrender_ ObjPass_ In shadermode - Unity

Why organize ShaderMode? (ShaderMode here is not SM2.0,3.0, but a TID)

1. Because it can handle and unify types in the greatest sense,

2. It is convenient to organize the rendering process and CPU collection, and reduce the state (data) switching of rendering

3. Be able to prepare for subsequent iterations

text

theory

realization

First step

Start different macros according to Path and enter two different branches for processing

Note here that if it can be done next time in the screen (or image) space, we can of course use the Switch statement

However, it's not very good if it's object by object. Even if we use PreCull, there's still a lot of waste

Deffer branch

Under the image (or Deffer, we can save TID in the object part and do it later in the light)

FDirectLightingResult IntegrateBxDFGBuffer(
    FLightMaterial pGLightBuffer
    ,float3 lightColor
    ,float3 normal,float3 lightDir,float3 viewDir
    )
{
    switch(pGLightBuffer.shaderModeId)
    {
        case SHADINGMODELID_UNLIT:
            return UnitBxDF(pGLightBuffer,lightColor,normal,lightDir,viewDir);
        case SHADINGMODELID_LAMBERT:
            return LambertBxDF(pGLightBuffer,lightColor,normal,lightDir,viewDir);
        case SHADINGMODELID_BLINPHONE:
            return BlinPhoneBxDF(pGLightBuffer,lightColor,normal,lightDir,viewDir);
        case SHADINGMODELID_PHONE:
            return PhoneBxDF(pGLightBuffer,lightColor,normal,lightDir,viewDir);
        case SHADINGMODELID_DEFAULT_LIT:
            return DefaultLitBxDF(pGLightBuffer,lightColor,normal,lightDir,viewDir);
        case SHADINGMODELID_CLEAR_COAT:
            return DefaultClearCostBxDF(pGLightBuffer,lightColor,normal,lightDir,viewDir);
        case SHADINGMODELID_SUBSURFACE_PROFILE:
            return DefaultSubsurfaceProfileBxDF(pGLightBuffer,lightColor,normal,lightDir,viewDir);
        default:
            return UnitBxDF(pGLightBuffer,lightColor,normal,lightDir,viewDir);
    }
    return UnitBxDF(pGLightBuffer,lightColor,normal,lightDir,viewDir);
}

Forward branch
FDirectLightingResult IntegrateBxDF_FORWARD(
    FLightMaterial pGLightBuffer
    ,float3 lightColor
    ,float3 normal,float3 lightDir,float3 viewDir
    )
{
    //return DefaultLitBxDF(pGLightBuffer,lightColor,normal,lightDir,viewDir);
    #if   _SHADERMODE_UNLIT
            return UnitBxDF(pGLightBuffer,lightColor,normal,lightDir,viewDir);
    #elif _SHADERMODE_LAMBER
            return LambertBxDF(pGLightBuffer,lightColor,normal,lightDir,viewDir);
    #elif _SHADERMODE_BLINPHONE
            return BlinPhoneBxDF(pGLightBuffer,lightColor,normal,lightDir,viewDir);
    #elif _SHADERMODE_PHONE
            return PhoneBxDF(pGLightBuffer,lightColor,normal,lightDir,viewDir);
    #elif _SHADERMODE_DEFAULTLIT
            return DefaultLitBxDF(pGLightBuffer,lightColor,normal,lightDir,viewDir);
    #elif _SHADERMODE_CLEARCOAT
            return DefaultClearCostBxDF(pGLightBuffer,lightColor,normal,lightDir,viewDir);
    #elif _SHADERMODE_SUBSURFACEPROFILE
            return DefaultSubsurfaceProfileBxDF(pGLightBuffer,lightColor,normal,lightDir,viewDir);
    #endif

    return UnitBxDF(pGLightBuffer,lightColor,normal,lightDir,viewDir);
    //return UnitBxDF(pGLightBuffer,lightColor,normal,lightDir,viewDir);
}

Step two

Organize FGLightMaterial

​ Here, I'll put in all the sufficient, but it's not necessary. For example, we can use an hlaf4 to organize semantics

struct FLightMaterial
{
    half3   diffuse;
    half3   specular;
    half    metallic;
    half    perceptualRoughness;
    half    roughness;
    half    roughness2;
    half    lerpRoughness;
    half    clearcoat;
    half    clearcoatgloss;
    half3   surfacecolor;
    half    grazing;
    uint    shaderModeId;
    half    alpha;
};
Realize the filling of DirectionLightMaterial

​ Here, we can do more according to the design

void SetLightMatForShadingModel(half3 albedo, half metallic, half3 specular, half smoothness, half alpha, 
    half3 surfacecolor,
    half clearcoat,
    half clearcoatgloss,
    uint shadermodeid,
    out FLightMaterial outBRDFData)
Implement filling GILightMaterial

​ Refer to the indirect light part for details

SetGIInputForShadingModel(half3 worldPos, half3 worldViewDir, half atten, half3 ambient,
    out GIInput outGI)
Implement the calculation part of Forward or Deffer

​ Here, I first do the Forward calculation lighting part, obtain the main light source data, and then calculate it. Finally, I simply add it up (manual funny. In fact, there is still some work to be done here, especially the Transmission processing). The reason is that we put some calculations into shadermode (both good and bad)

vLight = GetMainLight ();
            lightDir= normalize(vLight.direction).xyz;
            lightColor= vLight.color * (1-vLight.distanceAttenuation);
            
            FDirectLightingResult r =  IntegrateBxDF_FORWARD(GBuffer,lightColor,normal,lightDir,viewDir);;
            DirectLightResult += r.Diffuse + r.Specular + r.Transmission;

Stop before you finish, go to move the mountain

summary

remarks

Posted by lrdaramis on Sun, 08 May 2022 13:18:20 +0300