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:
authorJulian Eisel <julian@blender.org>2020-03-12 17:58:03 +0300
committerJulian Eisel <julian@blender.org>2020-03-12 17:58:03 +0300
commitb86be9b2145458037fd0b17433b7af0efa7b6472 (patch)
treef333625555402992ebb35d258f93eda1130389e6 /source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl
parent00f83ec125207e90bf180b3eb7752d8cb6482a86 (diff)
parentcb6cec904fa14ce0ab10a2a53af5c936d56376cf (diff)
Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl')
-rw-r--r--source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl130
1 files changed, 130 insertions, 0 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