feat: updated engine version to 4.4-rc1
This commit is contained in:
parent
ee00efde1f
commit
21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions
|
|
@ -1,4 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
from misc.utility.scons_hints import *
|
||||
|
||||
Import("env")
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -34,15 +34,16 @@
|
|||
#include "core/templates/paged_allocator.h"
|
||||
#include "servers/rendering/renderer_rd/cluster_builder_rd.h"
|
||||
#include "servers/rendering/renderer_rd/effects/fsr2.h"
|
||||
#ifdef METAL_ENABLED
|
||||
#include "servers/rendering/renderer_rd/effects/metal_fx.h"
|
||||
#endif
|
||||
#include "servers/rendering/renderer_rd/effects/motion_vectors_store.h"
|
||||
#include "servers/rendering/renderer_rd/effects/resolve.h"
|
||||
#include "servers/rendering/renderer_rd/effects/ss_effects.h"
|
||||
#include "servers/rendering/renderer_rd/effects/taa.h"
|
||||
#include "servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h"
|
||||
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
|
||||
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
|
||||
#include "servers/rendering/renderer_rd/shaders/forward_clustered/best_fit_normal.glsl.gen.h"
|
||||
#include "servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl.gen.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/utilities.h"
|
||||
|
||||
#define RB_SCOPE_FORWARD_CLUSTERED SNAME("forward_clustered")
|
||||
|
||||
|
|
@ -65,16 +66,6 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
MATERIAL_UNIFORM_SET = 3,
|
||||
};
|
||||
|
||||
enum {
|
||||
SPEC_CONSTANT_SOFT_SHADOW_SAMPLES = 6,
|
||||
SPEC_CONSTANT_PENUMBRA_SHADOW_SAMPLES = 7,
|
||||
SPEC_CONSTANT_DIRECTIONAL_SOFT_SHADOW_SAMPLES = 8,
|
||||
SPEC_CONSTANT_DIRECTIONAL_PENUMBRA_SHADOW_SAMPLES = 9,
|
||||
SPEC_CONSTANT_DECAL_FILTER = 10,
|
||||
SPEC_CONSTANT_PROJECTOR_FILTER = 11,
|
||||
SPEC_CONSTANT_USE_DEPTH_FOG = 12,
|
||||
};
|
||||
|
||||
enum {
|
||||
SDFGI_MAX_CASCADES = 8,
|
||||
MAX_VOXEL_GI_INSTANCESS = 8,
|
||||
|
|
@ -95,6 +86,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
|
||||
SceneShaderForwardClustered scene_shader;
|
||||
|
||||
public:
|
||||
/* Framebuffer */
|
||||
|
||||
class RenderBufferDataForwardClustered : public RenderBufferCustomDataRD {
|
||||
|
|
@ -103,6 +95,9 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
private:
|
||||
RenderSceneBuffersRD *render_buffers = nullptr;
|
||||
RendererRD::FSR2Context *fsr2_context = nullptr;
|
||||
#ifdef METAL_ENABLED
|
||||
RendererRD::MFXTemporalContext *mfx_temporal_context = nullptr;
|
||||
#endif
|
||||
|
||||
public:
|
||||
ClusterBuilderRD *cluster_builder = nullptr;
|
||||
|
|
@ -146,6 +141,11 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
void ensure_fsr2(RendererRD::FSR2Effect *p_effect);
|
||||
RendererRD::FSR2Context *get_fsr2_context() const { return fsr2_context; }
|
||||
|
||||
#ifdef METAL_ENABLED
|
||||
bool ensure_mfx_temporal(RendererRD::MFXTemporalEffect *p_effect);
|
||||
RendererRD::MFXTemporalContext *get_mfx_temporal_context() const { return mfx_temporal_context; }
|
||||
#endif
|
||||
|
||||
RID get_color_only_fb();
|
||||
RID get_color_pass_fb(uint32_t p_color_pass_flags);
|
||||
RID get_depth_fb(DepthFrameBufferType p_type = DEPTH_FB);
|
||||
|
|
@ -154,8 +154,16 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
|
||||
virtual void configure(RenderSceneBuffersRD *p_render_buffers) override;
|
||||
virtual void free_data() override;
|
||||
|
||||
static RD::DataFormat get_specular_format();
|
||||
static uint32_t get_specular_usage_bits(bool p_resolve, bool p_msaa, bool p_storage);
|
||||
static RD::DataFormat get_normal_roughness_format();
|
||||
static uint32_t get_normal_roughness_usage_bits(bool p_resolve, bool p_msaa, bool p_storage);
|
||||
static RD::DataFormat get_voxelgi_format();
|
||||
static uint32_t get_voxelgi_usage_bits(bool p_resolve, bool p_msaa, bool p_storage);
|
||||
};
|
||||
|
||||
private:
|
||||
virtual void setup_render_buffer_data(Ref<RenderSceneBuffersRD> p_render_buffers) override;
|
||||
|
||||
RID render_base_uniform_set;
|
||||
|
|
@ -182,6 +190,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI,
|
||||
PASS_MODE_DEPTH_MATERIAL,
|
||||
PASS_MODE_SDF,
|
||||
PASS_MODE_MAX
|
||||
};
|
||||
|
||||
enum ColorPassFlags {
|
||||
|
|
@ -211,9 +220,9 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
RD::FramebufferFormatID framebuffer_format = 0;
|
||||
uint32_t element_offset = 0;
|
||||
bool use_directional_soft_shadow = false;
|
||||
uint32_t spec_constant_base_flags = 0;
|
||||
SceneShaderForwardClustered::ShaderSpecialization base_specialization = {};
|
||||
|
||||
RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, uint32_t p_color_pass_flags, bool p_no_gi, bool p_use_directional_soft_shadows, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_spec_constant_base_flags = 0) {
|
||||
RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, uint32_t p_color_pass_flags, bool p_no_gi, bool p_use_directional_soft_shadows, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, SceneShaderForwardClustered::ShaderSpecialization p_base_specialization = {}) {
|
||||
elements = p_elements;
|
||||
element_info = p_element_info;
|
||||
element_count = p_element_count;
|
||||
|
|
@ -229,14 +238,15 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
screen_mesh_lod_threshold = p_screen_mesh_lod_threshold;
|
||||
element_offset = p_element_offset;
|
||||
use_directional_soft_shadow = p_use_directional_soft_shadows;
|
||||
spec_constant_base_flags = p_spec_constant_base_flags;
|
||||
base_specialization = p_base_specialization;
|
||||
}
|
||||
};
|
||||
|
||||
struct LightmapData {
|
||||
float normal_xform[12];
|
||||
float pad[3];
|
||||
float texture_size[2];
|
||||
float exposure_normalization;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct LightmapCaptureData {
|
||||
|
|
@ -245,6 +255,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
|
||||
// When changing any of these enums, remember to change the corresponding enums in the shader files as well.
|
||||
enum {
|
||||
INSTANCE_DATA_FLAG_MULTIMESH_INDIRECT = 1 << 2,
|
||||
INSTANCE_DATA_FLAGS_DYNAMIC = 1 << 3,
|
||||
INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 4,
|
||||
INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 5,
|
||||
|
|
@ -291,11 +302,17 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
uint32_t volumetric_fog_pad;
|
||||
};
|
||||
|
||||
struct PushConstantUbershader {
|
||||
SceneShaderForwardClustered::ShaderSpecialization specialization;
|
||||
SceneShaderForwardClustered::UbershaderConstants constants;
|
||||
};
|
||||
|
||||
struct PushConstant {
|
||||
uint32_t base_index; //
|
||||
uint32_t uv_offset; //packed
|
||||
uint32_t multimesh_motion_vectors_current_offset;
|
||||
uint32_t multimesh_motion_vectors_previous_offset;
|
||||
PushConstantUbershader ubershader;
|
||||
};
|
||||
|
||||
struct InstanceData {
|
||||
|
|
@ -343,7 +360,6 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
struct ShadowPass {
|
||||
uint32_t element_from;
|
||||
uint32_t element_count;
|
||||
bool flip_cull;
|
||||
PassMode pass_mode;
|
||||
|
||||
RID rp_uniform_set;
|
||||
|
|
@ -351,8 +367,9 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
float screen_mesh_lod_threshold;
|
||||
|
||||
RID framebuffer;
|
||||
RD::InitialAction initial_depth_action;
|
||||
Rect2i rect;
|
||||
bool clear_depth;
|
||||
bool flip_cull;
|
||||
};
|
||||
|
||||
LocalVector<ShadowPass> shadow_passes;
|
||||
|
|
@ -378,7 +395,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
template <PassMode p_pass_mode, uint32_t p_color_pass_flags = 0>
|
||||
_FORCE_INLINE_ void _render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element);
|
||||
void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element);
|
||||
void _render_list_with_draw_list(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 0.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2());
|
||||
void _render_list_with_draw_list(RenderListParameters *p_params, RID p_framebuffer, BitField<RD::DrawFlags> p_draw_flags = RD::DRAW_DEFAULT_ALL, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth_value = 0.0, uint32_t p_clear_stencil_value = 0, const Rect2 &p_region = Rect2());
|
||||
|
||||
void _update_instance_data_buffer(RenderListType p_render_list);
|
||||
void _fill_instance_data(RenderListType p_render_list, int *p_render_info = nullptr, uint32_t p_offset = 0, int32_t p_max_elements = -1, bool p_update_buffer = true);
|
||||
|
|
@ -411,6 +428,10 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
};
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint64_t sort_key1;
|
||||
uint64_t sort_key2;
|
||||
};
|
||||
struct {
|
||||
uint64_t lod_index : 8;
|
||||
uint64_t surface_index : 8;
|
||||
|
|
@ -426,10 +447,6 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
uint64_t depth_layer : 4;
|
||||
uint64_t priority : 8;
|
||||
};
|
||||
struct {
|
||||
uint64_t sort_key1;
|
||||
uint64_t sort_key2;
|
||||
};
|
||||
} sort;
|
||||
|
||||
RS::PrimitiveType primitive = RS::PRIMITIVE_MAX;
|
||||
|
|
@ -448,6 +465,11 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
|
||||
GeometryInstanceSurfaceDataCache *next = nullptr;
|
||||
GeometryInstanceForwardClustered *owner = nullptr;
|
||||
SelfList<GeometryInstanceSurfaceDataCache> compilation_dirty_element;
|
||||
SelfList<GeometryInstanceSurfaceDataCache> compilation_all_element;
|
||||
|
||||
GeometryInstanceSurfaceDataCache() :
|
||||
compilation_dirty_element(this), compilation_all_element(this) {}
|
||||
};
|
||||
|
||||
class GeometryInstanceForwardClustered : public RenderGeometryInstanceBase {
|
||||
|
|
@ -498,16 +520,63 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
static void _geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker);
|
||||
|
||||
SelfList<GeometryInstanceForwardClustered>::List geometry_instance_dirty_list;
|
||||
SelfList<GeometryInstanceSurfaceDataCache>::List geometry_surface_compilation_dirty_list;
|
||||
SelfList<GeometryInstanceSurfaceDataCache>::List geometry_surface_compilation_all_list;
|
||||
|
||||
PagedAllocator<GeometryInstanceForwardClustered> geometry_instance_alloc;
|
||||
PagedAllocator<GeometryInstanceSurfaceDataCache> geometry_instance_surface_alloc;
|
||||
PagedAllocator<GeometryInstanceLightmapSH> geometry_instance_lightmap_sh;
|
||||
|
||||
struct SurfacePipelineData {
|
||||
void *mesh_surface = nullptr;
|
||||
void *mesh_surface_shadow = nullptr;
|
||||
SceneShaderForwardClustered::ShaderData *shader = nullptr;
|
||||
SceneShaderForwardClustered::ShaderData *shader_shadow = nullptr;
|
||||
bool instanced = false;
|
||||
bool uses_opaque = false;
|
||||
bool uses_transparent = false;
|
||||
bool uses_depth = false;
|
||||
bool can_use_lightmap = false;
|
||||
};
|
||||
|
||||
struct GlobalPipelineData {
|
||||
union {
|
||||
uint32_t key;
|
||||
|
||||
struct {
|
||||
uint32_t texture_samples : 3;
|
||||
uint32_t use_reflection_probes : 1;
|
||||
uint32_t use_separate_specular : 1;
|
||||
uint32_t use_motion_vectors : 1;
|
||||
uint32_t use_normal_and_roughness : 1;
|
||||
uint32_t use_lightmaps : 1;
|
||||
uint32_t use_voxelgi : 1;
|
||||
uint32_t use_sdfgi : 1;
|
||||
uint32_t use_multiview : 1;
|
||||
uint32_t use_16_bit_shadows : 1;
|
||||
uint32_t use_32_bit_shadows : 1;
|
||||
uint32_t use_shadow_cubemaps : 1;
|
||||
uint32_t use_shadow_dual_paraboloid : 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
GlobalPipelineData global_pipeline_data_compiled = {};
|
||||
GlobalPipelineData global_pipeline_data_required = {};
|
||||
|
||||
typedef Pair<SceneShaderForwardClustered::ShaderData *, SceneShaderForwardClustered::ShaderData::PipelineKey> ShaderPipelinePair;
|
||||
|
||||
void _update_global_pipeline_data_requirements_from_project();
|
||||
void _update_global_pipeline_data_requirements_from_light_storage();
|
||||
void _geometry_instance_add_surface_with_material(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh);
|
||||
void _geometry_instance_add_surface_with_material_chain(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, RID p_mat_src, RID p_mesh);
|
||||
void _geometry_instance_add_surface(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, RID p_material, RID p_mesh);
|
||||
void _geometry_instance_update(RenderGeometryInstance *p_geometry_instance);
|
||||
void _mesh_compile_pipeline_for_surface(SceneShaderForwardClustered::ShaderData *p_shader, void *p_mesh_surface, bool p_ubershader, bool p_instanced_surface, RS::PipelineSource p_source, SceneShaderForwardClustered::ShaderData::PipelineKey &r_pipeline_key, Vector<ShaderPipelinePair> *r_pipeline_pairs = nullptr);
|
||||
void _mesh_compile_pipelines_for_surface(const SurfacePipelineData &p_surface, const GlobalPipelineData &p_global, RS::PipelineSource p_source, Vector<ShaderPipelinePair> *r_pipeline_pairs = nullptr);
|
||||
void _mesh_generate_all_pipelines_for_surface_cache(GeometryInstanceSurfaceDataCache *p_surface_cache, const GlobalPipelineData &p_global);
|
||||
void _update_dirty_geometry_instances();
|
||||
void _update_dirty_geometry_pipelines();
|
||||
|
||||
/* Render List */
|
||||
|
||||
|
|
@ -578,6 +647,11 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
RendererRD::FSR2Effect *fsr2_effect = nullptr;
|
||||
RendererRD::SSEffects *ss_effects = nullptr;
|
||||
|
||||
#ifdef METAL_ENABLED
|
||||
RendererRD::MFXTemporalEffect *mfx_temporal_effect = nullptr;
|
||||
#endif
|
||||
RendererRD::MotionVectorsStore *motion_vectors_store = nullptr;
|
||||
|
||||
/* Cluster builder */
|
||||
|
||||
ClusterBuilderSharedDataRD cluster_builder_shared;
|
||||
|
|
@ -661,8 +735,15 @@ public:
|
|||
|
||||
virtual uint32_t geometry_instance_get_pair_mask() override;
|
||||
|
||||
/* PIPELINES */
|
||||
|
||||
virtual void mesh_generate_pipelines(RID p_mesh, bool p_background_compilation) override;
|
||||
virtual uint32_t get_pipeline_compilations(RS::PipelineSource p_source) override;
|
||||
|
||||
virtual bool free(RID p_rid) override;
|
||||
|
||||
virtual void update() override;
|
||||
|
||||
RenderForwardClustered();
|
||||
~RenderForwardClustered();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -41,9 +41,9 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
|
|||
//compile
|
||||
|
||||
code = p_code;
|
||||
valid = false;
|
||||
ubo_size = 0;
|
||||
uniforms.clear();
|
||||
_clear_vertex_input_mask_cache();
|
||||
|
||||
if (code.is_empty()) {
|
||||
return; //just invalid, but no error
|
||||
|
|
@ -51,10 +51,10 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
|
|||
|
||||
ShaderCompiler::GeneratedCode gen_code;
|
||||
|
||||
int blend_mode = BLEND_MODE_MIX;
|
||||
int depth_testi = DEPTH_TEST_ENABLED;
|
||||
int alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF;
|
||||
int cull_modei = CULL_BACK;
|
||||
blend_mode = BLEND_MODE_MIX;
|
||||
depth_testi = DEPTH_TEST_ENABLED;
|
||||
alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF;
|
||||
int cull_modei = RS::CULL_MODE_BACK;
|
||||
|
||||
uses_point_size = false;
|
||||
uses_alpha = false;
|
||||
|
|
@ -66,8 +66,8 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
|
|||
uses_roughness = false;
|
||||
uses_normal = false;
|
||||
uses_tangent = false;
|
||||
bool uses_normal_map = false;
|
||||
bool wireframe = false;
|
||||
uses_normal_map = false;
|
||||
wireframe = false;
|
||||
|
||||
unshaded = false;
|
||||
uses_vertex = false;
|
||||
|
|
@ -90,7 +90,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
|
|||
actions.render_mode_values["blend_mix"] = Pair<int *, int>(&blend_mode, BLEND_MODE_MIX);
|
||||
actions.render_mode_values["blend_sub"] = Pair<int *, int>(&blend_mode, BLEND_MODE_SUB);
|
||||
actions.render_mode_values["blend_mul"] = Pair<int *, int>(&blend_mode, BLEND_MODE_MUL);
|
||||
actions.render_mode_values["blend_premul_alpha"] = Pair<int *, int>(&blend_mode, BLEND_MODE_PREMULT_ALPHA);
|
||||
actions.render_mode_values["blend_premul_alpha"] = Pair<int *, int>(&blend_mode, BLEND_MODE_PREMULTIPLIED_ALPHA);
|
||||
|
||||
actions.render_mode_values["alpha_to_coverage"] = Pair<int *, int>(&alpha_antialiasing_mode, ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE);
|
||||
actions.render_mode_values["alpha_to_coverage_and_one"] = Pair<int *, int>(&alpha_antialiasing_mode, ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE);
|
||||
|
|
@ -101,9 +101,9 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
|
|||
|
||||
actions.render_mode_values["depth_test_disabled"] = Pair<int *, int>(&depth_testi, DEPTH_TEST_DISABLED);
|
||||
|
||||
actions.render_mode_values["cull_disabled"] = Pair<int *, int>(&cull_modei, CULL_DISABLED);
|
||||
actions.render_mode_values["cull_front"] = Pair<int *, int>(&cull_modei, CULL_FRONT);
|
||||
actions.render_mode_values["cull_back"] = Pair<int *, int>(&cull_modei, CULL_BACK);
|
||||
actions.render_mode_values["cull_disabled"] = Pair<int *, int>(&cull_modei, RS::CULL_MODE_DISABLED);
|
||||
actions.render_mode_values["cull_front"] = Pair<int *, int>(&cull_modei, RS::CULL_MODE_FRONT);
|
||||
actions.render_mode_values["cull_back"] = Pair<int *, int>(&cull_modei, RS::CULL_MODE_BACK);
|
||||
|
||||
actions.render_mode_flags["unshaded"] = &unshaded;
|
||||
actions.render_mode_flags["wireframe"] = &wireframe;
|
||||
|
|
@ -141,17 +141,24 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
|
|||
|
||||
actions.uniforms = &uniforms;
|
||||
|
||||
SceneShaderForwardClustered *shader_singleton = (SceneShaderForwardClustered *)SceneShaderForwardClustered::singleton;
|
||||
Error err = shader_singleton->compiler.compile(RS::SHADER_SPATIAL, code, &actions, path, gen_code);
|
||||
ERR_FAIL_COND_MSG(err != OK, "Shader compilation failed.");
|
||||
MutexLock lock(SceneShaderForwardClustered::singleton_mutex);
|
||||
Error err = SceneShaderForwardClustered::singleton->compiler.compile(RS::SHADER_SPATIAL, code, &actions, path, gen_code);
|
||||
|
||||
if (err != OK) {
|
||||
if (version.is_valid()) {
|
||||
SceneShaderForwardClustered::singleton->shader.version_free(version);
|
||||
version = RID();
|
||||
}
|
||||
ERR_FAIL_MSG("Shader compilation failed.");
|
||||
}
|
||||
|
||||
if (version.is_null()) {
|
||||
version = shader_singleton->shader.version_create();
|
||||
version = SceneShaderForwardClustered::singleton->shader.version_create();
|
||||
}
|
||||
|
||||
depth_draw = DepthDraw(depth_drawi);
|
||||
depth_test = DepthTest(depth_testi);
|
||||
cull_mode = Cull(cull_modei);
|
||||
cull_mode = RS::CullMode(cull_modei);
|
||||
uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps;
|
||||
uses_screen_texture = gen_code.uses_screen_texture;
|
||||
uses_depth_texture = gen_code.uses_depth_texture;
|
||||
|
|
@ -178,235 +185,20 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
|
|||
print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX]);
|
||||
print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]);
|
||||
#endif
|
||||
shader_singleton->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);
|
||||
ERR_FAIL_COND(!shader_singleton->shader.version_is_valid(version));
|
||||
SceneShaderForwardClustered::singleton->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);
|
||||
|
||||
ubo_size = gen_code.uniform_total_size;
|
||||
ubo_offsets = gen_code.uniform_offsets;
|
||||
texture_uniforms = gen_code.texture_uniforms;
|
||||
|
||||
//blend modes
|
||||
pipeline_hash_map.clear_pipelines();
|
||||
|
||||
// if any form of Alpha Antialiasing is enabled, set the blend mode to alpha to coverage
|
||||
// If any form of Alpha Antialiasing is enabled, set the blend mode to alpha to coverage.
|
||||
if (alpha_antialiasing_mode != ALPHA_ANTIALIASING_OFF) {
|
||||
blend_mode = BLEND_MODE_ALPHA_TO_COVERAGE;
|
||||
}
|
||||
|
||||
RD::PipelineColorBlendState::Attachment blend_attachment;
|
||||
|
||||
switch (blend_mode) {
|
||||
case BLEND_MODE_MIX: {
|
||||
blend_attachment.enable_blend = true;
|
||||
blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD;
|
||||
blend_attachment.color_blend_op = RD::BLEND_OP_ADD;
|
||||
blend_attachment.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
|
||||
blend_attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
blend_attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
|
||||
blend_attachment.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
|
||||
} break;
|
||||
case BLEND_MODE_ADD: {
|
||||
blend_attachment.enable_blend = true;
|
||||
blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD;
|
||||
blend_attachment.color_blend_op = RD::BLEND_OP_ADD;
|
||||
blend_attachment.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
|
||||
blend_attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ONE;
|
||||
blend_attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
|
||||
blend_attachment.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
|
||||
uses_blend_alpha = true; //force alpha used because of blend
|
||||
|
||||
} break;
|
||||
case BLEND_MODE_SUB: {
|
||||
blend_attachment.enable_blend = true;
|
||||
blend_attachment.alpha_blend_op = RD::BLEND_OP_REVERSE_SUBTRACT;
|
||||
blend_attachment.color_blend_op = RD::BLEND_OP_REVERSE_SUBTRACT;
|
||||
blend_attachment.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
|
||||
blend_attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ONE;
|
||||
blend_attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
|
||||
blend_attachment.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
|
||||
uses_blend_alpha = true; //force alpha used because of blend
|
||||
|
||||
} break;
|
||||
case BLEND_MODE_MUL: {
|
||||
blend_attachment.enable_blend = true;
|
||||
blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD;
|
||||
blend_attachment.color_blend_op = RD::BLEND_OP_ADD;
|
||||
blend_attachment.src_color_blend_factor = RD::BLEND_FACTOR_DST_COLOR;
|
||||
blend_attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ZERO;
|
||||
blend_attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_DST_ALPHA;
|
||||
blend_attachment.dst_alpha_blend_factor = RD::BLEND_FACTOR_ZERO;
|
||||
uses_blend_alpha = true; //force alpha used because of blend
|
||||
} break;
|
||||
case BLEND_MODE_ALPHA_TO_COVERAGE: {
|
||||
blend_attachment.enable_blend = true;
|
||||
blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD;
|
||||
blend_attachment.color_blend_op = RD::BLEND_OP_ADD;
|
||||
blend_attachment.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
|
||||
blend_attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
blend_attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
|
||||
blend_attachment.dst_alpha_blend_factor = RD::BLEND_FACTOR_ZERO;
|
||||
} break;
|
||||
case BLEND_MODE_PREMULT_ALPHA: {
|
||||
blend_attachment.enable_blend = true;
|
||||
blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD;
|
||||
blend_attachment.color_blend_op = RD::BLEND_OP_ADD;
|
||||
blend_attachment.src_color_blend_factor = RD::BLEND_FACTOR_ONE;
|
||||
blend_attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
blend_attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
|
||||
blend_attachment.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
uses_blend_alpha = true; // Force alpha used because of blend.
|
||||
} break;
|
||||
}
|
||||
|
||||
// Color pass -> attachment 0: Color/Diffuse, attachment 1: Separate Specular, attachment 2: Motion Vectors
|
||||
RD::PipelineColorBlendState blend_state_color_blend;
|
||||
blend_state_color_blend.attachments = { blend_attachment, RD::PipelineColorBlendState::Attachment(), RD::PipelineColorBlendState::Attachment() };
|
||||
RD::PipelineColorBlendState blend_state_color_opaque = RD::PipelineColorBlendState::create_disabled(3);
|
||||
RD::PipelineColorBlendState blend_state_depth_normal_roughness = RD::PipelineColorBlendState::create_disabled(1);
|
||||
RD::PipelineColorBlendState blend_state_depth_normal_roughness_giprobe = RD::PipelineColorBlendState::create_disabled(2);
|
||||
|
||||
//update pipelines
|
||||
|
||||
RD::PipelineDepthStencilState depth_stencil_state;
|
||||
|
||||
if (depth_test != DEPTH_TEST_DISABLED) {
|
||||
depth_stencil_state.enable_depth_test = true;
|
||||
depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_GREATER_OR_EQUAL;
|
||||
depth_stencil_state.enable_depth_write = depth_draw != DEPTH_DRAW_DISABLED ? true : false;
|
||||
}
|
||||
bool depth_pre_pass_enabled = bool(GLOBAL_GET("rendering/driver/depth_prepass/enable"));
|
||||
|
||||
for (int i = 0; i < CULL_VARIANT_MAX; i++) {
|
||||
RD::PolygonCullMode cull_mode_rd_table[CULL_VARIANT_MAX][3] = {
|
||||
{ RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_FRONT, RD::POLYGON_CULL_BACK },
|
||||
{ RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_BACK, RD::POLYGON_CULL_FRONT },
|
||||
{ RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_DISABLED }
|
||||
};
|
||||
|
||||
RD::PolygonCullMode cull_mode_rd = cull_mode_rd_table[i][cull_mode];
|
||||
|
||||
for (int j = 0; j < RS::PRIMITIVE_MAX; j++) {
|
||||
RD::RenderPrimitive primitive_rd_table[RS::PRIMITIVE_MAX] = {
|
||||
RD::RENDER_PRIMITIVE_POINTS,
|
||||
RD::RENDER_PRIMITIVE_LINES,
|
||||
RD::RENDER_PRIMITIVE_LINESTRIPS,
|
||||
RD::RENDER_PRIMITIVE_TRIANGLES,
|
||||
RD::RENDER_PRIMITIVE_TRIANGLE_STRIPS,
|
||||
};
|
||||
|
||||
RD::RenderPrimitive primitive_rd = uses_point_size ? RD::RENDER_PRIMITIVE_POINTS : primitive_rd_table[j];
|
||||
|
||||
for (int k = 0; k < PIPELINE_VERSION_MAX; k++) {
|
||||
ShaderVersion shader_version;
|
||||
static const ShaderVersion shader_version_table[PIPELINE_VERSION_MAX] = {
|
||||
SHADER_VERSION_DEPTH_PASS,
|
||||
SHADER_VERSION_DEPTH_PASS_DP,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_SDF,
|
||||
SHADER_VERSION_DEPTH_PASS_MULTIVIEW,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW,
|
||||
SHADER_VERSION_COLOR_PASS,
|
||||
};
|
||||
|
||||
shader_version = shader_version_table[k];
|
||||
|
||||
if (!static_cast<SceneShaderForwardClustered *>(singleton)->shader.is_variant_enabled(shader_version)) {
|
||||
continue;
|
||||
}
|
||||
RD::PipelineRasterizationState raster_state;
|
||||
raster_state.cull_mode = cull_mode_rd;
|
||||
raster_state.wireframe = wireframe;
|
||||
|
||||
if (k == PIPELINE_VERSION_COLOR_PASS) {
|
||||
for (int l = 0; l < PIPELINE_COLOR_PASS_FLAG_COUNT; l++) {
|
||||
if (!shader_singleton->valid_color_pass_pipelines[l]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
RD::PipelineDepthStencilState depth_stencil = depth_stencil_state;
|
||||
|
||||
RD::PipelineColorBlendState blend_state;
|
||||
RD::PipelineMultisampleState multisample_state;
|
||||
|
||||
int shader_flags = 0;
|
||||
if (l & PIPELINE_COLOR_PASS_FLAG_TRANSPARENT) {
|
||||
if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE) {
|
||||
multisample_state.enable_alpha_to_coverage = true;
|
||||
} else if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE) {
|
||||
multisample_state.enable_alpha_to_coverage = true;
|
||||
multisample_state.enable_alpha_to_one = true;
|
||||
}
|
||||
|
||||
blend_state = blend_state_color_blend;
|
||||
|
||||
if (depth_draw == DEPTH_DRAW_OPAQUE) {
|
||||
depth_stencil.enable_depth_write = false; //alpha does not draw depth
|
||||
}
|
||||
} else {
|
||||
blend_state = blend_state_color_opaque;
|
||||
|
||||
if (depth_pre_pass_enabled) {
|
||||
// We already have a depth from the depth pre-pass, there is no need to write it again.
|
||||
// In addition we can use COMPARE_OP_EQUAL instead of COMPARE_OP_LESS_OR_EQUAL.
|
||||
// This way we can use the early depth test to discard transparent fragments before the fragment shader even starts.
|
||||
depth_stencil.depth_compare_operator = RD::COMPARE_OP_EQUAL;
|
||||
depth_stencil.enable_depth_write = false;
|
||||
}
|
||||
|
||||
if (l & PIPELINE_COLOR_PASS_FLAG_SEPARATE_SPECULAR) {
|
||||
shader_flags |= SHADER_COLOR_PASS_FLAG_SEPARATE_SPECULAR;
|
||||
}
|
||||
}
|
||||
|
||||
if (l & PIPELINE_COLOR_PASS_FLAG_MOTION_VECTORS) {
|
||||
shader_flags |= SHADER_COLOR_PASS_FLAG_MOTION_VECTORS;
|
||||
}
|
||||
|
||||
if (l & PIPELINE_COLOR_PASS_FLAG_LIGHTMAP) {
|
||||
shader_flags |= SHADER_COLOR_PASS_FLAG_LIGHTMAP;
|
||||
}
|
||||
|
||||
if (l & PIPELINE_COLOR_PASS_FLAG_MULTIVIEW) {
|
||||
shader_flags |= SHADER_COLOR_PASS_FLAG_MULTIVIEW;
|
||||
}
|
||||
|
||||
int variant = shader_version + shader_flags;
|
||||
|
||||
if (!static_cast<SceneShaderForwardClustered *>(singleton)->shader.is_variant_enabled(variant)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
RID shader_variant = shader_singleton->shader.version_get_shader(version, variant);
|
||||
color_pipelines[i][j][l].setup(shader_variant, primitive_rd, raster_state, multisample_state, depth_stencil, blend_state, 0, singleton->default_specialization_constants);
|
||||
}
|
||||
} else {
|
||||
RD::PipelineColorBlendState blend_state;
|
||||
RD::PipelineDepthStencilState depth_stencil = depth_stencil_state;
|
||||
RD::PipelineMultisampleState multisample_state;
|
||||
|
||||
if (k == PIPELINE_VERSION_DEPTH_PASS || k == PIPELINE_VERSION_DEPTH_PASS_DP || k == PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW) {
|
||||
//none, leave empty
|
||||
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS || k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW) {
|
||||
blend_state = blend_state_depth_normal_roughness;
|
||||
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI || k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW) {
|
||||
blend_state = blend_state_depth_normal_roughness_giprobe;
|
||||
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_MATERIAL) {
|
||||
blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way
|
||||
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_SDF) {
|
||||
blend_state = RD::PipelineColorBlendState(); //no color targets for SDF
|
||||
}
|
||||
|
||||
RID shader_variant = shader_singleton->shader.version_get_shader(version, shader_version);
|
||||
pipelines[i][j][k].setup(shader_variant, primitive_rd, raster_state, multisample_state, depth_stencil, blend_state, 0, singleton->default_specialization_constants);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
valid = true;
|
||||
uses_blend_alpha = blend_mode_uses_blend_alpha(BlendMode(blend_mode));
|
||||
}
|
||||
|
||||
bool SceneShaderForwardClustered::ShaderData::is_animated() const {
|
||||
|
|
@ -422,25 +214,259 @@ bool SceneShaderForwardClustered::ShaderData::casts_shadows() const {
|
|||
}
|
||||
|
||||
RS::ShaderNativeSourceCode SceneShaderForwardClustered::ShaderData::get_native_source_code() const {
|
||||
SceneShaderForwardClustered *shader_singleton = (SceneShaderForwardClustered *)SceneShaderForwardClustered::singleton;
|
||||
if (version.is_valid()) {
|
||||
MutexLock lock(SceneShaderForwardClustered::singleton_mutex);
|
||||
return SceneShaderForwardClustered::singleton->shader.version_get_native_source_code(version);
|
||||
} else {
|
||||
return RS::ShaderNativeSourceCode();
|
||||
}
|
||||
}
|
||||
|
||||
return shader_singleton->shader.version_get_native_source_code(version);
|
||||
uint16_t SceneShaderForwardClustered::ShaderData::_get_shader_version(PipelineVersion p_pipeline_version, uint32_t p_color_pass_flags, bool p_ubershader) const {
|
||||
uint32_t ubershader_base = p_ubershader ? ShaderVersion::SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL : 0;
|
||||
switch (p_pipeline_version) {
|
||||
case PIPELINE_VERSION_DEPTH_PASS:
|
||||
return ShaderVersion::SHADER_VERSION_DEPTH_PASS + ubershader_base;
|
||||
case PIPELINE_VERSION_DEPTH_PASS_DP:
|
||||
return ShaderVersion::SHADER_VERSION_DEPTH_PASS_DP + ubershader_base;
|
||||
case PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS:
|
||||
return ShaderVersion::SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS + ubershader_base;
|
||||
case PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI:
|
||||
return ShaderVersion::SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI + ubershader_base;
|
||||
case PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW:
|
||||
return ShaderVersion::SHADER_VERSION_DEPTH_PASS_MULTIVIEW + ubershader_base;
|
||||
case PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW:
|
||||
return ShaderVersion::SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW + ubershader_base;
|
||||
case PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW:
|
||||
return ShaderVersion::SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW + ubershader_base;
|
||||
case PIPELINE_VERSION_DEPTH_PASS_WITH_MATERIAL:
|
||||
return ShaderVersion::SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL + ShaderVersion::SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL;
|
||||
case PIPELINE_VERSION_DEPTH_PASS_WITH_SDF:
|
||||
return ShaderVersion::SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL + ShaderVersion::SHADER_VERSION_DEPTH_PASS_WITH_SDF;
|
||||
case PIPELINE_VERSION_COLOR_PASS: {
|
||||
int shader_flags = 0;
|
||||
|
||||
if (p_ubershader) {
|
||||
shader_flags |= SHADER_COLOR_PASS_FLAG_UBERSHADER;
|
||||
}
|
||||
|
||||
if (p_color_pass_flags & PIPELINE_COLOR_PASS_FLAG_SEPARATE_SPECULAR) {
|
||||
shader_flags |= SHADER_COLOR_PASS_FLAG_SEPARATE_SPECULAR;
|
||||
}
|
||||
|
||||
if (p_color_pass_flags & PIPELINE_COLOR_PASS_FLAG_MOTION_VECTORS) {
|
||||
shader_flags |= SHADER_COLOR_PASS_FLAG_MOTION_VECTORS;
|
||||
}
|
||||
|
||||
if (p_color_pass_flags & PIPELINE_COLOR_PASS_FLAG_LIGHTMAP) {
|
||||
shader_flags |= SHADER_COLOR_PASS_FLAG_LIGHTMAP;
|
||||
}
|
||||
|
||||
if (p_color_pass_flags & PIPELINE_COLOR_PASS_FLAG_MULTIVIEW) {
|
||||
shader_flags |= SHADER_COLOR_PASS_FLAG_MULTIVIEW;
|
||||
}
|
||||
|
||||
return ShaderVersion::SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL + ShaderVersion::SHADER_VERSION_COLOR_PASS + shader_flags;
|
||||
} break;
|
||||
default: {
|
||||
DEV_ASSERT(false && "Unknown pipeline version.");
|
||||
return 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneShaderForwardClustered::ShaderData::_create_pipeline(PipelineKey p_pipeline_key) {
|
||||
#if PRINT_PIPELINE_COMPILATION_KEYS
|
||||
print_line(
|
||||
"HASH:", p_pipeline_key.hash(),
|
||||
"VERSION:", version,
|
||||
"VERTEX:", p_pipeline_key.vertex_format_id,
|
||||
"FRAMEBUFFER:", p_pipeline_key.framebuffer_format_id,
|
||||
"CULL:", p_pipeline_key.cull_mode,
|
||||
"PRIMITIVE:", p_pipeline_key.primitive_type,
|
||||
"VERSION:", p_pipeline_key.version,
|
||||
"PASS FLAGS:", p_pipeline_key.color_pass_flags,
|
||||
"SPEC PACKED #0:", p_pipeline_key.shader_specialization.packed_0,
|
||||
"WIREFRAME:", p_pipeline_key.wireframe);
|
||||
#endif
|
||||
|
||||
// Color pass -> attachment 0: Color/Diffuse, attachment 1: Separate Specular, attachment 2: Motion Vectors
|
||||
RD::PipelineColorBlendState::Attachment blend_attachment = blend_mode_to_blend_attachment(BlendMode(blend_mode));
|
||||
RD::PipelineColorBlendState blend_state_color_blend;
|
||||
blend_state_color_blend.attachments = { blend_attachment, RD::PipelineColorBlendState::Attachment(), RD::PipelineColorBlendState::Attachment() };
|
||||
RD::PipelineColorBlendState blend_state_color_opaque = RD::PipelineColorBlendState::create_disabled(3);
|
||||
RD::PipelineColorBlendState blend_state_depth_normal_roughness = RD::PipelineColorBlendState::create_disabled(1);
|
||||
RD::PipelineColorBlendState blend_state_depth_normal_roughness_giprobe = RD::PipelineColorBlendState::create_disabled(2);
|
||||
|
||||
RD::PipelineDepthStencilState depth_stencil_state;
|
||||
|
||||
if (depth_test != DEPTH_TEST_DISABLED) {
|
||||
depth_stencil_state.enable_depth_test = true;
|
||||
depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_GREATER_OR_EQUAL;
|
||||
depth_stencil_state.enable_depth_write = depth_draw != DEPTH_DRAW_DISABLED ? true : false;
|
||||
}
|
||||
bool depth_pre_pass_enabled = bool(GLOBAL_GET("rendering/driver/depth_prepass/enable"));
|
||||
|
||||
RD::RenderPrimitive primitive_rd_table[RS::PRIMITIVE_MAX] = {
|
||||
RD::RENDER_PRIMITIVE_POINTS,
|
||||
RD::RENDER_PRIMITIVE_LINES,
|
||||
RD::RENDER_PRIMITIVE_LINESTRIPS,
|
||||
RD::RENDER_PRIMITIVE_TRIANGLES,
|
||||
RD::RENDER_PRIMITIVE_TRIANGLE_STRIPS,
|
||||
};
|
||||
|
||||
RD::RenderPrimitive primitive_rd = uses_point_size ? RD::RENDER_PRIMITIVE_POINTS : primitive_rd_table[p_pipeline_key.primitive_type];
|
||||
|
||||
RD::PipelineRasterizationState raster_state;
|
||||
raster_state.cull_mode = p_pipeline_key.cull_mode;
|
||||
raster_state.wireframe = wireframe || p_pipeline_key.wireframe;
|
||||
|
||||
RD::PipelineMultisampleState multisample_state;
|
||||
multisample_state.sample_count = RD::get_singleton()->framebuffer_format_get_texture_samples(p_pipeline_key.framebuffer_format_id, 0);
|
||||
|
||||
RD::PipelineColorBlendState blend_state;
|
||||
if (p_pipeline_key.version == PIPELINE_VERSION_COLOR_PASS) {
|
||||
if (p_pipeline_key.color_pass_flags & PIPELINE_COLOR_PASS_FLAG_TRANSPARENT) {
|
||||
if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE) {
|
||||
multisample_state.enable_alpha_to_coverage = true;
|
||||
} else if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE) {
|
||||
multisample_state.enable_alpha_to_coverage = true;
|
||||
multisample_state.enable_alpha_to_one = true;
|
||||
}
|
||||
|
||||
blend_state = blend_state_color_blend;
|
||||
|
||||
if (depth_draw == DEPTH_DRAW_OPAQUE) {
|
||||
depth_stencil_state.enable_depth_write = false; //alpha does not draw depth
|
||||
}
|
||||
} else {
|
||||
blend_state = blend_state_color_opaque;
|
||||
|
||||
if (depth_pre_pass_enabled) {
|
||||
// We already have a depth from the depth pre-pass, there is no need to write it again.
|
||||
// In addition we can use COMPARE_OP_EQUAL instead of COMPARE_OP_LESS_OR_EQUAL.
|
||||
// This way we can use the early depth test to discard transparent fragments before the fragment shader even starts.
|
||||
depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_EQUAL;
|
||||
depth_stencil_state.enable_depth_write = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (p_pipeline_key.version) {
|
||||
case PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS:
|
||||
case PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW:
|
||||
blend_state = blend_state_depth_normal_roughness;
|
||||
break;
|
||||
case PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI:
|
||||
case PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW:
|
||||
blend_state = blend_state_depth_normal_roughness_giprobe;
|
||||
break;
|
||||
case PIPELINE_VERSION_DEPTH_PASS_WITH_MATERIAL:
|
||||
// Writes to normal and roughness in opaque way.
|
||||
blend_state = RD::PipelineColorBlendState::create_disabled(5);
|
||||
break;
|
||||
case PIPELINE_VERSION_DEPTH_PASS:
|
||||
case PIPELINE_VERSION_DEPTH_PASS_DP:
|
||||
case PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW:
|
||||
case PIPELINE_VERSION_DEPTH_PASS_WITH_SDF:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the specialization from the key to pipeline specialization constants.
|
||||
Vector<RD::PipelineSpecializationConstant> specialization_constants;
|
||||
RD::PipelineSpecializationConstant sc;
|
||||
sc.constant_id = 0;
|
||||
sc.int_value = p_pipeline_key.shader_specialization.packed_0;
|
||||
sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT;
|
||||
specialization_constants.push_back(sc);
|
||||
|
||||
sc.constant_id = 1;
|
||||
sc.int_value = p_pipeline_key.shader_specialization.packed_1;
|
||||
specialization_constants.push_back(sc);
|
||||
|
||||
RID shader_rid = get_shader_variant(p_pipeline_key.version, p_pipeline_key.color_pass_flags, p_pipeline_key.ubershader);
|
||||
ERR_FAIL_COND(shader_rid.is_null());
|
||||
|
||||
RID pipeline = RD::get_singleton()->render_pipeline_create(shader_rid, p_pipeline_key.framebuffer_format_id, p_pipeline_key.vertex_format_id, primitive_rd, raster_state, multisample_state, depth_stencil_state, blend_state, 0, 0, specialization_constants);
|
||||
ERR_FAIL_COND(pipeline.is_null());
|
||||
|
||||
pipeline_hash_map.add_compiled_pipeline(p_pipeline_key.hash(), pipeline);
|
||||
}
|
||||
|
||||
RD::PolygonCullMode SceneShaderForwardClustered::ShaderData::get_cull_mode_from_cull_variant(CullVariant p_cull_variant) {
|
||||
const RD::PolygonCullMode cull_mode_rd_table[CULL_VARIANT_MAX][3] = {
|
||||
{ RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_FRONT, RD::POLYGON_CULL_BACK },
|
||||
{ RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_BACK, RD::POLYGON_CULL_FRONT },
|
||||
{ RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_DISABLED }
|
||||
};
|
||||
|
||||
return cull_mode_rd_table[p_cull_variant][cull_mode];
|
||||
}
|
||||
|
||||
RID SceneShaderForwardClustered::ShaderData::_get_shader_variant(uint16_t p_shader_version) const {
|
||||
if (version.is_valid()) {
|
||||
MutexLock lock(SceneShaderForwardClustered::singleton_mutex);
|
||||
ERR_FAIL_NULL_V(SceneShaderForwardClustered::singleton, RID());
|
||||
return SceneShaderForwardClustered::singleton->shader.version_get_shader(version, p_shader_version);
|
||||
} else {
|
||||
return RID();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneShaderForwardClustered::ShaderData::_clear_vertex_input_mask_cache() {
|
||||
for (uint32_t i = 0; i < VERTEX_INPUT_MASKS_SIZE; i++) {
|
||||
vertex_input_masks[i].store(0);
|
||||
}
|
||||
}
|
||||
|
||||
RID SceneShaderForwardClustered::ShaderData::get_shader_variant(PipelineVersion p_pipeline_version, uint32_t p_color_pass_flags, bool p_ubershader) const {
|
||||
return _get_shader_variant(_get_shader_version(p_pipeline_version, p_color_pass_flags, p_ubershader));
|
||||
}
|
||||
|
||||
uint64_t SceneShaderForwardClustered::ShaderData::get_vertex_input_mask(PipelineVersion p_pipeline_version, uint32_t p_color_pass_flags, bool p_ubershader) {
|
||||
// Vertex input masks require knowledge of the shader. Since querying the shader can be expensive due to high contention and the necessary mutex, we cache the result instead.
|
||||
uint16_t shader_version = _get_shader_version(p_pipeline_version, p_color_pass_flags, p_ubershader);
|
||||
uint64_t input_mask = vertex_input_masks[shader_version].load(std::memory_order_relaxed);
|
||||
if (input_mask == 0) {
|
||||
RID shader_rid = _get_shader_variant(shader_version);
|
||||
ERR_FAIL_COND_V(shader_rid.is_null(), 0);
|
||||
|
||||
input_mask = RD::get_singleton()->shader_get_vertex_input_attribute_mask(shader_rid);
|
||||
vertex_input_masks[shader_version].store(input_mask, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
return input_mask;
|
||||
}
|
||||
|
||||
bool SceneShaderForwardClustered::ShaderData::is_valid() const {
|
||||
if (version.is_valid()) {
|
||||
MutexLock lock(SceneShaderForwardClustered::singleton_mutex);
|
||||
ERR_FAIL_NULL_V(SceneShaderForwardClustered::singleton, false);
|
||||
return SceneShaderForwardClustered::singleton->shader.version_is_valid(version);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SceneShaderForwardClustered::ShaderData::ShaderData() :
|
||||
shader_list_element(this) {
|
||||
pipeline_hash_map.set_creation_object_and_function(this, &ShaderData::_create_pipeline);
|
||||
pipeline_hash_map.set_compilations(SceneShaderForwardClustered::singleton->pipeline_compilations, &SceneShaderForwardClustered::singleton_mutex);
|
||||
}
|
||||
|
||||
SceneShaderForwardClustered::ShaderData::~ShaderData() {
|
||||
SceneShaderForwardClustered *shader_singleton = (SceneShaderForwardClustered *)SceneShaderForwardClustered::singleton;
|
||||
ERR_FAIL_NULL(shader_singleton);
|
||||
//pipeline variants will clear themselves if shader is gone
|
||||
pipeline_hash_map.clear_pipelines();
|
||||
|
||||
if (version.is_valid()) {
|
||||
shader_singleton->shader.version_free(version);
|
||||
MutexLock lock(SceneShaderForwardClustered::singleton_mutex);
|
||||
ERR_FAIL_NULL(SceneShaderForwardClustered::singleton);
|
||||
SceneShaderForwardClustered::singleton->shader.version_free(version);
|
||||
}
|
||||
}
|
||||
|
||||
RendererRD::MaterialStorage::ShaderData *SceneShaderForwardClustered::_create_shader_func() {
|
||||
MutexLock lock(SceneShaderForwardClustered::singleton_mutex);
|
||||
ShaderData *shader_data = memnew(ShaderData);
|
||||
singleton->shader_list.add(&shader_data->shader_list_element);
|
||||
return shader_data;
|
||||
|
|
@ -455,9 +481,12 @@ void SceneShaderForwardClustered::MaterialData::set_next_pass(RID p_pass) {
|
|||
}
|
||||
|
||||
bool SceneShaderForwardClustered::MaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
|
||||
SceneShaderForwardClustered *shader_singleton = (SceneShaderForwardClustered *)SceneShaderForwardClustered::singleton;
|
||||
|
||||
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, shader_singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardClustered::MATERIAL_UNIFORM_SET, true, true);
|
||||
if (shader_data->version.is_valid()) {
|
||||
MutexLock lock(SceneShaderForwardClustered::singleton_mutex);
|
||||
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, SceneShaderForwardClustered::singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardClustered::MATERIAL_UNIFORM_SET, true, true);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SceneShaderForwardClustered::MaterialData::~MaterialData() {
|
||||
|
|
@ -472,6 +501,7 @@ RendererRD::MaterialStorage::MaterialData *SceneShaderForwardClustered::_create_
|
|||
}
|
||||
|
||||
SceneShaderForwardClustered *SceneShaderForwardClustered::singleton = nullptr;
|
||||
Mutex SceneShaderForwardClustered::singleton_mutex;
|
||||
|
||||
SceneShaderForwardClustered::SceneShaderForwardClustered() {
|
||||
// there should be only one of these, contained within our RenderFM singleton.
|
||||
|
|
@ -498,17 +528,22 @@ void SceneShaderForwardClustered::init(const String p_defines) {
|
|||
|
||||
{
|
||||
Vector<ShaderRD::VariantDefine> shader_versions;
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_BASE, "\n#define MODE_RENDER_DEPTH\n", true)); // SHADER_VERSION_DEPTH_PASS
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_BASE, "\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n", true)); // SHADER_VERSION_DEPTH_PASS_DP
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_BASE, "\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n", true)); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_ADVANCED, "\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n#define MODE_RENDER_VOXEL_GI\n", false)); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI
|
||||
for (uint32_t ubershader = 0; ubershader < 2; ubershader++) {
|
||||
const String base_define = ubershader ? "\n#define UBERSHADER\n" : "";
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_BASE, base_define + "\n#define MODE_RENDER_DEPTH\n", true)); // SHADER_VERSION_DEPTH_PASS
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_BASE, base_define + "\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n", true)); // SHADER_VERSION_DEPTH_PASS_DP
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_BASE, base_define + "\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n", true)); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_ADVANCED, base_define + "\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n#define MODE_RENDER_VOXEL_GI\n", false)); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_MULTIVIEW, base_define + "\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n", false)); // SHADER_VERSION_DEPTH_PASS_MULTIVIEW
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_MULTIVIEW, base_define + "\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n", false)); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_ADVANCED_MULTIVIEW, base_define + "\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n#define MODE_RENDER_VOXEL_GI\n", false)); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW
|
||||
}
|
||||
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_ADVANCED, "\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_MATERIAL\n", false)); // SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_ADVANCED, "\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_SDF\n", false)); // SHADER_VERSION_DEPTH_PASS_WITH_SDF
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_MULTIVIEW, "\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n", false)); // SHADER_VERSION_DEPTH_PASS_MULTIVIEW
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_MULTIVIEW, "\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n", false)); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_MULTIVIEW, "\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n#define MODE_RENDER_VOXEL_GI\n", false)); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW
|
||||
|
||||
Vector<String> color_pass_flags = {
|
||||
"\n#define UBERSHADER\n", // SHADER_COLOR_PASS_FLAG_UBERSHADER
|
||||
"\n#define MODE_SEPARATE_SPECULAR\n", // SHADER_COLOR_PASS_FLAG_SEPARATE_SPECULAR
|
||||
"\n#define USE_LIGHTMAP\n", // SHADER_COLOR_PASS_FLAG_LIGHTMAP
|
||||
"\n#define USE_MULTIVIEW\n", // SHADER_COLOR_PASS_FLAG_MULTIVIEW
|
||||
|
|
@ -545,16 +580,6 @@ void SceneShaderForwardClustered::init(const String p_defines) {
|
|||
}
|
||||
}
|
||||
|
||||
// Set flag to true if a combination is valid.
|
||||
// The only invalid combinations are those that include both TRANSPARENT and SEPARATE_SPECULAR.
|
||||
for (int i = 0; i < PIPELINE_COLOR_PASS_FLAG_COUNT; i++) {
|
||||
if ((i & PIPELINE_COLOR_PASS_FLAG_TRANSPARENT) && (i & PIPELINE_COLOR_PASS_FLAG_SEPARATE_SPECULAR)) {
|
||||
valid_color_pass_pipelines[i] = false;
|
||||
} else {
|
||||
valid_color_pass_pipelines[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
material_storage->shader_set_data_request_function(RendererRD::MaterialStorage::SHADER_TYPE_3D, _create_shader_funcs);
|
||||
material_storage->material_set_data_request_function(RendererRD::MaterialStorage::SHADER_TYPE_3D, _create_material_funcs);
|
||||
|
||||
|
|
@ -596,6 +621,8 @@ void SceneShaderForwardClustered::init(const String p_defines) {
|
|||
actions.renames["PI"] = _MKSTR(Math_PI);
|
||||
actions.renames["TAU"] = _MKSTR(Math_TAU);
|
||||
actions.renames["E"] = _MKSTR(Math_E);
|
||||
actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB";
|
||||
actions.renames["CLIP_SPACE_FAR"] = "SHADER_SPACE_FAR";
|
||||
actions.renames["VIEWPORT_SIZE"] = "read_viewport_size";
|
||||
|
||||
actions.renames["FRAGCOORD"] = "gl_FragCoord";
|
||||
|
|
@ -635,7 +662,6 @@ void SceneShaderForwardClustered::init(const String p_defines) {
|
|||
actions.renames["CUSTOM1"] = "custom1_attrib";
|
||||
actions.renames["CUSTOM2"] = "custom2_attrib";
|
||||
actions.renames["CUSTOM3"] = "custom3_attrib";
|
||||
actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB";
|
||||
actions.renames["LIGHT_VERTEX"] = "light_vertex";
|
||||
|
||||
actions.renames["NODE_POSITION_WORLD"] = "read_model_matrix[3].xyz";
|
||||
|
|
@ -729,13 +755,20 @@ void SceneShaderForwardClustered::init(const String p_defines) {
|
|||
actions.render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n";
|
||||
actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
|
||||
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
|
||||
|
||||
bool force_vertex_shading = GLOBAL_GET("rendering/shading/overrides/force_vertex_shading");
|
||||
if (!force_vertex_shading) {
|
||||
// If forcing vertex shading, this will be defined already.
|
||||
actions.render_mode_defines["vertex_lighting"] = "#define USE_VERTEX_LIGHTING\n";
|
||||
}
|
||||
|
||||
actions.render_mode_defines["debug_shadow_splits"] = "#define DEBUG_DRAW_PSSM_SPLITS\n";
|
||||
actions.render_mode_defines["fog_disabled"] = "#define FOG_DISABLED\n";
|
||||
|
||||
actions.base_texture_binding_index = 1;
|
||||
actions.texture_layout_set = RenderForwardClustered::MATERIAL_UNIFORM_SET;
|
||||
actions.base_uniform_string = "material.";
|
||||
actions.base_varying_index = 12;
|
||||
actions.base_varying_index = 14;
|
||||
|
||||
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
|
||||
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
|
||||
|
|
@ -771,8 +804,7 @@ void fragment() {
|
|||
material_storage->material_set_shader(default_material, default_shader);
|
||||
|
||||
MaterialData *md = static_cast<MaterialData *>(material_storage->material_get_data(default_material, RendererRD::MaterialStorage::SHADER_TYPE_3D));
|
||||
default_shader_rd = shader.version_get_shader(md->shader_data->version, SHADER_VERSION_COLOR_PASS);
|
||||
default_shader_sdfgi_rd = shader.version_get_shader(md->shader_data->version, SHADER_VERSION_DEPTH_PASS_WITH_SDF);
|
||||
default_shader_rd = md->shader_data->get_shader_variant(PIPELINE_VERSION_COLOR_PASS, 0, false);
|
||||
|
||||
default_material_shader_ptr = md->shader_data;
|
||||
default_material_uniform_set = md->uniform_set;
|
||||
|
|
@ -847,19 +879,11 @@ void fragment() {
|
|||
}
|
||||
}
|
||||
|
||||
void SceneShaderForwardClustered::set_default_specialization_constants(const Vector<RD::PipelineSpecializationConstant> &p_constants) {
|
||||
default_specialization_constants = p_constants;
|
||||
void SceneShaderForwardClustered::set_default_specialization(const ShaderSpecialization &p_specialization) {
|
||||
default_specialization = p_specialization;
|
||||
|
||||
for (SelfList<ShaderData> *E = shader_list.first(); E; E = E->next()) {
|
||||
for (int i = 0; i < ShaderData::CULL_VARIANT_MAX; i++) {
|
||||
for (int j = 0; j < RS::PRIMITIVE_MAX; j++) {
|
||||
for (int k = 0; k < SHADER_VERSION_MAX; k++) {
|
||||
E->self()->pipelines[i][j][k].update_specialization_constants(default_specialization_constants);
|
||||
}
|
||||
for (int k = 0; k < PIPELINE_COLOR_PASS_FLAG_COUNT; k++) {
|
||||
E->self()->color_pipelines[i][j][k].update_specialization_constants(default_specialization_constants);
|
||||
}
|
||||
}
|
||||
}
|
||||
E->self()->pipeline_hash_map.clear_pipelines();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -869,3 +893,20 @@ void SceneShaderForwardClustered::enable_advanced_shader_group(bool p_needs_mult
|
|||
}
|
||||
shader.enable_group(SHADER_GROUP_ADVANCED);
|
||||
}
|
||||
|
||||
bool SceneShaderForwardClustered::is_multiview_shader_group_enabled() const {
|
||||
return shader.is_group_enabled(SHADER_GROUP_MULTIVIEW);
|
||||
}
|
||||
|
||||
bool SceneShaderForwardClustered::is_advanced_shader_group_enabled(bool p_multiview) const {
|
||||
if (p_multiview) {
|
||||
return shader.is_group_enabled(SHADER_GROUP_ADVANCED_MULTIVIEW);
|
||||
} else {
|
||||
return shader.is_group_enabled(SHADER_GROUP_ADVANCED);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t SceneShaderForwardClustered::get_pipeline_compilations(RS::PipelineSource p_source) {
|
||||
MutexLock lock(SceneShaderForwardClustered::singleton_mutex);
|
||||
return pipeline_compilations[p_source];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@
|
|||
#ifndef SCENE_SHADER_FORWARD_CLUSTERED_H
|
||||
#define SCENE_SHADER_FORWARD_CLUSTERED_H
|
||||
|
||||
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
|
||||
#include "../storage_rd/material_storage.h"
|
||||
#include "servers/rendering/renderer_rd/pipeline_hash_map_rd.h"
|
||||
#include "servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl.gen.h"
|
||||
|
||||
namespace RendererSceneRenderImplementation {
|
||||
|
|
@ -39,6 +40,7 @@ namespace RendererSceneRenderImplementation {
|
|||
class SceneShaderForwardClustered {
|
||||
private:
|
||||
static SceneShaderForwardClustered *singleton;
|
||||
static Mutex singleton_mutex;
|
||||
|
||||
public:
|
||||
enum ShaderGroup {
|
||||
|
|
@ -48,26 +50,28 @@ public:
|
|||
SHADER_GROUP_ADVANCED_MULTIVIEW,
|
||||
};
|
||||
|
||||
enum ShaderVersion {
|
||||
SHADER_VERSION_DEPTH_PASS,
|
||||
SHADER_VERSION_DEPTH_PASS_DP,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_SDF,
|
||||
SHADER_VERSION_DEPTH_PASS_MULTIVIEW,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW,
|
||||
SHADER_VERSION_COLOR_PASS,
|
||||
SHADER_VERSION_MAX
|
||||
// Not an enum because these values are constants that are processed as numbers
|
||||
// to arrive at a unique version for a particular shader.
|
||||
struct ShaderVersion {
|
||||
constexpr static uint16_t SHADER_VERSION_DEPTH_PASS = 0;
|
||||
constexpr static uint16_t SHADER_VERSION_DEPTH_PASS_DP = 1;
|
||||
constexpr static uint16_t SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS = 2;
|
||||
constexpr static uint16_t SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI = 3;
|
||||
constexpr static uint16_t SHADER_VERSION_DEPTH_PASS_MULTIVIEW = 4;
|
||||
constexpr static uint16_t SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW = 5;
|
||||
constexpr static uint16_t SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW = 6;
|
||||
constexpr static uint16_t SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL = 7;
|
||||
constexpr static uint16_t SHADER_VERSION_DEPTH_PASS_WITH_SDF = 8;
|
||||
constexpr static uint16_t SHADER_VERSION_COLOR_PASS = 9;
|
||||
};
|
||||
|
||||
enum ShaderColorPassFlags {
|
||||
SHADER_COLOR_PASS_FLAG_SEPARATE_SPECULAR = 1 << 0,
|
||||
SHADER_COLOR_PASS_FLAG_LIGHTMAP = 1 << 1,
|
||||
SHADER_COLOR_PASS_FLAG_MULTIVIEW = 1 << 2,
|
||||
SHADER_COLOR_PASS_FLAG_MOTION_VECTORS = 1 << 3,
|
||||
SHADER_COLOR_PASS_FLAG_COUNT = 1 << 4
|
||||
SHADER_COLOR_PASS_FLAG_UBERSHADER = 1 << 0,
|
||||
SHADER_COLOR_PASS_FLAG_SEPARATE_SPECULAR = 1 << 1,
|
||||
SHADER_COLOR_PASS_FLAG_LIGHTMAP = 1 << 2,
|
||||
SHADER_COLOR_PASS_FLAG_MULTIVIEW = 1 << 3,
|
||||
SHADER_COLOR_PASS_FLAG_MOTION_VECTORS = 1 << 4,
|
||||
SHADER_COLOR_PASS_FLAG_COUNT = 1 << 5
|
||||
};
|
||||
|
||||
enum PipelineVersion {
|
||||
|
|
@ -90,26 +94,55 @@ public:
|
|||
PIPELINE_COLOR_PASS_FLAG_LIGHTMAP = 1 << 2,
|
||||
PIPELINE_COLOR_PASS_FLAG_MULTIVIEW = 1 << 3,
|
||||
PIPELINE_COLOR_PASS_FLAG_MOTION_VECTORS = 1 << 4,
|
||||
PIPELINE_COLOR_PASS_FLAG_COUNT = 1 << 5,
|
||||
PIPELINE_COLOR_PASS_FLAG_OPTIONS = 5,
|
||||
PIPELINE_COLOR_PASS_FLAG_COMBINATIONS = 1 << PIPELINE_COLOR_PASS_FLAG_OPTIONS,
|
||||
};
|
||||
|
||||
enum ShaderSpecializations {
|
||||
SHADER_SPECIALIZATION_FORWARD_GI = 1 << 0,
|
||||
SHADER_SPECIALIZATION_PROJECTOR = 1 << 1,
|
||||
SHADER_SPECIALIZATION_SOFT_SHADOWS = 1 << 2,
|
||||
SHADER_SPECIALIZATION_DIRECTIONAL_SOFT_SHADOWS = 1 << 3,
|
||||
struct ShaderSpecialization {
|
||||
union {
|
||||
uint32_t packed_0;
|
||||
|
||||
struct {
|
||||
uint32_t use_forward_gi : 1;
|
||||
uint32_t use_light_projector : 1;
|
||||
uint32_t use_light_soft_shadows : 1;
|
||||
uint32_t use_directional_soft_shadows : 1;
|
||||
uint32_t decal_use_mipmaps : 1;
|
||||
uint32_t projector_use_mipmaps : 1;
|
||||
uint32_t use_depth_fog : 1;
|
||||
uint32_t use_lightmap_bicubic_filter : 1;
|
||||
uint32_t soft_shadow_samples : 6;
|
||||
uint32_t penumbra_shadow_samples : 6;
|
||||
uint32_t directional_soft_shadow_samples : 6;
|
||||
uint32_t directional_penumbra_shadow_samples : 6;
|
||||
};
|
||||
};
|
||||
|
||||
union {
|
||||
uint32_t packed_1;
|
||||
|
||||
struct {
|
||||
uint32_t multimesh : 1;
|
||||
uint32_t multimesh_format_2d : 1;
|
||||
uint32_t multimesh_has_color : 1;
|
||||
uint32_t multimesh_has_custom_data : 1;
|
||||
};
|
||||
};
|
||||
|
||||
uint32_t packed_2;
|
||||
};
|
||||
|
||||
struct UbershaderConstants {
|
||||
union {
|
||||
uint32_t packed_0;
|
||||
|
||||
struct {
|
||||
uint32_t cull_mode : 2;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
struct ShaderData : public RendererRD::MaterialStorage::ShaderData {
|
||||
enum BlendMode { //used internally
|
||||
BLEND_MODE_MIX,
|
||||
BLEND_MODE_ADD,
|
||||
BLEND_MODE_SUB,
|
||||
BLEND_MODE_MUL,
|
||||
BLEND_MODE_ALPHA_TO_COVERAGE,
|
||||
BLEND_MODE_PREMULT_ALPHA,
|
||||
};
|
||||
|
||||
enum DepthDraw {
|
||||
DEPTH_DRAW_DISABLED,
|
||||
DEPTH_DRAW_OPAQUE,
|
||||
|
|
@ -121,12 +154,6 @@ public:
|
|||
DEPTH_TEST_ENABLED
|
||||
};
|
||||
|
||||
enum Cull {
|
||||
CULL_DISABLED,
|
||||
CULL_FRONT,
|
||||
CULL_BACK
|
||||
};
|
||||
|
||||
enum CullVariant {
|
||||
CULL_VARIANT_NORMAL,
|
||||
CULL_VARIANT_REVERSED,
|
||||
|
|
@ -141,11 +168,40 @@ public:
|
|||
ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE
|
||||
};
|
||||
|
||||
bool valid = false;
|
||||
struct PipelineKey {
|
||||
RD::VertexFormatID vertex_format_id;
|
||||
RD::FramebufferFormatID framebuffer_format_id;
|
||||
RD::PolygonCullMode cull_mode = RD::POLYGON_CULL_MAX;
|
||||
RS::PrimitiveType primitive_type = RS::PRIMITIVE_MAX;
|
||||
PipelineVersion version = PipelineVersion::PIPELINE_VERSION_MAX;
|
||||
uint32_t color_pass_flags = 0;
|
||||
ShaderSpecialization shader_specialization = {};
|
||||
uint32_t wireframe = false;
|
||||
uint32_t ubershader = false;
|
||||
|
||||
uint32_t hash() const {
|
||||
uint32_t h = hash_murmur3_one_64(vertex_format_id);
|
||||
h = hash_murmur3_one_32(framebuffer_format_id, h);
|
||||
h = hash_murmur3_one_32(cull_mode, h);
|
||||
h = hash_murmur3_one_32(primitive_type, h);
|
||||
h = hash_murmur3_one_32(version, h);
|
||||
h = hash_murmur3_one_32(color_pass_flags, h);
|
||||
h = hash_murmur3_one_32(shader_specialization.packed_0, h);
|
||||
h = hash_murmur3_one_32(shader_specialization.packed_1, h);
|
||||
h = hash_murmur3_one_32(shader_specialization.packed_2, h);
|
||||
h = hash_murmur3_one_32(wireframe, h);
|
||||
h = hash_murmur3_one_32(ubershader, h);
|
||||
return hash_fmix32(h);
|
||||
}
|
||||
};
|
||||
|
||||
void _create_pipeline(PipelineKey p_pipeline_key);
|
||||
PipelineHashMapRD<PipelineKey, ShaderData, void (ShaderData::*)(PipelineKey)> pipeline_hash_map;
|
||||
|
||||
RID version;
|
||||
uint64_t vertex_input_mask = 0;
|
||||
PipelineCacheRD pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][PIPELINE_VERSION_MAX];
|
||||
PipelineCacheRD color_pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][PIPELINE_COLOR_PASS_FLAG_COUNT];
|
||||
|
||||
static const uint32_t VERTEX_INPUT_MASKS_SIZE = ShaderVersion::SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL + ShaderVersion::SHADER_VERSION_COLOR_PASS + SHADER_COLOR_PASS_FLAG_COUNT;
|
||||
std::atomic<uint64_t> vertex_input_masks[VERTEX_INPUT_MASKS_SIZE] = {};
|
||||
|
||||
Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
|
||||
|
||||
|
|
@ -157,6 +213,10 @@ public:
|
|||
DepthDraw depth_draw = DEPTH_DRAW_OPAQUE;
|
||||
DepthTest depth_test = DEPTH_TEST_ENABLED;
|
||||
|
||||
int blend_mode = BLEND_MODE_MIX;
|
||||
int depth_testi = DEPTH_TEST_ENABLED;
|
||||
int alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF;
|
||||
|
||||
bool uses_point_size = false;
|
||||
bool uses_alpha = false;
|
||||
bool uses_blend_alpha = false;
|
||||
|
|
@ -168,6 +228,8 @@ public:
|
|||
bool uses_normal = false;
|
||||
bool uses_tangent = false;
|
||||
bool uses_particle_trails = false;
|
||||
bool uses_normal_map = false;
|
||||
bool wireframe = false;
|
||||
|
||||
bool unshaded = false;
|
||||
bool uses_vertex = false;
|
||||
|
|
@ -183,16 +245,44 @@ public:
|
|||
bool writes_modelview_or_projection = false;
|
||||
bool uses_world_coordinates = false;
|
||||
bool uses_screen_texture_mipmaps = false;
|
||||
Cull cull_mode = CULL_DISABLED;
|
||||
RS::CullMode cull_mode = RS::CULL_MODE_DISABLED;
|
||||
|
||||
uint64_t last_pass = 0;
|
||||
uint32_t index = 0;
|
||||
|
||||
_FORCE_INLINE_ bool uses_alpha_pass() const {
|
||||
bool has_read_screen_alpha = uses_screen_texture || uses_depth_texture || uses_normal_texture;
|
||||
bool has_base_alpha = (uses_alpha && (!uses_alpha_clip || uses_alpha_antialiasing)) || has_read_screen_alpha;
|
||||
bool has_blend_alpha = uses_blend_alpha;
|
||||
bool has_alpha = has_base_alpha || has_blend_alpha;
|
||||
bool no_depth_draw = depth_draw == DEPTH_DRAW_DISABLED;
|
||||
bool no_depth_test = depth_test == DEPTH_TEST_DISABLED;
|
||||
return has_alpha || has_read_screen_alpha || no_depth_draw || no_depth_test;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool uses_depth_in_alpha_pass() const {
|
||||
bool no_depth_draw = depth_draw == DEPTH_DRAW_DISABLED;
|
||||
bool no_depth_test = depth_test == DEPTH_TEST_DISABLED;
|
||||
return (uses_depth_prepass_alpha || uses_alpha_antialiasing) && !(no_depth_draw || no_depth_test);
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool uses_shared_shadow_material() const {
|
||||
bool backface_culling = cull_mode == RS::CULL_MODE_BACK;
|
||||
return !uses_particle_trails && !writes_modelview_or_projection && !uses_vertex && !uses_position && !uses_discard && !uses_depth_prepass_alpha && !uses_alpha_clip && !uses_alpha_antialiasing && backface_culling && !uses_point_size && !uses_world_coordinates && !wireframe;
|
||||
}
|
||||
|
||||
virtual void set_code(const String &p_Code);
|
||||
|
||||
virtual bool is_animated() const;
|
||||
virtual bool casts_shadows() const;
|
||||
virtual RS::ShaderNativeSourceCode get_native_source_code() const;
|
||||
uint16_t _get_shader_version(PipelineVersion p_pipeline_version, uint32_t p_color_pass_flags, bool p_ubershader) const;
|
||||
RID _get_shader_variant(uint16_t p_shader_version) const;
|
||||
void _clear_vertex_input_mask_cache();
|
||||
RID get_shader_variant(PipelineVersion p_pipeline_version, uint32_t p_color_pass_flags, bool p_ubershader) const;
|
||||
uint64_t get_vertex_input_mask(PipelineVersion p_pipeline_version, uint32_t p_color_pass_flags, bool p_ubershader);
|
||||
RD::PolygonCullMode get_cull_mode_from_cull_variant(CullVariant p_cull_variant);
|
||||
bool is_valid() const;
|
||||
|
||||
SelfList<ShaderData> shader_list_element;
|
||||
ShaderData();
|
||||
|
|
@ -250,14 +340,19 @@ public:
|
|||
RID debug_shadow_splits_material_uniform_set;
|
||||
ShaderData *debug_shadow_splits_material_shader_ptr = nullptr;
|
||||
|
||||
Vector<RD::PipelineSpecializationConstant> default_specialization_constants;
|
||||
bool valid_color_pass_pipelines[PIPELINE_COLOR_PASS_FLAG_COUNT];
|
||||
ShaderSpecialization default_specialization = {};
|
||||
|
||||
uint32_t pipeline_compilations[RS::PIPELINE_SOURCE_MAX] = {};
|
||||
|
||||
SceneShaderForwardClustered();
|
||||
~SceneShaderForwardClustered();
|
||||
|
||||
void init(const String p_defines);
|
||||
void set_default_specialization_constants(const Vector<RD::PipelineSpecializationConstant> &p_constants);
|
||||
void set_default_specialization(const ShaderSpecialization &p_specialization);
|
||||
void enable_advanced_shader_group(bool p_needs_multiview = false);
|
||||
bool is_multiview_shader_group_enabled() const;
|
||||
bool is_advanced_shader_group_enabled(bool p_multiview) const;
|
||||
uint32_t get_pipeline_compilations(RS::PipelineSource p_source);
|
||||
};
|
||||
|
||||
} // namespace RendererSceneRenderImplementation
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue