UNPKG

pex-renderer

Version:

Physically Based Renderer for Pex

50 lines (44 loc) 1.46 kB
module.exports = /* glsl */ ` vec2 envMapOctahedral(vec3 dir) { dir /= dot(vec3(1.0), abs(dir)); // Add epsylon to avoid bottom face flickering when sampling irradiance dir += 0.00001; if (dir.y < 0.0) { dir.xy = vec2(1.0 - abs(dir.zx)) * sign(dir.xz); } else { dir.xy = dir.xz; } dir.xy = dir.xy * 0.5; dir.xy += 0.5; // move to center // dir.xy = (dir.xy * 64.0 + 1.0) / 66.0; return dir.xy; } vec2 envMapOctahedral(vec3 dir, float textureSize) { dir /= dot(vec3(1.0), abs(dir)); if (dir.y < 0.0) { dir.xy = vec2(1.0 - abs(dir.zx)) * sign(dir.xz); } else { dir.xy = dir.xz; } dir.xy = dir.xy * 0.5; dir.xy += 0.5; // move to center // center on texels dir.xy += 0.5 / textureSize; dir.xy /= textureSize / (textureSize - 1.0); return dir.xy; } vec2 envMapOctahedral(vec3 dir, float mipmapLevel, float roughnessLevel) { float width = 2048.0; float maxLevel = 11.0; // this should come from log of size float levelSizeInPixels = pow(2.0, 1.0 + mipmapLevel + roughnessLevel); float levelSize = max(64.0, width / levelSizeInPixels); float roughnessLevelWidth = width / pow(2.0, 1.0 + roughnessLevel); float vOffset = (width - pow(2.0, maxLevel - roughnessLevel)); float hOffset = 2.0 * roughnessLevelWidth - pow(2.0, log2(2.0 * roughnessLevelWidth) - mipmapLevel); vec2 uv = envMapOctahedral(dir, levelSize); uv *= levelSize; return (uv + vec2(hOffset, vOffset)) / width; } `