Last active
December 3, 2023 05:01
-
-
Save BeRo1985/a099d46c376b636771bbe580d72fd6d6 to your computer and use it in GitHub Desktop.
GLSL Octahedral Texture Mapping with Edge Mirroring and Bilinear Interpolation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// GLSL Octahedral Texture Mapping with Edge Mirroring and Bilinear Interpolation (by Benjamin 'BeRo' Rosseaux) | |
ivec2 wrapOctahedralTexelCoordinates(const in ivec2 texel, const in ivec2 texSize) { | |
ivec2 wrapped = ((texel % texSize) + texSize) % texSize; | |
return ((((abs(texel.x / texSize.x) + int(texel.x < 0)) ^ (abs(texel.y / texSize.y) + int(texel.y < 0))) & 1) != 0) ? (texSize - (wrapped + ivec2(1))) : wrapped; | |
} | |
vec4 textureOctahedralMap(const in sampler2D tex, vec3 direction) { | |
direction = normalize(direction); // just for to make sure that it is normalized | |
vec2 uv = direction.xy / (abs(direction.x) + abs(direction.y) + abs(direction.z)); | |
uv = fma((direction.z < 0.0) ? ((1.0 - abs(uv.yx)) * vec2((uv.x >= 0.0) ? 1.0 : -1.0, (uv.y >= 0.0) ? 1.0 : -1.0)) : uv, vec2(0.5), vec2(0.5)); | |
ivec2 texSize = textureSize(tex, 0).xy; | |
vec2 invTexSize = vec2(1.0) / vec2(texSize); | |
if(any(lessThanEqual(uv, invTexSize)) || any(greaterThanEqual(uv, vec2(1.0) - invTexSize))){ | |
// Handle edges with manual bilinear interpolation using texelFetch for correct octahedral texel edge mirroring | |
uv = fma(uv, texSize, vec2(-0.5)); | |
ivec2 baseCoord = ivec2(floor(uv)); | |
vec2 fractionalPart = uv - vec2(baseCoord); | |
return mix(mix(texelFetch(tex, wrapOctahedralTexelCoordinates(baseCoord + ivec2(0, 0), texSize), 0), | |
texelFetch(tex, wrapOctahedralTexelCoordinates(baseCoord + ivec2(1, 0), texSize), 0), fractionalPart.x), | |
mix(texelFetch(tex, wrapOctahedralTexelCoordinates(baseCoord + ivec2(0, 1), texSize), 0), | |
texelFetch(tex, wrapOctahedralTexelCoordinates(baseCoord + ivec2(1, 1), texSize), 0), fractionalPart.x), fractionalPart.y); | |
}else{ | |
// Non-edge texels can be sampled directly with textureLod | |
return textureLod(tex, uv, 0.0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment