summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp26
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_effects_rd.h6
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp60
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_scene_rd.h3
-rw-r--r--servers/visual/rasterizer_rd/shaders/cubemap_roughness.glsl73
5 files changed, 76 insertions, 92 deletions
diff --git a/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp
index f4d59e9e54..85750df9d1 100644
--- a/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp
@@ -248,26 +248,30 @@ void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_framebuff
RD::get_singleton()->draw_list_end();
}
-void RasterizerEffectsRD::cubemap_roughness(RID p_source_rd_texture, bool p_source_is_panorama, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness) {
+void RasterizerEffectsRD::cubemap_roughness(RID p_source_rd_texture, bool p_source_is_panorama, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size) {
zeromem(&roughness.push_constant, sizeof(CubemapRoughnessPushConstant));
- roughness.push_constant.face_id = p_face_id;
+ roughness.push_constant.face_id = p_face_id > 9 ? 0 : p_face_id;
roughness.push_constant.roughness = p_roughness;
roughness.push_constant.sample_count = p_sample_count;
roughness.push_constant.use_direct_write = p_roughness == 0.0;
+ roughness.push_constant.face_size = p_size;
- //RUN
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, roughness.pipelines[p_source_is_panorama ? CUBEMAP_ROUGHNESS_SOURCE_PANORAMA : CUBEMAP_ROUGHNESS_SOURCE_CUBEMAP].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, roughness.pipelines[p_source_is_panorama ? CUBEMAP_ROUGHNESS_SOURCE_PANORAMA : CUBEMAP_ROUGHNESS_SOURCE_CUBEMAP]);
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_framebuffer), 1);
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &roughness.push_constant, sizeof(CubemapRoughnessPushConstant));
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &roughness.push_constant, sizeof(CubemapRoughnessPushConstant));
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
+ int x_groups = (p_size - 1) / 8 + 1;
+ int y_groups = (p_size - 1) / 8 + 1;
+
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, p_face_id > 9 ? 6 : 1);
+
+ RD::get_singleton()->compute_list_end();
}
void RasterizerEffectsRD::render_panorama(RD::DrawListID p_list, RenderingDevice::FramebufferFormatID p_fb_format, RID p_panorama, const CameraMatrix &p_camera, const Basis &p_orientation, float p_alpha, float p_multipler) {
@@ -841,7 +845,7 @@ RasterizerEffectsRD::RasterizerEffectsRD() {
roughness.shader_version = roughness.shader.version_create();
for (int i = 0; i < CUBEMAP_ROUGHNESS_SOURCE_MAX; i++) {
- roughness.pipelines[i].setup(roughness.shader.version_get_shader(roughness.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
+ roughness.pipelines[i] = RD::get_singleton()->compute_pipeline_create(roughness.shader.version_get_shader(roughness.shader_version, i));
}
}
diff --git a/servers/visual/rasterizer_rd/rasterizer_effects_rd.h b/servers/visual/rasterizer_rd/rasterizer_effects_rd.h
index 8ec202c399..fbf6b39ecb 100644
--- a/servers/visual/rasterizer_rd/rasterizer_effects_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_effects_rd.h
@@ -127,6 +127,8 @@ class RasterizerEffectsRD {
uint32_t sample_count;
float roughness;
uint32_t use_direct_write;
+ float face_size;
+ float pad[3];
};
struct CubemapRoughness {
@@ -134,7 +136,7 @@ class RasterizerEffectsRD {
CubemapRoughnessPushConstant push_constant;
CubemapRoughnessShaderRD shader;
RID shader_version;
- RenderPipelineVertexFormatCacheRD pipelines[CUBEMAP_ROUGHNESS_SOURCE_MAX];
+ RID pipelines[CUBEMAP_ROUGHNESS_SOURCE_MAX];
} roughness;
struct SkyPushConstant {
@@ -419,7 +421,7 @@ public:
void gaussian_blur(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, const Rect2 &p_region);
void gaussian_glow(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, float p_strength = 1.0, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_treshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0);
- void cubemap_roughness(RID p_source_rd_texture, bool p_source_is_panorama, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness);
+ void cubemap_roughness(RID p_source_rd_texture, bool p_source_is_panorama, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
void render_panorama(RD::DrawListID p_list, RenderingDevice::FramebufferFormatID p_fb_format, RID p_panorama, const CameraMatrix &p_camera, const Basis &p_orientation, float p_alpha, float p_multipler);
void make_mipmap(RID p_source_rd_texture, RID p_framebuffer_half, const Vector2 &p_pixel_size);
void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip);
diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp
index 4a78fa89ba..457f6970c8 100644
--- a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp
@@ -146,9 +146,7 @@ void RasterizerSceneRD::_create_reflection_from_panorama(ReflectionData &rd, RID
if (p_quality) {
//render directly to the layers
for (int i = 0; i < rd.layers.size(); i++) {
- for (int j = 0; j < 6; j++) {
- storage->get_effects()->cubemap_roughness(p_panorama, true, rd.layers[i].mipmaps[0].framebuffers[j], j, sky_ggx_samples_quality, float(i) / (rd.layers.size() - 1.0));
- }
+ storage->get_effects()->cubemap_roughness(p_panorama, true, rd.layers[i].views[0], 10, sky_ggx_samples_quality, float(i) / (rd.layers.size() - 1.0), rd.layers[i].mipmaps[0].size.x);
}
} else {
// Use fast filtering. Render directly to base mip levels
@@ -169,9 +167,7 @@ void RasterizerSceneRD::_create_reflection_from_panorama(ReflectionData &rd, RID
if (p_quality) {
//render directly to the layers
for (int i = 0; i < rd.layers[0].mipmaps.size(); i++) {
- for (int j = 0; j < 6; j++) {
- storage->get_effects()->cubemap_roughness(p_panorama, true, rd.layers[0].mipmaps[i].framebuffers[j], j, sky_ggx_samples_quality, float(i) / (rd.layers[0].mipmaps.size() - 1.0));
- }
+ storage->get_effects()->cubemap_roughness(p_panorama, true, rd.layers[0].views[i], 10, sky_ggx_samples_quality, float(i) / (rd.layers[0].mipmaps.size() - 1.0), rd.layers[0].mipmaps[i].size.x);
}
} else {
// Use fast filtering. Render directly to each mip level
@@ -185,15 +181,13 @@ void RasterizerSceneRD::_create_reflection_from_panorama(ReflectionData &rd, RID
}
}
-void RasterizerSceneRD::_create_reflection_from_base_mipmap(ReflectionData &rd, bool p_use_arrays, bool p_quality, int p_cube_side) {
+void RasterizerSceneRD::_create_reflection_from_base_mipmap(ReflectionData &rd, bool p_use_arrays, bool p_quality, int p_cube_side, int p_base_layer) {
if (p_use_arrays) {
if (p_quality) {
//render directly to the layers
- for (int i = 1; i < rd.layers.size(); i++) {
- storage->get_effects()->cubemap_roughness(rd.radiance_base_cubemap, false, rd.layers[i].mipmaps[0].framebuffers[p_cube_side], p_cube_side, sky_ggx_samples_quality, float(i) / (rd.layers.size() - 1.0));
- }
+ storage->get_effects()->cubemap_roughness(rd.radiance_base_cubemap, false, rd.layers[p_base_layer].views[0], p_cube_side, sky_ggx_samples_quality, float(p_base_layer) / (rd.layers.size() - 1.0), rd.layers[p_base_layer].mipmaps[0].size.x);
} else {
storage->get_effects()->cubemap_downsample(rd.radiance_base_cubemap, false, rd.downsampled_layer.mipmaps[0].view, rd.downsampled_layer.mipmaps[0].size);
@@ -211,10 +205,8 @@ void RasterizerSceneRD::_create_reflection_from_base_mipmap(ReflectionData &rd,
} else {
if (p_quality) {
- //render directly to the layers
- for (int i = 1; i < rd.layers[0].mipmaps.size(); i++) {
- storage->get_effects()->cubemap_roughness(rd.radiance_base_cubemap, false, rd.layers[0].mipmaps[i].framebuffers[p_cube_side], p_cube_side, sky_ggx_samples_quality, float(i) / (rd.layers[0].mipmaps.size() - 1.0));
- }
+
+ storage->get_effects()->cubemap_roughness(rd.layers[0].views[p_base_layer - 1], false, rd.layers[0].views[p_base_layer], p_cube_side, sky_ggx_samples_quality, float(p_base_layer) / (rd.layers[0].mipmaps.size() - 1.0), rd.layers[0].mipmaps[p_base_layer].size.x);
} else {
storage->get_effects()->cubemap_downsample(rd.radiance_base_cubemap, false, rd.downsampled_layer.mipmaps[0].view, rd.downsampled_layer.mipmaps[0].size);
@@ -742,6 +734,21 @@ bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, R
reflection_atlas_set_size(p_reflection_atlas, 128, atlas->count);
}
+ if (storage->reflection_probe_get_update_mode(rpi->probe) == VS::REFLECTION_PROBE_UPDATE_ALWAYS && atlas->reflection.is_valid() && atlas->reflections[0].data.layers[0].mipmaps.size() != 7) {
+ // Invalidate reflection atlas, need to regenerate
+ RD::get_singleton()->free(atlas->reflection);
+ atlas->reflection = RID();
+
+ for (int i = 0; i < atlas->reflections.size(); i++) {
+ if (atlas->reflections[i].owner.is_null()) {
+ continue;
+ }
+ reflection_probe_release_atlas_index(atlas->reflections[i].owner);
+ }
+
+ atlas->reflections.clear();
+ }
+
if (atlas->reflection.is_null()) {
int mipmaps = MIN(roughness_layers, Image::get_image_required_mipmaps(atlas->size, atlas->size, Image::FORMAT_RGBAH) + 1);
mipmaps = storage->reflection_probe_get_update_mode(rpi->probe) == VS::REFLECTION_PROBE_UPDATE_ALWAYS ? 7 : mipmaps; // always use 7 mipmaps with real time filtering
@@ -808,6 +815,7 @@ bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, R
rpi->atlas = p_reflection_atlas;
rpi->rendering = true;
rpi->dirty = false;
+ rpi->processing_layer = 1;
rpi->processing_side = 0;
return true;
@@ -827,24 +835,36 @@ bool RasterizerSceneRD::reflection_probe_instance_postprocess_step(RID p_instanc
return false;
}
- _create_reflection_from_base_mipmap(atlas->reflections.write[rpi->atlas_index].data, false, storage->reflection_probe_get_update_mode(rpi->probe) == VS::REFLECTION_PROBE_UPDATE_ONCE, rpi->processing_side);
+ if (rpi->processing_layer > 1) {
+ _create_reflection_from_base_mipmap(atlas->reflections.write[rpi->atlas_index].data, false, storage->reflection_probe_get_update_mode(rpi->probe) == VS::REFLECTION_PROBE_UPDATE_ONCE, 10, rpi->processing_layer);
+ rpi->processing_layer++;
+ if (rpi->processing_layer == atlas->reflections[rpi->atlas_index].data.layers[0].mipmaps.size()) {
+ rpi->rendering = false;
+ rpi->processing_side = 0;
+ rpi->processing_layer = 1;
+ return true;
+ }
+ return false;
+
+ } else {
+ _create_reflection_from_base_mipmap(atlas->reflections.write[rpi->atlas_index].data, false, storage->reflection_probe_get_update_mode(rpi->probe) == VS::REFLECTION_PROBE_UPDATE_ONCE, rpi->processing_side, rpi->processing_layer);
+ }
if (storage->reflection_probe_get_update_mode(rpi->probe) == VS::REFLECTION_PROBE_UPDATE_ALWAYS) {
// Using real time reflections, all roughness is done in one step
rpi->rendering = false;
rpi->processing_side = 0;
+ rpi->processing_layer = 1;
return true;
}
rpi->processing_side++;
-
if (rpi->processing_side == 6) {
- rpi->rendering = false;
rpi->processing_side = 0;
- return true;
- } else {
- return false;
+ rpi->processing_layer++;
}
+
+ return false;
}
uint32_t RasterizerSceneRD::reflection_probe_instance_get_resolution(RID p_instance) {
diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_rd.h b/servers/visual/rasterizer_rd/rasterizer_scene_rd.h
index 3e3ad5e4f5..0fa853f2df 100644
--- a/servers/visual/rasterizer_rd/rasterizer_scene_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_scene_rd.h
@@ -108,7 +108,7 @@ private:
void _clear_reflection_data(ReflectionData &rd);
void _update_reflection_data(ReflectionData &rd, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality);
void _create_reflection_from_panorama(ReflectionData &rd, RID p_panorama, bool p_quality);
- void _create_reflection_from_base_mipmap(ReflectionData &rd, bool p_use_arrays, bool p_quality, int p_cube_side);
+ void _create_reflection_from_base_mipmap(ReflectionData &rd, bool p_use_arrays, bool p_quality, int p_cube_side, int p_base_layer);
void _update_reflection_mipmaps(ReflectionData &rd, bool p_quality);
/* SKY */
@@ -165,6 +165,7 @@ private:
bool dirty = true;
bool rendering = false;
+ int processing_layer = 1;
int processing_side = 0;
uint32_t render_step = 0;
diff --git a/servers/visual/rasterizer_rd/shaders/cubemap_roughness.glsl b/servers/visual/rasterizer_rd/shaders/cubemap_roughness.glsl
index 011dfce985..3dba143e56 100644
--- a/servers/visual/rasterizer_rd/shaders/cubemap_roughness.glsl
+++ b/servers/visual/rasterizer_rd/shaders/cubemap_roughness.glsl
@@ -1,83 +1,38 @@
/* clang-format off */
-[vertex]
+[compute]
#version 450
VERSION_DEFINES
-layout(location = 0) out highp vec2 uv_interp;
-/* clang-format on */
-
-void main() {
-
- vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
- uv_interp = base_arr[gl_VertexIndex];
- gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0);
-}
-
-/* clang-format off */
-[fragment]
-
-#version 450
+#define GROUP_SIZE 8
-VERSION_DEFINES
+layout(local_size_x = GROUP_SIZE, local_size_y = GROUP_SIZE, local_size_z = 1) in;
+/* clang-format on */
#ifdef MODE_SOURCE_PANORAMA
layout(set = 0, binding = 0) uniform sampler2D source_panorama;
-/* clang-format on */
#endif
#ifdef MODE_SOURCE_CUBEMAP
layout(set = 0, binding = 0) uniform samplerCube source_cube;
#endif
+layout(rgba16f, set = 1, binding = 0) uniform restrict writeonly imageCube dest_cubemap;
+
layout(push_constant, binding = 1, std430) uniform Params {
uint face_id;
uint sample_count;
float roughness;
bool use_direct_write;
+ float face_size;
}
params;
-layout(location = 0) in vec2 uv_interp;
-
-layout(location = 0) out vec4 frag_color;
-
#define M_PI 3.14159265359
vec3 texelCoordToVec(vec2 uv, uint faceID) {
mat3 faceUvVectors[6];
- /*
- // -x
- faceUvVectors[0][0] = vec3(0.0, 0.0, 1.0); // u -> +z
- faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y
- faceUvVectors[0][2] = vec3(-1.0, 0.0, 0.0); // -x face
-
- // +x
- faceUvVectors[1][0] = vec3(0.0, 0.0, -1.0); // u -> -z
- faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y
- faceUvVectors[1][2] = vec3(1.0, 0.0, 0.0); // +x face
-
- // -y
- faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x
- faceUvVectors[2][1] = vec3(0.0, 0.0, -1.0); // v -> -z
- faceUvVectors[2][2] = vec3(0.0, -1.0, 0.0); // -y face
-
- // +y
- faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x
- faceUvVectors[3][1] = vec3(0.0, 0.0, 1.0); // v -> +z
- faceUvVectors[3][2] = vec3(0.0, 1.0, 0.0); // +y face
-
- // -z
- faceUvVectors[4][0] = vec3(-1.0, 0.0, 0.0); // u -> -x
- faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y
- faceUvVectors[4][2] = vec3(0.0, 0.0, -1.0); // -z face
-
- // +z
- faceUvVectors[5][0] = vec3(1.0, 0.0, 0.0); // u -> +x
- faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y
- faceUvVectors[5][2] = vec3(0.0, 0.0, 1.0); // +z face
- */
// -x
faceUvVectors[1][0] = vec3(0.0, 0.0, 1.0); // u -> +z
@@ -179,21 +134,23 @@ vec4 texturePanorama(vec3 normal, sampler2D pano) {
#endif
void main() {
+ uvec3 id = gl_GlobalInvocationID;
+ id.z += params.face_id;
- vec2 uv = (uv_interp * 2.0) - 1.0;
- vec3 N = texelCoordToVec(uv, params.face_id);
+ vec2 uv = ((vec2(id.xy) * 2.0 + 1.0) / (params.face_size) - 1.0);
+ vec3 N = texelCoordToVec(uv, id.z);
//vec4 color = color_interp;
if (params.use_direct_write) {
#ifdef MODE_SOURCE_PANORAMA
-
- frag_color = vec4(texturePanorama(N, source_panorama).rgb, 1.0);
+ imageStore(dest_cubemap, ivec3(id), vec4(texturePanorama(N, source_panorama).rgb, 1.0));
#endif
#ifdef MODE_SOURCE_CUBEMAP
- frag_color = vec4(texture(source_cube, N).rgb, 1.0);
+ imageStore(dest_cubemap, ivec3(id), vec4(texture(source_cube, N).rgb, 1.0));
+
#endif
} else {
@@ -222,6 +179,6 @@ void main() {
}
sum /= sum.a;
- frag_color = vec4(sum.rgb, 1.0);
+ imageStore(dest_cubemap, ivec3(id), vec4(sum.rgb, 1.0));
}
}