XDRender(Unity)_ObjPass_ShaderMode (1) ShaderMode结构组织
目录
前言
这是属于XDRender_ObjPass_ShaderMode中 ----Unity部分
为何要组织ShaderMode? (这里ShaderMode不是SM2.0,3.0, 只是一个TID)这里是
1、因为能最大意义上的类型处理和统一,
2、能够方便去组织渲染的过程和CPU收集组织, 减少绘制的状态(数据)切换
3、能够为后续的迭代做好准备
正文
理论
实现
第一步
先根据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;
未完先站, 去搬山了........