# XDRender(Unity)_ObjPass_ShaderMode (1) ShaderMode结构组织

XDRender(Unity)_ObjPass_ShaderMode (1) ShaderMode结构组织

image-20201106180247957

image-20201106180345780

image-20201106180421226

image-20201106180501294

前言


这是属于XDRender_ObjPass_ShaderMode中 ----Unity部分

为何要组织ShaderMode? (这里ShaderMode不是SM2.0,3.0, 只是一个TID)这里是

1、因为能最大意义上的类型处理和统一,

2、能够方便去组织渲染的过程和CPU收集组织, 减少绘制的状态(数据)切换

3、能够为后续的迭代做好准备

正文

理论


实现


image-20201106183345313

第一步

先根据Path启动不同的宏,进入两个不同分支处理

这里注意一下如果能在屏幕(或者图像)空间下一次搞定, 我们当然可Switch语句

但奈何如果是逐个物体那就不太妙了, 即使我们用上PreCull但还是有很大的浪费.

Deffer分支

图像下(或者说Deffer下, 我们可以在物体部分就将TID存起来, 后面光照再做)

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分支

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);
}

第二步

组织FGLightMaterial

​ 这里我先把充分的都放进来, 但缺少必要性, 比如我们可以用一个hlaf4来组织语义

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;
};
实现填充DirectionLightMaterial

​ 这里具体,可以多做几个根据设计

void SetLightMatForShadingModel(half3 albedo, half metallic, half3 specular, half smoothness, half alpha, 
    half3 surfacecolor,
    half clearcoat,
    half clearcoatgloss,
    uint shadermodeid,
    out FLightMaterial outBRDFData)
实现填充GILightMaterial

​ 具体可以参考间接光部分

SetGIInputForShadingModel(half3 worldPos, half3 worldViewDir, half atten, half3 ambient,
    out GIInput outGI)
实现Forward或者Deffer的计算部分

​ 这里我先做Forward的计算光照部分,获取主光源数据,然后计算最后简单的加起来(手动滑稽, 其实这里还有一些工作要做的,特别是Transmission处理),原因是我们把一些计算都放到ShaderMode(有好处也有不好)

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;

未完先站, 去搬山了........

总结


备注

posted @ 2020-11-06 18:48  白袍小道  阅读(187)  评论(0编辑  收藏  举报

白袍小道 DaoZhang_XDZ@163.com - 创建于 8012

窥探道理