diff options
author | Juan Linietsky <reduzio@gmail.com> | 2018-09-28 16:40:20 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2018-09-28 16:42:47 -0300 |
commit | f2ed26d71e20b92dbf21693eeea36ccfcc50ced6 (patch) | |
tree | 641b343f7fac36eb4b951c6effb33dbb5a86a51a /drivers/gles2/shaders | |
parent | 40c3c8745df3d08065802762e236beeaa6aa1345 (diff) |
Reflection probe support in GLES2 back-end.
Diffstat (limited to 'drivers/gles2/shaders')
-rw-r--r-- | drivers/gles2/shaders/cubemap_filter.glsl | 1 | ||||
-rw-r--r-- | drivers/gles2/shaders/scene.glsl | 283 |
2 files changed, 282 insertions, 2 deletions
diff --git a/drivers/gles2/shaders/cubemap_filter.glsl b/drivers/gles2/shaders/cubemap_filter.glsl index 2a1ad8d8f2..67b937984e 100644 --- a/drivers/gles2/shaders/cubemap_filter.glsl +++ b/drivers/gles2/shaders/cubemap_filter.glsl @@ -176,7 +176,6 @@ void main() { #ifdef USE_SOURCE_PANORAMA sum.rgb += texturePanorama(source_panorama, L).rgb * NdotL; #else - L.y = -L.y; sum.rgb += textureCubeLod(source_cube, L, 0.0).rgb * NdotL; #endif diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl index da4c3a84f1..b555cee80c 100644 --- a/drivers/gles2/shaders/scene.glsl +++ b/drivers/gles2/shaders/scene.glsl @@ -262,6 +262,35 @@ void light_compute( #endif +#ifdef USE_VERTEX_LIGHTING + +#ifdef USE_REFLECTION_PROBE1 + +uniform mat4 refprobe1_local_matrix; +varying mediump vec4 refprobe1_reflection_normal_blend; +uniform vec3 refprobe1_box_extents; + +#ifndef USE_LIGHTMAP +varying mediump vec3 refprobe1_ambient_normal; +#endif + +#endif //reflection probe1 + +#ifdef USE_REFLECTION_PROBE2 + +uniform mat4 refprobe2_local_matrix; +varying mediump vec4 refprobe2_reflection_normal_blend; +uniform vec3 refprobe2_box_extents; + +#ifndef USE_LIGHTMAP +varying mediump vec3 refprobe2_ambient_normal; +#endif + +#endif //reflection probe2 + +#endif //vertex lighting for refprobes + + void main() { highp vec4 vertex = vertex_attrib; @@ -498,6 +527,52 @@ VERTEX_SHADER_CODE #endif //use shadow and use lighting +#ifdef USE_VERTEX_LIGHTING + +#ifdef USE_REFLECTION_PROBE1 + { + vec3 ref_normal = normalize(reflect(vertex_interp, normal_interp)); + vec3 local_pos = (refprobe1_local_matrix * vec4(vertex_interp, 1.0)).xyz; + vec3 inner_pos = abs(local_pos / refprobe1_box_extents); + float blend = max(inner_pos.x, max(inner_pos.y, inner_pos.z)); + + { + vec3 local_ref_vec = (refprobe1_local_matrix * vec4(ref_normal, 0.0)).xyz; + refprobe1_reflection_normal_blend.xyz = local_ref_vec; + refprobe1_reflection_normal_blend.a = blend; + + } +#ifndef USE_LIGHTMAP + + refprobe1_ambient_normal = (refprobe1_local_matrix * vec4(normal_interp, 0.0)).xyz; +#endif + } + +#endif //USE_REFLECTION_PROBE1 + + +#ifdef USE_REFLECTION_PROBE2 + { + vec3 ref_normal = normalize(reflect(vertex_interp, normal_interp)); + vec3 local_pos = (refprobe2_local_matrix * vec4(vertex_interp, 1.0)).xyz; + vec3 inner_pos = abs(local_pos / refprobe2_box_extents); + float blend = max(inner_pos.x, max(inner_pos.y, inner_pos.z)); + + { + vec3 local_ref_vec = (refprobe2_local_matrix * vec4(ref_normal, 0.0)).xyz; + refprobe2_reflection_normal_blend.xyz = local_ref_vec; + refprobe2_reflection_normal_blend.a = blend; + + } +#ifndef USE_LIGHTMAP + + refprobe2_ambient_normal = (refprobe2_local_matrix * vec4(normal_interp, 0.0)).xyz; +#endif + } + +#endif //USE_REFLECTION_PROBE2 + +#endif //use vertex lighting gl_Position = projection_matrix * vec4(vertex_interp, 1.0); } @@ -548,10 +623,161 @@ uniform vec2 screen_pixel_size; uniform highp sampler2D screen_texture; //texunit:-4 #endif -#ifdef USE_RADIANCE_MAP +#ifdef USE_REFLECTION_PROBE1 + +#ifdef USE_VERTEX_LIGHTING + +varying mediump vec4 refprobe1_reflection_normal_blend; +#ifndef USE_LIGHTMAP +varying mediump vec3 refprobe1_ambient_normal; +#endif + +#else + +uniform bool refprobe1_use_box_project; +uniform vec3 refprobe1_box_extents; +uniform vec3 refprobe1_box_offset; +uniform mat4 refprobe1_local_matrix; + +#endif //use vertex lighting + +uniform bool refprobe1_exterior; + +uniform highp samplerCube reflection_probe1; //texunit:-4 + +uniform float refprobe1_intensity; +uniform vec4 refprobe1_ambient; + +#endif //USE_REFLECTION_PROBE1 + +#ifdef USE_REFLECTION_PROBE2 + +#ifdef USE_VERTEX_LIGHTING + +varying mediump vec4 refprobe2_reflection_normal_blend; +#ifndef USE_LIGHTMAP +varying mediump vec3 refprobe2_ambient_normal; +#endif + +#else + +uniform bool refprobe2_use_box_project; +uniform vec3 refprobe2_box_extents; +uniform vec3 refprobe2_box_offset; +uniform mat4 refprobe2_local_matrix; + +#endif //use vertex lighting + +uniform bool refprobe2_exterior; + +uniform highp samplerCube reflection_probe2; //texunit:-5 + +uniform float refprobe2_intensity; +uniform vec4 refprobe2_ambient; + +#endif //USE_REFLECTION_PROBE2 #define RADIANCE_MAX_LOD 6.0 +#if defined(USE_REFLECTION_PROBE1) || defined(USE_REFLECTION_PROBE2) + +void reflection_process(samplerCube reflection_map, +#ifdef USE_VERTEX_LIGHTING + vec3 ref_normal, +#ifndef USE_LIGHTMAP + vec3 amb_normal, +#endif + float ref_blend, + +#else //no vertex lighting + vec3 normal, vec3 vertex, + mat4 local_matrix, + bool use_box_project, vec3 box_extents, vec3 box_offset, +#endif //vertex lighting + bool exterior,float intensity, vec4 ref_ambient, float roughness, vec3 ambient, vec3 skybox, inout highp vec4 reflection_accum, inout highp vec4 ambient_accum) { + + vec4 reflection; + +#ifdef USE_VERTEX_LIGHTING + + reflection.rgb = textureCubeLod(reflection_map, ref_normal, roughness * RADIANCE_MAX_LOD).rgb; + + float blend = ref_blend; //crappier blend formula for vertex + blend *= blend; + blend = max(0.0, 1.0 - blend); + +#else //fragment lighting + + vec3 local_pos = (local_matrix * vec4(vertex, 1.0)).xyz; + + if (any(greaterThan(abs(local_pos), box_extents))) { //out of the reflection box + return; + } + + vec3 inner_pos = abs(local_pos / box_extents); + float blend = max(inner_pos.x, max(inner_pos.y, inner_pos.z)); + blend = mix(length(inner_pos), blend, blend); + blend *= blend; + blend = max(0.0, 1.0 - blend); + + //reflect and make local + vec3 ref_normal = normalize(reflect(vertex, normal)); + ref_normal = (local_matrix * vec4(ref_normal, 0.0)).xyz; + + if (use_box_project) { //box project + + vec3 nrdir = normalize(ref_normal); + vec3 rbmax = (box_extents - local_pos) / nrdir; + vec3 rbmin = (-box_extents - local_pos) / nrdir; + + vec3 rbminmax = mix(rbmin, rbmax, vec3(greaterThan(nrdir, vec3(0.0, 0.0, 0.0)))); + + float fa = min(min(rbminmax.x, rbminmax.y), rbminmax.z); + vec3 posonbox = local_pos + nrdir * fa; + ref_normal = posonbox - box_offset.xyz; + } + + reflection.rgb = textureCubeLod(reflection_map, ref_normal, roughness * RADIANCE_MAX_LOD).rgb; +#endif + + if (exterior) { + reflection.rgb = mix(skybox, reflection.rgb, blend); + } + reflection.rgb *= intensity; + reflection.a = blend; + reflection.rgb *= blend; + + reflection_accum += reflection; + + +#ifndef USE_LIGHTMAP + + vec4 ambient_out; +#ifndef USE_VERTEX_LIGHTING + + vec3 amb_normal = (local_matrix * vec4(normal, 0.0)).xyz; +#endif + + ambient_out.rgb = textureCubeLod(reflection_map, amb_normal, RADIANCE_MAX_LOD).rgb; + ambient_out.a = blend; + ambient_out.rgb = mix(ref_ambient.rgb, ambient_out.rgb, ref_ambient.a); + if (exterior) { + ambient_out.rgb = mix(ambient, ambient_out.rgb, blend); + } + + ambient_out.rgb *= blend; + ambient_accum += ambient_out; + +#endif +} + +#endif //use refprobe 1 or 2 + + + +#ifdef USE_RADIANCE_MAP + + uniform samplerCube radiance_map; // texunit:-2 uniform mat4 radiance_inverse_xform; @@ -660,6 +886,8 @@ vec3 metallic_to_specular_color(float metallic, float specular, vec3 albedo) { return mix(vec3(dielectric), albedo, metallic); // TODO: reference? } + + /* clang-format off */ FRAGMENT_SHADER_GLOBALS @@ -1123,6 +1351,59 @@ FRAGMENT_SHADER_CODE ambient_light *= ambient_energy; + + +#ifdef USE_REFLECTION_PROBE1 + + vec4 ambient_accum = vec4(0.0); + vec4 reflection_accum = vec4(0.0); + + + reflection_process(reflection_probe1, +#ifdef USE_VERTEX_LIGHTING + refprobe1_reflection_normal_blend.rgb, +#ifndef USE_LIGHTMAP + refprobe1_ambient_normal, +#endif + refprobe1_reflection_normal_blend.a, +#else + normal_interp,vertex_interp,refprobe1_local_matrix, + refprobe1_use_box_project,refprobe1_box_extents,refprobe1_box_offset, +#endif + refprobe1_exterior,refprobe1_intensity, refprobe1_ambient, roughness, + ambient_light, specular_light, reflection_accum, ambient_accum); + + +#ifdef USE_REFLECTION_PROBE2 + + reflection_process(reflection_probe2, +#ifdef USE_VERTEX_LIGHTING + refprobe2_reflection_normal_blend.rgb, +#ifndef USE_LIGHTMAP + refprobe2_ambient_normal, +#endif + refprobe2_reflection_normal_blend.a, +#else + normal_interp,vertex_interp,refprobe2_local_matrix, + refprobe2_use_box_project,refprobe2_box_extents,refprobe2_box_offset, +#endif + refprobe2_exterior,refprobe2_intensity, refprobe2_ambient, roughness, + ambient_light, specular_light, reflection_accum, ambient_accum); + +#endif // USE_REFLECTION_PROBE2 + + if (reflection_accum.a > 0.0) { + specular_light = reflection_accum.rgb / reflection_accum.a; + } + +#ifndef USE_LIGHTMAP + if (ambient_accum.a > 0.0) { + ambient_light = ambient_accum.rgb / ambient_accum.a; + } +#endif + +#endif //use reflection probe 1 + #endif //BASE PASS // |