Rewrite Radiance and Reflection probes to use Octahedral maps.

Co-authored-by: clayjohn <claynjohn@gmail.com>
This commit is contained in:
Dario 2025-06-13 16:03:49 -03:00 committed by clayjohn
parent 25203e24c4
commit c78c3ba894
48 changed files with 1513 additions and 1557 deletions

View file

@ -4,6 +4,8 @@
#VERSION_DEFINES
#include "../oct_inc.glsl"
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
#define MAX_CASCADES 8
@ -40,10 +42,10 @@ layout(rgba32i, set = 0, binding = 13) uniform restrict iimage2D lightprobe_aver
layout(rgba16f, set = 0, binding = 14) uniform restrict writeonly image2DArray lightprobe_ambient_texture;
#ifdef USE_CUBEMAP_ARRAY
layout(set = 1, binding = 0) uniform textureCubeArray sky_irradiance;
#ifdef USE_RADIANCE_OCTMAP_ARRAY
layout(set = 1, binding = 0) uniform texture2DArray sky_irradiance;
#else
layout(set = 1, binding = 0) uniform textureCube sky_irradiance;
layout(set = 1, binding = 0) uniform texture2D sky_irradiance;
#endif
layout(set = 1, binding = 1) uniform sampler linear_sampler_mipmaps;
@ -75,8 +77,9 @@ layout(push_constant, std430) uniform Params {
vec3 sky_color_or_orientation;
float y_mult;
vec2 sky_irradiance_border_size;
bool store_ambient_texture;
uint pad[3];
uint pad;
}
params;
@ -271,10 +274,10 @@ void main() {
vec4 sky_quat = vec4(params.sky_color_or_orientation, sky_sign * sqrt(1.0 - dot(params.sky_color_or_orientation, params.sky_color_or_orientation)));
vec3 sky_dir = cross(sky_quat.xyz, ray_dir);
sky_dir = ray_dir + ((sky_dir * sky_quat.w) + cross(sky_quat.xyz, sky_dir)) * 2.0;
#ifdef USE_CUBEMAP_ARRAY
light.rgb = textureLod(samplerCubeArray(sky_irradiance, linear_sampler_mipmaps), vec4(sky_dir, 0.0), 2.0).rgb; // Use second mipmap because we don't usually throw a lot of rays, so this compensates.
#ifdef USE_RADIANCE_OCTMAP_ARRAY
light.rgb = textureLod(sampler2DArray(sky_irradiance, linear_sampler_mipmaps), vec3(vec3_to_oct_with_border(sky_dir, params.sky_irradiance_border_size), 0.0), 2.0).rgb; // Use second mipmap because we don't usually throw a lot of rays, so this compensates.
#else
light.rgb = textureLod(samplerCube(sky_irradiance, linear_sampler_mipmaps), sky_dir, 2.0).rgb; // Use second mipmap because we don't usually throw a lot of rays, so this compensates.
light.rgb = textureLod(sampler2D(sky_irradiance, linear_sampler_mipmaps), vec3_to_oct_with_border(sky_dir, params.sky_irradiance_border_size), 2.0).rgb; // Use second mipmap because we don't usually throw a lot of rays, so this compensates.
#endif
light.rgb *= params.sky_energy;
light.a = 0.0;

View file

@ -29,6 +29,8 @@ void main() {
#VERSION_DEFINES
#include "../oct_inc.glsl"
#ifdef USE_MULTIVIEW
#extension GL_EXT_multiview : enable
#define ViewIndex gl_ViewIndex
@ -43,7 +45,7 @@ layout(push_constant, std430) uniform Params {
vec4 projection; // only applicable if not multiview
vec3 position;
float time;
vec2 pad;
vec2 border_size;
float luminance_multiplier;
float brightness_multiplier;
}
@ -100,10 +102,10 @@ layout(set = 1, binding = 0, std140) uniform MaterialUniforms {
/* clang-format on */
#endif
layout(set = 2, binding = 0) uniform textureCube radiance;
layout(set = 2, binding = 0) uniform texture2D radiance;
#ifdef USE_CUBEMAP_PASS
layout(set = 2, binding = 1) uniform textureCube half_res;
layout(set = 2, binding = 2) uniform textureCube quarter_res;
layout(set = 2, binding = 1) uniform texture2D half_res;
layout(set = 2, binding = 2) uniform texture2D quarter_res;
#elif defined(USE_MULTIVIEW)
layout(set = 2, binding = 1) uniform texture2DArray half_res;
layout(set = 2, binding = 2) uniform texture2DArray quarter_res;
@ -199,7 +201,11 @@ float atan2_approx(float y, float x) {
}
void main() {
vec2 uv = uv_interp * 0.5 + 0.5;
vec3 cube_normal;
#ifdef USE_CUBEMAP_PASS
cube_normal = oct_to_vec3_with_border(uv, params.border_size.y);
#else
#ifdef USE_MULTIVIEW
// In multiview our projection matrices will contain positional and rotational offsets that we need to properly unproject.
vec4 unproject = vec4(uv_interp.x, uv_interp.y, 0.0, 1.0); // unproject at the far plane
@ -215,8 +221,7 @@ void main() {
#endif
cube_normal = mat3(params.orientation) * cube_normal;
cube_normal = normalize(cube_normal);
vec2 uv = uv_interp * 0.5 + 0.5;
#endif
vec2 panorama_coords = vec2(atan2_approx(cube_normal.x, -cube_normal.z), acos_approx(cube_normal.y));
@ -235,10 +240,10 @@ void main() {
#ifdef USE_CUBEMAP_PASS
#ifdef USES_HALF_RES_COLOR
half_res_color = texture(samplerCube(half_res, SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), cube_normal) / params.luminance_multiplier;
half_res_color = texture(sampler2D(half_res, SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), vec3_to_oct_with_border(cube_normal, params.border_size)) / params.luminance_multiplier;
#endif
#ifdef USES_QUARTER_RES_COLOR
quarter_res_color = texture(samplerCube(quarter_res, SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), cube_normal) / params.luminance_multiplier;
quarter_res_color = texture(sampler2D(quarter_res, SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), vec3_to_oct_with_border(cube_normal, params.border_size)) / params.luminance_multiplier;
#endif
#else

View file

@ -16,6 +16,7 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
#include "../cluster_data_inc.glsl"
#include "../light_data_inc.glsl"
#include "../oct_inc.glsl"
#define M_PI 3.14159265359
@ -176,6 +177,9 @@ layout(set = 0, binding = 14, std140) uniform Params {
uint temporal_frame;
float temporal_blend;
vec2 sky_border_size;
vec2 pad;
mat3x4 cam_rotation;
mat4 to_prev_view;
@ -201,10 +205,10 @@ layout(r32ui, set = 0, binding = 17) uniform uimage3D light_only_map;
layout(r32ui, set = 0, binding = 18) uniform uimage3D emissive_only_map;
#endif
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
layout(set = 0, binding = 19) uniform textureCubeArray sky_texture;
#ifdef USE_RADIANCE_OCTMAP_ARRAY
layout(set = 0, binding = 19) uniform texture2DArray sky_texture;
#else
layout(set = 0, binding = 19) uniform textureCube sky_texture;
layout(set = 0, binding = 19) uniform texture2D sky_texture;
#endif
#endif // MODE_COPY
@ -429,13 +433,13 @@ void main() {
if (params.sky_contribution > 0.0) {
float mip_bias = 2.0 + total_density * (MAX_SKY_LOD - 2.0); // Not physically based, but looks nice
vec3 scatter_direction = (params.radiance_inverse_xform * normalize(view_pos)) * sign(params.phase_g);
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
isotropic = texture(samplerCubeArray(sky_texture, linear_sampler_with_mipmaps), vec4(0.0, 1.0, 0.0, mip_bias)).rgb;
anisotropic = texture(samplerCubeArray(sky_texture, linear_sampler_with_mipmaps), vec4(scatter_direction, mip_bias)).rgb;
#ifdef USE_RADIANCE_OCTMAP_ARRAY
isotropic = texture(sampler2DArray(sky_texture, linear_sampler_with_mipmaps), vec3(vec3_to_oct_with_border(vec3(0.0, 1.0, 0.0), params.sky_border_size), mip_bias)).rgb;
anisotropic = texture(sampler2DArray(sky_texture, linear_sampler_with_mipmaps), vec3(vec3_to_oct_with_border(scatter_direction, params.sky_border_size), mip_bias)).rgb;
#else
isotropic = textureLod(samplerCube(sky_texture, linear_sampler_with_mipmaps), vec3(0.0, 1.0, 0.0), mip_bias).rgb;
anisotropic = textureLod(samplerCube(sky_texture, linear_sampler_with_mipmaps), vec3(scatter_direction), mip_bias).rgb;
#endif //USE_RADIANCE_CUBEMAP_ARRAY
isotropic = textureLod(sampler2D(sky_texture, linear_sampler_with_mipmaps), vec3_to_oct_with_border(vec3(0.0, 1.0, 0.0), params.sky_border_size), mip_bias).rgb;
anisotropic = textureLod(sampler2D(sky_texture, linear_sampler_with_mipmaps), vec3_to_oct_with_border(scatter_direction, params.sky_border_size), mip_bias).rgb;
#endif //USE_RADIANCE_OCTMAP_ARRAY
}
total_light += mix(params.ambient_color, mix(isotropic, anisotropic, abs(params.phase_g)), params.sky_contribution) * params.ambient_inject;