diff options
Diffstat (limited to 'drivers/gles3/shaders')
-rw-r--r-- | drivers/gles3/shaders/cubemap_filter.glsl | 56 | ||||
-rw-r--r-- | drivers/gles3/shaders/scene.glsl | 68 |
2 files changed, 93 insertions, 31 deletions
diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl index 2aec6380f5..88a97a04aa 100644 --- a/drivers/gles3/shaders/cubemap_filter.glsl +++ b/drivers/gles3/shaders/cubemap_filter.glsl @@ -19,9 +19,16 @@ void main() { precision highp float; precision highp int; -#ifdef USE_PANORAMA +#ifdef USE_SOURCE_PANORAMA uniform sampler2D source_panorama; //texunit:0 -#else +#endif + +#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY +uniform sampler2DArray source_dual_paraboloid_array; //texunit:0 +uniform int source_array_index; +#endif + +#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA) uniform samplerCube source_cube; //texunit:0 #endif @@ -169,7 +176,7 @@ vec2 Hammersley(uint i, uint N) { uniform bool z_flip; -#ifdef USE_PANORAMA +#ifdef USE_SOURCE_PANORAMA vec4 texturePanorama(vec3 normal,sampler2D pano ) { @@ -189,6 +196,21 @@ vec4 texturePanorama(vec3 normal,sampler2D pano ) { #endif +#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY + + +vec4 textureDualParaboloidArray(vec3 normal) { + + vec3 norm = normalize(normal); + norm.xy/=1.0+abs(norm.z); + norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25); + norm.y+=max(0.0,sign(-norm.z))*0.5; + return textureLod(source_dual_paraboloid_array, vec3(norm.xy, float(source_array_index) ), 0.0); + +} + +#endif + void main() { #ifdef USE_DUAL_PARABOLOID @@ -198,7 +220,7 @@ void main() { N = normalize(N); if (!z_flip) { - N.y=-N.y; //y is flipped to improve blending between both sides + //N.y=-N.y; //y is flipped to improve blending between both sides } else { N.z=-N.z; } @@ -212,13 +234,24 @@ void main() { #ifdef USE_DIRECT_WRITE -#ifdef USE_PANORAMA +#ifdef USE_SOURCE_PANORAMA frag_color=vec4(texturePanorama(N,source_panorama).rgb,1.0); -#else +#endif + +#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY + + frag_color=vec4(textureDualParaboloidArray(N).rgb,1.0); +#endif + +#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA) + frag_color=vec4(texture(N,source_cube).rgb,1.0); #endif + + + #else vec4 sum = vec4(0.0, 0.0, 0.0, 0.0); @@ -233,9 +266,16 @@ void main() { float ndotl = clamp(dot(N, L),0.0,1.0); if (ndotl>0.0) { -#ifdef USE_PANORAMA +#ifdef USE_SOURCE_PANORAMA sum.rgb += texturePanorama(H,source_panorama).rgb *ndotl; -#else +#endif + +#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY + + sum.rgb += textureDualParaboloidArray(H).rgb *ndotl; +#endif + +#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA) sum.rgb += textureLod(source_cube, H, 0.0).rgb *ndotl; #endif sum.a += ndotl; diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 40a295bc83..f94ca6fcba 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -405,7 +405,6 @@ uniform bool no_ambient_light; #ifdef USE_RADIANCE_MAP -uniform sampler2D radiance_map; //texunit:-2 layout(std140) uniform Radiance { //ubo:2 @@ -415,6 +414,49 @@ layout(std140) uniform Radiance { //ubo:2 }; +#define RADIANCE_MAX_LOD 5.0 + +#ifdef USE_RADIANCE_MAP_ARRAY + +uniform sampler2DArray radiance_map; //texunit:-2 + +vec3 textureDualParaboloid(sampler2DArray p_tex, vec3 p_vec,float p_roughness) { + + vec3 norm = normalize(p_vec); + norm.xy/=1.0+abs(norm.z); + norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25); + + // we need to lie the derivatives (normg) and assume that DP side is always the same + // to get proper texure filtering + vec2 normg=norm.xy; + norm.y+=max(0.0,sign(norm.z))*0.5; + + // thanks to OpenGL spec using floor(layer + 0.5) for texture arrays, + // it's easy to have precision errors using fract() to interpolate layers + // as such, using fixed point to ensure it works. + + float index = p_roughness * RADIANCE_MAX_LOD; + int indexi = int(index * 256.0); + vec3 base = textureGrad(p_tex, vec3(norm.xy, float(indexi/256)),dFdx(normg),dFdy(normg)).xyz; + vec3 next = textureGrad(p_tex, vec3(norm.xy, float(indexi/256+1)),dFdx(normg),dFdy(normg)).xyz; + return mix(base,next,float(indexi%256)/256.0); +} + +#else + +uniform sampler2D radiance_map; //texunit:-2 + +vec3 textureDualParaboloid(sampler2D p_tex, vec3 p_vec,float p_roughness) { + + vec3 norm = normalize(p_vec); + norm.xy/=1.0+abs(norm.z); + norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25); + norm.y+=max(0.0,sign(norm.z))*0.5; + return textureLod(p_tex, norm.xy, p_roughness * RADIANCE_MAX_LOD).xyz; +} + +#endif + #endif /* Material Uniforms */ @@ -1231,23 +1273,7 @@ void gi_probes_compute(vec3 pos, vec3 normal, float roughness, inout vec3 out_sp #endif -vec3 textureDualParabolod(sampler2D p_tex, vec3 p_vec,float p_lod) { - - vec3 norm = normalize(p_vec); - float y_ofs=0.0; - if (norm.z>=0.0) { - - norm.z+=1.0; - y_ofs+=0.5; - } else { - norm.z=1.0 - norm.z; - norm.y=-norm.y; - } - norm.xy/=norm.z; - norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25+y_ofs); - return textureLod(p_tex, norm.xy, p_lod).xyz; -} void main() { @@ -1387,15 +1413,11 @@ FRAGMENT_SHADER_CODE } else { { - -#define RADIANCE_MAX_LOD 5.0 - float lod = roughness * RADIANCE_MAX_LOD; - { //read radiance from dual paraboloid vec3 ref_vec = reflect(-eye_vec,normal); //2.0 * ndotv * normal - view; // reflect(v, n); ref_vec=normalize((radiance_inverse_xform * vec4(ref_vec,0.0)).xyz); - vec3 radiance = textureDualParabolod(radiance_map,ref_vec,lod) * bg_energy; + vec3 radiance = textureDualParaboloid(radiance_map,ref_vec,roughness) * bg_energy; specular_light = radiance; } @@ -1407,7 +1429,7 @@ FRAGMENT_SHADER_CODE { vec3 ambient_dir=normalize((radiance_inverse_xform * vec4(normal,0.0)).xyz); - vec3 env_ambient=textureDualParabolod(radiance_map,ambient_dir,RADIANCE_MAX_LOD) * bg_energy; + vec3 env_ambient=textureDualParaboloid(radiance_map,ambient_dir,1.0) * bg_energy; ambient_light=mix(ambient_light_color.rgb,env_ambient,radiance_ambient_contribution); //ambient_light=vec3(0.0,0.0,0.0); |