diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 2b0f78e10f1..de79c034cb7 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -933,6 +933,15 @@ 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; } RID RasterizerSceneGLES3::light_instance_create(RID p_light) { @@ -1697,7 +1706,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 +1718,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); @@ -1751,8 +1760,6 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ 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 +1941,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 +2030,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 +2045,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)) @@ -2797,6 +2808,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 +2886,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 +3125,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 +3196,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)); @@ -3594,6 +3620,17 @@ 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.bind(); state.tonemap_shader.set_uniform(TonemapShaderGLES3::EXPOSURE, env->tone_mapper_exposure); @@ -3616,6 +3653,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 +3676,8 @@ 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); } 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 +3692,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 +3701,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 +3765,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 +3818,7 @@ 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 glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height); @@ -3910,6 +3954,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 322343bc89d..03c6f080ac2 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -170,6 +170,7 @@ public: bool cull_front; bool used_sss; + bool used_screen_texture; } state; @@ -389,6 +390,12 @@ 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; + Environment() { bg_mode = VS::ENV_BG_CLEAR_COLOR; sky_scale = 1.0; @@ -445,6 +452,11 @@ 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; } }; @@ -711,6 +723,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 7ac82a9ecaa..a503b6daa7e 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -1463,6 +1463,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 +1489,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; @@ -5669,8 +5671,8 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) { 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); + 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); diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 1572d4358ef..c8edeaefbfd 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -411,6 +411,7 @@ public: bool uses_vertex; bool uses_discard; bool uses_sss; + bool uses_screen_texture; bool writes_modelview_or_projection; } spatial; diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index 5ad2ae7362e..4f741c6b7ae 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -745,6 +745,9 @@ 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["SIDE"] = "side"; actions[VS::SHADER_SPATIAL].usage_defines["TANGENT"] = "#define ENABLE_TANGENT_INTERP\n"; actions[VS::SHADER_SPATIAL].usage_defines["BINORMAL"] = "@TANGENT"; @@ -763,6 +766,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 c8985e6902a..621ae83162c 100644 --- a/drivers/gles3/shaders/copy.glsl +++ b/drivers/gles3/shaders/copy.glsl @@ -84,8 +84,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 +151,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 29a7135eeda..f498eae9f59 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -153,7 +153,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 +338,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 +383,6 @@ in vec3 normal_interp; //used on forward mainly uniform bool no_ambient_light; -uniform sampler2D brdf_texture; //texunit:-1 #ifdef USE_RADIANCE_MAP @@ -482,7 +494,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 +512,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 +529,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 +551,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 +1037,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 +1045,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 +1282,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; diff --git a/drivers/gles3/shaders/tonemap.glsl b/drivers/gles3/shaders/tonemap.glsl index 8f7e0c7be3b..b2615fa29c5 100644 --- a/drivers/gles3/shaders/tonemap.glsl +++ b/drivers/gles3/shaders/tonemap.glsl @@ -39,6 +39,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 +268,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/scene/resources/material.cpp b/scene/resources/material.cpp index a9205fd5717..ce88325539b 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -193,7 +193,6 @@ void SpatialMaterial::init_shaders() { shader_names->depth_scale = "depth_scale"; shader_names->subsurface_scattering_strength = "subsurface_scattering_strength"; shader_names->refraction = "refraction"; - shader_names->refraction_roughness = "refraction_roughness"; shader_names->point_size = "point_size"; shader_names->uv1_scale = "uv1_scale"; shader_names->uv1_offset = "uv1_offset"; @@ -268,7 +267,12 @@ void SpatialMaterial::_update_shader() { case BLEND_MODE_MUL: code += "blend_mul"; break; } - switch (depth_draw_mode) { + DepthDrawMode ddm = depth_draw_mode; + if (features[FEATURE_REFRACTION]) { + ddm = DEPTH_DRAW_ALWAYS; + } + + switch (ddm) { case DEPTH_DRAW_OPAQUE_ONLY: code += ",depth_draw_opaque"; break; case DEPTH_DRAW_ALWAYS: code += ",depth_draw_always"; break; case DEPTH_DRAW_DISABLED: code += ",depth_draw_never"; break; @@ -322,6 +326,11 @@ void SpatialMaterial::_update_shader() { code += "uniform float emission_energy;\n"; } + if (features[FEATURE_REFRACTION]) { + code += "uniform sampler2D texture_refraction;\n"; + code += "uniform float refraction : hint_range(-16,16);\n"; + } + if (features[FEATURE_NORMAL_MAPPING]) { code += "uniform sampler2D texture_normal : hint_normal;\n"; code += "uniform float normal_scale : hint_range(-16,16);\n"; @@ -489,17 +498,37 @@ void SpatialMaterial::_update_shader() { } code += "\tALBEDO = albedo.rgb * albedo_tex.rgb;\n"; - if (features[FEATURE_TRANSPARENT]) { - code += "\tALPHA = albedo.a * albedo_tex.a;\n"; + code += "\tfloat metallic_tex = texture(texture_metallic,base_uv).r;\n"; + code += "\tMETALLIC = metallic_tex * metallic;\n"; + code += "\tfloat roughness_tex = texture(texture_roughness,base_uv).r;\n"; + code += "\tROUGHNESS = roughness_tex * roughness;\n"; + code += "\tSPECULAR = specular;\n"; + + if (features[FEATURE_NORMAL_MAPPING]) { + code += "\tNORMALMAP = texture(texture_normal,base_uv).rgb;\n"; + code += "\tNORMALMAP_DEPTH = normal_scale;\n"; } if (features[FEATURE_EMISSION]) { code += "\tEMISSION = (emission.rgb+texture(texture_emission,base_uv).rgb)*emission_energy;\n"; } - if (features[FEATURE_NORMAL_MAPPING]) { - code += "\tNORMALMAP = texture(texture_normal,base_uv).rgb;\n"; - code += "\tNORMALMAP_DEPTH = normal_scale;\n"; + if (features[FEATURE_REFRACTION]) { + + if (features[FEATURE_NORMAL_MAPPING]) { + code += "\tvec3 ref_normal = normalize( mix(NORMAL,TANGENT * NORMALMAP.x + BINORMAL * NORMALMAP.y + NORMAL * NORMALMAP.z,NORMALMAP_DEPTH) ) * SIDE;\n"; + } else { + code += "\tvec3 ref_normal = NORMAL;\n"; + } + + code += "\tvec2 ref_ofs = SCREEN_UV - ref_normal.xy * texture(texture_refraction,base_uv).r * refraction;\n"; + code += "\tfloat ref_amount = 1.0 - albedo.a * albedo_tex.a;\n"; + code += "\tEMISSION += textureLod(SCREEN_TEXTURE,ref_ofs,ROUGHNESS * 8.0).rgb * ref_amount;\n"; + code += "\tALBEDO *= 1.0 - ref_amount;\n"; + code += "\tALPHA = 1.0;\n"; + + } else if (features[FEATURE_TRANSPARENT]) { + code += "\tALPHA = albedo.a * albedo_tex.a;\n"; } if (features[FEATURE_RIM]) { @@ -557,12 +586,6 @@ void SpatialMaterial::_update_shader() { code += "\tALBEDO.rgb = mix(ALBEDO.rgb,detail,detail_mask_tex.r);\n"; } - code += "\tfloat metallic_tex = texture(texture_metallic,base_uv).r;\n"; - code += "\tMETALLIC = metallic_tex * metallic;\n"; - code += "\tfloat roughness_tex = texture(texture_roughness,base_uv).r;\n"; - code += "\tROUGHNESS = roughness_tex * roughness;\n"; - code += "\tSPECULAR = specular;\n"; - code += "}\n"; ShaderData shader_data; @@ -777,16 +800,6 @@ float SpatialMaterial::get_refraction() const { return refraction; } -void SpatialMaterial::set_refraction_roughness(float p_refraction_roughness) { - - refraction_roughness = p_refraction_roughness; - VS::get_singleton()->material_set_param(_get_material(), shader_names->refraction_roughness, refraction_roughness); -} -float SpatialMaterial::get_refraction_roughness() const { - - return refraction_roughness; -} - void SpatialMaterial::set_detail_uv(DetailUV p_detail_uv) { if (detail_uv == p_detail_uv) @@ -1125,9 +1138,6 @@ void SpatialMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_refraction", "refraction"), &SpatialMaterial::set_refraction); ClassDB::bind_method(D_METHOD("get_refraction"), &SpatialMaterial::get_refraction); - ClassDB::bind_method(D_METHOD("set_refraction_roughness", "refraction_roughness"), &SpatialMaterial::set_refraction_roughness); - ClassDB::bind_method(D_METHOD("get_refraction_roughness"), &SpatialMaterial::get_refraction_roughness); - ClassDB::bind_method(D_METHOD("set_line_width", "line_width"), &SpatialMaterial::set_line_width); ClassDB::bind_method(D_METHOD("get_line_width"), &SpatialMaterial::get_line_width); @@ -1277,8 +1287,7 @@ void SpatialMaterial::_bind_methods() { ADD_GROUP("Refraction", "refraction_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "refraction_enabled"), "set_feature", "get_feature", FEATURE_REFRACTION); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "refraction_displacement", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_refraction", "get_refraction"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "refraction_roughness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_refraction_roughness", "get_refraction_roughness"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "refraction_scale", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_refraction", "get_refraction"); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "refraction_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_REFRACTION); ADD_GROUP("Detail", "detail_"); @@ -1381,8 +1390,7 @@ SpatialMaterial::SpatialMaterial() set_anisotropy(0); set_depth_scale(0.05); set_subsurface_scattering_strength(0); - set_refraction(0); - set_refraction_roughness(0); + set_refraction(0.05); set_line_width(1); set_point_size(1); set_uv1_offset(Vector2(0, 0)); diff --git a/scene/resources/material.h b/scene/resources/material.h index e72d3d455b6..b6e85c8332f 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -248,7 +248,6 @@ private: StringName depth_scale; StringName subsurface_scattering_strength; StringName refraction; - StringName refraction_roughness; StringName point_size; StringName uv1_scale; StringName uv1_offset; @@ -288,7 +287,6 @@ private: float depth_scale; float subsurface_scattering_strength; float refraction; - float refraction_roughness; float line_width; float point_size; int particles_anim_h_frames; @@ -380,9 +378,6 @@ public: void set_refraction(float p_refraction); float get_refraction() const; - void set_refraction_roughness(float p_refraction_roughness); - float get_refraction_roughness() const; - void set_line_width(float p_line_width); float get_line_width() const; diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp index ea012f19581..44ec13af453 100644 --- a/servers/visual/shader_types.cpp +++ b/servers/visual/shader_types.cpp @@ -104,8 +104,10 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["EMISSION"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SPECIAL"] = ShaderLanguage::TYPE_FLOAT; shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["DISCARD"] = ShaderLanguage::TYPE_BOOL; + shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SCREEN_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D; shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2; shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["POINT_COORD"] = ShaderLanguage::TYPE_VEC2; + shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SIDE"] = ShaderLanguage::TYPE_FLOAT; shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["WORLD_MATRIX"] = ShaderLanguage::TYPE_MAT4; shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["INV_CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4;