Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2020-03-11 19:12:01 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-03-11 19:12:16 +0300
commit7dd0be9554ae7a728ded1a95d4709a93b68301b4 (patch)
tree52a097fd8edd1128def41fcda6bed64e8c6b39b7 /source/blender/draw/engines/eevee/shaders
parentc476c36e400883d929a7149def8dcb6ad6157a86 (diff)
EEVEE: Replace octahedron reflection probe by cubemap array
We implement cubemap array support for EEVEE's lightcache reflection probes. This removes stretched texels and bottom hemisphere seams artifacts caused by the octahedral projection previously used. This introduce versioning code for the lightcache which will discard any lightcache version that is not compatible. Differential Revision: https://developer.blender.org/D7066
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders')
-rw-r--r--source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl130
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl22
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl9
-rw-r--r--source/blender/draw/engines/eevee/shaders/octahedron_lib.glsl18
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));
-}