UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

48 lines (46 loc) 1.78 kB
var reflectionEnvPS = ` #ifndef ENV_ATLAS #define ENV_ATLAS var texture_envAtlas: texture_2d<f32>; var texture_envAtlasSampler: sampler; #endif uniform material_reflectivity: f32; fn shinyMipLevel(uv: vec2f) -> f32 { let dx: vec2f = dpdx(uv); let dy: vec2f = dpdy(uv); let uv2: vec2f = vec2f(fract(uv.x + 0.5), uv.y); let dx2: vec2f = dpdx(uv2); let dy2: vec2f = dpdy(uv2); let maxd: f32 = min(max(dot(dx, dx), dot(dy, dy)), max(dot(dx2, dx2), dot(dy2, dy2))); return clamp(0.5 * log2(maxd) - 1.0 + uniform.textureBias, 0.0, 5.0); } fn calcReflection(reflDir: vec3f, gloss: f32) -> vec3f { let dir: vec3f = cubeMapProject(reflDir) * vec3f(-1.0, 1.0, 1.0); let uv: vec2f = toSphericalUv(dir); let level: f32 = saturate(1.0 - gloss) * 5.0; let ilevel: f32 = floor(level); let level2: f32 = shinyMipLevel(uv * atlasSize); let ilevel2: f32 = floor(level2); var uv0: vec2f; var uv1: vec2f; var weight: f32; if (ilevel == 0.0) { uv0 = mapShinyUv(uv, ilevel2); uv1 = mapShinyUv(uv, ilevel2 + 1.0); weight = level2 - ilevel2; } else { uv0 = mapRoughnessUv(uv, ilevel); uv1 = uv0; weight = 0.0; } let linearA: vec3f = {reflectionDecode}(textureSample(texture_envAtlas, texture_envAtlasSampler, uv0)); let linearB: vec3f = {reflectionDecode}(textureSample(texture_envAtlas, texture_envAtlasSampler, uv1)); let linear0: vec3f = mix(linearA, linearB, weight); let linear1: vec3f = {reflectionDecode}(textureSample(texture_envAtlas, texture_envAtlasSampler, mapRoughnessUv(uv, ilevel + 1.0))); return processEnvironment(mix(linear0, linear1, level - ilevel)); } fn addReflection(reflDir: vec3f, gloss: f32) { dReflection = dReflection + vec4f(calcReflection(reflDir, gloss), uniform.material_reflectivity); } `; export { reflectionEnvPS as default };