1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-16 14:00:40 +00:00

Merge pull request #100544 from Namey5/sdfgi-sky-rotation

Support custom sky rotation in SDFGI
This commit is contained in:
Thaddeus Crews
2024-12-19 19:59:46 -06:00
3 changed files with 44 additions and 30 deletions

View File

@@ -1307,24 +1307,24 @@ void GI::SDFGI::update_probes(RID p_env, SkyRD::Sky *p_sky) {
push_constant.store_ambient_texture = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_enabled(p_env); push_constant.store_ambient_texture = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_enabled(p_env);
RID sky_uniform_set = gi->sdfgi_shader.integrate_default_sky_uniform_set; RID sky_uniform_set = gi->sdfgi_shader.integrate_default_sky_uniform_set;
push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_DISABLED; push_constant.sky_flags = 0;
push_constant.y_mult = y_mult; push_constant.y_mult = y_mult;
if (reads_sky && p_env.is_valid()) { if (reads_sky && p_env.is_valid()) {
push_constant.sky_energy = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy_multiplier(p_env); push_constant.sky_energy = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy_multiplier(p_env);
if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_CLEAR_COLOR) { if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_CLEAR_COLOR) {
push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_COLOR; push_constant.sky_flags |= SDFGIShader::IntegratePushConstant::SKY_FLAGS_MODE_COLOR;
Color c = RSG::texture_storage->get_default_clear_color().srgb_to_linear(); Color c = RSG::texture_storage->get_default_clear_color().srgb_to_linear();
push_constant.sky_color[0] = c.r; push_constant.sky_color_or_orientation[0] = c.r;
push_constant.sky_color[1] = c.g; push_constant.sky_color_or_orientation[1] = c.g;
push_constant.sky_color[2] = c.b; push_constant.sky_color_or_orientation[2] = c.b;
} else if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_COLOR) { } else if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_COLOR) {
push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_COLOR; push_constant.sky_flags |= SDFGIShader::IntegratePushConstant::SKY_FLAGS_MODE_COLOR;
Color c = RendererSceneRenderRD::get_singleton()->environment_get_bg_color(p_env); Color c = RendererSceneRenderRD::get_singleton()->environment_get_bg_color(p_env);
push_constant.sky_color[0] = c.r; push_constant.sky_color_or_orientation[0] = c.r;
push_constant.sky_color[1] = c.g; push_constant.sky_color_or_orientation[1] = c.g;
push_constant.sky_color[2] = c.b; push_constant.sky_color_or_orientation[2] = c.b;
} else if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_SKY) { } else if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_SKY) {
if (p_sky && p_sky->radiance.is_valid()) { if (p_sky && p_sky->radiance.is_valid()) {
@@ -1350,7 +1350,16 @@ void GI::SDFGI::update_probes(RID p_env, SkyRD::Sky *p_sky) {
integrate_sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.integrate.version_get_shader(gi->sdfgi_shader.integrate_shader, 0), 1); integrate_sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.integrate.version_get_shader(gi->sdfgi_shader.integrate_shader, 0), 1);
} }
sky_uniform_set = integrate_sky_uniform_set; sky_uniform_set = integrate_sky_uniform_set;
push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_SKY; push_constant.sky_flags |= SDFGIShader::IntegratePushConstant::SKY_FLAGS_MODE_SKY;
// Encode sky orientation as quaternion in existing push constants.
const Basis sky_basis = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env);
const Quaternion sky_quaternion = sky_basis.get_quaternion().inverse();
push_constant.sky_color_or_orientation[0] = sky_quaternion.x;
push_constant.sky_color_or_orientation[1] = sky_quaternion.y;
push_constant.sky_color_or_orientation[2] = sky_quaternion.z;
// Ideally we would reconstruct the largest component for least error, but sky contribution to GI is low frequency so just needs to get the idea across.
push_constant.sky_flags |= SDFGIShader::IntegratePushConstant::SKY_FLAGS_ORIENTATION_SIGN * (sky_quaternion.w < 0.0 ? 0 : 1);
} }
} }
} }
@@ -1396,7 +1405,7 @@ void GI::SDFGI::store_probes() {
push_constant.image_size[1] = probe_axis_count; push_constant.image_size[1] = probe_axis_count;
push_constant.store_ambient_texture = false; push_constant.store_ambient_texture = false;
push_constant.sky_mode = 0; push_constant.sky_flags = 0;
push_constant.y_mult = y_mult; push_constant.y_mult = y_mult;
// Then store values into the lightprobe texture. Separating these steps has a small performance hit, but it allows for multiple bounces // Then store values into the lightprobe texture. Separating these steps has a small performance hit, but it allows for multiple bounces
@@ -2092,11 +2101,11 @@ void GI::SDFGI::render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_
ipush_constant.history_size = history_size; ipush_constant.history_size = history_size;
ipush_constant.ray_count = 0; ipush_constant.ray_count = 0;
ipush_constant.ray_bias = 0; ipush_constant.ray_bias = 0;
ipush_constant.sky_mode = 0; ipush_constant.sky_flags = 0;
ipush_constant.sky_energy = 0; ipush_constant.sky_energy = 0;
ipush_constant.sky_color[0] = 0; ipush_constant.sky_color_or_orientation[0] = 0;
ipush_constant.sky_color[1] = 0; ipush_constant.sky_color_or_orientation[1] = 0;
ipush_constant.sky_color[2] = 0; ipush_constant.sky_color_or_orientation[2] = 0;
ipush_constant.y_mult = y_mult; ipush_constant.y_mult = y_mult;
ipush_constant.store_ambient_texture = false; ipush_constant.store_ambient_texture = false;

View File

@@ -392,9 +392,9 @@ private:
}; };
struct IntegratePushConstant { struct IntegratePushConstant {
enum { enum {
SKY_MODE_DISABLED, SKY_FLAGS_MODE_COLOR = 0x01,
SKY_MODE_COLOR, SKY_FLAGS_MODE_SKY = 0x02,
SKY_MODE_SKY, SKY_FLAGS_ORIENTATION_SIGN = 0x04,
}; };
float grid_size[3]; float grid_size[3];
@@ -410,12 +410,12 @@ private:
int32_t image_size[2]; int32_t image_size[2];
int32_t world_offset[3]; int32_t world_offset[3];
uint32_t sky_mode; uint32_t sky_flags;
int32_t scroll[3]; int32_t scroll[3];
float sky_energy; float sky_energy;
float sky_color[3]; float sky_color_or_orientation[3];
float y_mult; float y_mult;
uint32_t store_ambient_texture; uint32_t store_ambient_texture;

View File

@@ -49,9 +49,9 @@ layout(set = 1, binding = 1) uniform sampler linear_sampler_mipmaps;
#define HISTORY_BITS 10 #define HISTORY_BITS 10
#define SKY_MODE_DISABLED 0 #define SKY_FLAGS_MODE_COLOR 0x01
#define SKY_MODE_COLOR 1 #define SKY_FLAGS_MODE_SKY 0x02
#define SKY_MODE_SKY 2 #define SKY_FLAGS_ORIENTATION_SIGN 0x04
layout(push_constant, std430) uniform Params { layout(push_constant, std430) uniform Params {
vec3 grid_size; vec3 grid_size;
@@ -67,12 +67,12 @@ layout(push_constant, std430) uniform Params {
ivec2 image_size; ivec2 image_size;
ivec3 world_offset; ivec3 world_offset;
uint sky_mode; uint sky_flags;
ivec3 scroll; ivec3 scroll;
float sky_energy; float sky_energy;
vec3 sky_color; vec3 sky_color_or_orientation;
float y_mult; float y_mult;
bool store_ambient_texture; bool store_ambient_texture;
@@ -265,17 +265,22 @@ void main() {
} }
} }
} else if (params.sky_mode == SKY_MODE_SKY) { } else if (bool(params.sky_flags & SKY_FLAGS_MODE_SKY)) {
// Reconstruct sky orientation as quaternion and rotate ray_dir before sampling.
float sky_sign = bool(params.sky_flags & SKY_FLAGS_ORIENTATION_SIGN) ? 1.0 : -1.0;
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 #ifdef USE_CUBEMAP_ARRAY
light.rgb = textureLod(samplerCubeArray(sky_irradiance, linear_sampler_mipmaps), vec4(ray_dir, 0.0), 2.0).rgb; // Use second mipmap because we don't usually throw a lot of rays, so this compensates. 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.
#else #else
light.rgb = textureLod(samplerCube(sky_irradiance, linear_sampler_mipmaps), ray_dir, 2.0).rgb; // Use second mipmap because we don't usually throw a lot of rays, so this compensates. 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.
#endif #endif
light.rgb *= params.sky_energy; light.rgb *= params.sky_energy;
light.a = 0.0; light.a = 0.0;
} else if (params.sky_mode == SKY_MODE_COLOR) { } else if (bool(params.sky_flags & SKY_FLAGS_MODE_COLOR)) {
light.rgb = params.sky_color; light.rgb = params.sky_color_or_orientation;
light.rgb *= params.sky_energy; light.rgb *= params.sky_energy;
light.a = 0.0; light.a = 0.0;
} else { } else {