2021-02-13 12:08:08 +00:00
|
|
|
/*************************************************************************/
|
2022-07-19 04:17:58 +00:00
|
|
|
/* sky.cpp */
|
2021-02-13 12:08:08 +00:00
|
|
|
/*************************************************************************/
|
|
|
|
/* This file is part of: */
|
|
|
|
/* GODOT ENGINE */
|
|
|
|
/* https://godotengine.org */
|
|
|
|
/*************************************************************************/
|
2022-01-03 20:27:34 +00:00
|
|
|
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
|
|
|
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
2021-02-13 12:08:08 +00:00
|
|
|
/* */
|
|
|
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
|
|
/* a copy of this software and associated documentation files (the */
|
|
|
|
/* "Software"), to deal in the Software without restriction, including */
|
|
|
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
|
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
|
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
|
|
/* the following conditions: */
|
|
|
|
/* */
|
|
|
|
/* The above copyright notice and this permission notice shall be */
|
|
|
|
/* included in all copies or substantial portions of the Software. */
|
|
|
|
/* */
|
|
|
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
|
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
|
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
|
|
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
|
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
|
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
|
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
|
|
/*************************************************************************/
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
#include "sky.h"
|
2021-02-13 12:08:08 +00:00
|
|
|
#include "core/config/project_settings.h"
|
2021-05-19 12:12:55 +00:00
|
|
|
#include "core/math/math_defs.h"
|
2022-04-29 07:10:54 +00:00
|
|
|
#include "servers/rendering/renderer_rd/effects/copy_effects.h"
|
2021-05-07 13:19:04 +00:00
|
|
|
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
|
2022-07-19 04:17:58 +00:00
|
|
|
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
|
2022-03-21 11:25:25 +00:00
|
|
|
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
|
2022-03-12 11:19:59 +00:00
|
|
|
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
|
2021-02-13 12:08:08 +00:00
|
|
|
#include "servers/rendering/rendering_server_default.h"
|
2022-06-21 00:08:33 +00:00
|
|
|
#include "servers/rendering/rendering_server_globals.h"
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
using namespace RendererRD;
|
|
|
|
|
2021-02-13 12:08:08 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// SKY SHADER
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::SkyShaderData::set_path_hint(const String &p_path) {
|
2022-06-29 09:31:18 +00:00
|
|
|
path = p_path;
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::SkyShaderData::set_code(const String &p_code) {
|
2021-02-13 12:08:08 +00:00
|
|
|
//compile
|
|
|
|
|
|
|
|
code = p_code;
|
|
|
|
valid = false;
|
|
|
|
ubo_size = 0;
|
|
|
|
uniforms.clear();
|
|
|
|
|
2021-12-09 09:42:46 +00:00
|
|
|
if (code.is_empty()) {
|
2021-02-13 12:08:08 +00:00
|
|
|
return; //just invalid, but no error
|
|
|
|
}
|
|
|
|
|
2021-11-16 15:25:42 +00:00
|
|
|
ShaderCompiler::GeneratedCode gen_code;
|
|
|
|
ShaderCompiler::IdentifierActions actions;
|
|
|
|
actions.entry_point_stages["sky"] = ShaderCompiler::STAGE_FRAGMENT;
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
uses_time = false;
|
|
|
|
uses_half_res = false;
|
|
|
|
uses_quarter_res = false;
|
|
|
|
uses_position = false;
|
|
|
|
uses_light = false;
|
|
|
|
|
|
|
|
actions.render_mode_flags["use_half_res_pass"] = &uses_half_res;
|
|
|
|
actions.render_mode_flags["use_quarter_res_pass"] = &uses_quarter_res;
|
|
|
|
|
|
|
|
actions.usage_flag_pointers["TIME"] = &uses_time;
|
|
|
|
actions.usage_flag_pointers["POSITION"] = &uses_position;
|
|
|
|
actions.usage_flag_pointers["LIGHT0_ENABLED"] = &uses_light;
|
|
|
|
actions.usage_flag_pointers["LIGHT0_ENERGY"] = &uses_light;
|
|
|
|
actions.usage_flag_pointers["LIGHT0_DIRECTION"] = &uses_light;
|
|
|
|
actions.usage_flag_pointers["LIGHT0_COLOR"] = &uses_light;
|
|
|
|
actions.usage_flag_pointers["LIGHT0_SIZE"] = &uses_light;
|
|
|
|
actions.usage_flag_pointers["LIGHT1_ENABLED"] = &uses_light;
|
|
|
|
actions.usage_flag_pointers["LIGHT1_ENERGY"] = &uses_light;
|
|
|
|
actions.usage_flag_pointers["LIGHT1_DIRECTION"] = &uses_light;
|
|
|
|
actions.usage_flag_pointers["LIGHT1_COLOR"] = &uses_light;
|
|
|
|
actions.usage_flag_pointers["LIGHT1_SIZE"] = &uses_light;
|
|
|
|
actions.usage_flag_pointers["LIGHT2_ENABLED"] = &uses_light;
|
|
|
|
actions.usage_flag_pointers["LIGHT2_ENERGY"] = &uses_light;
|
|
|
|
actions.usage_flag_pointers["LIGHT2_DIRECTION"] = &uses_light;
|
|
|
|
actions.usage_flag_pointers["LIGHT2_COLOR"] = &uses_light;
|
|
|
|
actions.usage_flag_pointers["LIGHT2_SIZE"] = &uses_light;
|
|
|
|
actions.usage_flag_pointers["LIGHT3_ENABLED"] = &uses_light;
|
|
|
|
actions.usage_flag_pointers["LIGHT3_ENERGY"] = &uses_light;
|
|
|
|
actions.usage_flag_pointers["LIGHT3_DIRECTION"] = &uses_light;
|
|
|
|
actions.usage_flag_pointers["LIGHT3_COLOR"] = &uses_light;
|
|
|
|
actions.usage_flag_pointers["LIGHT3_SIZE"] = &uses_light;
|
|
|
|
|
|
|
|
actions.uniforms = &uniforms;
|
|
|
|
|
|
|
|
// !BAS! Contemplate making `SkyShader sky` accessible from this struct or even part of this struct.
|
2022-04-05 10:40:26 +00:00
|
|
|
RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
Error err = scene_singleton->sky.sky_shader.compiler.compile(RS::SHADER_SKY, code, &actions, path, gen_code);
|
2021-08-16 08:25:20 +00:00
|
|
|
ERR_FAIL_COND_MSG(err != OK, "Shader compilation failed.");
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
if (version.is_null()) {
|
|
|
|
version = scene_singleton->sky.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
|
|
|
|
|
2021-11-16 15:25:42 +00:00
|
|
|
scene_singleton->sky.sky_shader.shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines);
|
2021-02-13 12:08:08 +00:00
|
|
|
ERR_FAIL_COND(!scene_singleton->sky.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 = true;
|
|
|
|
depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
|
|
|
|
|
2021-06-14 01:05:16 +00:00
|
|
|
if (scene_singleton->sky.sky_shader.shader.is_variant_enabled(i)) {
|
|
|
|
RID shader_variant = scene_singleton->sky.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);
|
|
|
|
} else {
|
|
|
|
pipelines[i].clear();
|
|
|
|
}
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
valid = true;
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) {
|
2021-02-13 12:08:08 +00:00
|
|
|
if (!p_texture.is_valid()) {
|
2021-10-17 11:38:26 +00:00
|
|
|
if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) {
|
|
|
|
default_texture_params[p_name].erase(p_index);
|
|
|
|
|
|
|
|
if (default_texture_params[p_name].is_empty()) {
|
|
|
|
default_texture_params.erase(p_name);
|
|
|
|
}
|
|
|
|
}
|
2021-02-13 12:08:08 +00:00
|
|
|
} else {
|
2021-10-17 11:38:26 +00:00
|
|
|
if (!default_texture_params.has(p_name)) {
|
2022-05-13 13:04:37 +00:00
|
|
|
default_texture_params[p_name] = HashMap<int, RID>();
|
2021-10-17 11:38:26 +00:00
|
|
|
}
|
|
|
|
default_texture_params[p_name][p_index] = p_texture;
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
|
2022-05-13 13:04:37 +00:00
|
|
|
HashMap<int, StringName> order;
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2021-08-09 20:13:42 +00:00
|
|
|
for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
|
|
|
|
if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
|
2021-02-13 12:08:08 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-08-09 20:13:42 +00:00
|
|
|
if (E.value.texture_order >= 0) {
|
|
|
|
order[E.value.texture_order + 100000] = E.key;
|
2021-02-13 12:08:08 +00:00
|
|
|
} else {
|
2021-08-09 20:13:42 +00:00
|
|
|
order[E.value.order] = E.key;
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
}
|
2022-07-13 08:31:27 +00:00
|
|
|
String last_group;
|
2021-08-09 20:13:42 +00:00
|
|
|
for (const KeyValue<int, StringName> &E : order) {
|
2022-07-13 08:31:27 +00:00
|
|
|
String group = uniforms[E.value].group;
|
|
|
|
if (!uniforms[E.value].subgroup.is_empty()) {
|
|
|
|
group += "::" + uniforms[E.value].subgroup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (group != last_group) {
|
|
|
|
PropertyInfo pi;
|
|
|
|
pi.usage = PROPERTY_USAGE_GROUP;
|
|
|
|
pi.name = group;
|
|
|
|
p_param_list->push_back(pi);
|
|
|
|
|
|
|
|
last_group = group;
|
|
|
|
}
|
|
|
|
|
2021-08-09 20:13:42 +00:00
|
|
|
PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]);
|
|
|
|
pi.name = E.value;
|
2021-02-13 12:08:08 +00:00
|
|
|
p_param_list->push_back(pi);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::SkyShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const {
|
2021-08-09 20:13:42 +00:00
|
|
|
for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
|
|
|
|
if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
|
2021-02-13 12:08:08 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-03-21 11:25:25 +00:00
|
|
|
RendererMaterialStorage::InstanceShaderParam p;
|
2021-08-09 20:13:42 +00:00
|
|
|
p.info = ShaderLanguage::uniform_to_property_info(E.value);
|
|
|
|
p.info.name = E.key; //supply name
|
|
|
|
p.index = E.value.instance_index;
|
2021-06-09 09:33:41 +00:00
|
|
|
p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint);
|
2021-02-13 12:08:08 +00:00
|
|
|
p_param_list->push_back(p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
bool SkyRD::SkyShaderData::is_param_texture(const StringName &p_param) const {
|
2021-02-13 12:08:08 +00:00
|
|
|
if (!uniforms.has(p_param)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return uniforms[p_param].texture_order >= 0;
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
bool SkyRD::SkyShaderData::is_animated() const {
|
2021-02-13 12:08:08 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
bool SkyRD::SkyShaderData::casts_shadows() const {
|
2021-02-13 12:08:08 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
Variant SkyRD::SkyShaderData::get_default_parameter(const StringName &p_parameter) const {
|
2021-02-13 12:08:08 +00:00
|
|
|
if (uniforms.has(p_parameter)) {
|
|
|
|
ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
|
|
|
|
Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
|
2021-06-09 09:33:41 +00:00
|
|
|
return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint);
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
return Variant();
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
RS::ShaderNativeSourceCode SkyRD::SkyShaderData::get_native_source_code() const {
|
2022-04-05 10:40:26 +00:00
|
|
|
RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
return scene_singleton->sky.sky_shader.shader.version_get_native_source_code(version);
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
SkyRD::SkyShaderData::~SkyShaderData() {
|
2022-04-05 10:40:26 +00:00
|
|
|
RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton);
|
2021-02-13 12:08:08 +00:00
|
|
|
ERR_FAIL_COND(!scene_singleton);
|
|
|
|
//pipeline variants will clear themselves if shader is gone
|
|
|
|
if (version.is_valid()) {
|
|
|
|
scene_singleton->sky.sky_shader.shader.version_free(version);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Sky material
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
bool SkyRD::SkyMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
|
2022-04-05 10:40:26 +00:00
|
|
|
RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
uniform_set_updated = true;
|
|
|
|
|
2021-07-06 21:56:28 +00:00
|
|
|
return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, scene_singleton->sky.sky_shader.shader.version_get_shader(shader_data->version, 0), SKY_SET_MATERIAL);
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
SkyRD::SkyMaterialData::~SkyMaterialData() {
|
2021-07-07 22:55:20 +00:00
|
|
|
free_parameters_uniform_set(uniform_set);
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
|
2021-06-22 06:24:09 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Render sky
|
|
|
|
|
|
|
|
static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_array) {
|
2022-04-24 22:07:35 +00:00
|
|
|
p_array[0] = p_basis.rows[0][0];
|
|
|
|
p_array[1] = p_basis.rows[1][0];
|
|
|
|
p_array[2] = p_basis.rows[2][0];
|
2021-06-22 06:24:09 +00:00
|
|
|
p_array[3] = 0;
|
2022-04-24 22:07:35 +00:00
|
|
|
p_array[4] = p_basis.rows[0][1];
|
|
|
|
p_array[5] = p_basis.rows[1][1];
|
|
|
|
p_array[6] = p_basis.rows[2][1];
|
2021-06-22 06:24:09 +00:00
|
|
|
p_array[7] = 0;
|
2022-04-24 22:07:35 +00:00
|
|
|
p_array[8] = p_basis.rows[0][2];
|
|
|
|
p_array[9] = p_basis.rows[1][2];
|
|
|
|
p_array[10] = p_basis.rows[2][2];
|
2021-06-22 06:24:09 +00:00
|
|
|
p_array[11] = 0;
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const Projection *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position, float p_luminance_multiplier) {
|
2021-06-22 06:24:09 +00:00
|
|
|
SkyPushConstant sky_push_constant;
|
|
|
|
|
|
|
|
memset(&sky_push_constant, 0, sizeof(SkyPushConstant));
|
|
|
|
|
|
|
|
for (uint32_t v = 0; v < p_view_count; v++) {
|
|
|
|
// We only need key components of our projection matrix
|
|
|
|
sky_push_constant.projections[v][0] = p_projections[v].matrix[2][0];
|
|
|
|
sky_push_constant.projections[v][1] = p_projections[v].matrix[0][0];
|
|
|
|
sky_push_constant.projections[v][2] = p_projections[v].matrix[2][1];
|
|
|
|
sky_push_constant.projections[v][3] = p_projections[v].matrix[1][1];
|
|
|
|
}
|
|
|
|
sky_push_constant.position[0] = p_position.x;
|
|
|
|
sky_push_constant.position[1] = p_position.y;
|
|
|
|
sky_push_constant.position[2] = p_position.z;
|
|
|
|
sky_push_constant.multiplier = p_multiplier;
|
|
|
|
sky_push_constant.time = p_time;
|
2021-07-26 11:31:15 +00:00
|
|
|
sky_push_constant.luminance_multiplier = p_luminance_multiplier;
|
2021-06-22 06:24:09 +00:00
|
|
|
store_transform_3x3(p_orientation, sky_push_constant.orientation);
|
|
|
|
|
|
|
|
RenderingDevice::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(p_fb);
|
|
|
|
|
|
|
|
RD::DrawListID draw_list = p_list;
|
|
|
|
|
2021-06-26 10:49:25 +00:00
|
|
|
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, p_pipeline->get_render_pipeline(RD::INVALID_ID, fb_format, false, RD::get_singleton()->draw_list_get_current_pass()));
|
2021-06-22 06:24:09 +00:00
|
|
|
|
2021-08-06 08:17:09 +00:00
|
|
|
// Update uniform sets.
|
|
|
|
{
|
|
|
|
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, sky_scene_state.uniform_set, 0);
|
2021-08-19 06:10:44 +00:00
|
|
|
if (p_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(p_uniform_set)) { // Material may not have a uniform set.
|
2021-08-06 08:17:09 +00:00
|
|
|
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_uniform_set, 1);
|
|
|
|
}
|
|
|
|
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_texture_set, 2);
|
2021-10-03 11:28:55 +00:00
|
|
|
// Fog uniform set can be invalidated before drawing, so validate at draw time
|
|
|
|
if (sky_scene_state.fog_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sky_scene_state.fog_uniform_set)) {
|
|
|
|
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, sky_scene_state.fog_uniform_set, 3);
|
|
|
|
} else {
|
|
|
|
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, sky_scene_state.default_fog_uniform_set, 3);
|
|
|
|
}
|
2021-06-22 06:24:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2021-02-13 12:08:08 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// ReflectionData
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::ReflectionData::clear_reflection_data() {
|
2021-02-13 12:08:08 +00:00
|
|
|
layers.clear();
|
|
|
|
radiance_base_cubemap = RID();
|
|
|
|
if (downsampled_radiance_cubemap.is_valid()) {
|
|
|
|
RD::get_singleton()->free(downsampled_radiance_cubemap);
|
|
|
|
}
|
|
|
|
downsampled_radiance_cubemap = RID();
|
|
|
|
downsampled_layer.mipmaps.clear();
|
|
|
|
coefficient_buffer = RID();
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format) {
|
2021-02-13 12:08:08 +00:00
|
|
|
//recreate radiance and all data
|
|
|
|
|
|
|
|
int mipmaps = p_mipmaps;
|
|
|
|
uint32_t w = p_size, h = p_size;
|
|
|
|
|
2022-06-21 00:08:33 +00:00
|
|
|
EffectsRD *effects = RendererCompositorRD::singleton->get_effects();
|
2021-07-27 13:33:47 +00:00
|
|
|
ERR_FAIL_NULL_MSG(effects, "Effects haven't been initialised");
|
|
|
|
bool prefer_raster_effects = effects->get_prefer_raster_effects();
|
|
|
|
|
2021-02-13 12:08:08 +00:00
|
|
|
if (p_use_array) {
|
|
|
|
int num_layers = p_low_quality ? 8 : p_roughness_layers;
|
|
|
|
|
|
|
|
for (int i = 0; i < num_layers; i++) {
|
|
|
|
ReflectionData::Layer layer;
|
|
|
|
uint32_t mmw = w;
|
|
|
|
uint32_t mmh = h;
|
|
|
|
layer.mipmaps.resize(mipmaps);
|
|
|
|
layer.views.resize(mipmaps);
|
|
|
|
for (int j = 0; j < mipmaps; j++) {
|
|
|
|
ReflectionData::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(), p_base_cube, p_base_layer + i * 6 + k, j);
|
|
|
|
Vector<RID> fbtex;
|
|
|
|
fbtex.push_back(mm.views[k]);
|
|
|
|
mm.framebuffers[k] = RD::get_singleton()->framebuffer_create(fbtex);
|
|
|
|
}
|
|
|
|
|
2021-08-03 07:07:32 +00:00
|
|
|
layer.views.write[j] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer + i * 6, j, 1, RD::TEXTURE_SLICE_CUBEMAP);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2022-03-08 14:10:48 +00:00
|
|
|
mmw = MAX(1u, mmw >> 1);
|
|
|
|
mmh = MAX(1u, mmh >> 1);
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
layers.push_back(layer);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
mipmaps = p_low_quality ? 8 : mipmaps;
|
|
|
|
//regular cubemap, lower quality (aliasing, less memory)
|
|
|
|
ReflectionData::Layer layer;
|
|
|
|
uint32_t mmw = w;
|
|
|
|
uint32_t mmh = h;
|
|
|
|
layer.mipmaps.resize(mipmaps);
|
|
|
|
layer.views.resize(mipmaps);
|
|
|
|
for (int j = 0; j < mipmaps; j++) {
|
|
|
|
ReflectionData::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(), p_base_cube, p_base_layer + k, j);
|
|
|
|
Vector<RID> fbtex;
|
|
|
|
fbtex.push_back(mm.views[k]);
|
|
|
|
mm.framebuffers[k] = RD::get_singleton()->framebuffer_create(fbtex);
|
|
|
|
}
|
|
|
|
|
2021-08-03 07:07:32 +00:00
|
|
|
layer.views.write[j] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer, j, 1, RD::TEXTURE_SLICE_CUBEMAP);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2022-03-08 14:10:48 +00:00
|
|
|
mmw = MAX(1u, mmw >> 1);
|
|
|
|
mmh = MAX(1u, mmh >> 1);
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
layers.push_back(layer);
|
|
|
|
}
|
|
|
|
|
2021-08-03 07:07:32 +00:00
|
|
|
radiance_base_cubemap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer, 0, 1, RD::TEXTURE_SLICE_CUBEMAP);
|
2021-07-27 13:33:47 +00:00
|
|
|
RD::get_singleton()->set_resource_name(radiance_base_cubemap, "radiance base cubemap");
|
2022-06-23 21:36:29 +00:00
|
|
|
|
2021-02-13 12:08:08 +00:00
|
|
|
RD::TextureFormat tf;
|
2021-07-27 13:33:47 +00:00
|
|
|
tf.format = p_texture_format;
|
2022-06-23 21:36:29 +00:00
|
|
|
tf.width = p_low_quality ? 64 : p_size >> 1; // Always 64x64 when using REALTIME.
|
|
|
|
tf.height = p_low_quality ? 64 : p_size >> 1;
|
2021-02-13 12:08:08 +00:00
|
|
|
tf.texture_type = RD::TEXTURE_TYPE_CUBE;
|
|
|
|
tf.array_layers = 6;
|
2022-06-23 21:36:29 +00:00
|
|
|
tf.mipmaps = p_low_quality ? 7 : mipmaps - 1;
|
2021-02-13 12:08:08 +00:00
|
|
|
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
|
|
|
|
|
|
|
|
downsampled_radiance_cubemap = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
2021-07-27 13:33:47 +00:00
|
|
|
RD::get_singleton()->set_resource_name(downsampled_radiance_cubemap, "downsampled radiance cubemap");
|
2021-02-13 12:08:08 +00:00
|
|
|
{
|
2022-06-23 21:36:29 +00:00
|
|
|
uint32_t mmw = tf.width;
|
|
|
|
uint32_t mmh = tf.height;
|
|
|
|
downsampled_layer.mipmaps.resize(tf.mipmaps);
|
2021-02-13 12:08:08 +00:00
|
|
|
for (int j = 0; j < downsampled_layer.mipmaps.size(); j++) {
|
|
|
|
ReflectionData::DownsampleLayer::Mipmap &mm = downsampled_layer.mipmaps.write[j];
|
|
|
|
mm.size.width = mmw;
|
|
|
|
mm.size.height = mmh;
|
2021-08-03 07:07:32 +00:00
|
|
|
mm.view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), downsampled_radiance_cubemap, 0, j, 1, RD::TEXTURE_SLICE_CUBEMAP);
|
2021-07-27 13:33:47 +00:00
|
|
|
RD::get_singleton()->set_resource_name(mm.view, "Downsampled Radiance Cubemap Mip " + itos(j) + " ");
|
|
|
|
if (prefer_raster_effects) {
|
|
|
|
// we need a framebuffer for each side of our cubemap
|
|
|
|
|
|
|
|
for (int k = 0; k < 6; k++) {
|
|
|
|
mm.views[k] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), downsampled_radiance_cubemap, k, j);
|
|
|
|
RD::get_singleton()->set_resource_name(mm.view, "Downsampled Radiance Cubemap Mip: " + itos(j) + " Face: " + itos(k) + " ");
|
|
|
|
Vector<RID> fbtex;
|
|
|
|
fbtex.push_back(mm.views[k]);
|
|
|
|
mm.framebuffers[k] = RD::get_singleton()->framebuffer_create(fbtex);
|
|
|
|
}
|
|
|
|
}
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2022-03-08 14:10:48 +00:00
|
|
|
mmw = MAX(1u, mmw >> 1);
|
|
|
|
mmh = MAX(1u, mmh >> 1);
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::ReflectionData::create_reflection_fast_filter(bool p_use_arrays) {
|
2022-06-17 03:55:23 +00:00
|
|
|
RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();
|
|
|
|
ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised");
|
|
|
|
bool prefer_raster_effects = copy_effects->get_prefer_raster_effects();
|
2021-07-27 13:33:47 +00:00
|
|
|
|
|
|
|
if (prefer_raster_effects) {
|
|
|
|
RD::get_singleton()->draw_command_begin_label("Downsample radiance map");
|
|
|
|
for (int k = 0; k < 6; k++) {
|
2022-06-17 03:55:23 +00:00
|
|
|
copy_effects->cubemap_downsample_raster(radiance_base_cubemap, downsampled_layer.mipmaps[0].framebuffers[k], k, downsampled_layer.mipmaps[0].size);
|
2021-07-27 13:33:47 +00:00
|
|
|
}
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2021-07-27 13:33:47 +00:00
|
|
|
for (int i = 1; i < downsampled_layer.mipmaps.size(); i++) {
|
|
|
|
for (int k = 0; k < 6; k++) {
|
2022-06-17 03:55:23 +00:00
|
|
|
copy_effects->cubemap_downsample_raster(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].framebuffers[k], k, downsampled_layer.mipmaps[i].size);
|
2021-07-27 13:33:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
RD::get_singleton()->draw_command_end_label(); // Downsample Radiance
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2021-07-27 13:33:47 +00:00
|
|
|
if (p_use_arrays) {
|
|
|
|
RD::get_singleton()->draw_command_begin_label("filter radiance map into array heads");
|
|
|
|
for (int i = 0; i < layers.size(); i++) {
|
|
|
|
for (int k = 0; k < 6; k++) {
|
2022-06-17 03:55:23 +00:00
|
|
|
copy_effects->cubemap_filter_raster(downsampled_radiance_cubemap, layers[i].mipmaps[0].framebuffers[k], k, i);
|
2021-07-27 13:33:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
RD::get_singleton()->draw_command_begin_label("filter radiance map into mipmaps directly");
|
|
|
|
for (int j = 0; j < layers[0].mipmaps.size(); j++) {
|
|
|
|
for (int k = 0; k < 6; k++) {
|
2022-06-17 03:55:23 +00:00
|
|
|
copy_effects->cubemap_filter_raster(downsampled_radiance_cubemap, layers[0].mipmaps[j].framebuffers[k], k, j);
|
2021-07-27 13:33:47 +00:00
|
|
|
}
|
|
|
|
}
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
2021-07-27 13:33:47 +00:00
|
|
|
RD::get_singleton()->draw_command_end_label(); // Filter radiance
|
2021-02-13 12:08:08 +00:00
|
|
|
} else {
|
2022-02-16 08:54:08 +00:00
|
|
|
RD::get_singleton()->draw_command_begin_label("Downsample radiance map");
|
2022-06-17 03:55:23 +00:00
|
|
|
copy_effects->cubemap_downsample(radiance_base_cubemap, downsampled_layer.mipmaps[0].view, downsampled_layer.mipmaps[0].size);
|
2021-07-27 13:33:47 +00:00
|
|
|
|
|
|
|
for (int i = 1; i < downsampled_layer.mipmaps.size(); i++) {
|
2022-06-17 03:55:23 +00:00
|
|
|
copy_effects->cubemap_downsample(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].view, downsampled_layer.mipmaps[i].size);
|
2021-07-27 13:33:47 +00:00
|
|
|
}
|
2022-02-16 08:54:08 +00:00
|
|
|
RD::get_singleton()->draw_command_end_label(); // Downsample Radiance
|
2021-07-27 13:33:47 +00:00
|
|
|
Vector<RID> views;
|
|
|
|
if (p_use_arrays) {
|
|
|
|
for (int i = 1; i < layers.size(); i++) {
|
|
|
|
views.push_back(layers[i].views[0]);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (int i = 1; i < layers[0].views.size(); i++) {
|
|
|
|
views.push_back(layers[0].views[i]);
|
|
|
|
}
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
2022-02-16 08:54:08 +00:00
|
|
|
RD::get_singleton()->draw_command_begin_label("Fast filter radiance");
|
2022-06-17 03:55:23 +00:00
|
|
|
copy_effects->cubemap_filter(downsampled_radiance_cubemap, views, p_use_arrays);
|
2022-02-16 08:54:08 +00:00
|
|
|
RD::get_singleton()->draw_command_end_label(); // Filter radiance
|
2021-07-27 13:33:47 +00:00
|
|
|
}
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::ReflectionData::create_reflection_importance_sample(bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality) {
|
2022-06-17 03:55:23 +00:00
|
|
|
RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();
|
|
|
|
ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised");
|
|
|
|
bool prefer_raster_effects = copy_effects->get_prefer_raster_effects();
|
2021-07-27 13:33:47 +00:00
|
|
|
|
|
|
|
if (prefer_raster_effects) {
|
2022-02-16 08:54:08 +00:00
|
|
|
if (p_base_layer == 1) {
|
|
|
|
RD::get_singleton()->draw_command_begin_label("Downsample radiance map");
|
|
|
|
for (int k = 0; k < 6; k++) {
|
2022-06-17 03:55:23 +00:00
|
|
|
copy_effects->cubemap_downsample_raster(radiance_base_cubemap, downsampled_layer.mipmaps[0].framebuffers[k], k, downsampled_layer.mipmaps[0].size);
|
2022-02-16 08:54:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 1; i < downsampled_layer.mipmaps.size(); i++) {
|
|
|
|
for (int k = 0; k < 6; k++) {
|
2022-06-17 03:55:23 +00:00
|
|
|
copy_effects->cubemap_downsample_raster(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].framebuffers[k], k, downsampled_layer.mipmaps[i].size);
|
2022-02-16 08:54:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
RD::get_singleton()->draw_command_end_label(); // Downsample Radiance
|
|
|
|
}
|
|
|
|
|
|
|
|
RD::get_singleton()->draw_command_begin_label("High Quality filter radiance");
|
2021-07-27 13:33:47 +00:00
|
|
|
if (p_use_arrays) {
|
|
|
|
for (int k = 0; k < 6; k++) {
|
2022-06-17 03:55:23 +00:00
|
|
|
copy_effects->cubemap_roughness_raster(
|
2022-02-16 08:54:08 +00:00
|
|
|
downsampled_radiance_cubemap,
|
2021-07-27 13:33:47 +00:00
|
|
|
layers[p_base_layer].mipmaps[0].framebuffers[k],
|
|
|
|
k,
|
|
|
|
p_sky_ggx_samples_quality,
|
|
|
|
float(p_base_layer) / (layers.size() - 1.0),
|
|
|
|
layers[p_base_layer].mipmaps[0].size.x);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (int k = 0; k < 6; k++) {
|
2022-06-17 03:55:23 +00:00
|
|
|
copy_effects->cubemap_roughness_raster(
|
2022-02-16 08:54:08 +00:00
|
|
|
downsampled_radiance_cubemap,
|
2021-07-27 13:33:47 +00:00
|
|
|
layers[0].mipmaps[p_base_layer].framebuffers[k],
|
|
|
|
k,
|
|
|
|
p_sky_ggx_samples_quality,
|
|
|
|
float(p_base_layer) / (layers[0].mipmaps.size() - 1.0),
|
|
|
|
layers[0].mipmaps[p_base_layer].size.x);
|
|
|
|
}
|
|
|
|
}
|
2021-02-13 12:08:08 +00:00
|
|
|
} else {
|
2022-02-16 08:54:08 +00:00
|
|
|
if (p_base_layer == 1) {
|
|
|
|
RD::get_singleton()->draw_command_begin_label("Downsample radiance map");
|
2022-06-17 03:55:23 +00:00
|
|
|
copy_effects->cubemap_downsample(radiance_base_cubemap, downsampled_layer.mipmaps[0].view, downsampled_layer.mipmaps[0].size);
|
2022-02-16 08:54:08 +00:00
|
|
|
|
|
|
|
for (int i = 1; i < downsampled_layer.mipmaps.size(); i++) {
|
2022-06-17 03:55:23 +00:00
|
|
|
copy_effects->cubemap_downsample(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].view, downsampled_layer.mipmaps[i].size);
|
2022-02-16 08:54:08 +00:00
|
|
|
}
|
|
|
|
RD::get_singleton()->draw_command_end_label(); // Downsample Radiance
|
|
|
|
}
|
|
|
|
|
|
|
|
RD::get_singleton()->draw_command_begin_label("High Quality filter radiance");
|
2021-07-27 13:33:47 +00:00
|
|
|
if (p_use_arrays) {
|
2022-06-17 03:55:23 +00:00
|
|
|
copy_effects->cubemap_roughness(downsampled_radiance_cubemap, layers[p_base_layer].views[0], p_cube_side, p_sky_ggx_samples_quality, float(p_base_layer) / (layers.size() - 1.0), layers[p_base_layer].mipmaps[0].size.x);
|
2021-07-27 13:33:47 +00:00
|
|
|
} else {
|
2022-06-17 03:55:23 +00:00
|
|
|
copy_effects->cubemap_roughness(
|
2022-02-16 08:54:08 +00:00
|
|
|
downsampled_radiance_cubemap,
|
2021-07-27 13:33:47 +00:00
|
|
|
layers[0].views[p_base_layer],
|
|
|
|
p_cube_side,
|
|
|
|
p_sky_ggx_samples_quality,
|
|
|
|
float(p_base_layer) / (layers[0].mipmaps.size() - 1.0),
|
|
|
|
layers[0].mipmaps[p_base_layer].size.x);
|
|
|
|
}
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
2022-02-16 08:54:08 +00:00
|
|
|
RD::get_singleton()->draw_command_end_label(); // Filter radiance
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::ReflectionData::update_reflection_mipmaps(int p_start, int p_end) {
|
2022-06-17 03:55:23 +00:00
|
|
|
RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();
|
|
|
|
ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised");
|
|
|
|
bool prefer_raster_effects = copy_effects->get_prefer_raster_effects();
|
2021-07-27 13:33:47 +00:00
|
|
|
|
|
|
|
RD::get_singleton()->draw_command_begin_label("Update Radiance Cubemap Array Mipmaps");
|
2021-02-13 12:08:08 +00:00
|
|
|
for (int i = p_start; i < p_end; i++) {
|
|
|
|
for (int j = 0; j < layers[i].views.size() - 1; j++) {
|
|
|
|
RID view = layers[i].views[j];
|
|
|
|
Size2i size = layers[i].mipmaps[j + 1].size;
|
2021-07-27 13:33:47 +00:00
|
|
|
if (prefer_raster_effects) {
|
|
|
|
for (int k = 0; k < 6; k++) {
|
|
|
|
RID framebuffer = layers[i].mipmaps[j + 1].framebuffers[k];
|
2022-06-17 03:55:23 +00:00
|
|
|
copy_effects->cubemap_downsample_raster(view, framebuffer, k, size);
|
2021-07-27 13:33:47 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
RID texture = layers[i].views[j + 1];
|
2022-06-17 03:55:23 +00:00
|
|
|
copy_effects->cubemap_downsample(view, texture, size);
|
2021-07-27 13:33:47 +00:00
|
|
|
}
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
}
|
2021-07-27 13:33:47 +00:00
|
|
|
RD::get_singleton()->draw_command_end_label();
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2022-07-19 04:17:58 +00:00
|
|
|
// SkyRD::Sky
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::Sky::free() {
|
2021-02-13 12:08:08 +00:00
|
|
|
if (radiance.is_valid()) {
|
|
|
|
RD::get_singleton()->free(radiance);
|
|
|
|
radiance = RID();
|
|
|
|
}
|
|
|
|
reflection.clear_reflection_data();
|
|
|
|
|
|
|
|
if (uniform_buffer.is_valid()) {
|
|
|
|
RD::get_singleton()->free(uniform_buffer);
|
|
|
|
uniform_buffer = RID();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (half_res_pass.is_valid()) {
|
|
|
|
RD::get_singleton()->free(half_res_pass);
|
|
|
|
half_res_pass = RID();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (quarter_res_pass.is_valid()) {
|
|
|
|
RD::get_singleton()->free(quarter_res_pass);
|
|
|
|
quarter_res_pass = RID();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (material.is_valid()) {
|
2022-06-21 00:08:33 +00:00
|
|
|
RSG::material_storage->material_free(material);
|
2021-10-18 11:23:10 +00:00
|
|
|
material = RID();
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
RID SkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd) {
|
2022-03-12 11:19:59 +00:00
|
|
|
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
|
|
|
|
2021-02-13 12:08:08 +00:00
|
|
|
if (texture_uniform_sets[p_version].is_valid() && RD::get_singleton()->uniform_set_is_valid(texture_uniform_sets[p_version])) {
|
|
|
|
return texture_uniform_sets[p_version];
|
|
|
|
}
|
|
|
|
Vector<RD::Uniform> uniforms;
|
|
|
|
{
|
|
|
|
RD::Uniform u;
|
|
|
|
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
|
|
|
u.binding = 0;
|
|
|
|
if (radiance.is_valid() && p_version <= SKY_TEXTURE_SET_QUARTER_RES) {
|
2022-03-06 11:57:09 +00:00
|
|
|
u.append_id(radiance);
|
2021-02-13 12:08:08 +00:00
|
|
|
} else {
|
2022-03-12 11:19:59 +00:00
|
|
|
u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
uniforms.push_back(u);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
RD::Uniform u;
|
|
|
|
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
|
|
|
u.binding = 1; // half res
|
|
|
|
if (half_res_pass.is_valid() && p_version != SKY_TEXTURE_SET_HALF_RES && p_version != SKY_TEXTURE_SET_CUBEMAP_HALF_RES) {
|
|
|
|
if (p_version >= SKY_TEXTURE_SET_CUBEMAP) {
|
2022-03-06 11:57:09 +00:00
|
|
|
u.append_id(reflection.layers[0].views[1]);
|
2021-02-13 12:08:08 +00:00
|
|
|
} else {
|
2022-03-06 11:57:09 +00:00
|
|
|
u.append_id(half_res_pass);
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (p_version < SKY_TEXTURE_SET_CUBEMAP) {
|
2022-03-12 11:19:59 +00:00
|
|
|
u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE));
|
2021-02-13 12:08:08 +00:00
|
|
|
} else {
|
2022-03-12 11:19:59 +00:00
|
|
|
u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
uniforms.push_back(u);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
RD::Uniform u;
|
|
|
|
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
|
|
|
u.binding = 2; // quarter res
|
|
|
|
if (quarter_res_pass.is_valid() && p_version != SKY_TEXTURE_SET_QUARTER_RES && p_version != SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES) {
|
|
|
|
if (p_version >= SKY_TEXTURE_SET_CUBEMAP) {
|
2022-03-06 11:57:09 +00:00
|
|
|
u.append_id(reflection.layers[0].views[2]);
|
2021-02-13 12:08:08 +00:00
|
|
|
} else {
|
2022-03-06 11:57:09 +00:00
|
|
|
u.append_id(quarter_res_pass);
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (p_version < SKY_TEXTURE_SET_CUBEMAP) {
|
2022-03-12 11:19:59 +00:00
|
|
|
u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE));
|
2021-02-13 12:08:08 +00:00
|
|
|
} else {
|
2022-03-12 11:19:59 +00:00
|
|
|
u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
uniforms.push_back(u);
|
|
|
|
}
|
|
|
|
|
|
|
|
texture_uniform_sets[p_version] = RD::get_singleton()->uniform_set_create(uniforms, p_default_shader_rd, SKY_SET_TEXTURES);
|
|
|
|
return texture_uniform_sets[p_version];
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
bool SkyRD::Sky::set_radiance_size(int p_radiance_size) {
|
2021-02-13 12:08:08 +00:00
|
|
|
ERR_FAIL_COND_V(p_radiance_size < 32 || p_radiance_size > 2048, false);
|
|
|
|
if (radiance_size == p_radiance_size) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
radiance_size = p_radiance_size;
|
|
|
|
|
|
|
|
if (mode == RS::SKY_MODE_REALTIME && radiance_size != 256) {
|
|
|
|
WARN_PRINT("Realtime Skies can only use a radiance size of 256. Radiance size will be set to 256 internally.");
|
|
|
|
radiance_size = 256;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (radiance.is_valid()) {
|
|
|
|
RD::get_singleton()->free(radiance);
|
|
|
|
radiance = RID();
|
|
|
|
}
|
|
|
|
reflection.clear_reflection_data();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
bool SkyRD::Sky::set_mode(RS::SkyMode p_mode) {
|
2021-02-13 12:08:08 +00:00
|
|
|
if (mode == p_mode) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
mode = p_mode;
|
|
|
|
|
|
|
|
if (mode == RS::SKY_MODE_REALTIME && radiance_size != 256) {
|
|
|
|
WARN_PRINT("Realtime Skies can only use a radiance size of 256. Radiance size will be set to 256 internally.");
|
|
|
|
set_radiance_size(256);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (radiance.is_valid()) {
|
|
|
|
RD::get_singleton()->free(radiance);
|
|
|
|
radiance = RID();
|
|
|
|
}
|
|
|
|
reflection.clear_reflection_data();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
bool SkyRD::Sky::set_material(RID p_material) {
|
2021-02-13 12:08:08 +00:00
|
|
|
if (material == p_material) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
material = p_material;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
Ref<Image> SkyRD::Sky::bake_panorama(float p_energy, int p_roughness_layers, const Size2i &p_size) {
|
2021-02-13 12:08:08 +00:00
|
|
|
if (radiance.is_valid()) {
|
2022-04-29 07:10:54 +00:00
|
|
|
RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();
|
|
|
|
|
2021-02-13 12:08:08 +00:00
|
|
|
RD::TextureFormat tf;
|
|
|
|
tf.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
|
|
|
|
tf.width = p_size.width;
|
|
|
|
tf.height = p_size.height;
|
|
|
|
tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
|
|
|
|
|
|
|
|
RID rad_tex = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
2022-04-29 07:10:54 +00:00
|
|
|
copy_effects->copy_cubemap_to_panorama(radiance, rad_tex, p_size, p_roughness_layers, reflection.layers.size() > 1);
|
2021-02-13 12:08:08 +00:00
|
|
|
Vector<uint8_t> data = RD::get_singleton()->texture_get_data(rad_tex, 0);
|
|
|
|
RD::get_singleton()->free(rad_tex);
|
|
|
|
|
|
|
|
Ref<Image> img;
|
2021-06-17 22:03:09 +00:00
|
|
|
img.instantiate();
|
2021-02-13 12:08:08 +00:00
|
|
|
img->create(p_size.width, p_size.height, false, Image::FORMAT_RGBAF, data);
|
|
|
|
for (int i = 0; i < p_size.width; i++) {
|
|
|
|
for (int j = 0; j < p_size.height; j++) {
|
|
|
|
Color c = img->get_pixel(i, j);
|
|
|
|
c.r *= p_energy;
|
|
|
|
c.g *= p_energy;
|
|
|
|
c.b *= p_energy;
|
|
|
|
img->set_pixel(i, j, c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return img;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Ref<Image>();
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2022-07-19 04:17:58 +00:00
|
|
|
// SkyRD
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
RendererRD::ShaderData *SkyRD::_create_sky_shader_func() {
|
2021-02-13 12:08:08 +00:00
|
|
|
SkyShaderData *shader_data = memnew(SkyShaderData);
|
|
|
|
return shader_data;
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
RendererRD::ShaderData *SkyRD::_create_sky_shader_funcs() {
|
2021-02-13 12:08:08 +00:00
|
|
|
// !BAS! Why isn't _create_sky_shader_func not just static too?
|
|
|
|
return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->sky._create_sky_shader_func();
|
|
|
|
};
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
RendererRD::MaterialData *SkyRD::_create_sky_material_func(SkyShaderData *p_shader) {
|
2021-02-13 12:08:08 +00:00
|
|
|
SkyMaterialData *material_data = memnew(SkyMaterialData);
|
|
|
|
material_data->shader_data = p_shader;
|
|
|
|
//update will happen later anyway so do nothing.
|
|
|
|
return material_data;
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
RendererRD::MaterialData *SkyRD::_create_sky_material_funcs(RendererRD::ShaderData *p_shader) {
|
2021-02-13 12:08:08 +00:00
|
|
|
// !BAS! same here, we could just make _create_sky_material_func static?
|
|
|
|
return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->sky._create_sky_material_func(static_cast<SkyShaderData *>(p_shader));
|
|
|
|
};
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
SkyRD::SkyRD() {
|
2021-02-13 12:08:08 +00:00
|
|
|
roughness_layers = GLOBAL_GET("rendering/reflections/sky_reflections/roughness_layers");
|
|
|
|
sky_ggx_samples_quality = GLOBAL_GET("rendering/reflections/sky_reflections/ggx_samples");
|
|
|
|
sky_use_cubemap_array = GLOBAL_GET("rendering/reflections/sky_reflections/texture_array_reflections");
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::init() {
|
2022-03-12 11:19:59 +00:00
|
|
|
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
2022-03-21 11:25:25 +00:00
|
|
|
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
{
|
|
|
|
// Start with the directional lights for the sky
|
|
|
|
sky_scene_state.max_directional_lights = 4;
|
|
|
|
uint32_t directional_light_buffer_size = sky_scene_state.max_directional_lights * sizeof(SkyDirectionalLightData);
|
|
|
|
sky_scene_state.directional_lights = memnew_arr(SkyDirectionalLightData, sky_scene_state.max_directional_lights);
|
|
|
|
sky_scene_state.last_frame_directional_lights = memnew_arr(SkyDirectionalLightData, sky_scene_state.max_directional_lights);
|
|
|
|
sky_scene_state.last_frame_directional_light_count = sky_scene_state.max_directional_lights + 1;
|
|
|
|
sky_scene_state.directional_light_buffer = RD::get_singleton()->uniform_buffer_create(directional_light_buffer_size);
|
|
|
|
|
|
|
|
String defines = "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(sky_scene_state.max_directional_lights) + "\n";
|
|
|
|
|
|
|
|
// Initialize sky
|
|
|
|
Vector<String> sky_modes;
|
|
|
|
sky_modes.push_back(""); // Full size
|
|
|
|
sky_modes.push_back("\n#define USE_HALF_RES_PASS\n"); // Half Res
|
|
|
|
sky_modes.push_back("\n#define USE_QUARTER_RES_PASS\n"); // Quarter res
|
|
|
|
sky_modes.push_back("\n#define USE_CUBEMAP_PASS\n"); // Cubemap
|
|
|
|
sky_modes.push_back("\n#define USE_CUBEMAP_PASS\n#define USE_HALF_RES_PASS\n"); // Half Res Cubemap
|
|
|
|
sky_modes.push_back("\n#define USE_CUBEMAP_PASS\n#define USE_QUARTER_RES_PASS\n"); // Quarter res Cubemap
|
2021-05-07 13:19:04 +00:00
|
|
|
|
|
|
|
sky_modes.push_back("\n#define USE_MULTIVIEW\n"); // Full size multiview
|
|
|
|
sky_modes.push_back("\n#define USE_HALF_RES_PASS\n#define USE_MULTIVIEW\n"); // Half Res multiview
|
|
|
|
sky_modes.push_back("\n#define USE_QUARTER_RES_PASS\n#define USE_MULTIVIEW\n"); // Quarter res multiview
|
|
|
|
|
2021-02-13 12:08:08 +00:00
|
|
|
sky_shader.shader.initialize(sky_modes, defines);
|
2021-05-07 13:19:04 +00:00
|
|
|
|
|
|
|
if (!RendererCompositorRD::singleton->is_xr_enabled()) {
|
|
|
|
sky_shader.shader.set_variant_enabled(SKY_VERSION_BACKGROUND_MULTIVIEW, false);
|
|
|
|
sky_shader.shader.set_variant_enabled(SKY_VERSION_HALF_RES_MULTIVIEW, false);
|
|
|
|
sky_shader.shader.set_variant_enabled(SKY_VERSION_QUARTER_RES_MULTIVIEW, false);
|
|
|
|
}
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// register our shader funds
|
2022-03-21 11:25:25 +00:00
|
|
|
material_storage->shader_set_data_request_function(RendererRD::SHADER_TYPE_SKY, _create_sky_shader_funcs);
|
|
|
|
material_storage->material_set_data_request_function(RendererRD::SHADER_TYPE_SKY, _create_sky_material_funcs);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
{
|
2021-11-16 15:25:42 +00:00
|
|
|
ShaderCompiler::DefaultIdentifierActions actions;
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
actions.renames["COLOR"] = "color";
|
|
|
|
actions.renames["ALPHA"] = "alpha";
|
|
|
|
actions.renames["EYEDIR"] = "cube_normal";
|
|
|
|
actions.renames["POSITION"] = "params.position_multiplier.xyz";
|
|
|
|
actions.renames["SKY_COORDS"] = "panorama_coords";
|
|
|
|
actions.renames["SCREEN_UV"] = "uv";
|
2022-04-29 19:46:29 +00:00
|
|
|
actions.renames["FRAGCOORD"] = "gl_FragCoord";
|
2021-02-13 12:08:08 +00:00
|
|
|
actions.renames["TIME"] = "params.time";
|
2021-05-19 12:12:55 +00:00
|
|
|
actions.renames["PI"] = _MKSTR(Math_PI);
|
|
|
|
actions.renames["TAU"] = _MKSTR(Math_TAU);
|
|
|
|
actions.renames["E"] = _MKSTR(Math_E);
|
2021-02-13 12:08:08 +00:00
|
|
|
actions.renames["HALF_RES_COLOR"] = "half_res_color";
|
|
|
|
actions.renames["QUARTER_RES_COLOR"] = "quarter_res_color";
|
|
|
|
actions.renames["RADIANCE"] = "radiance";
|
|
|
|
actions.renames["FOG"] = "custom_fog";
|
|
|
|
actions.renames["LIGHT0_ENABLED"] = "directional_lights.data[0].enabled";
|
|
|
|
actions.renames["LIGHT0_DIRECTION"] = "directional_lights.data[0].direction_energy.xyz";
|
|
|
|
actions.renames["LIGHT0_ENERGY"] = "directional_lights.data[0].direction_energy.w";
|
|
|
|
actions.renames["LIGHT0_COLOR"] = "directional_lights.data[0].color_size.xyz";
|
|
|
|
actions.renames["LIGHT0_SIZE"] = "directional_lights.data[0].color_size.w";
|
|
|
|
actions.renames["LIGHT1_ENABLED"] = "directional_lights.data[1].enabled";
|
|
|
|
actions.renames["LIGHT1_DIRECTION"] = "directional_lights.data[1].direction_energy.xyz";
|
|
|
|
actions.renames["LIGHT1_ENERGY"] = "directional_lights.data[1].direction_energy.w";
|
|
|
|
actions.renames["LIGHT1_COLOR"] = "directional_lights.data[1].color_size.xyz";
|
|
|
|
actions.renames["LIGHT1_SIZE"] = "directional_lights.data[1].color_size.w";
|
|
|
|
actions.renames["LIGHT2_ENABLED"] = "directional_lights.data[2].enabled";
|
|
|
|
actions.renames["LIGHT2_DIRECTION"] = "directional_lights.data[2].direction_energy.xyz";
|
|
|
|
actions.renames["LIGHT2_ENERGY"] = "directional_lights.data[2].direction_energy.w";
|
|
|
|
actions.renames["LIGHT2_COLOR"] = "directional_lights.data[2].color_size.xyz";
|
|
|
|
actions.renames["LIGHT2_SIZE"] = "directional_lights.data[2].color_size.w";
|
|
|
|
actions.renames["LIGHT3_ENABLED"] = "directional_lights.data[3].enabled";
|
|
|
|
actions.renames["LIGHT3_DIRECTION"] = "directional_lights.data[3].direction_energy.xyz";
|
|
|
|
actions.renames["LIGHT3_ENERGY"] = "directional_lights.data[3].direction_energy.w";
|
|
|
|
actions.renames["LIGHT3_COLOR"] = "directional_lights.data[3].color_size.xyz";
|
|
|
|
actions.renames["LIGHT3_SIZE"] = "directional_lights.data[3].color_size.w";
|
|
|
|
actions.renames["AT_CUBEMAP_PASS"] = "AT_CUBEMAP_PASS";
|
|
|
|
actions.renames["AT_HALF_RES_PASS"] = "AT_HALF_RES_PASS";
|
|
|
|
actions.renames["AT_QUARTER_RES_PASS"] = "AT_QUARTER_RES_PASS";
|
|
|
|
actions.custom_samplers["RADIANCE"] = "material_samplers[3]";
|
|
|
|
actions.usage_defines["HALF_RES_COLOR"] = "\n#define USES_HALF_RES_COLOR\n";
|
|
|
|
actions.usage_defines["QUARTER_RES_COLOR"] = "\n#define USES_QUARTER_RES_COLOR\n";
|
|
|
|
actions.render_mode_defines["disable_fog"] = "#define DISABLE_FOG\n";
|
|
|
|
|
|
|
|
actions.sampler_array_name = "material_samplers";
|
|
|
|
actions.base_texture_binding_index = 1;
|
|
|
|
actions.texture_layout_set = 1;
|
|
|
|
actions.base_uniform_string = "material.";
|
|
|
|
actions.base_varying_index = 10;
|
|
|
|
|
|
|
|
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
|
|
|
|
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
|
|
|
|
actions.global_buffer_array_variable = "global_variables.data";
|
|
|
|
|
|
|
|
sky_shader.compiler.initialize(actions);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
// default material and shader for sky shader
|
2022-03-21 11:25:25 +00:00
|
|
|
sky_shader.default_shader = material_storage->shader_allocate();
|
|
|
|
material_storage->shader_initialize(sky_shader.default_shader);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2022-03-21 11:25:25 +00:00
|
|
|
material_storage->shader_set_code(sky_shader.default_shader, R"(
|
2021-08-18 01:09:22 +00:00
|
|
|
// Default sky shader.
|
|
|
|
|
2021-07-19 06:06:51 +00:00
|
|
|
shader_type sky;
|
|
|
|
|
|
|
|
void sky() {
|
|
|
|
COLOR = vec3(0.0);
|
|
|
|
}
|
|
|
|
)");
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2022-03-21 11:25:25 +00:00
|
|
|
sky_shader.default_material = material_storage->material_allocate();
|
|
|
|
material_storage->material_initialize(sky_shader.default_material);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2022-03-21 11:25:25 +00:00
|
|
|
material_storage->material_set_shader(sky_shader.default_material, sky_shader.default_shader);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2022-04-05 10:40:26 +00:00
|
|
|
SkyMaterialData *md = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_shader.default_material, RendererRD::SHADER_TYPE_SKY));
|
2021-02-13 12:08:08 +00:00
|
|
|
sky_shader.default_shader_rd = sky_shader.shader.version_get_shader(md->shader_data->version, SKY_VERSION_BACKGROUND);
|
|
|
|
|
|
|
|
sky_scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SkySceneState::UBO));
|
|
|
|
|
|
|
|
Vector<RD::Uniform> uniforms;
|
|
|
|
|
|
|
|
{
|
2022-03-06 11:57:09 +00:00
|
|
|
Vector<RID> ids;
|
|
|
|
ids.resize(12);
|
|
|
|
RID *ids_ptr = ids.ptrw();
|
2022-04-12 11:41:50 +00:00
|
|
|
ids_ptr[0] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
|
|
|
|
ids_ptr[1] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
|
|
|
|
ids_ptr[2] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
|
|
|
|
ids_ptr[3] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
|
|
|
|
ids_ptr[4] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
|
|
|
|
ids_ptr[5] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
|
|
|
|
ids_ptr[6] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
|
|
|
|
ids_ptr[7] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
|
|
|
|
ids_ptr[8] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
|
|
|
|
ids_ptr[9] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
|
|
|
|
ids_ptr[10] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
|
|
|
|
ids_ptr[11] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
|
2022-03-06 11:57:09 +00:00
|
|
|
|
|
|
|
RD::Uniform u(RD::UNIFORM_TYPE_SAMPLER, 0, ids);
|
|
|
|
|
2021-02-13 12:08:08 +00:00
|
|
|
uniforms.push_back(u);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
RD::Uniform u;
|
|
|
|
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
|
|
|
u.binding = 1;
|
2022-03-21 11:25:25 +00:00
|
|
|
u.append_id(RendererRD::MaterialStorage::get_singleton()->global_variables_get_storage_buffer());
|
2021-02-13 12:08:08 +00:00
|
|
|
uniforms.push_back(u);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
RD::Uniform u;
|
|
|
|
u.binding = 2;
|
|
|
|
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
2022-03-06 11:57:09 +00:00
|
|
|
u.append_id(sky_scene_state.uniform_buffer);
|
2021-02-13 12:08:08 +00:00
|
|
|
uniforms.push_back(u);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
RD::Uniform u;
|
|
|
|
u.binding = 3;
|
|
|
|
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
2022-03-06 11:57:09 +00:00
|
|
|
u.append_id(sky_scene_state.directional_light_buffer);
|
2021-02-13 12:08:08 +00:00
|
|
|
uniforms.push_back(u);
|
|
|
|
}
|
|
|
|
|
|
|
|
sky_scene_state.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_UNIFORMS);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
Vector<RD::Uniform> uniforms;
|
|
|
|
{
|
|
|
|
RD::Uniform u;
|
|
|
|
u.binding = 0;
|
|
|
|
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
2022-03-12 11:19:59 +00:00
|
|
|
RID vfog = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE);
|
2022-03-06 11:57:09 +00:00
|
|
|
u.append_id(vfog);
|
2021-02-13 12:08:08 +00:00
|
|
|
uniforms.push_back(u);
|
|
|
|
}
|
|
|
|
|
|
|
|
sky_scene_state.default_fog_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_FOG);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
// Need defaults for using fog with clear color
|
2022-03-21 11:25:25 +00:00
|
|
|
sky_scene_state.fog_shader = material_storage->shader_allocate();
|
|
|
|
material_storage->shader_initialize(sky_scene_state.fog_shader);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2022-03-21 11:25:25 +00:00
|
|
|
material_storage->shader_set_code(sky_scene_state.fog_shader, R"(
|
2021-08-18 01:09:22 +00:00
|
|
|
// Default clear color sky shader.
|
|
|
|
|
2021-07-19 06:06:51 +00:00
|
|
|
shader_type sky;
|
|
|
|
|
|
|
|
uniform vec4 clear_color;
|
|
|
|
|
|
|
|
void sky() {
|
|
|
|
COLOR = clear_color.rgb;
|
|
|
|
}
|
|
|
|
)");
|
2022-03-21 11:25:25 +00:00
|
|
|
sky_scene_state.fog_material = material_storage->material_allocate();
|
|
|
|
material_storage->material_initialize(sky_scene_state.fog_material);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2022-03-21 11:25:25 +00:00
|
|
|
material_storage->material_set_shader(sky_scene_state.fog_material, sky_scene_state.fog_shader);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
Vector<RD::Uniform> uniforms;
|
|
|
|
{
|
|
|
|
RD::Uniform u;
|
|
|
|
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
|
|
|
u.binding = 0;
|
2022-03-12 11:19:59 +00:00
|
|
|
u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
|
2021-02-13 12:08:08 +00:00
|
|
|
uniforms.push_back(u);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
RD::Uniform u;
|
|
|
|
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
|
|
|
u.binding = 1;
|
2022-03-12 11:19:59 +00:00
|
|
|
u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE));
|
2021-02-13 12:08:08 +00:00
|
|
|
uniforms.push_back(u);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
RD::Uniform u;
|
|
|
|
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
|
|
|
u.binding = 2;
|
2022-03-12 11:19:59 +00:00
|
|
|
u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE));
|
2021-02-13 12:08:08 +00:00
|
|
|
uniforms.push_back(u);
|
|
|
|
}
|
|
|
|
|
|
|
|
sky_scene_state.fog_only_texture_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_TEXTURES);
|
|
|
|
}
|
2021-06-22 06:24:09 +00:00
|
|
|
|
|
|
|
{ //create index array for copy shaders
|
|
|
|
Vector<uint8_t> pv;
|
|
|
|
pv.resize(6 * 4);
|
|
|
|
{
|
|
|
|
uint8_t *w = pv.ptrw();
|
|
|
|
int *p32 = (int *)w;
|
|
|
|
p32[0] = 0;
|
|
|
|
p32[1] = 1;
|
|
|
|
p32[2] = 2;
|
|
|
|
p32[3] = 0;
|
|
|
|
p32[4] = 2;
|
|
|
|
p32[5] = 3;
|
|
|
|
}
|
|
|
|
index_buffer = RD::get_singleton()->index_buffer_create(6, RenderingDevice::INDEX_BUFFER_FORMAT_UINT32, pv);
|
|
|
|
index_array = RD::get_singleton()->index_array_create(index_buffer, 0, 6);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::set_texture_format(RD::DataFormat p_texture_format) {
|
2021-07-27 13:33:47 +00:00
|
|
|
texture_format = p_texture_format;
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
SkyRD::~SkyRD() {
|
2022-03-21 11:25:25 +00:00
|
|
|
// cleanup anything created in init...
|
|
|
|
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
|
|
|
|
|
2022-04-05 10:40:26 +00:00
|
|
|
SkyMaterialData *md = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_shader.default_material, RendererRD::SHADER_TYPE_SKY));
|
2022-03-21 11:25:25 +00:00
|
|
|
sky_shader.shader.version_free(md->shader_data->version);
|
|
|
|
RD::get_singleton()->free(sky_scene_state.directional_light_buffer);
|
|
|
|
RD::get_singleton()->free(sky_scene_state.uniform_buffer);
|
|
|
|
memdelete_arr(sky_scene_state.directional_lights);
|
|
|
|
memdelete_arr(sky_scene_state.last_frame_directional_lights);
|
|
|
|
material_storage->shader_free(sky_shader.default_shader);
|
|
|
|
material_storage->material_free(sky_shader.default_material);
|
|
|
|
material_storage->shader_free(sky_scene_state.fog_shader);
|
|
|
|
material_storage->material_free(sky_scene_state.fog_material);
|
2021-06-22 06:24:09 +00:00
|
|
|
|
|
|
|
if (RD::get_singleton()->uniform_set_is_valid(sky_scene_state.uniform_set)) {
|
|
|
|
RD::get_singleton()->free(sky_scene_state.uniform_set);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (RD::get_singleton()->uniform_set_is_valid(sky_scene_state.default_fog_uniform_set)) {
|
|
|
|
RD::get_singleton()->free(sky_scene_state.default_fog_uniform_set);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (RD::get_singleton()->uniform_set_is_valid(sky_scene_state.fog_only_texture_uniform_set)) {
|
|
|
|
RD::get_singleton()->free(sky_scene_state.fog_only_texture_uniform_set);
|
|
|
|
}
|
|
|
|
|
|
|
|
RD::get_singleton()->free(index_buffer); //array gets freed as dependency
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
void SkyRD::setup(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) {
|
2022-04-09 09:34:31 +00:00
|
|
|
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
|
2022-03-21 11:25:25 +00:00
|
|
|
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
|
2022-07-27 06:14:23 +00:00
|
|
|
ERR_FAIL_COND(p_env.is_null());
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
SkyMaterialData *material = nullptr;
|
2022-07-27 06:14:23 +00:00
|
|
|
Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env));
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
RID sky_material;
|
|
|
|
|
|
|
|
SkyShaderData *shader_data = nullptr;
|
|
|
|
|
2021-10-07 04:46:07 +00:00
|
|
|
if (sky) {
|
2022-07-27 06:14:23 +00:00
|
|
|
sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env));
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
if (sky_material.is_valid()) {
|
2022-04-05 10:40:26 +00:00
|
|
|
material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY));
|
2021-02-13 12:08:08 +00:00
|
|
|
if (!material || !material->shader_data->valid) {
|
|
|
|
material = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!material) {
|
|
|
|
sky_material = sky_shader.default_material;
|
2022-04-05 10:40:26 +00:00
|
|
|
material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY));
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ERR_FAIL_COND(!material);
|
|
|
|
|
|
|
|
shader_data = material->shader_data;
|
|
|
|
|
|
|
|
ERR_FAIL_COND(!shader_data);
|
|
|
|
|
|
|
|
// Invalidate supbass buffers if screen size changes
|
|
|
|
if (sky->screen_size != p_screen_size) {
|
|
|
|
sky->screen_size = p_screen_size;
|
|
|
|
sky->screen_size.x = sky->screen_size.x < 4 ? 4 : sky->screen_size.x;
|
|
|
|
sky->screen_size.y = sky->screen_size.y < 4 ? 4 : sky->screen_size.y;
|
|
|
|
if (shader_data->uses_half_res) {
|
|
|
|
if (sky->half_res_pass.is_valid()) {
|
|
|
|
RD::get_singleton()->free(sky->half_res_pass);
|
|
|
|
sky->half_res_pass = RID();
|
|
|
|
}
|
|
|
|
invalidate_sky(sky);
|
|
|
|
}
|
|
|
|
if (shader_data->uses_quarter_res) {
|
|
|
|
if (sky->quarter_res_pass.is_valid()) {
|
|
|
|
RD::get_singleton()->free(sky->quarter_res_pass);
|
|
|
|
sky->quarter_res_pass = RID();
|
|
|
|
}
|
|
|
|
invalidate_sky(sky);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create new subpass buffers if necessary
|
|
|
|
if ((shader_data->uses_half_res && sky->half_res_pass.is_null()) ||
|
|
|
|
(shader_data->uses_quarter_res && sky->quarter_res_pass.is_null()) ||
|
|
|
|
sky->radiance.is_null()) {
|
|
|
|
invalidate_sky(sky);
|
|
|
|
update_dirty_skys();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (shader_data->uses_time && p_scene_render->time - sky->prev_time > 0.00001) {
|
|
|
|
sky->prev_time = p_scene_render->time;
|
|
|
|
sky->reflection.dirty = true;
|
|
|
|
RenderingServerDefault::redraw_request();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (material != sky->prev_material) {
|
|
|
|
sky->prev_material = material;
|
|
|
|
sky->reflection.dirty = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (material->uniform_set_updated) {
|
|
|
|
material->uniform_set_updated = false;
|
|
|
|
sky->reflection.dirty = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!p_transform.origin.is_equal_approx(sky->prev_position) && shader_data->uses_position) {
|
|
|
|
sky->prev_position = p_transform.origin;
|
|
|
|
sky->reflection.dirty = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (shader_data->uses_light) {
|
2022-01-23 23:06:49 +00:00
|
|
|
sky_scene_state.ubo.directional_light_count = 0;
|
|
|
|
// Run through the list of lights in the scene and pick out the Directional Lights.
|
|
|
|
// This can't be done in RenderSceneRenderRD::_setup lights because that needs to be called
|
|
|
|
// after the depth prepass, but this runs before the depth prepass
|
|
|
|
for (int i = 0; i < (int)p_lights.size(); i++) {
|
|
|
|
RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.get_or_null(p_lights[i]);
|
|
|
|
if (!li) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
RID base = li->light;
|
|
|
|
|
|
|
|
ERR_CONTINUE(base.is_null());
|
|
|
|
|
2022-04-09 09:34:31 +00:00
|
|
|
RS::LightType type = light_storage->light_get_type(base);
|
|
|
|
if (type == RS::LIGHT_DIRECTIONAL && light_storage->light_directional_get_sky_mode(base) != RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_ONLY) {
|
2022-01-23 23:06:49 +00:00
|
|
|
SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[sky_scene_state.ubo.directional_light_count];
|
|
|
|
Transform3D light_transform = li->transform;
|
|
|
|
Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized();
|
|
|
|
|
|
|
|
sky_light_data.direction[0] = world_direction.x;
|
|
|
|
sky_light_data.direction[1] = world_direction.y;
|
2022-03-07 07:54:21 +00:00
|
|
|
sky_light_data.direction[2] = world_direction.z;
|
2022-01-23 23:06:49 +00:00
|
|
|
|
2022-04-09 09:34:31 +00:00
|
|
|
float sign = light_storage->light_is_negative(base) ? -1 : 1;
|
|
|
|
sky_light_data.energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY);
|
2022-01-23 23:06:49 +00:00
|
|
|
|
2022-04-09 09:34:31 +00:00
|
|
|
Color linear_col = light_storage->light_get_color(base).srgb_to_linear();
|
2022-01-23 23:06:49 +00:00
|
|
|
sky_light_data.color[0] = linear_col.r;
|
|
|
|
sky_light_data.color[1] = linear_col.g;
|
|
|
|
sky_light_data.color[2] = linear_col.b;
|
|
|
|
|
|
|
|
sky_light_data.enabled = true;
|
|
|
|
|
2022-04-09 09:34:31 +00:00
|
|
|
float angular_diameter = light_storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
|
2022-01-23 23:06:49 +00:00
|
|
|
if (angular_diameter > 0.0) {
|
|
|
|
// I know tan(0) is 0, but let's not risk it with numerical precision.
|
|
|
|
// technically this will keep expanding until reaching the sun, but all we care
|
|
|
|
// is expand until we reach the radius of the near plane (there can't be more occluders than that)
|
|
|
|
angular_diameter = Math::tan(Math::deg2rad(angular_diameter));
|
|
|
|
} else {
|
|
|
|
angular_diameter = 0.0;
|
|
|
|
}
|
|
|
|
sky_light_data.size = angular_diameter;
|
|
|
|
sky_scene_state.ubo.directional_light_count++;
|
|
|
|
if (sky_scene_state.ubo.directional_light_count >= sky_scene_state.max_directional_lights) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-02-13 12:08:08 +00:00
|
|
|
// Check whether the directional_light_buffer changes
|
2022-02-10 19:21:28 +00:00
|
|
|
bool light_data_dirty = false;
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2022-01-23 23:06:49 +00:00
|
|
|
// Light buffer is dirty if we have fewer or more lights
|
|
|
|
// If we have fewer lights, make sure that old lights are disabled
|
2021-02-13 12:08:08 +00:00
|
|
|
if (sky_scene_state.ubo.directional_light_count != sky_scene_state.last_frame_directional_light_count) {
|
|
|
|
light_data_dirty = true;
|
|
|
|
for (uint32_t i = sky_scene_state.ubo.directional_light_count; i < sky_scene_state.max_directional_lights; i++) {
|
|
|
|
sky_scene_state.directional_lights[i].enabled = false;
|
|
|
|
}
|
|
|
|
}
|
2022-01-23 23:06:49 +00:00
|
|
|
|
2021-02-13 12:08:08 +00:00
|
|
|
if (!light_data_dirty) {
|
|
|
|
for (uint32_t i = 0; i < sky_scene_state.ubo.directional_light_count; i++) {
|
|
|
|
if (sky_scene_state.directional_lights[i].direction[0] != sky_scene_state.last_frame_directional_lights[i].direction[0] ||
|
|
|
|
sky_scene_state.directional_lights[i].direction[1] != sky_scene_state.last_frame_directional_lights[i].direction[1] ||
|
|
|
|
sky_scene_state.directional_lights[i].direction[2] != sky_scene_state.last_frame_directional_lights[i].direction[2] ||
|
|
|
|
sky_scene_state.directional_lights[i].energy != sky_scene_state.last_frame_directional_lights[i].energy ||
|
|
|
|
sky_scene_state.directional_lights[i].color[0] != sky_scene_state.last_frame_directional_lights[i].color[0] ||
|
|
|
|
sky_scene_state.directional_lights[i].color[1] != sky_scene_state.last_frame_directional_lights[i].color[1] ||
|
|
|
|
sky_scene_state.directional_lights[i].color[2] != sky_scene_state.last_frame_directional_lights[i].color[2] ||
|
|
|
|
sky_scene_state.directional_lights[i].enabled != sky_scene_state.last_frame_directional_lights[i].enabled ||
|
|
|
|
sky_scene_state.directional_lights[i].size != sky_scene_state.last_frame_directional_lights[i].size) {
|
|
|
|
light_data_dirty = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (light_data_dirty) {
|
|
|
|
RD::get_singleton()->buffer_update(sky_scene_state.directional_light_buffer, 0, sizeof(SkyDirectionalLightData) * sky_scene_state.max_directional_lights, sky_scene_state.directional_lights);
|
|
|
|
|
|
|
|
SkyDirectionalLightData *temp = sky_scene_state.last_frame_directional_lights;
|
|
|
|
sky_scene_state.last_frame_directional_lights = sky_scene_state.directional_lights;
|
|
|
|
sky_scene_state.directional_lights = temp;
|
|
|
|
sky_scene_state.last_frame_directional_light_count = sky_scene_state.ubo.directional_light_count;
|
|
|
|
sky->reflection.dirty = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//setup fog variables
|
|
|
|
sky_scene_state.ubo.volumetric_fog_enabled = false;
|
|
|
|
if (p_render_buffers.is_valid()) {
|
|
|
|
if (p_scene_render->render_buffers_has_volumetric_fog(p_render_buffers)) {
|
|
|
|
sky_scene_state.ubo.volumetric_fog_enabled = true;
|
|
|
|
|
|
|
|
float fog_end = p_scene_render->render_buffers_get_volumetric_fog_end(p_render_buffers);
|
|
|
|
if (fog_end > 0.0) {
|
|
|
|
sky_scene_state.ubo.volumetric_fog_inv_length = 1.0 / fog_end;
|
|
|
|
} else {
|
|
|
|
sky_scene_state.ubo.volumetric_fog_inv_length = 1.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
float fog_detail_spread = p_scene_render->render_buffers_get_volumetric_fog_detail_spread(p_render_buffers); //reverse lookup
|
|
|
|
if (fog_detail_spread > 0.0) {
|
|
|
|
sky_scene_state.ubo.volumetric_fog_detail_spread = 1.0 / fog_detail_spread;
|
|
|
|
} else {
|
|
|
|
sky_scene_state.ubo.volumetric_fog_detail_spread = 1.0;
|
|
|
|
}
|
|
|
|
|
2021-10-03 11:28:55 +00:00
|
|
|
sky_scene_state.fog_uniform_set = p_scene_render->render_buffers_get_volumetric_fog_sky_uniform_set(p_render_buffers);
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sky_scene_state.ubo.z_far = p_projection.get_z_far();
|
2022-07-27 06:14:23 +00:00
|
|
|
sky_scene_state.ubo.fog_enabled = RendererSceneRenderRD::get_singleton()->environment_get_fog_enabled(p_env);
|
|
|
|
sky_scene_state.ubo.fog_density = RendererSceneRenderRD::get_singleton()->environment_get_fog_density(p_env);
|
|
|
|
sky_scene_state.ubo.fog_aerial_perspective = RendererSceneRenderRD::get_singleton()->environment_get_fog_aerial_perspective(p_env);
|
|
|
|
Color fog_color = RendererSceneRenderRD::get_singleton()->environment_get_fog_light_color(p_env).srgb_to_linear();
|
|
|
|
float fog_energy = RendererSceneRenderRD::get_singleton()->environment_get_fog_light_energy(p_env);
|
2021-02-13 12:08:08 +00:00
|
|
|
sky_scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy;
|
|
|
|
sky_scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy;
|
|
|
|
sky_scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy;
|
2022-07-27 06:14:23 +00:00
|
|
|
sky_scene_state.ubo.fog_sun_scatter = RendererSceneRenderRD::get_singleton()->environment_get_fog_sun_scatter(p_env);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo);
|
|
|
|
}
|
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
|
2022-03-21 11:25:25 +00:00
|
|
|
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
|
2022-07-27 06:14:23 +00:00
|
|
|
ERR_FAIL_COND(p_env.is_null());
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env));
|
2021-02-13 12:08:08 +00:00
|
|
|
ERR_FAIL_COND(!sky);
|
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
RID sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env));
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
SkyMaterialData *material = nullptr;
|
|
|
|
|
|
|
|
if (sky_material.is_valid()) {
|
2022-04-05 10:40:26 +00:00
|
|
|
material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY));
|
2021-02-13 12:08:08 +00:00
|
|
|
if (!material || !material->shader_data->valid) {
|
|
|
|
material = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!material) {
|
|
|
|
sky_material = sky_shader.default_material;
|
2022-04-05 10:40:26 +00:00
|
|
|
material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY));
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ERR_FAIL_COND(!material);
|
|
|
|
|
|
|
|
SkyShaderData *shader_data = material->shader_data;
|
|
|
|
|
|
|
|
ERR_FAIL_COND(!shader_data);
|
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
bool update_single_frame = sky->mode == RS::SKY_MODE_REALTIME || sky->mode == RS::SKY_MODE_QUALITY;
|
|
|
|
RS::SkyMode sky_mode = sky->mode;
|
|
|
|
|
|
|
|
if (sky_mode == RS::SKY_MODE_AUTOMATIC) {
|
|
|
|
if (shader_data->uses_time || shader_data->uses_position) {
|
|
|
|
update_single_frame = true;
|
|
|
|
sky_mode = RS::SKY_MODE_REALTIME;
|
|
|
|
} else if (shader_data->uses_light || shader_data->ubo_size > 0) {
|
|
|
|
update_single_frame = false;
|
|
|
|
sky_mode = RS::SKY_MODE_INCREMENTAL;
|
|
|
|
} else {
|
|
|
|
update_single_frame = true;
|
|
|
|
sky_mode = RS::SKY_MODE_QUALITY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sky->processing_layer == 0 && sky_mode == RS::SKY_MODE_INCREMENTAL) {
|
|
|
|
// On the first frame after creating sky, rebuild in single frame
|
|
|
|
update_single_frame = true;
|
|
|
|
sky_mode = RS::SKY_MODE_QUALITY;
|
|
|
|
}
|
|
|
|
|
|
|
|
int max_processing_layer = sky_use_cubemap_array ? sky->reflection.layers.size() : sky->reflection.layers[0].mipmaps.size();
|
|
|
|
|
|
|
|
// Update radiance cubemap
|
|
|
|
if (sky->reflection.dirty && (sky->processing_layer >= max_processing_layer || update_single_frame)) {
|
|
|
|
static const Vector3 view_normals[6] = {
|
|
|
|
Vector3(+1, 0, 0),
|
|
|
|
Vector3(-1, 0, 0),
|
|
|
|
Vector3(0, +1, 0),
|
|
|
|
Vector3(0, -1, 0),
|
|
|
|
Vector3(0, 0, +1),
|
|
|
|
Vector3(0, 0, -1)
|
|
|
|
};
|
|
|
|
static const Vector3 view_up[6] = {
|
|
|
|
Vector3(0, -1, 0),
|
|
|
|
Vector3(0, -1, 0),
|
|
|
|
Vector3(0, 0, +1),
|
|
|
|
Vector3(0, 0, -1),
|
|
|
|
Vector3(0, -1, 0),
|
|
|
|
Vector3(0, -1, 0)
|
|
|
|
};
|
|
|
|
|
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
|
|
|
Projection cm;
|
2021-02-13 12:08:08 +00:00
|
|
|
cm.set_perspective(90, 1, 0.01, 10.0);
|
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
|
|
|
Projection correction;
|
2021-02-13 12:08:08 +00:00
|
|
|
correction.set_depth_correction(true);
|
|
|
|
cm = correction * cm;
|
|
|
|
|
|
|
|
if (shader_data->uses_quarter_res) {
|
2021-07-27 13:33:47 +00:00
|
|
|
RD::get_singleton()->draw_command_begin_label("Render Sky to Quarter Res Cubemap");
|
2021-02-13 12:08:08 +00:00
|
|
|
PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP_QUARTER_RES];
|
|
|
|
|
|
|
|
Vector<Color> clear_colors;
|
|
|
|
clear_colors.push_back(Color(0.0, 0.0, 0.0));
|
|
|
|
RD::DrawListID cubemap_draw_list;
|
|
|
|
|
|
|
|
for (int i = 0; i < 6; i++) {
|
2021-07-21 03:32:00 +00:00
|
|
|
Basis local_view = Basis::looking_at(view_normals[i], view_up[i]);
|
2022-06-21 00:08:33 +00:00
|
|
|
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES, sky_shader.default_shader_rd);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[2].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
|
2021-07-26 11:31:15 +00:00
|
|
|
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin, p_luminance_multiplier);
|
2021-02-13 12:08:08 +00:00
|
|
|
RD::get_singleton()->draw_list_end();
|
|
|
|
}
|
2021-07-27 13:33:47 +00:00
|
|
|
RD::get_singleton()->draw_command_end_label();
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (shader_data->uses_half_res) {
|
2021-07-27 13:33:47 +00:00
|
|
|
RD::get_singleton()->draw_command_begin_label("Render Sky to Half Res Cubemap");
|
2021-02-13 12:08:08 +00:00
|
|
|
PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP_HALF_RES];
|
|
|
|
|
|
|
|
Vector<Color> clear_colors;
|
|
|
|
clear_colors.push_back(Color(0.0, 0.0, 0.0));
|
|
|
|
RD::DrawListID cubemap_draw_list;
|
|
|
|
|
|
|
|
for (int i = 0; i < 6; i++) {
|
2021-07-21 03:32:00 +00:00
|
|
|
Basis local_view = Basis::looking_at(view_normals[i], view_up[i]);
|
2022-06-21 00:08:33 +00:00
|
|
|
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_HALF_RES, sky_shader.default_shader_rd);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[1].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
|
2021-07-26 11:31:15 +00:00
|
|
|
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin, p_luminance_multiplier);
|
2021-02-13 12:08:08 +00:00
|
|
|
RD::get_singleton()->draw_list_end();
|
|
|
|
}
|
2021-07-27 13:33:47 +00:00
|
|
|
RD::get_singleton()->draw_command_end_label();
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
RD::DrawListID cubemap_draw_list;
|
|
|
|
PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP];
|
|
|
|
|
2021-07-27 13:33:47 +00:00
|
|
|
RD::get_singleton()->draw_command_begin_label("Render Sky Cubemap");
|
2021-02-13 12:08:08 +00:00
|
|
|
for (int i = 0; i < 6; i++) {
|
2021-07-21 03:32:00 +00:00
|
|
|
Basis local_view = Basis::looking_at(view_normals[i], view_up[i]);
|
2022-06-21 00:08:33 +00:00
|
|
|
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP, sky_shader.default_shader_rd);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[0].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
|
2021-07-26 11:31:15 +00:00
|
|
|
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin, p_luminance_multiplier);
|
2021-02-13 12:08:08 +00:00
|
|
|
RD::get_singleton()->draw_list_end();
|
|
|
|
}
|
2021-07-27 13:33:47 +00:00
|
|
|
RD::get_singleton()->draw_command_end_label();
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
if (sky_mode == RS::SKY_MODE_REALTIME) {
|
2022-06-21 00:08:33 +00:00
|
|
|
sky->reflection.create_reflection_fast_filter(sky_use_cubemap_array);
|
2021-02-13 12:08:08 +00:00
|
|
|
if (sky_use_cubemap_array) {
|
2022-06-21 00:08:33 +00:00
|
|
|
sky->reflection.update_reflection_mipmaps(0, sky->reflection.layers.size());
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (update_single_frame) {
|
|
|
|
for (int i = 1; i < max_processing_layer; i++) {
|
2022-06-21 00:08:33 +00:00
|
|
|
sky->reflection.create_reflection_importance_sample(sky_use_cubemap_array, 10, i, sky_ggx_samples_quality);
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
if (sky_use_cubemap_array) {
|
2022-06-21 00:08:33 +00:00
|
|
|
sky->reflection.update_reflection_mipmaps(0, sky->reflection.layers.size());
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (sky_use_cubemap_array) {
|
|
|
|
// Multi-Frame so just update the first array level
|
2022-06-21 00:08:33 +00:00
|
|
|
sky->reflection.update_reflection_mipmaps(0, 1);
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
sky->processing_layer = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
sky->reflection.dirty = false;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
if (sky_mode == RS::SKY_MODE_INCREMENTAL && sky->processing_layer < max_processing_layer) {
|
2022-06-21 00:08:33 +00:00
|
|
|
sky->reflection.create_reflection_importance_sample(sky_use_cubemap_array, 10, sky->processing_layer, sky_ggx_samples_quality);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
if (sky_use_cubemap_array) {
|
2022-06-21 00:08:33 +00:00
|
|
|
sky->reflection.update_reflection_mipmaps(sky->processing_layer, sky->processing_layer + 1);
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sky->processing_layer++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time) {
|
2022-03-21 11:25:25 +00:00
|
|
|
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
|
2022-07-27 06:14:23 +00:00
|
|
|
ERR_FAIL_COND(p_env.is_null());
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2021-05-07 13:19:04 +00:00
|
|
|
ERR_FAIL_COND(p_view_count == 0);
|
|
|
|
ERR_FAIL_COND(p_view_count > RendererSceneRender::MAX_RENDER_VIEWS);
|
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env));
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
SkyMaterialData *material = nullptr;
|
|
|
|
RID sky_material;
|
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
RS::EnvironmentBG background = RendererSceneRenderRD::get_singleton()->environment_get_background(p_env);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
if (!(background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) || sky) {
|
|
|
|
ERR_FAIL_COND(!sky);
|
2022-07-27 06:14:23 +00:00
|
|
|
sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env));
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
if (sky_material.is_valid()) {
|
2022-04-05 10:40:26 +00:00
|
|
|
material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY));
|
2021-02-13 12:08:08 +00:00
|
|
|
if (!material || !material->shader_data->valid) {
|
|
|
|
material = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!material) {
|
|
|
|
sky_material = sky_shader.default_material;
|
2022-04-05 10:40:26 +00:00
|
|
|
material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY));
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) {
|
|
|
|
sky_material = sky_scene_state.fog_material;
|
2022-04-05 10:40:26 +00:00
|
|
|
material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY));
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ERR_FAIL_COND(!material);
|
|
|
|
|
|
|
|
SkyShaderData *shader_data = material->shader_data;
|
|
|
|
|
|
|
|
ERR_FAIL_COND(!shader_data);
|
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env);
|
2021-02-13 12:08:08 +00:00
|
|
|
sky_transform.invert();
|
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env);
|
|
|
|
float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env);
|
2021-05-07 13:19:04 +00:00
|
|
|
|
2021-02-13 12:08:08 +00:00
|
|
|
// Camera
|
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
|
|
|
Projection camera;
|
2021-05-07 13:19:04 +00:00
|
|
|
uint32_t view_count = p_view_count;
|
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
|
|
|
const Projection *projections = p_projections;
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
if (custom_fov) {
|
2021-05-07 13:19:04 +00:00
|
|
|
// With custom fov we don't support stereo...
|
|
|
|
float near_plane = p_projections[0].get_z_near();
|
|
|
|
float far_plane = p_projections[0].get_z_far();
|
|
|
|
float aspect = p_projections[0].get_aspect();
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
camera.set_perspective(custom_fov, aspect, near_plane, far_plane);
|
|
|
|
|
2021-05-07 13:19:04 +00:00
|
|
|
view_count = 1;
|
|
|
|
projections = &camera;
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
|
2022-06-09 19:35:20 +00:00
|
|
|
sky_transform = sky_transform * p_transform.basis;
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
if (shader_data->uses_quarter_res) {
|
2021-05-07 13:19:04 +00:00
|
|
|
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES];
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2022-06-21 00:08:33 +00:00
|
|
|
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
Vector<Color> clear_colors;
|
|
|
|
clear_colors.push_back(Color(0.0, 0.0, 0.0));
|
|
|
|
|
|
|
|
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->quarter_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
|
2021-07-26 11:31:15 +00:00
|
|
|
_render_sky(draw_list, p_time, sky->quarter_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, 1.0);
|
2021-02-13 12:08:08 +00:00
|
|
|
RD::get_singleton()->draw_list_end();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (shader_data->uses_half_res) {
|
2021-05-07 13:19:04 +00:00
|
|
|
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_HALF_RES_MULTIVIEW : SKY_VERSION_HALF_RES];
|
2021-02-13 12:08:08 +00:00
|
|
|
|
2022-06-21 00:08:33 +00:00
|
|
|
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
Vector<Color> clear_colors;
|
|
|
|
clear_colors.push_back(Color(0.0, 0.0, 0.0));
|
|
|
|
|
|
|
|
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->half_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
|
2021-07-26 11:31:15 +00:00
|
|
|
_render_sky(draw_list, p_time, sky->half_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, 1.0);
|
2021-02-13 12:08:08 +00:00
|
|
|
RD::get_singleton()->draw_list_end();
|
|
|
|
}
|
|
|
|
|
2021-05-07 13:19:04 +00:00
|
|
|
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_BACKGROUND_MULTIVIEW : SKY_VERSION_BACKGROUND];
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
RID texture_uniform_set;
|
|
|
|
if (sky) {
|
2022-06-21 00:08:33 +00:00
|
|
|
texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd);
|
2021-02-13 12:08:08 +00:00
|
|
|
} else {
|
|
|
|
texture_uniform_set = sky_scene_state.fog_only_texture_uniform_set;
|
|
|
|
}
|
|
|
|
|
|
|
|
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_fb, RD::INITIAL_ACTION_CONTINUE, p_can_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, p_can_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
|
2021-07-26 11:31:15 +00:00
|
|
|
_render_sky(draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, 1.0);
|
2021-02-13 12:08:08 +00:00
|
|
|
RD::get_singleton()->draw_list_end();
|
|
|
|
}
|
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
void SkyRD::update_res_buffers(RID p_env, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
|
2022-03-21 11:25:25 +00:00
|
|
|
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
|
2022-07-27 06:14:23 +00:00
|
|
|
ERR_FAIL_COND(p_env.is_null());
|
2021-06-26 10:49:25 +00:00
|
|
|
|
|
|
|
ERR_FAIL_COND(p_view_count == 0);
|
|
|
|
ERR_FAIL_COND(p_view_count > RendererSceneRender::MAX_RENDER_VIEWS);
|
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env));
|
2021-06-26 10:49:25 +00:00
|
|
|
ERR_FAIL_COND(!sky);
|
|
|
|
|
|
|
|
SkyMaterialData *material = nullptr;
|
|
|
|
RID sky_material;
|
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env));
|
2021-06-26 10:49:25 +00:00
|
|
|
|
2021-10-07 04:46:07 +00:00
|
|
|
if (sky_material.is_valid()) {
|
2022-04-05 10:40:26 +00:00
|
|
|
material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY));
|
2021-10-07 04:46:07 +00:00
|
|
|
if (!material || !material->shader_data->valid) {
|
|
|
|
material = nullptr;
|
2021-06-26 10:49:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-07 04:46:07 +00:00
|
|
|
if (!material) {
|
|
|
|
sky_material = sky_shader.default_material;
|
2022-04-05 10:40:26 +00:00
|
|
|
material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY));
|
2021-06-26 10:49:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ERR_FAIL_COND(!material);
|
|
|
|
|
|
|
|
SkyShaderData *shader_data = material->shader_data;
|
|
|
|
|
|
|
|
ERR_FAIL_COND(!shader_data);
|
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env);
|
2021-06-26 10:49:25 +00:00
|
|
|
sky_transform.invert();
|
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env);
|
|
|
|
float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env);
|
2021-06-26 10:49:25 +00:00
|
|
|
|
|
|
|
// Camera
|
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
|
|
|
Projection camera;
|
2021-06-26 10:49:25 +00:00
|
|
|
uint32_t view_count = p_view_count;
|
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
|
|
|
const Projection *projections = p_projections;
|
2021-06-26 10:49:25 +00:00
|
|
|
|
|
|
|
if (custom_fov) {
|
|
|
|
// With custom fov we don't support stereo...
|
|
|
|
float near_plane = p_projections[0].get_z_near();
|
|
|
|
float far_plane = p_projections[0].get_z_far();
|
|
|
|
float aspect = p_projections[0].get_aspect();
|
|
|
|
|
|
|
|
camera.set_perspective(custom_fov, aspect, near_plane, far_plane);
|
|
|
|
|
|
|
|
view_count = 1;
|
|
|
|
projections = &camera;
|
|
|
|
}
|
|
|
|
|
|
|
|
sky_transform = p_transform.basis * sky_transform;
|
|
|
|
|
|
|
|
if (shader_data->uses_quarter_res) {
|
|
|
|
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES];
|
|
|
|
|
2022-06-21 00:08:33 +00:00
|
|
|
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd);
|
2021-06-26 10:49:25 +00:00
|
|
|
|
|
|
|
Vector<Color> clear_colors;
|
|
|
|
clear_colors.push_back(Color(0.0, 0.0, 0.0));
|
|
|
|
|
|
|
|
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->quarter_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
|
2021-07-26 11:31:15 +00:00
|
|
|
_render_sky(draw_list, p_time, sky->quarter_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, p_luminance_multiplier);
|
2021-06-26 10:49:25 +00:00
|
|
|
RD::get_singleton()->draw_list_end();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (shader_data->uses_half_res) {
|
|
|
|
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_HALF_RES_MULTIVIEW : SKY_VERSION_HALF_RES];
|
|
|
|
|
2022-06-21 00:08:33 +00:00
|
|
|
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd);
|
2021-06-26 10:49:25 +00:00
|
|
|
|
|
|
|
Vector<Color> clear_colors;
|
|
|
|
clear_colors.push_back(Color(0.0, 0.0, 0.0));
|
|
|
|
|
|
|
|
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->half_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
|
2021-07-26 11:31:15 +00:00
|
|
|
_render_sky(draw_list, p_time, sky->half_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, p_luminance_multiplier);
|
2021-06-26 10:49:25 +00:00
|
|
|
RD::get_singleton()->draw_list_end();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
void SkyRD::draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
|
2022-03-21 11:25:25 +00:00
|
|
|
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
|
2022-07-27 06:14:23 +00:00
|
|
|
ERR_FAIL_COND(p_env.is_null());
|
2021-06-26 10:49:25 +00:00
|
|
|
|
|
|
|
ERR_FAIL_COND(p_view_count == 0);
|
|
|
|
ERR_FAIL_COND(p_view_count > RendererSceneRender::MAX_RENDER_VIEWS);
|
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env));
|
2021-06-26 10:49:25 +00:00
|
|
|
|
|
|
|
SkyMaterialData *material = nullptr;
|
|
|
|
RID sky_material;
|
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
RS::EnvironmentBG background = RendererSceneRenderRD::get_singleton()->environment_get_background(p_env);
|
2021-06-26 10:49:25 +00:00
|
|
|
|
|
|
|
if (!(background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) || sky) {
|
|
|
|
ERR_FAIL_COND(!sky);
|
2022-07-27 06:14:23 +00:00
|
|
|
sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env));
|
2021-06-26 10:49:25 +00:00
|
|
|
|
|
|
|
if (sky_material.is_valid()) {
|
2022-04-05 10:40:26 +00:00
|
|
|
material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY));
|
2021-06-26 10:49:25 +00:00
|
|
|
if (!material || !material->shader_data->valid) {
|
|
|
|
material = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!material) {
|
|
|
|
sky_material = sky_shader.default_material;
|
2022-04-05 10:40:26 +00:00
|
|
|
material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY));
|
2021-06-26 10:49:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) {
|
|
|
|
sky_material = sky_scene_state.fog_material;
|
2022-04-05 10:40:26 +00:00
|
|
|
material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY));
|
2021-06-26 10:49:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ERR_FAIL_COND(!material);
|
|
|
|
|
|
|
|
SkyShaderData *shader_data = material->shader_data;
|
|
|
|
|
|
|
|
ERR_FAIL_COND(!shader_data);
|
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env);
|
2021-06-26 10:49:25 +00:00
|
|
|
sky_transform.invert();
|
|
|
|
|
2022-07-27 06:14:23 +00:00
|
|
|
float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env);
|
|
|
|
float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env);
|
2021-06-26 10:49:25 +00:00
|
|
|
|
|
|
|
// Camera
|
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
|
|
|
Projection camera;
|
2021-06-26 10:49:25 +00:00
|
|
|
uint32_t view_count = p_view_count;
|
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
|
|
|
const Projection *projections = p_projections;
|
2021-06-26 10:49:25 +00:00
|
|
|
|
|
|
|
if (custom_fov) {
|
|
|
|
// With custom fov we don't support stereo...
|
|
|
|
float near_plane = p_projections[0].get_z_near();
|
|
|
|
float far_plane = p_projections[0].get_z_far();
|
|
|
|
float aspect = p_projections[0].get_aspect();
|
|
|
|
|
|
|
|
camera.set_perspective(custom_fov, aspect, near_plane, far_plane);
|
|
|
|
|
|
|
|
view_count = 1;
|
|
|
|
projections = &camera;
|
|
|
|
}
|
|
|
|
|
|
|
|
sky_transform = p_transform.basis * sky_transform;
|
|
|
|
|
|
|
|
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_BACKGROUND_MULTIVIEW : SKY_VERSION_BACKGROUND];
|
|
|
|
|
|
|
|
RID texture_uniform_set;
|
|
|
|
if (sky) {
|
2022-06-21 00:08:33 +00:00
|
|
|
texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd);
|
2021-06-26 10:49:25 +00:00
|
|
|
} else {
|
|
|
|
texture_uniform_set = sky_scene_state.fog_only_texture_uniform_set;
|
|
|
|
}
|
|
|
|
|
2021-07-26 11:31:15 +00:00
|
|
|
_render_sky(p_draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, p_luminance_multiplier);
|
2021-06-26 10:49:25 +00:00
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::invalidate_sky(Sky *p_sky) {
|
2021-02-13 12:08:08 +00:00
|
|
|
if (!p_sky->dirty) {
|
|
|
|
p_sky->dirty = true;
|
|
|
|
p_sky->dirty_list = dirty_sky_list;
|
|
|
|
dirty_sky_list = p_sky;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::update_dirty_skys() {
|
2021-02-13 12:08:08 +00:00
|
|
|
Sky *sky = dirty_sky_list;
|
|
|
|
|
|
|
|
while (sky) {
|
|
|
|
bool texture_set_dirty = false;
|
|
|
|
//update sky configuration if texture is missing
|
|
|
|
|
|
|
|
if (sky->radiance.is_null()) {
|
|
|
|
int mipmaps = Image::get_image_required_mipmaps(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBAH) + 1;
|
|
|
|
|
|
|
|
uint32_t w = sky->radiance_size, h = sky->radiance_size;
|
|
|
|
int layers = roughness_layers;
|
|
|
|
if (sky->mode == RS::SKY_MODE_REALTIME) {
|
|
|
|
layers = 8;
|
|
|
|
if (roughness_layers != 8) {
|
|
|
|
WARN_PRINT("When using REALTIME skies, roughness_layers should be set to 8 in the project settings for best quality reflections");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sky_use_cubemap_array) {
|
|
|
|
//array (higher quality, 6 times more memory)
|
|
|
|
RD::TextureFormat tf;
|
|
|
|
tf.array_layers = layers * 6;
|
2021-07-27 13:33:47 +00:00
|
|
|
tf.format = texture_format;
|
2021-02-13 12:08:08 +00:00
|
|
|
tf.texture_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 | RD::TEXTURE_USAGE_STORAGE_BIT;
|
|
|
|
|
|
|
|
sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
|
|
|
|
2022-06-21 00:08:33 +00:00
|
|
|
sky->reflection.update_reflection_data(sky->radiance_size, mipmaps, true, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers, texture_format);
|
2021-02-13 12:08:08 +00:00
|
|
|
|
|
|
|
} else {
|
|
|
|
//regular cubemap, lower quality (aliasing, less memory)
|
|
|
|
RD::TextureFormat tf;
|
|
|
|
tf.array_layers = 6;
|
2021-07-27 13:33:47 +00:00
|
|
|
tf.format = texture_format;
|
2021-02-13 12:08:08 +00:00
|
|
|
tf.texture_type = RD::TEXTURE_TYPE_CUBE;
|
|
|
|
tf.mipmaps = MIN(mipmaps, layers);
|
|
|
|
tf.width = w;
|
|
|
|
tf.height = h;
|
|
|
|
tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
|
|
|
|
|
|
|
|
sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
|
|
|
|
2022-06-21 00:08:33 +00:00
|
|
|
sky->reflection.update_reflection_data(sky->radiance_size, MIN(mipmaps, layers), false, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers, texture_format);
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
texture_set_dirty = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create subpass buffers if they haven't been created already
|
|
|
|
if (sky->half_res_pass.is_null() && !RD::get_singleton()->texture_is_valid(sky->half_res_pass) && sky->screen_size.x >= 4 && sky->screen_size.y >= 4) {
|
|
|
|
RD::TextureFormat tformat;
|
2021-07-27 13:33:47 +00:00
|
|
|
tformat.format = texture_format;
|
2021-02-13 12:08:08 +00:00
|
|
|
tformat.width = sky->screen_size.x / 2;
|
|
|
|
tformat.height = sky->screen_size.y / 2;
|
|
|
|
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
|
|
|
|
tformat.texture_type = RD::TEXTURE_TYPE_2D;
|
|
|
|
|
|
|
|
sky->half_res_pass = RD::get_singleton()->texture_create(tformat, RD::TextureView());
|
|
|
|
Vector<RID> texs;
|
|
|
|
texs.push_back(sky->half_res_pass);
|
|
|
|
sky->half_res_framebuffer = RD::get_singleton()->framebuffer_create(texs);
|
|
|
|
texture_set_dirty = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sky->quarter_res_pass.is_null() && !RD::get_singleton()->texture_is_valid(sky->quarter_res_pass) && sky->screen_size.x >= 4 && sky->screen_size.y >= 4) {
|
|
|
|
RD::TextureFormat tformat;
|
2021-07-27 13:33:47 +00:00
|
|
|
tformat.format = texture_format;
|
2021-02-13 12:08:08 +00:00
|
|
|
tformat.width = sky->screen_size.x / 4;
|
|
|
|
tformat.height = sky->screen_size.y / 4;
|
|
|
|
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
|
|
|
|
tformat.texture_type = RD::TEXTURE_TYPE_2D;
|
|
|
|
|
|
|
|
sky->quarter_res_pass = RD::get_singleton()->texture_create(tformat, RD::TextureView());
|
|
|
|
Vector<RID> texs;
|
|
|
|
texs.push_back(sky->quarter_res_pass);
|
|
|
|
sky->quarter_res_framebuffer = RD::get_singleton()->framebuffer_create(texs);
|
|
|
|
texture_set_dirty = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (texture_set_dirty) {
|
|
|
|
for (int i = 0; i < SKY_TEXTURE_SET_MAX; i++) {
|
|
|
|
if (sky->texture_uniform_sets[i].is_valid() && RD::get_singleton()->uniform_set_is_valid(sky->texture_uniform_sets[i])) {
|
|
|
|
RD::get_singleton()->free(sky->texture_uniform_sets[i]);
|
|
|
|
sky->texture_uniform_sets[i] = RID();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sky->reflection.dirty = true;
|
|
|
|
sky->processing_layer = 0;
|
|
|
|
|
|
|
|
Sky *next = sky->dirty_list;
|
|
|
|
sky->dirty_list = nullptr;
|
|
|
|
sky->dirty = false;
|
|
|
|
sky = next;
|
|
|
|
}
|
|
|
|
|
|
|
|
dirty_sky_list = nullptr;
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
RID SkyRD::sky_get_material(RID p_sky) const {
|
2021-02-13 12:08:08 +00:00
|
|
|
Sky *sky = get_sky(p_sky);
|
|
|
|
ERR_FAIL_COND_V(!sky, RID());
|
|
|
|
|
|
|
|
return sky->material;
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
RID SkyRD::allocate_sky_rid() {
|
2021-02-13 12:08:08 +00:00
|
|
|
return sky_owner.allocate_rid();
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::initialize_sky_rid(RID p_rid) {
|
2021-02-13 12:08:08 +00:00
|
|
|
sky_owner.initialize_rid(p_rid, Sky());
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
SkyRD::Sky *SkyRD::get_sky(RID p_sky) const {
|
2021-09-29 17:08:41 +00:00
|
|
|
return sky_owner.get_or_null(p_sky);
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::free_sky(RID p_sky) {
|
2021-02-13 12:08:08 +00:00
|
|
|
Sky *sky = get_sky(p_sky);
|
|
|
|
ERR_FAIL_COND(!sky);
|
|
|
|
|
2022-06-21 00:08:33 +00:00
|
|
|
sky->free();
|
2021-02-13 12:08:08 +00:00
|
|
|
sky_owner.free(p_sky);
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) {
|
2021-02-13 12:08:08 +00:00
|
|
|
Sky *sky = get_sky(p_sky);
|
|
|
|
ERR_FAIL_COND(!sky);
|
|
|
|
|
|
|
|
if (sky->set_radiance_size(p_radiance_size)) {
|
|
|
|
invalidate_sky(sky);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::sky_set_mode(RID p_sky, RS::SkyMode p_mode) {
|
2021-02-13 12:08:08 +00:00
|
|
|
Sky *sky = get_sky(p_sky);
|
|
|
|
ERR_FAIL_COND(!sky);
|
|
|
|
|
|
|
|
if (sky->set_mode(p_mode)) {
|
|
|
|
invalidate_sky(sky);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
void SkyRD::sky_set_material(RID p_sky, RID p_material) {
|
2021-02-13 12:08:08 +00:00
|
|
|
Sky *sky = get_sky(p_sky);
|
|
|
|
ERR_FAIL_COND(!sky);
|
|
|
|
|
|
|
|
if (sky->set_material(p_material)) {
|
|
|
|
invalidate_sky(sky);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
Ref<Image> SkyRD::sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) {
|
2021-02-13 12:08:08 +00:00
|
|
|
Sky *sky = get_sky(p_sky);
|
|
|
|
ERR_FAIL_COND_V(!sky, Ref<Image>());
|
|
|
|
|
|
|
|
update_dirty_skys();
|
|
|
|
|
2022-04-29 07:10:54 +00:00
|
|
|
return sky->bake_panorama(p_energy, p_bake_irradiance ? roughness_layers : 0, p_size);
|
2021-02-13 12:08:08 +00:00
|
|
|
}
|
|
|
|
|
2022-07-19 04:17:58 +00:00
|
|
|
RID SkyRD::sky_get_radiance_texture_rd(RID p_sky) const {
|
2021-02-13 12:08:08 +00:00
|
|
|
Sky *sky = get_sky(p_sky);
|
|
|
|
ERR_FAIL_COND_V(!sky, RID());
|
|
|
|
|
|
|
|
return sky->radiance;
|
|
|
|
}
|