170 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			170 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| 
								 | 
							
								## 描边
							 | 
						|||
| 
								 | 
							
								- RenderToonOutlineToBaseColor
							 | 
						|||
| 
								 | 
							
								- RenderToonOutlineToSceneColor
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								相关Shader:
							 | 
						|||
| 
								 | 
							
								- ToonDataPassShader.usf
							 | 
						|||
| 
								 | 
							
								- ToonOutline.usf
							 | 
						|||
| 
								 | 
							
								- ToonShadingModel.ush
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								相关RT
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								//Begin YivanLee's Modify
							 | 
						|||
| 
								 | 
							
								TRefCountPtr<IPooledRenderTarget> SceneColorCopy;
							 | 
						|||
| 
								 | 
							
								TRefCountPtr<IPooledRenderTarget> BaseColorCopy;
							 | 
						|||
| 
								 | 
							
								TRefCountPtr<IPooledRenderTarget> ToonBufferDepth;
							 | 
						|||
| 
								 | 
							
								TRefCountPtr<IPooledRenderTarget> ToonOutlineTexture;
							 | 
						|||
| 
								 | 
							
								TRefCountPtr<IPooledRenderTarget> ToonOutlineMaskBlurTexture;
							 | 
						|||
| 
								 | 
							
								TRefCountPtr<IPooledRenderTarget> ToonIDOutlineTexture;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								//ToonDataTexture01 is ToonNormal
							 | 
						|||
| 
								 | 
							
								TRefCountPtr<IPooledRenderTarget> ToonDataTexture01;
							 | 
						|||
| 
								 | 
							
								//ToonDataTexture02 is R: ShadowController G: B: A:
							 | 
						|||
| 
								 | 
							
								TRefCountPtr<IPooledRenderTarget> ToonDataTexture02;
							 | 
						|||
| 
								 | 
							
								//ToonDataTexture03 is OutlineColorMask and OutlineMask
							 | 
						|||
| 
								 | 
							
								TRefCountPtr<IPooledRenderTarget> ToonDataTexture03;
							 | 
						|||
| 
								 | 
							
								//ToonDataTexture04 is IDTexture
							 | 
						|||
| 
								 | 
							
								TRefCountPtr<IPooledRenderTarget> ToonDataTexture04;
							 | 
						|||
| 
								 | 
							
								//End YivanLee's Modify
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								### GBuffer
							 | 
						|||
| 
								 | 
							
								ToonData0 = float4(N * 0.5 + 0.5, 1.0f);//WorldNormal
							 | 
						|||
| 
								 | 
							
								ToonData1 = GetMaterialToonDataA(MaterialParameters);//Shadow controller
							 | 
						|||
| 
								 | 
							
								ToonData2 = GetMaterialToonDataB(MaterialParameters);//OutlinleColor,OutlineMask
							 | 
						|||
| 
								 | 
							
								ToonData3 = GetMaterialToonDataC(MaterialParameters);//IDTexture,OutlineWidth
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								### BasePass部分
							 | 
						|||
| 
								 | 
							
								位于FDeferredShadingSceneRenderer::RenderBasePass()最后,
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								if (ShouldRenderToonDataPass())
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									//Begin Recreate ToonData Render targets
							 | 
						|||
| 
								 | 
							
									SceneContext.ReleaseToonDataTarget();
							 | 
						|||
| 
								 | 
							
									SceneContext.AllocateToonDataTarget(GraphBuilder.RHICmdList);
							 | 
						|||
| 
								 | 
							
									SceneContext.ReleaseToonDataGBuffer();
							 | 
						|||
| 
								 | 
							
									SceneContext.AllocateToonDataGBuffer(GraphBuilder.RHICmdList);
							 | 
						|||
| 
								 | 
							
									//End Recreate ToonData Render targets
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									TStaticArray<FRDGTextureRef, MaxSimultaneousRenderTargets> ToonDataPassTextures;
							 | 
						|||
| 
								 | 
							
									uint32 ToonDataTextureCount = SceneContext.GetToonDataGBufferRenderTargets(GraphBuilder, ToonDataPassTextures);
							 | 
						|||
| 
								 | 
							
									TArrayView<FRDGTextureRef> ToonDataPassTexturesView = MakeArrayView(ToonDataPassTextures.GetData(), ToonDataTextureCount);
							 | 
						|||
| 
								 | 
							
									
							 | 
						|||
| 
								 | 
							
									ERenderTargetLoadAction ToonTargetsAction;
							 | 
						|||
| 
								 | 
							
									if (bEnableParallelBasePasses)//Windows DirectX12
							 | 
						|||
| 
								 | 
							
									{
							 | 
						|||
| 
								 | 
							
										ToonTargetsAction = ERenderTargetLoadAction::ELoad;
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									else//Windows DirectX11
							 | 
						|||
| 
								 | 
							
									{
							 | 
						|||
| 
								 | 
							
										ToonTargetsAction = ERenderTargetLoadAction::EClear;
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									FRenderTargetBindingSlots ToonDataPassRenderTargets = GetRenderTargetBindings(ToonTargetsAction, ToonDataPassTexturesView);
							 | 
						|||
| 
								 | 
							
									ToonDataPassRenderTargets.DepthStencil = FDepthStencilBinding(SceneDepthTexture, ERenderTargetLoadAction::ELoad, ERenderTargetLoadAction::ELoad, ExclusiveDepthStencil);
							 | 
						|||
| 
								 | 
							
									ToonDataPassRenderTargets.ShadingRateTexture = GVRSImageManager.GetVariableRateShadingImage(GraphBuilder, ViewFamily, nullptr, EVRSType::None);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									AddSetCurrentStatPass(GraphBuilder, GET_STATID(STAT_CLM_ToonDataPass));
							 | 
						|||
| 
								 | 
							
									RenderToonDataPass(GraphBuilder, ToonDataPassTextures, ToonDataTextureCount, ToonDataPassRenderTargets, bEnableParallelBasePasses);
							 | 
						|||
| 
								 | 
							
									AddSetCurrentStatPass(GraphBuilder, GET_STATID(STAT_CLM_AfterToonDataPass));
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									RenderToonOutlineToBaseColor(GraphBuilder, SceneDepthTexture, bEnableParallelBasePasses);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								#### RenderNormalDepthOutline
							 | 
						|||
| 
								 | 
							
								- ToonOutlineMain:使用拉普拉斯算子与Sobel算子计算并混合结果。计算Depth与Normal,最后Length(float4(Normal,Depth));
							 | 
						|||
| 
								 | 
							
								- ToonIDOutlinePSMain:使用Sobel计算描边。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#### RenderToonIDOutline
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#### CombineOutlineToBaseColor
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								### 渲染管线Render()
							 | 
						|||
| 
								 | 
							
								RenderToonOutlineToSceneColor()位于RenderLights()之后与RenderDeferredReflectionsAndSkyLighting()之前的位置。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## ShaderModel
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								### DefaultLitBxDF
							 | 
						|||
| 
								 | 
							
								```c#
							 | 
						|||
| 
								 | 
							
								Lighting.Diffuse  = AreaLight.FalloffColor * (Falloff * NoL) * Diffuse_Lambert( GBuffer.DiffuseColor );
							 | 
						|||
| 
								 | 
							
								Lighting.Specular = AreaLight.FalloffColor * (Falloff * NoL) * SpecularGGX(GBuffer.Roughness, GBuffer.SpecularColor, Context, NoL, AreaLight);
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								### Toon
							 | 
						|||
| 
								 | 
							
								- ToonDataA:R ShadowOffset   GBA 未使用
							 | 
						|||
| 
								 | 
							
								- ToonDataB:RGB OutlineColor A OutlineMask
							 | 
						|||
| 
								 | 
							
								- ToonDataC:RGB IDMap        A OutlineWidth 
							 | 
						|||
| 
								 | 
							
								- PreIntegratedToonBRDF: R 为NoL 预积分Ramp G 为GGX高光预积分值。
							 | 
						|||
| 
								 | 
							
								- PreIntegratedToonSkinBRDF:RGB为皮肤预积分颜色。
							 | 
						|||
| 
								 | 
							
								- SubsurfaceColor:该数据存放在CustomData.rgb位置,在天光计算中其作用
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								PS.ToonShadingStandard没有使用SubsurfaceColor。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#### ToonShadingStandard
							 | 
						|||
| 
								 | 
							
								在原始的PBR公式做了以下修改:
							 | 
						|||
| 
								 | 
							
								固有色部分
							 | 
						|||
| 
								 | 
							
								1. 使用ShadowOffset(ToonDataA.r)来控制阴影区域的偏移也就是类似UTS的Step。但使用lerp(Context.NoL, 1.0, ShadowOffset),这导致偏移并不易于控制。
							 | 
						|||
| 
								 | 
							
								2. 计算FallOffMask(预积分衰减调整系数)。使用ShadowOffset过的NoL与Metalic作为UV对PreIntegratedToonBRDF图进行查表,返回r值。
							 | 
						|||
| 
								 | 
							
								3. Lighting.Diffuse = AreaLight.FalloffColor * FallOffMask * GBuffer.BaseColor / 3.1415927f;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								高光部分
							 | 
						|||
| 
								 | 
							
								1. D(预积分GGX),使用NoH与Roughness作为UV对PreIntegratedToonBRDF进行查表,返回g值。
							 | 
						|||
| 
								 | 
							
								2. F(边缘光效果系数),return smoothstep(0.67, 1.0, 1 - NoV);
							 | 
						|||
| 
								 | 
							
								3. Lighting.Specular = (F + D) * (AreaLight.FalloffColor * GBuffer.SpecularColor * FallOffMask * 8);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								```c++
							 | 
						|||
| 
								 | 
							
								float ShadowOffset = GBuffer.ToonDataA.r;
							 | 
						|||
| 
								 | 
							
								float FallOffMask = Falloff * GetPreintegratedToonBRDF(lerp(Context.NoL, 1.0, ShadowOffset), GBuffer.Metallic);
							 | 
						|||
| 
								 | 
							
								Lighting.Diffuse = AreaLight.FalloffColor * FallOffMask * GBuffer.BaseColor / 3.1415927f;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								float R2 = GBuffer.Roughness * GBuffer.Roughness;
							 | 
						|||
| 
								 | 
							
								float ToonGGX = GetPreintegratedToonSpecBRDF(Context.NoH, GBuffer.Roughness);
							 | 
						|||
| 
								 | 
							
								float D = lerp(ToonGGX, 0.0, R2);
							 | 
						|||
| 
								 | 
							
								float3 F = GetToonF(Context.NoV);
							 | 
						|||
| 
								 | 
							
								Lighting.Specular = (F + D) * (AreaLight.FalloffColor * GBuffer.SpecularColor * FallOffMask * 8);
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#### ToonShadingSkin
							 | 
						|||
| 
								 | 
							
								在ToonShadingStandard的基础上做了以下修改:
							 | 
						|||
| 
								 | 
							
								固有色部分:
							 | 
						|||
| 
								 | 
							
								1. 使用ShadowOffset来偏移Context.NoL * Shadow.SurfaceShadow,来获得ShadowMask。
							 | 
						|||
| 
								 | 
							
								2. 使用ShadowMask与Opacity作为UV来查询PreIntegratedToonSkinBRDF,返回rgb值。
							 | 
						|||
| 
								 | 
							
								3. Lighting.Diffuse = AreaLight.FalloffColor * FallOffMask * GBuffer.BaseColor / 3.1415927f * PreintegratedBRDF;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								高光部分相同。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#### ToonShadingHair
							 | 
						|||
| 
								 | 
							
								在ToonShadingStandard的基础上做了以下修改:
							 | 
						|||
| 
								 | 
							
								固有色部分相同。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								高光部分增加各向异性计算:
							 | 
						|||
| 
								 | 
							
								```c++
							 | 
						|||
| 
								 | 
							
								float3 H = normalize(L + V);
							 | 
						|||
| 
								 | 
							
								float HoL = dot(H, geotangent);
							 | 
						|||
| 
								 | 
							
								float sinTH = saturate(sqrt(1 - HoL * HoL));
							 | 
						|||
| 
								 | 
							
								float spec = pow(sinTH, lerp(256, 4, GBuffer.Roughness));
							 | 
						|||
| 
								 | 
							
								float R2 = GBuffer.Roughness * GBuffer.Roughness;
							 | 
						|||
| 
								 | 
							
								float3 F = GetToonF(Context.NoV);
							 | 
						|||
| 
								 | 
							
								spec += F;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Lighting.Specular = AreaLight.FalloffColor * FallOffMask * spec * GBuffer.BaseColor;
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								#### 天光(环境光)
							 | 
						|||
| 
								 | 
							
								阴影部分的光照主要为环境光,逻辑为于ReflectionEnvironmentSkyLighting()
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								/*BeginYivanLee's Modify*/
							 | 
						|||
| 
								 | 
							
								float3 SkyLighting = float3(0.0, 0.0, 0.0);
							 | 
						|||
| 
								 | 
							
								BRANCH
							 | 
						|||
| 
								 | 
							
								if(ShadingModelID == SHADINGMODELID_TOONSTANDARD || ShadingModelID == SHADINGMODELID_TOONHAIR || ShadingModelID == SHADINGMODELID_TOONSKIN)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									float3 SubsurfaceColor = ExtractSubsurfaceColor(GBuffer);
							 | 
						|||
| 
								 | 
							
									float3 SkyToonLighting = GBuffer.BaseColor * SubsurfaceColor.rgb;
							 | 
						|||
| 
								 | 
							
									float3 SkyDiffuseLighting = SkyLightDiffuse(GBuffer, AmbientOcclusion, BufferUV, ScreenPosition, BentNormal, DiffuseColor) * CloudAmbientOcclusion;
							 | 
						|||
| 
								 | 
							
									SkyLighting = lerp(SkyDiffuseLighting, SkyToonLighting, 0.8f);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								else
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									SkyLighting = SkyLightDiffuse(GBuffer, AmbientOcclusion, BufferUV, ScreenPosition, BentNormal, DiffuseColor) * CloudAmbientOcclusion;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								/*EndYivanLee's Modify*/
							 | 
						|||
| 
								 | 
							
								```
							 |