summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/visual/rasterizer.h1
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp41
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_effects_rd.h23
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.cpp338
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.h86
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp10
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_scene_rd.h3
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp2
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_storage_rd.h1
-rw-r--r--servers/visual/rasterizer_rd/shaders/sky.glsl42
-rw-r--r--servers/visual/shader_types.cpp6
-rw-r--r--servers/visual/visual_server_raster.h1
-rw-r--r--servers/visual/visual_server_wrap_mt.h1
-rw-r--r--servers/visual_server.cpp2
-rw-r--r--servers/visual_server.h2
15 files changed, 493 insertions, 66 deletions
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 2670a750d7..3179481c98 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -66,6 +66,7 @@ public:
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;
virtual void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) = 0;
+ virtual void environment_set_bg_material(RID p_env, RID p_material) = 0;
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;
diff --git a/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp
index 6b6c750fd3..90a8a9592d 100644
--- a/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp
@@ -274,31 +274,6 @@ void RasterizerEffectsRD::cubemap_roughness(RID p_source_rd_texture, bool p_sour
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::render_panorama(RD::DrawListID p_list, RenderingDevice::FramebufferFormatID p_fb_format, RID p_panorama, const CameraMatrix &p_camera, const Basis &p_orientation, float p_alpha, float p_multipler) {
-
- 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) {
zeromem(&blur.push_constant, sizeof(BlurPushConstant));
@@ -850,22 +825,6 @@ RasterizerEffectsRD::RasterizerEffectsRD() {
}
{
- // 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);
- }
-
- {
// Initialize tonemapper
Vector<String> tonemap_modes;
tonemap_modes.push_back("\n");
diff --git a/servers/visual/rasterizer_rd/rasterizer_effects_rd.h b/servers/visual/rasterizer_rd/rasterizer_effects_rd.h
index fbf6b39ecb..ab4aa58ce0 100644
--- a/servers/visual/rasterizer_rd/rasterizer_effects_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_effects_rd.h
@@ -32,7 +32,7 @@
#define RASTERIZER_EFFECTS_RD_H
#include "core/math/camera_matrix.h"
-#include "render_pipeline_vertex_format_cache_rd.h"
+#include "servers/visual/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h"
#include "servers/visual/rasterizer_rd/shaders/blur.glsl.gen.h"
#include "servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl.gen.h"
#include "servers/visual/rasterizer_rd/shaders/copy.glsl.gen.h"
@@ -41,7 +41,6 @@
#include "servers/visual/rasterizer_rd/shaders/cubemap_roughness.glsl.gen.h"
#include "servers/visual/rasterizer_rd/shaders/luminance_reduce.glsl.gen.h"
#include "servers/visual/rasterizer_rd/shaders/roughness_limiter.glsl.gen.h"
-#include "servers/visual/rasterizer_rd/shaders/sky.glsl.gen.h"
#include "servers/visual/rasterizer_rd/shaders/ssao.glsl.gen.h"
#include "servers/visual/rasterizer_rd/shaders/ssao_blur.glsl.gen.h"
#include "servers/visual/rasterizer_rd/shaders/ssao_minify.glsl.gen.h"
@@ -139,23 +138,6 @@ class RasterizerEffectsRD {
RID 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;
-
enum TonemapMode {
TONEMAP_MODE_NORMAL,
TONEMAP_MODE_BICUBIC_GLOW_FILTER,
@@ -422,7 +404,6 @@ public:
void gaussian_glow(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, float p_strength = 1.0, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_treshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0);
void cubemap_roughness(RID p_source_rd_texture, bool p_source_is_panorama, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
- void render_panorama(RD::DrawListID p_list, RenderingDevice::FramebufferFormatID p_fb_format, RID p_panorama, const CameraMatrix &p_camera, const Basis &p_orientation, float p_alpha, float p_multipler);
void make_mipmap(RID p_source_rd_texture, RID p_framebuffer_half, const Vector2 &p_pixel_size);
void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip);
void luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false);
@@ -475,4 +456,4 @@ public:
~RasterizerEffectsRD();
};
-#endif // EFFECTS_RD_H
+#endif // !RASTERIZER_EFFECTS_RD_H
diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.cpp
index 0a3105b143..5becd6c72a 100644
--- a/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.cpp
@@ -76,6 +76,8 @@ static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_arra
}
}
}
+
+/* SCENE SHADER */
void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) {
//compile
@@ -345,6 +347,7 @@ void RasterizerSceneHighEndRD::ShaderData::set_default_texture_param(const Strin
default_texture_params[p_name] = p_texture;
}
}
+
void RasterizerSceneHighEndRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
Map<int, StringName> order;
@@ -377,6 +380,7 @@ bool RasterizerSceneHighEndRD::ShaderData::is_param_texture(const StringName &p_
bool RasterizerSceneHighEndRD::ShaderData::is_animated() const {
return false;
}
+
bool RasterizerSceneHighEndRD::ShaderData::casts_shadows() const {
return false;
}
@@ -499,6 +503,7 @@ void RasterizerSceneHighEndRD::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), MATERIAL_UNIFORM_SET);
}
+
RasterizerSceneHighEndRD::MaterialData::~MaterialData() {
if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
RD::get_singleton()->free(uniform_set);
@@ -517,6 +522,255 @@ RasterizerStorageRD::MaterialData *RasterizerSceneHighEndRD::_create_material_fu
return material_data;
}
+/* SKY SHADER */
+
+void RasterizerSceneHighEndRD::SkyShaderData::set_code(const String &p_code) {
+ //compile
+
+ code = p_code;
+ valid = false;
+ ubo_size = 0;
+ uniforms.clear();
+
+ if (code == String()) {
+ return; //just invalid, but no error
+ }
+
+ ShaderCompilerRD::GeneratedCode gen_code;
+ ShaderCompilerRD::IdentifierActions actions;
+
+ // actions.render_mode_values["blend_add"] = Pair<int *, int>(&blend_mode, BLEND_MODE_ADD);
+ // actions.usage_flag_pointers["ALPHA"] = &uses_alpha;
+
+ actions.uniforms = &uniforms;
+
+ RasterizerSceneHighEndRD *scene_singleton = (RasterizerSceneHighEndRD *)RasterizerSceneHighEndRD::singleton;
+
+ Error err = scene_singleton->sky_shader.compiler.compile(VS::SHADER_SKY, code, &actions, path, gen_code);
+
+ ERR_FAIL_COND(err != OK);
+
+ if (version.is_null()) {
+ version = scene_singleton->sky_shader.shader.version_create();
+ }
+
+#if 0
+ print_line("**compiling shader:");
+ print_line("**defines:\n");
+ for (int i = 0; i < gen_code.defines.size(); i++) {
+ print_line(gen_code.defines[i]);
+ }
+ print_line("\n**uniforms:\n" + gen_code.uniforms);
+// print_line("\n**vertex_globals:\n" + gen_code.vertex_global);
+// print_line("\n**vertex_code:\n" + gen_code.vertex);
+ print_line("\n**fragment_globals:\n" + gen_code.fragment_global);
+ print_line("\n**fragment_code:\n" + gen_code.fragment);
+ print_line("\n**light_code:\n" + gen_code.light);
+#endif
+
+ scene_singleton->sky_shader.shader.version_set_code(version, gen_code.uniforms, gen_code.vertex_global, gen_code.vertex, gen_code.fragment_global, gen_code.light, gen_code.fragment, gen_code.defines);
+ ERR_FAIL_COND(!scene_singleton->sky_shader.shader.version_is_valid(version));
+
+ ubo_size = gen_code.uniform_total_size;
+ ubo_offsets = gen_code.uniform_offsets;
+ texture_uniforms = gen_code.texture_uniforms;
+
+ //update pipelines
+
+ for (int i = 0; i < SKY_VERSION_MAX; i++) {
+
+ RD::PipelineDepthStencilState depth_stencil_state;
+ depth_stencil_state.enable_depth_test = false;
+
+ RID shader_variant = scene_singleton->sky_shader.shader.version_get_shader(version, i);
+ pipelines[i].setup(shader_variant, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), depth_stencil_state, RD::PipelineColorBlendState::create_disabled(), 0);
+ }
+
+ valid = true;
+}
+
+void RasterizerSceneHighEndRD::SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
+ if (!p_texture.is_valid()) {
+ default_texture_params.erase(p_name);
+ } else {
+ default_texture_params[p_name] = p_texture;
+ }
+}
+
+void RasterizerSceneHighEndRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
+
+ Map<int, StringName> order;
+
+ for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
+
+ if (E->get().texture_order >= 0) {
+ order[E->get().texture_order + 100000] = E->key();
+ } else {
+ order[E->get().order] = E->key();
+ }
+ }
+
+ for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) {
+
+ PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]);
+ pi.name = E->get();
+ p_param_list->push_back(pi);
+ }
+}
+
+bool RasterizerSceneHighEndRD::SkyShaderData::is_param_texture(const StringName &p_param) const {
+ if (!uniforms.has(p_param)) {
+ return false;
+ }
+
+ return uniforms[p_param].texture_order >= 0;
+}
+
+bool RasterizerSceneHighEndRD::SkyShaderData::is_animated() const {
+ return false;
+}
+
+bool RasterizerSceneHighEndRD::SkyShaderData::casts_shadows() const {
+ return false;
+}
+
+Variant RasterizerSceneHighEndRD::SkyShaderData::get_default_parameter(const StringName &p_parameter) const {
+ if (uniforms.has(p_parameter)) {
+ ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
+ Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
+ return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.hint);
+ }
+ return Variant();
+}
+
+RasterizerSceneHighEndRD::SkyShaderData::SkyShaderData() {
+ valid = false;
+}
+
+RasterizerSceneHighEndRD::SkyShaderData::~SkyShaderData() {
+ RasterizerSceneHighEndRD *scene_singleton = (RasterizerSceneHighEndRD *)RasterizerSceneHighEndRD::singleton;
+ ERR_FAIL_COND(!scene_singleton);
+ //pipeline variants will clear themselves if shader is gone
+ if (version.is_valid()) {
+ scene_singleton->sky_shader.shader.version_free(version);
+ }
+}
+
+RasterizerStorageRD::ShaderData *RasterizerSceneHighEndRD::_create_sky_shader_func() {
+ SkyShaderData *shader_data = memnew(SkyShaderData);
+ return shader_data;
+}
+
+void RasterizerSceneHighEndRD::SkyMaterialData::set_render_priority(int p_priority) {
+ priority = p_priority - VS::MATERIAL_RENDER_PRIORITY_MIN; //8 bits
+}
+
+void RasterizerSceneHighEndRD::SkyMaterialData::set_next_pass(RID p_pass) {
+ next_pass = p_pass;
+}
+
+void RasterizerSceneHighEndRD::SkyMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+
+ RasterizerSceneHighEndRD *scene_singleton = (RasterizerSceneHighEndRD *)RasterizerSceneHighEndRD::singleton;
+
+ if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
+ p_uniform_dirty = true;
+ if (uniform_buffer.is_valid()) {
+ RD::get_singleton()->free(uniform_buffer);
+ uniform_buffer = RID();
+ }
+
+ ubo_data.resize(shader_data->ubo_size);
+ if (ubo_data.size()) {
+ uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size());
+ memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear
+ }
+
+ //clear previous uniform set
+ if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ RD::get_singleton()->free(uniform_set);
+ uniform_set = RID();
+ }
+ }
+
+ //check whether buffer changed
+ if (p_uniform_dirty && ubo_data.size()) {
+
+ update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
+ RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw());
+ }
+
+ uint32_t tex_uniform_count = shader_data->texture_uniforms.size();
+
+ if ((uint32_t)texture_cache.size() != tex_uniform_count) {
+ texture_cache.resize(tex_uniform_count);
+ p_textures_dirty = true;
+
+ //clear previous uniform set
+ if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ RD::get_singleton()->free(uniform_set);
+ uniform_set = RID();
+ }
+ }
+
+ if (p_textures_dirty && tex_uniform_count) {
+
+ update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true);
+ }
+
+ if (shader_data->ubo_size == 0 && shader_data->texture_uniforms.size() == 0) {
+ // This material does not require an uniform set, so don't create it.
+ return;
+ }
+
+ if (!p_textures_dirty && uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ //no reason to update uniform set, only UBO (or nothing) was needed to update
+ return;
+ }
+
+ Vector<RD::Uniform> uniforms;
+
+ {
+
+ if (shader_data->ubo_size) {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 0;
+ u.ids.push_back(uniform_buffer);
+ uniforms.push_back(u);
+ }
+
+ const RID *textures = texture_cache.ptrw();
+ for (uint32_t i = 0; i < tex_uniform_count; i++) {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 1 + i;
+ u.ids.push_back(textures[i]);
+ uniforms.push_back(u);
+ }
+ }
+
+ uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_singleton->sky_shader.shader.version_get_shader(shader_data->version, 0), 2);
+}
+
+RasterizerSceneHighEndRD::SkyMaterialData::~SkyMaterialData() {
+ if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ RD::get_singleton()->free(uniform_set);
+ }
+
+ if (uniform_buffer.is_valid()) {
+ RD::get_singleton()->free(uniform_buffer);
+ }
+}
+
+RasterizerStorageRD::MaterialData *RasterizerSceneHighEndRD::_create_sky_material_func(SkyShaderData *p_shader) {
+ SkyMaterialData *material_data = memnew(SkyMaterialData);
+ material_data->shader_data = p_shader;
+ material_data->last_frame = false;
+ //update will happen later anyway so do nothing.
+ return material_data;
+}
+
RasterizerSceneHighEndRD::RenderBufferDataHighEnd::~RenderBufferDataHighEnd() {
clear();
}
@@ -1294,6 +1548,39 @@ void RasterizerSceneHighEndRD::_draw_sky(RD::DrawListID p_draw_list, RD::Framebu
ERR_FAIL_COND(!is_environment(p_environment));
+ RID env_material = environment_get_bg_material(p_environment);
+ ERR_FAIL_COND(!env_material.is_valid());
+
+ SkyMaterialData *material = NULL;
+
+ if (env_material.is_valid()) {
+ material = (SkyMaterialData *)storage->material_get_data(env_material, RasterizerStorageRD::SHADER_TYPE_SKY);
+ if (!material || !material->shader_data->valid) {
+ material = NULL;
+ }
+ }
+
+ if (!material) {
+ env_material = sky_shader.default_material;
+ material = (SkyMaterialData *)storage->material_get_data(env_material, RasterizerStorageRD::SHADER_TYPE_SKY);
+ }
+
+ ERR_FAIL_COND(!material);
+
+ SkyShaderData *shader_data = material->shader_data;
+
+ ERR_FAIL_COND(!shader_data);
+
+ RenderPipelineVertexFormatCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_BACKGROUND];
+
+
+ //@TODO need to gather parameters we source from our environment settings and feed into our material/shader
+ // such as bg energy, sky transform, etc.
+ // some we should remove and make part of our material settings instead of environment settings
+
+ /*
+ TODO need to change this to use our sky shader instead
+
RID sky = environment_get_sky(p_environment);
ERR_FAIL_COND(!sky.is_valid());
RID panorama = sky_get_panorama_texture_rd(sky);
@@ -1320,6 +1607,7 @@ void RasterizerSceneHighEndRD::_draw_sky(RD::DrawListID p_draw_list, RD::Framebu
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 RasterizerSceneHighEndRD::_setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, RID p_environment) {
@@ -1809,7 +2097,9 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
case VS::ENV_BG_SKY: {
RID sky = environment_get_sky(p_environment);
if (sky.is_valid()) {
+ // TODO: change this, we need to check if our radiance texture is dirty and needs updating...
radiance_uniform_set = sky_get_radiance_uniform_set_rd(sky, default_shader_rd, RADIANCE_UNIFORM_SET);
+
draw_sky = true;
}
} break;
@@ -2371,7 +2661,7 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
singleton = this;
storage = p_storage;
- /* SHADER */
+ /* SCENE SHADER */
{
String defines;
@@ -2596,6 +2886,41 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
shader.compiler.initialize(actions);
}
+ /* SKY SHADER */
+ {
+ // Initialize sky, we may need two modes here
+ Vector<String> sky_modes;
+ sky_modes.push_back(""); // background
+ sky_shader.shader.initialize(sky_modes);
+ }
+
+ // register our shader funds
+ storage->shader_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_SKY, _create_sky_shader_funcs);
+ storage->material_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_SKY, _create_sky_material_funcs);
+
+ {
+ ShaderCompilerRD::DefaultIdentifierActions actions;
+
+ actions.renames["COLOR"] = "color";
+ actions.renames["EYEDIR"] = "cube_normal";
+
+ // actions.usage_defines["TANGENT"] = "#define TANGENT_USED\n";
+
+ // actions.render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
+
+ // are these correct?
+ actions.sampler_array_name = "material_samplers";
+ actions.base_texture_binding_index = 1;
+ actions.texture_layout_set = 2;
+ actions.base_uniform_string = "material.";
+ actions.base_varying_index = 10;
+
+ actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
+ actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
+
+ sky_shader.compiler.initialize(actions);
+ }
+
//render list
render_list.max_elements = GLOBAL_DEF_RST("rendering/limits/rendering/max_renderable_elements", (int)128000);
render_list.init();
@@ -2622,6 +2947,17 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
}
{
+ // default material and shader for sky shader
+ sky_shader.default_shader = storage->shader_create();
+ storage->shader_set_code(sky_shader.default_shader, "shader_type sky; void fragment() { COLOR = vec3(0.0, 0.0, 0.0); } \n");
+ sky_shader.default_material = storage->material_create();
+ storage->material_set_shader(sky_shader.default_material, sky_shader.default_shader);
+
+ MaterialData *md = (MaterialData *)storage->material_get_data(sky_shader.default_material, RasterizerStorageRD::SHADER_TYPE_SKY);
+ sky_shader.default_shader_rd = sky_shader.shader.version_get_shader(md->shader_data->version, SKY_VERSION_BACKGROUND);
+ }
+
+ {
overdraw_material_shader = storage->shader_create();
storage->shader_set_code(overdraw_material_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.2; }");
diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.h b/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.h
index 647b8f225e..c95139c0ee 100644
--- a/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.h
@@ -36,6 +36,7 @@
#include "servers/visual/rasterizer_rd/rasterizer_storage_rd.h"
#include "servers/visual/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h"
#include "servers/visual/rasterizer_rd/shaders/scene_high_end.glsl.gen.h"
+#include "servers/visual/rasterizer_rd/shaders/sky.glsl.gen.h"
class RasterizerSceneHighEndRD : public RasterizerSceneRD {
@@ -48,7 +49,9 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
MATERIAL_UNIFORM_SET = 5
};
- /* Shader */
+ /* Scene Shader */
+
+ // TODO possibly rename this to make it clear we have a SceneShader and SkyShader??
enum ShaderVersion {
SHADER_VERSION_DEPTH_PASS,
@@ -193,6 +196,87 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
uint32_t pad[3];
};
+ /* Sky shader */
+
+ enum SkyVersion {
+ SKY_VERSION_BACKGROUND,
+ SKY_VERSION_MAX
+ };
+
+ struct SkyShader {
+ SkyShaderRD shader;
+ ShaderCompilerRD compiler;
+
+ RID default_shader;
+ RID default_material;
+ RID default_shader_rd;
+ } sky_shader;
+
+ struct SkyShaderData : public RasterizerStorageRD::ShaderData {
+ bool valid;
+ RID version;
+
+ RenderPipelineVertexFormatCacheRD pipelines[SKY_VERSION_MAX];
+ Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
+ Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
+
+ Vector<uint32_t> ubo_offsets;
+ uint32_t ubo_size;
+
+ String path;
+ String code;
+ Map<StringName, RID> default_texture_params;
+
+ virtual void set_code(const String &p_Code);
+ virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
+ virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
+ virtual bool is_param_texture(const StringName &p_param) const;
+ virtual bool is_animated() const;
+ virtual bool casts_shadows() const;
+ virtual Variant get_default_parameter(const StringName &p_parameter) const;
+ SkyShaderData();
+ virtual ~SkyShaderData();
+ };
+
+ RasterizerStorageRD::ShaderData *_create_sky_shader_func();
+ static RasterizerStorageRD::ShaderData *_create_sky_shader_funcs() {
+ return static_cast<RasterizerSceneHighEndRD *>(singleton)->_create_sky_shader_func();
+ };
+
+ // !BAS! Can we re-use MaterialData for our sky shader? does it need its own material subclass?
+
+ struct SkyMaterialData : public RasterizerStorageRD::MaterialData {
+ // !BAS! do we need all of these?
+ uint64_t last_frame;
+ SkyShaderData *shader_data;
+ RID uniform_buffer;
+ RID uniform_set;
+ Vector<RID> texture_cache;
+ Vector<uint8_t> ubo_data;
+ uint64_t last_pass = 0;
+ uint32_t index = 0;
+ RID next_pass;
+ uint8_t priority;
+ virtual void set_render_priority(int p_priority);
+ virtual void set_next_pass(RID p_pass);
+ virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
+ virtual ~SkyMaterialData();
+ };
+
+ RasterizerStorageRD::MaterialData *_create_sky_material_func(SkyShaderData *p_shader);
+ static RasterizerStorageRD::MaterialData *_create_sky_material_funcs(RasterizerStorageRD::ShaderData *p_shader) {
+ return static_cast<RasterizerSceneHighEndRD *>(singleton)->_create_sky_material_func(static_cast<SkyShaderData *>(p_shader));
+ };
+
+ struct SkyPushConstant {
+ float orientation[12];
+ float proj[4];
+ float multiplier;
+ float alpha;
+ float depth;
+ float pad;
+ };
+
/* Framebuffer */
struct RenderBufferDataHighEnd : public RenderBufferData {
diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp
index 457f6970c8..cd441a2d04 100644
--- a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp
@@ -444,6 +444,11 @@ void RasterizerSceneRD::environment_set_sky_orientation(RID p_env, const Basis &
ERR_FAIL_COND(!env);
env->sky_orientation = p_orientation;
}
+void RasterizerSceneRD::environment_set_bg_material(RID p_env, RID p_material) {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+ env->bg_material = p_material;
+}
void RasterizerSceneRD::environment_set_bg_color(RID p_env, const Color &p_color) {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -490,6 +495,11 @@ Basis RasterizerSceneRD::environment_get_sky_orientation(RID p_env) const {
ERR_FAIL_COND_V(!env, Basis());
return env->sky_orientation;
}
+RID RasterizerSceneRD::environment_get_bg_material(RID p_env) const {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, RID());
+ return env->bg_material;
+}
Color RasterizerSceneRD::environment_get_bg_color(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, Color());
diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_rd.h b/servers/visual/rasterizer_rd/rasterizer_scene_rd.h
index 0fa853f2df..fcd0db48b4 100644
--- a/servers/visual/rasterizer_rd/rasterizer_scene_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_scene_rd.h
@@ -465,6 +465,7 @@ private:
// BG
VS::EnvironmentBG background = VS::ENV_BG_CLEAR_COLOR;
RID sky;
+ RID bg_material;
float sky_custom_fov = 0.0;
Basis sky_orientation;
Color bg_color;
@@ -661,6 +662,7 @@ public:
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_material(RID p_env, RID p_material);
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);
@@ -670,6 +672,7 @@ public:
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;
+ RID environment_get_bg_material(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;
diff --git a/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp
index b8d7a9dcf4..6e7f0aac07 100644
--- a/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp
@@ -881,6 +881,8 @@ void RasterizerStorageRD::shader_set_code(RID p_shader, const String &p_code) {
new_type = SHADER_TYPE_PARTICLES;
else if (mode_string == "spatial")
new_type = SHADER_TYPE_3D;
+ else if (mode_string == "sky")
+ new_type = SHADER_TYPE_SKY;
else
new_type = SHADER_TYPE_MAX;
diff --git a/servers/visual/rasterizer_rd/rasterizer_storage_rd.h b/servers/visual/rasterizer_rd/rasterizer_storage_rd.h
index 9bc4beab6e..410cd4adb4 100644
--- a/servers/visual/rasterizer_rd/rasterizer_storage_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_storage_rd.h
@@ -44,6 +44,7 @@ public:
SHADER_TYPE_2D,
SHADER_TYPE_3D,
SHADER_TYPE_PARTICLES,
+ SHADER_TYPE_SKY,
SHADER_TYPE_MAX
};
diff --git a/servers/visual/rasterizer_rd/shaders/sky.glsl b/servers/visual/rasterizer_rd/shaders/sky.glsl
index 28fd2883c3..d536b9dbd5 100644
--- a/servers/visual/rasterizer_rd/shaders/sky.glsl
+++ b/servers/visual/rasterizer_rd/shaders/sky.glsl
@@ -49,6 +49,22 @@ layout(push_constant, binding = 1, std430) uniform Params {
}
params;
+#ifdef USE_MATERIAL_UNIFORMS
+layout(set = 3, binding = 0, std140) uniform MaterialUniforms{
+ /* clang-format off */
+
+MATERIAL_UNIFORMS
+
+ /* clang-format on */
+} material;
+#endif
+
+/* clang-format off */
+
+FRAGMENT_SHADER_GLOBALS
+
+/* clang-format on */
+
vec4 texturePanorama(sampler2D pano, vec3 normal) {
vec2 st = vec2(
@@ -68,12 +84,34 @@ layout(location = 0) out vec4 frag_color;
void main() {
vec3 cube_normal;
- cube_normal.z = -1000000.0;
+ cube_normal.z = -1.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;
+ vec3 color = vec3(0.0, 0.0, 0.0);
+
+ // unused, just here to make our compiler happy, make sure we don't execute any light code the user adds in..
+#ifndef REALLYINCLUDETHIS
+ {
+ /* clang-format off */
+
+LIGHT_SHADER_CODE
+
+ /* clang-format on */
+ }
+#endif
+
+ // color = texturePanorama(source_panorama, normalize(cube_normal.xyz)).rgb;
+ {
+ /* clang-format off */
+
+FRAGMENT_SHADER_CODE
+
+ /* clang-format on */
+ }
+
+ frag_color.rgb = color;
frag_color.a = params.alpha;
}
diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp
index 631925e770..082f8a558f 100644
--- a/servers/visual/shader_types.cpp
+++ b/servers/visual/shader_types.cpp
@@ -285,7 +285,13 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_PARTICLES].modes.push_back("disable_velocity");
shader_modes[VS::SHADER_PARTICLES].modes.push_back("keep_data");
+ /************ SKY **************************/
+
+ shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["EYEDIR"] = ShaderLanguage::TYPE_VEC3;
+
shader_types.insert("spatial");
shader_types.insert("canvas_item");
shader_types.insert("particles");
+ shader_types.insert("sky");
}
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 09b34ce25c..c609de5046 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -515,6 +515,7 @@ public:
BIND2(environment_set_sky, RID, RID)
BIND2(environment_set_sky_custom_fov, RID, float)
BIND2(environment_set_sky_orientation, RID, const Basis &)
+ BIND2(environment_set_bg_material, RID, RID)
BIND2(environment_set_bg_color, RID, const Color &)
BIND2(environment_set_bg_energy, RID, float)
BIND2(environment_set_canvas_max_layer, RID, int)
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index 8f4df6a0e2..7d22efb287 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -429,6 +429,7 @@ public:
FUNC2(environment_set_sky, RID, RID)
FUNC2(environment_set_sky_custom_fov, RID, float)
FUNC2(environment_set_sky_orientation, RID, const Basis &)
+ FUNC2(environment_set_bg_material, RID, RID)
FUNC2(environment_set_bg_color, RID, const Color &)
FUNC2(environment_set_bg_energy, RID, float)
FUNC2(environment_set_canvas_max_layer, RID, int)
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 1506561952..cc12647876 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -1797,6 +1797,7 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("environment_set_sky", "env", "sky"), &VisualServer::environment_set_sky);
ClassDB::bind_method(D_METHOD("environment_set_sky_custom_fov", "env", "scale"), &VisualServer::environment_set_sky_custom_fov);
ClassDB::bind_method(D_METHOD("environment_set_sky_orientation", "env", "orientation"), &VisualServer::environment_set_sky_orientation);
+ ClassDB::bind_method(D_METHOD("environment_set_bg_material", "env", "material"), &VisualServer::environment_set_bg_material);
ClassDB::bind_method(D_METHOD("environment_set_bg_color", "env", "color"), &VisualServer::environment_set_bg_color);
ClassDB::bind_method(D_METHOD("environment_set_bg_energy", "env", "energy"), &VisualServer::environment_set_bg_energy);
ClassDB::bind_method(D_METHOD("environment_set_canvas_max_layer", "env", "max_layer"), &VisualServer::environment_set_canvas_max_layer);
@@ -1971,6 +1972,7 @@ void VisualServer::_bind_methods() {
BIND_ENUM_CONSTANT(SHADER_SPATIAL);
BIND_ENUM_CONSTANT(SHADER_CANVAS_ITEM);
BIND_ENUM_CONSTANT(SHADER_PARTICLES);
+ BIND_ENUM_CONSTANT(SHADER_SKY);
BIND_ENUM_CONSTANT(SHADER_MAX);
BIND_ENUM_CONSTANT(ARRAY_VERTEX);
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 4bb1c1a080..55b13de734 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -160,6 +160,7 @@ public:
SHADER_SPATIAL,
SHADER_CANVAS_ITEM,
SHADER_PARTICLES,
+ SHADER_SKY,
SHADER_MAX
};
@@ -715,6 +716,7 @@ public:
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;
virtual void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) = 0;
+ virtual void environment_set_bg_material(RID p_env, RID p_material) = 0;
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;