171 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			171 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| 
								 | 
							
								BasePassPixelShader.usf中的FPixelShaderInOut_MainPS(),为BasePass阶段Shader的主要逻辑。会被PixelShaderOutputCommon.usf的MainPS(),即PixelShader入口函数中被调用。
							 | 
						|||
| 
								 | 
							
								该阶段会取得材质编辑器各个引脚的计算结果,在一些计算下最终输出GBuffer,以备后续光照计算。可以认为是“紧接”材质编辑器的下一步工作。相关的c++逻辑位于FDeferredShadingSceneRenderer::Render()的RenderBasePass()中。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								但因为个人能力与时间所限,只能写一篇杂乱笔记作为记录,以供后续使用。
							 | 
						|||
| 
								 | 
							
								<!--more-->
							 | 
						|||
| 
								 | 
							
								### 780~889:计算变量并且填充FMaterialPixelParameters MaterialParameters。BaseColor、Metallic、Specular就位于867~877。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								### 915~1072:计算GBuffer或者DBuffer
							 | 
						|||
| 
								 | 
							
								- 915~942:计算贴花相关的DBuffer
							 | 
						|||
| 
								 | 
							
								- 954~1028:按照ShaderModel来填充GBuffer。(983~1008 Velocity、1013~1022 使用法线来调整粗糙度,在皮肤以及车漆ShaderModel中有用到)
							 | 
						|||
| 
								 | 
							
								- 1041:GBuffer.DiffuseColor = BaseColor - BaseColor * Metallic;
							 | 
						|||
| 
								 | 
							
								- 1059~1072:使用法线(清漆ShaderModel还会计算的底层法线)计算BentNormal以及GBufferAO。(使用SphericalGaussian)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								### 1081~1146:
							 | 
						|||
| 
								 | 
							
								#### 1086~1116:计算DiffuseColorForIndirect
							 | 
						|||
| 
								 | 
							
								DiffuseColorForIndirect(DiffuseDir只在Hair中计算)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								- 次表面与皮肤:DiffuseColorForIndirect += SubsurfaceColor;
							 | 
						|||
| 
								 | 
							
								- 布料:DiffuseColorForIndirect += SubsurfaceColor * saturate(GetMaterialCustomData0(MaterialParameters));
							 | 
						|||
| 
								 | 
							
								- 头发:DiffuseColorForIndirect = 2*PI * HairShading( GBuffer, L, V, N, 1, TransmittanceData, 0, 0.2, uint2(0,0);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#### 1118~1120:计算预间接光照结果
							 | 
						|||
| 
								 | 
							
								GetPrecomputedIndirectLightingAndSkyLight:
							 | 
						|||
| 
								 | 
							
								采样对应的预结算缓存:
							 | 
						|||
| 
								 | 
							
								1. PRECOMPUTED_IRRADIANCE_VOLUME_LIGHTING:根据TRANSLUCENCY_LIGHTING_VOLUMETRIC_PERVERTEX_NONDIRECTIONAL来判断是进行读取顶点AO值还是采样体积关照贴图来作为IrradianceSH的值。最后累加到OutDiffuseLighting上。
							 | 
						|||
| 
								 | 
							
								2. CACHED_VOLUME_INDIRECT_LIGHTING:采样IndirectLightingCache,最后累加到最后累加到OutDiffuseLighting上。
							 | 
						|||
| 
								 | 
							
								3. 采样HQ_TEXTURE_LIGHTMAP或者LQ_TEXTURE_LIGHTMAP,最后累加到OutDiffuseLighting上。
							 | 
						|||
| 
								 | 
							
								   
							 | 
						|||
| 
								 | 
							
								调用GetSkyLighting()取得天光值并累加到OutDiffuseLighting上。最后计算OutDiffuseLighting的亮度值最后作为OutIndirectIrradiance输出。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#### 1138:计算DiffuseColor
							 | 
						|||
| 
								 | 
							
								DiffuseColor=Diffuse间接照明 * Diffse颜色 + 次表面间接光照 * 次表面颜色+AO
							 | 
						|||
| 
								 | 
							
								```c#
							 | 
						|||
| 
								 | 
							
								DiffuseColor += (DiffuseIndirectLighting * DiffuseColorForIndirect + SubsurfaceIndirectLighting * SubsurfaceColor) * AOMultiBounce( GBuffer.BaseColor, DiffOcclusion );
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								#### 1140~1146:SingleLayerWater 覆盖颜色操作
							 | 
						|||
| 
								 | 
							
								```c#
							 | 
						|||
| 
								 | 
							
								GBuffer.DiffuseColor *= BaseMaterialCoverageOverWater;
							 | 
						|||
| 
								 | 
							
								DiffuseColor *= BaseMaterialCoverageOverWater;
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								### 1148~1211
							 | 
						|||
| 
								 | 
							
								1. 使用ForwardDirectLighting的DiffuseLighting与SpecularLighting累加,Color,THIN_TRANSLUCENT Model则为 DiffuseColor与ColorSeparateSpecular。
							 | 
						|||
| 
								 | 
							
								2. SIMPLE_FORWARD_DIRECTIONAL_LIGHT:调用GetSimpleForwardLightingDirectionalLight()计算方向光结果。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								根据光照模式累加,最后累加到Color上:
							 | 
						|||
| 
								 | 
							
								```c#
							 | 
						|||
| 
								 | 
							
								#if STATICLIGHTING_SIGNEDDISTANCEFIELD
							 | 
						|||
| 
								 | 
							
								    DirectionalLighting *= GBuffer.PrecomputedShadowFactors.x;
							 | 
						|||
| 
								 | 
							
								#elif PRECOMPUTED_IRRADIANCE_VOLUME_LIGHTING
							 | 
						|||
| 
								 | 
							
								    DirectionalLighting *= GetVolumetricLightmapDirectionalLightShadowing(VolumetricLightmapBrickTextureUVs);
							 | 
						|||
| 
								 | 
							
								#elif CACHED_POINT_INDIRECT_LIGHTING
							 | 
						|||
| 
								 | 
							
								    DirectionalLighting *= IndirectLightingCache.DirectionalLightShadowing;
							 | 
						|||
| 
								 | 
							
								#endif
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    Color += DirectionalLighting;
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								```c#
							 | 
						|||
| 
								 | 
							
								float3 GetSimpleForwardLightingDirectionalLight(FGBufferData GBuffer, float3 DiffuseColor, float3 SpecularColor, float Roughness, float3 WorldNormal, float3 CameraVector)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									float3 V = -CameraVector;
							 | 
						|||
| 
								 | 
							
									float3 N = WorldNormal;
							 | 
						|||
| 
								 | 
							
									float3 L = ResolvedView.DirectionalLightDirection;
							 | 
						|||
| 
								 | 
							
									float NoL = saturate( dot( N, L ) );
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									float3 LightColor = ResolvedView.DirectionalLightColor.rgb * PI;
							 | 
						|||
| 
								 | 
							
									
							 | 
						|||
| 
								 | 
							
									FShadowTerms Shadow = { 1, 1, 1, InitHairTransmittanceData() };
							 | 
						|||
| 
								 | 
							
									FDirectLighting Lighting = EvaluateBxDF( GBuffer, N, V, L, NoL, Shadow );
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									// Not computing specular, material was forced fully rough
							 | 
						|||
| 
								 | 
							
									return LightColor * (Lighting.Diffuse + Lighting.Transmission);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								### 1213~1273:渲染雾效果
							 | 
						|||
| 
								 | 
							
								包括VertexFog、PixelFog、体积雾,以及体积光效果(lit translucency)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								体积雾只要使用View.VolumetricFogGridZParams中的值计算UV,调用Texture3DSampleLevel采样FogStruct.IntegratedLightScattering,最后的值为float4(VolumetricFogLookup.rgb + GlobalFog.rgb * VolumetricFogLookup.a, VolumetricFogLookup.a * GlobalFog.a);。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								### 1283~1310:取得材质中自发光值得计算结果并且累加到Color上
							 | 
						|||
| 
								 | 
							
								```c#
							 | 
						|||
| 
								 | 
							
								half3 Emissive = GetMaterialEmissive(PixelMaterialInputs);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#if !POST_PROCESS_SUBSURFACE && !MATERIAL_SHADINGMODEL_THIN_TRANSLUCENT
							 | 
						|||
| 
								 | 
							
								 	// For skin we need to keep them separate. We also keep them separate for thin translucent.
							 | 
						|||
| 
								 | 
							
									// Otherwise just add them together.
							 | 
						|||
| 
								 | 
							
									Color += DiffuseColor;
							 | 
						|||
| 
								 | 
							
								#endif
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#if !MATERIAL_SHADINGMODEL_THIN_TRANSLUCENT
							 | 
						|||
| 
								 | 
							
									Color += Emissive;
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								### 1312~1349:SingleLayerWater光照计算
							 | 
						|||
| 
								 | 
							
								计算SunIlluminance、WaterDiffuseIndirectIlluminance、Normal、ViewVector、EnvBrdf(预积分G F * 高光颜色,位于BRDF.ush)后根据设置采用对应的方式(前向渲染与延迟渲染方式)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								```c#
							 | 
						|||
| 
								 | 
							
								const float3 SunIlluminance = ResolvedView.DirectionalLightColor.rgb * PI;	// times PI because it is divided by PI on CPU (=luminance) and we want illuminance here. 
							 | 
						|||
| 
								 | 
							
								const float3 WaterDiffuseIndirectIlluminance = DiffuseIndirectLighting * PI;// DiffuseIndirectLighting is luminance. So we need to multiply by PI to get illuminance.
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								### 1352~1372:超薄透明物体光照计算
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								### 1375~1529:GBuffer相关
							 | 
						|||
| 
								 | 
							
								1. BlendMode处理
							 | 
						|||
| 
								 | 
							
								2. GBuffer.IndirectIrradiance = IndirectIrradiance;
							 | 
						|||
| 
								 | 
							
								3. 调用LightAccumulator_Add()累加关照对BaseColor的影响。Out.MRT[0]=FLightAccumulator.TotalLight
							 | 
						|||
| 
								 | 
							
								4. 调用EncodeGBuffer(),填充GBuffer12345数据。
							 | 
						|||
| 
								 | 
							
								5. Out.MRT[4] = OutVelocity;
							 | 
						|||
| 
								 | 
							
								6. Out.MRT[GBUFFER_HAS_VELOCITY ? 5 : 4] = OutGBufferD;
							 | 
						|||
| 
								 | 
							
								7. Out.MRT[GBUFFER_HAS_VELOCITY ? 6 : 5] = OutGBufferE;
							 | 
						|||
| 
								 | 
							
								8. Out.MRT[0].rgb  *= ViewPreExposure;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								### 1553:FinalizeVirtualTextureFeedback
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								# UE5
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## Lumen相关
							 | 
						|||
| 
								 | 
							
								- GetSkyLighting()
							 | 
						|||
| 
								 | 
							
									- Lumen
							 | 
						|||
| 
								 | 
							
										- GetTranslucencyGIVolumeLighting()
							 | 
						|||
| 
								 | 
							
									- SkyLighting
							 | 
						|||
| 
								 | 
							
										- GetEffectiveSkySHDiffuse()
							 | 
						|||
| 
								 | 
							
											- GetVolumetricLightmapSkyBentNormal()
							 | 
						|||
| 
								 | 
							
											- GetSkyBentNormalAndOcclusion()
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								**GetSkyLighting()** 演示了采样SkyLight与Lumen的方法。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								### SkyLighting
							 | 
						|||
| 
								 | 
							
								GetEffectiveSkySHDiffuse()是一个宏,会根据平台指向下面2个函数:
							 | 
						|||
| 
								 | 
							
								```c++
							 | 
						|||
| 
								 | 
							
								/**   
							 | 
						|||
| 
								 | 
							
								 * Computes sky diffuse lighting from the SH irradiance map.    
							 | 
						|||
| 
								 | 
							
								 * This has the SH basis evaluation and diffuse convolution weights combined for minimal ALU's - see "Stupid Spherical Harmonics (SH) Tricks"   
							 | 
						|||
| 
								 | 
							
								 */  
							 | 
						|||
| 
								 | 
							
								float3 GetSkySHDiffuse(float3 Normal)  
							 | 
						|||
| 
								 | 
							
								{  
							 | 
						|||
| 
								 | 
							
								    float4 NormalVector = float4(Normal, 1.0f);   
							 | 
						|||
| 
								 | 
							
								    float3 Intermediate0, Intermediate1, Intermediate2;  
							 | 
						|||
| 
								 | 
							
								    Intermediate0.x = dot(SkyIrradianceEnvironmentMap[0], NormalVector);  
							 | 
						|||
| 
								 | 
							
								    Intermediate0.y = dot(SkyIrradianceEnvironmentMap[1], NormalVector);  
							 | 
						|||
| 
								 | 
							
								    Intermediate0.z = dot(SkyIrradianceEnvironmentMap[2], NormalVector);  
							 | 
						|||
| 
								 | 
							
								  
							 | 
						|||
| 
								 | 
							
								    float4 vB = NormalVector.xyzz * NormalVector.yzzx;  
							 | 
						|||
| 
								 | 
							
								    Intermediate1.x = dot(SkyIrradianceEnvironmentMap[3], vB);  
							 | 
						|||
| 
								 | 
							
								    Intermediate1.y = dot(SkyIrradianceEnvironmentMap[4], vB);  
							 | 
						|||
| 
								 | 
							
								    Intermediate1.z = dot(SkyIrradianceEnvironmentMap[5], vB);  
							 | 
						|||
| 
								 | 
							
								  
							 | 
						|||
| 
								 | 
							
								    float vC = NormalVector.x * NormalVector.x - NormalVector.y * NormalVector.y;  
							 | 
						|||
| 
								 | 
							
								    Intermediate2 = SkyIrradianceEnvironmentMap[6].xyz * vC;  
							 | 
						|||
| 
								 | 
							
								  
							 | 
						|||
| 
								 | 
							
								    // max to not get negative colors  
							 | 
						|||
| 
								 | 
							
								    return max(0, Intermediate0 + Intermediate1 + Intermediate2);  
							 | 
						|||
| 
								 | 
							
								}  
							 | 
						|||
| 
								 | 
							
								  
							 | 
						|||
| 
								 | 
							
								/**  
							 | 
						|||
| 
								 | 
							
								* Computes sky diffuse lighting from the SH irradiance map.  
							 | 
						|||
| 
								 | 
							
								* This has the SH basis evaluation and diffuse convolution weights combined for minimal ALU's - see "Stupid Spherical Harmonics (SH) Tricks"  
							 | 
						|||
| 
								 | 
							
								* Only does the first 3 components for speed.  
							 | 
						|||
| 
								 | 
							
								*/  
							 | 
						|||
| 
								 | 
							
								float3 GetSkySHDiffuseSimple(float3 Normal)  
							 | 
						|||
| 
								 | 
							
								{  
							 | 
						|||
| 
								 | 
							
								    float4 NormalVector = float4(Normal, 1);  
							 | 
						|||
| 
								 | 
							
								  
							 | 
						|||
| 
								 | 
							
								    float3 Intermediate0;  
							 | 
						|||
| 
								 | 
							
								    Intermediate0.x = dot(SkyIrradianceEnvironmentMap[0], NormalVector);  
							 | 
						|||
| 
								 | 
							
								    Intermediate0.y = dot(SkyIrradianceEnvironmentMap[1], NormalVector);  
							 | 
						|||
| 
								 | 
							
								    Intermediate0.z = dot(SkyIrradianceEnvironmentMap[2], NormalVector);        
							 | 
						|||
| 
								 | 
							
								    // max to not get negative colors  
							 | 
						|||
| 
								 | 
							
								    return max(0, Intermediate0);  
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								```
							 |