summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2019-08-26 17:43:58 -0300
committerJuan Linietsky <reduzio@gmail.com>2020-02-11 12:01:05 +0100
commit2d6a916835bd851b2ea03a2e887ba83f0065dae4 (patch)
tree25542172b4275da52396b40033d8e77f7e2ce64c /servers
parentf7aa7927e7268f7b9f99eed18e13dd04e25be8b2 (diff)
Environment sky more or less working.
Diffstat (limited to 'servers')
-rw-r--r--servers/visual/rasterizer.h21
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp70
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp155
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_effects_rd.h47
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_rd.h2
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp374
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.h33
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp391
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_scene_rd.h113
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp55
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_storage_rd.h7
-rw-r--r--servers/visual/rasterizer_rd/shaders/SCsub4
-rw-r--r--servers/visual/rasterizer_rd/shaders/blur.glsl11
-rw-r--r--servers/visual/rasterizer_rd/shaders/canvas.glsl12
-rw-r--r--servers/visual/rasterizer_rd/shaders/cubemap_roughness.glsl234
-rw-r--r--servers/visual/rasterizer_rd/shaders/scene_forward.glsl66
-rw-r--r--servers/visual/rasterizer_rd/shaders/scene_forward_inc.glsl39
-rw-r--r--servers/visual/rasterizer_rd/shaders/sky.glsl89
-rw-r--r--servers/visual/rendering_device.h8
-rw-r--r--servers/visual/visual_server_raster.cpp2
-rw-r--r--servers/visual/visual_server_raster.h15
-rw-r--r--servers/visual/visual_server_scene.cpp4
-rw-r--r--servers/visual/visual_server_wrap_mt.h15
-rw-r--r--servers/visual_server.cpp21
-rw-r--r--servers/visual_server.h35
25 files changed, 1572 insertions, 251 deletions
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 8df43bc695..c6517a12ed 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -49,6 +49,13 @@ public:
virtual int get_directional_light_shadow_size(RID p_light_intance) = 0;
virtual void set_directional_shadow_count(int p_count) = 0;
+ /* SKY API */
+
+ virtual RID sky_create() = 0;
+ virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0;
+ virtual void sky_set_mode(RID p_sky, VS::SkyMode p_samples) = 0;
+ virtual void sky_set_texture(RID p_sky, RID p_panorama) = 0;
+
/* ENVIRONMENT API */
virtual RID environment_create() = 0;
@@ -60,7 +67,7 @@ public:
virtual void environment_set_bg_color(RID p_env, const Color &p_color) = 0;
virtual void environment_set_bg_energy(RID p_env, float p_energy) = 0;
virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0;
- virtual void environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy = 1.0, float p_sky_contribution = 0.0) = 0;
+ virtual void environment_set_ambient_light(RID p_env, const Color &p_color, VS::EnvironmentAmbientSource p_ambient = VS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, VS::EnvironmentReflectionSource p_reflection_source = VS::ENV_REFLECTION_SOURCE_BG) = 0;
// FIXME: Disabled during Vulkan refactoring, should be ported.
#if 0
virtual void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) = 0;
@@ -82,9 +89,9 @@ public:
virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;
virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0;
- virtual bool is_environment(RID p_env) = 0;
- virtual VS::EnvironmentBG environment_get_background(RID p_env) = 0;
- virtual int environment_get_canvas_max_layer(RID p_env) = 0;
+ virtual bool is_environment(RID p_env) const = 0;
+ virtual VS::EnvironmentBG environment_get_background(RID p_env) const = 0;
+ virtual int environment_get_canvas_max_layer(RID p_env) const = 0;
struct InstanceBase;
@@ -258,6 +265,7 @@ public:
virtual bool free(RID p_rid) = 0;
+ virtual void update() = 0;
virtual ~RasterizerScene() {}
};
@@ -304,11 +312,6 @@ public:
virtual Size2 texture_size_with_proxy(RID p_proxy) = 0;
- /* SKY API */
-
- virtual RID sky_create() = 0;
- virtual void sky_set_texture(RID p_sky, RID p_cube_map, int p_radiance_size) = 0;
-
/* SHADER API */
virtual RID shader_create() = 0;
diff --git a/servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp
index 130e0e15b7..bf2214752d 100644
--- a/servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp
@@ -265,10 +265,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
if ((uint32_t)p_uvs.size() == vertex_count) {
stride += 2;
}
- if ((uint32_t)p_bones.size() == vertex_count * 4) {
- stride += 4;
- }
- if ((uint32_t)p_weights.size() == vertex_count * 4) {
+ if ((uint32_t)p_bones.size() == vertex_count * 4 && (uint32_t)p_weights.size() == vertex_count * 4) {
stride += 4;
}
@@ -277,9 +274,9 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
PoolVector<uint8_t> polygon_buffer;
polygon_buffer.resize(buffer_size * sizeof(float));
Vector<RD::VertexDescription> descriptions;
- descriptions.resize(5);
+ descriptions.resize(4);
Vector<RID> buffers;
- buffers.resize(5);
+ buffers.resize(4);
{
PoolVector<uint8_t>::Read r = polygon_buffer.read();
@@ -374,7 +371,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
}
//bones
- if ((uint32_t)p_indices.size() == vertex_count * 4) {
+ if ((uint32_t)p_indices.size() == vertex_count * 4 && (uint32_t)p_weights.size() == vertex_count * 4) {
RD::VertexDescription vd;
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
vd.offset = base_offset * sizeof(float);
@@ -384,12 +381,22 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
descriptions.write[3] = vd;
const int *bone_ptr = p_bones.ptr();
+ const float *weight_ptr = p_weights.ptr();
for (uint32_t i = 0; i < vertex_count; i++) {
- uptr[base_offset + i * stride + 0] = bone_ptr[i * 4 + 0];
- uptr[base_offset + i * stride + 1] = bone_ptr[i * 4 + 1];
- uptr[base_offset + i * stride + 2] = bone_ptr[i * 4 + 2];
- uptr[base_offset + i * stride + 3] = bone_ptr[i * 4 + 3];
+
+ uint16_t *bone16w = (uint16_t *)&uptr[base_offset + i * stride];
+ uint16_t *weight16w = (uint16_t *)&uptr[base_offset + i * stride + 2];
+
+ bone16w[0] = bone_ptr[i * 4 + 0];
+ bone16w[1] = bone_ptr[i * 4 + 1];
+ bone16w[2] = bone_ptr[i * 4 + 2];
+ bone16w[3] = bone_ptr[i * 4 + 3];
+
+ weight16w[0] = CLAMP(weight_ptr[i * 4 + 0] * 65535, 0, 65535);
+ weight16w[1] = CLAMP(weight_ptr[i * 4 + 1] * 65535, 0, 65535);
+ weight16w[2] = CLAMP(weight_ptr[i * 4 + 2] * 65535, 0, 65535);
+ weight16w[3] = CLAMP(weight_ptr[i * 4 + 3] * 65535, 0, 65535);
}
base_offset += 4;
@@ -404,37 +411,6 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
buffers.write[3] = storage->mesh_get_default_rd_buffer(RasterizerStorageRD::DEFAULT_RD_BUFFER_BONES);
}
- //bones
- if ((uint32_t)p_weights.size() == vertex_count * 4) {
- RD::VertexDescription vd;
- vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
- vd.offset = base_offset * sizeof(float);
- vd.location = VS::ARRAY_WEIGHTS;
- vd.stride = stride * sizeof(float);
-
- descriptions.write[4] = vd;
-
- const float *weight_ptr = p_weights.ptr();
-
- for (uint32_t i = 0; i < vertex_count; i++) {
- fptr[base_offset + i * stride + 0] = weight_ptr[i * 4 + 0];
- fptr[base_offset + i * stride + 1] = weight_ptr[i * 4 + 1];
- fptr[base_offset + i * stride + 2] = weight_ptr[i * 4 + 2];
- fptr[base_offset + i * stride + 3] = weight_ptr[i * 4 + 3];
- }
-
- base_offset += 4;
- } else {
- RD::VertexDescription vd;
- vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
- vd.offset = 0;
- vd.location = VS::ARRAY_WEIGHTS;
- vd.stride = 0;
-
- descriptions.write[4] = vd;
- buffers.write[4] = storage->mesh_get_default_rd_buffer(RasterizerStorageRD::DEFAULT_RD_BUFFER_WEIGHTS);
- }
-
//check that everything is as it should be
ERR_FAIL_COND_V(base_offset != stride, 0); //bug
}
@@ -913,7 +889,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
ERR_CONTINUE(!pb);
//bind pipeline
{
- static const PipelineVariant variant[VS::PRIMITIVE_MAX] = { PIPELINE_VARIANT_ATTRIBUTE_POINTS, PIPELINE_VARIANT_ATTRIBUTE_LINES, PIPELINE_VARIANT_ATTRIBUTE_TRIANGLES };
+ static const PipelineVariant variant[VS::PRIMITIVE_MAX] = { PIPELINE_VARIANT_ATTRIBUTE_POINTS, PIPELINE_VARIANT_ATTRIBUTE_LINES, PIPELINE_VARIANT_ATTRIBUTE_LINES_STRIP, PIPELINE_VARIANT_ATTRIBUTE_TRIANGLES, PIPELINE_VARIANT_ATTRIBUTE_TRIANGLE_STRIP };
ERR_CONTINUE(polygon->primitive < 0 || polygon->primitive >= VS::PRIMITIVE_MAX);
RID pipeline = pipeline_variants->variants[light_mode][variant[polygon->primitive]].get_render_pipeline(pb->vertex_format_id, p_framebuffer_format);
RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline);
@@ -1976,9 +1952,12 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) {
RD::RENDER_PRIMITIVE_LINES,
RD::RENDER_PRIMITIVE_POINTS,
RD::RENDER_PRIMITIVE_TRIANGLES,
+ RD::RENDER_PRIMITIVE_TRIANGLE_STRIPS,
RD::RENDER_PRIMITIVE_LINES,
+ RD::RENDER_PRIMITIVE_LINESTRIPS,
RD::RENDER_PRIMITIVE_POINTS,
};
+
ShaderVariant shader_variants[PIPELINE_LIGHT_MODE_MAX][PIPELINE_VARIANT_MAX] = {
{ //non lit
SHADER_VARIANT_QUAD,
@@ -1988,6 +1967,8 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) {
SHADER_VARIANT_PRIMITIVE_POINTS,
SHADER_VARIANT_ATTRIBUTES,
SHADER_VARIANT_ATTRIBUTES,
+ SHADER_VARIANT_ATTRIBUTES,
+ SHADER_VARIANT_ATTRIBUTES,
SHADER_VARIANT_ATTRIBUTES_POINTS },
{ //lit
SHADER_VARIANT_QUAD_LIGHT,
@@ -1997,6 +1978,8 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) {
SHADER_VARIANT_PRIMITIVE_POINTS_LIGHT,
SHADER_VARIANT_ATTRIBUTES_LIGHT,
SHADER_VARIANT_ATTRIBUTES_LIGHT,
+ SHADER_VARIANT_ATTRIBUTES_LIGHT,
+ SHADER_VARIANT_ATTRIBUTES_LIGHT,
SHADER_VARIANT_ATTRIBUTES_POINTS_LIGHT },
};
@@ -2283,6 +2266,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
RD::RENDER_PRIMITIVE_LINESTRIPS,
RD::RENDER_PRIMITIVE_POINTS,
};
+
ShaderVariant shader_variants[PIPELINE_LIGHT_MODE_MAX][PIPELINE_VARIANT_MAX] = {
{ //non lit
SHADER_VARIANT_QUAD,
diff --git a/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp
index 765e718279..121cc5b48a 100644
--- a/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp
@@ -1,5 +1,20 @@
#include "rasterizer_effects_rd.h"
+static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_array) {
+ p_array[0] = p_basis.elements[0][0];
+ p_array[1] = p_basis.elements[1][0];
+ p_array[2] = p_basis.elements[2][0];
+ p_array[3] = 0;
+ p_array[4] = p_basis.elements[0][1];
+ p_array[5] = p_basis.elements[1][1];
+ p_array[6] = p_basis.elements[2][1];
+ p_array[7] = 0;
+ p_array[8] = p_basis.elements[0][2];
+ p_array[9] = p_basis.elements[1][2];
+ p_array[10] = p_basis.elements[2][2];
+ p_array[11] = 0;
+}
+
RID RasterizerEffectsRD::_get_uniform_set_from_texture(RID p_texture) {
if (texture_to_uniform_set_cache.has(p_texture)) {
@@ -86,31 +101,127 @@ void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_framebuff
RD::get_singleton()->draw_list_end();
}
-RasterizerEffectsRD::RasterizerEffectsRD() {
+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) {
+
+ zeromem(&roughness.push_constant, sizeof(CubemapRoughnessPushConstant));
+
+ roughness.push_constant.face_id = 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;
+
+ //RUN
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP_COLOR, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH);
+ 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::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()->draw_list_set_push_constant(draw_list, &roughness.push_constant, sizeof(CubemapRoughnessPushConstant));
+
+ RD::get_singleton()->draw_list_draw(draw_list, true);
+ RD::get_singleton()->draw_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) {
+
+ zeromem(&sky.push_constant, sizeof(SkyPushConstant));
+
+ sky.push_constant.proj[0] = p_camera.matrix[2][0];
+ sky.push_constant.proj[1] = p_camera.matrix[0][0];
+ sky.push_constant.proj[2] = p_camera.matrix[2][1];
+ sky.push_constant.proj[3] = p_camera.matrix[1][1];
+ sky.push_constant.alpha = p_alpha;
+ sky.push_constant.depth = 1.0;
+ sky.push_constant.multiplier = p_multipler;
+ store_transform_3x3(p_orientation, sky.push_constant.orientation);
+
+ RD::DrawListID draw_list = p_list;
+
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, sky.pipeline.get_render_pipeline(RD::INVALID_ID, p_fb_format));
+
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_panorama), 0);
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
+
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &sky.push_constant, sizeof(SkyPushConstant));
+
+ RD::get_singleton()->draw_list_draw(draw_list, true);
+}
+
+void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_framebuffer, const Vector2 &p_pixel_size) {
- // Initialize blur
- Vector<String> blur_modes;
- blur_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n");
- blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n");
- blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n");
- blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_LOW\n");
- blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_MEDIUM\n");
- blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_HIGH\n");
- blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_LOW\n#define DOF_NEAR_BLUR_MERGE\n");
- blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_MEDIUM\n#define DOF_NEAR_BLUR_MERGE\n");
- blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_HIGH\n#define DOF_NEAR_BLUR_MERGE\n");
- blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_LOW\n");
- blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_MEDIUM\n");
- blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_HIGH\n");
- blur_modes.push_back("\n#define MODE_SSAO_MERGE\n");
- blur_modes.push_back("\n#define MODE_SIMPLE_COPY\n");
-
- blur.shader.initialize(blur_modes);
zeromem(&blur.push_constant, sizeof(BlurPushConstant));
- blur.shader_version = blur.shader.version_create();
- for (int i = 0; i < BLUR_MODE_MAX; i++) {
- blur.pipelines[i].setup(blur.shader.version_get_shader(blur.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
+ blur.push_constant.pixel_size[0] = p_pixel_size.x;
+ blur.push_constant.pixel_size[1] = p_pixel_size.y;
+
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP_COLOR, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH);
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_MIPMAP].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, _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()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
+ RD::get_singleton()->draw_list_draw(draw_list, true);
+ RD::get_singleton()->draw_list_end();
+}
+
+RasterizerEffectsRD::RasterizerEffectsRD() {
+
+ {
+ // Initialize blur
+ Vector<String> blur_modes;
+ blur_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n");
+ blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n");
+ blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n");
+ blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_LOW\n");
+ blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_MEDIUM\n");
+ blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_HIGH\n");
+ blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_LOW\n#define DOF_NEAR_BLUR_MERGE\n");
+ blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_MEDIUM\n#define DOF_NEAR_BLUR_MERGE\n");
+ blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_HIGH\n#define DOF_NEAR_BLUR_MERGE\n");
+ blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_LOW\n");
+ blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_MEDIUM\n");
+ blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_HIGH\n");
+ blur_modes.push_back("\n#define MODE_SSAO_MERGE\n");
+ blur_modes.push_back("\n#define MODE_SIMPLE_COPY\n");
+ blur_modes.push_back("\n#define MODE_MIPMAP\n");
+
+ blur.shader.initialize(blur_modes);
+ zeromem(&blur.push_constant, sizeof(BlurPushConstant));
+ blur.shader_version = blur.shader.version_create();
+
+ for (int i = 0; i < BLUR_MODE_MAX; i++) {
+ blur.pipelines[i].setup(blur.shader.version_get_shader(blur.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
+ }
+ }
+
+ {
+ // Initialize roughness
+ Vector<String> cubemap_roughness_modes;
+ cubemap_roughness_modes.push_back("\n#define MODE_SOURCE_PANORAMA\n");
+ cubemap_roughness_modes.push_back("\n#define MODE_SOURCE_CUBEMAP\n");
+ roughness.shader.initialize(cubemap_roughness_modes);
+
+ 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);
+ }
+ }
+
+ {
+ // Initialize sky
+ Vector<String> sky_modes;
+ sky_modes.push_back("");
+ sky.shader.initialize(sky_modes);
+
+ sky.shader_version = sky.shader.version_create();
+
+ RD::PipelineDepthStencilState depth_stencil_state;
+
+ depth_stencil_state.enable_depth_test = true;
+ depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
+
+ sky.pipeline.setup(sky.shader.version_get_shader(sky.shader_version, 0), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), depth_stencil_state, RD::PipelineColorBlendState::create_disabled(), 0);
}
RD::SamplerState sampler;
diff --git a/servers/visual/rasterizer_rd/rasterizer_effects_rd.h b/servers/visual/rasterizer_rd/rasterizer_effects_rd.h
index a51340b368..259eb32b76 100644
--- a/servers/visual/rasterizer_rd/rasterizer_effects_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_effects_rd.h
@@ -1,8 +1,11 @@
#ifndef RASTERIZER_EFFECTS_RD_H
#define RASTERIZER_EFFECTS_RD_H
+#include "core/math/camera_matrix.h"
#include "render_pipeline_vertex_format_cache_rd.h"
-#include "shaders/blur.glsl.gen.h"
+#include "servers/visual/rasterizer_rd/shaders/blur.glsl.gen.h"
+#include "servers/visual/rasterizer_rd/shaders/cubemap_roughness.glsl.gen.h"
+#include "servers/visual/rasterizer_rd/shaders/sky.glsl.gen.h"
class RasterizerEffectsRD {
@@ -21,6 +24,7 @@ class RasterizerEffectsRD {
BLUR_MODE_DOF_FAR_HIGH,
BLUR_MODE_SSAO_MERGE,
BLUR_MODE_SIMPLY_COPY,
+ BLUR_MODE_MIPMAP,
BLUR_MODE_MAX,
};
@@ -68,6 +72,44 @@ class RasterizerEffectsRD {
} blur;
+ enum CubemapRoughnessSource {
+ CUBEMAP_ROUGHNESS_SOURCE_PANORAMA,
+ CUBEMAP_ROUGHNESS_SOURCE_CUBEMAP,
+ CUBEMAP_ROUGHNESS_SOURCE_MAX
+ };
+
+ struct CubemapRoughnessPushConstant {
+ uint32_t face_id;
+ uint32_t sample_count;
+ float roughness;
+ uint32_t use_direct_write;
+ };
+
+ struct CubemapRoughness {
+
+ CubemapRoughnessPushConstant push_constant;
+ CubemapRoughnessShaderRD shader;
+ RID shader_version;
+ RenderPipelineVertexFormatCacheRD pipelines[CUBEMAP_ROUGHNESS_SOURCE_MAX];
+ } roughness;
+
+ struct SkyPushConstant {
+ float orientation[12];
+ float proj[4];
+ float multiplier;
+ float alpha;
+ float depth;
+ float pad;
+ };
+
+ struct Sky {
+
+ SkyPushConstant push_constant;
+ SkyShaderRD shader;
+ RID shader_version;
+ RenderPipelineVertexFormatCacheRD pipeline;
+ } sky;
+
RID default_sampler;
RID index_buffer;
RID index_array;
@@ -79,6 +121,9 @@ class RasterizerEffectsRD {
public:
void copy(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_region);
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 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 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);
RasterizerEffectsRD();
~RasterizerEffectsRD();
diff --git a/servers/visual/rasterizer_rd/rasterizer_rd.h b/servers/visual/rasterizer_rd/rasterizer_rd.h
index ca0103de7f..31d8c5bc17 100644
--- a/servers/visual/rasterizer_rd/rasterizer_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_rd.h
@@ -85,7 +85,7 @@ public:
_create_func = _create_current;
}
- virtual bool is_low_end() const { return true; }
+ virtual bool is_low_end() const { return false; }
static ThreadWorkPool thread_work_pool;
diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp
index 1eb0ab3d8d..b4c3e86194 100644
--- a/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp
@@ -254,6 +254,7 @@ void RasterizerSceneForwardRD::ShaderData::set_code(const String &p_code) {
RD::PipelineDepthStencilState depth_stencil_state;
if (depth_test != DEPTH_TEST_DISABLED) {
+ depth_stencil_state.enable_depth_test = true;
depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
depth_stencil_state.enable_depth_write = depth_draw != DEPTH_DRAW_DISABLED ? true : false;
}
@@ -487,7 +488,7 @@ void RasterizerSceneForwardRD::MaterialData::update_parameters(const Map<StringN
}
}
- uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_singleton->shader.scene_shader.version_get_shader(shader_data->version, 0), 3);
+ uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_singleton->shader.scene_shader.version_get_shader(shader_data->version, 0), 2);
}
RasterizerSceneForwardRD::MaterialData::~MaterialData() {
if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
@@ -563,6 +564,13 @@ void RasterizerSceneForwardRD::RenderBufferDataForward::configure(RID p_render_t
color_fb = RD::get_singleton()->framebuffer_create(fb);
}
+
+ {
+ Vector<RID> fb;
+ fb.push_back(color);
+
+ color_only_fb = RD::get_singleton()->framebuffer_create(fb);
+ }
}
RasterizerSceneRD::RenderBufferData *RasterizerSceneForwardRD::_create_render_buffer_data() {
@@ -580,6 +588,7 @@ bool RasterizerSceneForwardRD::free(RID p_rid) {
void RasterizerSceneForwardRD::instance_create_custom_data(InstanceBase *p_instance) {
InstanceGeometryData *geom_data = memnew(InstanceGeometryData);
geom_data->ubo = RD::get_singleton()->uniform_buffer_create(sizeof(InstanceGeometryData::UBO));
+ geom_data->using_lightmap_gi = p_instance->lightmap.is_valid();
p_instance->custom_data = geom_data;
}
@@ -632,13 +641,13 @@ void RasterizerSceneForwardRD::instance_custom_data_update_transform(InstanceBas
/// RENDERING ///
-void RasterizerSceneForwardRD::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, RID p_screen_uniform_set, bool p_no_gi) {
+void RasterizerSceneForwardRD::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi) {
RD::DrawListID draw_list = p_draw_list;
RD::FramebufferFormatID framebuffer_format = p_framebuffer_Format;
//global scope bindings
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_screen_uniform_set, 0);
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, render_base_uniform_set, 0);
MaterialData *prev_material = nullptr;
// ShaderData *prev_shader = nullptr;
@@ -827,11 +836,10 @@ void RasterizerSceneForwardRD::_render_list(RenderingDevice::DrawListID p_draw_l
}
}
-void RasterizerSceneForwardRD::_setup_environment(RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_no_fog) {
- Transform sky_orientation;
+void RasterizerSceneForwardRD::_setup_environment(RID p_render_target, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_no_fog) {
CameraMatrix projection = p_cam_projection;
- projection.flip_y();
+ projection.flip_y(); // Vulkan and modern APIs use Y-Down
//store camera into ubo
store_camera(projection, scene_state.ubo.projection_matrix);
@@ -842,8 +850,68 @@ void RasterizerSceneForwardRD::_setup_environment(RID p_environment, const Camer
//time global variables
scene_state.ubo.time = time;
- RD::get_singleton()->buffer_update(scene_state.uniform_buffer, 0, sizeof(SceneState::UBO), &scene_state.ubo, true);
+ if (is_environment(p_environment)) {
+
+ VS::EnvironmentBG env_bg = environment_get_background(p_environment);
+ VS::EnvironmentAmbientSource ambient_src = environment_get_ambient_light_ambient_source(p_environment);
+
+ float bg_energy = environment_get_bg_energy(p_environment);
+ scene_state.ubo.ambient_light_color_energy[3] = bg_energy;
+
+ scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_environment);
+
+ //ambient
+ if (ambient_src == VS::ENV_AMBIENT_SOURCE_BG && (env_bg == VS::ENV_BG_CLEAR_COLOR || env_bg == VS::ENV_BG_COLOR)) {
+
+ Color color = (p_render_target.is_valid() && env_bg == VS::ENV_BG_CLEAR_COLOR) ? storage->render_target_get_clear_request_color(p_render_target) : environment_get_bg_color(p_environment);
+ color = color.to_linear();
+
+ scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy;
+ scene_state.ubo.ambient_light_color_energy[1] = color.g * bg_energy;
+ scene_state.ubo.ambient_light_color_energy[2] = color.b * bg_energy;
+ scene_state.ubo.use_ambient_light = true;
+ scene_state.ubo.use_ambient_cubemap = false;
+ } else {
+
+ float energy = environment_get_ambient_light_ambient_energy(p_environment);
+ Color color = environment_get_ambient_light_color(p_environment);
+ color = color.to_linear();
+ scene_state.ubo.ambient_light_color_energy[0] = color.r * energy;
+ scene_state.ubo.ambient_light_color_energy[1] = color.g * energy;
+ scene_state.ubo.ambient_light_color_energy[2] = color.b * energy;
+ Basis sky_transform = environment_get_sky_orientation(p_environment);
+ sky_transform = sky_transform.inverse() * p_cam_transform.basis;
+ store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform);
+
+ scene_state.ubo.use_ambient_cubemap = (ambient_src == VS::ENV_AMBIENT_SOURCE_BG && env_bg == VS::ENV_BG_SKY) || ambient_src == VS::ENV_AMBIENT_SOURCE_SKY;
+ scene_state.ubo.use_ambient_light = scene_state.ubo.use_ambient_cubemap || ambient_src == VS::ENV_AMBIENT_SOURCE_COLOR;
+ }
+
+ //specular
+ VS::EnvironmentReflectionSource ref_src = environment_get_reflection_source(p_environment);
+ if ((ref_src == VS::ENV_REFLECTION_SOURCE_BG && env_bg == VS::ENV_BG_SKY) || ref_src == VS::ENV_REFLECTION_SOURCE_SKY) {
+ scene_state.ubo.use_reflection_cubemap = true;
+ } else {
+ scene_state.ubo.use_reflection_cubemap = false;
+ }
+
+ } else {
+ if (p_render_target.is_valid()) {
+ scene_state.ubo.use_ambient_light = true;
+ Color clear_color = storage->render_target_get_clear_request_color(p_render_target);
+ clear_color = clear_color.to_linear();
+ scene_state.ubo.ambient_light_color_energy[0] = clear_color.r;
+ scene_state.ubo.ambient_light_color_energy[1] = clear_color.g;
+ scene_state.ubo.ambient_light_color_energy[2] = clear_color.b;
+ scene_state.ubo.ambient_light_color_energy[3] = 1.0;
+ } else {
+ scene_state.ubo.use_ambient_light = false;
+ }
+
+ scene_state.ubo.use_ambient_cubemap = false;
+ scene_state.ubo.use_reflection_cubemap = false;
+ }
#if 0
//bg and ambient
if (p_environment.is_valid()) {
@@ -952,6 +1020,8 @@ void RasterizerSceneForwardRD::_setup_environment(RID p_environment, const Camer
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(State::EnvironmentRadianceUBO), &state.env_radiance_data);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
#endif
+
+ RD::get_singleton()->buffer_update(scene_state.uniform_buffer, 0, sizeof(SceneState::UBO), &scene_state.ubo, true);
}
void RasterizerSceneForwardRD::_add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode) {
@@ -1239,6 +1309,38 @@ void RasterizerSceneForwardRD::_fill_render_list(InstanceBase **p_cull_result, i
}
}
+void RasterizerSceneForwardRD::_draw_sky(RD::DrawListID p_draw_list, RD::FramebufferFormatID p_fb_format, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, float p_alpha) {
+
+ ERR_FAIL_COND(!is_environment(p_environment));
+
+ RID sky = environment_get_sky(p_environment);
+ ERR_FAIL_COND(!sky.is_valid());
+ RID panorama = sky_get_panorama_texture_rd(sky);
+ ERR_FAIL_COND(!panorama.is_valid());
+ Basis sky_transform = environment_get_sky_orientation(p_environment);
+ sky_transform.invert();
+
+ float multiplier = environment_get_bg_energy(p_environment);
+ float custom_fov = environment_get_sky_custom_fov(p_environment);
+ // Camera
+ CameraMatrix camera;
+
+ if (custom_fov) {
+
+ float near_plane = p_projection.get_z_near();
+ float far_plane = p_projection.get_z_far();
+ float aspect = p_projection.get_aspect();
+
+ camera.set_perspective(custom_fov, aspect, near_plane, far_plane);
+
+ } else {
+ camera = p_projection;
+ }
+
+ sky_transform = p_transform.basis * sky_transform;
+ storage->get_effects()->render_panorama(p_draw_list, p_fb_format, panorama, camera, sky_transform, 1.0, multiplier);
+}
+
void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
RenderBufferDataForward *render_buffer = (RenderBufferDataForward *)p_buffer_data;
@@ -1285,12 +1387,15 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
scene_state.ubo.viewport_size[0] = vp_he.x;
scene_state.ubo.viewport_size[1] = vp_he.y;
+ RID render_target;
+
if (render_buffer) {
scene_state.ubo.screen_pixel_size[0] = 1.0 / render_buffer->width;
scene_state.ubo.screen_pixel_size[1] = 1.0 / render_buffer->height;
+ render_target = render_buffer->render_target;
}
- _setup_environment(p_environment, p_cam_projection, p_cam_transform, p_reflection_probe.is_valid());
+ _setup_environment(render_target, p_environment, p_cam_projection, p_cam_transform, p_reflection_probe.is_valid());
#if 0
for (int i = 0; i < p_light_cull_count; i++) {
@@ -1356,6 +1461,7 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
bool use_mrt = false;
#endif
+
render_list.clear();
_fill_render_list(p_cull_result, p_cull_count, PASS_MODE_COLOR, render_buffer == nullptr);
#if 0
@@ -1620,16 +1726,77 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
}
#endif
+ RID radiance_cubemap;
+ bool draw_sky = false;
+
+ Color clear_color;
+ bool keep_color = false;
+
+ if (is_environment(p_environment)) {
+ VS::EnvironmentBG bg_mode = environment_get_background(p_environment);
+ float bg_energy = environment_get_bg_energy(p_environment);
+ switch (bg_mode) {
+ case VS::ENV_BG_CLEAR_COLOR: {
+ clear_color = render_target.is_valid() ? storage->render_target_get_clear_request_color(render_target) : environment_get_bg_color(p_environment);
+ clear_color.r *= bg_energy;
+ clear_color.g *= bg_energy;
+ clear_color.b *= bg_energy;
+ } break;
+ case VS::ENV_BG_COLOR: {
+ clear_color = environment_get_bg_color(p_environment);
+ clear_color.r *= bg_energy;
+ clear_color.g *= bg_energy;
+ clear_color.b *= bg_energy;
+ } break;
+ case VS::ENV_BG_SKY: {
+ RID sky = environment_get_sky(p_environment);
+ if (sky.is_valid()) {
+ radiance_cubemap = sky_get_radiance_texture_rd(sky);
+ draw_sky = true;
+ }
+ } break;
+ case VS::ENV_BG_CANVAS: {
+ keep_color = true;
+ } break;
+ case VS::ENV_BG_KEEP: {
+ keep_color = true;
+ } break;
+ case VS::ENV_BG_CAMERA_FEED: {
+
+ } break;
+ }
+ } else {
+ if (render_target.is_valid()) {
+ clear_color = storage->render_target_get_clear_request_color(render_target);
+ }
+ }
+
+ _setup_render_base_uniform_set(RID(), RID(), RID(), RID(), radiance_cubemap);
+
render_list.sort_by_key(false);
+ bool can_continue = true; //unless the middle buffers are needed
+ bool using_separate_specular = false;
+
{
//regular forward for now
Vector<Color> c;
- c.push_back(Color(0, 0, 0, 1));
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(render_buffer->color_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE, c);
+ c.push_back(clear_color.to_linear());
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(render_buffer->color_fb, keep_color ? RD::INITIAL_ACTION_KEEP_COLOR : RD::INITIAL_ACTION_CLEAR, (can_continue || draw_sky) ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ_COLOR_AND_DEPTH, c);
+ _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(render_buffer->color_fb), render_list.elements, render_list.element_count, false, PASS_MODE_COLOR, render_buffer == nullptr);
+ RD::get_singleton()->draw_list_end();
+ }
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(render_buffer->color_fb), render_list.elements, render_list.element_count, false, PASS_MODE_COLOR, default_render_buffer_uniform_set, render_buffer == nullptr);
+ if (draw_sky) {
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(render_buffer->color_fb, RD::INITIAL_ACTION_CONTINUE, can_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ_COLOR_AND_DEPTH);
+ _draw_sky(draw_list, RD::get_singleton()->framebuffer_get_format(render_buffer->color_fb), p_environment, p_cam_projection, p_cam_transform, 1.0);
RD::get_singleton()->draw_list_end();
+
+ if (using_separate_specular && !can_continue) {
+ //can't continue, so close the buffers
+ //RD::get_singleton()->draw_list_begin(render_buffer->color_specular_fb, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_READ_COLOR_AND_DEPTH, c);
+ //RD::get_singleton()->draw_list_end();
+ }
}
//_render_list
@@ -1721,8 +1888,8 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
render_list.sort_by_reverse_depth_and_priority(true);
{
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(render_buffer->color_fb, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH);
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(render_buffer->color_fb), render_list.elements, render_list.element_count, false, PASS_MODE_COLOR, default_render_buffer_uniform_set, render_buffer == nullptr);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(render_buffer->color_fb, can_continue ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP_COLOR_AND_DEPTH, RD::FINAL_ACTION_READ_COLOR_AND_DEPTH);
+ _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(render_buffer->color_fb), &render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, false, PASS_MODE_COLOR, render_buffer == nullptr);
RD::get_singleton()->draw_list_end();
}
@@ -1806,6 +1973,90 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
#endif
}
+void RasterizerSceneForwardRD::_setup_render_base_uniform_set(RID p_depth_buffer, RID p_color_buffer, RID p_normal_buffer, RID p_roughness_limit_buffer, RID p_radiance_cubemap) {
+
+ if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) {
+ RD::get_singleton()->free(render_base_uniform_set);
+ }
+
+ //default render buffer and scene state uniform set
+
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.binding = 1;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ RID texture = p_depth_buffer.is_valid() ? p_depth_buffer : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE);
+ u.ids.push_back(texture);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 2;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ RID texture = p_color_buffer.is_valid() ? p_color_buffer : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK);
+ u.ids.push_back(texture);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 3;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ RID texture = p_normal_buffer.is_valid() ? p_normal_buffer : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_NORMAL);
+ u.ids.push_back(texture);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.binding = 4;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ RID texture = p_roughness_limit_buffer.is_valid() ? p_roughness_limit_buffer : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK);
+ u.ids.push_back(texture);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.binding = 5;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ RID texture = p_radiance_cubemap.is_valid() ? p_radiance_cubemap : storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK);
+ u.ids.push_back(texture);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 6;
+ u.ids.resize(12);
+ RID *ids_ptr = u.ids.ptrw();
+ ids_ptr[0] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[1] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[2] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[3] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[4] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS_ANISOTROPIC, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[5] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[6] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[7] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[8] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[9] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[10] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS_ANISOTROPIC, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[11] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.binding = 7;
+ u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.ids.push_back(scene_state.uniform_buffer);
+ uniforms.push_back(u);
+ }
+
+ render_base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, 0);
+}
+
RasterizerSceneForwardRD *RasterizerSceneForwardRD::singleton = NULL;
void RasterizerSceneForwardRD::set_scene_pass(uint64_t p_pass) {
@@ -1816,7 +2067,8 @@ void RasterizerSceneForwardRD::set_time(double p_time) {
time = p_time;
}
-RasterizerSceneForwardRD::RasterizerSceneForwardRD(RasterizerStorageRD *p_storage) {
+RasterizerSceneForwardRD::RasterizerSceneForwardRD(RasterizerStorageRD *p_storage) :
+ RasterizerSceneRD(p_storage) {
singleton = this;
storage = p_storage;
@@ -1824,6 +2076,10 @@ RasterizerSceneForwardRD::RasterizerSceneForwardRD(RasterizerStorageRD *p_storag
{
String defines;
+ defines += "\n#define MAX_ROUGHNESS_LOD " + itos(get_roughness_layers() - 1) + ".0\n";
+ if (is_using_radiance_cubemap_array()) {
+ defines += "\n#define USE_RADIANCE_CUBEMAP_ARRAY \n";
+ }
Vector<String> shader_versions;
shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n");
@@ -1847,7 +2103,7 @@ RasterizerSceneForwardRD::RasterizerSceneForwardRD(RasterizerStorageRD *p_storag
actions.renames["WORLD_MATRIX"] = "world_matrix";
actions.renames["WORLD_NORMAL_MATRIX"] = "world_normal_matrix";
- actions.renames["INV_CAMERA_MATRIX"] = "scene_data.camera_inverse_matrix";
+ actions.renames["INV_CAMERA_MATRIX"] = "scene_data.inv_camera_matrix";
actions.renames["CAMERA_MATRIX"] = "scene_data.camera_matrix";
actions.renames["PROJECTION_MATRIX"] = "projection_matrix";
actions.renames["INV_PROJECTION_MATRIX"] = "scene_data.inv_projection_matrix";
@@ -1907,21 +2163,21 @@ RasterizerSceneForwardRD::RasterizerSceneForwardRD(RasterizerStorageRD *p_storag
actions.renames["DIFFUSE_LIGHT"] = "diffuse_light";
actions.renames["SPECULAR_LIGHT"] = "specular_light";
- actions.usage_defines["TANGENT"] = "#define ENABLE_TANGENT_INTERP\n";
+ actions.usage_defines["TANGENT"] = "#define TANGENT_USED\n";
actions.usage_defines["BINORMAL"] = "@TANGENT";
- actions.usage_defines["RIM"] = "#define LIGHT_USE_RIM\n";
+ actions.usage_defines["RIM"] = "#define LIGHT_RIM_USED\n";
actions.usage_defines["RIM_TINT"] = "@RIM";
- actions.usage_defines["CLEARCOAT"] = "#define LIGHT_USE_CLEARCOAT\n";
+ actions.usage_defines["CLEARCOAT"] = "#define LIGHT_CLEARCOAT_USED\n";
actions.usage_defines["CLEARCOAT_GLOSS"] = "@CLEARCOAT";
- actions.usage_defines["ANISOTROPY"] = "#define LIGHT_USE_ANISOTROPY\n";
+ actions.usage_defines["ANISOTROPY"] = "#define LIGHT_ANISOTROPY_USED\n";
actions.usage_defines["ANISOTROPY_FLOW"] = "@ANISOTROPY";
- actions.usage_defines["AO"] = "#define ENABLE_AO\n";
- actions.usage_defines["AO_LIGHT_AFFECT"] = "#define ENABLE_AO\n";
- actions.usage_defines["UV"] = "#define ENABLE_UV_INTERP\n";
- actions.usage_defines["UV2"] = "#define ENABLE_UV2_INTERP\n";
- actions.usage_defines["NORMALMAP"] = "#define ENABLE_NORMALMAP\n";
+ actions.usage_defines["AO"] = "#define AO_USED\n";
+ actions.usage_defines["AO_LIGHT_AFFECT"] = "#define AO_USED\n";
+ actions.usage_defines["UV"] = "#define UV_USED\n";
+ actions.usage_defines["UV2"] = "#define UV2_USED\n";
+ actions.usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n";
actions.usage_defines["NORMALMAP_DEPTH"] = "@NORMALMAP";
- actions.usage_defines["COLOR"] = "#define ENABLE_COLOR_INTERP\n";
+ actions.usage_defines["COLOR"] = "#define COLOR_USED\n";
actions.usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n";
actions.usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n";
@@ -1982,77 +2238,23 @@ RasterizerSceneForwardRD::RasterizerSceneForwardRD(RasterizerStorageRD *p_storag
scene_pass = 0;
render_pass = 0;
+ scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO));
+
{
//default material and shader
default_shader = storage->shader_create();
- storage->shader_set_code(default_shader, "shader_type spatial;\n");
+ storage->shader_set_code(default_shader, "shader_type spatial; void vertex() { ROUGHNESS = 0.8; } void fragment() { ALBEDO=vec3(0.6); ROUGHNESS=0.8; METALLIC=0.2; } \n");
default_material = storage->material_create();
storage->material_set_shader(default_material, default_shader);
MaterialData *md = (MaterialData *)storage->material_get_data(default_material, RasterizerStorageRD::SHADER_TYPE_3D);
default_shader_rd = shader.scene_shader.version_get_shader(md->shader_data->version, SHADER_VERSION_COLOR_PASS);
}
-
- //default render buffer and scene state uniform set
-
- {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.binding = 1;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE));
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 2;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE));
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 3;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE));
- uniforms.push_back(u);
- }
-
- scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO));
-
- {
-
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 4;
- u.ids.push_back(scene_state.uniform_buffer);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 5;
- u.ids.resize(12);
- RID *ids_ptr = u.ids.ptrw();
- ids_ptr[0] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- ids_ptr[1] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- ids_ptr[2] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- ids_ptr[3] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- ids_ptr[4] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS_ANISOTROPIC, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- ids_ptr[5] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- ids_ptr[6] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- ids_ptr[7] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- ids_ptr[8] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- ids_ptr[9] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- ids_ptr[10] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS_ANISOTROPIC, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- ids_ptr[11] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- uniforms.push_back(u);
- }
-
- default_render_buffer_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, 0);
- }
}
RasterizerSceneForwardRD::~RasterizerSceneForwardRD() {
+ //clear base uniform set if still valid
+ if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) {
+ RD::get_singleton()->free(render_base_uniform_set);
+ }
}
diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.h b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.h
index 299cd178e1..ca28678fcc 100644
--- a/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.h
@@ -214,13 +214,11 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
RID color;
RID depth;
RID color_fb;
+ RID color_only_fb;
int width, height;
RID render_target;
- RID uniform_set_opaque;
- RID uniform_set_alpha;
-
void clear();
virtual void configure(RID p_render_target, int p_width, int p_height, VS::ViewportMSAA p_msaa);
@@ -229,18 +227,8 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
virtual RenderBufferData *_create_render_buffer_data();
- RID default_render_buffer_uniform_set;
- /* Instance Data */
-
- struct InstanceData {
- struct UBO {
- };
-
- RID state_buffer;
- RID uniform_set;
- };
-
- RID_Owner<InstanceData> instance_data_owner;
+ RID render_base_uniform_set;
+ void _setup_render_base_uniform_set(RID p_depth_buffer, RID p_color_buffer, RID p_normal_buffer, RID p_roughness_limit_buffer, RID p_radiance_cubemap);
/* Scene State UBO */
@@ -260,6 +248,15 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
float time;
float reflection_multiplier;
+
+ float ambient_light_color_energy[4];
+
+ float ambient_color_sky_mix;
+ uint32_t use_ambient_light;
+ uint32_t use_ambient_cubemap;
+ uint32_t use_reflection_cubemap;
+
+ float radiance_inverse_xform[12];
};
UBO ubo;
@@ -427,14 +424,16 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
PASS_MODE_DEPTH_NORMAL_ROUGHNESS,
};
- void _setup_environment(RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_no_fog);
+ void _setup_environment(RID p_render_target, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_no_fog);
- void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, RID p_screen_uniform_set, bool p_no_gi);
+ void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi);
_FORCE_INLINE_ void _add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode);
_FORCE_INLINE_ void _add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, PassMode p_pass_mode);
void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, PassMode p_pass_mode, bool p_no_gi);
+ void _draw_sky(RD::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_fb_format, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, float p_alpha);
+
protected:
virtual void _render_scene(RenderBufferData *p_buffer_data, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp
index 26598b70a4..ab63cd9343 100644
--- a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp
@@ -1,4 +1,366 @@
#include "rasterizer_scene_rd.h"
+#include "core/project_settings.h"
+
+RID RasterizerSceneRD::sky_create() {
+ return sky_owner.make_rid(Sky());
+}
+
+void RasterizerSceneRD::_sky_invalidate(Sky *p_sky) {
+ if (!p_sky->dirty) {
+ p_sky->dirty = true;
+ p_sky->dirty_list = dirty_sky_list;
+ dirty_sky_list = p_sky;
+ }
+}
+
+void RasterizerSceneRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) {
+ Sky *sky = sky_owner.getornull(p_sky);
+ ERR_FAIL_COND(!sky);
+ ERR_FAIL_COND(p_radiance_size < 32 || p_radiance_size > 2048);
+ if (sky->radiance_size == p_radiance_size) {
+ return;
+ }
+ sky->radiance_size = p_radiance_size;
+ _sky_invalidate(sky);
+ if (sky->radiance.is_valid()) {
+ //if size changes, everything must be cleared
+ RD::get_singleton()->free(sky->radiance);
+ //everything else gets dependency, erase, so just clean it up
+ sky->radiance = RID();
+ sky->layers.clear();
+ sky->radiance_base_cubemap = RID();
+ }
+}
+
+void RasterizerSceneRD::sky_set_mode(RID p_sky, VS::SkyMode p_mode) {
+ Sky *sky = sky_owner.getornull(p_sky);
+ ERR_FAIL_COND(!sky);
+
+ if (sky->mode == p_mode) {
+ return;
+ }
+
+ sky->mode = p_mode;
+ _sky_invalidate(sky);
+}
+
+void RasterizerSceneRD::sky_set_texture(RID p_sky, RID p_panorama) {
+
+ Sky *sky = sky_owner.getornull(p_sky);
+ ERR_FAIL_COND(!sky);
+
+ if (sky->panorama.is_valid()) {
+ sky->panorama = RID();
+ RD::get_singleton()->free(sky->radiance);
+ sky->radiance = RID();
+ }
+
+ sky->panorama = p_panorama;
+
+ if (!sky->panorama.is_valid())
+ return; //cleared
+
+ _sky_invalidate(sky);
+}
+void RasterizerSceneRD::_update_dirty_skys() {
+
+ Sky *sky = dirty_sky_list;
+
+ while (sky) {
+
+ //update sky configuration if texture is missing
+
+ if (sky->radiance.is_null()) {
+ //recreate radiance and all data
+ int mipmaps = Image::get_image_required_mipmaps(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBAH) + 1;
+ if (sky->mode == VS::SKY_MODE_REALTIME) {
+ //use less mipmaps
+ mipmaps = MIN(8, mipmaps);
+ }
+
+ uint32_t w = sky->radiance_size, h = sky->radiance_size;
+
+ if (sky_use_cubemap_array) {
+ //array (higher quality, 6 times more memory)
+ RD::TextureFormat tf;
+ tf.array_layers = roughness_layers * 6;
+ tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ tf.type = RD::TEXTURE_TYPE_CUBE_ARRAY;
+ tf.mipmaps = mipmaps;
+ tf.width = w;
+ tf.height = h;
+ tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
+
+ sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView());
+
+ for (int i = 0; i < roughness_layers; i++) {
+ Sky::Layer layer;
+ uint32_t mmw = w;
+ uint32_t mmh = h;
+ layer.mipmaps.resize(mipmaps);
+ for (int j = 0; j < mipmaps; j++) {
+ Sky::Layer::Mipmap &mm = layer.mipmaps.write[j];
+ mm.size.width = mmw;
+ mm.size.height = mmh;
+ for (int k = 0; k < 6; k++) {
+ mm.views[k] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), sky->radiance, i * 6 + k, j);
+ Vector<RID> fbtex;
+ fbtex.push_back(mm.views[k]);
+ mm.framebuffers[k] = RD::get_singleton()->framebuffer_create(fbtex);
+ }
+
+ mmw = MAX(1, mmw >> 1);
+ mmh = MAX(1, mmh >> 1);
+ }
+
+ sky->layers.push_back(layer);
+ }
+
+ } else {
+ //regular cubemap, lower quality (aliasing, less memory)
+ RD::TextureFormat tf;
+ tf.array_layers = 6;
+ tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ tf.type = RD::TEXTURE_TYPE_CUBE;
+ tf.mipmaps = roughness_layers;
+ tf.width = w;
+ tf.height = h;
+ tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
+
+ sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView());
+
+ Sky::Layer layer;
+ uint32_t mmw = w;
+ uint32_t mmh = h;
+ layer.mipmaps.resize(roughness_layers);
+ for (int j = 0; j < roughness_layers; j++) {
+ Sky::Layer::Mipmap &mm = layer.mipmaps.write[j];
+ mm.size.width = mmw;
+ mm.size.height = mmh;
+ for (int k = 0; k < 6; k++) {
+ mm.views[k] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), sky->radiance, k, j);
+ Vector<RID> fbtex;
+ fbtex.push_back(mm.views[k]);
+ mm.framebuffers[k] = RD::get_singleton()->framebuffer_create(fbtex);
+ }
+
+ mmw = MAX(1, mmw >> 1);
+ mmh = MAX(1, mmh >> 1);
+ }
+
+ sky->layers.push_back(layer);
+ }
+
+ sky->radiance_base_cubemap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), sky->radiance, 0, 0, RD::TEXTURE_SLICE_CUBEMAP);
+ }
+
+ RID panorama_texture = storage->texture_get_rd_texture(sky->panorama);
+
+ if (panorama_texture.is_valid()) {
+ //is there a panorama texture?
+
+ if (sky_use_cubemap_array) {
+
+ if (sky->mode == VS::SKY_MODE_QUALITY) {
+ //render directly to the layers
+ for (int i = 0; i < sky->layers.size(); i++) {
+ for (int j = 0; j < 6; j++) {
+ storage->get_effects()->cubemap_roughness(panorama_texture, true, sky->layers[i].mipmaps[0].framebuffers[j], j, sky_ggx_samples_quality, float(i) / (sky->layers.size() - 1.0));
+ }
+ }
+ } else if (sky->mode == VS::SKY_MODE_REALTIME) {
+ //render to first mipmap
+ for (int j = 0; j < 6; j++) {
+ storage->get_effects()->cubemap_roughness(panorama_texture, true, sky->layers[0].mipmaps[0].framebuffers[j], j, sky_ggx_samples_realtime, 0.0);
+ }
+ //do the rest in other mipmaps and use cubemap itself as source
+ for (int i = 1; i < roughness_layers; i++) {
+ //render using a smaller mipmap, then copy to main layer
+ for (int j = 0; j < 6; j++) {
+ //storage->get_effects()->cubemap_roughness(sky->radiance_base_cubemap, false, sky->layers[0].mipmaps[i].framebuffers[0], j, sky_ggx_samples_realtime, float(i) / (sky->layers.size() - 1.0));
+ storage->get_effects()->cubemap_roughness(panorama_texture, true, sky->layers[0].mipmaps[i].framebuffers[0], j, sky_ggx_samples_realtime, float(i) / (sky->layers.size() - 1.0));
+ storage->get_effects()->copy(sky->layers[0].mipmaps[i].views[0], sky->layers[i].mipmaps[0].framebuffers[j], Rect2());
+ }
+ }
+ }
+
+ //generate mipmaps
+
+ for (int i = 0; i < sky->layers.size(); i++) {
+ for (int j = 0; j < sky->layers[i].mipmaps.size() - 1; j++) {
+ for (int k = 0; k < 6; k++) {
+ RID view = sky->layers[i].mipmaps[j].views[k];
+ RID fb = sky->layers[i].mipmaps[j + 1].framebuffers[k];
+ Vector2 size = sky->layers[i].mipmaps[j].size;
+ size = Vector2(1.0 / size.x, 1.0 / size.y);
+ storage->get_effects()->make_mipmap(view, fb, size);
+ }
+ }
+ }
+ } else {
+
+ if (sky->mode == VS::SKY_MODE_QUALITY) {
+ //render directly to the layers
+ for (int i = 0; i < sky->layers[0].mipmaps.size(); i++) {
+ for (int j = 0; j < 6; j++) {
+ storage->get_effects()->cubemap_roughness(panorama_texture, true, sky->layers[0].mipmaps[i].framebuffers[j], j, sky_ggx_samples_quality, float(i) / (sky->layers[0].mipmaps.size() - 1.0));
+ }
+ }
+ } else {
+
+ for (int j = 0; j < 6; j++) {
+ storage->get_effects()->cubemap_roughness(panorama_texture, true, sky->layers[0].mipmaps[0].framebuffers[j], j, sky_ggx_samples_realtime, 0);
+ }
+
+ for (int i = 1; i < sky->layers[0].mipmaps.size(); i++) {
+ for (int j = 0; j < 6; j++) {
+ storage->get_effects()->cubemap_roughness(sky->radiance_base_cubemap, false, sky->layers[0].mipmaps[i].framebuffers[j], j, sky_ggx_samples_realtime, float(i) / (sky->layers[0].mipmaps.size() - 1.0));
+ }
+ }
+ }
+ }
+ }
+
+ Sky *next = sky->dirty_list;
+ sky->dirty_list = nullptr;
+ sky->dirty = false;
+ sky = next;
+ }
+
+ dirty_sky_list = nullptr;
+}
+
+RID RasterizerSceneRD::sky_get_panorama_texture_rd(RID p_sky) const {
+
+ Sky *sky = sky_owner.getornull(p_sky);
+ ERR_FAIL_COND_V(!sky, RID());
+ if (sky->panorama.is_null()) {
+ return RID();
+ }
+
+ return storage->texture_get_rd_texture(sky->panorama, true);
+}
+RID RasterizerSceneRD::sky_get_radiance_texture_rd(RID p_sky) const {
+ Sky *sky = sky_owner.getornull(p_sky);
+ ERR_FAIL_COND_V(!sky, RID());
+
+ return sky->radiance;
+}
+
+RID RasterizerSceneRD::environment_create() {
+
+ return environment_owner.make_rid(Environent());
+}
+
+void RasterizerSceneRD::environment_set_background(RID p_env, VS::EnvironmentBG p_bg) {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+ env->background = p_bg;
+}
+void RasterizerSceneRD::environment_set_sky(RID p_env, RID p_sky) {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+ env->sky = p_sky;
+}
+void RasterizerSceneRD::environment_set_sky_custom_fov(RID p_env, float p_scale) {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+ env->sky_custom_fov = p_scale;
+}
+void RasterizerSceneRD::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+ env->sky_orientation = p_orientation;
+}
+void RasterizerSceneRD::environment_set_bg_color(RID p_env, const Color &p_color) {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+ env->bg_color = p_color;
+}
+void RasterizerSceneRD::environment_set_bg_energy(RID p_env, float p_energy) {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+ env->bg_energy = p_energy;
+}
+void RasterizerSceneRD::environment_set_canvas_max_layer(RID p_env, int p_max_layer) {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+ env->canvas_max_layer = p_max_layer;
+}
+void RasterizerSceneRD::environment_set_ambient_light(RID p_env, const Color &p_color, VS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, VS::EnvironmentReflectionSource p_reflection_source) {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+ env->ambient_light = p_color;
+ env->ambient_source = p_ambient;
+ env->ambient_light_energy = p_energy;
+ env->ambient_sky_contribution = p_sky_contribution;
+ env->reflection_source = p_reflection_source;
+}
+
+VS::EnvironmentBG RasterizerSceneRD::environment_get_background(RID p_env) const {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, VS::ENV_BG_MAX);
+ return env->background;
+}
+RID RasterizerSceneRD::environment_get_sky(RID p_env) const {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, RID());
+ return env->sky;
+}
+float RasterizerSceneRD::environment_get_sky_custom_fov(RID p_env) const {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, 0);
+ return env->sky_custom_fov;
+}
+Basis RasterizerSceneRD::environment_get_sky_orientation(RID p_env) const {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, Basis());
+ return env->sky_orientation;
+}
+Color RasterizerSceneRD::environment_get_bg_color(RID p_env) const {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, Color());
+ return env->bg_color;
+}
+float RasterizerSceneRD::environment_get_bg_energy(RID p_env) const {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, 0);
+ return env->bg_energy;
+}
+int RasterizerSceneRD::environment_get_canvas_max_layer(RID p_env) const {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, 0);
+ return env->canvas_max_layer;
+}
+Color RasterizerSceneRD::environment_get_ambient_light_color(RID p_env) const {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, Color());
+ return env->ambient_light;
+}
+VS::EnvironmentAmbientSource RasterizerSceneRD::environment_get_ambient_light_ambient_source(RID p_env) const {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, VS::ENV_AMBIENT_SOURCE_BG);
+ return env->ambient_source;
+}
+float RasterizerSceneRD::environment_get_ambient_light_ambient_energy(RID p_env) const {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, 0);
+ return env->ambient_light_energy;
+}
+float RasterizerSceneRD::environment_get_ambient_sky_contribution(RID p_env) const {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, 0);
+ return env->ambient_sky_contribution;
+}
+VS::EnvironmentReflectionSource RasterizerSceneRD::environment_get_reflection_source(RID p_env) const {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, VS::ENV_REFLECTION_SOURCE_DISABLED);
+ return env->reflection_source;
+}
+
+bool RasterizerSceneRD::is_environment(RID p_env) const {
+ return environment_owner.owns(p_env);
+}
RID RasterizerSceneRD::render_buffers_create() {
RenderBuffers rb;
@@ -16,6 +378,14 @@ void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_ren
rb->data->configure(p_render_target, p_width, p_height, p_msaa);
}
+int RasterizerSceneRD::get_roughness_layers() const {
+ return roughness_layers;
+}
+
+bool RasterizerSceneRD::is_using_radiance_cubemap_array() const {
+ return sky_use_cubemap_array;
+}
+
void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
@@ -30,6 +400,14 @@ bool RasterizerSceneRD::free(RID p_rid) {
RenderBuffers *rb = render_buffers_owner.getornull(p_rid);
memdelete(rb->data);
render_buffers_owner.free(p_rid);
+ } else if (environment_owner.owns(p_rid)) {
+ //not much to delete, just free it
+ environment_owner.free(p_rid);
+ } else if (sky_owner.owns(p_rid)) {
+ _update_dirty_skys();
+ Sky *sky = sky_owner.getornull(p_rid);
+ RD::get_singleton()->free(sky->radiance); //free radiance, everything else gets dependency-erased
+ sky_owner.free(p_rid);
} else {
return false;
}
@@ -37,5 +415,16 @@ bool RasterizerSceneRD::free(RID p_rid) {
return true;
}
-RasterizerSceneRD::RasterizerSceneRD() {
+void RasterizerSceneRD::update() {
+ _update_dirty_skys();
+}
+
+RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
+ storage = p_storage;
+
+ roughness_layers = GLOBAL_GET("rendering/quality/reflections/roughness_layers");
+ sky_ggx_samples_quality = GLOBAL_GET("rendering/quality/reflections/ggx_samples");
+ sky_ggx_samples_realtime = GLOBAL_GET("rendering/quality/reflections/ggx_samples_realtime");
+ sky_use_cubemap_array = GLOBAL_GET("rendering/quality/reflections/texture_array_reflections");
+ sky_use_cubemap_array = false;
}
diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_rd.h b/servers/visual/rasterizer_rd/rasterizer_scene_rd.h
index 2019d4e5a5..59f28a167f 100644
--- a/servers/visual/rasterizer_rd/rasterizer_scene_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_scene_rd.h
@@ -3,6 +3,9 @@
#include "core/rid_owner.h"
#include "servers/visual/rasterizer.h"
+#include "servers/visual/rasterizer_rd/rasterizer_storage_rd.h"
+#include "servers/visual/rendering_device.h"
+
class RasterizerSceneRD : public RasterizerScene {
protected:
struct RenderBufferData {
@@ -15,6 +18,58 @@ protected:
virtual void _render_scene(RenderBufferData *p_buffer_data, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) = 0;
private:
+ int roughness_layers;
+
+ RasterizerStorageRD *storage;
+
+ struct Sky {
+ int radiance_size = 256;
+ VS::SkyMode mode = VS::SKY_MODE_QUALITY;
+ RID panorama;
+ RID radiance;
+ bool dirty = false;
+ Sky *dirty_list = nullptr;
+ struct Layer {
+ struct Mipmap {
+ RID framebuffers[6];
+ RID views[6];
+ Size2i size;
+ };
+ Vector<Mipmap> mipmaps;
+ };
+ RID radiance_base_cubemap; //cubemap for first layer, first cubemap
+ Vector<Layer> layers;
+ };
+
+ Sky *dirty_sky_list = nullptr;
+
+ void _sky_invalidate(Sky *p_sky);
+ void _update_dirty_skys();
+
+ uint32_t sky_ggx_samples_quality;
+ uint32_t sky_ggx_samples_realtime;
+ bool sky_use_cubemap_array;
+
+ mutable RID_Owner<Sky> sky_owner;
+
+ struct Environent {
+
+ VS::EnvironmentBG background = VS::ENV_BG_CLEAR_COLOR;
+ RID sky;
+ float sky_custom_fov = 0.0;
+ Basis sky_orientation;
+ Color bg_color;
+ float bg_energy = 1.0;
+ int canvas_max_layer = 0;
+ VS::EnvironmentAmbientSource ambient_source = VS::ENV_AMBIENT_SOURCE_BG;
+ Color ambient_light;
+ float ambient_light_energy = 1.0;
+ float ambient_sky_contribution = 1.0;
+ VS::EnvironmentReflectionSource reflection_source = VS::ENV_REFLECTION_SOURCE_BG;
+ };
+
+ mutable RID_Owner<Environent> environment_owner;
+
struct RenderBuffers {
RenderBufferData *data = nullptr;
@@ -23,7 +78,7 @@ private:
RID render_target;
};
- RID_Owner<RenderBuffers> render_buffers_owner;
+ mutable RID_Owner<RenderBuffers> render_buffers_owner;
public:
/* SHADOW ATLAS API */
@@ -36,18 +91,43 @@ public:
int get_directional_light_shadow_size(RID p_light_intance) { return 0; }
void set_directional_shadow_count(int p_count) {}
- /* ENVIRONMENT API */
+ /* SKY API */
- RID environment_create() { return RID(); }
+ RID sky_create();
+ void sky_set_radiance_size(RID p_sky, int p_radiance_size);
+ void sky_set_mode(RID p_sky, VS::SkyMode p_mode);
+ void sky_set_texture(RID p_sky, RID p_panorama);
- void environment_set_background(RID p_env, VS::EnvironmentBG p_bg) {}
- void environment_set_sky(RID p_env, RID p_sky) {}
- void environment_set_sky_custom_fov(RID p_env, float p_scale) {}
- void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) {}
- void environment_set_bg_color(RID p_env, const Color &p_color) {}
- void environment_set_bg_energy(RID p_env, float p_energy) {}
- void environment_set_canvas_max_layer(RID p_env, int p_max_layer) {}
- void environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy = 1.0, float p_sky_contribution = 0.0) {}
+ RID sky_get_panorama_texture_rd(RID p_sky) const;
+ RID sky_get_radiance_texture_rd(RID p_sky) const;
+
+ /* ENVIRONMENT API */
+
+ RID environment_create();
+
+ void environment_set_background(RID p_env, VS::EnvironmentBG p_bg);
+ void environment_set_sky(RID p_env, RID p_sky);
+ void environment_set_sky_custom_fov(RID p_env, float p_scale);
+ void environment_set_sky_orientation(RID p_env, const Basis &p_orientation);
+ void environment_set_bg_color(RID p_env, const Color &p_color);
+ void environment_set_bg_energy(RID p_env, float p_energy);
+ void environment_set_canvas_max_layer(RID p_env, int p_max_layer);
+ void environment_set_ambient_light(RID p_env, const Color &p_color, VS::EnvironmentAmbientSource p_ambient = VS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, VS::EnvironmentReflectionSource p_reflection_source = VS::ENV_REFLECTION_SOURCE_BG);
+
+ VS::EnvironmentBG environment_get_background(RID p_env) const;
+ RID environment_get_sky(RID p_env) const;
+ float environment_get_sky_custom_fov(RID p_env) const;
+ Basis environment_get_sky_orientation(RID p_env) const;
+ Color environment_get_bg_color(RID p_env) const;
+ float environment_get_bg_energy(RID p_env) const;
+ int environment_get_canvas_max_layer(RID p_env) const;
+ Color environment_get_ambient_light_color(RID p_env) const;
+ VS::EnvironmentAmbientSource environment_get_ambient_light_ambient_source(RID p_env) const;
+ float environment_get_ambient_light_ambient_energy(RID p_env) const;
+ float environment_get_ambient_sky_contribution(RID p_env) const;
+ VS::EnvironmentReflectionSource environment_get_reflection_source(RID p_env) const;
+
+ bool is_environment(RID p_env) const;
void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality) {}
void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality) {}
@@ -66,10 +146,6 @@ public:
void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) {}
void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) {}
- bool is_environment(RID p_env) { return false; }
- VS::EnvironmentBG environment_get_background(RID p_env) { return VS::ENV_BG_KEEP; }
- int environment_get_canvas_max_layer(RID p_env) { return 0; }
-
RID light_instance_create(RID p_light) { return RID(); }
void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) {}
void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0) {}
@@ -97,9 +173,14 @@ public:
void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
+ int get_roughness_layers() const;
+ bool is_using_radiance_cubemap_array() const;
+
virtual bool free(RID p_rid);
- RasterizerSceneRD();
+ virtual void update();
+
+ RasterizerSceneRD(RasterizerStorageRD *p_storage);
};
#endif // RASTERIZER_SCENE_RD_H
diff --git a/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp
index 61f9a373a8..d28d2245cb 100644
--- a/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp
@@ -2598,6 +2598,61 @@ RasterizerStorageRD::RasterizerStorageRD() {
default_rd_textures[DEFAULT_RD_TEXTURE_MULTIMESH_BUFFER] = RD::get_singleton()->texture_buffer_create(16, RD::DATA_FORMAT_R8G8B8A8_UNORM, pv);
}
+ { //create default cubemap
+
+ RD::TextureFormat tformat;
+ tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+ tformat.width = 4;
+ tformat.height = 4;
+ tformat.array_layers = 6;
+ tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
+ tformat.type = RD::TEXTURE_TYPE_CUBE;
+
+ PoolVector<uint8_t> pv;
+ pv.resize(16 * 4);
+ for (int i = 0; i < 16; i++) {
+ pv.set(i * 4 + 0, 0);
+ pv.set(i * 4 + 1, 0);
+ pv.set(i * 4 + 2, 0);
+ pv.set(i * 4 + 3, 0);
+ }
+
+ {
+ Vector<PoolVector<uint8_t> > vpv;
+ for (int i = 0; i < 6; i++) {
+ vpv.push_back(pv);
+ }
+ default_rd_textures[DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
+ }
+ }
+
+ { //create default cubemap array
+
+ RD::TextureFormat tformat;
+ tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+ tformat.width = 4;
+ tformat.height = 4;
+ tformat.array_layers = 6;
+ tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
+ tformat.type = RD::TEXTURE_TYPE_CUBE_ARRAY;
+
+ PoolVector<uint8_t> pv;
+ pv.resize(16 * 4);
+ for (int i = 0; i < 16; i++) {
+ pv.set(i * 4 + 0, 0);
+ pv.set(i * 4 + 1, 0);
+ pv.set(i * 4 + 2, 0);
+ pv.set(i * 4 + 3, 0);
+ }
+
+ {
+ Vector<PoolVector<uint8_t> > vpv;
+ for (int i = 0; i < 6; i++) {
+ vpv.push_back(pv);
+ }
+ default_rd_textures[DEFAULT_RD_TEXTURE_CUBEMAP_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
+ }
+ }
//default samplers
for (int i = 1; i < VS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) {
for (int j = 1; j < VS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) {
diff --git a/servers/visual/rasterizer_rd/rasterizer_storage_rd.h b/servers/visual/rasterizer_rd/rasterizer_storage_rd.h
index dca270746b..1e9c137f6d 100644
--- a/servers/visual/rasterizer_rd/rasterizer_storage_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_storage_rd.h
@@ -77,6 +77,8 @@ public:
DEFAULT_RD_TEXTURE_NORMAL,
DEFAULT_RD_TEXTURE_ANISO,
DEFAULT_RD_TEXTURE_MULTIMESH_BUFFER,
+ DEFAULT_RD_TEXTURE_CUBEMAP_BLACK,
+ DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK,
DEFAULT_RD_TEXTURE_MAX
};
@@ -393,11 +395,6 @@ public:
return default_rd_samplers[p_filter][p_repeat];
}
- /* SKY API */
-
- RID sky_create() { return RID(); }
- void sky_set_texture(RID p_sky, RID p_cube_map, int p_radiance_size) {}
-
/* SHADER API */
RID shader_create();
diff --git a/servers/visual/rasterizer_rd/shaders/SCsub b/servers/visual/rasterizer_rd/shaders/SCsub
index 65a40e981d..e8a62d0660 100644
--- a/servers/visual/rasterizer_rd/shaders/SCsub
+++ b/servers/visual/rasterizer_rd/shaders/SCsub
@@ -6,5 +6,7 @@ if 'RD_GLSL' in env['BUILDERS']:
env.RD_GLSL('canvas.glsl');
env.RD_GLSL('canvas_occlusion.glsl');
env.RD_GLSL('blur.glsl');
+ env.RD_GLSL('cubemap_roughness.glsl');
env.RD_GLSL('scene_forward.glsl');
- env.RD_GLSL('scene_forward_inc.glsl');
+ env.RD_GLSL('sky.glsl');
+
diff --git a/servers/visual/rasterizer_rd/shaders/blur.glsl b/servers/visual/rasterizer_rd/shaders/blur.glsl
index 830d4d7d94..4f47595d2c 100644
--- a/servers/visual/rasterizer_rd/shaders/blur.glsl
+++ b/servers/visual/rasterizer_rd/shaders/blur.glsl
@@ -85,6 +85,17 @@ const float dof_kernel[21] = float[](0.028174, 0.032676, 0.037311, 0.041944, 0.0
void main() {
+#ifdef MODE_MIPMAP
+
+ vec2 pix_size = blur.pixel_size;
+ vec4 color = texture(source_color, uv_interp + vec2(-0.5,-0.5) * pix_size);
+ color += texture(source_color, uv_interp + vec2(0.5,-0.5) * pix_size);
+ color += texture(source_color, uv_interp + vec2(0.5,0.5) * pix_size);
+ color += texture(source_color, uv_interp + vec2(-0.5,0.5) * pix_size);
+ frag_color = color / 4.0;
+
+#endif
+
#ifdef MODE_GAUSSIAN_BLUR
//Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect
diff --git a/servers/visual/rasterizer_rd/shaders/canvas.glsl b/servers/visual/rasterizer_rd/shaders/canvas.glsl
index 63d2251465..f6c5251760 100644
--- a/servers/visual/rasterizer_rd/shaders/canvas.glsl
+++ b/servers/visual/rasterizer_rd/shaders/canvas.glsl
@@ -13,8 +13,7 @@ layout(location = 0) in vec2 vertex_attrib;
layout(location = 3) in vec4 color_attrib;
layout(location = 4) in vec2 uv_attrib;
-layout(location = 6) in uvec4 bone_indices_attrib;
-layout(location = 7) in vec4 bone_weights_attrib;
+layout(location = 6) in uvec4 bones_attrib;
#endif
@@ -68,8 +67,7 @@ void main() {
uv = draw_data.uvs[2];
color = vec4(unpackHalf2x16(draw_data.colors[4]),unpackHalf2x16(draw_data.colors[5]));
}
- uvec4 bone_indices = uvec4(0,0,0,0);
- vec4 bone_weights = vec4(0,0,0,0);
+ uvec4 bones = uvec4(0,0,0,0);
#elif defined(USE_ATTRIBUTES)
@@ -77,8 +75,7 @@ void main() {
vec4 color = color_attrib;
vec2 uv = uv_attrib;
- uvec4 bone_indices = bone_indices_attrib;
- vec4 bone_weights = bone_weights_attrib;
+ uvec4 bones = bones_attrib;
#else
vec2 vertex_base_arr[4] = vec2[](vec2(0.0,0.0),vec2(0.0,1.0),vec2(1.0,1.0),vec2(1.0,0.0));
@@ -87,8 +84,7 @@ void main() {
vec2 uv = draw_data.src_rect.xy + abs(draw_data.src_rect.zw) * ((draw_data.flags&FLAGS_TRANSPOSE_RECT)!=0 ? vertex_base.yx : vertex_base.xy);
vec4 color = draw_data.modulation;
vec2 vertex = draw_data.dst_rect.xy + abs(draw_data.dst_rect.zw) * mix(vertex_base, vec2(1.0, 1.0) - vertex_base, lessThan(draw_data.src_rect.zw, vec2(0.0, 0.0)));
- uvec4 bone_indices = uvec4(0,0,0,0);
- vec4 bone_weights = vec4(0,0,0,0);
+ uvec4 bones = uvec4(0,0,0,0);
#endif
diff --git a/servers/visual/rasterizer_rd/shaders/cubemap_roughness.glsl b/servers/visual/rasterizer_rd/shaders/cubemap_roughness.glsl
new file mode 100644
index 0000000000..f741fab355
--- /dev/null
+++ b/servers/visual/rasterizer_rd/shaders/cubemap_roughness.glsl
@@ -0,0 +1,234 @@
+/* clang-format off */
+[vertex]
+/* clang-format on */
+
+#version 450
+
+/* clang-format off */
+VERSION_DEFINES
+/* clang-format on */
+
+
+layout(location=0) out highp vec2 uv_interp;
+
+
+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]
+/* clang-format on */
+
+#version 450
+
+/* clang-format off */
+VERSION_DEFINES
+/* clang-format on */
+
+#ifdef MODE_SOURCE_PANORAMA
+layout( set=0, binding=0 ) uniform sampler2D source_panorama;
+#endif
+
+#ifdef MODE_SOURCE_CUBEMAP
+layout( set=0, binding=0 ) uniform samplerCube source_cube;
+#endif
+
+layout(push_constant, binding = 1, std430) uniform Params {
+ uint face_id;
+ uint sample_count;
+ float roughness;
+ bool use_direct_write;
+} 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
+ faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y
+ faceUvVectors[1][2] = vec3(-1.0, 0.0, 0.0); // -x face
+
+ // +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
+
+ // -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
+
+ // +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
+
+ // -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
+
+ // +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
+
+ // out = u * s_faceUv[0] + v * s_faceUv[1] + s_faceUv[2].
+ vec3 result = (faceUvVectors[faceID][0] * uv.x) + (faceUvVectors[faceID][1] * uv.y) + faceUvVectors[faceID][2];
+ return normalize(result);
+}
+
+vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) {
+ float a = Roughness * Roughness; // DISNEY'S ROUGHNESS [see Burley'12 siggraph]
+
+ // Compute distribution direction
+ float Phi = 2.0 * M_PI * Xi.x;
+ float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a * a - 1.0) * Xi.y));
+ float SinTheta = sqrt(1.0 - CosTheta * CosTheta);
+
+ // Convert to spherical direction
+ vec3 H;
+ H.x = SinTheta * cos(Phi);
+ H.y = SinTheta * sin(Phi);
+ H.z = CosTheta;
+
+ vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+ vec3 TangentX = normalize(cross(UpVector, N));
+ vec3 TangentY = cross(N, TangentX);
+
+ // Tangent to world space
+ return TangentX * H.x + TangentY * H.y + N * H.z;
+}
+
+// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
+float GGX(float NdotV, float a) {
+ float k = a / 2.0;
+ return NdotV / (NdotV * (1.0 - k) + k);
+}
+
+// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
+float G_Smith(float a, float nDotV, float nDotL) {
+ return GGX(nDotL, a * a) * GGX(nDotV, a * a);
+}
+
+float radicalInverse_VdC(uint bits) {
+ bits = (bits << 16u) | (bits >> 16u);
+ bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
+ bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
+ bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
+ bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
+ return float(bits) * 2.3283064365386963e-10; // / 0x100000000
+}
+
+vec2 Hammersley(uint i, uint N) {
+ return vec2(float(i) / float(N), radicalInverse_VdC(i));
+}
+
+#ifdef MODE_SOURCE_PANORAMA
+
+vec4 texturePanorama(vec3 normal, sampler2D pano) {
+
+ vec2 st = vec2(
+ atan(normal.x, -normal.z),
+ acos(normal.y));
+
+ if (st.x < 0.0)
+ st.x += M_PI * 2.0;
+
+ st /= vec2(M_PI * 2.0, M_PI);
+
+ return textureLod(pano, st, 0.0);
+}
+
+#endif
+
+
+void main() {
+
+ vec2 uv = (uv_interp * 2.0) - 1.0;
+ vec3 N = texelCoordToVec(uv, params.face_id);
+
+ //vec4 color = color_interp;
+
+ if (params.use_direct_write) {
+
+#ifdef MODE_SOURCE_PANORAMA
+
+ frag_color = vec4(texturePanorama(N, source_panorama).rgb, 1.0);
+#endif
+
+#ifdef MODE_SOURCE_CUBEMAP
+ frag_color = vec4(texture(source_cube,N).rgb, 1.0);
+#endif
+
+ } else {
+
+ vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
+
+ for (uint sampleNum = 0u; sampleNum < params.sample_count; sampleNum++) {
+ vec2 xi = Hammersley(sampleNum, params.sample_count);
+
+ vec3 H = ImportanceSampleGGX(xi, params.roughness, N);
+ vec3 V = N;
+ vec3 L = (2.0 * dot(V, H) * H - V);
+
+ float ndotl = clamp(dot(N, L), 0.0, 1.0);
+
+ if (ndotl > 0.0) {
+#ifdef MODE_SOURCE_PANORAMA
+ sum.rgb += texturePanorama(L, source_panorama).rgb * ndotl;
+#endif
+
+#ifdef MODE_SOURCE_CUBEMAP
+ sum.rgb += textureLod(source_cube, L, 0.0).rgb * ndotl;
+#endif
+ sum.a += ndotl;
+ }
+ }
+ sum /= sum.a;
+
+ frag_color = vec4(sum.rgb, 1.0);
+ }
+}
diff --git a/servers/visual/rasterizer_rd/shaders/scene_forward.glsl b/servers/visual/rasterizer_rd/shaders/scene_forward.glsl
index 57fcd049b5..df31d8c26f 100644
--- a/servers/visual/rasterizer_rd/shaders/scene_forward.glsl
+++ b/servers/visual/rasterizer_rd/shaders/scene_forward.glsl
@@ -44,7 +44,7 @@ layout(location = 2) out vec4 color_interp;
#endif
#if defined(UV_USED)
-layout(location = 3) out vec4 uv_interp;
+layout(location = 3) out vec2 uv_interp;
#endif
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
@@ -186,7 +186,7 @@ VERTEX_SHADER_CODE
#endif //MODE_RENDER_DEPTH
#ifdef USE_OVERRIDE_POSITION
- gl_Position = position;;
+ gl_Position = position;
#else
gl_Position = projection_matrix * vec4(vertex_interp, 1.0);
#endif
@@ -215,7 +215,7 @@ layout(location = 2) in vec4 color_interp;
#endif
#if defined(UV_USED)
-layout(location = 3) in vec4 uv_interp;
+layout(location = 3) in vec2 uv_interp;
#endif
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
@@ -351,15 +351,15 @@ LIGHT_SHADER_CODE
float NdotV = dot(N, V);
float cNdotV = max(NdotV, 0.0);
-#if defined(DIFFUSE_BURLEY) || defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_USE_CLEARCOAT)
+#if defined(DIFFUSE_BURLEY) || defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED)
vec3 H = normalize(V + L);
#endif
-#if defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_USE_CLEARCOAT)
+#if defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED)
float cNdotH = max(dot(N, H), 0.0);
#endif
-#if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_USE_CLEARCOAT)
+#if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED)
float cLdotH = max(dot(L, H), 0.0);
#endif
@@ -423,7 +423,7 @@ LIGHT_SHADER_CODE
diffuse_light += light_color * diffuse_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * transmission * attenuation;
#endif
-#if defined(LIGHT_USE_RIM)
+#if defined(RIM_LIGHT_USED)
float rim_light = pow(max(0.0, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0));
diffuse_light += rim_light * rim * mix(vec3(1.0), diffuse_color, rim_tint) * light_color;
#endif
@@ -495,7 +495,7 @@ LIGHT_SHADER_CODE
specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation;
#endif
-#if defined(LIGHT_USE_CLEARCOAT)
+#if defined(LIGHT_CLEARCOAT_USED)
#if !defined(SPECULAR_SCHLICK_GGX)
float cLdotH5 = SchlickFresnel(cLdotH);
@@ -537,7 +537,7 @@ void main() {
float anisotropy = 0.0;
vec2 anisotropy_flow = vec2(1.0, 0.0);
-#if defined(ENABLE_AO)
+#if defined(AO_USED)
float ao = 1.0;
float ao_light_affect = 0.0;
#endif
@@ -651,6 +651,48 @@ FRAGMENT_SHADER_CODE
vec3 diffuse_light = vec3(0.0, 0.0, 0.0);
vec3 ambient_light = vec3( 0.0, 0.0, 0.0);
+#ifndef MODE_RENDER_DEPTH
+ if (scene_data.use_reflection_cubemap){
+
+ vec3 ref_vec = reflect(-view, normal);
+ ref_vec = scene_data.radiance_inverse_xform * ref_vec;
+#ifdef USE_RADIANCE_CUBEMAP_ARRAY
+
+ float lod,blend;
+ blend = modf(roughness * MAX_ROUGHNESS_LOD, lod);
+ specular_light = texture(samplerCubeArray(radiance_cubemap,material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod)).rgb;
+ specular_light = mix(specular_light,texture(samplerCubeArray(radiance_cubemap,material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod+1)).rgb,blend);
+
+#else
+ specular_light = textureLod(samplerCube(radiance_cubemap,material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, roughness * MAX_ROUGHNESS_LOD).rgb;
+
+#endif //USE_RADIANCE_CUBEMAP_ARRAY
+ specular_light *= scene_data.ambient_light_color_energy.a;
+ }
+
+#ifndef USE_LIGHTMAP
+ //lightmap overrides everything
+ if (scene_data.use_ambient_light){
+
+ ambient_light = scene_data.ambient_light_color_energy.rgb;
+
+ if (scene_data.use_ambient_cubemap) {
+ vec3 ambient_dir = scene_data.radiance_inverse_xform * normal;
+#ifdef USE_RADIANCE_CUBEMAP_ARRAY
+ vec3 cubemap_ambient = texture(samplerCubeArray(radiance_cubemap,material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ambient_dir, MAX_ROUGHNESS_LOD)).rgb;
+#else
+ vec3 cubemap_ambient = textureLod(samplerCube(radiance_cubemap,material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ambient_dir, MAX_ROUGHNESS_LOD).rgb;
+#endif //USE_RADIANCE_CUBEMAP_ARRAY
+
+ ambient_light = mix( ambient_light, cubemap_ambient * scene_data.ambient_light_color_energy.a, scene_data.ambient_color_sky_mix );
+ }
+
+
+ }
+#endif // USE_LIGHTMAP
+
+#endif // MODE_RENDER_DEPTH
+
//radiance
float specular_blob_intensity = 1.0;
@@ -722,7 +764,7 @@ FRAGMENT_SHADER_CODE
specular_light *= scene_data.reflection_multiplier;
ambient_light *= albedo; //ambient must be multiplied by albedo at the end
-#if defined(ENABLE_AO)
+#if defined(AO_USED)
ambient_light *= ao;
ao_light_affect = mix(1.0, ao, ao_light_affect);
specular_light *= ao_light_affect;
@@ -753,8 +795,8 @@ FRAGMENT_SHADER_CODE
#ifdef USE_NO_SHADING
frag_color = vec4(albedo, alpha);
#else
- //frag_color = vec4(emission + ambient_light + diffuse_light + specular_light, alpha);
- frag_color = vec4(1.0);
+ frag_color = vec4(emission + ambient_light + diffuse_light + specular_light, alpha);
+ //frag_color = vec4(1.0);
#endif //USE_NO_SHADING
diff --git a/servers/visual/rasterizer_rd/shaders/scene_forward_inc.glsl b/servers/visual/rasterizer_rd/shaders/scene_forward_inc.glsl
index c481ddf8f4..3547cad46c 100644
--- a/servers/visual/rasterizer_rd/shaders/scene_forward_inc.glsl
+++ b/servers/visual/rasterizer_rd/shaders/scene_forward_inc.glsl
@@ -7,8 +7,35 @@
layout(set=0,binding=1) uniform texture2D depth_buffer;
layout(set=0,binding=2) uniform texture2D color_buffer;
layout(set=0,binding=3) uniform texture2D normal_buffer;
+layout(set=0,binding=4) uniform texture2D roughness_limit;
-layout(set=0,binding=4,std140) uniform SceneData {
+#ifdef USE_RADIANCE_CUBEMAP_ARRAY
+
+layout(set = 0, binding = 5) uniform textureCubeArray radiance_cubemap;
+
+#else
+
+layout(set = 0, binding = 5) uniform textureCube radiance_cubemap;
+
+#endif
+
+
+#define SAMPLER_NEAREST_CLAMP 0
+#define SAMPLER_LINEAR_CLAMP 1
+#define SAMPLER_NEAREST_WITH_MIMPAMPS_CLAMP 2
+#define SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP 3
+#define SAMPLER_NEAREST_WITH_MIMPAMPS_ANISOTROPIC_CLAMP 4
+#define SAMPLER_LINEAR_WITH_MIPMAPS_ANISOTROPIC_CLAMP 5
+#define SAMPLER_NEAREST_REPEAT 6
+#define SAMPLER_LINEAR_REPEAT 7
+#define SAMPLER_NEAREST_WITH_MIMPAMPS_REPEAT 8
+#define SAMPLER_LINEAR_WITH_MIPMAPS_REPEAT 9
+#define SAMPLER_NEAREST_WITH_MIMPAMPS_ANISOTROPIC_REPEAT 10
+#define SAMPLER_LINEAR_WITH_MIPMAPS_ANISOTROPIC_REPEAT 11
+
+layout(set = 0, binding = 6) uniform sampler material_samplers[12];
+
+layout(set=0,binding=7,std140) uniform SceneData {
mat4 projection_matrix;
mat4 inv_projection_matrix;
@@ -27,6 +54,15 @@ layout(set=0,binding=4,std140) uniform SceneData {
float time;
float reflection_multiplier; // one normally, zero when rendering reflections
+ vec4 ambient_light_color_energy;
+
+ float ambient_color_sky_mix;
+ bool use_ambient_light;
+ bool use_ambient_cubemap;
+ bool use_reflection_cubemap;
+
+ mat3 radiance_inverse_xform;
+
#if 0
vec4 ambient_light_color;
vec4 bg_color;
@@ -65,7 +101,6 @@ layout(set=0,binding=4,std140) uniform SceneData {
#endif
} scene_data;
-layout(set = 0, binding = 5) uniform sampler material_samplers[12];
#if 0
struct DirectionalLightData {
diff --git a/servers/visual/rasterizer_rd/shaders/sky.glsl b/servers/visual/rasterizer_rd/shaders/sky.glsl
new file mode 100644
index 0000000000..a32a1da41c
--- /dev/null
+++ b/servers/visual/rasterizer_rd/shaders/sky.glsl
@@ -0,0 +1,89 @@
+/* clang-format off */
+[vertex]
+/* clang-format on */
+
+#version 450
+
+/* clang-format off */
+VERSION_DEFINES
+/* clang-format on */
+
+layout(location =0) out vec2 uv_interp;
+
+layout(push_constant, binding = 1, std430) uniform Params {
+ mat3 orientation;
+ vec4 proj;
+ float multiplier;
+ float alpha;
+ float depth;
+ float pad;
+
+} params;
+
+void main() {
+
+ vec2 base_arr[4] = vec2[](vec2(-1.0,-1.0),vec2(-1.0,1.0),vec2(1.0,1.0),vec2(1.0,-1.0));
+ uv_interp = base_arr[gl_VertexIndex];
+ gl_Position = vec4(uv_interp,params.depth,1.0);
+
+}
+
+/* clang-format off */
+[fragment]
+/* clang-format on */
+
+#version 450
+
+/* clang-format off */
+VERSION_DEFINES
+/* clang-format on */
+
+#define M_PI 3.14159265359
+
+layout(location =0) in vec2 uv_interp;
+
+layout( set=0, binding=0 ) uniform sampler2D source_panorama;
+
+
+layout(push_constant, binding = 1, std430) uniform Params {
+ mat3 orientation;
+ vec4 proj;
+ float multiplier;
+ float alpha;
+ float depth;
+ float pad;
+
+} params;
+
+
+vec4 texturePanorama(sampler2D pano, vec3 normal) {
+
+ vec2 st = vec2(
+ atan(normal.x, normal.z),
+ acos(normal.y));
+
+ if (st.x < 0.0)
+ st.x += M_PI * 2.0;
+
+ st /= vec2(M_PI * 2.0, M_PI);
+
+ return texture(pano, st);
+}
+
+
+layout(location = 0) out vec4 frag_color;
+
+
+void main() {
+
+ vec3 cube_normal;
+ cube_normal.z = -1000000.0;
+ cube_normal.x = (cube_normal.z * (-uv_interp.x - params.proj.x)) / params.proj.y;
+ cube_normal.y = -(cube_normal.z * (-uv_interp.y - params.proj.z)) / params.proj.w;
+ cube_normal = mat3(params.orientation) * cube_normal;
+ cube_normal.z = -cube_normal.z;
+
+ frag_color.rgb = texturePanorama(source_panorama, normalize(cube_normal.xyz)).rgb;
+ frag_color.a = params.alpha;
+
+}
diff --git a/servers/visual/rendering_device.h b/servers/visual/rendering_device.h
index 64c4f0f0c1..32d5520c0a 100644
--- a/servers/visual/rendering_device.h
+++ b/servers/visual/rendering_device.h
@@ -409,7 +409,13 @@ public:
virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<PoolVector<uint8_t> > &p_data = Vector<PoolVector<uint8_t> >()) = 0;
virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture) = 0;
- virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap) = 0;
+
+ enum TextureSliceType {
+ TEXTURE_SLICE_2D,
+ TEXTURE_SLICE_CUBEMAP
+ };
+
+ virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D) = 0;
virtual Error texture_update(RID p_texture, uint32_t p_layer, const PoolVector<uint8_t> &p_data, bool p_sync_with_draw = false) = 0; //this function can be used from any thread and it takes effect at the begining of the frame, unless sync with draw is used, which is used to mix updates with draw calls
virtual PoolVector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer) = 0; // CPU textures will return immediately, while GPU textures will most likely force a flush
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index 1b9f5b58b2..0910bf3a9f 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -105,6 +105,8 @@ void VisualServerRaster::draw(bool p_swap_buffers, double frame_step) {
VSG::scene->update_dirty_instances(); //update scene stuff
+ VSG::scene_render->update();
+
VSG::viewport->draw_viewports();
VSG::scene->render_probes();
VSG::canvas_render->update();
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 3168359473..bef82a7da4 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -186,11 +186,6 @@ public:
BIND2(texture_set_force_redraw_if_visible, RID, bool)
- /* SKY API */
-
- BIND0R(RID, sky_create)
- BIND3(sky_set_texture, RID, RID, int)
-
/* SHADER API */
BIND0R(RID, shader_create)
@@ -494,6 +489,13 @@ public:
//from now on, calls forwarded to this singleton
#define BINDBASE VSG::scene_render
+ /* SKY API */
+
+ BIND0R(RID, sky_create)
+ BIND2(sky_set_radiance_size, RID, int)
+ BIND2(sky_set_mode, RID, SkyMode)
+ BIND2(sky_set_texture, RID, RID)
+
BIND0R(RID, environment_create)
BIND2(environment_set_background, RID, EnvironmentBG)
@@ -503,7 +505,8 @@ public:
BIND2(environment_set_bg_color, RID, const Color &)
BIND2(environment_set_bg_energy, RID, float)
BIND2(environment_set_canvas_max_layer, RID, int)
- BIND4(environment_set_ambient_light, RID, const Color &, float, float)
+ BIND6(environment_set_ambient_light, RID, const Color &, EnvironmentAmbientSource, float, float, EnvironmentReflectionSource)
+
// FIXME: Disabled during Vulkan refactoring, should be ported.
#if 0
BIND2(environment_set_camera_feed_id, RID, int)
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index 76ff6265cc..ae95fe386d 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -711,7 +711,9 @@ void VisualServerScene::instance_set_use_lightmap(RID p_instance, RID p_lightmap
instance->lightmap = p_lightmap;
}
- VSG::scene_render->instance_custom_data_update_lightmap(instance);
+ if (instance->custom_data) {
+ VSG::scene_render->instance_custom_data_update_lightmap(instance);
+ }
}
void VisualServerScene::instance_set_custom_aabb(RID p_instance, AABB p_aabb) {
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index 135e4a8bd0..ac4b5c3ecb 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -117,11 +117,6 @@ public:
FUNC2(texture_set_force_redraw_if_visible, RID, bool)
- /* SKY API */
-
- FUNCRID(sky)
- FUNC3(sky_set_texture, RID, RID, int)
-
/* SHADER API */
FUNCRID(shader)
@@ -409,6 +404,13 @@ public:
FUNC2(viewport_set_debug_draw, RID, ViewportDebugDraw)
+ /* SKY API */
+
+ FUNCRID(sky)
+ FUNC2(sky_set_radiance_size, RID, int)
+ FUNC2(sky_set_mode, RID, SkyMode)
+ FUNC2(sky_set_texture, RID, RID)
+
/* ENVIRONMENT API */
FUNCRID(environment)
@@ -420,7 +422,8 @@ public:
FUNC2(environment_set_bg_color, RID, const Color &)
FUNC2(environment_set_bg_energy, RID, float)
FUNC2(environment_set_canvas_max_layer, RID, int)
- FUNC4(environment_set_ambient_light, RID, const Color &, float, float)
+ FUNC6(environment_set_ambient_light, RID, const Color &, EnvironmentAmbientSource, float, float, EnvironmentReflectionSource)
+
// FIXME: Disabled during Vulkan refactoring, should be ported.
#if 0
FUNC2(environment_set_camera_feed_id, RID, int)
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 7aa2160545..e83498389e 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -1602,7 +1602,7 @@ void VisualServer::_bind_methods() {
#ifndef _3D_DISABLED
ClassDB::bind_method(D_METHOD("sky_create"), &VisualServer::sky_create);
- ClassDB::bind_method(D_METHOD("sky_set_texture", "sky", "cube_map", "radiance_size"), &VisualServer::sky_set_texture);
+ ClassDB::bind_method(D_METHOD("sky_set_texture", "sky", "panorama"), &VisualServer::sky_set_texture);
#endif
ClassDB::bind_method(D_METHOD("shader_create"), &VisualServer::shader_create);
ClassDB::bind_method(D_METHOD("shader_set_code", "shader", "code"), &VisualServer::shader_set_code);
@@ -2171,11 +2171,19 @@ void VisualServer::_bind_methods() {
BIND_ENUM_CONSTANT(ENV_BG_CLEAR_COLOR);
BIND_ENUM_CONSTANT(ENV_BG_COLOR);
BIND_ENUM_CONSTANT(ENV_BG_SKY);
- BIND_ENUM_CONSTANT(ENV_BG_COLOR_SKY);
BIND_ENUM_CONSTANT(ENV_BG_CANVAS);
BIND_ENUM_CONSTANT(ENV_BG_KEEP);
BIND_ENUM_CONSTANT(ENV_BG_MAX);
+ BIND_ENUM_CONSTANT(ENV_AMBIENT_SOURCE_BG);
+ BIND_ENUM_CONSTANT(ENV_AMBIENT_SOURCE_DISABLED);
+ BIND_ENUM_CONSTANT(ENV_AMBIENT_SOURCE_COLOR);
+ BIND_ENUM_CONSTANT(ENV_AMBIENT_SOURCE_SKY);
+
+ BIND_ENUM_CONSTANT(ENV_REFLECTION_SOURCE_BG);
+ BIND_ENUM_CONSTANT(ENV_REFLECTION_SOURCE_DISABLED);
+ BIND_ENUM_CONSTANT(ENV_REFLECTION_SOURCE_SKY);
+
BIND_ENUM_CONSTANT(ENV_DOF_BLUR_QUALITY_LOW);
BIND_ENUM_CONSTANT(ENV_DOF_BLUR_QUALITY_MEDIUM);
BIND_ENUM_CONSTANT(ENV_DOF_BLUR_QUALITY_HIGH);
@@ -2290,12 +2298,13 @@ VisualServer::VisualServer() {
GLOBAL_DEF("rendering/quality/shadows/filter_mode.mobile", 0);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadows/filter_mode", PropertyInfo(Variant::INT, "rendering/quality/shadows/filter_mode", PROPERTY_HINT_ENUM, "Disabled,PCF5,PCF13"));
+ GLOBAL_DEF("rendering/quality/reflections/roughness_layers", 6);
GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections", true);
GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections.mobile", false);
- GLOBAL_DEF("rendering/quality/reflections/high_quality_ggx", true);
- GLOBAL_DEF("rendering/quality/reflections/high_quality_ggx.mobile", false);
- GLOBAL_DEF("rendering/quality/reflections/irradiance_max_size", 128);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/reflections/irradiance_max_size", PropertyInfo(Variant::INT, "rendering/quality/reflections/irradiance_max_size", PROPERTY_HINT_RANGE, "32,2048"));
+ GLOBAL_DEF("rendering/quality/reflections/ggx_samples", 1024);
+ GLOBAL_DEF("rendering/quality/reflections/ggx_samples.mobile", 128);
+ GLOBAL_DEF("rendering/quality/reflections/ggx_samples_realtime", 64);
+ GLOBAL_DEF("rendering/quality/reflections/ggx_samples_realtime.mobile", 16);
GLOBAL_DEF("rendering/quality/shading/force_vertex_shading", false);
GLOBAL_DEF("rendering/quality/shading/force_vertex_shading.mobile", true);
diff --git a/servers/visual_server.h b/servers/visual_server.h
index e2c27675fb..fe64f1a04c 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -156,11 +156,6 @@ public:
virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0;
- /* SKY API */
-
- virtual RID sky_create() = 0;
- virtual void sky_set_texture(RID p_sky, RID p_cube_map, int p_radiance_size) = 0;
-
/* SHADER API */
enum ShaderMode {
@@ -678,6 +673,18 @@ public:
virtual void viewport_set_debug_draw(RID p_viewport, ViewportDebugDraw p_draw) = 0;
+ /* SKY API */
+
+ enum SkyMode {
+ SKY_MODE_QUALITY,
+ SKY_MODE_REALTIME
+ };
+
+ virtual RID sky_create() = 0;
+ virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0;
+ virtual void sky_set_mode(RID p_sky, SkyMode p_mode) = 0;
+ virtual void sky_set_texture(RID p_sky, RID p_panorama) = 0;
+
/* ENVIRONMENT API */
virtual RID environment_create() = 0;
@@ -687,13 +694,25 @@ public:
ENV_BG_CLEAR_COLOR,
ENV_BG_COLOR,
ENV_BG_SKY,
- ENV_BG_COLOR_SKY,
ENV_BG_CANVAS,
ENV_BG_KEEP,
ENV_BG_CAMERA_FEED,
ENV_BG_MAX
};
+ enum EnvironmentAmbientSource {
+ ENV_AMBIENT_SOURCE_BG,
+ ENV_AMBIENT_SOURCE_DISABLED,
+ ENV_AMBIENT_SOURCE_COLOR,
+ ENV_AMBIENT_SOURCE_SKY,
+ };
+
+ enum EnvironmentReflectionSource {
+ ENV_REFLECTION_SOURCE_BG,
+ ENV_REFLECTION_SOURCE_DISABLED,
+ ENV_REFLECTION_SOURCE_SKY,
+ };
+
virtual void environment_set_background(RID p_env, EnvironmentBG p_bg) = 0;
virtual void environment_set_sky(RID p_env, RID p_sky) = 0;
virtual void environment_set_sky_custom_fov(RID p_env, float p_scale) = 0;
@@ -701,7 +720,7 @@ public:
virtual void environment_set_bg_color(RID p_env, const Color &p_color) = 0;
virtual void environment_set_bg_energy(RID p_env, float p_energy) = 0;
virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0;
- virtual void environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy = 1.0, float p_sky_contribution = 0.0) = 0;
+ virtual void environment_set_ambient_light(RID p_env, const Color &p_color, EnvironmentAmbientSource p_ambient = ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, EnvironmentReflectionSource p_reflection_source = ENV_REFLECTION_SOURCE_BG) = 0;
// FIXME: Disabled during Vulkan refactoring, should be ported.
#if 0
virtual void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) = 0;
@@ -1093,6 +1112,8 @@ VARIANT_ENUM_CAST(VisualServer::LightDirectionalShadowDepthRangeMode);
VARIANT_ENUM_CAST(VisualServer::ReflectionProbeUpdateMode);
VARIANT_ENUM_CAST(VisualServer::ParticlesDrawOrder);
VARIANT_ENUM_CAST(VisualServer::EnvironmentBG);
+VARIANT_ENUM_CAST(VisualServer::EnvironmentAmbientSource);
+VARIANT_ENUM_CAST(VisualServer::EnvironmentReflectionSource);
VARIANT_ENUM_CAST(VisualServer::EnvironmentDOFBlurQuality);
VARIANT_ENUM_CAST(VisualServer::EnvironmentGlowBlendMode);
VARIANT_ENUM_CAST(VisualServer::EnvironmentToneMapper);