diff options
Diffstat (limited to 'servers/rendering/renderer_rd/shaders')
23 files changed, 701 insertions, 649 deletions
diff --git a/servers/rendering/renderer_rd/shaders/blur_raster.glsl b/servers/rendering/renderer_rd/shaders/blur_raster.glsl index b1d1c2365e..f8b4e3f610 100644 --- a/servers/rendering/renderer_rd/shaders/blur_raster.glsl +++ b/servers/rendering/renderer_rd/shaders/blur_raster.glsl @@ -37,33 +37,9 @@ layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure;  layout(location = 0) out vec4 frag_color; -//DOF -#ifdef MODE_DOF_BLUR - -layout(set = 1, binding = 0) uniform sampler2D dof_source_depth; - -#ifdef DOF_QUALITY_LOW -const int dof_kernel_size = 5; -const int dof_kernel_from = 2; -const float dof_kernel[5] = float[](0.153388, 0.221461, 0.250301, 0.221461, 0.153388); -#endif - -#ifdef DOF_QUALITY_MEDIUM -const int dof_kernel_size = 11; -const int dof_kernel_from = 5; -const float dof_kernel[11] = float[](0.055037, 0.072806, 0.090506, 0.105726, 0.116061, 0.119726, 0.116061, 0.105726, 0.090506, 0.072806, 0.055037); - -#endif - -#ifdef DOF_QUALITY_HIGH -const int dof_kernel_size = 21; -const int dof_kernel_from = 10; -const float dof_kernel[21] = float[](0.028174, 0.032676, 0.037311, 0.041944, 0.046421, 0.050582, 0.054261, 0.057307, 0.059587, 0.060998, 0.061476, 0.060998, 0.059587, 0.057307, 0.054261, 0.050582, 0.046421, 0.041944, 0.037311, 0.032676, 0.028174); -#endif - -#endif -  void main() { +	// We do not apply our color scale for our mobile renderer here, we'll leave our colors at half brightness and apply scale in the tonemap raster. +  #ifdef MODE_MIPMAP  	vec2 pix_size = blur.pixel_size; @@ -155,74 +131,8 @@ void main() {  #endif -#ifdef MODE_DOF_BLUR - -	vec4 color_accum = vec4(0.0); - -	float depth = texture(dof_source_depth, uv_interp, 0.0).r; -	depth = depth * 2.0 - 1.0; - -	if (bool(blur.flags & FLAG_USE_ORTHOGONAL_PROJECTION)) { -		depth = ((depth + (blur.camera_z_far + blur.camera_z_near) / (blur.camera_z_far - blur.camera_z_near)) * (blur.camera_z_far - blur.camera_z_near)) / 2.0; -	} else { -		depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - depth * (blur.camera_z_far - blur.camera_z_near)); -	} - -	// mix near and far blur amount -	float amount = 1.0; -	if (bool(blur.flags & FLAG_DOF_FAR)) { -		amount *= 1.0 - smoothstep(blur.dof_far_begin, blur.dof_far_end, depth); -	} -	if (bool(blur.flags & FLAG_DOF_NEAR)) { -		amount *= smoothstep(blur.dof_near_end, blur.dof_near_begin, depth); -	} -	amount = 1.0 - amount; - -	if (amount > 0.0) { -		float k_accum = 0.0; - -		for (int i = 0; i < dof_kernel_size; i++) { -			int int_ofs = i - dof_kernel_from; -			vec2 tap_uv = uv_interp + blur.dof_dir * float(int_ofs) * amount * blur.dof_radius; - -			float tap_k = dof_kernel[i]; - -			float tap_depth = texture(dof_source_depth, tap_uv, 0.0).r; -			tap_depth = tap_depth * 2.0 - 1.0; - -			if (bool(blur.flags & FLAG_USE_ORTHOGONAL_PROJECTION)) { -				tap_depth = ((tap_depth + (blur.camera_z_far + blur.camera_z_near) / (blur.camera_z_far - blur.camera_z_near)) * (blur.camera_z_far - blur.camera_z_near)) / 2.0; -			} else { -				tap_depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - tap_depth * (blur.camera_z_far - blur.camera_z_near)); -			} - -			// mix near and far blur amount -			float tap_amount = 1.0; -			if (bool(blur.flags & FLAG_DOF_FAR)) { -				tap_amount *= mix(1.0 - smoothstep(blur.dof_far_begin, blur.dof_far_end, tap_depth), 0.0, int_ofs == 0); -			} -			if (bool(blur.flags & FLAG_DOF_NEAR)) { -				tap_amount *= mix(smoothstep(blur.dof_near_end, blur.dof_near_begin, tap_depth), 0.0, int_ofs == 0); -			} -			tap_amount = 1.0 - tap_amount; - -			tap_amount *= tap_amount * tap_amount; //prevent undesired glow effect - -			vec4 tap_color = texture(source_color, tap_uv, 0.0) * tap_k; - -			k_accum += tap_k * tap_amount; -			color_accum += tap_color * tap_amount; -		} - -		if (k_accum > 0.0) { -			color_accum /= k_accum; -		} - -		frag_color = color_accum; ///k_accum; -	} else { -		// we are in focus, don't waste time -		frag_color = texture(source_color, uv_interp, 0.0); -	} - +#ifdef MODE_COPY +	vec4 color = textureLod(source_color, uv_interp, 0.0); +	frag_color = color;  #endif  } diff --git a/servers/rendering/renderer_rd/shaders/blur_raster_inc.glsl b/servers/rendering/renderer_rd/shaders/blur_raster_inc.glsl index 6ea968e595..52bf2886b5 100644 --- a/servers/rendering/renderer_rd/shaders/blur_raster_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/blur_raster_inc.glsl @@ -1,8 +1,6 @@  #define FLAG_HORIZONTAL (1 << 0)  #define FLAG_USE_ORTHOGONAL_PROJECTION (1 << 1)  #define FLAG_GLOW_FIRST_PASS (1 << 2) -#define FLAG_DOF_FAR (1 << 3) -#define FLAG_DOF_NEAR (1 << 4)  layout(push_constant, binding = 1, std430) uniform Blur {  	vec2 pixel_size; @@ -19,18 +17,5 @@ layout(push_constant, binding = 1, std430) uniform Blur {  	float glow_white;  	float glow_luminance_cap;  	float glow_auto_exposure_grey; - -	// DOF. -	float dof_far_begin; -	float dof_far_end; -	float dof_near_begin; -	float dof_near_end; - -	float dof_radius; -	float dof_pad[3]; - -	vec2 dof_dir; -	float camera_z_far; -	float camera_z_near;  }  blur; diff --git a/servers/rendering/renderer_rd/shaders/bokeh_dof.glsl b/servers/rendering/renderer_rd/shaders/bokeh_dof.glsl index b70e0b6bd5..0438671dd2 100644 --- a/servers/rendering/renderer_rd/shaders/bokeh_dof.glsl +++ b/servers/rendering/renderer_rd/shaders/bokeh_dof.glsl @@ -25,34 +25,7 @@ layout(set = 1, binding = 0) uniform sampler2D source_bokeh;  // based on https://www.shadertoy.com/view/Xd3GDl -layout(push_constant, binding = 1, std430) uniform Params { -	ivec2 size; -	float z_far; -	float z_near; - -	bool orthogonal; -	float blur_size; -	float blur_scale; -	int blur_steps; - -	bool blur_near_active; -	float blur_near_begin; -	float blur_near_end; -	bool blur_far_active; - -	float blur_far_begin; -	float blur_far_end; -	bool second_pass; -	bool half_size; - -	bool use_jitter; -	float jitter_seed; -	uint pad[2]; -} -params; - -//used to work around downsampling filter -#define DEPTH_GAP 0.0 +#include "bokeh_dof_inc.glsl"  #ifdef MODE_GEN_BLUR_SIZE @@ -80,15 +53,6 @@ float get_blur_size(float depth) {  #endif -const float GOLDEN_ANGLE = 2.39996323; - -//note: uniform pdf rand [0;1[ -float hash12n(vec2 p) { -	p = fract(p * vec2(5.3987, 5.4421)); -	p += dot(p.yx, p.xy + vec2(21.5351, 14.3137)); -	return fract(p.x * p.y * 95.4307); -} -  #if defined(MODE_BOKEH_BOX) || defined(MODE_BOKEH_HEXAGONAL)  vec4 weighted_filter_dir(vec2 dir, vec2 uv, vec2 pixel_size) { diff --git a/servers/rendering/renderer_rd/shaders/bokeh_dof_inc.glsl b/servers/rendering/renderer_rd/shaders/bokeh_dof_inc.glsl new file mode 100644 index 0000000000..fadea1631c --- /dev/null +++ b/servers/rendering/renderer_rd/shaders/bokeh_dof_inc.glsl @@ -0,0 +1,37 @@ +layout(push_constant, binding = 1, std430) uniform Params { +	ivec2 size; +	float z_far; +	float z_near; + +	bool orthogonal; +	float blur_size; +	float blur_scale; +	int blur_steps; + +	bool blur_near_active; +	float blur_near_begin; +	float blur_near_end; +	bool blur_far_active; + +	float blur_far_begin; +	float blur_far_end; +	bool second_pass; +	bool half_size; + +	bool use_jitter; +	float jitter_seed; +	uint pad[2]; +} +params; + +//used to work around downsampling filter +#define DEPTH_GAP 0.0 + +const float GOLDEN_ANGLE = 2.39996323; + +//note: uniform pdf rand [0;1[ +float hash12n(vec2 p) { +	p = fract(p * vec2(5.3987, 5.4421)); +	p += dot(p.yx, p.xy + vec2(21.5351, 14.3137)); +	return fract(p.x * p.y * 95.4307); +} diff --git a/servers/rendering/renderer_rd/shaders/bokeh_dof_raster.glsl b/servers/rendering/renderer_rd/shaders/bokeh_dof_raster.glsl new file mode 100644 index 0000000000..a3b3938ee9 --- /dev/null +++ b/servers/rendering/renderer_rd/shaders/bokeh_dof_raster.glsl @@ -0,0 +1,253 @@ +/* clang-format off */ +#[vertex] + +#version 450 + +#VERSION_DEFINES + +#include "bokeh_dof_inc.glsl" + +layout(location = 0) out vec2 uv_interp; +/* clang-format on */ + +void main() { +	vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); +	uv_interp = base_arr[gl_VertexIndex]; + +	gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0); +} + +/* clang-format off */ +#[fragment] + +#version 450 + +#VERSION_DEFINES + +#include "bokeh_dof_inc.glsl" + +layout(location = 0) in vec2 uv_interp; +/* clang-format on */ + +#ifdef MODE_GEN_BLUR_SIZE +layout(location = 0) out float weight; + +layout(set = 0, binding = 0) uniform sampler2D source_depth; +#else +layout(location = 0) out vec4 frag_color; +#ifdef OUTPUT_WEIGHT +layout(location = 1) out float weight; +#endif + +layout(set = 0, binding = 0) uniform sampler2D source_color; +layout(set = 1, binding = 0) uniform sampler2D source_weight; +#ifdef MODE_COMPOSITE_BOKEH +layout(set = 2, binding = 0) uniform sampler2D original_weight; +#endif +#endif + +//DOF +// Bokeh single pass implementation based on https://tuxedolabs.blogspot.com/2018/05/bokeh-depth-of-field-in-single-pass.html + +#ifdef MODE_GEN_BLUR_SIZE + +float get_depth_at_pos(vec2 uv) { +	float depth = textureLod(source_depth, uv, 0.0).x; +	if (params.orthogonal) { +		depth = ((depth + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0; +	} else { +		depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near)); +	} +	return depth; +} + +float get_blur_size(float depth) { +	if (params.blur_near_active && depth < params.blur_near_begin) { +		return -(1.0 - smoothstep(params.blur_near_end, params.blur_near_begin, depth)) * params.blur_size - DEPTH_GAP; //near blur is negative +	} + +	if (params.blur_far_active && depth > params.blur_far_begin) { +		return smoothstep(params.blur_far_begin, params.blur_far_end, depth) * params.blur_size + DEPTH_GAP; +	} + +	return 0.0; +} + +#endif + +#if defined(MODE_BOKEH_BOX) || defined(MODE_BOKEH_HEXAGONAL) + +vec4 weighted_filter_dir(vec2 dir, vec2 uv, vec2 pixel_size) { +	dir *= pixel_size; +	vec4 color = texture(source_color, uv); +	color.a = texture(source_weight, uv).r; + +	vec4 accum = color; +	float total = 1.0; + +	float blur_scale = params.blur_size / float(params.blur_steps); + +	if (params.use_jitter) { +		uv += dir * (hash12n(uv + params.jitter_seed) - 0.5); +	} + +	for (int i = -params.blur_steps; i <= params.blur_steps; i++) { +		if (i == 0) { +			continue; +		} +		float radius = float(i) * blur_scale; +		vec2 suv = uv + dir * radius; +		radius = abs(radius); + +		vec4 sample_color = texture(source_color, suv); +		sample_color.a = texture(source_weight, suv).r; +		float limit; + +		if (sample_color.a < color.a) { +			limit = abs(sample_color.a); +		} else { +			limit = abs(color.a); +		} + +		limit -= DEPTH_GAP; + +		float m = smoothstep(radius - 0.5, radius + 0.5, limit); + +		accum += mix(color, sample_color, m); + +		total += 1.0; +	} + +	return accum / total; +} + +#endif + +void main() { +	vec2 pixel_size = 1.0 / vec2(params.size); +	vec2 uv = uv_interp; + +#ifdef MODE_GEN_BLUR_SIZE +	uv += pixel_size * 0.5; +	float center_depth = get_depth_at_pos(uv); +	weight = get_blur_size(center_depth); +#endif + +#ifdef MODE_BOKEH_BOX +	//pixel_size*=0.5; //resolution is doubled +	if (params.second_pass || !params.half_size) { +		uv += pixel_size * 0.5; //half pixel to read centers +	} else { +		uv += pixel_size * 0.25; //half pixel to read centers from full res +	} + +	float alpha = texture(source_color, uv).a; // retain this +	vec2 dir = (params.second_pass ? vec2(0.0, 1.0) : vec2(1.0, 0.0)); + +	vec4 color = weighted_filter_dir(dir, uv, pixel_size); + +	frag_color = color; +	frag_color.a = alpha; // attempt to retain this in case we have a transparent background, ignored if half_size +#ifdef OUTPUT_WEIGHT +	weight = color.a; +#endif + +#endif + +#ifdef MODE_BOKEH_HEXAGONAL + +	//pixel_size*=0.5; //resolution is doubled +	if (params.second_pass || !params.half_size) { +		uv += pixel_size * 0.5; //half pixel to read centers +	} else { +		uv += pixel_size * 0.25; //half pixel to read centers from full res +	} + +	float alpha = texture(source_color, uv).a; // retain this + +	vec2 dir = (params.second_pass ? normalize(vec2(1.0, 0.577350269189626)) : vec2(0.0, 1.0)); + +	vec4 color = weighted_filter_dir(dir, uv, pixel_size); + +	if (params.second_pass) { +		dir = normalize(vec2(-1.0, 0.577350269189626)); + +		vec4 color2 = weighted_filter_dir(dir, uv, pixel_size); + +		color.rgb = min(color.rgb, color2.rgb); +		color.a = (color.a + color2.a) * 0.5; +	} + +	frag_color = color; +	frag_color.a = alpha; // attempt to retain this in case we have a transparent background, ignored if half_size +#ifdef OUTPUT_WEIGHT +	weight = color.a; +#endif + +#endif + +#ifdef MODE_BOKEH_CIRCULAR +	if (params.half_size) { +		pixel_size *= 0.5; //resolution is doubled +	} + +	uv += pixel_size * 0.5; //half pixel to read centers + +	vec4 color = texture(source_color, uv); +	float alpha = color.a; // retain this +	color.a = texture(source_weight, uv).r; + +	vec4 color_accum = color; +	float accum = 1.0; + +	float radius = params.blur_scale; +	for (float ang = 0.0; radius < params.blur_size; ang += GOLDEN_ANGLE) { +		vec2 uv_adj = uv + vec2(cos(ang), sin(ang)) * pixel_size * radius; + +		vec4 sample_color = texture(source_color, uv_adj); +		sample_color.a = texture(source_weight, uv_adj).r; + +		float limit; + +		if (sample_color.a < color.a) { +			limit = abs(sample_color.a); +		} else { +			limit = abs(color.a); +		} + +		limit -= DEPTH_GAP; + +		float m = smoothstep(radius - 0.5, radius + 0.5, limit); +		color_accum += mix(color_accum / accum, sample_color, m); +		accum += 1.0; + +		radius += params.blur_scale / radius; +	} + +	color_accum = color_accum / accum; + +	frag_color.rgb = color_accum.rgb; +	frag_color.a = alpha; // attempt to retain this in case we have a transparent background, ignored if half_size +#ifdef OUTPUT_WEIGHT +	weight = color_accum.a; +#endif + +#endif + +#ifdef MODE_COMPOSITE_BOKEH +	frag_color.rgb = texture(source_color, uv).rgb; + +	float center_weigth = texture(source_weight, uv).r; +	float sample_weight = texture(original_weight, uv).r; + +	float mix_amount; +	if (sample_weight < center_weigth) { +		mix_amount = min(1.0, max(0.0, max(abs(center_weigth), abs(sample_weight)) - DEPTH_GAP)); +	} else { +		mix_amount = min(1.0, max(0.0, abs(center_weigth) - DEPTH_GAP)); +	} + +	// let alpha blending take care of mixing +	frag_color.a = mix_amount; +#endif +} diff --git a/servers/rendering/renderer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl index a443bcdcb8..2911e8b731 100644 --- a/servers/rendering/renderer_rd/shaders/canvas.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas.glsl @@ -458,6 +458,14 @@ void light_blend_compute(uint light_base, vec4 light_color, inout vec3 color) {  #endif +float msdf_median(float r, float g, float b, float a) { +	return min(max(min(r, g), min(max(r, g), b)), a); +} + +vec2 msdf_map(vec2 value, vec2 in_min, vec2 in_max, vec2 out_min, vec2 out_max) { +	return out_min + (out_max - out_min) * (value - in_min) / (in_max - in_min); +} +  void main() {  	vec4 color = color_interp;  	vec2 uv = uv_interp; @@ -485,7 +493,34 @@ void main() {  #endif -	color *= texture(sampler2D(color_texture, texture_sampler), uv); +#ifndef USE_PRIMITIVE +	if (bool(draw_data.flags & FLAGS_USE_MSDF)) { +		float px_range = draw_data.ninepatch_margins.x; +		float outline_thickness = draw_data.ninepatch_margins.y; +		//float reserved1 = draw_data.ninepatch_margins.z; +		//float reserved2 = draw_data.ninepatch_margins.w; + +		vec4 msdf_sample = texture(sampler2D(color_texture, texture_sampler), uv); +		vec2 msdf_size = vec2(textureSize(sampler2D(color_texture, texture_sampler), 0)); +		vec2 dest_size = vec2(1.0) / fwidth(uv); +		float px_size = max(0.5 * dot((vec2(px_range) / msdf_size), dest_size), 1.0); +		float d = msdf_median(msdf_sample.r, msdf_sample.g, msdf_sample.b, msdf_sample.a) - 0.5; + +		if (outline_thickness > 0) { +			float cr = clamp(outline_thickness, 0.0, px_range / 2) / px_range; +			float a = clamp((d + cr) * px_size, 0.0, 1.0); +			color.a = a * color.a; +		} else { +			float a = clamp(d * px_size + 0.5, 0.0, 1.0); +			color.a = a * color.a; +		} + +	} else { +#else +	{ +#endif +		color *= texture(sampler2D(color_texture, texture_sampler), uv); +	}  	uint light_count = (draw_data.flags >> FLAGS_LIGHT_COUNT_SHIFT) & 0xF; //max 16 lights  	bool using_light = light_count > 0 || canvas_data.directional_light_count > 0; diff --git a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl index 451f9b0089..0cff505cae 100644 --- a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl @@ -24,6 +24,8 @@  #define FLAGS_DEFAULT_NORMAL_MAP_USED (1 << 26)  #define FLAGS_DEFAULT_SPECULAR_MAP_USED (1 << 27) +#define FLAGS_USE_MSDF (1 << 28) +  #define SAMPLER_NEAREST_CLAMP 0  #define SAMPLER_LINEAR_CLAMP 1  #define SAMPLER_NEAREST_WITH_MIPMAPS_CLAMP 2 diff --git a/servers/rendering/renderer_rd/shaders/cluster_render.glsl b/servers/rendering/renderer_rd/shaders/cluster_render.glsl index da7d189281..6d95722a57 100644 --- a/servers/rendering/renderer_rd/shaders/cluster_render.glsl +++ b/servers/rendering/renderer_rd/shaders/cluster_render.glsl @@ -117,7 +117,7 @@ void main() {  	uint cluster_thread_group_index;  	if (!gl_HelperInvocation) { -		//http://advances.realtimerendering.com/s2017/2017_Sig_Improved_Culling_final.pdf +		//https://advances.realtimerendering.com/s2017/2017_Sig_Improved_Culling_final.pdf  		uvec4 mask; diff --git a/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl b/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl index dfbce29119..69b895ed29 100644 --- a/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl +++ b/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl @@ -7,8 +7,7 @@  layout(push_constant, binding = 1, std430) uniform Params {  	float z_far;  	float z_near; -	bool z_flip; -	uint pad; +	vec2 texel_size;  	vec4 screen_rect;  }  params; @@ -35,22 +34,23 @@ layout(set = 0, binding = 0) uniform samplerCube source_cube;  layout(push_constant, binding = 1, std430) uniform Params {  	float z_far;  	float z_near; -	bool z_flip; -	uint pad; +	vec2 texel_size;  	vec4 screen_rect;  }  params;  void main() {  	vec2 uv = uv_interp; +	vec2 texel_size = abs(params.texel_size); -	vec3 normal = vec3(uv * 2.0 - 1.0, 0.0); +	uv = clamp(uv * (1.0 + 2.0 * texel_size) - texel_size, vec2(0.0), vec2(1.0)); -	normal.z = 0.5 - 0.5 * ((normal.x * normal.x) + (normal.y * normal.y)); +	vec3 normal = vec3(uv * 2.0 - 1.0, 0.0); +	normal.z = 0.5 * (1.0 - dot(normal.xy, normal.xy)); // z = 1/2 - 1/2 * (x^2 + y^2)  	normal = normalize(normal);  	normal.y = -normal.y; //needs to be flipped to match projection matrix -	if (!params.z_flip) { +	if (params.texel_size.x >= 0.0) { // Sign is used to encode Z flip  		normal.z = -normal.z;  	} diff --git a/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl b/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl index 80c0ac4fb4..be12be5dec 100644 --- a/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl @@ -69,13 +69,13 @@ vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) {  	return TangentX * H.x + TangentY * H.y + N * H.z;  } -// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html +// https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html  float GGX(float NdotV, float a) {  	float k = a / 2.0;  	return NdotV / (NdotV * (1.0 - k) + k);  } -// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html +// https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html  float G_Smith(float a, float nDotV, float nDotL) {  	return GGX(nDotL, a * a) * GGX(nDotV, a * a);  } diff --git a/servers/rendering/renderer_rd/shaders/decal_data_inc.glsl b/servers/rendering/renderer_rd/shaders/decal_data_inc.glsl index ccaad13311..158096d3c7 100644 --- a/servers/rendering/renderer_rd/shaders/decal_data_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/decal_data_inc.glsl @@ -1,18 +1,18 @@  struct DecalData { -	mat4 xform; //to decal transform -	vec3 inv_extents; -	float albedo_mix; -	vec4 albedo_rect; -	vec4 normal_rect; -	vec4 orm_rect; -	vec4 emission_rect; -	vec4 modulate; -	float emission_energy; +	highp mat4 xform; //to decal transform +	highp vec3 inv_extents; +	mediump float albedo_mix; +	highp vec4 albedo_rect; +	highp vec4 normal_rect; +	highp vec4 orm_rect; +	highp vec4 emission_rect; +	highp vec4 modulate; +	mediump float emission_energy;  	uint mask; -	float upper_fade; -	float lower_fade; -	mat3x4 normal_xform; -	vec3 normal; -	float normal_fade; +	mediump float upper_fade; +	mediump float lower_fade; +	mediump mat3x4 normal_xform; +	mediump vec3 normal; +	mediump float normal_fade;  }; diff --git a/servers/rendering/renderer_rd/shaders/giprobe_write.glsl b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl index 5dc2d08a3b..25d87ca45d 100644 --- a/servers/rendering/renderer_rd/shaders/giprobe_write.glsl +++ b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl @@ -202,12 +202,7 @@ void main() {  	vec3 emission = vec3(ivec3(cell_data.data[cell_index].emission & 0x3FF, (cell_data.data[cell_index].emission >> 10) & 0x7FF, cell_data.data[cell_index].emission >> 21)) * params.emission_scale;  	vec4 normal = unpackSnorm4x8(cell_data.data[cell_index].normal); -#ifdef MODE_ANISOTROPIC -	vec3 accum[6] = vec3[](vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0)); -	const vec3 accum_dirs[6] = vec3[](vec3(1.0, 0.0, 0.0), vec3(-1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(0.0, -1.0, 0.0), vec3(0.0, 0.0, 1.0), vec3(0.0, 0.0, -1.0)); -#else  	vec3 accum = vec3(0.0); -#endif  	for (uint i = 0; i < params.light_count; i++) {  		float attenuation; @@ -242,77 +237,35 @@ void main() {  		vec3 light = lights.data[i].color * albedo.rgb * attenuation * lights.data[i].energy; -#ifdef MODE_ANISOTROPIC -		for (uint j = 0; j < 6; j++) { -			accum[j] += max(0.0, dot(accum_dir, -light_dir)) * light + emission; -		} -#else  		if (length(normal.xyz) > 0.2) {  			accum += max(0.0, dot(normal.xyz, -light_dir)) * light + emission;  		} else {  			//all directions  			accum += light + emission;  		} -#endif  	} -#ifdef MODE_ANISOTROPIC - -	output.data[cell_index * 6 + 0] = vec4(accum[0], 0.0); -	output.data[cell_index * 6 + 1] = vec4(accum[1], 0.0); -	output.data[cell_index * 6 + 2] = vec4(accum[2], 0.0); -	output.data[cell_index * 6 + 3] = vec4(accum[3], 0.0); -	output.data[cell_index * 6 + 4] = vec4(accum[4], 0.0); -	output.data[cell_index * 6 + 5] = vec4(accum[5], 0.0); -#else  	output.data[cell_index] = vec4(accum, 0.0); -#endif -  #endif //MODE_COMPUTE_LIGHT  #ifdef MODE_UPDATE_MIPMAPS  	{ -#ifdef MODE_ANISOTROPIC -		vec3 light_accum[6] = vec3[](vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0)); -#else  		vec3 light_accum = vec3(0.0); -#endif  		float count = 0.0;  		for (uint i = 0; i < 8; i++) {  			uint child_index = cell_children.data[cell_index].children[i];  			if (child_index == NO_CHILDREN) {  				continue;  			} -#ifdef MODE_ANISOTROPIC -			light_accum[1] += output.data[child_index * 6 + 0].rgb; -			light_accum[2] += output.data[child_index * 6 + 1].rgb; -			light_accum[3] += output.data[child_index * 6 + 2].rgb; -			light_accum[4] += output.data[child_index * 6 + 3].rgb; -			light_accum[5] += output.data[child_index * 6 + 4].rgb; -			light_accum[6] += output.data[child_index * 6 + 5].rgb; - -#else  			light_accum += output.data[child_index].rgb; -#endif -  			count += 1.0;  		}  		float divisor = mix(8.0, count, params.propagation); -#ifdef MODE_ANISOTROPIC -		output.data[cell_index * 6 + 0] = vec4(light_accum[0] / divisor, 0.0); -		output.data[cell_index * 6 + 1] = vec4(light_accum[1] / divisor, 0.0); -		output.data[cell_index * 6 + 2] = vec4(light_accum[2] / divisor, 0.0); -		output.data[cell_index * 6 + 3] = vec4(light_accum[3] / divisor, 0.0); -		output.data[cell_index * 6 + 4] = vec4(light_accum[4] / divisor, 0.0); -		output.data[cell_index * 6 + 5] = vec4(light_accum[5] / divisor, 0.0); - -#else  		output.data[cell_index] = vec4(light_accum / divisor, 0.0); -#endif  	}  #endif diff --git a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl index 2fce258cff..fdc7729338 100644 --- a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl @@ -3,31 +3,31 @@  #define LIGHT_BAKE_STATIC 2  struct LightData { //this structure needs to be as packed as possible -	vec3 position; -	float inv_radius; +	highp vec3 position; +	highp float inv_radius; -	vec3 direction; -	float size; +	mediump vec3 direction; +	highp float size; -	vec3 color; -	float attenuation; +	mediump vec3 color; +	mediump float attenuation; -	float cone_attenuation; -	float cone_angle; -	float specular_amount; +	mediump float cone_attenuation; +	mediump float cone_angle; +	mediump float specular_amount;  	bool shadow_enabled; -	vec4 atlas_rect; // rect in the shadow atlas -	mat4 shadow_matrix; -	float shadow_bias; -	float shadow_normal_bias; -	float transmittance_bias; -	float soft_shadow_size; // for spot, it's the size in uv coordinates of the light, for omni it's the span angle -	float soft_shadow_scale; // scales the shadow kernel for blurrier shadows +	highp vec4 atlas_rect; // rect in the shadow atlas +	highp mat4 shadow_matrix; +	highp float shadow_bias; +	highp float shadow_normal_bias; +	highp float transmittance_bias; +	highp float soft_shadow_size; // for spot, it's the size in uv coordinates of the light, for omni it's the span angle +	highp float soft_shadow_scale; // scales the shadow kernel for blurrier shadows  	uint mask; -	float shadow_volumetric_fog_fade; +	mediump float shadow_volumetric_fog_fade;  	uint bake_mode; -	vec4 projector_rect; //projector rect in srgb decal atlas +	highp vec4 projector_rect; //projector rect in srgb decal atlas  };  #define REFLECTION_AMBIENT_DISABLED 0 @@ -35,53 +35,53 @@ struct LightData { //this structure needs to be as packed as possible  #define REFLECTION_AMBIENT_COLOR 2  struct ReflectionData { -	vec3 box_extents; -	float index; -	vec3 box_offset; +	highp vec3 box_extents; +	mediump float index; +	highp vec3 box_offset;  	uint mask; -	vec3 ambient; // ambient color -	float intensity; +	mediump vec3 ambient; // ambient color +	mediump float intensity;  	bool exterior;  	bool box_project;  	uint ambient_mode;  	uint pad;  	//0-8 is intensity,8-9 is ambient, mode -	mat4 local_matrix; // up to here for spot and omni, rest is for directional +	highp mat4 local_matrix; // up to here for spot and omni, rest is for directional  	// notes: for ambientblend, use distance to edge to blend between already existing global environment  };  struct DirectionalLightData { -	vec3 direction; -	float energy; -	vec3 color; -	float size; -	float specular; +	mediump vec3 direction; +	mediump float energy; +	mediump vec3 color; +	mediump float size; +	mediump float specular;  	uint mask; -	float softshadow_angle; -	float soft_shadow_scale; +	highp float softshadow_angle; +	highp float soft_shadow_scale;  	bool blend_splits;  	bool shadow_enabled; -	float fade_from; -	float fade_to; +	highp float fade_from; +	highp float fade_to;  	uvec2 pad;  	uint bake_mode; -	float shadow_volumetric_fog_fade; -	vec4 shadow_bias; -	vec4 shadow_normal_bias; -	vec4 shadow_transmittance_bias; -	vec4 shadow_z_range; -	vec4 shadow_range_begin; -	vec4 shadow_split_offsets; -	mat4 shadow_matrix1; -	mat4 shadow_matrix2; -	mat4 shadow_matrix3; -	mat4 shadow_matrix4; -	vec4 shadow_color1; -	vec4 shadow_color2; -	vec4 shadow_color3; -	vec4 shadow_color4; -	vec2 uv_scale1; -	vec2 uv_scale2; -	vec2 uv_scale3; -	vec2 uv_scale4; +	mediump float shadow_volumetric_fog_fade; +	highp vec4 shadow_bias; +	highp vec4 shadow_normal_bias; +	highp vec4 shadow_transmittance_bias; +	highp vec4 shadow_z_range; +	highp vec4 shadow_range_begin; +	highp vec4 shadow_split_offsets; +	highp mat4 shadow_matrix1; +	highp mat4 shadow_matrix2; +	highp mat4 shadow_matrix3; +	highp mat4 shadow_matrix4; +	mediump vec4 shadow_color1; +	mediump vec4 shadow_color2; +	mediump vec4 shadow_color3; +	mediump vec4 shadow_color4; +	highp vec2 uv_scale1; +	highp vec2 uv_scale2; +	highp vec2 uv_scale3; +	highp vec2 uv_scale4;  }; diff --git a/servers/rendering/renderer_rd/shaders/luminance_reduce_raster_inc.glsl b/servers/rendering/renderer_rd/shaders/luminance_reduce_raster_inc.glsl index ed389ffe56..3cde9923fa 100644 --- a/servers/rendering/renderer_rd/shaders/luminance_reduce_raster_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/luminance_reduce_raster_inc.glsl @@ -6,6 +6,6 @@ layout(push_constant, binding = 1, std430) uniform PushConstant {  	float exposure_adjust;  	float min_luminance;  	float max_luminance; -	float pad; +	uint pad1;  }  settings; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl index b3a349c948..edbe1031b7 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl @@ -118,7 +118,7 @@ void main() {  	mat3 world_normal_matrix;  	if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_NON_UNIFORM_SCALE)) { -		world_normal_matrix = inverse(mat3(world_matrix)); +		world_normal_matrix = transpose(inverse(mat3(world_matrix)));  	} else {  		world_normal_matrix = mat3(world_matrix);  	} @@ -374,6 +374,9 @@ layout(constant_id = 9) const uint sc_directional_penumbra_shadow_samples = 4;  layout(constant_id = 10) const bool sc_decal_use_mipmaps = true;  layout(constant_id = 11) const bool sc_projector_use_mipmaps = true; +// not used in clustered renderer but we share some code with the mobile renderer that requires this. +const float sc_luminance_multiplier = 1.0; +  #include "scene_forward_clustered_inc.glsl"  /* Varyings */ @@ -466,6 +469,11 @@ layout(location = 0) out vec4 frag_color;  #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) +/* Make a default specular mode SPECULAR_SCHLICK_GGX. */ +#if !defined(SPECULAR_DISABLED) && !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_BLINN) && !defined(SPECULAR_PHONG) && !defined(SPECULAR_TOON) +#define SPECULAR_SCHLICK_GGX +#endif +  #include "scene_forward_lights_inc.glsl"  #include "scene_forward_gi_inc.glsl" @@ -876,7 +884,7 @@ void main() {  #ifdef NORMAL_USED  	if (scene_data.roughness_limiter_enabled) { -		//http://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf +		//https://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf  		float roughness2 = roughness * roughness;  		vec3 dndu = dFdx(normal), dndv = dFdy(normal);  		float variance = scene_data.roughness_limiter_amount * (dot(dndu, dndu) + dot(dndv, dndv)); @@ -907,6 +915,8 @@ void main() {  		specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, roughness * MAX_ROUGHNESS_LOD).rgb;  #endif //USE_RADIANCE_CUBEMAP_ARRAY +		float horizon = min(1.0 + dot(ref_vec, normal), 1.0); +		specular_light *= horizon * horizon;  		specular_light *= scene_data.ambient_light_color_energy.a;  	} @@ -1594,7 +1604,7 @@ void main() {  					continue; // Statically baked light and object uses lightmap, skip  				} -				float shadow = light_process_omni_shadow(light_index, vertex, view); +				float shadow = light_process_omni_shadow(light_index, vertex, normal);  				shadow = blur_shadow(shadow); @@ -1670,7 +1680,7 @@ void main() {  					continue; // Statically baked light and object uses lightmap, skip  				} -				float shadow = light_process_spot_shadow(light_index, vertex, view); +				float shadow = light_process_spot_shadow(light_index, vertex, normal);  				shadow = blur_shadow(shadow); diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl index 7039ea2942..f3db4abe3b 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl @@ -208,11 +208,10 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte  		//normalized blinn  		float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25; -		float blinn = pow(cNdotH, shininess) * cNdotL; -		blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); -		float intensity = blinn; +		float blinn = pow(cNdotH, shininess); +		blinn *= (shininess + 2.0) * (1.0 / (8.0 * M_PI)); -		specular_light += light_color * intensity * attenuation * specular_amount; +		specular_light += light_color * attenuation * specular_amount * blinn * f0 * unpackUnorm4x8(orms).w;  #elif defined(SPECULAR_PHONG) @@ -220,10 +219,9 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte  		float cRdotV = clamp(A + dot(R, V), 0.0, 1.0);  		float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25;  		float phong = pow(cRdotV, shininess); -		phong *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); -		float intensity = (phong) / max(4.0 * cNdotV * cNdotL, 0.75); +		phong *= (shininess + 1.0) * (1.0 / (8.0 * M_PI)); -		specular_light += light_color * intensity * attenuation * specular_amount; +		specular_light += light_color * attenuation * specular_amount * phong * f0 * unpackUnorm4x8(orms).w;  #elif defined(SPECULAR_TOON) @@ -281,7 +279,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte  	}  #ifdef USE_SHADOW_TO_OPACITY -	alpha = min(alpha, clamp(1.0 - attenuation), 0.0, 1.0)); +	alpha = min(alpha, clamp(1.0 - attenuation, 0.0, 1.0));  #endif  #endif //defined(LIGHT_CODE_USED) @@ -290,7 +288,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte  #ifndef USE_NO_SHADOWS  // Interleaved Gradient Noise -// http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare +// https://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare  float quick_hash(vec2 pos) {  	const vec3 magic = vec3(0.06711056f, 0.00583715f, 52.9829189f);  	return fract(magic.z * fract(dot(pos, magic.xy))); @@ -322,7 +320,7 @@ float sample_directional_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, ve  	return avg * (1.0 / float(sc_directional_soft_shadow_samples));  } -float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) { +float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec3 coord) {  	vec2 pos = coord.xy;  	float depth = coord.z; @@ -348,6 +346,49 @@ float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) {  	return avg * (1.0 / float(sc_soft_shadow_samples));  } +float sample_omni_pcf_shadow(texture2D shadow, float blur_scale, vec2 coord, vec4 uv_rect, vec2 flip_offset, float depth) { +	//if only one sample is taken, take it from the center +	if (sc_soft_shadow_samples == 1) { +		vec2 pos = coord * 0.5 + 0.5; +		pos = uv_rect.xy + pos * uv_rect.zw; +		return textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos, depth, 1.0)); +	} + +	mat2 disk_rotation; +	{ +		float r = quick_hash(gl_FragCoord.xy) * 2.0 * M_PI; +		float sr = sin(r); +		float cr = cos(r); +		disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr)); +	} + +	float avg = 0.0; +	vec2 offset_scale = blur_scale * 2.0 * scene_data.shadow_atlas_pixel_size / uv_rect.zw; + +	for (uint i = 0; i < sc_soft_shadow_samples; i++) { +		vec2 offset = offset_scale * (disk_rotation * scene_data.soft_shadow_kernel[i].xy); +		vec2 sample_coord = coord + offset; + +		float sample_coord_length_sqaured = dot(sample_coord, sample_coord); +		bool do_flip = sample_coord_length_sqaured > 1.0; + +		if (do_flip) { +			float len = sqrt(sample_coord_length_sqaured); +			sample_coord = sample_coord * (2.0 / len - 1.0); +		} + +		sample_coord = sample_coord * 0.5 + 0.5; +		sample_coord = uv_rect.xy + sample_coord * uv_rect.zw; + +		if (do_flip) { +			sample_coord += flip_offset; +		} +		avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(sample_coord, depth, 1.0)); +	} + +	return avg * (1.0 / float(sc_soft_shadow_samples)); +} +  float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex_scale) {  	//find blocker  	float blocker_count = 0.0; @@ -405,21 +446,21 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) {  #ifndef USE_NO_SHADOWS  	if (omni_lights.data[idx].shadow_enabled) {  		// there is a shadowmap +		vec2 texel_size = scene_data.shadow_atlas_pixel_size; +		vec4 base_uv_rect = omni_lights.data[idx].atlas_rect; +		base_uv_rect.xy += texel_size; +		base_uv_rect.zw -= texel_size * 2.0; -		vec3 light_rel_vec = omni_lights.data[idx].position - vertex; -		float light_length = length(light_rel_vec); +		// Omni lights use direction.xy to store to store the offset between the two paraboloid regions +		vec2 flip_offset = omni_lights.data[idx].direction.xy; -		vec4 v = vec4(vertex, 1.0); +		vec3 local_vert = (omni_lights.data[idx].shadow_matrix * vec4(vertex, 1.0)).xyz; -		vec4 splane = (omni_lights.data[idx].shadow_matrix * v); -		float shadow_len = length(splane.xyz); //need to remember shadow len from here +		float shadow_len = length(local_vert); //need to remember shadow len from here +		vec3 shadow_dir = normalize(local_vert); -		{ -			vec3 nofs = normal_interp * omni_lights.data[idx].shadow_normal_bias / omni_lights.data[idx].inv_radius; -			nofs *= (1.0 - max(0.0, dot(normalize(light_rel_vec), normalize(normal_interp)))); -			v.xyz += nofs; -			splane = (omni_lights.data[idx].shadow_matrix * v); -		} +		vec3 local_normal = normalize(mat3(omni_lights.data[idx].shadow_matrix) * normal); +		vec3 normal_bias = local_normal * omni_lights.data[idx].shadow_normal_bias * (1.0 - abs(dot(local_normal, shadow_dir)));  		float shadow; @@ -439,10 +480,10 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) {  				disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr));  			} -			vec3 normal = normalize(splane.xyz); -			vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); -			vec3 tangent = normalize(cross(v0, normal)); -			vec3 bitangent = normalize(cross(tangent, normal)); +			vec3 basis_normal = shadow_dir; +			vec3 v0 = abs(basis_normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); +			vec3 tangent = normalize(cross(v0, basis_normal)); +			vec3 bitangent = normalize(cross(tangent, basis_normal));  			float z_norm = shadow_len * omni_lights.data[idx].inv_radius;  			tangent *= omni_lights.data[idx].soft_shadow_size * omni_lights.data[idx].soft_shadow_scale; @@ -451,18 +492,17 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) {  			for (uint i = 0; i < sc_penumbra_shadow_samples; i++) {  				vec2 disk = disk_rotation * scene_data.penumbra_shadow_kernel[i].xy; -				vec3 pos = splane.xyz + tangent * disk.x + bitangent * disk.y; +				vec3 pos = local_vert + tangent * disk.x + bitangent * disk.y;  				pos = normalize(pos); -				vec4 uv_rect = omni_lights.data[idx].atlas_rect; + +				vec4 uv_rect = base_uv_rect;  				if (pos.z >= 0.0) { -					pos.z += 1.0; -					uv_rect.y += uv_rect.w; -				} else { -					pos.z = 1.0 - pos.z; +					uv_rect.xy += flip_offset;  				} +				pos.z = 1.0 + abs(pos.z);  				pos.xy /= pos.z;  				pos.xy = pos.xy * 0.5 + 0.5; @@ -487,18 +527,18 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) {  				shadow = 0.0;  				for (uint i = 0; i < sc_penumbra_shadow_samples; i++) {  					vec2 disk = disk_rotation * scene_data.penumbra_shadow_kernel[i].xy; -					vec3 pos = splane.xyz + tangent * disk.x + bitangent * disk.y; +					vec3 pos = local_vert + tangent * disk.x + bitangent * disk.y;  					pos = normalize(pos); -					vec4 uv_rect = omni_lights.data[idx].atlas_rect; +					pos = normalize(pos + normal_bias); + +					vec4 uv_rect = base_uv_rect;  					if (pos.z >= 0.0) { -						pos.z += 1.0; -						uv_rect.y += uv_rect.w; -					} else { -						pos.z = 1.0 - pos.z; +						uv_rect.xy += flip_offset;  					} +					pos.z = 1.0 + abs(pos.z);  					pos.xy /= pos.z;  					pos.xy = pos.xy * 0.5 + 0.5; @@ -513,25 +553,19 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) {  				shadow = 1.0;  			}  		} else { -			splane.xyz = normalize(splane.xyz); -			vec4 clamp_rect = omni_lights.data[idx].atlas_rect; - -			if (splane.z >= 0.0) { -				splane.z += 1.0; +			vec4 uv_rect = base_uv_rect; -				clamp_rect.y += clamp_rect.w; - -			} else { -				splane.z = 1.0 - splane.z; +			vec3 shadow_sample = normalize(shadow_dir + normal_bias); +			if (shadow_sample.z >= 0.0) { +				uv_rect.xy += flip_offset; +				flip_offset *= -1.0;  			} -			splane.xy /= splane.z; - -			splane.xy = splane.xy * 0.5 + 0.5; -			splane.z = (shadow_len - omni_lights.data[idx].shadow_bias) * omni_lights.data[idx].inv_radius; -			splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw; -			splane.w = 1.0; //needed? i think it should be 1 already -			shadow = sample_pcf_shadow(shadow_atlas, omni_lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, splane); +			shadow_sample.z = 1.0 + abs(shadow_sample.z); +			vec2 pos = shadow_sample.xy / shadow_sample.z; +			float depth = shadow_len - omni_lights.data[idx].shadow_bias; +			depth *= omni_lights.data[idx].inv_radius; +			shadow = sample_omni_pcf_shadow(shadow_atlas, omni_lights.data[idx].soft_shadow_scale / shadow_sample.z, pos, uv_rect, flip_offset, depth);  		}  		return shadow; @@ -615,13 +649,11 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v  		vec4 atlas_rect = omni_lights.data[idx].projector_rect;  		if (local_v.z >= 0.0) { -			local_v.z += 1.0;  			atlas_rect.y += atlas_rect.w; - -		} else { -			local_v.z = 1.0 - local_v.z;  		} +		local_v.z = 1.0 + abs(local_v.z); +  		local_v.xy /= local_v.z;  		local_v.xy = local_v.xy * 0.5 + 0.5;  		vec2 proj_uv = local_v.xy * atlas_rect.zw; @@ -701,30 +733,23 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) {  		vec3 light_rel_vec = spot_lights.data[idx].position - vertex;  		float light_length = length(light_rel_vec);  		vec3 spot_dir = spot_lights.data[idx].direction; -		//there is a shadowmap -		vec4 v = vec4(vertex, 1.0); - -		v.xyz -= spot_dir * spot_lights.data[idx].shadow_bias; - -		float z_norm = dot(spot_dir, -light_rel_vec) * spot_lights.data[idx].inv_radius; -		float depth_bias_scale = 1.0 / (max(0.0001, z_norm)); //the closer to the light origin, the more you have to offset to reach 1px in the map -		vec3 normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(spot_dir, -normalize(normal_interp)))) * spot_lights.data[idx].shadow_normal_bias * depth_bias_scale; -		normal_bias -= spot_dir * dot(spot_dir, normal_bias); //only XY, no Z -		v.xyz += normal_bias; +		vec3 shadow_dir = light_rel_vec / light_length; +		vec3 normal_bias = normal * light_length * spot_lights.data[idx].shadow_normal_bias * (1.0 - abs(dot(normal, shadow_dir))); -		//adjust with bias -		z_norm = dot(spot_dir, v.xyz - spot_lights.data[idx].position) * spot_lights.data[idx].inv_radius; - -		float shadow; +		//there is a shadowmap +		vec4 v = vec4(vertex + normal_bias, 1.0);  		vec4 splane = (spot_lights.data[idx].shadow_matrix * v); +		splane.z -= spot_lights.data[idx].shadow_bias / (light_length * spot_lights.data[idx].inv_radius);  		splane /= splane.w; +		float shadow;  		if (sc_use_light_soft_shadows && spot_lights.data[idx].soft_shadow_size > 0.0) {  			//soft shadow  			//find blocker +			float z_norm = dot(spot_dir, -light_rel_vec) * spot_lights.data[idx].inv_radius;  			vec2 shadow_uv = splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy; @@ -770,11 +795,9 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) {  				//no blockers found, so no shadow  				shadow = 1.0;  			} -  		} else {  			//hard shadow -			vec4 shadow_uv = vec4(splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy, splane.z, 1.0); - +			vec3 shadow_uv = vec3(splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy, splane.z);  			shadow = sample_pcf_shadow(shadow_atlas, spot_lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, shadow_uv);  		} @@ -946,7 +969,7 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughnes  		vec4 reflection; -		reflection.rgb = textureLod(samplerCubeArray(reflection_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(local_ref_vec, reflections.data[ref_index].index), roughness * MAX_ROUGHNESS_LOD).rgb; +		reflection.rgb = textureLod(samplerCubeArray(reflection_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(local_ref_vec, reflections.data[ref_index].index), roughness * MAX_ROUGHNESS_LOD).rgb * sc_luminance_multiplier;  		if (reflections.data[ref_index].exterior) {  			reflection.rgb = mix(specular_light, reflection.rgb, blend); diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl index 70900a847c..518b0a6c7f 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl @@ -59,27 +59,27 @@ layout(location = 11) in vec4 weight_attrib;  /* Varyings */ -layout(location = 0) out vec3 vertex_interp; +layout(location = 0) highp out vec3 vertex_interp;  #ifdef NORMAL_USED -layout(location = 1) out vec3 normal_interp; +layout(location = 1) mediump out vec3 normal_interp;  #endif  #if defined(COLOR_USED) -layout(location = 2) out vec4 color_interp; +layout(location = 2) mediump out vec4 color_interp;  #endif  #ifdef UV_USED -layout(location = 3) out vec2 uv_interp; +layout(location = 3) mediump out vec2 uv_interp;  #endif  #if defined(UV2_USED) || defined(USE_LIGHTMAP) -layout(location = 4) out vec2 uv2_interp; +layout(location = 4) mediump out vec2 uv2_interp;  #endif  #if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) -layout(location = 5) out vec3 tangent_interp; -layout(location = 6) out vec3 binormal_interp; +layout(location = 5) mediump out vec3 tangent_interp; +layout(location = 6) mediump out vec3 binormal_interp;  #endif  #ifdef MATERIAL_UNIFORMS_USED @@ -92,7 +92,7 @@ layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms  #ifdef MODE_DUAL_PARABOLOID -layout(location = 8) out float dp_clip; +layout(location = 8) out highp float dp_clip;  #endif @@ -124,7 +124,7 @@ void main() {  	mat3 world_normal_matrix;  	if (bool(draw_call.flags & INSTANCE_FLAGS_NON_UNIFORM_SCALE)) { -		world_normal_matrix = inverse(mat3(world_matrix)); +		world_normal_matrix = transpose(inverse(mat3(world_matrix)));  	} else {  		world_normal_matrix = mat3(world_matrix);  	} @@ -372,55 +372,68 @@ void main() {  /* Specialization Constants */ -/* Specialization Constants (Toggles) */ +#if !defined(MODE_RENDER_DEPTH) + +#if !defined(MODE_UNSHADED) + +layout(constant_id = 0) const bool sc_use_light_projector = false; +layout(constant_id = 1) const bool sc_use_light_soft_shadows = false; +layout(constant_id = 2) const bool sc_use_directional_soft_shadows = false; + +layout(constant_id = 3) const uint sc_soft_shadow_samples = 4; +layout(constant_id = 4) const uint sc_penumbra_shadow_samples = 4; -layout(constant_id = 0) const bool sc_use_forward_gi = false; -layout(constant_id = 1) const bool sc_use_light_projector = false; -layout(constant_id = 2) const bool sc_use_light_soft_shadows = false; -layout(constant_id = 3) const bool sc_use_directional_soft_shadows = false; +layout(constant_id = 5) const uint sc_directional_soft_shadow_samples = 4; +layout(constant_id = 6) const uint sc_directional_penumbra_shadow_samples = 4; -/* Specialization Constants (Values) */ +layout(constant_id = 8) const bool sc_projector_use_mipmaps = true; -layout(constant_id = 6) const uint sc_soft_shadow_samples = 4; -layout(constant_id = 7) const uint sc_penumbra_shadow_samples = 4; +layout(constant_id = 9) const bool sc_disable_omni_lights = false; +layout(constant_id = 10) const bool sc_disable_spot_lights = false; +layout(constant_id = 11) const bool sc_disable_reflection_probes = false; +layout(constant_id = 12) const bool sc_disable_directional_lights = false; -layout(constant_id = 8) const uint sc_directional_soft_shadow_samples = 4; -layout(constant_id = 9) const uint sc_directional_penumbra_shadow_samples = 4; +#endif //!MODE_UNSHADED + +layout(constant_id = 7) const bool sc_decal_use_mipmaps = true; +layout(constant_id = 13) const bool sc_disable_decals = false; +layout(constant_id = 14) const bool sc_disable_fog = false; + +#endif //!MODE_RENDER_DEPTH -layout(constant_id = 10) const bool sc_decal_use_mipmaps = true; -layout(constant_id = 11) const bool sc_projector_use_mipmaps = true; +layout(constant_id = 15) const float sc_luminance_multiplier = 2.0;  /* Include our forward mobile UBOs definitions etc. */  #include "scene_forward_mobile_inc.glsl"  /* Varyings */ -layout(location = 0) in vec3 vertex_interp; +layout(location = 0) highp in vec3 vertex_interp;  #ifdef NORMAL_USED -layout(location = 1) in vec3 normal_interp; +layout(location = 1) mediump in vec3 normal_interp;  #endif  #if defined(COLOR_USED) -layout(location = 2) in vec4 color_interp; +layout(location = 2) mediump in vec4 color_interp;  #endif  #ifdef UV_USED -layout(location = 3) in vec2 uv_interp; +layout(location = 3) mediump in vec2 uv_interp;  #endif  #if defined(UV2_USED) || defined(USE_LIGHTMAP) -layout(location = 4) in vec2 uv2_interp; +layout(location = 4) mediump in vec2 uv2_interp;  #endif  #if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) -layout(location = 5) in vec3 tangent_interp; -layout(location = 6) in vec3 binormal_interp; +layout(location = 5) mediump in vec3 tangent_interp; +layout(location = 6) mediump in vec3 binormal_interp;  #endif  #ifdef MODE_DUAL_PARABOLOID -layout(location = 8) in float dp_clip; +layout(location = 8) highp in float dp_clip;  #endif @@ -482,7 +495,7 @@ layout(location = 0) out vec4 diffuse_buffer; //diffuse (rgb) and roughness  layout(location = 1) out vec4 specular_buffer; //specular and SSS (subsurface scatter)  #else -layout(location = 0) out vec4 frag_color; +layout(location = 0) out mediump vec4 frag_color;  #endif // MODE_MULTIPLE_RENDER_TARGETS  #endif // RENDER DEPTH @@ -491,6 +504,11 @@ layout(location = 0) out vec4 frag_color;  #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) +/* Make a default specular mode SPECULAR_SCHLICK_GGX. */ +#if !defined(SPECULAR_DISABLED) && !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_BLINN) && !defined(SPECULAR_PHONG) && !defined(SPECULAR_TOON) +#define SPECULAR_SCHLICK_GGX +#endif +  #include "scene_forward_lights_inc.glsl"  #endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) @@ -726,7 +744,7 @@ void main() {  	// to maximize VGPR usage  	// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky. -	if (scene_data.fog_enabled) { +	if (!sc_disable_fog && scene_data.fog_enabled) {  		fog = fog_process(vertex);  	} @@ -744,7 +762,7 @@ void main() {  	vec3 vertex_ddx = dFdx(vertex);  	vec3 vertex_ddy = dFdy(vertex); -	{ //Decals +	if (!sc_disable_decals) { //Decals  		// must implement  		uint decal_indices = draw_call.decals.x; @@ -765,25 +783,35 @@ void main() {  				continue; //out of decal  			} -			//we need ddx/ddy for mipmaps, so simulate them -			vec2 ddx = (decals.data[decal_index].xform * vec4(vertex_ddx, 0.0)).xz; -			vec2 ddy = (decals.data[decal_index].xform * vec4(vertex_ddy, 0.0)).xz; -  			float fade = pow(1.0 - (uv_local.y > 0.0 ? uv_local.y : -uv_local.y), uv_local.y > 0.0 ? decals.data[decal_index].upper_fade : decals.data[decal_index].lower_fade);  			if (decals.data[decal_index].normal_fade > 0.0) {  				fade *= smoothstep(decals.data[decal_index].normal_fade, 1.0, dot(normal_interp, decals.data[decal_index].normal) * 0.5 + 0.5);  			} +			//we need ddx/ddy for mipmaps, so simulate them +			vec2 ddx = (decals.data[decal_index].xform * vec4(vertex_ddx, 0.0)).xz; +			vec2 ddy = (decals.data[decal_index].xform * vec4(vertex_ddy, 0.0)).xz; +  			if (decals.data[decal_index].albedo_rect != vec4(0.0)) {  				//has albedo -				vec4 decal_albedo = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, ddx * decals.data[decal_index].albedo_rect.zw, ddy * decals.data[decal_index].albedo_rect.zw); +				vec4 decal_albedo; +				if (sc_decal_use_mipmaps) { +					decal_albedo = textureGrad(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, ddx * decals.data[decal_index].albedo_rect.zw, ddy * decals.data[decal_index].albedo_rect.zw); +				} else { +					decal_albedo = textureLod(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, 0.0); +				}  				decal_albedo *= decals.data[decal_index].modulate;  				decal_albedo.a *= fade;  				albedo = mix(albedo, decal_albedo.rgb, decal_albedo.a * decals.data[decal_index].albedo_mix);  				if (decals.data[decal_index].normal_rect != vec4(0.0)) { -					vec3 decal_normal = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz; +					vec3 decal_normal; +					if (sc_decal_use_mipmaps) { +						decal_normal = textureGrad(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz; +					} else { +						decal_normal = textureLod(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, 0.0).xyz; +					}  					decal_normal.xy = decal_normal.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); //users prefer flipped y normal maps in most authoring software  					decal_normal.z = sqrt(max(0.0, 1.0 - dot(decal_normal.xy, decal_normal.xy)));  					//convert to view space, use xzy because y is up @@ -793,7 +821,12 @@ void main() {  				}  				if (decals.data[decal_index].orm_rect != vec4(0.0)) { -					vec3 decal_orm = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz; +					vec3 decal_orm; +					if (sc_decal_use_mipmaps) { +						decal_orm = textureGrad(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz; +					} else { +						decal_orm = textureLod(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, 0.0).xyz; +					}  					ao = mix(ao, decal_orm.r, decal_albedo.a);  					roughness = mix(roughness, decal_orm.g, decal_albedo.a);  					metallic = mix(metallic, decal_orm.b, decal_albedo.a); @@ -802,7 +835,11 @@ void main() {  			if (decals.data[decal_index].emission_rect != vec4(0.0)) {  				//emission is additive, so its independent from albedo -				emission += textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, ddx * decals.data[decal_index].emission_rect.zw, ddy * decals.data[decal_index].emission_rect.zw).xyz * decals.data[decal_index].emission_energy * fade; +				if (sc_decal_use_mipmaps) { +					emission += textureGrad(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, ddx * decals.data[decal_index].emission_rect.zw, ddy * decals.data[decal_index].emission_rect.zw).xyz * decals.data[decal_index].emission_energy * fade; +				} else { +					emission += textureLod(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, 0.0).xyz * decals.data[decal_index].emission_energy * fade; +				}  			}  		}  	} //Decals @@ -812,7 +849,7 @@ void main() {  #ifdef NORMAL_USED  	if (scene_data.roughness_limiter_enabled) { -		//http://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf +		//https://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf  		float roughness2 = roughness * roughness;  		vec3 dndu = dFdx(normal), dndv = dFdy(normal);  		float variance = scene_data.roughness_limiter_amount * (dot(dndu, dndu) + dot(dndv, dndv)); @@ -843,6 +880,8 @@ void main() {  		specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, roughness * MAX_ROUGHNESS_LOD).rgb;  #endif //USE_RADIANCE_CUBEMAP_ARRAY +		float horizon = min(1.0 + dot(ref_vec, normal), 1.0); +		specular_light *= horizon * horizon;  		specular_light *= scene_data.ambient_light_color_energy.a;  	} @@ -940,7 +979,7 @@ void main() {  	// skipping ssao, do we remove ssao totally? -	{ //Reflection probes +	if (!sc_disable_reflection_probes) { //Reflection probes  		vec4 reflection_accum = vec4(0.0, 0.0, 0.0, 0.0);  		vec4 ambient_accum = vec4(0.0, 0.0, 0.0, 0.0); @@ -1006,7 +1045,7 @@ void main() {  // LIGHTING  #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) -	{ //directional light +	if (!sc_disable_directional_lights) { //directional light  		// Do shadow and lighting in two passes to reduce register pressure  		uint shadow0 = 0; @@ -1336,7 +1375,7 @@ void main() {  		}  	} //directional light -	{ //omni lights +	if (!sc_disable_omni_lights) { //omni lights  		uint light_indices = draw_call.omni_lights.x;  		for (uint i = 0; i < 8; i++) {  			uint light_index = light_indices & 0xFF; @@ -1350,7 +1389,7 @@ void main() {  				break;  			} -			float shadow = light_process_omni_shadow(light_index, vertex, view); +			float shadow = light_process_omni_shadow(light_index, vertex, normal);  			shadow = blur_shadow(shadow); @@ -1383,7 +1422,7 @@ void main() {  		}  	} //omni lights -	{ //spot lights +	if (!sc_disable_spot_lights) { //spot lights  		uint light_indices = draw_call.spot_lights.x;  		for (uint i = 0; i < 8; i++) { @@ -1398,7 +1437,7 @@ void main() {  				break;  			} -			float shadow = light_process_spot_shadow(light_index, vertex, view); +			float shadow = light_process_spot_shadow(light_index, vertex, normal);  			shadow = blur_shadow(shadow); @@ -1514,12 +1553,15 @@ void main() {  	frag_color = vec4(albedo, alpha);  #else // MODE_UNSHADED  	frag_color = vec4(emission + ambient_light + diffuse_light + specular_light, alpha); -	//frag_color = vec4(1.0);  #endif // MODE_UNSHADED  	// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.  	frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a); +	// On mobile we use a UNORM buffer with 10bpp which results in a range from 0.0 - 1.0 resulting in HDR breaking +	// We divide by sc_luminance_multiplier to support a range from 0.0 - 2.0 both increasing precision on bright and darker images +	frag_color.rgb = frag_color.rgb / sc_luminance_multiplier; +  #endif //MODE_MULTIPLE_RENDER_TARGETS  #endif //MODE_RENDER_DEPTH diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl index d9682d7b23..dd8879acb4 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl @@ -16,12 +16,12 @@  /* don't exceed 128 bytes!! */  /* put instance data into our push content, not a array */  layout(push_constant, binding = 0, std430) uniform DrawCall { -	mat4 transform; // 64 - 64 +	highp mat4 transform; // 64 - 64  	uint flags; // 04 - 68  	uint instance_uniforms_ofs; //base offset in global buffer for instance variables	// 04 - 72  	uint gi_offset; //GI information when using lightmapping (VCT or lightmap index)    // 04 - 76  	uint layer_mask; // 04 - 80 -	vec4 lightmap_uv_scale; // 16 - 96 doubles as uv_offset when needed +	highp vec4 lightmap_uv_scale; // 16 - 96 doubles as uv_offset when needed  	uvec2 reflection_probes; // 08 - 104  	uvec2 omni_lights; // 08 - 112 @@ -93,7 +93,7 @@ directional_lights;  #define LIGHTMAP_FLAG_USE_SPECULAR_DIRECTION 2  struct Lightmap { -	mat3 normal_xform; +	mediump mat3 normal_xform;  };  layout(set = 0, binding = 9, std140) restrict readonly buffer Lightmaps { @@ -102,7 +102,7 @@ layout(set = 0, binding = 9, std140) restrict readonly buffer Lightmaps {  lightmaps;  struct LightmapCapture { -	vec4 sh[9]; +	mediump vec4 sh[9];  };  layout(set = 0, binding = 10, std140) restrict readonly buffer LightmapCaptures { @@ -110,8 +110,8 @@ layout(set = 0, binding = 10, std140) restrict readonly buffer LightmapCaptures  }  lightmap_captures; -layout(set = 0, binding = 11) uniform texture2D decal_atlas; -layout(set = 0, binding = 12) uniform texture2D decal_atlas_srgb; +layout(set = 0, binding = 11) uniform mediump texture2D decal_atlas; +layout(set = 0, binding = 12) uniform mediump texture2D decal_atlas_srgb;  layout(set = 0, binding = 13, std430) restrict readonly buffer Decals {  	DecalData data[]; @@ -119,72 +119,72 @@ layout(set = 0, binding = 13, std430) restrict readonly buffer Decals {  decals;  layout(set = 0, binding = 14, std430) restrict readonly buffer GlobalVariableData { -	vec4 data[]; +	highp vec4 data[];  }  global_variables;  /* Set 1: Render Pass (changes per render pass) */  layout(set = 1, binding = 0, std140) uniform SceneData { -	mat4 projection_matrix; -	mat4 inv_projection_matrix; -	mat4 camera_matrix; -	mat4 inv_camera_matrix; +	highp mat4 projection_matrix; +	highp mat4 inv_projection_matrix; +	highp mat4 camera_matrix; +	highp mat4 inv_camera_matrix;  	// only used for multiview -	mat4 projection_matrix_view[MAX_VIEWS]; -	mat4 inv_projection_matrix_view[MAX_VIEWS]; +	highp mat4 projection_matrix_view[MAX_VIEWS]; +	highp mat4 inv_projection_matrix_view[MAX_VIEWS]; -	vec2 viewport_size; -	vec2 screen_pixel_size; +	highp vec2 viewport_size; +	highp vec2 screen_pixel_size;  	// Use vec4s because std140 doesn't play nice with vec2s, z and w are wasted. -	vec4 directional_penumbra_shadow_kernel[32]; -	vec4 directional_soft_shadow_kernel[32]; -	vec4 penumbra_shadow_kernel[32]; -	vec4 soft_shadow_kernel[32]; +	highp vec4 directional_penumbra_shadow_kernel[32]; +	highp vec4 directional_soft_shadow_kernel[32]; +	highp vec4 penumbra_shadow_kernel[32]; +	highp vec4 soft_shadow_kernel[32]; -	vec4 ambient_light_color_energy; +	mediump vec4 ambient_light_color_energy; -	float ambient_color_sky_mix; +	mediump float ambient_color_sky_mix;  	bool use_ambient_light;  	bool use_ambient_cubemap;  	bool use_reflection_cubemap; -	mat3 radiance_inverse_xform; +	mediump mat3 radiance_inverse_xform; -	vec2 shadow_atlas_pixel_size; -	vec2 directional_shadow_pixel_size; +	highp vec2 shadow_atlas_pixel_size; +	highp vec2 directional_shadow_pixel_size;  	uint directional_light_count; -	float dual_paraboloid_side; -	float z_far; -	float z_near; +	mediump float dual_paraboloid_side; +	highp float z_far; +	highp float z_near;  	bool ssao_enabled; -	float ssao_light_affect; -	float ssao_ao_affect; +	mediump float ssao_light_affect; +	mediump float ssao_ao_affect;  	bool roughness_limiter_enabled; -	float roughness_limiter_amount; -	float roughness_limiter_limit; +	mediump float roughness_limiter_amount; +	mediump float roughness_limiter_limit;  	uvec2 roughness_limiter_pad; -	vec4 ao_color; +	mediump vec4 ao_color;  	bool fog_enabled; -	float fog_density; -	float fog_height; -	float fog_height_density; +	highp float fog_density; +	highp float fog_height; +	highp float fog_height_density; -	vec3 fog_light_color; -	float fog_sun_scatter; +	mediump vec3 fog_light_color; +	mediump float fog_sun_scatter; -	float fog_aerial_perspective; +	mediump float fog_aerial_perspective;  	bool material_uv2_mode; -	float time; -	float reflection_multiplier; // one normally, zero when rendering reflections +	highp float time; +	mediump float reflection_multiplier; // one normally, zero when rendering reflections  	bool pancake_shadows;  	uint pad1; @@ -195,30 +195,30 @@ scene_data;  #ifdef USE_RADIANCE_CUBEMAP_ARRAY -layout(set = 1, binding = 2) uniform textureCubeArray radiance_cubemap; +layout(set = 1, binding = 2) uniform mediump textureCubeArray radiance_cubemap;  #else -layout(set = 1, binding = 2) uniform textureCube radiance_cubemap; +layout(set = 1, binding = 2) uniform mediump textureCube radiance_cubemap;  #endif -layout(set = 1, binding = 3) uniform textureCubeArray reflection_atlas; +layout(set = 1, binding = 3) uniform mediump textureCubeArray reflection_atlas; -layout(set = 1, binding = 4) uniform texture2D shadow_atlas; +layout(set = 1, binding = 4) uniform highp texture2D shadow_atlas; -layout(set = 1, binding = 5) uniform texture2D directional_shadow_atlas; +layout(set = 1, binding = 5) uniform highp texture2D directional_shadow_atlas;  // this needs to change to providing just the lightmap we're using..  layout(set = 1, binding = 6) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES]; -layout(set = 1, binding = 9) uniform texture2D depth_buffer; -layout(set = 1, binding = 10) uniform texture2D color_buffer; +layout(set = 1, binding = 9) uniform highp texture2D depth_buffer; +layout(set = 1, binding = 10) uniform mediump texture2D color_buffer;  /* Set 2 Skeleton & Instancing (can change per item) */  layout(set = 2, binding = 0, std430) restrict readonly buffer Transforms { -	vec4 data[]; +	highp vec4 data[];  }  transforms; diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl index 0eacbc5363..4290d5b869 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl @@ -24,7 +24,7 @@ layout(push_constant, binding = 0, std430) uniform Params {  }  params; -// http://in4k.untergrund.net/html_articles/hugi_27_-_coding_corner_polaris_sphere_tessellation_101.htm +// https://in4k.untergrund.net/html_articles/hugi_27_-_coding_corner_polaris_sphere_tessellation_101.htm  vec3 get_sphere_vertex(uint p_vertex_id) {  	float x_angle = float(p_vertex_id & 1u) + (p_vertex_id >> params.band_power); diff --git a/servers/rendering/renderer_rd/shaders/sky.glsl b/servers/rendering/renderer_rd/shaders/sky.glsl index 41c6325bc5..d07a454ade 100644 --- a/servers/rendering/renderer_rd/shaders/sky.glsl +++ b/servers/rendering/renderer_rd/shaders/sky.glsl @@ -17,6 +17,8 @@ layout(push_constant, binding = 1, std430) uniform Params {  	vec4 projections[MAX_VIEWS];  	vec4 position_multiplier;  	float time; +	float luminance_multiplier; +	float pad[2];  }  params; @@ -55,6 +57,8 @@ layout(push_constant, binding = 1, std430) uniform Params {  	vec4 projections[MAX_VIEWS];  	vec4 position_multiplier;  	float time; +	float luminance_multiplier; +	float pad[2];  }  params; @@ -199,17 +203,17 @@ void main() {  	vec3 inverted_cube_normal = cube_normal;  	inverted_cube_normal.z *= -1.0;  #ifdef USES_HALF_RES_COLOR -	half_res_color = texture(samplerCube(half_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), inverted_cube_normal); +	half_res_color = texture(samplerCube(half_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), inverted_cube_normal) * params.luminance_multiplier;  #endif  #ifdef USES_QUARTER_RES_COLOR -	quarter_res_color = texture(samplerCube(quarter_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), inverted_cube_normal); +	quarter_res_color = texture(samplerCube(quarter_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), inverted_cube_normal) * params.luminance_multiplier;  #endif  #else  #ifdef USES_HALF_RES_COLOR -	half_res_color = textureLod(sampler2D(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0); +	half_res_color = textureLod(sampler2D(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0) * params.luminance_multiplier;  #endif  #ifdef USES_QUARTER_RES_COLOR -	quarter_res_color = textureLod(sampler2D(quarter_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0); +	quarter_res_color = textureLod(sampler2D(quarter_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0) * params.luminance_multiplier;  #endif  #endif @@ -246,4 +250,7 @@ void main() {  	if (!AT_CUBEMAP_PASS && !AT_HALF_RES_PASS && !AT_QUARTER_RES_PASS) {  		frag_color.a = 0.0;  	} + +	// For mobile renderer we're dividing by 2.0 as we're using a UNORM buffer +	frag_color.rgb = frag_color.rgb / params.luminance_multiplier;  } diff --git a/servers/rendering/renderer_rd/shaders/tonemap.glsl b/servers/rendering/renderer_rd/shaders/tonemap.glsl index f028195a74..4411587116 100644 --- a/servers/rendering/renderer_rd/shaders/tonemap.glsl +++ b/servers/rendering/renderer_rd/shaders/tonemap.glsl @@ -37,15 +37,15 @@ layout(location = 0) in vec2 uv_interp;  #ifdef SUBPASS  layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput input_color; -#else -#if MULTIVIEW +#elif defined(MULTIVIEW)  layout(set = 0, binding = 0) uniform sampler2DArray source_color;  #else  layout(set = 0, binding = 0) uniform sampler2D source_color;  #endif -#endif +  layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure;  layout(set = 2, binding = 0) uniform sampler2D source_glow; +  #ifdef USE_1D_LUT  layout(set = 3, binding = 0) uniform sampler2D source_color_correction;  #else @@ -71,7 +71,7 @@ layout(push_constant, binding = 1, std430) uniform Params {  	float exposure;  	float white;  	float auto_exposure_grey; -	uint pad2; +	float luminance_multiplier;  	vec2 pixel_size;  	bool use_fxaa; @@ -184,10 +184,6 @@ vec3 tonemap_aces(vec3 color, float white) {  }  vec3 tonemap_reinhard(vec3 color, float white) { -	// Ensure color values are positive. -	// They can be negative in the case of negative lights, which leads to undesired behavior. -	color = max(vec3(0.0), color); -  	return (white * color + color) / (color * white + white);  } @@ -211,7 +207,7 @@ vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR, always o  		return tonemap_reinhard(color, white);  	} else if (params.tonemapper == TONEMAPPER_FILMIC) {  		return tonemap_filmic(color, white); -	} else { //aces +	} else { // TONEMAPPER_ACES  		return tonemap_aces(color, white);  	}  } @@ -302,15 +298,15 @@ vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) {  	const float FXAA_SPAN_MAX = 8.0;  #ifdef MULTIVIEW -	vec3 rgbNW = textureLod(source_color, vec3(uv_interp + vec2(-1.0, -1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure; -	vec3 rgbNE = textureLod(source_color, vec3(uv_interp + vec2(1.0, -1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure; -	vec3 rgbSW = textureLod(source_color, vec3(uv_interp + vec2(-1.0, 1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure; -	vec3 rgbSE = textureLod(source_color, vec3(uv_interp + vec2(1.0, 1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure; +	vec3 rgbNW = textureLod(source_color, vec3(uv_interp + vec2(-1.0, -1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier; +	vec3 rgbNE = textureLod(source_color, vec3(uv_interp + vec2(1.0, -1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier; +	vec3 rgbSW = textureLod(source_color, vec3(uv_interp + vec2(-1.0, 1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier; +	vec3 rgbSE = textureLod(source_color, vec3(uv_interp + vec2(1.0, 1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier;  #else -	vec3 rgbNW = textureLod(source_color, uv_interp + vec2(-1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure; -	vec3 rgbNE = textureLod(source_color, uv_interp + vec2(1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure; -	vec3 rgbSW = textureLod(source_color, uv_interp + vec2(-1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure; -	vec3 rgbSE = textureLod(source_color, uv_interp + vec2(1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure; +	vec3 rgbNW = textureLod(source_color, uv_interp + vec2(-1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier; +	vec3 rgbNE = textureLod(source_color, uv_interp + vec2(1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier; +	vec3 rgbSW = textureLod(source_color, uv_interp + vec2(-1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier; +	vec3 rgbSE = textureLod(source_color, uv_interp + vec2(1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier;  #endif  	vec3 rgbM = color;  	vec3 luma = vec3(0.299, 0.587, 0.114); @@ -337,11 +333,11 @@ vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) {  		  params.pixel_size;  #ifdef MULTIVIEW -	vec3 rgbA = 0.5 * exposure * (textureLod(source_color, vec3(uv_interp + dir * (1.0 / 3.0 - 0.5), ViewIndex), 0.0).xyz + textureLod(source_color, vec3(uv_interp + dir * (2.0 / 3.0 - 0.5), ViewIndex), 0.0).xyz); -	vec3 rgbB = rgbA * 0.5 + 0.25 * exposure * (textureLod(source_color, vec3(uv_interp + dir * -0.5, ViewIndex), 0.0).xyz + textureLod(source_color, vec3(uv_interp + dir * 0.5, ViewIndex), 0.0).xyz); +	vec3 rgbA = 0.5 * exposure * (textureLod(source_color, vec3(uv_interp + dir * (1.0 / 3.0 - 0.5), ViewIndex), 0.0).xyz + textureLod(source_color, vec3(uv_interp + dir * (2.0 / 3.0 - 0.5), ViewIndex), 0.0).xyz) * params.luminance_multiplier; +	vec3 rgbB = rgbA * 0.5 + 0.25 * exposure * (textureLod(source_color, vec3(uv_interp + dir * -0.5, ViewIndex), 0.0).xyz + textureLod(source_color, vec3(uv_interp + dir * 0.5, ViewIndex), 0.0).xyz) * params.luminance_multiplier;  #else -	vec3 rgbA = 0.5 * exposure * (textureLod(source_color, uv_interp + dir * (1.0 / 3.0 - 0.5), 0.0).xyz + textureLod(source_color, uv_interp + dir * (2.0 / 3.0 - 0.5), 0.0).xyz); -	vec3 rgbB = rgbA * 0.5 + 0.25 * exposure * (textureLod(source_color, uv_interp + dir * -0.5, 0.0).xyz + textureLod(source_color, uv_interp + dir * 0.5, 0.0).xyz); +	vec3 rgbA = 0.5 * exposure * (textureLod(source_color, uv_interp + dir * (1.0 / 3.0 - 0.5), 0.0).xyz + textureLod(source_color, uv_interp + dir * (2.0 / 3.0 - 0.5), 0.0).xyz) * params.luminance_multiplier; +	vec3 rgbB = rgbA * 0.5 + 0.25 * exposure * (textureLod(source_color, uv_interp + dir * -0.5, 0.0).xyz + textureLod(source_color, uv_interp + dir * 0.5, 0.0).xyz) * params.luminance_multiplier;  #endif  	float lumaB = dot(rgbB, luma); @@ -353,7 +349,7 @@ vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) {  }  #endif // !SUBPASS -// From http://alex.vlachos.com/graphics/Alex_Vlachos_Advanced_VR_Rendering_GDC2015.pdf +// From https://alex.vlachos.com/graphics/Alex_Vlachos_Advanced_VR_Rendering_GDC2015.pdf  // and https://www.shadertoy.com/view/MslGR8 (5th one starting from the bottom)  // NOTE: `frag_coord` is in pixels (i.e. not normalized UV).  vec3 screen_space_dither(vec2 frag_coord) { @@ -368,11 +364,11 @@ vec3 screen_space_dither(vec2 frag_coord) {  void main() {  #ifdef SUBPASS  	// SUBPASS and MULTIVIEW can be combined but in that case we're already reading from the correct layer -	vec3 color = subpassLoad(input_color).rgb; -#elif MULTIVIEW -	vec3 color = textureLod(source_color, vec3(uv_interp, ViewIndex), 0.0f).rgb; +	vec3 color = subpassLoad(input_color).rgb * params.luminance_multiplier; +#elif defined(MULTIVIEW) +	vec3 color = textureLod(source_color, vec3(uv_interp, ViewIndex), 0.0f).rgb * params.luminance_multiplier;  #else -	vec3 color = textureLod(source_color, uv_interp, 0.0f).rgb; +	vec3 color = textureLod(source_color, uv_interp, 0.0f).rgb * params.luminance_multiplier;  #endif  	// Exposure @@ -381,7 +377,7 @@ void main() {  #ifndef SUBPASS  	if (params.use_auto_exposure) { -		exposure *= 1.0 / (texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / params.auto_exposure_grey); +		exposure *= 1.0 / (texelFetch(source_auto_exposure, ivec2(0, 0), 0).r * params.luminance_multiplier / params.auto_exposure_grey);  	}  #endif @@ -390,7 +386,7 @@ void main() {  	// Early Tonemap & SRGB Conversion  #ifndef SUBPASS  	if (params.use_glow && params.glow_mode == GLOW_MODE_MIX) { -		vec3 glow = gather_glow(source_glow, uv_interp); +		vec3 glow = gather_glow(source_glow, uv_interp) * params.luminance_multiplier;  		color.rgb = mix(color.rgb, glow, params.glow_intensity);  	} @@ -405,7 +401,9 @@ void main() {  		color += screen_space_dither(gl_FragCoord.xy);  	} -	color = apply_tonemapping(color, params.white); +	// Ensure color values passed to tonemappers are positive. +	// They can be negative in the case of negative lights, which leads to undesired behavior. +	color = apply_tonemapping(max(vec3(0.0), color), params.white);  	color = linear_to_srgb(color); // regular linear -> SRGB conversion @@ -413,7 +411,7 @@ void main() {  	// Glow  	if (params.use_glow && params.glow_mode != GLOW_MODE_MIX) { -		vec3 glow = gather_glow(source_glow, uv_interp) * params.glow_intensity; +		vec3 glow = gather_glow(source_glow, uv_interp) * params.glow_intensity * params.luminance_multiplier;  		// high dynamic range -> SRGB  		glow = apply_tonemapping(glow, params.white); diff --git a/servers/rendering/renderer_rd/shaders/voxel_gi.glsl b/servers/rendering/renderer_rd/shaders/voxel_gi.glsl index 49a493cdc7..779f04ed35 100644 --- a/servers/rendering/renderer_rd/shaders/voxel_gi.glsl +++ b/servers/rendering/renderer_rd/shaders/voxel_gi.glsl @@ -71,11 +71,6 @@ lights;  layout(set = 0, binding = 5) uniform texture3D color_texture; -#ifdef MODE_ANISOTROPIC -layout(set = 0, binding = 7) uniform texture3D aniso_pos_texture; -layout(set = 0, binding = 8) uniform texture3D aniso_neg_texture; -#endif // MODE ANISOTROPIC -  #endif // MODE_SECOND_BOUNCE  #ifndef MODE_DYNAMIC @@ -110,13 +105,6 @@ layout(set = 0, binding = 10) uniform sampler texture_sampler;  layout(rgba8, set = 0, binding = 5) uniform restrict writeonly image3D color_tex; -#ifdef MODE_ANISOTROPIC - -layout(r16ui, set = 0, binding = 6) uniform restrict writeonly uimage3D aniso_pos_tex; -layout(r16ui, set = 0, binding = 7) uniform restrict writeonly uimage3D aniso_neg_tex; - -#endif -  #endif  #ifdef MODE_DYNAMIC @@ -170,13 +158,6 @@ layout(r32f, set = 0, binding = 8) uniform restrict writeonly image2D depth;  layout(rgba8, set = 0, binding = 11) uniform restrict image3D color_texture; -#ifdef MODE_ANISOTROPIC - -layout(r16ui, set = 0, binding = 12) uniform restrict writeonly uimage3D aniso_pos_texture; -layout(r16ui, set = 0, binding = 13) uniform restrict writeonly uimage3D aniso_neg_texture; - -#endif // MODE ANISOTROPIC -  #endif //MODE_DYNAMIC_SHRINK_PLOT  #endif // MODE_DYNAMIC_SHRINK @@ -374,12 +355,7 @@ void main() {  	vec3 emission = vec3(uvec3(cell_data.data[cell_index].emission & 0x1ff, (cell_data.data[cell_index].emission >> 9) & 0x1ff, (cell_data.data[cell_index].emission >> 18) & 0x1ff)) * pow(2.0, float(cell_data.data[cell_index].emission >> 27) - 15.0 - 9.0);  	vec3 normal = unpackSnorm4x8(cell_data.data[cell_index].normal).xyz; -#ifdef MODE_ANISOTROPIC -	vec3 accum[6] = vec3[](vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0)); -	const vec3 accum_dirs[6] = vec3[](vec3(1.0, 0.0, 0.0), vec3(-1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(0.0, -1.0, 0.0), vec3(0.0, 0.0, 1.0), vec3(0.0, 0.0, -1.0)); -#else  	vec3 accum = vec3(0.0); -#endif  	for (uint i = 0; i < params.light_count; i++) {  		vec3 light; @@ -390,38 +366,16 @@ void main() {  		light *= albedo.rgb; -#ifdef MODE_ANISOTROPIC -		for (uint j = 0; j < 6; j++) { -			accum[j] += max(0.0, dot(accum_dirs[j], -light_dir)) * light; -		} -#else  		if (length(normal) > 0.2) {  			accum += max(0.0, dot(normal, -light_dir)) * light;  		} else {  			//all directions  			accum += light;  		} -#endif  	} -#ifdef MODE_ANISOTROPIC - -	for (uint i = 0; i < 6; i++) { -		vec3 light = accum[i]; -		if (length(normal) > 0.2) { -			light += max(0.0, dot(accum_dirs[i], -normal)) * emission; -		} else { -			light += emission; -		} - -		outputs.data[cell_index * 6 + i] = vec4(light, 0.0); -	} - -#else  	outputs.data[cell_index] = vec4(accum + emission, 0.0); -#endif -  #endif //MODE_COMPUTE_LIGHT  	/////////////////SECOND BOUNCE/////////////////////////////// @@ -431,32 +385,8 @@ void main() {  	ivec3 ipos = ivec3(posu);  	vec4 normal = unpackSnorm4x8(cell_data.data[cell_index].normal); -#ifdef MODE_ANISOTROPIC -	vec3 accum[6]; -	const vec3 accum_dirs[6] = vec3[](vec3(1.0, 0.0, 0.0), vec3(-1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(0.0, -1.0, 0.0), vec3(0.0, 0.0, 1.0), vec3(0.0, 0.0, -1.0)); - -	/*vec3 src_color = texelFetch(sampler3D(color_texture,texture_sampler),ipos,0).rgb * params.dynamic_range; -	vec3 src_aniso_pos = texelFetch(sampler3D(aniso_pos_texture,texture_sampler),ipos,0).rgb; -	vec3 src_anisp_neg = texelFetch(sampler3D(anisp_neg_texture,texture_sampler),ipos,0).rgb; -	accum[0]=src_col * src_aniso_pos.x; -	accum[1]=src_col * src_aniso_neg.x; -	accum[2]=src_col * src_aniso_pos.y; -	accum[3]=src_col * src_aniso_neg.y; -	accum[4]=src_col * src_aniso_pos.z; -	accum[5]=src_col * src_aniso_neg.z;*/ - -	accum[0] = outputs.data[cell_index * 6 + 0].rgb; -	accum[1] = outputs.data[cell_index * 6 + 1].rgb; -	accum[2] = outputs.data[cell_index * 6 + 2].rgb; -	accum[3] = outputs.data[cell_index * 6 + 3].rgb; -	accum[4] = outputs.data[cell_index * 6 + 4].rgb; -	accum[5] = outputs.data[cell_index * 6 + 5].rgb; - -#else  	vec3 accum = outputs.data[cell_index].rgb; -#endif -  	if (length(normal.xyz) > 0.2) {  		vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);  		vec3 tangent = normalize(cross(v0, normal.xyz)); @@ -484,9 +414,6 @@ void main() {  				float max_distance = length(vec3(params.limits));  				vec3 cell_size = 1.0 / vec3(params.limits); -#ifdef MODE_ANISOTROPIC -				vec3 aniso_normal = mix(direction, normal.xyz, params.aniso_strength); -#endif  				while (dist < max_distance && color.a < 0.95) {  					float diameter = max(1.0, 2.0 * tan_half_angle * dist);  					vec3 uvw_pos = (pos + dist * direction) * cell_size; @@ -498,42 +425,18 @@ void main() {  					float log2_diameter = log2(diameter);  					vec4 scolor = textureLod(sampler3D(color_texture, texture_sampler), uvw_pos, log2_diameter); -#ifdef MODE_ANISOTROPIC - -					vec3 aniso_neg = textureLod(sampler3D(aniso_neg_texture, texture_sampler), uvw_pos, log2_diameter).rgb; -					vec3 aniso_pos = textureLod(sampler3D(aniso_pos_texture, texture_sampler), uvw_pos, log2_diameter).rgb; - -					scolor.rgb *= dot(max(vec3(0.0), (aniso_normal * aniso_pos)), vec3(1.0)) + dot(max(vec3(0.0), (-aniso_normal * aniso_neg)), vec3(1.0)); -#endif  					float a = (1.0 - color.a);  					color += a * scolor;  					dist += half_diameter;  				}  			}  			color *= cone_weights[i] * vec4(albedo.rgb, 1.0) * params.dynamic_range; //restore range -#ifdef MODE_ANISOTROPIC -			for (uint j = 0; j < 6; j++) { -				accum[j] += max(0.0, dot(accum_dirs[j], direction)) * color.rgb; -			} -#else  			accum += color.rgb; -#endif  		}  	} -#ifdef MODE_ANISOTROPIC - -	outputs.data[cell_index * 6 + 0] = vec4(accum[0], 0.0); -	outputs.data[cell_index * 6 + 1] = vec4(accum[1], 0.0); -	outputs.data[cell_index * 6 + 2] = vec4(accum[2], 0.0); -	outputs.data[cell_index * 6 + 3] = vec4(accum[3], 0.0); -	outputs.data[cell_index * 6 + 4] = vec4(accum[4], 0.0); -	outputs.data[cell_index * 6 + 5] = vec4(accum[5], 0.0); -#else  	outputs.data[cell_index] = vec4(accum, 0.0); -#endif -  #endif // MODE_SECOND_BOUNCE  	/////////////////UPDATE MIPMAPS/////////////////////////////// @@ -541,45 +444,20 @@ void main() {  #ifdef MODE_UPDATE_MIPMAPS  	{ -#ifdef MODE_ANISOTROPIC -		vec3 light_accum[6] = vec3[](vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0)); -#else  		vec3 light_accum = vec3(0.0); -#endif  		float count = 0.0;  		for (uint i = 0; i < 8; i++) {  			uint child_index = cell_children.data[cell_index].children[i];  			if (child_index == NO_CHILDREN) {  				continue;  			} -#ifdef MODE_ANISOTROPIC -			light_accum[0] += outputs.data[child_index * 6 + 0].rgb; -			light_accum[1] += outputs.data[child_index * 6 + 1].rgb; -			light_accum[2] += outputs.data[child_index * 6 + 2].rgb; -			light_accum[3] += outputs.data[child_index * 6 + 3].rgb; -			light_accum[4] += outputs.data[child_index * 6 + 4].rgb; -			light_accum[5] += outputs.data[child_index * 6 + 5].rgb; - -#else  			light_accum += outputs.data[child_index].rgb; -#endif -  			count += 1.0;  		}  		float divisor = mix(8.0, count, params.propagation); -#ifdef MODE_ANISOTROPIC -		outputs.data[cell_index * 6 + 0] = vec4(light_accum[0] / divisor, 0.0); -		outputs.data[cell_index * 6 + 1] = vec4(light_accum[1] / divisor, 0.0); -		outputs.data[cell_index * 6 + 2] = vec4(light_accum[2] / divisor, 0.0); -		outputs.data[cell_index * 6 + 3] = vec4(light_accum[3] / divisor, 0.0); -		outputs.data[cell_index * 6 + 4] = vec4(light_accum[4] / divisor, 0.0); -		outputs.data[cell_index * 6 + 5] = vec4(light_accum[5] / divisor, 0.0); - -#else  		outputs.data[cell_index] = vec4(light_accum / divisor, 0.0); -#endif  	}  #endif @@ -587,40 +465,7 @@ void main() {  #ifdef MODE_WRITE_TEXTURE  	{ -#ifdef MODE_ANISOTROPIC -		vec3 accum_total = vec3(0.0); -		accum_total += outputs.data[cell_index * 6 + 0].rgb; -		accum_total += outputs.data[cell_index * 6 + 1].rgb; -		accum_total += outputs.data[cell_index * 6 + 2].rgb; -		accum_total += outputs.data[cell_index * 6 + 3].rgb; -		accum_total += outputs.data[cell_index * 6 + 4].rgb; -		accum_total += outputs.data[cell_index * 6 + 5].rgb; - -		float accum_total_energy = max(dot(accum_total, GREY_VEC), 0.00001); -		vec3 iso_positive = vec3(dot(outputs.data[cell_index * 6 + 0].rgb, GREY_VEC), dot(outputs.data[cell_index * 6 + 2].rgb, GREY_VEC), dot(outputs.data[cell_index * 6 + 4].rgb, GREY_VEC)) / vec3(accum_total_energy); -		vec3 iso_negative = vec3(dot(outputs.data[cell_index * 6 + 1].rgb, GREY_VEC), dot(outputs.data[cell_index * 6 + 3].rgb, GREY_VEC), dot(outputs.data[cell_index * 6 + 5].rgb, GREY_VEC)) / vec3(accum_total_energy); - -		{ -			uint aniso_pos = uint(clamp(iso_positive.b * 31.0, 0.0, 31.0)); -			aniso_pos |= uint(clamp(iso_positive.g * 63.0, 0.0, 63.0)) << 5; -			aniso_pos |= uint(clamp(iso_positive.r * 31.0, 0.0, 31.0)) << 11; -			imageStore(aniso_pos_tex, ivec3(posu), uvec4(aniso_pos)); -		} - -		{ -			uint aniso_neg = uint(clamp(iso_negative.b * 31.0, 0.0, 31.0)); -			aniso_neg |= uint(clamp(iso_negative.g * 63.0, 0.0, 63.0)) << 5; -			aniso_neg |= uint(clamp(iso_negative.r * 31.0, 0.0, 31.0)) << 11; -			imageStore(aniso_neg_tex, ivec3(posu), uvec4(aniso_neg)); -		} - -		imageStore(color_tex, ivec3(posu), vec4(accum_total / params.dynamic_range, albedo.a)); - -#else -  		imageStore(color_tex, ivec3(posu), vec4(outputs.data[cell_index].rgb / params.dynamic_range, albedo.a)); - -#endif  	}  #endif @@ -763,13 +608,6 @@ void main() {  			color.rgb /= params.dynamic_range;  			imageStore(color_texture, pos3d, color);  			//imageStore(color_texture,pos3d,vec4(1,1,1,1)); - -#ifdef MODE_ANISOTROPIC -			//do not care about anisotropy for dynamic objects, just store full lit in all directions -			imageStore(aniso_pos_texture, pos3d, uvec4(0xFFFF)); -			imageStore(aniso_neg_texture, pos3d, uvec4(0xFFFF)); - -#endif // ANISOTROPIC  		}  #endif // MODE_DYNAMIC_SHRINK_PLOT  	} diff --git a/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl b/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl index 7d4d72967a..281c496df3 100644 --- a/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl +++ b/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl @@ -20,11 +20,6 @@ layout(set = 0, binding = 2) uniform texture3D color_tex;  layout(set = 0, binding = 3) uniform sampler tex_sampler; -#ifdef USE_ANISOTROPY -layout(set = 0, binding = 4) uniform texture3D aniso_pos_tex; -layout(set = 0, binding = 5) uniform texture3D aniso_neg_tex; -#endif -  layout(push_constant, binding = 0, std430) uniform Params {  	mat4 projection;  	uint cell_offset;  |