UNPKG

@babylonjs/viewer

Version:

The Babylon Viewer aims to simplify a specific but common Babylon.js use case: loading, viewing, and interacting with a 3D model.

90 lines (88 loc) 4.41 kB
const STAGE_FRAGMENT = 2; const IBL_HELPERS = ` fn environmentHorizonOcclusion(V: vec3<f32>, N: vec3<f32>, geoN: vec3<f32>) -> f32 { let R = reflect(V, N); let temp = saturate(1.0 + 1.1 * dot(R, geoN)); return temp * temp; } fn getEnergyConservationFactor(F0: vec3<f32>, brdfY: f32) -> vec3<f32> { return 1.0 + F0 * (1.0 / brdfY - 1.0); } fn rotateY(v: vec3<f32>, angle: f32) -> vec3<f32> { let c = cos(angle); let s = sin(angle); return vec3<f32>(v.x * c + v.z * s, v.y, -v.x * s + v.z * c); } `; function makeIblCalculation(hasNormalMap, anisoBentNormalCode = "", skyboxCalculation = "") { if (skyboxCalculation) { return skyboxCalculation; } const ehoLine = hasNormalMap ? `let eho = environmentHorizonOcclusion(-V, N, N_geom);` : `let eho = 1.0;`; const reflectionDir = anisoBentNormalCode ? anisoBentNormalCode : `let R_raw = reflect(-V, N);`; const irradianceCode = `let environmentIrradiance = (scene.vSphericalL00.rgb + scene.vSphericalL1_1.rgb * N_env.y + scene.vSphericalL10.rgb * N_env.z + scene.vSphericalL11.rgb * N_env.x + scene.vSphericalL2_2.rgb * (N_env.y * N_env.x) + scene.vSphericalL2_1.rgb * (N_env.y * N_env.z) + scene.vSphericalL20.rgb * (3.0 * N_env.z * N_env.z - 1.0) + scene.vSphericalL21.rgb * (N_env.z * N_env.x) + scene.vSphericalL22.rgb * (N_env.x * N_env.x - N_env.y * N_env.y)) * material.environmentIntensity;`; return `${reflectionDir} let R = rotateY(R_raw, scene.envRotationY); let N_env = rotateY(N, scene.envRotationY); let brdf = textureSample(brdfLUT, brdfSampler_, vec2<f32>(NdotV, roughness)); let environmentBrdf = brdf.rgb; let specularEnvironmentReflectance = (colorF90 - colorF0) * environmentBrdf.x + colorF0 * environmentBrdf.y; let seo = clamp((NdotVUnclamped + occlusion) * (NdotVUnclamped + occlusion) - 1.0 + occlusion, 0.0, 1.0); ${ehoLine} let colorSpecularEnvReflectance = specularEnvironmentReflectance * seo * eho; let energyConservation = getEnergyConservationFactor(colorF0, max(environmentBrdf.y, 0.001)); ${irradianceCode} let maxLod = f32(textureNumLevels(iblTexture) - 1); let cubemapDim = f32(textureDimensions(iblTexture).x); var specLod = log2(cubemapDim * alphaG) * scene.vImageInfos.z; var environmentRadiance = textureSampleLevel(iblTexture, iblSampler, R, clamp(specLod, 0.0, maxLod)).rgb * material.environmentIntensity; environmentRadiance = mix(environmentRadiance, environmentIrradiance, alphaG); let finalIrradiance = environmentIrradiance * surfaceAlbedo * occlusion; let finalSpecularScaled = directSpecular * energyConservation; let finalRadianceScaled = environmentRadiance * colorSpecularEnvReflectance * energyConservation; color = finalIrradiance + finalRadianceScaled + finalSpecularScaled + directDiffuse + emissive;`; } function createIblFragment(hasNormalMap, anisoBentNormalCode = "", skyboxCalculation = "") { return { _id: "ibl", // SH coefficients are in the PBR template's baseSceneUboFields (not here) // to preserve fixed scene UBO layout compatibility. _bindings: [ { _name: "brdfLUT", _type: { _kind: "texture", _textureType: "texture_2d<f32>" }, _visibility: STAGE_FRAGMENT }, { _name: "brdfSampler_", _type: { _kind: "sampler", _samplerType: "sampler" }, _visibility: STAGE_FRAGMENT }, { _name: "iblTexture", _type: { _kind: "texture", _textureType: "texture_cube<f32>" }, _visibility: STAGE_FRAGMENT }, { _name: "iblSampler", _type: { _kind: "sampler", _samplerType: "sampler" }, _visibility: STAGE_FRAGMENT } ], _helperFunctions: IBL_HELPERS, _fragmentSlots: { AI: makeIblCalculation(hasNormalMap, anisoBentNormalCode, skyboxCalculation), BA: `luminanceOverAlpha += dot(finalRadianceScaled, vec3<f32>(0.2126, 0.7152, 0.0722));` } }; } const pbrExt = { id: "ibl", phase: "ibl", frag(ctx) { if (!ctx._hasIbl) { return null; } return createIblFragment(ctx._hasAnyNormal, ctx._anisoBentNormalCode ?? "", ctx._iblSkyboxCalc ?? ""); }, bind(ctx, entries, b) { if (!ctx._env) { return b; } entries.push({ binding: b++, resource: ctx._env.brdfLutView }); entries.push({ binding: b++, resource: ctx._env.brdfSampler }); entries.push({ binding: b++, resource: ctx._env.specularCubeView }); entries.push({ binding: b++, resource: ctx._env.cubeSampler }); return b; } }; export { createIblFragment, pbrExt }; //# sourceMappingURL=ibl-fragment-DmZObtww.esm.js.map