initial water shader handling for path tracing

This commit is contained in:
Turánszki János
2025-10-20 09:35:02 +02:00
parent 83032f6da1
commit 537d60c29a
5 changed files with 81 additions and 14 deletions
+24 -5
View File
@@ -76,11 +76,29 @@ enum SHADERMATERIAL_OPTIONS
SHADERMATERIAL_OPTION_BIT_DOUBLE_SIDED = 1 << 7,
SHADERMATERIAL_OPTION_BIT_TRANSPARENT = 1 << 8,
SHADERMATERIAL_OPTION_BIT_ADDITIVE = 1 << 9,
SHADERMATERIAL_OPTION_BIT_UNLIT = 1 << 10,
SHADERMATERIAL_OPTION_BIT_USE_VERTEXAO = 1 << 11,
SHADERMATERIAL_OPTION_BIT_CAPSULE_SHADOW_DISABLED = 1 << 12,
SHADERMATERIAL_OPTION_BIT_USE_VERTEXAO = 1 << 10,
SHADERMATERIAL_OPTION_BIT_CAPSULE_SHADOW_DISABLED = 1 << 11,
};
#ifndef __cplusplus
enum SHADERTYPE
{
SHADERTYPE_PBR,
SHADERTYPE_PBR_PLANARREFLECTION,
SHADERTYPE_PBR_PARALLAXOCCLUSIONMAPPING,
SHADERTYPE_PBR_ANISOTROPIC,
SHADERTYPE_WATER,
SHADERTYPE_CARTOON,
SHADERTYPE_UNLIT,
SHADERTYPE_PBR_CLOTH,
SHADERTYPE_PBR_CLEARCOAT,
SHADERTYPE_PBR_CLOTH_CLEARCOAT,
SHADERTYPE_PBR_TERRAINBLENDED,
SHADERTYPE_INTERIORMAPPING,
SHADERTYPE_COUNT
};
#endif // __cplusplus
// Same as MaterialComponent::TEXTURESLOT
enum TEXTURESLOT
{
@@ -445,7 +463,6 @@ struct alignas(16) ShaderMaterial
inline uint GetStencilRef() { return options_stencilref >> 24u; }
inline uint GetShaderType() { return shaderType_meshblend & 0xFFFF; }
inline half GetMeshBlend() { return f16tof32(shaderType_meshblend >> 16u); }
#endif // __cplusplus
inline uint GetOptions() { return options_stencilref; }
inline bool IsUsingVertexColors() { return GetOptions() & SHADERMATERIAL_OPTION_BIT_USE_VERTEXCOLORS; }
@@ -456,11 +473,13 @@ struct alignas(16) ShaderMaterial
inline bool IsUsingWind() { return GetOptions() & SHADERMATERIAL_OPTION_BIT_USE_WIND; }
inline bool IsReceiveShadow() { return GetOptions() & SHADERMATERIAL_OPTION_BIT_RECEIVE_SHADOW; }
inline bool IsCastingShadow() { return GetOptions() & SHADERMATERIAL_OPTION_BIT_CAST_SHADOW; }
inline bool IsUnlit() { return GetOptions() & SHADERMATERIAL_OPTION_BIT_UNLIT; }
inline bool IsTransparent() { return GetOptions() & SHADERMATERIAL_OPTION_BIT_TRANSPARENT; }
inline bool IsAdditive() { return GetOptions() & SHADERMATERIAL_OPTION_BIT_ADDITIVE; }
inline bool IsDoubleSided() { return GetOptions() & SHADERMATERIAL_OPTION_BIT_DOUBLE_SIDED; }
inline bool IsCapsuleShadowDisabled() { return GetOptions() & SHADERMATERIAL_OPTION_BIT_CAPSULE_SHADOW_DISABLED; }
inline bool IsUnlit() { return GetShaderType() == SHADERTYPE_UNLIT; }
#endif // __cplusplus
};
// For binning shading based on shader types:
+27 -2
View File
@@ -3,6 +3,7 @@
#define SURFACE_LOAD_MIPCONE
#define SVT_FEEDBACK
#define TEXTURE_SLOT_NONUNIFORM
#define WATER
#include "globals.hlsli"
#include "raytracingHF.hlsli"
#include "lightingHF.hlsli"
@@ -57,6 +58,10 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
RayCone raycone = pixel_ray_cone_from_image_height(xTraceResolution.y);
float4 water_opacity = 0;
float water_depth = -1;
float3 extinction = 1;
float depth = 0;
uint stencil = 0;
@@ -194,6 +199,14 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
surface.V = -ray.Direction;
surface.update();
if (water_depth >= 0)
{
water_depth += surface.hit_depth;
float waterfog = saturate(exp(-water_depth * water_opacity));
float3 transmittance = saturate(exp(-water_depth * extinction * water_opacity));
energy *= transmittance;
}
result += energy * surface.emissiveColor;
float roughnessBRDF = sqr(clamp(surface.roughness, min_roughness, 1));
@@ -425,14 +438,26 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
energy /= termination_chance;
// Set up next bounce:
const bool is_water = surface.material.GetShaderType() == SHADERTYPE_WATER;
if (is_water)
{
surface.transmission = 0.9; // hack the water into the transmission path somehow to still have a bit of reflection
extinction *= surface.material.GetSheenColor().rgb; // Note: sheen color is repurposed as extinction color for water
water_opacity = surface.baseColor.a;
water_depth = max(0, water_depth);
}
if (rng.next_float() < surface.transmission)
{
// Refraction
const float3 R = refract(ray.Direction, surface.N, 1 - lerp(surface.material.GetRefraction(), 0.1, surface.material.GetCloak()));
float roughnessBRDF = sqr(clamp(lerp(surface.roughness, 0.1, surface.material.GetCloak()), min_roughness, 1));
ray.Direction = lerp(R, sample_hemisphere_cos(R, rng), roughnessBRDF);
energy *= lerp(surface.albedo, 1, surface.material.GetCloak()) / max(0.001, surface.transmission);
if (!is_water) // water will have depth based extinction instead of simple tint
{
energy *= lerp(surface.albedo, 1, surface.material.GetCloak()) / max(0.001, surface.transmission);
}
// Add a new bounce iteration, otherwise the transparent effect can disappear:
bounce--;
}
+29 -1
View File
@@ -499,6 +499,31 @@ struct Surface
[branch]
if (geometry.vb_tan >= 0 && material.textures[NORMALMAP].IsValid())
{
#ifdef WATER
[branch]
if (material.GetShaderType() == SHADERTYPE_WATER)
{
// WATER NORMALMAP
half2 bumpColor0 = 0;
half2 bumpColor1 = 0;
#ifdef SURFACE_LOAD_QUAD_DERIVATIVES
bumpColor0 = material.textures[NORMALMAP].SampleGrad(sam, uvsets - material.texMulAdd.wwww, uvsets_dx, uvsets_dy).rg * 2 - 1;
bumpColor1 = material.textures[NORMALMAP].SampleGrad(sam, uvsets + material.texMulAdd.zwzw, uvsets_dx, uvsets_dy).rg * 2 - 1;
#else
float lod = 0;
#ifdef SURFACE_LOAD_MIPCONE
lod = compute_texture_lod(material.textures[NORMALMAP].GetTexture(), material.textures[NORMALMAP].GetUVSet() == 0 ? lod_constant0 : lod_constant1, ray_direction, surf_normal, cone_width);
#endif // SURFACE_LOAD_MIPCONE
bumpColor0 = material.textures[NORMALMAP].SampleLevel(sam, uvsets - material.texMulAdd.wwww, lod).rg * 2 - 1;
bumpColor1 = material.textures[NORMALMAP].SampleLevel(sam, uvsets + material.texMulAdd.zwzw, lod).rg * 2 - 1;
#endif // SURFACE_LOAD_QUAD_DERIVATIVES
bumpColor = half3(bumpColor0 + bumpColor1, 1) * material.GetRefraction();
N = normalize(lerp(N, mul(normalize(bumpColor), TBN), material.GetNormalMapStrength()));
bumpColor.rg *= material.GetNormalMapStrength();
}
else {
#endif // WATER
#ifdef SURFACE_LOAD_QUAD_DERIVATIVES
bumpColor = half3(material.textures[NORMALMAP].SampleGrad(sam, uvsets, uvsets_dx, uvsets_dy).rg, 1);
#else
@@ -510,9 +535,12 @@ struct Surface
#endif // SURFACE_LOAD_QUAD_DERIVATIVES
bumpColor = bumpColor * 2 - 1;
bumpColor.rg *= material.GetNormalMapStrength();
#ifdef WATER
} // water else
#endif // WATER
}
#ifdef ANISOTROPIC
aniso.strength = material.GetAnisotropy();
aniso.direction = half2(material.GetAnisotropyCos(), material.GetAnisotropySin());
-5
View File
@@ -379,10 +379,6 @@ namespace wi::scene
{
material.options_stencilref |= SHADERMATERIAL_OPTION_BIT_ADDITIVE;
}
if (shaderType == SHADERTYPE_UNLIT)
{
material.options_stencilref |= SHADERMATERIAL_OPTION_BIT_UNLIT;
}
if (!IsVertexAODisabled())
{
material.options_stencilref |= SHADERMATERIAL_OPTION_BIT_USE_VERTEXAO;
@@ -2661,7 +2657,6 @@ namespace wi::scene
XMStoreFloat4x4(&InvProjection, _InvP);
XMMATRIX _VP = XMMatrixMultiply(_V, _P);
XMStoreFloat4x4(&View, _V);
XMStoreFloat4x4(&VP, _VP);
XMMATRIX _InvV = XMMatrixInverse(nullptr, _V);
XMStoreFloat4x4(&InvView, _InvV);
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wi::version
// minor features, major updates, breaking compatibility changes
const int minor = 71;
// minor bug fixes, alterations, refactors, updates
const int revision = 841;
const int revision = 842;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);