Skip to content

Commit

Permalink
feat: material system extensions for physically-based rendering suppo…
Browse files Browse the repository at this point in the history
…rt. (#352)

* feat: material system extensions for physically-based rendering support.

* feat: pbr specular respects skylighting, slight SL specular change

* refactor: move truePBR to it's own feature

* fix: revert making TruePBR a feature but keep logic and storage in it

* style: 🎨 apply clang-format changes

* fix: fixed artifacts of terrain blending interacting with PBR.

* chore: review fixes.

* style: 🎨 apply clang-format changes

* chore: shader compilation fix.

* chore: clib update compatibility.

* fix: better wetness integration with pbr.

* style: 🎨 apply clang-format changes

* chore: review fix.

* fix: lighting shader constants indices for VR.

* style: 🎨 apply clang-format changes

* build: update to latest clib-ng

* fix: fix shader constants indices for VR

---------

Co-authored-by: Ilya Perapechka <i_perapechka@wargaming.net>
Co-authored-by: Pentalimbed <pentalimbed@gmail.com>
Co-authored-by: FlayaN <hannes.feldt@gmail.com>
Co-authored-by: Jonahex <Jonahex@users.noreply.github.com>
  • Loading branch information
5 people authored Aug 1, 2024
1 parent e577051 commit 2c64acd
Show file tree
Hide file tree
Showing 24 changed files with 3,959 additions and 363 deletions.
2 changes: 1 addition & 1 deletion extern/CommonLibSSE-NG
Submodule CommonLibSSE-NG updated 211 files
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,23 @@ half2 EnvBRDFApprox(half Roughness, half NoV)

#if !defined(WATER)

float3 GetDynamicCubemapSpecularIrradiance(float2 uv, float3 N, float3 VN, float3 V, float roughness, float distance)
{
float3 R = reflect(-V, N);
float level = roughness * 9.0;

// Horizon specular occlusion
// https://marmosetco.tumblr.com/post/81245981087
float horizon = min(1.0 + dot(R, VN), 1.0);
horizon *= horizon * horizon;

float3 specularIrradiance = specularTexture.SampleLevel(SampColorSampler, R, level).xyz;
specularIrradiance *= horizon;
specularIrradiance = sRGB2Lin(specularIrradiance);

return specularIrradiance;
}

float3 GetDynamicCubemap(float2 uv, float3 N, float3 VN, float3 V, float roughness, float3 F0, float3 diffuseColor, float distance)
{
float3 R = reflect(-V, N);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,23 @@
// http://www.diva-portal.org/smash/get/diva2:831762/FULLTEXT01.pdf
// https://bartwronski.files.wordpress.com/2014/03/ac4_gdc.pdf

struct DisplacementParams
{
float DisplacementScale;
float DisplacementOffset;
float HeightScale;
};

float AdjustDisplacement(float displacement, DisplacementParams params)
{
return (displacement - 0.5) * params.DisplacementScale + 0.5 + params.DisplacementOffset;
}

float4 AdjustDisplacement(float4 displacement, DisplacementParams params)
{
return float4(AdjustDisplacement(displacement.x, params), AdjustDisplacement(displacement.y, params), AdjustDisplacement(displacement.z, params), AdjustDisplacement(displacement.w, params));
}

float GetMipLevel(float2 coords, Texture2D<float4> tex)
{
// Compute the current gradients:
Expand Down Expand Up @@ -36,7 +53,7 @@ float GetMipLevel(float2 coords, Texture2D<float4> tex)
# define HEIGHT_POWER 4.0
# define INV_HEIGHT_POWER 0.25

float GetTerrainHeight(PS_INPUT input, float2 coords, float mipLevels[6], float blendFactor, out float pixelOffset[6])
float GetTerrainHeight(PS_INPUT input, float2 coords, float mipLevels[6], DisplacementParams params[6], float blendFactor, out float pixelOffset[6])
{
float4 w1 = pow(input.LandBlendWeights1, 1 + 1 * blendFactor);
float2 w2 = pow(input.LandBlendWeights2.xy, 1 + 1 * blendFactor);
Expand All @@ -48,6 +65,20 @@ float GetTerrainHeight(PS_INPUT input, float2 coords, float mipLevels[6], float
pixelOffset[3] = 0;
pixelOffset[4] = 0;
pixelOffset[5] = 0;
# if defined(TRUE_PBR)
[branch] if ((PBRFlags & TruePBR_LandTile0HasDisplacement) != 0) if (w1.x > 0.0)
pixelOffset[0] = w1.x * (0.001 + pow(AdjustDisplacement(TexLandDisplacement0Sampler.SampleLevel(SampTerrainParallaxSampler, coords, mipLevels[0]).x, params[0]), blendPower));
[branch] if ((PBRFlags & TruePBR_LandTile1HasDisplacement) != 0) if (w1.y > 0.0)
pixelOffset[1] = w1.y * (0.001 + pow(AdjustDisplacement(TexLandDisplacement1Sampler.SampleLevel(SampTerrainParallaxSampler, coords, mipLevels[1]).x, params[1]), blendPower));
[branch] if ((PBRFlags & TruePBR_LandTile2HasDisplacement) != 0) if (w1.z > 0.0)
pixelOffset[2] = w1.z * (0.001 + pow(AdjustDisplacement(TexLandDisplacement2Sampler.SampleLevel(SampTerrainParallaxSampler, coords, mipLevels[2]).x, params[2]), blendPower));
[branch] if ((PBRFlags & TruePBR_LandTile3HasDisplacement) != 0) if (w1.w > 0.0)
pixelOffset[3] = w1.w * (0.001 + pow(AdjustDisplacement(TexLandDisplacement3Sampler.SampleLevel(SampTerrainParallaxSampler, coords, mipLevels[3]).x, params[3]), blendPower));
[branch] if ((PBRFlags & TruePBR_LandTile4HasDisplacement) != 0) if (w2.x > 0.0)
pixelOffset[4] = w2.x * (0.001 + pow(AdjustDisplacement(TexLandDisplacement4Sampler.SampleLevel(SampTerrainParallaxSampler, coords, mipLevels[4]).x, params[4]), blendPower));
[branch] if ((PBRFlags & TruePBR_LandTile5HasDisplacement) != 0) if (w2.y > 0.0)
pixelOffset[5] = w2.y * (0.001 + pow(AdjustDisplacement(TexLandDisplacement5Sampler.SampleLevel(SampTerrainParallaxSampler, coords, mipLevels[5]).x, params[5]), blendPower));
# else
if (w1.x > 0.0)
pixelOffset[0] = w1.x * (0.001 + pow(TexColorSampler.SampleLevel(SampTerrainParallaxSampler, coords, mipLevels[0]).w, blendPower));
if (w1.y > 0.0)
Expand All @@ -60,6 +91,8 @@ float GetTerrainHeight(PS_INPUT input, float2 coords, float mipLevels[6], float
pixelOffset[4] = w2.x * (0.001 + pow(TexLandColor5Sampler.SampleLevel(SampTerrainParallaxSampler, coords, mipLevels[4]).w, blendPower));
if (w2.y > 0.0)
pixelOffset[5] = w2.y * (0.001 + pow(TexLandColor6Sampler.SampleLevel(SampTerrainParallaxSampler, coords, mipLevels[5]).w, blendPower));
# endif

float total = 0;
[unroll] for (int i = 0; i < 6; i++)
{
Expand All @@ -75,9 +108,9 @@ float GetTerrainHeight(PS_INPUT input, float2 coords, float mipLevels[6], float
#endif

#if defined(LANDSCAPE)
float2 GetParallaxCoords(PS_INPUT input, float distance, float2 coords, float mipLevels[6], float3 viewDir, float3x3 tbn, float noise, out float pixelOffset, out float heights[6])
float2 GetParallaxCoords(PS_INPUT input, float distance, float2 coords, float mipLevels[6], float3 viewDir, float3x3 tbn, float noise, DisplacementParams params[6], out float pixelOffset, out float heights[6])
#else
float2 GetParallaxCoords(float distance, float2 coords, float mipLevel, float3 viewDir, float3x3 tbn, float noise, Texture2D<float4> tex, SamplerState texSampler, uint channel, out float pixelOffset)
float2 GetParallaxCoords(float distance, float2 coords, float mipLevel, float3 viewDir, float3x3 tbn, float noise, Texture2D<float4> tex, SamplerState texSampler, uint channel, DisplacementParams params, out float pixelOffset)
#endif
{
float3 viewDirTS = normalize(mul(tbn, viewDir));
Expand All @@ -89,7 +122,11 @@ float2 GetParallaxCoords(float distance, float2 coords, float mipLevel, float3 v
float blendFactor = extendedMaterialSettings.EnableComplexMaterial ? saturate(1 - nearBlendToFar) : INV_HEIGHT_POWER;
#endif

float maxHeight = 0.1;
#if defined(LANDSCAPE)
float maxHeight = 0.1 * (params[0].HeightScale + params[1].HeightScale + params[2].HeightScale + params[3].HeightScale + params[4].HeightScale + params[5].HeightScale) / 6;
#else
float maxHeight = 0.1 * params.HeightScale;
#endif
float minHeight = maxHeight * 0.5;

if (nearBlendToFar < 1.0) {
Expand All @@ -116,16 +153,18 @@ float2 GetParallaxCoords(float distance, float2 coords, float mipLevel, float3 v

#if defined(LANDSCAPE)
float4 currHeight;
currHeight.x = GetTerrainHeight(input, currentOffset[0].xy, mipLevels, blendFactor, heights);
currHeight.y = GetTerrainHeight(input, currentOffset[0].zw, mipLevels, blendFactor, heights);
currHeight.z = GetTerrainHeight(input, currentOffset[1].xy, mipLevels, blendFactor, heights);
currHeight.w = GetTerrainHeight(input, currentOffset[1].zw, mipLevels, blendFactor, heights);
currHeight.x = GetTerrainHeight(input, currentOffset[0].xy, mipLevels, params, blendFactor, heights);
currHeight.y = GetTerrainHeight(input, currentOffset[0].zw, mipLevels, params, blendFactor, heights);
currHeight.z = GetTerrainHeight(input, currentOffset[1].xy, mipLevels, params, blendFactor, heights);
currHeight.w = GetTerrainHeight(input, currentOffset[1].zw, mipLevels, params, blendFactor, heights);
#else
float4 currHeight;
currHeight.x = tex.SampleLevel(texSampler, currentOffset[0].xy, mipLevel)[channel];
currHeight.y = tex.SampleLevel(texSampler, currentOffset[0].zw, mipLevel)[channel];
currHeight.z = tex.SampleLevel(texSampler, currentOffset[1].xy, mipLevel)[channel];
currHeight.w = tex.SampleLevel(texSampler, currentOffset[1].zw, mipLevel)[channel];

currHeight = AdjustDisplacement(currHeight, params);
#endif

bool4 testResult = currHeight >= currentBound;
Expand Down Expand Up @@ -197,34 +236,34 @@ float2 GetParallaxCoords(float distance, float2 coords, float mipLevel, float3 v
// https://advances.realtimerendering.com/s2006/Tatarchuk-POM.pdf

// Cheap method of creating shadows using height for a given light source
float GetParallaxSoftShadowMultiplier(float2 coords, float mipLevel, float3 L, float sh0, Texture2D<float4> tex, SamplerState texSampler, uint channel, float quality, float noise)
float GetParallaxSoftShadowMultiplier(float2 coords, float mipLevel, float3 L, float sh0, Texture2D<float4> tex, SamplerState texSampler, uint channel, float quality, float noise, DisplacementParams params)
{
[branch] if (quality > 0.0)
{
float2 rayDir = L.xy * 0.1;
float4 multipliers = rcp((float4(4, 3, 2, 1) + noise));
float4 sh;
sh.x = tex.SampleLevel(texSampler, coords + rayDir * multipliers.x, mipLevel)[channel];
sh.y = tex.SampleLevel(texSampler, coords + rayDir * multipliers.y, mipLevel)[channel];
sh.z = tex.SampleLevel(texSampler, coords + rayDir * multipliers.z, mipLevel)[channel];
sh.w = tex.SampleLevel(texSampler, coords + rayDir * multipliers.w, mipLevel)[channel];
return 1.0 - saturate(dot(max(0, sh - sh0), 1.0) * 2.0) * quality;
sh.x = AdjustDisplacement(tex.SampleLevel(texSampler, coords + rayDir * multipliers.x, mipLevel)[channel], params);
sh.y = AdjustDisplacement(tex.SampleLevel(texSampler, coords + rayDir * multipliers.y, mipLevel)[channel], params);
sh.z = AdjustDisplacement(tex.SampleLevel(texSampler, coords + rayDir * multipliers.z, mipLevel)[channel], params);
sh.w = AdjustDisplacement(tex.SampleLevel(texSampler, coords + rayDir * multipliers.w, mipLevel)[channel], params);
return 1.0 - saturate(dot(max(0, sh - sh0), 1.0) * params.HeightScale * 2.0) * quality;
}
return 1.0;
}

#if defined(LANDSCAPE)
float GetParallaxSoftShadowMultiplierTerrain(PS_INPUT input, float2 coords, float mipLevel[6], float3 L, float sh0, float quality, float noise)
float GetParallaxSoftShadowMultiplierTerrain(PS_INPUT input, float2 coords, float mipLevel[6], float3 L, float sh0, float quality, float noise, DisplacementParams params[6])
{
if (quality > 0.0) {
float2 rayDir = L.xy * 0.1;
float4 multipliers = rcp((float4(4, 3, 2, 1) + noise));
float4 sh;
float heights[6] = { 0, 0, 0, 0, 0, 0 };
sh.x = GetTerrainHeight(input, coords + rayDir * multipliers.x, mipLevel, quality, heights);
sh.y = GetTerrainHeight(input, coords + rayDir * multipliers.y, mipLevel, quality, heights);
sh.z = GetTerrainHeight(input, coords + rayDir * multipliers.z, mipLevel, quality, heights);
sh.w = GetTerrainHeight(input, coords + rayDir * multipliers.w, mipLevel, quality, heights);
sh.x = GetTerrainHeight(input, coords + rayDir * multipliers.x, mipLevel, params, quality, heights);
sh.y = GetTerrainHeight(input, coords + rayDir * multipliers.y, mipLevel, params, quality, heights);
sh.z = GetTerrainHeight(input, coords + rayDir * multipliers.z, mipLevel, params, quality, heights);
sh.w = GetTerrainHeight(input, coords + rayDir * multipliers.w, mipLevel, params, quality, heights);
return 1.0 - saturate(dot(max(0, sh - sh0), 1.0) * 2.0) * quality;
}
return 1.0;
Expand Down
Loading

0 comments on commit 2c64acd

Please sign in to comment.