From 84eb24d6425fd775eee52d433693537c57d33b4d Mon Sep 17 00:00:00 2001 From: BlueRose <378100977@qq.com> Date: Mon, 24 Mar 2025 16:18:29 +0800 Subject: [PATCH] vault backup: 2025-03-24 16:18:29 --- .../渲染功能/ToonReflection&GI控制/ToonReflection.md | 241 +++++++++++++++++- .../其他游戏与软件参考/星穹铁道_阮梅_皮肤_屁股.png | 3 + 2 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 03-UnrealEngine/卡通渲染相关资料/渲染功能/其他参考/其他游戏与软件参考/星穹铁道_阮梅_皮肤_屁股.png diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ToonReflection&GI控制/ToonReflection.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ToonReflection&GI控制/ToonReflection.md index c657fea..7e50578 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/ToonReflection&GI控制/ToonReflection.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/ToonReflection&GI控制/ToonReflection.md @@ -46,7 +46,246 @@ rating: ⭐ 3. 结果赋予给FRDGTextureRef ReflectionsColor。 - 执行完上述反射方法后,最后执行`AddSkyReflectionPass()` -`FReflectionEnvironmentSkyLightingPS`位于/Engine/Private/ReflectionEnvironmentPixelShader.usf的ReflectionEnvironmentSkyLighting()。 +FReflectionEnvironmentSkyLightingPS位于/Engine/Private/ReflectionEnvironmentPixelShader.usf的`ReflectionEnvironmentSkyLighting()`。 +### ReflectionEnvironmentSkyLighting +```c++ +void ReflectionEnvironmentSkyLighting( + in float4 SvPosition : SV_Position, + out float4 OutColor : SV_Target0 +#if STRATA_OPAQUE_ROUGH_REFRACTION_ENABLED + , out float3 OutOpaqueRoughRefractionSceneColor : SV_Target1 + , out float3 OutSubSurfaceSceneColor : SV_Target2 +#endif + ) +{ + ResolvedView = ResolveView(); + //计算获去BufferUV、ScreenPosition + uint2 PixelPos = SvPosition.xy; + float2 BufferUV = SvPositionToBufferUV(SvPosition); + float2 ScreenPosition = SvPositionToScreenPosition(SvPosition).xy; + + OutColor = 0.0f; +#if STRATA_OPAQUE_ROUGH_REFRACTION_ENABLED + OutOpaqueRoughRefractionSceneColor = 0.0f; + OutSubSurfaceSceneColor = 0.0f; +#endif + +#if STRATA_ENABLED +... +... +#else // STRATA_ENABLED + + // Sample scene textures. + FGBufferData GBuffer = GetGBufferDataFromSceneTextures(BufferUV); + + uint ShadingModelID = GBuffer.ShadingModelID; + const bool bUnlitMaterial = ShadingModelID == SHADINGMODELID_UNLIT; + + float3 DiffuseColor = GBuffer.DiffuseColor; + float3 SpecularColor = GBuffer.SpecularColor; + RemapClearCoatDiffuseAndSpecularColor(GBuffer, ScreenPosition, DiffuseColor, SpecularColor);//针对清漆材质进行Diffuse颜色与Specular颜色重新映射 + + // Sample the ambient occlusion that is dynamically generated every frame. + float AmbientOcclusion = AmbientOcclusionTexture.SampleLevel(AmbientOcclusionSampler, BufferUV, 0).r; + + float3 BentNormal = GBuffer.WorldNormal; +#if APPLY_SKY_SHADOWING + { + BentNormal = UpsampleDFAO(BufferUV, GBuffer.Depth, GBuffer.WorldNormal); + } +#endif + +#if ENABLE_DYNAMIC_SKY_LIGHT + BRANCH + if (!bUnlitMaterial) // Only light pixels marked as lit //Unlit材质不会计算动态天光GI的效果。 + { + float3 TranslatedWorldPosition = mul(float4(GetScreenPositionForProjectionType(ScreenPosition, GBuffer.Depth), GBuffer.Depth, 1), View.ScreenToTranslatedWorld).xyz; + const float CloudVolumetricAOShadow = GetCloudVolumetricAOShadow(TranslatedWorldPosition);//从体积云 VolumetricCloudShadowMapTexture中取得ShadowFrontDepthKm、MaxOpticalDepth,MeanExtinction,最终计算出体积云阴影。UE5.3该函数没有启用。 + + float3 SkyLighting = CloudVolumetricAOShadow * SkyLightDiffuse(GBuffer, AmbientOcclusion, BufferUV, ScreenPosition, BentNormal, DiffuseColor); + + FLightAccumulator LightAccumulator = (FLightAccumulator)0; + const bool bNeedsSeparateSubsurfaceLightAccumulation = UseSubsurfaceProfile(ShadingModelID); + LightAccumulator_Add(LightAccumulator, SkyLighting, SkyLighting, 1.0f, bNeedsSeparateSubsurfaceLightAccumulation); + OutColor = LightAccumulator_GetResult(LightAccumulator); + } + +#endif // ENABLE_DYNAMIC_SKY_LIGHT + + BRANCH + if (!bUnlitMaterial && ShadingModelID != SHADINGMODELID_HAIR)// + { + OutColor.xyz += ReflectionEnvironment(GBuffer, AmbientOcclusion, BufferUV, ScreenPosition, SvPosition, BentNormal, SpecularColor, ShadingModelID); + } + +#endif // STRATA_ENABLED +} + + +``` + +### SkyLightDiffuse +1. 计算float3 SkyLightingNormal、FSkyLightVisibilityData SkyVisData。 +2. 计算Normal、ViewVector、NoV。 +3. 针对制定ShadingModel进行额外计算: + 1. SHADINGMODELID_TWOSIDED_FOLIAGE:使用Normal反向量取得SkySHDiffuse,在乘以SubsurfaceColor、SkyVisData.SkyDiffuseLookUpMul后累加到结果上。 + 2. SHADINGMODELID_SUBSURFACE、SHADINGMODELID_PREINTEGRATED_SKIN:从GBuffer中提取SubsurfaceColor并累加到结果上。 + 3. SHADINGMODELID_CLOTH:从GBuffer中提取ClothFuzz(SubsurfaceColor)乘以CustomData.a,并累加到结果上。 + 4. SHADINGMODELID_HAIR: + 1. DiffuseColor = EvaluateEnvHair(GBuffer, V, N, L); + 2. SkyVisData.SkyDiffuseLookUpNormal = L; + 3. DiffuseWeight = 1.0f; +4. 调用GetSkySHDiffuse()计算天光光照效果。GetSkySHDiffuse()本质是采样球谐贴图,来获得天光GI结果。 + +### ReflectionEnvironment +```c++ +float3 ReflectionEnvironment(FGBufferData GBuffer, float AmbientOcclusion, float2 BufferUV, float2 ScreenPosition, float4 SvPosition, float3 BentNormal, float3 SpecularColor, uint ShadingModelID) +{ + float4 Color = float4(0, 0, 0, 1); + + float IndirectIrradiance = GBuffer.IndirectIrradiance; + +#if ENABLE_SKY_LIGHT && ALLOW_STATIC_LIGHTING + BRANCH + // Add in diffuse contribution from dynamic skylights so reflection captures will have something to mix with + if (ReflectionStruct.SkyLightParameters.y > 0 && ReflectionStruct.SkyLightParameters.z > 0) + { + //如果开启天光、并且开启静态关照。会在这里采样SkySH,以此累加间接照明。 + IndirectIrradiance += GetDynamicSkyIndirectIrradiance(BentNormal, GBuffer.WorldNormal); + } +#endif + + //计算反射Vector、WorldNormal、ViewVector + float3 TranslatedWorldPosition = mul(float4(GetScreenPositionForProjectionType(ScreenPosition, GBuffer.Depth), GBuffer.Depth, 1), View.ScreenToTranslatedWorld).xyz; + float3 CameraToPixel = normalize(TranslatedWorldPosition - View.TranslatedWorldCameraOrigin); + float3 ReflectionVector = reflect(CameraToPixel, GBuffer.WorldNormal); + float3 V = -CameraToPixel; + float3 N = GBuffer.WorldNormal; + + const float3 SavedTopLayerNormal = N; + +#if SUPPORTS_ANISOTROPIC_MATERIALS + ModifyGGXAnisotropicNormalRoughness(GBuffer.WorldTangent, GBuffer.Anisotropy, GBuffer.Roughness, N, V); +#endif + + float3 R = 2 * dot( V, N ) * N - V; + float NoV = saturate( dot( N, V ) ); + + // Point lobe in off-specular peak direction + R = GetOffSpecularPeakReflectionDir(N, R, GBuffer.Roughness); + + // 采样 SSR, planar reflections, RT reflections or Lumen 反射结果。 + float4 ReflectionInput = Texture2DSample(ReflectionTexture, ReflectionTextureSampler, BufferUV); + Color = CompositeReflections(ReflectionInput, BufferUV, GBuffer.Roughness, ShadingModelID);//Color = float4(ReflectionInput.rgb, 1 - ReflectionInput.a) + +#if RAY_TRACED_REFLECTIONS + float4 SavedColor = Color; // When a clear coat material is encountered, we save the reflection buffer color for it to not be affected by operations. +#endif + if(GBuffer.ShadingModelID == SHADINGMODELID_CLEAR_COAT ) + { +#if RAY_TRACED_REFLECTIONS + Color = float4(0, 0, 0, 1); // Clear coat reflection is expected to be computed on a black background +#endif + const float ClearCoat = GBuffer.CustomData.x; + Color = lerp( Color, float4(0,0,0,1), ClearCoat ); + +#if CLEAR_COAT_BOTTOM_NORMAL + const float2 oct1 = ((float2(GBuffer.CustomData.a, GBuffer.CustomData.z) * 4) - (512.0/255.0)) + UnitVectorToOctahedron(GBuffer.WorldNormal); + const float3 ClearCoatUnderNormal = OctahedronToUnitVector(oct1); + + const float3 BottomEffectiveNormal = ClearCoatUnderNormal; + R = 2 * dot( V, ClearCoatUnderNormal ) * ClearCoatUnderNormal - V; +#endif + } + + float AO = GBuffer.GBufferAO * AmbientOcclusion;//AmbientOcclusion为SSAO或者RTAO或者DFAO或者Lumen…… + float RoughnessSq = GBuffer.Roughness * GBuffer.Roughness; + float SpecularOcclusion = GetSpecularOcclusion(NoV, RoughnessSq, AO); + Color.a *= SpecularOcclusion; + +#if FEATURE_LEVEL >= FEATURE_LEVEL_SM5 + float2 LocalPosition = SvPosition.xy - View.ViewRectMin.xy; + + uint GridIndex = ComputeLightGridCellIndex(uint2(LocalPosition.x, LocalPosition.y), GBuffer.Depth); + uint NumCulledEntryIndex = (ForwardLightData.NumGridCells + GridIndex) * NUM_CULLED_LIGHTS_GRID_STRIDE; + uint NumCulledReflectionCaptures = min(ForwardLightData.NumCulledLightsGrid[NumCulledEntryIndex + 0], ForwardLightData.NumReflectionCaptures); + uint DataStartIndex = ForwardLightData.NumCulledLightsGrid[NumCulledEntryIndex + 1]; +#else + uint DataStartIndex = 0; + uint NumCulledReflectionCaptures = 0; +#endif + + const FBxDFEnergyTerms EnergyTerms = ComputeGGXSpecEnergyTerms(GBuffer.Roughness, NoV, GBuffer.SpecularColor); + + //常规反射 或 底层清漆 光照计算 + //Top of regular reflection or bottom layer of clear coat. + Color.rgb += View.PreExposure * GatherRadiance(Color.a, TranslatedWorldPosition, R, GBuffer.Roughness, BentNormal, IndirectIrradiance, GBuffer.ShadingModelID, NumCulledReflectionCaptures, DataStartIndex); + + BRANCH + if( GBuffer.ShadingModelID == SHADINGMODELID_CLEAR_COAT) + { + const float ClearCoat = GBuffer.CustomData.x; + const float ClearCoatRoughness = GBuffer.CustomData.y; + + // Restore saved values needed for the top layer. + GBuffer.WorldNormal = SavedTopLayerNormal; + // Recompute some values unaffected by anistropy for the top layer + N = GBuffer.WorldNormal; + R = 2 * dot(V, N) * N - V; + NoV = saturate(dot(N, V)); + R = GetOffSpecularPeakReflectionDir(N, R, ClearCoatRoughness); + + // TODO EnvBRDF should have a mask param + #if USE_ENERGY_CONSERVATION + Color.rgb *= EnergyTerms.E * (1 - ClearCoat); + #else + // Hack: Ensures when clear coat is >0, grazing angle does not get too much energy, + // but preserve response at normal incidence + float2 AB = PreIntegratedGF.SampleLevel(PreIntegratedGFSampler, float2(NoV, GBuffer.Roughness), 0).rg; + Color.rgb *= SpecularColor * AB.x + AB.y * saturate(50 * SpecularColor.g) * (1 - ClearCoat); + #endif + + // F_Schlick + const float CoatF0 = 0.04f; + #if USE_ENERGY_CONSERVATION + float F = ComputeGGXSpecEnergyTerms(ClearCoatRoughness, NoV, CoatF0).E.x; + #else + float F = EnvBRDF(CoatF0, ClearCoatRoughness, NoV).x; + #endif + + F *= ClearCoat; + + float LayerAttenuation = (1 - F); + Color.rgb *= LayerAttenuation; + Color.a = F; + +#if !RAY_TRACED_REFLECTIONS + Color.rgb += ReflectionInput.rgb * F; + Color.a *= 1 - ReflectionInput.a; +#endif + + Color.a *= SpecularOcclusion; + + float3 TopLayerR = 2 * dot( V, N ) * N - V; + Color.rgb += View.PreExposure * GatherRadiance(Color.a, TranslatedWorldPosition, TopLayerR, ClearCoatRoughness, BentNormal, IndirectIrradiance, GBuffer.ShadingModelID, NumCulledReflectionCaptures, DataStartIndex); + + #if RAY_TRACED_REFLECTIONS + Color.rgb = SavedColor.rgb + Color.rgb * SavedColor.a; // Compose default clear coat reflection over regular refelction (using Premultiplied alpha where SaveColor.a=transmittance) + #endif + } + else + { + #if USE_ENERGY_CONSERVATION + Color.rgb *= EnergyTerms.E; + #else + Color.rgb *= EnvBRDF( SpecularColor, GBuffer.Roughness, NoV ); + #endif + } + + // Transform NaNs to black, transform negative colors to black. + return -min(-Color.rgb, 0.0); +} +``` ## DiffuseIndirectComposite 位于IndirectLightRendering.cpp的`RenderDiffuseIndirectAndAmbientOcclusion()` \ No newline at end of file diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/其他参考/其他游戏与软件参考/星穹铁道_阮梅_皮肤_屁股.png b/03-UnrealEngine/卡通渲染相关资料/渲染功能/其他参考/其他游戏与软件参考/星穹铁道_阮梅_皮肤_屁股.png new file mode 100644 index 0000000..49698ce --- /dev/null +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/其他参考/其他游戏与软件参考/星穹铁道_阮梅_皮肤_屁股.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0e812e38b2dbe26da0177dbabba92f2c36c16ac6c30b09a4494e15515151c5a3 +size 1264786