From 975a8f9ada76e227f6c50b2a6f51ea84e1244ce4 Mon Sep 17 00:00:00 2001 From: clayjohn Date: Mon, 5 Dec 2022 18:10:13 -0800 Subject: [PATCH] Clean up specialization constants in OpenGL scene renderer Also add support for disabling omni and spot lights when not used --- drivers/gles3/rasterizer_scene_gles3.cpp | 35 ++++++++++++++++-------- drivers/gles3/rasterizer_scene_gles3.h | 4 +-- drivers/gles3/shaders/canvas.glsl | 2 -- drivers/gles3/shaders/scene.glsl | 5 +++- 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 27438014667..66c02f55660 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1902,7 +1902,7 @@ void RasterizerSceneGLES3::render_scene(const Ref &p_render_ glColorMask(0, 0, 0, 0); glClearDepth(1.0f); glClear(GL_DEPTH_BUFFER_BIT); - uint32_t spec_constant = SceneShaderGLES3::DISABLE_FOG | SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL | + uint64_t spec_constant = SceneShaderGLES3::DISABLE_FOG | SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL | SceneShaderGLES3::DISABLE_LIGHTMAP | SceneShaderGLES3::DISABLE_LIGHT_OMNI | SceneShaderGLES3::DISABLE_LIGHT_SPOT; @@ -1943,7 +1943,7 @@ void RasterizerSceneGLES3::render_scene(const Ref &p_render_ glClearBufferfv(GL_COLOR, 0, clear_color.components); } RENDER_TIMESTAMP("Render Opaque Pass"); - uint32_t spec_constant_base_flags = 0; + uint64_t spec_constant_base_flags = 0; { // Specialization Constants that apply for entire rendering pass. @@ -2014,8 +2014,10 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, GeometryInstanceGLES3 *prev_inst = nullptr; SceneShaderGLES3::ShaderVariant prev_variant = SceneShaderGLES3::ShaderVariant::MODE_COLOR; SceneShaderGLES3::ShaderVariant shader_variant = SceneShaderGLES3::MODE_COLOR; // Assigned to silence wrong -Wmaybe-initialized + uint64_t prev_spec_constants = 0; - uint32_t base_spec_constants = p_params->spec_constant_base_flags; + // Specializations constants used by all instances in the scene. + uint64_t base_spec_constants = p_params->spec_constant_base_flags; if (p_render_data->view_count > 1) { base_spec_constants |= SceneShaderGLES3::USE_MULTIVIEW; @@ -2235,8 +2237,18 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, instance_variant = SceneShaderGLES3::ShaderVariant(1 + int(shader_variant)); } - if (prev_shader != shader || prev_variant != instance_variant) { - bool success = material_storage->shaders.scene_shader.version_bind_shader(shader->version, instance_variant, base_spec_constants); + uint64_t spec_constants = base_spec_constants; + + if (inst->omni_light_count == 0) { + spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_OMNI; + } + + if (inst->spot_light_count == 0) { + spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_SPOT; + } + + if (prev_shader != shader || prev_variant != instance_variant || spec_constants != prev_spec_constants) { + bool success = material_storage->shaders.scene_shader.version_bind_shader(shader->version, instance_variant, spec_constants); if (!success) { continue; } @@ -2248,29 +2260,30 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, opaque_prepass_threshold = 0.1; } - material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::OPAQUE_PREPASS_THRESHOLD, opaque_prepass_threshold, shader->version, instance_variant, base_spec_constants); + material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::OPAQUE_PREPASS_THRESHOLD, opaque_prepass_threshold, shader->version, instance_variant, spec_constants); prev_shader = shader; prev_variant = instance_variant; + prev_spec_constants = spec_constants; } if (prev_inst != inst || prev_shader != shader || prev_variant != instance_variant) { // Rebind the light indices. - material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::OMNI_LIGHT_COUNT, inst->omni_light_count, shader->version, instance_variant, base_spec_constants); - material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::SPOT_LIGHT_COUNT, inst->spot_light_count, shader->version, instance_variant, base_spec_constants); + material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::OMNI_LIGHT_COUNT, inst->omni_light_count, shader->version, instance_variant, spec_constants); + material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::SPOT_LIGHT_COUNT, inst->spot_light_count, shader->version, instance_variant, spec_constants); if (inst->omni_light_count) { - glUniform1uiv(material_storage->shaders.scene_shader.version_get_uniform(SceneShaderGLES3::OMNI_LIGHT_INDICES, shader->version, instance_variant, base_spec_constants), inst->omni_light_count, inst->omni_light_gl_cache.ptr()); + glUniform1uiv(material_storage->shaders.scene_shader.version_get_uniform(SceneShaderGLES3::OMNI_LIGHT_INDICES, shader->version, instance_variant, spec_constants), inst->omni_light_count, inst->omni_light_gl_cache.ptr()); } if (inst->spot_light_count) { - glUniform1uiv(material_storage->shaders.scene_shader.version_get_uniform(SceneShaderGLES3::SPOT_LIGHT_INDICES, shader->version, instance_variant, base_spec_constants), inst->spot_light_count, inst->spot_light_gl_cache.ptr()); + glUniform1uiv(material_storage->shaders.scene_shader.version_get_uniform(SceneShaderGLES3::SPOT_LIGHT_INDICES, shader->version, instance_variant, spec_constants), inst->spot_light_count, inst->spot_light_gl_cache.ptr()); } prev_inst = inst; } - material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, world_transform, shader->version, instance_variant, base_spec_constants); + material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, world_transform, shader->version, instance_variant, spec_constants); if (inst->instance_count > 0) { // Using MultiMesh or Particles. // Bind instance buffers. diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index cd1f44e679c..255e62fc334 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -392,10 +392,10 @@ private: GeometryInstanceSurface **elements = nullptr; int element_count = 0; bool reverse_cull = false; - uint32_t spec_constant_base_flags = 0; + uint64_t spec_constant_base_flags = 0; bool force_wireframe = false; - RenderListParameters(GeometryInstanceSurface **p_elements, int p_element_count, bool p_reverse_cull, uint32_t p_spec_constant_base_flags, bool p_force_wireframe = false) { + RenderListParameters(GeometryInstanceSurface **p_elements, int p_element_count, bool p_reverse_cull, uint64_t p_spec_constant_base_flags, bool p_force_wireframe = false) { elements = p_elements; element_count = p_element_count; reverse_cull = p_reverse_cull; diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index a61ea1587d6..c1c26ed9639 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -41,8 +41,6 @@ layout(std140) uniform MaterialUniforms{ //ubo:4 #include "canvas_uniforms_inc.glsl" #include "stdlib_inc.glsl" -uniform sampler2D transforms_texture; //texunit:-1 - out vec2 uv_interp; out vec4 color_interp; out vec2 vertex_interp; diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 32557d33145..fa68f0063f2 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -779,7 +779,7 @@ float get_omni_attenuation(float distance, float inv_range, float decay) { nd *= nd; // nd^2 return nd * pow(max(distance, 0.0001), -decay); } - +#ifndef DISABLE_LIGHT_OMNI void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f0, float roughness, float metallic, float shadow, vec3 albedo, inout float alpha, #ifdef LIGHT_BACKLIGHT_USED vec3 backlight, @@ -821,7 +821,9 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f diffuse_light, specular_light); } +#endif // !DISABLE_LIGHT_OMNI +#ifndef DISABLE_LIGHT_SPOT void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f0, float roughness, float metallic, float shadow, vec3 albedo, inout float alpha, #ifdef LIGHT_BACKLIGHT_USED vec3 backlight, @@ -869,6 +871,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f #endif diffuse_light, specular_light); } +#endif // !DISABLE_LIGHT_SPOT #endif // !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) && !defined(DISABLE_LIGHT_SPOT) #ifndef MODE_RENDER_DEPTH