summaryrefslogtreecommitdiff
path: root/drivers/gles3/shaders/screen_space_reflection.glsl
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles3/shaders/screen_space_reflection.glsl')
-rw-r--r--drivers/gles3/shaders/screen_space_reflection.glsl244
1 files changed, 106 insertions, 138 deletions
diff --git a/drivers/gles3/shaders/screen_space_reflection.glsl b/drivers/gles3/shaders/screen_space_reflection.glsl
index b2e6f7a736..86546319a0 100644
--- a/drivers/gles3/shaders/screen_space_reflection.glsl
+++ b/drivers/gles3/shaders/screen_space_reflection.glsl
@@ -1,8 +1,9 @@
+/* clang-format off */
[vertex]
-
-layout(location=0) in highp vec4 vertex_attrib;
-layout(location=4) in vec2 uv_in;
+layout(location = 0) in highp vec4 vertex_attrib;
+/* clang-format on */
+layout(location = 4) in vec2 uv_in;
out vec2 uv_interp;
out vec2 pos_interp;
@@ -11,13 +12,14 @@ void main() {
uv_interp = uv_in;
gl_Position = vertex_attrib;
- pos_interp.xy=gl_Position.xy;
+ pos_interp.xy = gl_Position.xy;
}
+/* clang-format off */
[fragment]
-
in vec2 uv_interp;
+/* clang-format on */
in vec2 pos_interp;
uniform sampler2D source_diffuse; //texunit:0
@@ -40,81 +42,67 @@ uniform float depth_tolerance;
uniform float distance_fade;
uniform float curve_fade_in;
-
layout(location = 0) out vec4 frag_color;
-
-vec2 view_to_screen(vec3 view_pos,out float w) {
- vec4 projected = projection * vec4(view_pos, 1.0);
- projected.xyz /= projected.w;
- projected.xy = projected.xy * 0.5 + 0.5;
- w=projected.w;
- return projected.xy;
+vec2 view_to_screen(vec3 view_pos, out float w) {
+ vec4 projected = projection * vec4(view_pos, 1.0);
+ projected.xyz /= projected.w;
+ projected.xy = projected.xy * 0.5 + 0.5;
+ w = projected.w;
+ return projected.xy;
}
-
-
#define M_PI 3.14159265359
void main() {
-
- ////
-
- vec4 diffuse = texture( source_diffuse, uv_interp );
- vec4 normal_roughness = texture( source_normal_roughness, uv_interp);
+ vec4 diffuse = texture(source_diffuse, uv_interp);
+ vec4 normal_roughness = texture(source_normal_roughness, uv_interp);
vec3 normal;
-
- normal = normal_roughness.xyz*2.0-1.0;
+ normal = normal_roughness.xyz * 2.0 - 1.0;
float roughness = normal_roughness.w;
- float depth_tex = texture(source_depth,uv_interp).r;
+ float depth_tex = texture(source_depth, uv_interp).r;
- vec4 world_pos = inverse_projection * vec4( uv_interp*2.0-1.0, depth_tex*2.0-1.0, 1.0 );
- vec3 vertex = world_pos.xyz/world_pos.w;
+ vec4 world_pos = inverse_projection * vec4(uv_interp * 2.0 - 1.0, depth_tex * 2.0 - 1.0, 1.0);
+ vec3 vertex = world_pos.xyz / world_pos.w;
vec3 view_dir = normalize(vertex);
vec3 ray_dir = normalize(reflect(view_dir, normal));
- if (dot(ray_dir,normal)<0.001) {
- frag_color=vec4(0.0);
+ if (dot(ray_dir, normal) < 0.001) {
+ frag_color = vec4(0.0);
return;
}
//ray_dir = normalize(view_dir - normal * dot(normal,view_dir) * 2.0);
-
- //ray_dir = normalize(vec3(1,1,-1));
-
+ //ray_dir = normalize(vec3(1, 1, -1));
////////////////
-
- //make ray length and clip it against the near plane (don't want to trace beyond visible)
+ // make ray length and clip it against the near plane (don't want to trace beyond visible)
float ray_len = (vertex.z + ray_dir.z * camera_z_far) > -camera_z_near ? (-camera_z_near - vertex.z) / ray_dir.z : camera_z_far;
- vec3 ray_end = vertex + ray_dir*ray_len;
+ vec3 ray_end = vertex + ray_dir * ray_len;
float w_begin;
- vec2 vp_line_begin = view_to_screen(vertex,w_begin);
+ vec2 vp_line_begin = view_to_screen(vertex, w_begin);
float w_end;
- vec2 vp_line_end = view_to_screen( ray_end, w_end);
- vec2 vp_line_dir = vp_line_end-vp_line_begin;
-
- //we need to interpolate w along the ray, to generate perspective correct reflections
-
- w_begin = 1.0/w_begin;
- w_end = 1.0/w_end;
+ vec2 vp_line_end = view_to_screen(ray_end, w_end);
+ vec2 vp_line_dir = vp_line_end - vp_line_begin;
+ // we need to interpolate w along the ray, to generate perspective correct reflections
+ w_begin = 1.0 / w_begin;
+ w_end = 1.0 / w_end;
- float z_begin = vertex.z*w_begin;
- float z_end = ray_end.z*w_end;
+ float z_begin = vertex.z * w_begin;
+ float z_end = ray_end.z * w_end;
- vec2 line_begin = vp_line_begin/pixel_size;
- vec2 line_dir = vp_line_dir/pixel_size;
+ vec2 line_begin = vp_line_begin / pixel_size;
+ vec2 line_dir = vp_line_dir / pixel_size;
float z_dir = z_end - z_begin;
float w_dir = w_end - w_begin;
-
// clip the line to the viewport edges
float scale_max_x = min(1.0, 0.99 * (1.0 - vp_line_begin.x) / max(1e-5, vp_line_dir.x));
@@ -124,126 +112,114 @@ void main() {
float line_clip = min(scale_max_x, scale_max_y) * min(scale_min_x, scale_min_y);
line_dir *= line_clip;
z_dir *= line_clip;
- w_dir *=line_clip;
+ w_dir *= line_clip;
- //clip z and w advance to line advance
- vec2 line_advance = normalize(line_dir); //down to pixel
- float step_size = length(line_advance)/length(line_dir);
- float z_advance = z_dir*step_size; // adapt z advance to line advance
- float w_advance = w_dir*step_size; // adapt w advance to line advance
+ // clip z and w advance to line advance
+ vec2 line_advance = normalize(line_dir); // down to pixel
+ float step_size = length(line_advance) / length(line_dir);
+ float z_advance = z_dir * step_size; // adapt z advance to line advance
+ float w_advance = w_dir * step_size; // adapt w advance to line advance
- //make line advance faster if direction is closer to pixel edges (this avoids sampling the same pixel twice)
- float advance_angle_adj = 1.0/max(abs(line_advance.x),abs(line_advance.y));
- line_advance*=advance_angle_adj; // adapt z advance to line advance
- z_advance*=advance_angle_adj;
- w_advance*=advance_angle_adj;
+ // make line advance faster if direction is closer to pixel edges (this avoids sampling the same pixel twice)
+ float advance_angle_adj = 1.0 / max(abs(line_advance.x), abs(line_advance.y));
+ line_advance *= advance_angle_adj; // adapt z advance to line advance
+ z_advance *= advance_angle_adj;
+ w_advance *= advance_angle_adj;
vec2 pos = line_begin;
float z = z_begin;
float w = w_begin;
- float z_from=z/w;
- float z_to=z_from;
+ float z_from = z / w;
+ float z_to = z_from;
float depth;
- vec2 prev_pos=pos;
+ vec2 prev_pos = pos;
- bool found=false;
+ bool found = false;
- float steps_taken=0.0;
+ float steps_taken = 0.0;
- for(int i=0;i<num_steps;i++) {
+ for (int i = 0; i < num_steps; i++) {
- pos+=line_advance;
- z+=z_advance;
- w+=w_advance;
+ pos += line_advance;
+ z += z_advance;
+ w += w_advance;
- //convert to linear depth
+ // convert to linear depth
- depth = texture(source_depth, pos*pixel_size).r * 2.0 - 1.0;
+ depth = texture(source_depth, pos * pixel_size).r * 2.0 - 1.0;
#ifdef USE_ORTHOGONAL_PROJECTION
- depth = ((depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0;
+ depth = ((depth + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0;
#else
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
#endif
- depth=-depth;
+ depth = -depth;
z_from = z_to;
- z_to = z/w;
+ z_to = z / w;
- if (depth>z_to) {
- //if depth was surpassed
- if (depth<=max(z_to,z_from)+depth_tolerance) {
- //check the depth tolerance
- found=true;
+ if (depth > z_to) {
+ // if depth was surpassed
+ if (depth <= max(z_to, z_from) + depth_tolerance) {
+ // check the depth tolerance
+ found = true;
}
break;
}
- steps_taken+=1.0;
- prev_pos=pos;
+ steps_taken += 1.0;
+ prev_pos = pos;
}
-
-
-
if (found) {
- float margin_blend=1.0;
+ float margin_blend = 1.0;
-
- vec2 margin = vec2((viewport_size.x+viewport_size.y)*0.5*0.05); //make a uniform margin
- if (any(bvec4(lessThan(pos,-margin),greaterThan(pos,viewport_size+margin)))) {
- //clip outside screen + margin
- frag_color=vec4(0.0);
+ vec2 margin = vec2((viewport_size.x + viewport_size.y) * 0.5 * 0.05); // make a uniform margin
+ if (any(bvec4(lessThan(pos, -margin), greaterThan(pos, viewport_size + margin)))) {
+ // clip outside screen + margin
+ frag_color = vec4(0.0);
return;
}
{
//blend fading out towards external margin
- vec2 margin_grad = mix(pos-viewport_size,-pos,lessThan(pos,vec2(0.0)));
- margin_blend = 1.0-smoothstep(0.0,margin.x,max(margin_grad.x,margin_grad.y));
- //margin_blend=1.0;
-
+ vec2 margin_grad = mix(pos - viewport_size, -pos, lessThan(pos, vec2(0.0)));
+ margin_blend = 1.0 - smoothstep(0.0, margin.x, max(margin_grad.x, margin_grad.y));
+ //margin_blend = 1.0;
}
vec2 final_pos;
float grad;
- grad=steps_taken/float(num_steps);
- float initial_fade = curve_fade_in==0.0 ? 1.0 : pow(clamp(grad,0.0,1.0),curve_fade_in);
- float fade = pow(clamp(1.0-grad,0.0,1.0),distance_fade)*initial_fade;
- final_pos=pos;
-
-
-
-
-
-
+ grad = steps_taken / float(num_steps);
+ float initial_fade = curve_fade_in == 0.0 ? 1.0 : pow(clamp(grad, 0.0, 1.0), curve_fade_in);
+ float fade = pow(clamp(1.0 - grad, 0.0, 1.0), distance_fade) * initial_fade;
+ final_pos = pos;
#ifdef REFLECT_ROUGHNESS
-
vec4 final_color;
- //if roughness is enabled, do screen space cone tracing
+ // if roughness is enabled, do screen space cone tracing
if (roughness > 0.001) {
///////////////////////////////////////////////////////////////////////////////////////
- //use a blurred version (in consecutive mipmaps) of the screen to simulate roughness
+ // use a blurred version (in consecutive mipmaps) of the screen to simulate roughness
- float gloss = 1.0-roughness;
+ float gloss = 1.0 - roughness;
float cone_angle = roughness * M_PI * 0.5;
vec2 cone_dir = final_pos - line_begin;
float cone_len = length(cone_dir);
- cone_dir = normalize(cone_dir); //will be used normalized from now on
+ cone_dir = normalize(cone_dir); // will be used normalized from now on
float max_mipmap = filter_mipmap_levels - 1.0;
- float gloss_mult=gloss;
+ float gloss_mult = gloss;
- float rem_alpha=1.0;
+ float rem_alpha = 1.0;
final_color = vec4(0.0);
- for(int i=0;i<7;i++) {
+ for (int i = 0; i < 7; i++) {
- float op_len = 2.0 * tan(cone_angle) * cone_len; //opposite side of iso triangle
+ float op_len = 2.0 * tan(cone_angle) * cone_len; // opposite side of iso triangle
float radius;
{
- //fit to sphere inside cone (sphere ends at end of cone), something like this:
+ // fit to sphere inside cone (sphere ends at end of cone), something like this:
// ___
// \O/
// V
@@ -257,31 +233,31 @@ void main() {
radius = (a * (sqrt(a2 + fh2) - a)) / (4.0f * h);
}
- //find the place where screen must be sampled
- vec2 sample_pos = ( line_begin + cone_dir * (cone_len - radius) ) * pixel_size;
- //radius is in pixels, so it's natural that log2(radius) maps to the right mipmap for the amount of pixels
- float mipmap = clamp( log2( radius ), 0.0, max_mipmap );
+ // find the place where screen must be sampled
+ vec2 sample_pos = (line_begin + cone_dir * (cone_len - radius)) * pixel_size;
+ // radius is in pixels, so it's natural that log2(radius) maps to the right mipmap for the amount of pixels
+ float mipmap = clamp(log2(radius), 0.0, max_mipmap);
+ //mipmap = max(mipmap - 1.0, 0.0);
- //mipmap = max(mipmap-1.0,0.0);
- //do sampling
+ // do sampling
vec4 sample_color;
{
- sample_color = textureLod(source_diffuse,sample_pos,mipmap);
+ sample_color = textureLod(source_diffuse, sample_pos, mipmap);
}
- //multiply by gloss
- sample_color.rgb*=gloss_mult;
- sample_color.a=gloss_mult;
+ // multiply by gloss
+ sample_color.rgb *= gloss_mult;
+ sample_color.a = gloss_mult;
rem_alpha -= sample_color.a;
- if(rem_alpha < 0.0) {
+ if (rem_alpha < 0.0) {
sample_color.rgb *= (1.0 - abs(rem_alpha));
}
- final_color+=sample_color;
+ final_color += sample_color;
- if (final_color.a>=0.95) {
+ if (final_color.a >= 0.95) {
// This code of accumulating gloss and aborting on near one
// makes sense when you think of cone tracing.
// Think of it as if roughness was 0, then we could abort on the first
@@ -290,29 +266,21 @@ void main() {
break;
}
- cone_len-=radius*2.0; //go to next (smaller) circle.
-
- gloss_mult*=gloss;
-
+ cone_len -= radius * 2.0; // go to next (smaller) circle.
+ gloss_mult *= gloss;
}
} else {
- final_color = textureLod(source_diffuse,final_pos*pixel_size,0.0);
+ final_color = textureLod(source_diffuse, final_pos * pixel_size, 0.0);
}
- frag_color = vec4(final_color.rgb,fade*margin_blend);
+ frag_color = vec4(final_color.rgb, fade * margin_blend);
#else
- frag_color = vec4(textureLod(source_diffuse,final_pos*pixel_size,0.0).rgb,fade*margin_blend);
+ frag_color = vec4(textureLod(source_diffuse, final_pos * pixel_size, 0.0).rgb, fade * margin_blend);
#endif
-
-
} else {
- frag_color = vec4(0.0,0.0,0.0,0.0);
+ frag_color = vec4(0.0, 0.0, 0.0, 0.0);
}
-
-
-
}
-