More optimizations on the mobile renderer.
* Specialization constants used to disable anything not needed to draw * Added softshadow and projector support on mobile. This new approach ensures mobile shaders are smaller and more efficient, but relies on more pipeline versions compiled on demand. As a result, random stalls can ocur like in Godot 3.x. These will be solved by using background compilation and fallbacks eventually (but needs to be tested first).
This commit is contained in:
parent
3a48474c49
commit
cfac8972e1
3 changed files with 139 additions and 46 deletions
|
@ -664,6 +664,23 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|||
|
||||
_pre_opaque_render(p_render_data, false, false, RID(), RID());
|
||||
|
||||
uint32_t spec_constant_base_flags = 0;
|
||||
|
||||
{
|
||||
//figure out spec constants
|
||||
|
||||
if (p_render_data->directional_light_count > 0) {
|
||||
if (p_render_data->directional_light_soft_shadows) {
|
||||
spec_constant_base_flags |= 1 << SPEC_CONSTANT_USING_DIRECTIONAL_SOFT_SHADOWS;
|
||||
}
|
||||
} else {
|
||||
spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_DIRECTIONAL_LIGHTS;
|
||||
}
|
||||
|
||||
if (!is_environment(p_render_data->environment) || environment_is_fog_enabled(p_render_data->environment)) {
|
||||
spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_FOG;
|
||||
}
|
||||
}
|
||||
{
|
||||
if (render_buffer) {
|
||||
RD::get_singleton()->draw_command_begin_label("Render 3D Pass");
|
||||
|
@ -706,7 +723,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|||
}
|
||||
|
||||
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer);
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, p_render_data->view_count);
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, p_render_data->view_count);
|
||||
render_list_params.framebuffer_format = fb_format;
|
||||
if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) {
|
||||
// secondary command buffers need more testing at this time
|
||||
|
@ -760,7 +777,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|||
|
||||
if (using_subpass_transparent) {
|
||||
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer);
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, p_render_data->view_count);
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, p_render_data->view_count);
|
||||
render_list_params.framebuffer_format = fb_format;
|
||||
if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) {
|
||||
// secondary command buffers need more testing at this time
|
||||
|
@ -797,7 +814,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|||
// _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false);
|
||||
|
||||
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer);
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, p_render_data->view_count);
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, p_render_data->view_count);
|
||||
render_list_params.framebuffer_format = fb_format;
|
||||
if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) {
|
||||
// secondary command buffers need more testing at this time
|
||||
|
@ -924,7 +941,7 @@ void RenderForwardMobile::_render_shadow_end(uint32_t p_barrier) {
|
|||
|
||||
for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) {
|
||||
SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i];
|
||||
RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_lod_threshold, 1, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER);
|
||||
RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, shadow_pass.rp_uniform_set, 0, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_lod_threshold, 1, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER);
|
||||
_render_list_with_threads(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, shadow_pass.final_depth_action, Vector<Color>(), 1.0, 0, shadow_pass.rect);
|
||||
}
|
||||
|
||||
|
@ -964,7 +981,7 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c
|
|||
RENDER_TIMESTAMP("Render Material");
|
||||
|
||||
{
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, rp_uniform_set);
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, rp_uniform_set, 0);
|
||||
//regular forward for now
|
||||
Vector<Color> clear;
|
||||
clear.push_back(Color(0, 0, 0, 0));
|
||||
|
@ -1005,7 +1022,7 @@ void RenderForwardMobile::_render_uv2(const PagedArray<GeometryInstance *> &p_in
|
|||
RENDER_TIMESTAMP("Render Material");
|
||||
|
||||
{
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, rp_uniform_set, true);
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, rp_uniform_set, true, 0);
|
||||
//regular forward for now
|
||||
Vector<Color> clear;
|
||||
clear.push_back(Color(0, 0, 0, 0));
|
||||
|
@ -1079,7 +1096,7 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const
|
|||
|
||||
{
|
||||
//regular forward for now
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), false, pass_mode, rp_uniform_set);
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), false, pass_mode, rp_uniform_set, 0);
|
||||
_render_list_with_threads(&render_list_params, p_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ);
|
||||
}
|
||||
RD::get_singleton()->draw_command_end_label();
|
||||
|
@ -1722,7 +1739,7 @@ void RenderForwardMobile::_render_list_with_threads(RenderListParameters *p_para
|
|||
}
|
||||
}
|
||||
|
||||
void RenderForwardMobile::_fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, const GeometryInstanceForwardMobile *p_instance) {
|
||||
void RenderForwardMobile::_fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, uint32_t &spec_constants, const GeometryInstanceForwardMobile *p_instance) {
|
||||
// first zero out our indices
|
||||
|
||||
p_push_constant->omni_lights[0] = 0xFFFF;
|
||||
|
@ -1737,6 +1754,19 @@ void RenderForwardMobile::_fill_push_constant_instance_indices(GeometryInstanceF
|
|||
p_push_constant->reflection_probes[0] = 0xFFFF;
|
||||
p_push_constant->reflection_probes[1] = 0xFFFF;
|
||||
|
||||
if (p_instance->omni_light_count == 0) {
|
||||
spec_constants |= 1 << SPEC_CONSTANT_DISABLE_OMNI_LIGHTS;
|
||||
}
|
||||
if (p_instance->spot_light_count == 0) {
|
||||
spec_constants |= 1 << SPEC_CONSTANT_DISABLE_SPOT_LIGHTS;
|
||||
}
|
||||
if (p_instance->reflection_probe_count == 0) {
|
||||
spec_constants |= 1 << SPEC_CONSTANT_DISABLE_REFLECTION_PROBES;
|
||||
}
|
||||
if (p_instance->decals_count == 0) {
|
||||
spec_constants |= 1 << SPEC_CONSTANT_DISABLE_DECALS;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < MAX_RDL_CULL; i++) {
|
||||
uint32_t ofs = i < 4 ? 0 : 1;
|
||||
uint32_t shift = (i & 0x3) << 3;
|
||||
|
@ -1784,6 +1814,8 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
|
|||
const RenderElementInfo &element_info = p_params->element_info[i];
|
||||
const GeometryInstanceForwardMobile *inst = surf->owner;
|
||||
|
||||
uint32_t base_spec_constants = p_params->spec_constant_base_flags;
|
||||
|
||||
// GeometryInstanceForwardMobile::PushConstant push_constant = inst->push_constant;
|
||||
GeometryInstanceForwardMobile::PushConstant push_constant;
|
||||
|
||||
|
@ -1819,7 +1851,13 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
|
|||
mesh_surface = surf->surface_shadow;
|
||||
|
||||
} else {
|
||||
_fill_push_constant_instance_indices(&push_constant, inst);
|
||||
if (inst->use_projector) {
|
||||
base_spec_constants |= 1 << SPEC_CONSTANT_USING_PROJECTOR;
|
||||
}
|
||||
if (inst->use_soft_shadow) {
|
||||
base_spec_constants |= 1 << SPEC_CONSTANT_USING_SOFT_SHADOWS;
|
||||
}
|
||||
_fill_push_constant_instance_indices(&push_constant, base_spec_constants, inst);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING)) {
|
||||
|
@ -1911,7 +1949,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
|
|||
prev_index_array_rd = index_array_rd;
|
||||
}
|
||||
|
||||
RID pipeline_rd = pipeline->get_render_pipeline(vertex_format, framebuffer_format, p_params->force_wireframe, p_params->subpass);
|
||||
RID pipeline_rd = pipeline->get_render_pipeline(vertex_format, framebuffer_format, p_params->force_wireframe, p_params->subpass, base_spec_constants);
|
||||
|
||||
if (pipeline_rd != prev_pipeline_rd) {
|
||||
// checking with prev shader does not make so much sense, as
|
||||
|
@ -2170,6 +2208,11 @@ void RenderForwardMobile::geometry_instance_pair_voxel_gi_instances(GeometryInst
|
|||
}
|
||||
|
||||
void RenderForwardMobile::geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) {
|
||||
GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance);
|
||||
ERR_FAIL_COND(!ginstance);
|
||||
|
||||
ginstance->use_projector = p_projector;
|
||||
ginstance->use_soft_shadow = p_softshadow;
|
||||
}
|
||||
|
||||
void RenderForwardMobile::_geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance) {
|
||||
|
@ -2548,12 +2591,12 @@ void RenderForwardMobile::_update_shader_quality_settings() {
|
|||
spec_constants.push_back(sc);
|
||||
|
||||
sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;
|
||||
sc.constant_id = SPEC_CONSTANT_DECAL_FILTER;
|
||||
sc.constant_id = SPEC_CONSTANT_DECAL_USE_MIPMAPS;
|
||||
sc.bool_value = decals_get_filter() == RS::DECAL_FILTER_NEAREST_MIPMAPS || decals_get_filter() == RS::DECAL_FILTER_LINEAR_MIPMAPS || decals_get_filter() == RS::DECAL_FILTER_LINEAR_MIPMAPS_ANISOTROPIC;
|
||||
|
||||
spec_constants.push_back(sc);
|
||||
|
||||
sc.constant_id = SPEC_CONSTANT_PROJECTOR_FILTER;
|
||||
sc.constant_id = SPEC_CONSTANT_PROJECTOR_USE_MIPMAPS;
|
||||
sc.bool_value = light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS || light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS || light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS_ANISOTROPIC;
|
||||
|
||||
spec_constants.push_back(sc);
|
||||
|
|
|
@ -65,12 +65,27 @@ protected:
|
|||
};
|
||||
|
||||
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_USING_PROJECTOR = 0,
|
||||
SPEC_CONSTANT_USING_SOFT_SHADOWS = 1,
|
||||
SPEC_CONSTANT_USING_DIRECTIONAL_SOFT_SHADOWS = 2,
|
||||
|
||||
SPEC_CONSTANT_SOFT_SHADOW_SAMPLES = 3,
|
||||
SPEC_CONSTANT_PENUMBRA_SHADOW_SAMPLES = 4,
|
||||
SPEC_CONSTANT_DIRECTIONAL_SOFT_SHADOW_SAMPLES = 5,
|
||||
SPEC_CONSTANT_DIRECTIONAL_PENUMBRA_SHADOW_SAMPLES = 6,
|
||||
|
||||
SPEC_CONSTANT_DECAL_USE_MIPMAPS = 7,
|
||||
SPEC_CONSTANT_PROJECTOR_USE_MIPMAPS = 8,
|
||||
|
||||
SPEC_CONSTANT_DISABLE_OMNI_LIGHTS = 9,
|
||||
SPEC_CONSTANT_DISABLE_SPOT_LIGHTS = 10,
|
||||
SPEC_CONSTANT_DISABLE_REFLECTION_PROBES = 11,
|
||||
SPEC_CONSTANT_DISABLE_DIRECTIONAL_LIGHTS = 12,
|
||||
|
||||
SPEC_CONSTANT_DISABLE_DECALS = 13,
|
||||
SPEC_CONSTANT_DISABLE_FOG = 14,
|
||||
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -159,6 +174,7 @@ protected:
|
|||
bool force_wireframe = false;
|
||||
Vector2 uv_offset;
|
||||
Plane lod_plane;
|
||||
uint32_t spec_constant_base_flags = 0;
|
||||
float lod_distance_multiplier = 0.0;
|
||||
float screen_lod_threshold = 0.0;
|
||||
RD::FramebufferFormatID framebuffer_format = 0;
|
||||
|
@ -166,7 +182,7 @@ protected:
|
|||
uint32_t barrier = RD::BARRIER_MASK_ALL;
|
||||
uint32_t subpass = 0;
|
||||
|
||||
RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) {
|
||||
RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, RID p_render_pass_uniform_set, uint32_t p_spec_constant_base_flags = 0, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) {
|
||||
elements = p_elements;
|
||||
element_info = p_element_info;
|
||||
element_count = p_element_count;
|
||||
|
@ -182,6 +198,7 @@ protected:
|
|||
screen_lod_threshold = p_screen_lod_threshold;
|
||||
element_offset = p_element_offset;
|
||||
barrier = p_barrier;
|
||||
spec_constant_base_flags = p_spec_constant_base_flags;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -526,6 +543,8 @@ protected:
|
|||
RID transforms_uniform_set;
|
||||
float depth = 0;
|
||||
bool mirror = false;
|
||||
bool use_projector = false;
|
||||
bool use_soft_shadow = false;
|
||||
Transform3D transform;
|
||||
bool store_transform_cache = true; // if true we copy our transform into our PushConstant, if false we use our transforms UBO and clear our PushConstants transform
|
||||
bool non_uniform_scale = false;
|
||||
|
@ -584,7 +603,7 @@ protected:
|
|||
dirty_list_element(this) {}
|
||||
};
|
||||
|
||||
_FORCE_INLINE_ void _fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, const GeometryInstanceForwardMobile *p_instance);
|
||||
_FORCE_INLINE_ void _fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, uint32_t &spec_constants, const GeometryInstanceForwardMobile *p_instance);
|
||||
|
||||
void _update_shader_quality_settings() override;
|
||||
|
||||
|
|
|
@ -373,26 +373,38 @@ void main() {
|
|||
//use medium precision for floats on mobile.
|
||||
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
/* Specialization Constants */
|
||||
|
||||
/* Specialization Constants (Toggles) */
|
||||
#if !defined(MODE_RENDER_DEPTH)
|
||||
|
||||
layout(constant_id = 0) const bool sc_use_forward_gi = false;
|
||||
layout(constant_id = 1) const bool sc_use_light_projector = false;
|
||||
layout(constant_id = 2) const bool sc_use_light_soft_shadows = false;
|
||||
layout(constant_id = 3) const bool sc_use_directional_soft_shadows = false;
|
||||
#if !defined(MODE_UNSHADED)
|
||||
|
||||
/* Specialization Constants (Values) */
|
||||
layout(constant_id = 0) const bool sc_use_light_projector = false;
|
||||
layout(constant_id = 1) const bool sc_use_light_soft_shadows = false;
|
||||
layout(constant_id = 2) const bool sc_use_directional_soft_shadows = false;
|
||||
|
||||
layout(constant_id = 6) const uint sc_soft_shadow_samples = 4;
|
||||
layout(constant_id = 7) const uint sc_penumbra_shadow_samples = 4;
|
||||
layout(constant_id = 3) const uint sc_soft_shadow_samples = 4;
|
||||
layout(constant_id = 4) const uint sc_penumbra_shadow_samples = 4;
|
||||
|
||||
layout(constant_id = 8) const uint sc_directional_soft_shadow_samples = 4;
|
||||
layout(constant_id = 9) const uint sc_directional_penumbra_shadow_samples = 4;
|
||||
layout(constant_id = 5) const uint sc_directional_soft_shadow_samples = 4;
|
||||
layout(constant_id = 6) const uint sc_directional_penumbra_shadow_samples = 4;
|
||||
|
||||
layout(constant_id = 10) const bool sc_decal_use_mipmaps = true;
|
||||
layout(constant_id = 11) const bool sc_projector_use_mipmaps = true;
|
||||
layout(constant_id = 8) const bool sc_projector_use_mipmaps = true;
|
||||
|
||||
layout(constant_id = 9) const bool sc_disable_omni_lights = false;
|
||||
layout(constant_id = 10) const bool sc_disable_spot_lights = false;
|
||||
layout(constant_id = 11) const bool sc_disable_reflection_probes = false;
|
||||
layout(constant_id = 12) const bool sc_disable_directional_lights = false;
|
||||
|
||||
#endif //!MODE_UNSHADED
|
||||
|
||||
layout(constant_id = 7) const bool sc_decal_use_mipmaps = true;
|
||||
layout(constant_id = 13) const bool sc_disable_decals = false;
|
||||
layout(constant_id = 14) const bool sc_disable_fog = false;
|
||||
|
||||
#endif //!MODE_RENDER_DEPTH
|
||||
|
||||
/* Include our forward mobile UBOs definitions etc. */
|
||||
#include "scene_forward_mobile_inc.glsl"
|
||||
|
@ -735,7 +747,7 @@ void main() {
|
|||
// to maximize VGPR usage
|
||||
// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
|
||||
|
||||
if (scene_data.fog_enabled) {
|
||||
if (!sc_disable_fog && scene_data.fog_enabled) {
|
||||
fog = fog_process(vertex);
|
||||
}
|
||||
|
||||
|
@ -753,7 +765,7 @@ void main() {
|
|||
vec3 vertex_ddx = dFdx(vertex);
|
||||
vec3 vertex_ddy = dFdy(vertex);
|
||||
|
||||
{ //Decals
|
||||
if (!sc_disable_decals) { //Decals
|
||||
// must implement
|
||||
|
||||
uint decal_indices = draw_call.decals.x;
|
||||
|
@ -774,25 +786,35 @@ void main() {
|
|||
continue; //out of decal
|
||||
}
|
||||
|
||||
//we need ddx/ddy for mipmaps, so simulate them
|
||||
vec2 ddx = (decals.data[decal_index].xform * vec4(vertex_ddx, 0.0)).xz;
|
||||
vec2 ddy = (decals.data[decal_index].xform * vec4(vertex_ddy, 0.0)).xz;
|
||||
|
||||
float fade = pow(1.0 - (uv_local.y > 0.0 ? uv_local.y : -uv_local.y), uv_local.y > 0.0 ? decals.data[decal_index].upper_fade : decals.data[decal_index].lower_fade);
|
||||
|
||||
if (decals.data[decal_index].normal_fade > 0.0) {
|
||||
fade *= smoothstep(decals.data[decal_index].normal_fade, 1.0, dot(normal_interp, decals.data[decal_index].normal) * 0.5 + 0.5);
|
||||
}
|
||||
|
||||
//we need ddx/ddy for mipmaps, so simulate them
|
||||
vec2 ddx = (decals.data[decal_index].xform * vec4(vertex_ddx, 0.0)).xz;
|
||||
vec2 ddy = (decals.data[decal_index].xform * vec4(vertex_ddy, 0.0)).xz;
|
||||
|
||||
if (decals.data[decal_index].albedo_rect != vec4(0.0)) {
|
||||
//has albedo
|
||||
vec4 decal_albedo = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, ddx * decals.data[decal_index].albedo_rect.zw, ddy * decals.data[decal_index].albedo_rect.zw);
|
||||
vec4 decal_albedo;
|
||||
if (sc_decal_use_mipmaps) {
|
||||
decal_albedo = textureGrad(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, ddx * decals.data[decal_index].albedo_rect.zw, ddy * decals.data[decal_index].albedo_rect.zw);
|
||||
} else {
|
||||
decal_albedo = textureLod(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, 0.0);
|
||||
}
|
||||
decal_albedo *= decals.data[decal_index].modulate;
|
||||
decal_albedo.a *= fade;
|
||||
albedo = mix(albedo, decal_albedo.rgb, decal_albedo.a * decals.data[decal_index].albedo_mix);
|
||||
|
||||
if (decals.data[decal_index].normal_rect != vec4(0.0)) {
|
||||
vec3 decal_normal = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz;
|
||||
vec3 decal_normal;
|
||||
if (sc_decal_use_mipmaps) {
|
||||
decal_normal = textureGrad(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz;
|
||||
} else {
|
||||
decal_normal = textureLod(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, 0.0).xyz;
|
||||
}
|
||||
decal_normal.xy = decal_normal.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); //users prefer flipped y normal maps in most authoring software
|
||||
decal_normal.z = sqrt(max(0.0, 1.0 - dot(decal_normal.xy, decal_normal.xy)));
|
||||
//convert to view space, use xzy because y is up
|
||||
|
@ -802,7 +824,12 @@ void main() {
|
|||
}
|
||||
|
||||
if (decals.data[decal_index].orm_rect != vec4(0.0)) {
|
||||
vec3 decal_orm = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz;
|
||||
vec3 decal_orm;
|
||||
if (sc_decal_use_mipmaps) {
|
||||
decal_orm = textureGrad(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz;
|
||||
} else {
|
||||
decal_orm = textureLod(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, 0.0).xyz;
|
||||
}
|
||||
ao = mix(ao, decal_orm.r, decal_albedo.a);
|
||||
roughness = mix(roughness, decal_orm.g, decal_albedo.a);
|
||||
metallic = mix(metallic, decal_orm.b, decal_albedo.a);
|
||||
|
@ -811,7 +838,11 @@ void main() {
|
|||
|
||||
if (decals.data[decal_index].emission_rect != vec4(0.0)) {
|
||||
//emission is additive, so its independent from albedo
|
||||
emission += textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, ddx * decals.data[decal_index].emission_rect.zw, ddy * decals.data[decal_index].emission_rect.zw).xyz * decals.data[decal_index].emission_energy * fade;
|
||||
if (sc_decal_use_mipmaps) {
|
||||
emission += textureGrad(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, ddx * decals.data[decal_index].emission_rect.zw, ddy * decals.data[decal_index].emission_rect.zw).xyz * decals.data[decal_index].emission_energy * fade;
|
||||
} else {
|
||||
emission += textureLod(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, 0.0).xyz * decals.data[decal_index].emission_energy * fade;
|
||||
}
|
||||
}
|
||||
}
|
||||
} //Decals
|
||||
|
@ -951,7 +982,7 @@ void main() {
|
|||
|
||||
// skipping ssao, do we remove ssao totally?
|
||||
|
||||
{ //Reflection probes
|
||||
if (!sc_disable_reflection_probes) { //Reflection probes
|
||||
vec4 reflection_accum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 ambient_accum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
|
@ -1017,7 +1048,7 @@ void main() {
|
|||
// LIGHTING
|
||||
#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
|
||||
|
||||
{ //directional light
|
||||
if (!sc_disable_directional_lights) { //directional light
|
||||
|
||||
// Do shadow and lighting in two passes to reduce register pressure
|
||||
uint shadow0 = 0;
|
||||
|
@ -1347,7 +1378,7 @@ void main() {
|
|||
}
|
||||
} //directional light
|
||||
|
||||
{ //omni lights
|
||||
if (!sc_disable_omni_lights) { //omni lights
|
||||
uint light_indices = draw_call.omni_lights.x;
|
||||
for (uint i = 0; i < 8; i++) {
|
||||
uint light_index = light_indices & 0xFF;
|
||||
|
@ -1394,7 +1425,7 @@ void main() {
|
|||
}
|
||||
} //omni lights
|
||||
|
||||
{ //spot lights
|
||||
if (!sc_disable_spot_lights) { //spot lights
|
||||
|
||||
uint light_indices = draw_call.spot_lights.x;
|
||||
for (uint i = 0; i < 8; i++) {
|
||||
|
|
Loading…
Reference in a new issue