diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 222 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.h | 65 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.cpp | 277 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.h | 6 | ||||
-rw-r--r-- | drivers/gles3/shader_compiler_gles3.cpp | 6 | ||||
-rw-r--r-- | drivers/gles3/shaders/copy.glsl | 35 | ||||
-rw-r--r-- | drivers/gles3/shaders/scene.glsl | 107 | ||||
-rw-r--r-- | drivers/gles3/shaders/tonemap.glsl | 32 | ||||
-rw-r--r-- | drivers/png/resource_saver_png.cpp | 35 |
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; |