mirror of
https://github.com/godotengine/godot.git
synced 2026-02-07 19:32:36 +00:00
Merge pull request #114907 from clayjohn/RD-env-filter
Fix downsampled radiance map generation
This commit is contained in:
@@ -166,27 +166,15 @@ CopyEffects::CopyEffects(BitField<RasterEffects> p_raster_effects) {
|
||||
|
||||
{
|
||||
// Initialize octmap downsampler.
|
||||
Vector<String> downsampler_modes;
|
||||
if (raster_effects.has_flag(RASTER_EFFECT_OCTMAP)) {
|
||||
for (int i = 0; i < DOWNSAMPLER_MODE_RASTER_MAX; i++) {
|
||||
String mode;
|
||||
if (i & DOWNSAMPLER_MODE_FLAG_HIGH_QUALITY) {
|
||||
mode += "\n#define USE_HIGH_QUALITY\n";
|
||||
}
|
||||
downsampler_modes.push_back(mode);
|
||||
}
|
||||
|
||||
octmap_downsampler.raster_shader.initialize(downsampler_modes);
|
||||
if (raster_effects.has_flag(RASTER_EFFECT_OCTMAP)) {
|
||||
octmap_downsampler.raster_shader.initialize({ "" });
|
||||
octmap_downsampler.shader_version = octmap_downsampler.raster_shader.version_create();
|
||||
for (int i = 0; i < DOWNSAMPLER_MODE_RASTER_MAX; i++) {
|
||||
octmap_downsampler.raster_pipelines[i].setup(octmap_downsampler.raster_shader.version_get_shader(octmap_downsampler.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
|
||||
}
|
||||
octmap_downsampler.raster_pipeline.setup(octmap_downsampler.raster_shader.version_get_shader(octmap_downsampler.shader_version, 0), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
|
||||
} else {
|
||||
Vector<String> downsampler_modes;
|
||||
for (int i = 0; i < DOWNSAMPLER_MODE_COMPUTE_MAX; i++) {
|
||||
String mode;
|
||||
if (i & DOWNSAMPLER_MODE_FLAG_HIGH_QUALITY) {
|
||||
mode += "\n#define USE_HIGH_QUALITY\n";
|
||||
}
|
||||
if (i & DOWNSAMPLER_MODE_FLAG_RGB10_A2) {
|
||||
mode += "\n#define OCTMAP_FORMAT rgb10_a2\n";
|
||||
} else {
|
||||
@@ -1152,7 +1140,7 @@ void CopyEffects::copy_cubemap_to_octmap(RID p_source_rd_texture, RID p_dst_fram
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
void CopyEffects::octmap_downsample(RID p_source_octmap, RID p_dest_octmap, const Size2i &p_size, bool p_use_filter_quality, float p_border_size) {
|
||||
void CopyEffects::octmap_downsample(RID p_source_octmap, RID p_dest_octmap, const Size2i &p_size, float p_border_size) {
|
||||
ERR_FAIL_COND_MSG(raster_effects.has_flag(RASTER_EFFECT_OCTMAP), "Can't use compute based octmap downsample.");
|
||||
|
||||
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
|
||||
@@ -1170,9 +1158,6 @@ void CopyEffects::octmap_downsample(RID p_source_octmap, RID p_dest_octmap, cons
|
||||
RD::Uniform u_dest_octmap(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_dest_octmap }));
|
||||
|
||||
int mode = 0;
|
||||
if (!p_use_filter_quality || filter.use_high_quality) {
|
||||
mode |= DOWNSAMPLER_MODE_FLAG_HIGH_QUALITY;
|
||||
}
|
||||
|
||||
RD::TextureFormat texture_format = RD::get_singleton()->texture_get_format(p_dest_octmap);
|
||||
switch (texture_format.format) {
|
||||
@@ -1205,7 +1190,7 @@ void CopyEffects::octmap_downsample(RID p_source_octmap, RID p_dest_octmap, cons
|
||||
RD::get_singleton()->compute_list_end();
|
||||
}
|
||||
|
||||
void CopyEffects::octmap_downsample_raster(RID p_source_octmap, RID p_dest_framebuffer, const Size2i &p_size, bool p_use_filter_quality, float p_border_size) {
|
||||
void CopyEffects::octmap_downsample_raster(RID p_source_octmap, RID p_dest_framebuffer, const Size2i &p_size, float p_border_size) {
|
||||
ERR_FAIL_COND_MSG(!raster_effects.has_flag(RASTER_EFFECT_OCTMAP), "Can't use raster based octmap downsample.");
|
||||
|
||||
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
|
||||
@@ -1221,16 +1206,11 @@ void CopyEffects::octmap_downsample_raster(RID p_source_octmap, RID p_dest_frame
|
||||
|
||||
RD::Uniform u_source_cubemap(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_octmap }));
|
||||
|
||||
int mode = 0;
|
||||
if (!p_use_filter_quality || filter.use_high_quality) {
|
||||
mode |= DOWNSAMPLER_MODE_FLAG_HIGH_QUALITY;
|
||||
}
|
||||
|
||||
RID shader = octmap_downsampler.raster_shader.version_get_shader(octmap_downsampler.shader_version, mode);
|
||||
RID shader = octmap_downsampler.raster_shader.version_get_shader(octmap_downsampler.shader_version, 0);
|
||||
ERR_FAIL_COND(shader.is_null());
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::DRAW_IGNORE_COLOR_ALL);
|
||||
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, octmap_downsampler.raster_pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
|
||||
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, octmap_downsampler.raster_pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_cubemap), 0);
|
||||
|
||||
RD::get_singleton()->draw_list_set_push_constant(draw_list, &octmap_downsampler.push_constant, sizeof(OctmapDownsamplerPushConstant));
|
||||
|
||||
@@ -256,11 +256,10 @@ private:
|
||||
};
|
||||
|
||||
enum OctmapDownsamplerMode {
|
||||
DOWNSAMPLER_MODE_FLAG_HIGH_QUALITY = (1 << 0),
|
||||
DOWNSAMPLER_MODE_FLAG_RGB10_A2 = (1 << 1),
|
||||
DOWNSAMPLER_MODE_FLAG_RGB10_A2 = (1 << 0),
|
||||
|
||||
DOWNSAMPLER_MODE_COMPUTE_MAX = ((DOWNSAMPLER_MODE_FLAG_HIGH_QUALITY | DOWNSAMPLER_MODE_FLAG_RGB10_A2) + 1),
|
||||
DOWNSAMPLER_MODE_RASTER_MAX = (DOWNSAMPLER_MODE_FLAG_HIGH_QUALITY + 1),
|
||||
DOWNSAMPLER_MODE_COMPUTE_MAX = (DOWNSAMPLER_MODE_FLAG_RGB10_A2 + 1),
|
||||
DOWNSAMPLER_MODE_RASTER_MAX = 1,
|
||||
};
|
||||
|
||||
struct OctmapDownsampler {
|
||||
@@ -269,7 +268,7 @@ private:
|
||||
OctmapDownsamplerRasterShaderRD raster_shader;
|
||||
RID shader_version;
|
||||
PipelineDeferredRD compute_pipelines[DOWNSAMPLER_MODE_COMPUTE_MAX];
|
||||
PipelineCacheRD raster_pipelines[DOWNSAMPLER_MODE_RASTER_MAX];
|
||||
PipelineCacheRD raster_pipeline;
|
||||
} octmap_downsampler;
|
||||
|
||||
enum OctmapFilterMode {
|
||||
@@ -393,8 +392,8 @@ public:
|
||||
|
||||
void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, const Vector2 &p_dst_size, float p_z_near, float p_z_far, bool p_dp_flip);
|
||||
void copy_cubemap_to_octmap(RID p_source_rd_texture, RID p_dst_framebuffer, float p_border_size);
|
||||
void octmap_downsample(RID p_source_octmap, RID p_dest_octmap, const Size2i &p_size, bool p_use_filter_quality, float p_border_size);
|
||||
void octmap_downsample_raster(RID p_source_octmap, RID p_dest_framebuffer, const Size2i &p_size, bool p_use_filter_quality, float p_border_size);
|
||||
void octmap_downsample(RID p_source_octmap, RID p_dest_octmap, const Size2i &p_size, float p_border_size);
|
||||
void octmap_downsample_raster(RID p_source_octmap, RID p_dest_framebuffer, const Size2i &p_size, float p_border_size);
|
||||
void octmap_filter(RID p_source_octmap, const Vector<RID> &p_dest_octmap, bool p_use_array, float p_border_size);
|
||||
void octmap_filter_raster(RID p_source_octmap, RID p_dest_framebuffer, uint32_t p_mip_level, float p_border_size);
|
||||
void octmap_roughness(RID p_source_rd_texture, RID p_dest_texture, uint32_t p_sample_count, float p_roughness, uint32_t p_source_size, uint32_t p_dest_size, float p_border_size);
|
||||
|
||||
@@ -340,7 +340,7 @@ void SkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bo
|
||||
tf.format = p_texture_format;
|
||||
tf.width = p_low_quality ? 160 : p_size >> 1; // Always 160x160 when using REALTIME.
|
||||
tf.height = p_low_quality ? 160 : p_size >> 1;
|
||||
tf.mipmaps = p_low_quality ? 7 : mipmaps - 1;
|
||||
tf.mipmaps = p_low_quality ? 5 : mipmaps - 1;
|
||||
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
if (!use_raster_effect) {
|
||||
tf.usage_bits |= RD::TEXTURE_USAGE_STORAGE_BIT;
|
||||
@@ -378,10 +378,10 @@ void SkyRD::ReflectionData::create_reflection_fast_filter(bool p_use_arrays) {
|
||||
|
||||
if (use_raster_effect) {
|
||||
RD::get_singleton()->draw_command_begin_label("Downsample Radiance Map");
|
||||
copy_effects->octmap_downsample_raster(radiance_base_octmap, downsampled_layer.mipmaps[0].framebuffer, downsampled_layer.mipmaps[0].size, true, uv_border_size);
|
||||
copy_effects->octmap_downsample_raster(radiance_base_octmap, downsampled_layer.mipmaps[0].framebuffer, downsampled_layer.mipmaps[0].size, uv_border_size);
|
||||
|
||||
for (uint32_t i = 1; i < downsampled_layer.mipmaps.size(); i++) {
|
||||
copy_effects->octmap_downsample_raster(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].framebuffer, downsampled_layer.mipmaps[i].size, true, uv_border_size);
|
||||
copy_effects->octmap_downsample_raster(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].framebuffer, downsampled_layer.mipmaps[i].size, uv_border_size);
|
||||
}
|
||||
RD::get_singleton()->draw_command_end_label(); // Downsample Radiance
|
||||
|
||||
@@ -399,10 +399,10 @@ void SkyRD::ReflectionData::create_reflection_fast_filter(bool p_use_arrays) {
|
||||
RD::get_singleton()->draw_command_end_label(); // Filter radiance
|
||||
} else {
|
||||
RD::get_singleton()->draw_command_begin_label("Downsample Radiance Map");
|
||||
copy_effects->octmap_downsample(radiance_base_octmap, downsampled_layer.mipmaps[0].view, downsampled_layer.mipmaps[0].size, true, uv_border_size);
|
||||
copy_effects->octmap_downsample(radiance_base_octmap, downsampled_layer.mipmaps[0].view, downsampled_layer.mipmaps[0].size, uv_border_size);
|
||||
|
||||
for (uint32_t i = 1; i < downsampled_layer.mipmaps.size(); i++) {
|
||||
copy_effects->octmap_downsample(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].view, downsampled_layer.mipmaps[i].size, true, uv_border_size);
|
||||
copy_effects->octmap_downsample(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].view, downsampled_layer.mipmaps[i].size, uv_border_size);
|
||||
}
|
||||
RD::get_singleton()->draw_command_end_label(); // Downsample Radiance
|
||||
Vector<RID> views;
|
||||
@@ -429,10 +429,10 @@ void SkyRD::ReflectionData::create_reflection_importance_sample(bool p_use_array
|
||||
if (use_raster_effect) {
|
||||
if (p_base_layer == 1) {
|
||||
RD::get_singleton()->draw_command_begin_label("Downsample Radiance Map");
|
||||
copy_effects->octmap_downsample_raster(radiance_base_octmap, downsampled_layer.mipmaps[0].framebuffer, downsampled_layer.mipmaps[0].size, false, uv_border_size);
|
||||
copy_effects->octmap_downsample_raster(radiance_base_octmap, downsampled_layer.mipmaps[0].framebuffer, downsampled_layer.mipmaps[0].size, uv_border_size);
|
||||
|
||||
for (uint32_t i = 1; i < downsampled_layer.mipmaps.size(); i++) {
|
||||
copy_effects->octmap_downsample_raster(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].framebuffer, downsampled_layer.mipmaps[i].size, false, uv_border_size);
|
||||
copy_effects->octmap_downsample_raster(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].framebuffer, downsampled_layer.mipmaps[i].size, uv_border_size);
|
||||
}
|
||||
RD::get_singleton()->draw_command_end_label(); // Downsample Radiance
|
||||
}
|
||||
@@ -460,10 +460,10 @@ void SkyRD::ReflectionData::create_reflection_importance_sample(bool p_use_array
|
||||
} else {
|
||||
if (p_base_layer == 1) {
|
||||
RD::get_singleton()->draw_command_begin_label("Downsample Radiance Map");
|
||||
copy_effects->octmap_downsample(radiance_base_octmap, downsampled_layer.mipmaps[0].view, downsampled_layer.mipmaps[0].size, false, uv_border_size);
|
||||
copy_effects->octmap_downsample(radiance_base_octmap, downsampled_layer.mipmaps[0].view, downsampled_layer.mipmaps[0].size, uv_border_size);
|
||||
|
||||
for (uint32_t i = 1; i < downsampled_layer.mipmaps.size(); i++) {
|
||||
copy_effects->octmap_downsample(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].view, downsampled_layer.mipmaps[i].size, false, uv_border_size);
|
||||
copy_effects->octmap_downsample(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].view, downsampled_layer.mipmaps[i].size, uv_border_size);
|
||||
}
|
||||
RD::get_singleton()->draw_command_end_label(); // Downsample Radiance
|
||||
}
|
||||
@@ -490,10 +490,10 @@ void SkyRD::ReflectionData::update_reflection_mipmaps(int p_start, int p_end) {
|
||||
Size2i size = layers[i].mipmaps[j + 1].size;
|
||||
if (use_raster_effect) {
|
||||
RID framebuffer = layers[i].mipmaps[j + 1].framebuffer;
|
||||
copy_effects->octmap_downsample_raster(view, framebuffer, size, false, uv_border_size);
|
||||
copy_effects->octmap_downsample_raster(view, framebuffer, size, uv_border_size);
|
||||
} else {
|
||||
RID texture = layers[i].mipmaps[j + 1].view;
|
||||
copy_effects->octmap_downsample(view, texture, size, false, uv_border_size);
|
||||
copy_effects->octmap_downsample(view, texture, size, uv_border_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ params;
|
||||
|
||||
// Use an approximation of the Jacobian.
|
||||
float calcWeight(float u, float v) {
|
||||
vec3 d = oct_to_vec3_with_border(vec2(u, v), params.border_size);
|
||||
vec3 d = oct_to_vec3_with_border(vec2(u, v) * 0.5 + 0.5, params.border_size);
|
||||
return 1.0 / pow(abs(d.z) + 1.0, 3.0);
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ void main() {
|
||||
float inv_size = 1.0 / float(params.size);
|
||||
uvec2 sample_id = id;
|
||||
|
||||
#ifdef USE_HIGH_QUALITY
|
||||
float u0 = (float(sample_id.x) * 2.0f + 1.0f - 0.75f) * inv_size - 1.0f;
|
||||
float u1 = (float(sample_id.x) * 2.0f + 1.0f + 0.75f) * inv_size - 1.0f;
|
||||
float v0 = (float(sample_id.y) * 2.0f + 1.0f - 0.75f) * inv_size - 1.0f;
|
||||
@@ -75,9 +74,5 @@ void main() {
|
||||
color += textureLod(source_octmap, vec2(u0, v1) * 0.5f + 0.5f, 0.0) * weights[2];
|
||||
color += textureLod(source_octmap, vec2(u1, v1) * 0.5f + 0.5f, 0.0) * weights[3];
|
||||
imageStore(dest_octmap, ivec2(id), color);
|
||||
#else
|
||||
vec2 uv = (vec2(sample_id.xy) + 0.5) * inv_size;
|
||||
imageStore(dest_octmap, ivec2(id), textureLod(source_octmap, uv, 0.0));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user