summaryrefslogtreecommitdiffstats
path: root/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h')
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h585
1 files changed, 585 insertions, 0 deletions
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h
new file mode 100644
index 0000000000..4c3422cedb
--- /dev/null
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h
@@ -0,0 +1,585 @@
+/*************************************************************************/
+/* rasterizer_scene_high_end_rd.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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. */
+/*************************************************************************/
+
+#ifndef RASTERIZER_SCENE_HIGHEND_RD_H
+#define RASTERIZER_SCENE_HIGHEND_RD_H
+
+#include "servers/rendering/rasterizer_rd/light_cluster_builder.h"
+#include "servers/rendering/rasterizer_rd/rasterizer_scene_rd.h"
+#include "servers/rendering/rasterizer_rd/rasterizer_storage_rd.h"
+#include "servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h"
+#include "servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl.gen.h"
+
+class RasterizerSceneHighEndRD : public RasterizerSceneRD {
+
+ enum {
+ SCENE_UNIFORM_SET = 0,
+ RADIANCE_UNIFORM_SET = 1,
+ VIEW_DEPENDANT_UNIFORM_SET = 2,
+ RENDER_BUFFERS_UNIFORM_SET = 3,
+ TRANSFORMS_UNIFORM_SET = 4,
+ MATERIAL_UNIFORM_SET = 5
+ };
+
+ /* Scene Shader */
+
+ enum ShaderVersion {
+ SHADER_VERSION_DEPTH_PASS,
+ SHADER_VERSION_DEPTH_PASS_DP,
+ SHADER_VERSION_DEPTH_PASS_WITH_NORMAL,
+ SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS,
+ SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL,
+ SHADER_VERSION_COLOR_PASS,
+ SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR,
+ SHADER_VERSION_VCT_COLOR_PASS,
+ SHADER_VERSION_VCT_COLOR_PASS_WITH_SEPARATE_SPECULAR,
+ SHADER_VERSION_LIGHTMAP_COLOR_PASS,
+ SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR,
+ SHADER_VERSION_MAX
+ };
+
+ struct {
+ SceneHighEndShaderRD scene_shader;
+ ShaderCompilerRD compiler;
+ } shader;
+
+ RasterizerStorageRD *storage;
+
+ /* Material */
+
+ struct ShaderData : public RasterizerStorageRD::ShaderData {
+
+ enum BlendMode { //used internally
+ BLEND_MODE_MIX,
+ BLEND_MODE_ADD,
+ BLEND_MODE_SUB,
+ BLEND_MODE_MUL,
+ };
+
+ enum DepthDraw {
+ DEPTH_DRAW_DISABLED,
+ DEPTH_DRAW_OPAQUE,
+ DEPTH_DRAW_ALWAYS
+ };
+
+ enum DepthTest {
+ DEPTH_TEST_DISABLED,
+ DEPTH_TEST_ENABLED
+ };
+
+ enum Cull {
+ CULL_DISABLED,
+ CULL_FRONT,
+ CULL_BACK
+ };
+
+ enum CullVariant {
+ CULL_VARIANT_NORMAL,
+ CULL_VARIANT_REVERSED,
+ CULL_VARIANT_DOUBLE_SIDED,
+ CULL_VARIANT_MAX
+
+ };
+
+ bool valid;
+ RID version;
+ uint32_t vertex_input_mask;
+ RenderPipelineVertexFormatCacheRD pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][SHADER_VERSION_MAX];
+
+ String path;
+
+ Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
+ Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
+
+ Vector<uint32_t> ubo_offsets;
+ uint32_t ubo_size;
+
+ String code;
+ Map<StringName, RID> default_texture_params;
+
+ DepthDraw depth_draw;
+ DepthTest depth_test;
+
+ bool uses_point_size;
+ bool uses_alpha;
+ bool uses_blend_alpha;
+ bool uses_depth_pre_pass;
+ bool uses_discard;
+ bool uses_roughness;
+ bool uses_normal;
+
+ bool unshaded;
+ bool uses_vertex;
+ bool uses_sss;
+ bool uses_screen_texture;
+ bool uses_depth_texture;
+ bool uses_normal_texture;
+ bool uses_time;
+ bool writes_modelview_or_projection;
+ bool uses_world_coordinates;
+
+ uint64_t last_pass = 0;
+ uint32_t index = 0;
+
+ virtual void set_code(const String &p_Code);
+ virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
+ virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
+ virtual bool is_param_texture(const StringName &p_param) const;
+ virtual bool is_animated() const;
+ virtual bool casts_shadows() const;
+ virtual Variant get_default_parameter(const StringName &p_parameter) const;
+ ShaderData();
+ virtual ~ShaderData();
+ };
+
+ RasterizerStorageRD::ShaderData *_create_shader_func();
+ static RasterizerStorageRD::ShaderData *_create_shader_funcs() {
+ return static_cast<RasterizerSceneHighEndRD *>(singleton)->_create_shader_func();
+ }
+
+ struct MaterialData : public RasterizerStorageRD::MaterialData {
+ uint64_t last_frame;
+ ShaderData *shader_data;
+ RID uniform_buffer;
+ RID uniform_set;
+ Vector<RID> texture_cache;
+ Vector<uint8_t> ubo_data;
+ uint64_t last_pass = 0;
+ uint32_t index = 0;
+ RID next_pass;
+ uint8_t priority;
+ virtual void set_render_priority(int p_priority);
+ virtual void set_next_pass(RID p_pass);
+ virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
+ virtual ~MaterialData();
+ };
+
+ RasterizerStorageRD::MaterialData *_create_material_func(ShaderData *p_shader);
+ static RasterizerStorageRD::MaterialData *_create_material_funcs(RasterizerStorageRD::ShaderData *p_shader) {
+ return static_cast<RasterizerSceneHighEndRD *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader));
+ }
+
+ /* Push Constant */
+
+ struct PushConstant {
+ uint32_t index;
+ uint32_t pad[3];
+ };
+
+ /* Framebuffer */
+
+ struct RenderBufferDataHighEnd : public RenderBufferData {
+ //for rendering, may be MSAAd
+ RID color;
+ RID depth;
+ RID specular;
+ RID normal_buffer;
+ RID roughness_buffer;
+ RID depth_fb;
+ RID depth_normal_fb;
+ RID depth_normal_roughness_fb;
+ RID color_fb;
+ RID color_specular_fb;
+ int width, height;
+
+ void ensure_specular();
+ void clear();
+ virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa);
+
+ RID uniform_set;
+
+ ~RenderBufferDataHighEnd();
+ };
+
+ virtual RenderBufferData *_create_render_buffer_data();
+ void _allocate_normal_texture(RenderBufferDataHighEnd *rb);
+ void _allocate_roughness_texture(RenderBufferDataHighEnd *rb);
+
+ RID shadow_sampler;
+ RID render_base_uniform_set;
+ RID view_dependant_uniform_set;
+
+ virtual void _base_uniforms_changed();
+ void _render_buffers_clear_uniform_set(RenderBufferDataHighEnd *rb);
+ virtual void _render_buffers_uniform_set_changed(RID p_render_buffers);
+ virtual RID _render_buffers_get_roughness_texture(RID p_render_buffers);
+ virtual RID _render_buffers_get_normal_texture(RID p_render_buffers);
+
+ void _update_render_base_uniform_set();
+ void _setup_view_dependant_uniform_set(RID p_shadow_atlas, RID p_reflection_atlas);
+ void _update_render_buffers_uniform_set(RID p_render_buffers);
+
+ /* Scene State UBO */
+
+ struct ReflectionData { //should always be 128 bytes
+ float box_extents[3];
+ float index;
+ float box_offset[3];
+ uint32_t mask;
+ float params[4]; // intensity, 0, interior , boxproject
+ float ambient[4]; // ambient color, energy
+ float local_matrix[16]; // up to here for spot and omni, rest is for directional
+ };
+
+ struct LightData {
+ float position[3];
+ float inv_radius;
+ float direction[3];
+ uint16_t attenuation_energy[2]; //16 bits attenuation, then energy
+ uint8_t color_specular[4]; //rgb color, a specular (8 bit unorm)
+ uint16_t cone_attenuation_angle[2]; // attenuation and angle, (16bit float)
+ uint32_t mask;
+ uint8_t shadow_color_enabled[4]; //shadow rgb color, a>0.5 enabled (8bit unorm)
+ float atlas_rect[4]; // in omni, used for atlas uv, in spot, used for projector uv
+ float shadow_matrix[16];
+ };
+
+ struct DirectionalLightData {
+
+ float direction[3];
+ float energy;
+ float color[3];
+ float specular;
+ float shadow_color[3];
+ uint32_t mask;
+ uint32_t blend_splits;
+ uint32_t shadow_enabled;
+ float fade_from;
+ float fade_to;
+ float shadow_split_offsets[4];
+ float shadow_matrices[4][16];
+ };
+
+ struct GIProbeData {
+ float xform[16];
+ float bounds[3];
+ float dynamic_range;
+
+ float bias;
+ float normal_bias;
+ uint32_t blend_ambient;
+ uint32_t texture_slot;
+
+ float anisotropy_strength;
+ float ao;
+ float ao_size;
+ uint32_t pad[1];
+ };
+
+ enum {
+ INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12,
+ INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13,
+ INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14,
+ INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA = 1 << 15,
+ INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT = 16,
+ INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_MASK = 0x7,
+ INSTANCE_DATA_FLAG_SKELETON = 1 << 19,
+ };
+
+ struct InstanceData {
+ float transform[16];
+ float normal_transform[16];
+ uint32_t flags;
+ uint32_t instance_ofs; //instance_offset in instancing/skeleton buffer
+ uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap)
+ uint32_t mask;
+ };
+
+ struct SceneState {
+ struct UBO {
+ float projection_matrix[16];
+ float inv_projection_matrix[16];
+
+ float camera_matrix[16];
+ float inv_camera_matrix[16];
+
+ float viewport_size[2];
+ float screen_pixel_size[2];
+
+ float shadow_z_offset;
+ float shadow_z_slope_scale;
+
+ float time;
+ float reflection_multiplier;
+
+ float ambient_light_color_energy[4];
+
+ float ambient_color_sky_mix;
+ uint32_t use_ambient_light;
+ uint32_t use_ambient_cubemap;
+ uint32_t use_reflection_cubemap;
+
+ float radiance_inverse_xform[12];
+
+ float shadow_atlas_pixel_size[2];
+ float directional_shadow_pixel_size[2];
+
+ uint32_t directional_light_count;
+ float dual_paraboloid_side;
+ float z_far;
+ float z_near;
+
+ uint32_t ssao_enabled;
+ float ssao_light_affect;
+ float ssao_ao_affect;
+ uint32_t roughness_limiter_enabled;
+
+ float ao_color[4];
+ };
+
+ UBO ubo;
+
+ RID uniform_buffer;
+
+ ReflectionData *reflections;
+ uint32_t max_reflections;
+ RID reflection_buffer;
+ uint32_t max_reflection_probes_per_instance;
+
+ GIProbeData *gi_probes;
+ uint32_t max_gi_probes;
+ RID gi_probe_buffer;
+ uint32_t max_gi_probe_probes_per_instance;
+
+ LightData *lights;
+ uint32_t max_lights;
+ RID light_buffer;
+
+ DirectionalLightData *directional_lights;
+ uint32_t max_directional_lights;
+ RID directional_light_buffer;
+
+ RID instance_buffer;
+ InstanceData *instances;
+ uint32_t max_instances;
+
+ bool used_screen_texture = false;
+ bool used_normal_texture = false;
+ bool used_depth_texture = false;
+ bool used_sss = false;
+ uint32_t current_shader_index = 0;
+ uint32_t current_material_index = 0;
+ } scene_state;
+
+ /* Render List */
+
+ struct RenderList {
+
+ int max_elements;
+
+ struct Element {
+ RasterizerScene::InstanceBase *instance;
+ MaterialData *material;
+ union {
+ struct {
+ //from least significant to most significant in sort, TODO: should be endian swapped on big endian
+ uint64_t geometry_index : 20;
+ uint64_t material_index : 15;
+ uint64_t shader_index : 12;
+ uint64_t uses_instancing : 1;
+ uint64_t uses_vct : 1;
+ uint64_t uses_lightmap : 1;
+ uint64_t depth_layer : 4;
+ uint64_t priority : 8;
+ };
+
+ uint64_t sort_key;
+ };
+ uint32_t surface_index;
+ };
+
+ Element *base_elements;
+ Element **elements;
+
+ int element_count;
+ int alpha_element_count;
+
+ void clear() {
+
+ element_count = 0;
+ alpha_element_count = 0;
+ }
+
+ //should eventually be replaced by radix
+
+ struct SortByKey {
+
+ _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
+ return A->sort_key < B->sort_key;
+ }
+ };
+
+ void sort_by_key(bool p_alpha) {
+
+ SortArray<Element *, SortByKey> sorter;
+ if (p_alpha) {
+ sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
+ } else {
+ sorter.sort(elements, element_count);
+ }
+ }
+
+ struct SortByDepth {
+
+ _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
+ return A->instance->depth < B->instance->depth;
+ }
+ };
+
+ void sort_by_depth(bool p_alpha) { //used for shadows
+
+ SortArray<Element *, SortByDepth> sorter;
+ if (p_alpha) {
+ sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
+ } else {
+ sorter.sort(elements, element_count);
+ }
+ }
+
+ struct SortByReverseDepthAndPriority {
+
+ _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
+ uint32_t layer_A = uint32_t(A->priority);
+ uint32_t layer_B = uint32_t(B->priority);
+ if (layer_A == layer_B) {
+ return A->instance->depth > B->instance->depth;
+ } else {
+ return layer_A < layer_B;
+ }
+ }
+ };
+
+ void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha
+
+ SortArray<Element *, SortByReverseDepthAndPriority> sorter;
+ if (p_alpha) {
+ sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
+ } else {
+ sorter.sort(elements, element_count);
+ }
+ }
+
+ _FORCE_INLINE_ Element *add_element() {
+
+ if (element_count + alpha_element_count >= max_elements)
+ return NULL;
+ elements[element_count] = &base_elements[element_count];
+ return elements[element_count++];
+ }
+
+ _FORCE_INLINE_ Element *add_alpha_element() {
+
+ if (element_count + alpha_element_count >= max_elements)
+ return NULL;
+ int idx = max_elements - alpha_element_count - 1;
+ elements[idx] = &base_elements[idx];
+ alpha_element_count++;
+ return elements[idx];
+ }
+
+ void init() {
+
+ element_count = 0;
+ alpha_element_count = 0;
+ elements = memnew_arr(Element *, max_elements);
+ base_elements = memnew_arr(Element, max_elements);
+ for (int i = 0; i < max_elements; i++)
+ elements[i] = &base_elements[i]; // assign elements
+ }
+
+ RenderList() {
+
+ max_elements = 0;
+ }
+
+ ~RenderList() {
+ memdelete_arr(elements);
+ memdelete_arr(base_elements);
+ }
+ };
+
+ RenderList render_list;
+
+ static RasterizerSceneHighEndRD *singleton;
+ uint64_t render_pass;
+ double time;
+ RID default_shader;
+ RID default_material;
+ RID overdraw_material_shader;
+ RID overdraw_material;
+ RID wireframe_material_shader;
+ RID wireframe_material;
+ RID default_shader_rd;
+ RID default_radiance_uniform_set;
+ RID default_render_buffers_uniform_set;
+
+ RID default_vec4_xform_buffer;
+ RID default_vec4_xform_uniform_set;
+
+ LightClusterBuilder cluster_builder;
+
+ enum PassMode {
+ PASS_MODE_COLOR,
+ PASS_MODE_COLOR_SPECULAR,
+ PASS_MODE_COLOR_TRANSPARENT,
+ PASS_MODE_SHADOW,
+ PASS_MODE_SHADOW_DP,
+ PASS_MODE_DEPTH,
+ PASS_MODE_DEPTH_NORMAL,
+ PASS_MODE_DEPTH_NORMAL_ROUGHNESS,
+ PASS_MODE_DEPTH_MATERIAL,
+ };
+
+ void _setup_environment(RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false);
+ void _setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows);
+ void _setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, RID p_environment);
+ void _setup_gi_probes(RID *p_gi_probe_probe_cull_result, int p_gi_probe_probe_cull_count, const Transform &p_camera_transform);
+
+ void _fill_instances(RenderList::Element **p_elements, int p_element_count, bool p_for_depth);
+ void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_radiance_uniform_set, RID p_render_buffers_uniform_set);
+ _FORCE_INLINE_ void _add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index);
+ _FORCE_INLINE_ void _add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index);
+
+ void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, PassMode p_pass_mode, bool p_no_gi);
+
+protected:
+ virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color);
+ virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip);
+ virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region);
+
+public:
+ virtual void set_time(double p_time, double p_step);
+
+ virtual bool free(RID p_rid);
+
+ RasterizerSceneHighEndRD(RasterizerStorageRD *p_storage);
+ ~RasterizerSceneHighEndRD();
+};
+#endif // RASTERIZER_SCENE_HIGHEND_RD_H