XDRender(Unity)_ObjPass_ShaderMode (1) ShaderMode structure organization
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