summaryrefslogtreecommitdiff
path: root/drivers/gles3/rasterizer_scene_gles3.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles3/rasterizer_scene_gles3.cpp')
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp109
1 files changed, 77 insertions, 32 deletions
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 30a77c4b39..a492629dae 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -3,7 +3,7 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
-/* http://www.godotengine.org */
+/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
@@ -120,7 +120,7 @@ void RasterizerSceneGLES3::shadow_atlas_set_size(RID p_atlas, int p_size) {
ERR_FAIL_COND(!shadow_atlas);
ERR_FAIL_COND(p_size < 0);
- p_size = nearest_power_of_2(p_size);
+ p_size = next_power_of_2(p_size);
if (p_size == shadow_atlas->size)
return;
@@ -185,7 +185,7 @@ void RasterizerSceneGLES3::shadow_atlas_set_quadrant_subdivision(RID p_atlas, in
ERR_FAIL_INDEX(p_quadrant, 4);
ERR_FAIL_INDEX(p_subdivision, 16384);
- uint32_t subdiv = nearest_power_of_2(p_subdivision);
+ uint32_t subdiv = next_power_of_2(p_subdivision);
if (subdiv & 0xaaaaaaaa) { //sqrt(subdiv) must be integer
subdiv <<= 1;
}
@@ -310,7 +310,7 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in
}
uint32_t quad_size = shadow_atlas->size >> 1;
- int desired_fit = MIN(quad_size / shadow_atlas->smallest_subdiv, nearest_power_of_2(quad_size * p_coverage));
+ int desired_fit = MIN(quad_size / shadow_atlas->smallest_subdiv, next_power_of_2(quad_size * p_coverage));
int valid_quadrants[4];
int valid_quadrant_count = 0;
@@ -479,7 +479,7 @@ void RasterizerSceneGLES3::reflection_atlas_set_size(RID p_ref_atlas, int p_size
ReflectionAtlas *reflection_atlas = reflection_atlas_owner.getornull(p_ref_atlas);
ERR_FAIL_COND(!reflection_atlas);
- int size = nearest_power_of_2(p_size);
+ int size = next_power_of_2(p_size);
if (size == reflection_atlas->size)
return;
@@ -554,7 +554,7 @@ void RasterizerSceneGLES3::reflection_atlas_set_subdivision(RID p_ref_atlas, int
ReflectionAtlas *reflection_atlas = reflection_atlas_owner.getornull(p_ref_atlas);
ERR_FAIL_COND(!reflection_atlas);
- uint32_t subdiv = nearest_power_of_2(p_subdiv);
+ uint32_t subdiv = next_power_of_2(p_subdiv);
if (subdiv & 0xaaaaaaaa) { //sqrt(subdiv) must be integer
subdiv <<= 1;
}
@@ -1088,11 +1088,12 @@ void RasterizerSceneGLES3::gi_probe_instance_set_bounds(RID p_probe, const Vecto
bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_material, bool p_alpha_pass) {
+ /* this is handled outside
if (p_material->shader->spatial.cull_mode == RasterizerStorageGLES3::Shader::Spatial::CULL_MODE_DISABLED) {
glDisable(GL_CULL_FACE);
} else {
glEnable(GL_CULL_FACE);
- }
+ } */
if (state.current_line_width != p_material->line_width) {
//glLineWidth(MAX(p_material->line_width,1.0));
@@ -1857,12 +1858,21 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e, const Transform
}
}
-void RasterizerSceneGLES3::_set_cull(bool p_front, bool p_reverse_cull) {
+void RasterizerSceneGLES3::_set_cull(bool p_front, bool p_disabled, bool p_reverse_cull) {
bool front = p_front;
if (p_reverse_cull)
front = !front;
+ if (p_disabled != state.cull_disabled) {
+ if (p_disabled)
+ glDisable(GL_CULL_FACE);
+ else
+ glEnable(GL_CULL_FACE);
+
+ state.cull_disabled = p_disabled;
+ }
+
if (front != state.cull_front) {
glCullFace(front ? GL_FRONT : GL_BACK);
@@ -1900,7 +1910,9 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
}
state.cull_front = false;
+ state.cull_disabled = false;
glCullFace(GL_BACK);
+ glEnable(GL_CULL_FACE);
state.current_depth_test = true;
glEnable(GL_DEPTH_TEST);
@@ -2101,7 +2113,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
storage->info.render.surface_switch_count++;
}
- _set_cull(e->sort_key & RenderList::SORT_KEY_MIRROR_FLAG, p_reverse_cull);
+ _set_cull(e->sort_key & RenderList::SORT_KEY_MIRROR_FLAG, e->sort_key & RenderList::SORT_KEY_CULL_DISABLED_FLAG, p_reverse_cull);
state.scene_shader.set_uniform(SceneShaderGLES3::NORMAL_MULT, e->instance->mirror ? -1.0 : 1.0);
state.scene_shader.set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, e->instance->transform);
@@ -2174,44 +2186,51 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
while (m->next_pass.is_valid()) {
m = storage->material_owner.getornull(m->next_pass);
- if (!m)
+ if (!m || !m->shader || !m->shader->valid)
break;
_add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_shadow);
}
}
-void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *m, bool p_shadow) {
+void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_shadow) {
- bool has_base_alpha = (m->shader->spatial.uses_alpha && !m->shader->spatial.uses_alpha_scissor) || m->shader->spatial.uses_screen_texture || m->shader->spatial.unshaded;
- bool has_blend_alpha = m->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX || m->shader->spatial.ontop;
+ bool has_base_alpha = (p_material->shader->spatial.uses_alpha && !p_material->shader->spatial.uses_alpha_scissor) || p_material->shader->spatial.uses_screen_texture;
+ bool has_blend_alpha = p_material->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX || p_material->shader->spatial.ontop;
bool has_alpha = has_base_alpha || has_blend_alpha;
bool shadow = false;
bool mirror = p_instance->mirror;
+ bool no_cull = false;
- if (m->shader->spatial.cull_mode == RasterizerStorageGLES3::Shader::Spatial::CULL_MODE_FRONT) {
+ if (p_material->shader->spatial.cull_mode == RasterizerStorageGLES3::Shader::Spatial::CULL_MODE_DISABLED) {
+ no_cull = true;
+ mirror = false;
+ } else if (p_material->shader->spatial.cull_mode == RasterizerStorageGLES3::Shader::Spatial::CULL_MODE_FRONT) {
mirror = !mirror;
}
- if (m->shader->spatial.uses_sss) {
+ if (p_material->shader->spatial.uses_sss) {
state.used_sss = true;
}
- if (m->shader->spatial.uses_screen_texture) {
+ if (p_material->shader->spatial.uses_screen_texture) {
state.used_screen_texture = true;
}
if (p_shadow) {
- if (has_blend_alpha || (has_base_alpha && m->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS))
+ if (has_blend_alpha || (has_base_alpha && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS))
return; //bye
- if (!m->shader->spatial.uses_alpha_scissor && !m->shader->spatial.writes_modelview_or_projection && !m->shader->spatial.uses_vertex && !m->shader->spatial.uses_discard && m->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
+ if (!p_material->shader->spatial.uses_alpha_scissor && !p_material->shader->spatial.writes_modelview_or_projection && !p_material->shader->spatial.uses_vertex && !p_material->shader->spatial.uses_discard && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
//shader does not use discard and does not write a vertex position, use generic material
- if (p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED)
- m = storage->material_owner.getptr(default_material_twosided);
- else
- m = storage->material_owner.getptr(default_material);
+ if (p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED) {
+ p_material = storage->material_owner.getptr(default_material_twosided);
+ no_cull = true;
+ mirror = false;
+ } else {
+ p_material = storage->material_owner.getptr(default_material);
+ }
}
has_alpha = false;
@@ -2223,7 +2242,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
return;
e->geometry = p_geometry;
- e->material = m;
+ e->material = p_material;
e->instance = p_instance;
e->owner = p_owner;
e->sort_key = 0;
@@ -2250,7 +2269,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
e->sort_key |= uint64_t(e->material->index) << RenderList::SORT_KEY_MATERIAL_INDEX_SHIFT;
e->sort_key |= uint64_t(e->instance->depth_layer) << RenderList::SORT_KEY_DEPTH_LAYER_SHIFT;
- if (!has_blend_alpha && has_alpha && m->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
+ if (!has_blend_alpha && has_alpha && p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
//if nothing exists, add this element as opaque too
RenderList::Element *oe = render_list.add_element();
@@ -2275,17 +2294,31 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
e->sort_key |= RenderList::SORT_KEY_MIRROR_FLAG;
}
+ if (no_cull) {
+ e->sort_key |= RenderList::SORT_KEY_CULL_DISABLED_FLAG;
+ }
+
//e->light_type=0xFF; // no lights!
- if (shadow || m->shader->spatial.unshaded || state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
+ if (shadow || p_material->shader->spatial.unshaded || state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
e->sort_key |= SORT_KEY_UNSHADED_FLAG;
}
- if (!shadow && (m->shader->spatial.uses_vertex_lighting || storage->config.force_vertex_shading)) {
+ if (!shadow && (p_material->shader->spatial.uses_vertex_lighting || storage->config.force_vertex_shading)) {
e->sort_key |= SORT_KEY_VERTEX_LIT_FLAG;
}
+
+ if (!shadow && has_alpha && p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
+ //depth prepass for alpha
+ RenderList::Element *eo = render_list.add_element();
+
+ eo->instance = e->instance;
+ eo->geometry = e->geometry;
+ eo->material = e->material;
+ eo->sort_key = e->sort_key;
+ }
}
void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_scale, float p_energy) {
@@ -3226,6 +3259,8 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
state.ssao_blur_shader.set_uniform(SsaoBlurShaderGLES3::CAMERA_Z_NEAR, p_cam_projection.get_z_near());
GLint axis[2] = { i, 1 - i };
glUniform2iv(state.ssao_blur_shader.get_uniform(SsaoBlurShaderGLES3::AXIS), 1, axis);
+ glUniform2iv(state.ssao_blur_shader.get_uniform(SsaoBlurShaderGLES3::SCREEN_SIZE), 1, ss);
+
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.ssao.blur_red[i]);
glActiveTexture(GL_TEXTURE1);
@@ -3269,6 +3304,10 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
if (state.used_sss) { //sss enabled
//copy diffuse while performing sss
+ Plane p = p_cam_projection.xform4(Plane(1, 0, -1, 1));
+ p.normal /= p.d;
+ float unit_size = p.normal.x;
+
//copy normal and roughness to effect buffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
glReadBuffer(GL_COLOR_ATTACHMENT3);
@@ -3279,9 +3318,10 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_17_SAMPLES, subsurface_scatter_quality == SSS_QUALITY_MEDIUM);
state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_25_SAMPLES, subsurface_scatter_quality == SSS_QUALITY_HIGH);
state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::ENABLE_FOLLOW_SURFACE, subsurface_scatter_follow_surface);
+ state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::ENABLE_STRENGTH_WEIGHTING, subsurface_scatter_weight_samples);
state.sss_shader.bind();
state.sss_shader.set_uniform(SubsurfScatteringShaderGLES3::MAX_RADIUS, subsurface_scatter_size);
- state.sss_shader.set_uniform(SubsurfScatteringShaderGLES3::FOVY, p_cam_projection.get_fov());
+ state.sss_shader.set_uniform(SubsurfScatteringShaderGLES3::UNIT_SIZE, unit_size);
state.sss_shader.set_uniform(SubsurfScatteringShaderGLES3::CAMERA_Z_NEAR, p_cam_projection.get_z_near());
state.sss_shader.set_uniform(SubsurfScatteringShaderGLES3::CAMERA_Z_FAR, p_cam_projection.get_z_far());
state.sss_shader.set_uniform(SubsurfScatteringShaderGLES3::DIR, Vector2(1, 0));
@@ -3296,14 +3336,13 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.ssao.blur_red[0]);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->depth);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
+ //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); //copy to front first
_copy_screen(true);
glActiveTexture(GL_TEXTURE0);
-
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->color);
state.sss_shader.set_uniform(SubsurfScatteringShaderGLES3::DIR, Vector2(0, 1));
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo); // copy to base level
@@ -4406,9 +4445,10 @@ void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_
}
}
+ float bias_mult = Math::lerp(1.0f, light_instance->shadow_transform[p_pass].bias_scale, light->param[VS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE]);
zfar = light->param[VS::LIGHT_PARAM_RANGE];
- bias = light->param[VS::LIGHT_PARAM_SHADOW_BIAS] * light_instance->shadow_transform[p_pass].bias_scale;
- normal_bias = light->param[VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] * light_instance->shadow_transform[p_pass].bias_scale;
+ bias = light->param[VS::LIGHT_PARAM_SHADOW_BIAS] * bias_mult;
+ normal_bias = light->param[VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] * bias_mult;
fbo = directional_shadow.fbo;
vp_height = directional_shadow.size;
@@ -4535,6 +4575,9 @@ void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_
state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_DEPTH, true);
+ if (light->reverse_cull) {
+ flip_facing = !flip_facing;
+ }
_render_list(render_list.elements, render_list.element_count, light_transform, light_projection, 0, flip_facing, false, true, false, false);
state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_DEPTH, false);
@@ -4757,7 +4800,7 @@ void RasterizerSceneGLES3::initialize() {
{
//directional light shadow
directional_shadow.light_count = 0;
- directional_shadow.size = nearest_power_of_2(GLOBAL_GET("rendering/quality/directional_shadow/size"));
+ directional_shadow.size = next_power_of_2(GLOBAL_GET("rendering/quality/directional_shadow/size"));
glGenFramebuffers(1, &directional_shadow.fbo);
glBindFramebuffer(GL_FRAMEBUFFER, directional_shadow.fbo);
glGenTextures(1, &directional_shadow.depth);
@@ -4919,6 +4962,7 @@ void RasterizerSceneGLES3::initialize() {
GLOBAL_DEF("rendering/quality/subsurface_scattering/scale", 1.0);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/scale", PropertyInfo(Variant::INT, "rendering/quality/subsurface_scattering/scale", PROPERTY_HINT_RANGE, "0.01,8,0.01"));
GLOBAL_DEF("rendering/quality/subsurface_scattering/follow_surface", false);
+ GLOBAL_DEF("rendering/quality/subsurface_scattering/weight_samples", true);
GLOBAL_DEF("rendering/quality/voxel_cone_tracing/high_quality", true);
}
@@ -4961,6 +5005,7 @@ void RasterizerSceneGLES3::iteration() {
shadow_filter_mode = ShadowFilterMode(int(ProjectSettings::get_singleton()->get("rendering/quality/shadows/filter_mode")));
subsurface_scatter_follow_surface = ProjectSettings::get_singleton()->get("rendering/quality/subsurface_scattering/follow_surface");
+ subsurface_scatter_weight_samples = ProjectSettings::get_singleton()->get("rendering/quality/subsurface_scattering/weight_samples");
subsurface_scatter_quality = SubSurfaceScatterQuality(int(ProjectSettings::get_singleton()->get("rendering/quality/subsurface_scattering/quality")));
subsurface_scatter_size = ProjectSettings::get_singleton()->get("rendering/quality/subsurface_scattering/scale");