summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp222
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h65
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp277
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h6
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp6
-rw-r--r--drivers/gles3/shaders/copy.glsl35
-rw-r--r--drivers/gles3/shaders/scene.glsl107
-rw-r--r--drivers/gles3/shaders/tonemap.glsl32
-rw-r--r--drivers/png/resource_saver_png.cpp35
9 files changed, 544 insertions, 241 deletions
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 2b0f78e10f..7152b49d27 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -933,6 +933,49 @@ void RasterizerSceneGLES3::environment_set_tonemap(RID p_env, VS::EnvironmentTon
}
void RasterizerSceneGLES3::environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) {
+
+ Environment *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->adjustments_enabled = p_enable;
+ env->adjustments_brightness = p_brightness;
+ env->adjustments_contrast = p_contrast;
+ env->adjustments_saturation = p_saturation;
+ env->color_correction = p_ramp;
+}
+
+void RasterizerSceneGLES3::environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) {
+
+ Environment *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->fog_enabled = p_enable;
+ env->fog_color = p_color;
+ env->fog_sun_color = p_sun_color;
+ env->fog_sun_amount = p_sun_amount;
+}
+
+void RasterizerSceneGLES3::environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) {
+
+ Environment *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->fog_depth_enabled = p_enable;
+ env->fog_depth_begin = p_depth_begin;
+ env->fog_depth_curve = p_depth_curve;
+ env->fog_transmit_enabled = p_transmit;
+ env->fog_transmit_curve = p_transmit_curve;
+}
+
+void RasterizerSceneGLES3::environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) {
+
+ Environment *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->fog_height_enabled = p_enable;
+ env->fog_height_min = p_min_height;
+ env->fog_height_max = p_max_height;
+ env->fog_height_curve = p_height_curve;
}
RID RasterizerSceneGLES3::light_instance_create(RID p_light) {
@@ -1697,7 +1740,7 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e, const Transform
GIProbeInstance *gipi = gi_probe_instance_owner.getptr(ridp[0]);
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 10);
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 9);
glBindTexture(GL_TEXTURE_3D, gipi->tex_cache);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_XFORM1, gipi->transform_to_data * p_view_transform);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BOUNDS1, gipi->bounds);
@@ -1709,7 +1752,7 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e, const Transform
GIProbeInstance *gipi2 = gi_probe_instance_owner.getptr(ridp[1]);
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 11);
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 10);
glBindTexture(GL_TEXTURE_3D, gipi2->tex_cache);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_XFORM2, gipi2->transform_to_data * p_view_transform);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BOUNDS2, gipi2->bounds);
@@ -1740,19 +1783,10 @@ void RasterizerSceneGLES3::_set_cull(bool p_front, bool p_reverse_cull) {
void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_element_count, const Transform &p_view_transform, const CameraMatrix &p_projection, GLuint p_base_env, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add, bool p_directional_shadows) {
- if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) {
- //p_reverse_cull=!p_reverse_cull;
- glFrontFace(GL_CCW);
- } else {
- glFrontFace(GL_CW);
- }
-
glBindBufferBase(GL_UNIFORM_BUFFER, 0, state.scene_ubo); //bind globals ubo
if (!p_shadow && !p_directional_add) {
glBindBufferBase(GL_UNIFORM_BUFFER, 2, state.env_radiance_ubo); //bind environment radiance info
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
- glBindTexture(GL_TEXTURE_2D, state.brdf_texture);
if (p_base_env) {
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
@@ -1934,7 +1968,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
if (skeleton.is_valid()) {
RasterizerStorageGLES3::Skeleton *sk = storage->skeleton_owner.getornull(skeleton);
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 6);
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
glBindTexture(GL_TEXTURE_2D, sk->texture);
}
}
@@ -2023,7 +2057,7 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
ERR_FAIL_COND(!m);
- bool has_base_alpha = (m->shader->spatial.uses_alpha);
+ bool has_base_alpha = (m->shader->spatial.uses_alpha || m->shader->spatial.uses_screen_texture);
bool has_blend_alpha = m->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX || m->shader->spatial.ontop;
bool has_alpha = has_base_alpha || has_blend_alpha;
bool shadow = false;
@@ -2038,6 +2072,10 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
state.used_sss = true;
}
+ if (m->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))
@@ -2213,6 +2251,7 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
state.ubo_data.time[i] = storage->frame.time[i];
}
+ state.ubo_data.z_far = p_cam_projection.get_z_far();
//bg and ambient
if (env) {
state.ubo_data.bg_energy = env->bg_energy;
@@ -2244,6 +2283,30 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
state.env_radiance_data.ambient_contribution = env->ambient_sky_contribution;
state.ubo_data.ambient_occlusion_affect_light = env->ssao_light_affect;
+
+ //fog
+
+ Color linear_fog = env->fog_color.to_linear();
+ state.ubo_data.fog_color_enabled[0] = linear_fog.r;
+ state.ubo_data.fog_color_enabled[1] = linear_fog.g;
+ state.ubo_data.fog_color_enabled[2] = linear_fog.b;
+ state.ubo_data.fog_color_enabled[3] = env->fog_enabled ? 1.0 : 0.0;
+
+ Color linear_sun = env->fog_sun_color.to_linear();
+ state.ubo_data.fog_sun_color_amount[0] = linear_sun.r;
+ state.ubo_data.fog_sun_color_amount[1] = linear_sun.g;
+ state.ubo_data.fog_sun_color_amount[2] = linear_sun.b;
+ state.ubo_data.fog_sun_color_amount[3] = env->fog_sun_amount;
+ state.ubo_data.fog_depth_enabled = env->fog_depth_enabled;
+ state.ubo_data.fog_depth_begin = env->fog_depth_begin;
+ state.ubo_data.fog_depth_curve = env->fog_depth_curve;
+ state.ubo_data.fog_transmit_enabled = env->fog_transmit_enabled;
+ state.ubo_data.fog_transmit_curve = env->fog_transmit_curve;
+ state.ubo_data.fog_height_enabled = env->fog_height_enabled;
+ state.ubo_data.fog_height_min = env->fog_height_min;
+ state.ubo_data.fog_height_max = env->fog_height_max;
+ state.ubo_data.fog_height_curve = env->fog_height_curve;
+
} else {
state.ubo_data.bg_energy = 1.0;
state.ubo_data.ambient_energy = 1.0;
@@ -2261,6 +2324,8 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
state.env_radiance_data.ambient_contribution = 0;
state.ubo_data.ambient_occlusion_affect_light = 0;
+
+ state.ubo_data.fog_color_enabled[3] = 0.0;
}
{
@@ -2797,6 +2862,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
current_geometry_index = 0;
current_material_index = 0;
state.used_sss = false;
+ state.used_screen_texture = false;
//fill list
@@ -2874,6 +2940,39 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
}
}
+void RasterizerSceneGLES3::_blur_effect_buffer() {
+
+ //blur diffuse into effect mipmaps using separatable convolution
+ //storage->shaders.copy.set_conditional(CopyShaderGLES3::GAUSSIAN_HORIZONTAL,true);
+ for (int i = 0; i < storage->frame.current_rt->effects.mip_maps[1].sizes.size(); i++) {
+
+ int vp_w = storage->frame.current_rt->effects.mip_maps[1].sizes[i].width;
+ int vp_h = storage->frame.current_rt->effects.mip_maps[1].sizes[i].height;
+ glViewport(0, 0, vp_w, vp_h);
+ //horizontal pass
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_HORIZONTAL, true);
+ state.effect_blur_shader.bind();
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::PIXEL_SIZE, Vector2(1.0 / vp_w, 1.0 / vp_h));
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD, float(i));
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color); //previous level, since mipmaps[0] starts one level bigger
+ glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[1].sizes[i].fbo);
+ _copy_screen();
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_HORIZONTAL, false);
+
+ //vertical pass
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_VERTICAL, true);
+ state.effect_blur_shader.bind();
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::PIXEL_SIZE, Vector2(1.0 / vp_w, 1.0 / vp_h));
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD, float(i));
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[1].color);
+ glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[i + 1].fbo); //next level, since mipmaps[0] starts one level bigger
+ _copy_screen();
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_VERTICAL, false);
+ }
+}
+
void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_cam_projection) {
glDepthMask(GL_FALSE);
@@ -3080,33 +3179,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
//blur diffuse into effect mipmaps using separatable convolution
//storage->shaders.copy.set_conditional(CopyShaderGLES3::GAUSSIAN_HORIZONTAL,true);
- for (int i = 0; i < storage->frame.current_rt->effects.mip_maps[1].sizes.size(); i++) {
-
- int vp_w = storage->frame.current_rt->effects.mip_maps[1].sizes[i].width;
- int vp_h = storage->frame.current_rt->effects.mip_maps[1].sizes[i].height;
- glViewport(0, 0, vp_w, vp_h);
- //horizontal pass
- state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_HORIZONTAL, true);
- state.effect_blur_shader.bind();
- state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::PIXEL_SIZE, Vector2(1.0 / vp_w, 1.0 / vp_h));
- state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD, float(i));
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color); //previous level, since mipmaps[0] starts one level bigger
- glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[1].sizes[i].fbo);
- _copy_screen();
- state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_HORIZONTAL, false);
-
- //vertical pass
- state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_VERTICAL, true);
- state.effect_blur_shader.bind();
- state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::PIXEL_SIZE, Vector2(1.0 / vp_w, 1.0 / vp_h));
- state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD, float(i));
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[1].color);
- glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[i + 1].fbo); //next level, since mipmaps[0] starts one level bigger
- _copy_screen();
- state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_VERTICAL, false);
- }
+ _blur_effect_buffer();
//perform SSR
@@ -3177,6 +3250,13 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
glDisable(GL_BLEND); //end additive
+ if (state.used_screen_texture) {
+ _blur_effect_buffer();
+ //restored framebuffer
+ glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo);
+ glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
+ }
+
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::SIMPLE_COPY, true);
state.effect_blur_shader.bind();
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD, float(0));
@@ -3219,19 +3299,21 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
- if (!env) {
- //no environment, simply return and convert to SRGB
+ if (!env || storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
+ //no environment or transparent render, simply return and convert to SRGB
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color);
storage->shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB, true);
- storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, true);
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::V_FLIP, storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]);
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]);
storage->shaders.copy.bind();
_copy_screen();
storage->shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB, false);
storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, false); //compute luminance
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::V_FLIP, false);
return;
}
@@ -3594,6 +3676,18 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color);
}
+ if (env->adjustments_enabled) {
+
+ state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_BCS, true);
+ RasterizerStorageGLES3::Texture *tex = storage->texture_owner.getornull(env->color_correction);
+ if (tex) {
+ state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_COLOR_CORRECTION, true);
+ glActiveTexture(GL_TEXTURE3);
+ glBindTexture(tex->target, tex->tex_id);
+ }
+ }
+
+ state.tonemap_shader.set_conditional(TonemapShaderGLES3::V_FLIP, storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]);
state.tonemap_shader.bind();
state.tonemap_shader.set_uniform(TonemapShaderGLES3::EXPOSURE, env->tone_mapper_exposure);
@@ -3616,6 +3710,11 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
state.tonemap_shader.set_uniform(TonemapShaderGLES3::AUTO_EXPOSURE_GREY, env->auto_exposure_grey);
}
+ if (env->adjustments_enabled) {
+
+ state.tonemap_shader.set_uniform(TonemapShaderGLES3::BCS, Vector3(env->adjustments_brightness, env->adjustments_contrast, env->adjustments_saturation));
+ }
+
_copy_screen();
//turn off everything used
@@ -3634,6 +3733,9 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_SCREEN, false);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_SOFTLIGHT, false);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_FILTER_BICUBIC, false);
+ state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_BCS, false);
+ state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_COLOR_CORRECTION, false);
+ state.tonemap_shader.set_conditional(TonemapShaderGLES3::V_FLIP, false);
}
void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
@@ -3648,7 +3750,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
ReflectionAtlas *reflection_atlas = reflection_atlas_owner.getornull(p_reflection_atlas);
if (shadow_atlas && shadow_atlas->size) {
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 5);
glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
@@ -3657,7 +3759,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
}
if (reflection_atlas && reflection_atlas->size) {
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 5);
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
glBindTexture(GL_TEXTURE_2D, reflection_atlas->color);
}
@@ -3721,7 +3823,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
//bind depth for read
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 9);
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 8);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->depth);
}
@@ -3774,7 +3876,10 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
} else {
- use_mrt = env && (state.used_sss || env->ssao_enabled || env->ssr_enabled); //only enable MRT rendering if any of these is enabled
+ use_mrt = env && (state.used_screen_texture || state.used_sss || env->ssao_enabled || env->ssr_enabled); //only enable MRT rendering if any of these is enabled
+ //effects disabled and transparency also prevent using MRTs
+ use_mrt = use_mrt && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT];
+ use_mrt = use_mrt && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS];
glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
@@ -3823,7 +3928,9 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
RasterizerStorageGLES3::Sky *sky = NULL;
GLuint env_radiance_tex = 0;
- if (!env || env->bg_mode == VS::ENV_BG_CLEAR_COLOR) {
+ if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
+ clear_color = Color(0, 0, 0, 0);
+ } else if (!env || env->bg_mode == VS::ENV_BG_CLEAR_COLOR) {
if (storage->frame.clear_request) {
@@ -3856,20 +3963,14 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
} else {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glDisable(GL_BLEND);
}
- glDisable(GL_BLEND);
-
render_list.sort_by_key(false);
- if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- } else {
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
-
if (state.directional_light_count == 0) {
directional_light = NULL;
_render_list(render_list.elements, render_list.element_count, p_cam_transform, p_cam_projection, env_radiance_tex, false, false, false, false, shadow_atlas != NULL);
@@ -3891,14 +3992,14 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
glDrawBuffers(1, &gldb);
}
- if (env && env->bg_mode == VS::ENV_BG_SKY) {
+ if (env && env->bg_mode == VS::ENV_BG_SKY && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
/*
if (use_mrt) {
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.fbo); //switch to alpha fbo for sky, only diffuse/ambient matters
*/
- _draw_sky(sky, p_cam_projection, p_cam_transform, storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP], env->sky_scale, env->bg_energy);
+ _draw_sky(sky, p_cam_projection, p_cam_transform, false, env->sky_scale, env->bg_energy);
}
//_render_list_forward(&alpha_render_list,camera_transform,camera_transform_inverse,camera_projection,false,fragment_lighting,true);
@@ -3910,6 +4011,11 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
_render_mrts(env, p_cam_projection);
}
+ if (state.used_screen_texture) {
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 7);
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color);
+ }
+
glEnable(GL_BLEND);
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 322343bc89..55d314a800 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -111,6 +111,9 @@ public:
float time[4];
float ambient_light_color[4];
float bg_color[4];
+ float fog_color_enabled[4];
+ float fog_sun_color_amount[4];
+
float ambient_energy;
float bg_energy;
float shadow_z_offset;
@@ -120,10 +123,22 @@ public:
float screen_pixel_size[2];
float shadow_atlas_pixel_size[2];
float shadow_directional_pixel_size[2];
+
+ float z_far;
float reflection_multiplier;
float subsurface_scatter_width;
float ambient_occlusion_affect_light;
+ bool fog_depth_enabled;
+ float fog_depth_begin;
+ float fog_depth_curve;
+ bool fog_transmit_enabled;
+ float fog_transmit_curve;
+ bool fog_height_enabled;
+ float fog_height_min;
+ float fog_height_max;
+ float fog_height_curve;
+
} ubo_data;
GLuint scene_ubo;
@@ -170,6 +185,7 @@ public:
bool cull_front;
bool used_sss;
+ bool used_screen_texture;
} state;
@@ -389,6 +405,27 @@ public:
float dof_blur_near_amount;
VS::EnvironmentDOFBlurQuality dof_blur_near_quality;
+ bool adjustments_enabled;
+ float adjustments_brightness;
+ float adjustments_contrast;
+ float adjustments_saturation;
+ RID color_correction;
+
+ bool fog_enabled;
+ Color fog_color;
+ Color fog_sun_color;
+ float fog_sun_amount;
+
+ bool fog_depth_enabled;
+ float fog_depth_begin;
+ float fog_depth_curve;
+ bool fog_transmit_enabled;
+ float fog_transmit_curve;
+ bool fog_height_enabled;
+ float fog_height_min;
+ float fog_height_max;
+ float fog_height_curve;
+
Environment() {
bg_mode = VS::ENV_BG_CLEAR_COLOR;
sky_scale = 1.0;
@@ -445,6 +482,29 @@ public:
dof_blur_near_transition = 1;
dof_blur_near_amount = 0.1;
dof_blur_near_quality = VS::ENV_DOF_BLUR_QUALITY_MEDIUM;
+
+ adjustments_enabled = false;
+ adjustments_brightness = 1.0;
+ adjustments_contrast = 1.0;
+ adjustments_saturation = 1.0;
+
+ fog_enabled = false;
+ fog_color = Color(0.5, 0.5, 0.5);
+ fog_sun_color = Color(0.8, 0.8, 0.0);
+ fog_sun_amount = 0;
+
+ fog_depth_enabled = true;
+
+ fog_depth_begin = 10;
+ fog_depth_curve = 1;
+
+ fog_transmit_enabled = true;
+ fog_transmit_curve = 1;
+
+ fog_height_enabled = false;
+ fog_height_min = 0;
+ fog_height_max = 100;
+ fog_height_curve = 1;
}
};
@@ -472,6 +532,10 @@ public:
virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp);
+ virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount);
+ virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve);
+ virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve);
+
/* LIGHT INSTANCE */
struct LightDataUBO {
@@ -711,6 +775,7 @@ public:
void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_shadow);
+ void _blur_effect_buffer();
void _render_mrts(Environment *env, const CameraMatrix &p_cam_projection);
void _post_process(Environment *env, const CameraMatrix &p_cam_projection);
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 7ac82a9eca..c6e18944e7 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -782,7 +782,6 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p
int bh = h;
glCompressedTexImage2D(blit_target, i, internal_format, bw, bh, 0, size, &read[ofs]);
- print_line("format: " + Image::get_format_name(texture->format) + " size: " + Vector2(bw, bh) + " block: " + itos(block));
} else {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -825,8 +824,7 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, VS::CubeMapSi
ERR_FAIL_COND_V(!texture, Ref<Image>());
ERR_FAIL_COND_V(!texture->active, Ref<Image>());
- ERR_FAIL_COND_V(texture->data_size == 0, Ref<Image>());
- ERR_FAIL_COND_V(texture->render_target, Ref<Image>());
+ ERR_FAIL_COND_V(texture->data_size == 0 && !texture->render_target, Ref<Image>());
if (!texture->images[p_cube_side].is_null()) {
return texture->images[p_cube_side];
@@ -1463,6 +1461,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
p_shader->spatial.unshaded = false;
p_shader->spatial.ontop = false;
p_shader->spatial.uses_sss = false;
+ p_shader->spatial.uses_screen_texture = false;
p_shader->spatial.uses_vertex = false;
p_shader->spatial.writes_modelview_or_projection = false;
@@ -1488,6 +1487,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
shaders.actions_scene.usage_flag_pointers["SSS_STRENGTH"] = &p_shader->spatial.uses_sss;
shaders.actions_scene.usage_flag_pointers["DISCARD"] = &p_shader->spatial.uses_discard;
+ shaders.actions_scene.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->spatial.uses_screen_texture;
shaders.actions_scene.write_flag_pointers["MODELVIEW_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
shaders.actions_scene.write_flag_pointers["PROJECTION_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
@@ -5491,6 +5491,7 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
tex->alloc_width = 0;
tex->width = 0;
tex->height = 0;
+ tex->active = false;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < rt->effects.mip_maps[i].sizes.size(); j++) {
@@ -5587,13 +5588,14 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
tex->alloc_width = rt->width;
tex->height = rt->height;
tex->alloc_height = rt->height;
+ tex->active = true;
texture_set_flags(rt->texture, tex->flags);
}
/* BACK FBO */
- if (config.render_arch == RENDER_ARCH_DESKTOP && !rt->flags[RENDER_TARGET_NO_3D]) {
+ if (!rt->flags[RENDER_TARGET_NO_3D]) {
static const int msaa_value[] = { 0, 2, 4, 8, 16 };
int msaa = msaa_value[rt->msaa];
@@ -5621,75 +5623,155 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rt->buffers.diffuse);
- glGenRenderbuffers(1, &rt->buffers.specular);
- glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.specular);
+ if (!rt->flags[RENDER_TARGET_NO_3D_EFFECTS]) {
- if (msaa == 0)
- glRenderbufferStorage(GL_RENDERBUFFER, color_internal_format, rt->width, rt->height);
- else
- glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, color_internal_format, rt->width, rt->height);
+ glGenRenderbuffers(1, &rt->buffers.specular);
+ glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.specular);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rt->buffers.specular);
+ if (msaa == 0)
+ glRenderbufferStorage(GL_RENDERBUFFER, color_internal_format, rt->width, rt->height);
+ else
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, color_internal_format, rt->width, rt->height);
- glGenRenderbuffers(1, &rt->buffers.normal_rough);
- glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.normal_rough);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rt->buffers.specular);
- if (msaa == 0)
- glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, rt->width, rt->height);
- else
- glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_RGBA8, rt->width, rt->height);
+ glGenRenderbuffers(1, &rt->buffers.normal_rough);
+ glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.normal_rough);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, rt->buffers.normal_rough);
+ if (msaa == 0)
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, rt->width, rt->height);
+ else
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_RGBA8, rt->width, rt->height);
- glGenRenderbuffers(1, &rt->buffers.sss);
- glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.sss);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, rt->buffers.normal_rough);
- if (msaa == 0)
- glRenderbufferStorage(GL_RENDERBUFFER, GL_R8, rt->width, rt->height);
- else
- glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_R8, rt->width, rt->height);
+ glGenRenderbuffers(1, &rt->buffers.sss);
+ glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.sss);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_RENDERBUFFER, rt->buffers.sss);
+ if (msaa == 0)
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_R8, rt->width, rt->height);
+ else
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_R8, rt->width, rt->height);
- GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
- glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_RENDERBUFFER, rt->buffers.sss);
- if (status != GL_FRAMEBUFFER_COMPLETE) {
- printf("err status: %x\n", status);
- _render_target_clear(rt);
- ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
- }
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
- glBindRenderbuffer(GL_RENDERBUFFER, 0);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ printf("err status: %x\n", status);
+ _render_target_clear(rt);
+ ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
+ }
- // effect resolver
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
- glGenFramebuffers(1, &rt->buffers.effect_fbo);
- glBindFramebuffer(GL_FRAMEBUFFER, rt->buffers.effect_fbo);
+ // effect resolver
- glGenTextures(1, &rt->buffers.effect);
- glBindTexture(GL_TEXTURE_2D, rt->buffers.effect);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rt->width, rt->height, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D, rt->buffers.effect, 0);
+ glGenFramebuffers(1, &rt->buffers.effect_fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, rt->buffers.effect_fbo);
- if (status != GL_FRAMEBUFFER_COMPLETE) {
- printf("err status: %x\n", status);
- _render_target_clear(rt);
- ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
- }
+ glGenTextures(1, &rt->buffers.effect);
+ glBindTexture(GL_TEXTURE_2D, rt->buffers.effect);
+ glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0,
+ color_format, color_type, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, rt->buffers.effect, 0);
- glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ printf("err status: %x\n", status);
+ _render_target_clear(rt);
+ ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
+ }
- if (status != GL_FRAMEBUFFER_COMPLETE) {
- _render_target_clear(rt);
- ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
+ glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
+
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ _render_target_clear(rt);
+ ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
+ }
+
+ ///////////////// ssao
+
+ //AO strength textures
+ for (int i = 0; i < 2; i++) {
+
+ glGenFramebuffers(1, &rt->effects.ssao.blur_fbo[i]);
+ glBindFramebuffer(GL_FRAMEBUFFER, rt->effects.ssao.blur_fbo[i]);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_TEXTURE_2D, rt->depth, 0);
+
+ glGenTextures(1, &rt->effects.ssao.blur_red[i]);
+ glBindTexture(GL_TEXTURE_2D, rt->effects.ssao.blur_red[i]);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, rt->width, rt->height, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->effects.ssao.blur_red[i], 0);
+
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ _render_target_clear(rt);
+ ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
+ }
+ }
+ //5 mip levels for depth texture, but base is read separately
+
+ glGenTextures(1, &rt->effects.ssao.linear_depth);
+ glBindTexture(GL_TEXTURE_2D, rt->effects.ssao.linear_depth);
+
+ int ssao_w = rt->width / 2;
+ int ssao_h = rt->height / 2;
+
+ for (int i = 0; i < 4; i++) { //5, but 4 mips, base is read directly to save bw
+
+ glTexImage2D(GL_TEXTURE_2D, i, GL_R16UI, ssao_w, ssao_h, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, NULL);
+ ssao_w >>= 1;
+ ssao_h >>= 1;
+ }
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3);
+
+ for (int i = 0; i < 4; i++) { //5, but 4 mips, base is read directly to save bw
+
+ GLuint fbo;
+ glGenFramebuffers(1, &fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->effects.ssao.linear_depth, i);
+ rt->effects.ssao.depth_mipmap_fbos.push_back(fbo);
+ }
+
+ //////Exposure
+
+ glGenFramebuffers(1, &rt->exposure.fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, rt->exposure.fbo);
+
+ glGenTextures(1, &rt->exposure.color);
+ glBindTexture(GL_TEXTURE_2D, rt->exposure.color);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 1, 1, 0, GL_RED, GL_FLOAT, NULL);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->exposure.color, 0);
+
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ _render_target_clear(rt);
+ ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
+ }
}
+ }
+
+ if (!rt->flags[RENDER_TARGET_NO_SAMPLING]) {
for (int i = 0; i < 2; i++) {
@@ -5736,7 +5818,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
glBindFramebuffer(GL_FRAMEBUFFER, mm.fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->effects.mip_maps[i].color, j);
- status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
_render_target_clear(rt);
ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
@@ -5756,79 +5838,6 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
- ///////////////// ssao
-
- //AO strength textures
- for (int i = 0; i < 2; i++) {
-
- glGenFramebuffers(1, &rt->effects.ssao.blur_fbo[i]);
- glBindFramebuffer(GL_FRAMEBUFFER, rt->effects.ssao.blur_fbo[i]);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
- GL_TEXTURE_2D, rt->depth, 0);
-
- glGenTextures(1, &rt->effects.ssao.blur_red[i]);
- glBindTexture(GL_TEXTURE_2D, rt->effects.ssao.blur_red[i]);
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, rt->width, rt->height, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->effects.ssao.blur_red[i], 0);
-
- status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
- if (status != GL_FRAMEBUFFER_COMPLETE) {
- _render_target_clear(rt);
- ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
- }
- }
- //5 mip levels for depth texture, but base is read separately
-
- glGenTextures(1, &rt->effects.ssao.linear_depth);
- glBindTexture(GL_TEXTURE_2D, rt->effects.ssao.linear_depth);
-
- int ssao_w = rt->width / 2;
- int ssao_h = rt->height / 2;
-
- for (int i = 0; i < 4; i++) { //5, but 4 mips, base is read directly to save bw
-
- glTexImage2D(GL_TEXTURE_2D, i, GL_R16UI, ssao_w, ssao_h, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, NULL);
- ssao_w >>= 1;
- ssao_h >>= 1;
- }
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3);
-
- for (int i = 0; i < 4; i++) { //5, but 4 mips, base is read directly to save bw
-
- GLuint fbo;
- glGenFramebuffers(1, &fbo);
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->effects.ssao.linear_depth, i);
- rt->effects.ssao.depth_mipmap_fbos.push_back(fbo);
- }
-
- //////Exposure
-
- glGenFramebuffers(1, &rt->exposure.fbo);
- glBindFramebuffer(GL_FRAMEBUFFER, rt->exposure.fbo);
-
- glGenTextures(1, &rt->exposure.color);
- glBindTexture(GL_TEXTURE_2D, rt->exposure.color);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 1, 1, 0, GL_RED, GL_FLOAT, NULL);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->exposure.color, 0);
-
- status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
- if (status != GL_FRAMEBUFFER_COMPLETE) {
- _render_target_clear(rt);
- ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
- }
}
}
@@ -5853,9 +5862,10 @@ RID RasterizerStorageGLES3::render_target_create() {
t->srgb = false;
t->total_data_size = 0;
t->ignore_mipmaps = false;
- t->mipmaps = 0;
+ t->mipmaps = 1;
t->active = true;
t->tex_id = 0;
+ t->render_target = rt;
rt->texture = texture_owner.make_rid(t);
@@ -5892,8 +5902,10 @@ void RasterizerStorageGLES3::render_target_set_flag(RID p_render_target, RenderT
rt->flags[p_flag] = p_value;
switch (p_flag) {
+ case RENDER_TARGET_HDR:
case RENDER_TARGET_NO_3D:
- case RENDER_TARGET_TRANSPARENT: {
+ case RENDER_TARGET_NO_SAMPLING:
+ case RENDER_TARGET_NO_3D_EFFECTS: {
//must reset for these formats
_render_target_clear(rt);
_render_target_allocate(rt);
@@ -6335,9 +6347,6 @@ bool RasterizerStorageGLES3::has_os_feature(const String &p_feature) const {
void RasterizerStorageGLES3::initialize() {
- config.render_arch = RENDER_ARCH_DESKTOP;
- //config.fbo_deferred=int(Globals::get_singleton()->get("rendering/gles3/lighting_technique"));
-
RasterizerStorageGLES3::system_fbo = 0;
//// extensions config
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 1572d4358e..9af342301c 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -61,8 +61,6 @@ public:
struct Config {
- RenderArchitecture render_arch;
-
bool shrink_textures_x2;
bool use_fast_texture_filter;
bool use_anisotropic_filter;
@@ -411,6 +409,7 @@ public:
bool uses_vertex;
bool uses_discard;
bool uses_sss;
+ bool uses_screen_texture;
bool writes_modelview_or_projection;
} spatial;
@@ -1208,9 +1207,10 @@ public:
flags[RENDER_TARGET_VFLIP] = false;
flags[RENDER_TARGET_TRANSPARENT] = false;
+ flags[RENDER_TARGET_NO_3D_EFFECTS] = false;
flags[RENDER_TARGET_NO_3D] = false;
- flags[RENDER_TARGET_HDR] = true;
flags[RENDER_TARGET_NO_SAMPLING] = false;
+ flags[RENDER_TARGET_HDR] = true;
last_exposure_tick = 0;
}
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index 5ad2ae7362..b1f7b4c9bd 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -745,6 +745,10 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
//actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"]=ShaderLanguage::TYPE_VEC2;
actions[VS::SHADER_SPATIAL].renames["POINT_COORD"] = "gl_PointCoord";
actions[VS::SHADER_SPATIAL].renames["INSTANCE_CUSTOM"] = "instance_custom";
+ actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"] = "screen_uv";
+ actions[VS::SHADER_SPATIAL].renames["SCREEN_TEXTURE"] = "screen_texture";
+ actions[VS::SHADER_SPATIAL].renames["DEPTH_TEXTURE"] = "depth_buffer";
+ actions[VS::SHADER_SPATIAL].renames["SIDE"] = "side";
actions[VS::SHADER_SPATIAL].usage_defines["TANGENT"] = "#define ENABLE_TANGENT_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["BINORMAL"] = "@TANGENT";
@@ -763,6 +767,8 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n";
actions[VS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n";
actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength";
diff --git a/drivers/gles3/shaders/copy.glsl b/drivers/gles3/shaders/copy.glsl
index c8985e6902..4c8648903e 100644
--- a/drivers/gles3/shaders/copy.glsl
+++ b/drivers/gles3/shaders/copy.glsl
@@ -23,6 +23,10 @@ void main() {
cube_interp = cube_in;
#else
uv_interp = uv_in;
+#ifdef V_FLIP
+ uv_interp.y = 1.0-uv_interp.y;
+#endif
+
#endif
uv2_interp = uv2_in;
gl_Position = vertex_attrib;
@@ -84,8 +88,24 @@ uniform vec2 pixel_size;
in vec2 uv2_interp;
+
+#ifdef USE_BCS
+
+uniform vec3 bcs;
+
+#endif
+
+#ifdef USE_COLOR_CORRECTION
+
+uniform sampler2D color_correction; //texunit:1
+
+#endif
+
layout(location = 0) out vec4 frag_color;
+
+
+
void main() {
//vec4 color = color_interp;
@@ -135,6 +155,21 @@ void main() {
color+=texture( source, uv_interp+vec2( 0.0,-2.0)*pixel_size )*0.06136;
#endif
+#ifdef USE_BCS
+
+ color.rgb = mix(vec3(0.0),color.rgb,bcs.x);
+ color.rgb = mix(vec3(0.5),color.rgb,bcs.y);
+ color.rgb = mix(vec3(dot(vec3(1.0),color.rgb)*0.33333),color.rgb,bcs.z);
+
+#endif
+
+#ifdef USE_COLOR_CORRECTION
+
+ color.r = texture(color_correction,vec2(color.r,0.0)).r;
+ color.g = texture(color_correction,vec2(color.g,0.0)).g;
+ color.b = texture(color_correction,vec2(color.b,0.0)).b;
+#endif
+
#ifdef USE_MULTIPLIER
color.rgb*=multiplier;
#endif
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 29a7135eed..60efc953f9 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -67,6 +67,10 @@ layout(std140) uniform SceneData { //ubo:0
highp vec4 ambient_light_color;
highp vec4 bg_color;
+
+ vec4 fog_color_enabled;
+ vec4 fog_sun_color_amount;
+
float ambient_energy;
float bg_energy;
@@ -79,10 +83,21 @@ layout(std140) uniform SceneData { //ubo:0
vec2 shadow_atlas_pixel_size;
vec2 directional_shadow_pixel_size;
+ float z_far;
float reflection_multiplier;
float subsurface_scatter_width;
float ambient_occlusion_affect_light;
+ bool fog_depth_enabled;
+ float fog_depth_begin;
+ float fog_depth_curve;
+ bool fog_transmit_enabled;
+ float fog_transmit_curve;
+ bool fog_height_enabled;
+ float fog_height_min;
+ float fog_height_max;
+ float fog_height_curve;
+
};
uniform highp mat4 world_transform;
@@ -153,7 +168,7 @@ out highp float dp_clip;
#define SKELETON_TEXTURE_WIDTH 256
#ifdef USE_SKELETON
-uniform highp sampler2D skeleton_texture; //texunit:-6
+uniform highp sampler2D skeleton_texture; //texunit:-1
#endif
out highp vec4 position_interp;
@@ -338,7 +353,20 @@ VERTEX_SHADER_CODE
[fragment]
+/* texture unit usage, N is max_texture_unity-N
+1-skeleton
+2-radiance
+3-reflection_atlas
+4-directional_shadow
+5-shadow_atlas
+6-decal_atlas
+7-screen
+8-depth
+9-probe1
+10-probe2
+
+*/
#define M_PI 3.14159265359
@@ -370,7 +398,6 @@ in vec3 normal_interp;
//used on forward mainly
uniform bool no_ambient_light;
-uniform sampler2D brdf_texture; //texunit:-1
#ifdef USE_RADIANCE_MAP
@@ -413,6 +440,8 @@ layout(std140) uniform SceneData {
highp vec4 ambient_light_color;
highp vec4 bg_color;
+ vec4 fog_color_enabled;
+ vec4 fog_sun_color_amount;
float ambient_energy;
float bg_energy;
@@ -426,10 +455,20 @@ layout(std140) uniform SceneData {
vec2 shadow_atlas_pixel_size;
vec2 directional_shadow_pixel_size;
+ float z_far;
float reflection_multiplier;
float subsurface_scatter_width;
float ambient_occlusion_affect_light;
+ bool fog_depth_enabled;
+ float fog_depth_begin;
+ float fog_depth_curve;
+ bool fog_transmit_enabled;
+ float fog_transmit_curve;
+ bool fog_height_enabled;
+ float fog_height_min;
+ float fog_height_max;
+ float fog_height_curve;
};
//directional light data
@@ -482,7 +521,7 @@ layout(std140) uniform SpotLightData { //ubo:5
};
-uniform highp sampler2DShadow shadow_atlas; //texunit:-3
+uniform highp sampler2DShadow shadow_atlas; //texunit:-5
struct ReflectionData {
@@ -500,7 +539,7 @@ layout(std140) uniform ReflectionProbeData { //ubo:6
ReflectionData reflections[MAX_REFLECTION_DATA_STRUCTS];
};
-uniform mediump sampler2D reflection_atlas; //texunit:-5
+uniform mediump sampler2D reflection_atlas; //texunit:-3
#ifdef USE_FORWARD_LIGHTING
@@ -517,6 +556,11 @@ uniform int reflection_count;
#endif
+#if defined(SCREEN_TEXTURE_USED)
+
+uniform highp sampler2D screen_texture; //texunit:-7
+
+#endif
#ifdef USE_MULTIPLE_RENDER_TARGETS
@@ -534,7 +578,7 @@ layout(location=0) out vec4 frag_color;
#endif
in highp vec4 position_interp;
-uniform highp sampler2D depth_buffer; //texunit:-9
+uniform highp sampler2D depth_buffer; //texunit:-8
float contact_shadow_compute(vec3 pos, vec3 dir, float max_distance) {
@@ -1020,7 +1064,7 @@ void reflection_process(int idx, vec3 vertex, vec3 normal,vec3 binormal, vec3 ta
#ifdef USE_GI_PROBES
-uniform mediump sampler3D gi_probe1; //texunit:-10
+uniform mediump sampler3D gi_probe1; //texunit:-9
uniform highp mat4 gi_probe_xform1;
uniform highp vec3 gi_probe_bounds1;
uniform highp vec3 gi_probe_cell_size1;
@@ -1028,7 +1072,7 @@ uniform highp float gi_probe_multiplier1;
uniform highp float gi_probe_bias1;
uniform bool gi_probe_blend_ambient1;
-uniform mediump sampler3D gi_probe2; //texunit:-11
+uniform mediump sampler3D gi_probe2; //texunit:-10
uniform highp mat4 gi_probe_xform2;
uniform highp vec3 gi_probe_bounds2;
uniform highp vec3 gi_probe_cell_size2;
@@ -1265,7 +1309,9 @@ void main() {
float normaldepth=1.0;
-
+#if defined(SCREEN_UV_USED)
+ vec2 screen_uv = gl_FragCoord.xy*screen_pixel_size;
+#endif
#if defined(ENABLE_DISCARD)
bool discard_=false;
@@ -1596,6 +1642,49 @@ FRAGMENT_SHADER_CODE
specular_light *= min(1.0,50.0 * f0.g) * brdf.y + brdf.x * f0;
}
+ if (fog_color_enabled.a > 0.5) {
+
+ float fog_amount=0;
+
+
+
+#ifdef USE_LIGHT_DIRECTIONAL
+
+ vec3 fog_color = mix( fog_color_enabled.rgb, fog_sun_color_amount.rgb,fog_sun_color_amount.a * pow(max( dot(normalize(vertex),-light_direction_attenuation.xyz), 0.0),8.0) );
+#else
+
+ vec3 fog_color = fog_color_enabled.rgb;
+#endif
+
+ //apply fog
+
+ if (fog_depth_enabled) {
+
+ float fog_z = smoothstep(fog_depth_begin,z_far,-vertex.z);
+
+ fog_amount = pow(fog_z,fog_depth_curve);
+ if (fog_transmit_enabled) {
+ vec3 total_light = emission + ambient_light + specular_light + diffuse_light;
+ float transmit = pow(fog_z,fog_transmit_curve);
+ fog_color = mix(max(total_light,fog_color),fog_color,transmit);
+ }
+ }
+
+ if (fog_height_enabled) {
+ float y = (camera_matrix * vec4(vertex,1.0)).y;
+ fog_amount = max(fog_amount,pow(1.0-smoothstep(fog_height_min,fog_height_max,y),fog_height_curve));
+ }
+
+ float rev_amount = 1.0 - fog_amount;
+
+
+ emission = emission * rev_amount + fog_color * fog_amount;
+ ambient_light*=rev_amount;
+ specular_light*rev_amount;
+ diffuse_light*=rev_amount;
+
+ }
+
#ifdef USE_MULTIPLE_RENDER_TARGETS
#if defined(ENABLE_AO)
@@ -1620,7 +1709,7 @@ FRAGMENT_SHADER_CODE
sss_buffer = sss_strength;
#endif
-#else
+#else //USE_MULTIPLE_RENDER_TARGETS
#ifdef SHADELESS
diff --git a/drivers/gles3/shaders/tonemap.glsl b/drivers/gles3/shaders/tonemap.glsl
index 8f7e0c7be3..3ce2edf4e9 100644
--- a/drivers/gles3/shaders/tonemap.glsl
+++ b/drivers/gles3/shaders/tonemap.glsl
@@ -6,12 +6,13 @@ layout(location=4) in vec2 uv_in;
out vec2 uv_interp;
-
-
void main() {
gl_Position = vertex_attrib;
uv_interp = uv_in;
+#ifdef V_FLIP
+ uv_interp.y = 1.0-uv_interp.y;
+#endif
}
@@ -39,6 +40,19 @@ uniform highp float glow_intensity;
#endif
+#ifdef USE_BCS
+
+uniform vec3 bcs;
+
+#endif
+
+#ifdef USE_COLOR_CORRECTION
+
+uniform sampler2D color_correction; //texunit:3
+
+#endif
+
+
layout(location = 0) out vec4 frag_color;
#ifdef USE_GLOW_FILTER_BICUBIC
@@ -255,6 +269,20 @@ void main() {
color.rgb = mix( (vec3(1.0)+a)*pow(color.rgb,vec3(1.0/2.4))-a , 12.92*color.rgb , lessThan(color.rgb,vec3(0.0031308)));
+#ifdef USE_BCS
+
+ color.rgb = mix(vec3(0.0),color.rgb,bcs.x);
+ color.rgb = mix(vec3(0.5),color.rgb,bcs.y);
+ color.rgb = mix(vec3(dot(vec3(1.0),color.rgb)*0.33333),color.rgb,bcs.z);
+
+#endif
+
+#ifdef USE_COLOR_CORRECTION
+
+ color.r = texture(color_correction,vec2(color.r,0.0)).r;
+ color.g = texture(color_correction,vec2(color.g,0.0)).g;
+ color.b = texture(color_correction,vec2(color.b,0.0)).b;
+#endif
frag_color=vec4(color.rgb,1.0);
diff --git a/drivers/png/resource_saver_png.cpp b/drivers/png/resource_saver_png.cpp
index 1700603489..0d7e1d9d72 100644
--- a/drivers/png/resource_saver_png.cpp
+++ b/drivers/png/resource_saver_png.cpp
@@ -55,41 +55,6 @@ Error ResourceSaverPNG::save(const String &p_path, const RES &p_resource, uint32
Error err = save_image(p_path, img);
if (err == OK) {
-
- bool global_filter = GlobalConfig::get_singleton()->get("image_loader/filter");
- bool global_mipmaps = GlobalConfig::get_singleton()->get("image_loader/gen_mipmaps");
- bool global_repeat = GlobalConfig::get_singleton()->get("image_loader/repeat");
-
- String text;
-
- if (global_filter != bool(texture->get_flags() & Texture::FLAG_FILTER)) {
- text += bool(texture->get_flags() & Texture::FLAG_FILTER) ? "filter=true\n" : "filter=false\n";
- }
- if (global_mipmaps != bool(texture->get_flags() & Texture::FLAG_MIPMAPS)) {
- text += bool(texture->get_flags() & Texture::FLAG_MIPMAPS) ? "gen_mipmaps=true\n" : "gen_mipmaps=false\n";
- }
- if (global_repeat != bool(texture->get_flags() & Texture::FLAG_REPEAT)) {
- text += bool(texture->get_flags() & Texture::FLAG_REPEAT) ? "repeat=true\n" : "repeat=false\n";
- }
- if (bool(texture->get_flags() & Texture::FLAG_ANISOTROPIC_FILTER)) {
- text += "anisotropic=true\n";
- }
- if (bool(texture->get_flags() & Texture::FLAG_CONVERT_TO_LINEAR)) {
- text += "tolinear=true\n";
- }
- if (bool(texture->get_flags() & Texture::FLAG_MIRRORED_REPEAT)) {
- text += "mirroredrepeat=true\n";
- }
-
- if (text != "" || FileAccess::exists(p_path + ".flags")) {
-
- FileAccess *f = FileAccess::open(p_path + ".flags", FileAccess::WRITE);
- if (f) {
-
- f->store_string(text);
- memdelete(f);
- }
- }
}
return err;