2023-06-29 11:55:02 +08:00

170 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 描边
- 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
- ToonDataAR ShadowOffset GBA 未使用
- ToonDataBRGB OutlineColor A OutlineMask
- ToonDataCRGB IDMap A OutlineWidth
- PreIntegratedToonBRDF: R 为NoL 预积分Ramp G 为GGX高光预积分值。
- PreIntegratedToonSkinBRDFRGB为皮肤预积分颜色。
- 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*/
```