Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support custom sky rotation in SDFGI #100544

Merged
merged 1 commit into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 24 additions & 15 deletions servers/rendering/renderer_rd/environment/gi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

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;

if (reads_sky && p_env.is_valid()) {
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) {
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();
push_constant.sky_color[0] = c.r;
push_constant.sky_color[1] = c.g;
push_constant.sky_color[2] = c.b;
push_constant.sky_color_or_orientation[0] = c.r;
push_constant.sky_color_or_orientation[1] = c.g;
push_constant.sky_color_or_orientation[2] = c.b;
} 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);
push_constant.sky_color[0] = c.r;
push_constant.sky_color[1] = c.g;
push_constant.sky_color[2] = c.b;
push_constant.sky_color_or_orientation[0] = c.r;
push_constant.sky_color_or_orientation[1] = c.g;
push_constant.sky_color_or_orientation[2] = c.b;

} else if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_SKY) {
if (p_sky && p_sky->radiance.is_valid()) {
Expand All @@ -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);
}
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);
}
}
}
Expand Down Expand Up @@ -1396,7 +1405,7 @@ void GI::SDFGI::store_probes() {
push_constant.image_size[1] = probe_axis_count;
push_constant.store_ambient_texture = false;

push_constant.sky_mode = 0;
push_constant.sky_flags = 0;
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
Expand Down Expand Up @@ -2092,11 +2101,11 @@ void GI::SDFGI::render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_
ipush_constant.history_size = history_size;
ipush_constant.ray_count = 0;
ipush_constant.ray_bias = 0;
ipush_constant.sky_mode = 0;
ipush_constant.sky_flags = 0;
ipush_constant.sky_energy = 0;
ipush_constant.sky_color[0] = 0;
ipush_constant.sky_color[1] = 0;
ipush_constant.sky_color[2] = 0;
ipush_constant.sky_color_or_orientation[0] = 0;
ipush_constant.sky_color_or_orientation[1] = 0;
ipush_constant.sky_color_or_orientation[2] = 0;
ipush_constant.y_mult = y_mult;
ipush_constant.store_ambient_texture = false;

Expand Down
10 changes: 5 additions & 5 deletions servers/rendering/renderer_rd/environment/gi.h
Original file line number Diff line number Diff line change
Expand Up @@ -392,9 +392,9 @@ class GI : public RendererGI {
};
struct IntegratePushConstant {
enum {
SKY_MODE_DISABLED,
SKY_MODE_COLOR,
SKY_MODE_SKY,
SKY_FLAGS_MODE_COLOR = 0x01,
SKY_FLAGS_MODE_SKY = 0x02,
SKY_FLAGS_ORIENTATION_SIGN = 0x04,
};

float grid_size[3];
Expand All @@ -410,12 +410,12 @@ class GI : public RendererGI {
int32_t image_size[2];

int32_t world_offset[3];
uint32_t sky_mode;
uint32_t sky_flags;

int32_t scroll[3];
float sky_energy;

float sky_color[3];
float sky_color_or_orientation[3];
float y_mult;

uint32_t store_ambient_texture;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ layout(set = 1, binding = 1) uniform sampler linear_sampler_mipmaps;

#define HISTORY_BITS 10

#define SKY_MODE_DISABLED 0
#define SKY_MODE_COLOR 1
#define SKY_MODE_SKY 2
#define SKY_FLAGS_MODE_COLOR 0x01
#define SKY_FLAGS_MODE_SKY 0x02
#define SKY_FLAGS_ORIENTATION_SIGN 0x04

layout(push_constant, std430) uniform Params {
vec3 grid_size;
Expand All @@ -67,12 +67,12 @@ layout(push_constant, std430) uniform Params {
ivec2 image_size;

ivec3 world_offset;
uint sky_mode;
uint sky_flags;

ivec3 scroll;
float sky_energy;

vec3 sky_color;
vec3 sky_color_or_orientation;
float y_mult;

bool store_ambient_texture;
Expand Down Expand Up @@ -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
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
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
light.rgb *= params.sky_energy;
light.a = 0.0;

} else if (params.sky_mode == SKY_MODE_COLOR) {
light.rgb = params.sky_color;
} else if (bool(params.sky_flags & SKY_FLAGS_MODE_COLOR)) {
light.rgb = params.sky_color_or_orientation;
light.rgb *= params.sky_energy;
light.a = 0.0;
} else {
Expand Down