diff options
author | Juan Linietsky <reduzio@gmail.com> | 2016-12-02 22:23:16 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2016-12-02 22:23:16 -0300 |
commit | 27a46d78ec43b69a70a1d84c540353e3cb3b04c0 (patch) | |
tree | dc4fc077c325b26d6f7a159419fe4ca55bc29783 /drivers/gles3/shaders | |
parent | 8c6a586b75692eaa67ddaf4bb73edf325cc60e5d (diff) |
Subsurface scattering material param is now working!
Diffstat (limited to 'drivers/gles3/shaders')
-rw-r--r-- | drivers/gles3/shaders/SCsub | 2 | ||||
-rw-r--r-- | drivers/gles3/shaders/resolve.glsl | 12 | ||||
-rw-r--r-- | drivers/gles3/shaders/scene.glsl | 42 | ||||
-rw-r--r-- | drivers/gles3/shaders/screen_space_reflection.glsl | 7 | ||||
-rw-r--r-- | drivers/gles3/shaders/subsurf_scattering.glsl | 172 |
5 files changed, 221 insertions, 14 deletions
diff --git a/drivers/gles3/shaders/SCsub b/drivers/gles3/shaders/SCsub index 66a19eefd1..b5797e78b8 100644 --- a/drivers/gles3/shaders/SCsub +++ b/drivers/gles3/shaders/SCsub @@ -11,4 +11,6 @@ if env['BUILDERS'].has_key('GLES3_GLSL'): env.GLES3_GLSL('blend_shape.glsl'); env.GLES3_GLSL('screen_space_reflection.glsl'); env.GLES3_GLSL('effect_blur.glsl'); + env.GLES3_GLSL('subsurf_scattering.glsl'); + diff --git a/drivers/gles3/shaders/resolve.glsl b/drivers/gles3/shaders/resolve.glsl index 4ca6297303..6acc712299 100644 --- a/drivers/gles3/shaders/resolve.glsl +++ b/drivers/gles3/shaders/resolve.glsl @@ -17,11 +17,8 @@ void main() { in vec2 uv_interp; -uniform sampler2D source_diffuse; //texunit:0 -uniform sampler2D source_specular; //texunit:1 - - -uniform sampler2D source_ssr_ssao; //texunit:2 +uniform sampler2D source_specular; //texunit:0 +uniform sampler2D source_ssr; //texunit:1 uniform float stuff; @@ -31,15 +28,14 @@ layout(location = 0) out vec4 frag_color; void main() { - vec4 diffuse = texture( source_diffuse, uv_interp ); vec4 specular = texture( source_specular, uv_interp ); #ifdef USE_SSR - vec4 ssr = textureLod(source_ssr_ssao,uv_interp,0.0); + vec4 ssr = textureLod(source_ssr,uv_interp,0.0); specular.rgb = mix(specular.rgb,ssr.rgb*specular.a,ssr.a); #endif - frag_color = vec4(diffuse.rgb,1.0)+vec4(specular.rgb,1.0); + frag_color = vec4(specular.rgb,1.0); } diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 192042192e..230544c1c3 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -75,6 +75,7 @@ layout(std140) uniform SceneData { //ubo:0 vec2 directional_shadow_pixel_size; float reflection_multiplier; + float subsurface_scatter_width; }; @@ -385,6 +386,7 @@ layout(std140) uniform SceneData { vec2 directional_shadow_pixel_size; float reflection_multiplier; + float subsurface_scatter_width; }; @@ -479,6 +481,9 @@ uniform int reflection_count; layout(location=0) out vec4 diffuse_buffer; layout(location=1) out vec4 specular_buffer; layout(location=2) out vec4 normal_mr_buffer; +#if defined (ENABLE_SSS_MOTION) +layout(location=3) out uint motion_ssr_buffer; +#endif #else @@ -621,6 +626,35 @@ in highp float dp_clip; #endif +#if 0 +//need to save texture depth for this + +vec3 light_transmittance(float translucency,vec3 light_vec, vec3 normal, vec3 pos, float distance) { + + float scale = 8.25 * (1.0 - translucency) / subsurface_scatter_width; + float d = scale * distance; + + /** + * Armed with the thickness, we can now calculate the color by means of the + * precalculated transmittance profile. + * (It can be precomputed into a texture, for maximum performance): + */ + float dd = -d * d; + vec3 profile = vec3(0.233, 0.455, 0.649) * exp(dd / 0.0064) + + vec3(0.1, 0.336, 0.344) * exp(dd / 0.0484) + + vec3(0.118, 0.198, 0.0) * exp(dd / 0.187) + + vec3(0.113, 0.007, 0.007) * exp(dd / 0.567) + + vec3(0.358, 0.004, 0.0) * exp(dd / 1.99) + + vec3(0.078, 0.0, 0.0) * exp(dd / 7.41); + + /** + * Using the profile, we finally approximate the transmitted lighting from + * the back of the object: + */ + return profile * clamp(0.3 + dot(light_vec, normal),0.0,1.0); +} +#endif + void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, vec3 specular, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse_light, inout vec3 specular_light) { vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz-vertex; @@ -870,6 +904,10 @@ void main() { bool discard_=false; #endif +#if defined (ENABLE_SSS_MOTION) + float sss_strength=0.0; +#endif + { @@ -1194,6 +1232,10 @@ LIGHT_SHADER_CODE normal_mr_buffer=vec4(normalize(normal)*0.5+0.5,roughness); +#if defined (ENABLE_SSS_MOTION) + motion_ssr_buffer = uint(clamp(sqrt(sss_strength)*255.0,0.0,255))<<24; +#endif + #else diff --git a/drivers/gles3/shaders/screen_space_reflection.glsl b/drivers/gles3/shaders/screen_space_reflection.glsl index 5b24013c07..ec4bdf86c9 100644 --- a/drivers/gles3/shaders/screen_space_reflection.glsl +++ b/drivers/gles3/shaders/screen_space_reflection.glsl @@ -23,7 +23,6 @@ in vec2 pos_interp; uniform sampler2D source_diffuse; //texunit:0 uniform sampler2D source_normal_roughness; //texunit:1 uniform sampler2D source_depth; //texunit:2 -uniform sampler2D source_diffuse_mipmaps; //texunit:3 uniform float camera_z_near; uniform float camera_z_far; @@ -295,11 +294,7 @@ void main() { vec4 sample_color; { - sample_color = textureLod(source_diffuse_mipmaps,sample_pos,max(1.0,mipmap)); - if (mipmap<1.0) { //we use another image as base to avoid copying all the screen unnecesarily - vec4 base_sample_color = textureLod(source_diffuse,sample_pos,0.0); - sample_color = mix(base_sample_color,sample_color,mipmap); - } + sample_color = textureLod(source_diffuse,sample_pos,mipmap); } //multiply by gloss diff --git a/drivers/gles3/shaders/subsurf_scattering.glsl b/drivers/gles3/shaders/subsurf_scattering.glsl new file mode 100644 index 0000000000..89e618b66c --- /dev/null +++ b/drivers/gles3/shaders/subsurf_scattering.glsl @@ -0,0 +1,172 @@ +[vertex] + + +layout(location=0) in highp vec4 vertex_attrib; +layout(location=4) in vec2 uv_in; + +out vec2 uv_interp; + + +void main() { + + uv_interp = uv_in; + gl_Position = vertex_attrib; +} + +[fragment] + +//#define QUALIFIER uniform // some guy on the interweb says it may be faster with this +#define QUALIFIER const + +#ifdef USE_25_SAMPLES + +const int kernel_size=25; +QUALIFIER vec4 kernel[25] = vec4[] ( + vec4(0.530605, 0.613514, 0.739601, 0.0), + vec4(0.000973794, 1.11862e-005, 9.43437e-007, -3.0), + vec4(0.00333804, 7.85443e-005, 1.2945e-005, -2.52083), + vec4(0.00500364, 0.00020094, 5.28848e-005, -2.08333), + vec4(0.00700976, 0.00049366, 0.000151938, -1.6875), + vec4(0.0094389, 0.00139119, 0.000416598, -1.33333), + vec4(0.0128496, 0.00356329, 0.00132016, -1.02083), + vec4(0.017924, 0.00711691, 0.00347194, -0.75), + vec4(0.0263642, 0.0119715, 0.00684598, -0.520833), + vec4(0.0410172, 0.0199899, 0.0118481, -0.333333), + vec4(0.0493588, 0.0367726, 0.0219485, -0.1875), + vec4(0.0402784, 0.0657244, 0.04631, -0.0833333), + vec4(0.0211412, 0.0459286, 0.0378196, -0.0208333), + vec4(0.0211412, 0.0459286, 0.0378196, 0.0208333), + vec4(0.0402784, 0.0657244, 0.04631, 0.0833333), + vec4(0.0493588, 0.0367726, 0.0219485, 0.1875), + vec4(0.0410172, 0.0199899, 0.0118481, 0.333333), + vec4(0.0263642, 0.0119715, 0.00684598, 0.520833), + vec4(0.017924, 0.00711691, 0.00347194, 0.75), + vec4(0.0128496, 0.00356329, 0.00132016, 1.02083), + vec4(0.0094389, 0.00139119, 0.000416598, 1.33333), + vec4(0.00700976, 0.00049366, 0.000151938, 1.6875), + vec4(0.00500364, 0.00020094, 5.28848e-005, 2.08333), + vec4(0.00333804, 7.85443e-005, 1.2945e-005, 2.52083), + vec4(0.000973794, 1.11862e-005, 9.43437e-007, 3.0) +); + +#endif //USE_25_SAMPLES + +#ifdef USE_17_SAMPLES + +const int kernel_size=17; + +QUALIFIER vec4 kernel[17] = vec4[]( + vec4(0.536343, 0.624624, 0.748867, 0.0), + vec4(0.00317394, 0.000134823, 3.77269e-005, -2.0), + vec4(0.0100386, 0.000914679, 0.000275702, -1.53125), + vec4(0.0144609, 0.00317269, 0.00106399, -1.125), + vec4(0.0216301, 0.00794618, 0.00376991, -0.78125), + vec4(0.0347317, 0.0151085, 0.00871983, -0.5), + vec4(0.0571056, 0.0287432, 0.0172844, -0.28125), + vec4(0.0582416, 0.0659959, 0.0411329, -0.125), + vec4(0.0324462, 0.0656718, 0.0532821, -0.03125), + vec4(0.0324462, 0.0656718, 0.0532821, 0.03125), + vec4(0.0582416, 0.0659959, 0.0411329, 0.125), + vec4(0.0571056, 0.0287432, 0.0172844, 0.28125), + vec4(0.0347317, 0.0151085, 0.00871983, 0.5), + vec4(0.0216301, 0.00794618, 0.00376991, 0.78125), + vec4(0.0144609, 0.00317269, 0.00106399, 1.125), + vec4(0.0100386, 0.000914679, 0.000275702, 1.53125), + vec4(0.00317394, 0.000134823, 3.77269e-005, 2.0) +); + +#endif //USE_17_SAMPLES + + +#ifdef USE_11_SAMPLES + +const int kernel_size=11; + +QUALIFIER vec4 kernel[11] = vec4[]( + vec4(0.560479, 0.669086, 0.784728, 0.0), + vec4(0.00471691, 0.000184771, 5.07566e-005, -2.0), + vec4(0.0192831, 0.00282018, 0.00084214, -1.28), + vec4(0.03639, 0.0130999, 0.00643685, -0.72), + vec4(0.0821904, 0.0358608, 0.0209261, -0.32), + vec4(0.0771802, 0.113491, 0.0793803, -0.08), + vec4(0.0771802, 0.113491, 0.0793803, 0.08), + vec4(0.0821904, 0.0358608, 0.0209261, 0.32), + vec4(0.03639, 0.0130999, 0.00643685, 0.72), + vec4(0.0192831, 0.00282018, 0.00084214, 1.28), + vec4(0.00471691, 0.000184771, 5.07565e-005, 2.0) +); + +#endif //USE_11_SAMPLES + + +uniform float max_radius; +uniform float fovy; +uniform float camera_z_far; +uniform float camera_z_near; +uniform vec2 dir; +in vec2 uv_interp; + +uniform sampler2D source_diffuse; //texunit:0 +uniform highp usampler2D source_motion_ss; //texunit:1 +uniform sampler2D source_depth; //texunit:2 + +layout(location = 0) out vec4 frag_color; + +void main() { + + float strength = float(texture(source_motion_ss,uv_interp).r>>24)*(1.0/255.0); + strength*=strength; //stored as sqrt + + // Fetch color of current pixel: + vec4 base_color = texture(source_diffuse, uv_interp); + + if (strength>0.0) { + + + // Fetch linear depth of current pixel: + float depth = texture(source_depth, uv_interp).r * 2.0 - 1.0; + depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near)); + depth=-depth; + + + // Calculate the radius scale (1.0 for a unit plane sitting on the + // projection window): + float distance = 1.0 / tan(0.5 * fovy); + float scale = distance / -depth; //remember depth is negative by default in OpenGL + + // Calculate the final step to fetch the surrounding pixels: + vec2 step = max_radius * scale * dir; + step *= strength; // Modulate it using the alpha channel. + step *= 1.0 / 3.0; // Divide by 3 as the kernels range from -3 to 3. + + // Accumulate the center sample: + vec3 color_accum = base_color.rgb; + color_accum *= kernel[0].rgb; + + // Accumulate the other samples: + for (int i = 1; i < kernel_size; i++) { + // Fetch color and depth for current sample: + vec2 offset = uv_interp + kernel[i].a * step; + vec3 color = texture(source_diffuse, offset).rgb; + +#ifdef ENABLE_FOLLOW_SURFACE + // If the difference in depth is huge, we lerp color back to "colorM": + float depth_cmp = texture(source_depth, offset).r *2.0 - 1.0; + depth_cmp = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth_cmp * (camera_z_far - camera_z_near)); + depth_cmp=-depth_cmp; + + float s = clamp(300.0f * distance * + max_radius * abs(depth - depth_cmp),0.0,1.0); + color = mix(color, base_color.rgb, s); +#endif + + // Accumulate: + color_accum += kernel[i].rgb * color; + } + + frag_color = vec4(color_accum,base_color.a); //keep alpha (used for SSAO) + } else { + frag_color = base_color; + } +} + |