diff options
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders')
5 files changed, 135 insertions, 47 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl b/source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl new file mode 100644 index 00000000000..90272400915 --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl @@ -0,0 +1,130 @@ + +#ifdef GPU_ARB_texture_cube_map_array + +# define textureLod_cubemapArray(tex, co, lod) textureLod(tex, co, lod) + +#else + +/* Fallback implementation for hardware not supporting cubemap arrays. */ +# define samplerCubeArray sampler2DArray + +float cubemap_face_index(vec3 P) +{ + vec3 aP = abs(P); + if (all(greaterThan(aP.xx, aP.yz))) { + return (P.x > 0.0) ? 0.0 : 1.0; + } + else if (all(greaterThan(aP.yy, aP.xz))) { + return (P.y > 0.0) ? 2.0 : 3.0; + } + else { + return (P.z > 0.0) ? 4.0 : 5.0; + } +} + +vec2 cubemap_face_coord(vec3 P, float face) +{ + if (face < 2.0) { + return (P.zy / P.x) * vec2(-0.5, -sign(P.x) * 0.5) + 0.5; + } + else if (face < 4.0) { + return (P.xz / P.y) * vec2(sign(P.y) * 0.5, 0.5) + 0.5; + } + else { + return (P.xy / P.z) * vec2(0.5, -sign(P.z) * 0.5) + 0.5; + } +} + +vec3 cubemap_adj_x(float face) +{ + bool y_axis = (face == 2.0 || face == 3.0); + return y_axis ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); +} + +vec3 cubemap_adj_y(float face) +{ + bool x_axis = (face < 2.0); + return x_axis ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); +} + +vec3 cubemap_adj_xy(float face) +{ + if (face < 2.0) { + return vec3(0.0, 1.0, 1.0); + } + else if (face < 4.0) { + return vec3(1.0, 0.0, 1.0); + } + else { + return vec3(1.0, 1.0, 0.0); + } +} + +vec4 cubemap_seamless(sampler2DArray tex, vec4 cubevec, float lod) +{ + /* Manual Cube map Layer indexing. */ + float face = cubemap_face_index(cubevec.xyz); + vec2 uv = cubemap_face_coord(cubevec.xyz, face); + vec3 coord = vec3(uv, cubevec.w * 6.0 + face); + + vec4 col = textureLod(tex, coord, lod); + + float cube_size = float(textureSize(tex, int(lod)).x); + + vec2 uv_border = (abs(uv - 0.5) + (0.5 / cube_size - 0.5)) * 2.0 * cube_size; + bvec2 border = greaterThan(uv_border, vec2(0.0)); + if (all(border)) { + /* Corners case. */ + vec3 cubevec_adj; + float face_adj; + /* Get the other face coords. */ + cubevec_adj = cubevec.xyz * cubemap_adj_x(face); + face_adj = cubemap_face_index(cubevec_adj); + /* Still use the original cubevec to get the outer texels or the face. */ + uv = cubemap_face_coord(cubevec.xyz, face_adj); + coord = vec3(uv, cubevec.w * 6.0 + face_adj); + vec4 col1 = textureLod(tex, coord, lod); + + /* Get the 3rd face coords. */ + cubevec_adj = cubevec.xyz * cubemap_adj_y(face); + face_adj = cubemap_face_index(cubevec_adj); + /* Still use the original cubevec to get the outer texels or the face. */ + uv = cubemap_face_coord(cubevec.xyz, face_adj); + coord = vec3(uv, cubevec.w * 6.0 + face_adj); + vec4 col2 = textureLod(tex, coord, lod); + + /* Mix all colors to get the corner color. */ + vec4 col3 = (col + col1 + col2) / 3.0; + + vec2 mix_fac = uv_border * 0.5; + return mix(mix(col, col2, mix_fac.x), mix(col1, col3, mix_fac.x), mix_fac.y); + } + else if (any(border)) { + /* Edges case. */ + /* Get the other face coords. */ + vec3 cubevec_adj = cubevec.xyz * cubemap_adj_xy(face); + face = cubemap_face_index(cubevec_adj); + /* Still use the original cubevec to get the outer texels or the face. */ + uv = cubemap_face_coord(cubevec.xyz, face); + coord = vec3(uv, cubevec.w * 6.0 + face); + + float mix_fac = max(uv_border.x, uv_border.y) * 0.5; + return mix(col, textureLod(tex, coord, lod), mix_fac); + } + else { + return col; + } +} + +vec4 textureLod_cubemapArray(sampler2DArray tex, vec4 cubevec, float lod) +{ + float lod1 = floor(lod); + float lod2 = ceil(lod); + + vec4 col_lod1 = cubemap_seamless(tex, cubevec, lod1); + vec4 col_lod2 = cubemap_seamless(tex, cubevec, lod2); + + return mix(col_lod1, col_lod2, lod - lod1); +} + +#endif diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl index a852dd47872..96fe94fc41e 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl @@ -15,6 +15,5 @@ void main() vec3 view_nor = vec3(quadCoord, sqrt(max(0.0, 1.0 - dist_sqr))); vec3 world_ref = mat3(ViewMatrixInverse) * reflect(vec3(0.0, 0.0, -1.0), view_nor); - FragColor = vec4(textureLod_octahedron(probeCubes, vec4(world_ref, pid), 0.0, prbLodCubeMax).rgb, - 1.0); + FragColor = vec4(textureLod_cubemapArray(probeCubes, vec4(world_ref, pid), 0.0).rgb, 1.0); } diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl index 06c31272ecd..00eb3c7e200 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl @@ -33,29 +33,9 @@ vec3 octahedral_to_cubemap_proj(vec2 co) void main() { - vec2 uvs = gl_FragCoord.xy * texelSize; - - /* Add a N pixel border to ensure filtering is correct - * for N mipmap levels. */ - uvs = (uvs - paddingSize) / (1.0 - 2.0 * paddingSize); - - /* edge mirroring : only mirror if directly adjacent - * (not diagonally adjacent) */ - vec2 m = abs(uvs - 0.5) + 0.5; - vec2 f = floor(m); - if (f.x - f.y != 0.0) { - uvs = 1.0 - uvs; - } - - /* clamp to [0-1] */ - uvs = fract(uvs); - - /* get cubemap vector */ - vec3 cubevec = octahedral_to_cubemap_proj(uvs); - vec3 N, T, B, V; - vec3 R = normalize(cubevec); + vec3 R = normalize(worldPosition); /* Isotropic assumption */ N = V = R; diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl index ab205b78274..6c6db88139b 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl @@ -1,7 +1,7 @@ /* ----------- Uniforms --------- */ uniform sampler2DArray probePlanars; -uniform sampler2DArray probeCubes; +uniform samplerCubeArray probeCubes; /* ----------- Structures --------- */ @@ -172,15 +172,12 @@ vec3 probe_evaluate_cube(int pd_id, vec3 W, vec3 R, float roughness) float fac = saturate(original_roughness * 2.0 - 1.0); R = mix(intersection, R, fac * fac); - return textureLod_octahedron( - probeCubes, vec4(R, float(pd_id)), roughness * prbLodCubeMax, prbLodCubeMax) - .rgb; + return textureLod_cubemapArray(probeCubes, vec4(R, float(pd_id)), roughness * prbLodCubeMax).rgb; } vec3 probe_evaluate_world_spec(vec3 R, float roughness) { - return textureLod_octahedron(probeCubes, vec4(R, 0.0), roughness * prbLodCubeMax, prbLodCubeMax) - .rgb; + return textureLod_cubemapArray(probeCubes, vec4(R, 0.0), roughness * prbLodCubeMax).rgb; } vec3 probe_evaluate_planar( diff --git a/source/blender/draw/engines/eevee/shaders/octahedron_lib.glsl b/source/blender/draw/engines/eevee/shaders/octahedron_lib.glsl index bfb6bc890ec..e05cc2719fa 100644 --- a/source/blender/draw/engines/eevee/shaders/octahedron_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/octahedron_lib.glsl @@ -18,21 +18,3 @@ vec2 mapping_octahedron(vec3 cubevec, vec2 texel_size) return uvs; } - -vec4 textureLod_octahedron(sampler2DArray tex, vec4 cubevec, float lod, float lod_max) -{ - vec2 texelSize = 1.0 / vec2(textureSize(tex, int(lod_max))); - - vec2 uvs = mapping_octahedron(cubevec.xyz, texelSize); - - return textureLod(tex, vec3(uvs, cubevec.w), lod); -} - -vec4 texture_octahedron(sampler2DArray tex, vec4 cubevec) -{ - vec2 texelSize = 1.0 / vec2(textureSize(tex, 0)); - - vec2 uvs = mapping_octahedron(cubevec.xyz, texelSize); - - return texture(tex, vec3(uvs, cubevec.w)); -} |