Browse Source

-working SCREEN_TEXTURE, SCREEN_UV shader variables
-Added refraction support for default material
-Enabled BCS adjustments, as well as color correction.

Juan Linietsky 8 years ago
parent
commit
0fb99306ff

+ 86 - 37
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);

+ 13 - 0
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);
 

+ 4 - 2
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);

+ 1 - 0
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;

+ 5 - 0
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";
 

+ 31 - 0
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

+ 27 - 8
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;

+ 27 - 0
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);

+ 38 - 30
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));

+ 0 - 5
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;
 

+ 2 - 0
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;