@luma.gl/shadertools 9.1.9 → 9.2.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/dist/dist.dev.js +1614 -3716
  2. package/dist/dist.min.js +278 -484
  3. package/dist/index.cjs +366 -804
  4. package/dist/index.cjs.map +4 -4
  5. package/dist/index.d.ts +0 -6
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +0 -10
  8. package/dist/index.js.map +1 -1
  9. package/dist/lib/shader-assembly/assemble-shaders.d.ts +6 -4
  10. package/dist/lib/shader-assembly/assemble-shaders.d.ts.map +1 -1
  11. package/dist/lib/shader-assembly/assemble-shaders.js +14 -9
  12. package/dist/lib/shader-assembly/assemble-shaders.js.map +1 -1
  13. package/dist/lib/shader-assembly/platform-info.d.ts +1 -1
  14. package/dist/lib/shader-assembly/platform-info.d.ts.map +1 -1
  15. package/dist/lib/shader-module/shader-module.d.ts +1 -1
  16. package/dist/lib/shader-module/shader-module.d.ts.map +1 -1
  17. package/dist/lib/wgsl/get-shader-layout-wgsl.d.ts.map +1 -1
  18. package/dist/lib/wgsl/get-shader-layout-wgsl.js +3 -1
  19. package/dist/lib/wgsl/get-shader-layout-wgsl.js.map +1 -1
  20. package/dist/modules/engine/project/project.d.ts.map +1 -1
  21. package/dist/modules/engine/project/project.js +4 -2
  22. package/dist/modules/engine/project/project.js.map +1 -1
  23. package/dist/modules/lighting/gouraud-material/gouraud-material.js +1 -1
  24. package/dist/modules/lighting/gouraud-material/gouraud-material.js.map +1 -1
  25. package/dist/modules/lighting/lights/{lighting-uniforms-glsl.d.ts → lighting-glsl.d.ts} +1 -1
  26. package/dist/modules/lighting/lights/lighting-glsl.d.ts.map +1 -0
  27. package/dist/modules/lighting/lights/{lighting-uniforms-glsl.js → lighting-glsl.js} +1 -1
  28. package/dist/modules/lighting/lights/lighting-glsl.js.map +1 -0
  29. package/dist/modules/lighting/lights/{lighting-uniforms-wgsl.d.ts → lighting-wgsl.d.ts} +1 -1
  30. package/dist/modules/lighting/lights/lighting-wgsl.d.ts.map +1 -0
  31. package/dist/modules/lighting/lights/{lighting-uniforms-wgsl.js → lighting-wgsl.js} +1 -1
  32. package/dist/modules/lighting/lights/lighting-wgsl.js.map +1 -0
  33. package/dist/modules/lighting/lights/lighting.d.ts +1 -3
  34. package/dist/modules/lighting/lights/lighting.d.ts.map +1 -1
  35. package/dist/modules/lighting/lights/lighting.js +4 -4
  36. package/dist/modules/lighting/lights/lighting.js.map +1 -1
  37. package/dist/modules/lighting/no-material/dirlight.d.ts.map +1 -1
  38. package/dist/modules/lighting/no-material/dirlight.js +1 -2
  39. package/dist/modules/lighting/no-material/dirlight.js.map +1 -1
  40. package/dist/modules/lighting/pbr-material/{pbr-fragment-glsl.d.ts → pbr-material-glsl.d.ts} +2 -1
  41. package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts.map +1 -0
  42. package/dist/modules/lighting/pbr-material/{pbr-fragment-glsl.js → pbr-material-glsl.js} +36 -1
  43. package/dist/modules/lighting/pbr-material/pbr-material-glsl.js.map +1 -0
  44. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts +3 -0
  45. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts.map +1 -0
  46. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js +487 -0
  47. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js.map +1 -0
  48. package/dist/modules/lighting/pbr-material/pbr-material.d.ts +11 -4
  49. package/dist/modules/lighting/pbr-material/pbr-material.d.ts.map +1 -1
  50. package/dist/modules/lighting/pbr-material/pbr-material.js +12 -12
  51. package/dist/modules/lighting/pbr-material/pbr-material.js.map +1 -1
  52. package/dist/modules/lighting/pbr-material/pbr-projection.d.ts.map +1 -1
  53. package/dist/modules/lighting/pbr-material/pbr-projection.js.map +1 -1
  54. package/dist/modules/lighting/phong-material/phong-material.js +1 -1
  55. package/dist/modules/lighting/phong-material/phong-material.js.map +1 -1
  56. package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts +1 -1
  57. package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts.map +1 -1
  58. package/dist/modules/lighting/phong-material/phong-shaders-glsl.js +2 -0
  59. package/dist/modules/lighting/phong-material/phong-shaders-glsl.js.map +1 -1
  60. package/dist/modules/math/random/random.d.ts +1 -0
  61. package/dist/modules/math/random/random.d.ts.map +1 -1
  62. package/dist/modules/math/random/random.js +7 -0
  63. package/dist/modules/math/random/random.js.map +1 -1
  64. package/package.json +3 -3
  65. package/src/index.ts +0 -17
  66. package/src/lib/shader-assembly/assemble-shaders.ts +12 -11
  67. package/src/lib/shader-assembly/platform-info.ts +1 -1
  68. package/src/lib/shader-module/shader-module.ts +1 -1
  69. package/src/lib/wgsl/get-shader-layout-wgsl.ts +7 -5
  70. package/src/modules/engine/project/project.ts +8 -5
  71. package/src/modules/lighting/gouraud-material/gouraud-material.ts +1 -1
  72. package/src/modules/lighting/lights/lighting.ts +4 -4
  73. package/src/modules/lighting/no-material/dirlight.ts +2 -3
  74. package/src/modules/lighting/pbr-material/{pbr-fragment-glsl.ts → pbr-material-glsl.ts} +36 -1
  75. package/src/modules/lighting/pbr-material/pbr-material-wgsl.ts +490 -0
  76. package/src/modules/lighting/pbr-material/pbr-material.ts +12 -12
  77. package/src/modules/lighting/pbr-material/pbr-projection.ts +0 -2
  78. package/src/modules/lighting/phong-material/phong-material.ts +1 -1
  79. package/src/modules/lighting/phong-material/phong-shaders-glsl.ts +2 -0
  80. package/src/modules/math/random/random.ts +8 -0
  81. package/dist/modules/lighting/lights/lighting-uniforms-glsl.d.ts.map +0 -1
  82. package/dist/modules/lighting/lights/lighting-uniforms-glsl.js.map +0 -1
  83. package/dist/modules/lighting/lights/lighting-uniforms-wgsl.d.ts.map +0 -1
  84. package/dist/modules/lighting/lights/lighting-uniforms-wgsl.js.map +0 -1
  85. package/dist/modules/lighting/pbr-material/pbr-fragment-glsl.d.ts.map +0 -1
  86. package/dist/modules/lighting/pbr-material/pbr-fragment-glsl.js.map +0 -1
  87. package/dist/modules/lighting/pbr-material/pbr-uniforms-glsl.d.ts +0 -2
  88. package/dist/modules/lighting/pbr-material/pbr-uniforms-glsl.d.ts.map +0 -1
  89. package/dist/modules/lighting/pbr-material/pbr-uniforms-glsl.js +0 -67
  90. package/dist/modules/lighting/pbr-material/pbr-uniforms-glsl.js.map +0 -1
  91. package/dist/modules/lighting/pbr-material/pbr-vertex-glsl.d.ts +0 -2
  92. package/dist/modules/lighting/pbr-material/pbr-vertex-glsl.d.ts.map +0 -1
  93. package/dist/modules/lighting/pbr-material/pbr-vertex-glsl.js +0 -39
  94. package/dist/modules/lighting/pbr-material/pbr-vertex-glsl.js.map +0 -1
  95. package/dist/modules/module-injectors.d.ts +0 -3
  96. package/dist/modules/module-injectors.d.ts.map +0 -1
  97. package/dist/modules/module-injectors.js +0 -31
  98. package/dist/modules/module-injectors.js.map +0 -1
  99. package/dist/modules-webgl1/geometry/geometry.d.ts +0 -9
  100. package/dist/modules-webgl1/geometry/geometry.d.ts.map +0 -1
  101. package/dist/modules-webgl1/geometry/geometry.js +0 -39
  102. package/dist/modules-webgl1/geometry/geometry.js.map +0 -1
  103. package/dist/modules-webgl1/lighting/dirlight/dirlight.d.ts +0 -10
  104. package/dist/modules-webgl1/lighting/dirlight/dirlight.d.ts.map +0 -1
  105. package/dist/modules-webgl1/lighting/dirlight/dirlight.js +0 -38
  106. package/dist/modules-webgl1/lighting/dirlight/dirlight.js.map +0 -1
  107. package/dist/modules-webgl1/lighting/lights/lights-glsl.d.ts +0 -2
  108. package/dist/modules-webgl1/lighting/lights/lights-glsl.d.ts.map +0 -1
  109. package/dist/modules-webgl1/lighting/lights/lights-glsl.js +0 -40
  110. package/dist/modules-webgl1/lighting/lights/lights-glsl.js.map +0 -1
  111. package/dist/modules-webgl1/lighting/lights/lights.d.ts +0 -38
  112. package/dist/modules-webgl1/lighting/lights/lights.d.ts.map +0 -1
  113. package/dist/modules-webgl1/lighting/lights/lights.js +0 -93
  114. package/dist/modules-webgl1/lighting/lights/lights.js.map +0 -1
  115. package/dist/modules-webgl1/lighting/pbr/pbr-fragment-glsl.d.ts +0 -2
  116. package/dist/modules-webgl1/lighting/pbr/pbr-fragment-glsl.d.ts.map +0 -1
  117. package/dist/modules-webgl1/lighting/pbr/pbr-fragment-glsl.js +0 -393
  118. package/dist/modules-webgl1/lighting/pbr/pbr-fragment-glsl.js.map +0 -1
  119. package/dist/modules-webgl1/lighting/pbr/pbr-vertex-glsl.d.ts +0 -2
  120. package/dist/modules-webgl1/lighting/pbr/pbr-vertex-glsl.d.ts.map +0 -1
  121. package/dist/modules-webgl1/lighting/pbr/pbr-vertex-glsl.js +0 -43
  122. package/dist/modules-webgl1/lighting/pbr/pbr-vertex-glsl.js.map +0 -1
  123. package/dist/modules-webgl1/lighting/pbr/pbr.d.ts +0 -23
  124. package/dist/modules-webgl1/lighting/pbr/pbr.d.ts.map +0 -1
  125. package/dist/modules-webgl1/lighting/pbr/pbr.js +0 -21
  126. package/dist/modules-webgl1/lighting/pbr/pbr.js.map +0 -1
  127. package/dist/modules-webgl1/lighting/phong-lighting/phong-lighting-glsl.d.ts +0 -2
  128. package/dist/modules-webgl1/lighting/phong-lighting/phong-lighting-glsl.d.ts.map +0 -1
  129. package/dist/modules-webgl1/lighting/phong-lighting/phong-lighting-glsl.js +0 -79
  130. package/dist/modules-webgl1/lighting/phong-lighting/phong-lighting-glsl.js.map +0 -1
  131. package/dist/modules-webgl1/lighting/phong-lighting/phong-lighting.d.ts +0 -45
  132. package/dist/modules-webgl1/lighting/phong-lighting/phong-lighting.d.ts.map +0 -1
  133. package/dist/modules-webgl1/lighting/phong-lighting/phong-lighting.js +0 -44
  134. package/dist/modules-webgl1/lighting/phong-lighting/phong-lighting.js.map +0 -1
  135. package/dist/modules-webgl1/math/fp64/fp64-arithmetic-glsl.d.ts +0 -2
  136. package/dist/modules-webgl1/math/fp64/fp64-arithmetic-glsl.d.ts.map +0 -1
  137. package/dist/modules-webgl1/math/fp64/fp64-arithmetic-glsl.js +0 -171
  138. package/dist/modules-webgl1/math/fp64/fp64-arithmetic-glsl.js.map +0 -1
  139. package/dist/modules-webgl1/math/fp64/fp64-functions-glsl.d.ts +0 -2
  140. package/dist/modules-webgl1/math/fp64/fp64-functions-glsl.d.ts.map +0 -1
  141. package/dist/modules-webgl1/math/fp64/fp64-functions-glsl.js +0 -675
  142. package/dist/modules-webgl1/math/fp64/fp64-functions-glsl.js.map +0 -1
  143. package/dist/modules-webgl1/math/fp64/fp64.d.ts +0 -35
  144. package/dist/modules-webgl1/math/fp64/fp64.d.ts.map +0 -1
  145. package/dist/modules-webgl1/math/fp64/fp64.js +0 -38
  146. package/dist/modules-webgl1/math/fp64/fp64.js.map +0 -1
  147. package/dist/modules-webgl1/project/project.d.ts +0 -20
  148. package/dist/modules-webgl1/project/project.d.ts.map +0 -1
  149. package/dist/modules-webgl1/project/project.js +0 -114
  150. package/dist/modules-webgl1/project/project.js.map +0 -1
  151. package/src/modules/lighting/pbr-material/pbr-uniforms-glsl.ts +0 -67
  152. package/src/modules/lighting/pbr-material/pbr-vertex-glsl.ts +0 -39
  153. package/src/modules/module-injectors.ts +0 -32
  154. package/src/modules-webgl1/geometry/geometry.ts +0 -41
  155. package/src/modules-webgl1/lighting/dirlight/dirlight.ts +0 -50
  156. package/src/modules-webgl1/lighting/lights/lights-glsl.ts +0 -40
  157. package/src/modules-webgl1/lighting/lights/lights.ts +0 -143
  158. package/src/modules-webgl1/lighting/pbr/README.md +0 -12
  159. package/src/modules-webgl1/lighting/pbr/pbr-fragment-glsl.ts +0 -396
  160. package/src/modules-webgl1/lighting/pbr/pbr-vertex-glsl.ts +0 -43
  161. package/src/modules-webgl1/lighting/pbr/pbr.ts +0 -23
  162. package/src/modules-webgl1/lighting/phong-lighting/phong-lighting-glsl.ts +0 -79
  163. package/src/modules-webgl1/lighting/phong-lighting/phong-lighting.ts +0 -64
  164. package/src/modules-webgl1/math/fp64/fp64-arithmetic-glsl.ts +0 -171
  165. package/src/modules-webgl1/math/fp64/fp64-functions-glsl.ts +0 -675
  166. package/src/modules-webgl1/math/fp64/fp64.ts +0 -44
  167. package/src/modules-webgl1/project/README.md +0 -52
  168. package/src/modules-webgl1/project/project.ts +0 -135
  169. /package/src/modules/lighting/lights/{lighting-uniforms-glsl.ts → lighting-glsl.ts} +0 -0
  170. /package/src/modules/lighting/lights/{lighting-uniforms-wgsl.ts → lighting-wgsl.ts} +0 -0
@@ -0,0 +1,3 @@
1
+ export declare const pbrMaterialUniforms = "uniform Projection {\n // Projection\n vec3 u_Camera;\n};\n\nuniform pbrMaterialUniforms {\n // Material is unlit\n bool unlit;\n\n // Base color map\n bool baseColorMapEnabled;\n vec4 baseColorFactor;\n\n bool normalMapEnabled; \n float normalScale; // #ifdef HAS_NORMALMAP\n\n bool emissiveMapEnabled;\n vec3 emissiveFactor; // #ifdef HAS_EMISSIVEMAP\n\n vec2 metallicRoughnessValues;\n bool metallicRoughnessMapEnabled;\n\n bool occlusionMapEnabled;\n float occlusionStrength; // #ifdef HAS_OCCLUSIONMAP\n \n bool alphaCutoffEnabled;\n float alphaCutoff; // #ifdef ALPHA_CUTOFF\n \n // IBL\n bool IBLenabled;\n vec2 scaleIBLAmbient; // #ifdef USE_IBL\n \n // debugging flags used for shader output of intermediate PBR variables\n // #ifdef PBR_DEBUG\n vec4 scaleDiffBaseMR;\n vec4 scaleFGDSpec;\n // #endif\n};\n\n// Samplers\n#ifdef HAS_BASECOLORMAP\nuniform sampler2D u_BaseColorSampler;\n#endif\n#ifdef HAS_NORMALMAP\nuniform sampler2D u_NormalSampler;\n#endif\n#ifdef HAS_EMISSIVEMAP\nuniform sampler2D u_EmissiveSampler;\n#endif\n#ifdef HAS_METALROUGHNESSMAP\nuniform sampler2D u_MetallicRoughnessSampler;\n#endif\n#ifdef HAS_OCCLUSIONMAP\nuniform sampler2D u_OcclusionSampler;\n#endif\n#ifdef USE_IBL\nuniform samplerCube u_DiffuseEnvSampler;\nuniform samplerCube u_SpecularEnvSampler;\nuniform sampler2D u_brdfLUT;\n#endif\n\n";
2
+ export declare const source = "struct PBRFragmentInputs {\n pbr_vPosition: vec3f,\n pbr_vUV: vec2f,\n pbr_vTBN: mat3f,\n pbr_vNormal: vec3f\n};\n\nvar fragmentInputs: PBRFragmentInputs;\n\nfn pbr_setPositionNormalTangentUV(position: vec4f, normal: vec4f, tangent: vec4f, uv: vec2f)\n{\n var pos: vec4f = pbrProjection.modelMatrix * position;\n pbr_vPosition = vec3(pos.xyz) / pos.w;\n\n#ifdef HAS_NORMALS\n#ifdef HAS_TANGENTS\n let normalW: vec3f = normalize(vec3(pbrProjection.normalMatrix * vec4(normal.xyz, 0.0)));\n let tangentW: vec3f = normalize(vec3(pbrProjection.modelMatrix * vec4(tangent.xyz, 0.0)));\n let bitangentW: vec3f = cross(normalW, tangentW) * tangent.w;\n fragmentInputs,pbr_vTBN = mat3(tangentW, bitangentW, normalW);\n#else // HAS_TANGENTS != 1\n fragmentInputs.pbr_vNormal = normalize(vec3(pbrProjection.modelMatrix * vec4(normal.xyz, 0.0)));\n#endif\n#endif\n\n#ifdef HAS_UV\n pbr_vUV = uv;\n#else\n pbr_vUV = vec2(0.,0.);\n#endif\n}\n\nstruct pbrMaterialUniforms {\n // Material is unlit\n unlit: uint32,\n\n // Base color map\n baseColorMapEnabled: uint32,\n baseColorFactor: vec4f,\n\n normalMapEnabled : uint32,\n normalScale: f32, // #ifdef HAS_NORMALMAP\n\n emissiveMapEnabled: uint32,\n emissiveFactor: vec3f, // #ifdef HAS_EMISSIVEMAP\n\n metallicRoughnessValues: vec2f,\n metallicRoughnessMapEnabled: uint32,\n\n occlusionMapEnabled: i32,\n occlusionStrength: f32, // #ifdef HAS_OCCLUSIONMAP\n \n alphaCutoffEnabled: i32,\n alphaCutoff: f32, // #ifdef ALPHA_CUTOFF\n \n // IBL\n IBLenabled: i32,\n scaleIBLAmbient: vec2f, // #ifdef USE_IBL\n \n // debugging flags used for shader output of intermediate PBR variables\n // #ifdef PBR_DEBUG\n scaleDiffBaseMR: vec4f,\n scaleFGDSpec: vec4f\n // #endif\n} \n \n@binding(2) @group(0) var<uniform> material : pbrMaterialUniforms;\n\n// Samplers\n#ifdef HAS_BASECOLORMAP\nuniform sampler2D pbr_baseColorSampler;\n#endif\n#ifdef HAS_NORMALMAP\nuniform sampler2D pbr_normalSampler;\n#endif\n#ifdef HAS_EMISSIVEMAP\nuniform sampler2D pbr_emissiveSampler;\n#endif\n#ifdef HAS_METALROUGHNESSMAP\nuniform sampler2D pbr_metallicRoughnessSampler;\n#endif\n#ifdef HAS_OCCLUSIONMAP\nuniform sampler2D pbr_occlusionSampler;\n#endif\n#ifdef USE_IBL\nuniform samplerCube pbr_diffuseEnvSampler;\nuniform samplerCube pbr_specularEnvSampler;\nuniform sampler2D pbr_brdfLUT;\n#endif\n\n// Encapsulate the various inputs used by the various functions in the shading equation\n// We store values in this struct to simplify the integration of alternative implementations\n// of the shading terms, outlined in the Readme.MD Appendix.\nstruct PBRInfo {\n NdotL: f32, // cos angle between normal and light direction\n NdotV: f32, // cos angle between normal and view direction\n NdotH: f32, // cos angle between normal and half vector\n LdotH: f32, // cos angle between light direction and half vector\n VdotH: f32, // cos angle between view direction and half vector\n perceptualRoughness: f32, // roughness value, as authored by the model creator (input to shader)\n metalness: f32, // metallic value at the surface\n reflectance0: vec3f, // full reflectance color (normal incidence angle)\n reflectance90: vec3f, // reflectance color at grazing angle\n alphaRoughness: f32, // roughness mapped to a more linear change in the roughness (proposed by [2])\n diffuseColor: vec3f, // color contribution from diffuse lighting\n specularColor: vec3f, // color contribution from specular lighting\n n: vec3f, // normal at surface point\n v: vec3f, // vector from surface point to camera\n};\n\nconst M_PI = 3.141592653589793;\nconst c_MinRoughness = 0.04;\n\nfn SRGBtoLINEAR(srgbIn: vec4f ) -> vec4f\n{\n#ifdef MANUAL_SRGB\n#ifdef SRGB_FAST_APPROXIMATION\n var linOut: vec3f = pow(srgbIn.xyz,vec3(2.2));\n#else // SRGB_FAST_APPROXIMATION\n var bLess: vec3f = step(vec3(0.04045),srgbIn.xyz);\n var linOut: vec3f = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess );\n#endif //SRGB_FAST_APPROXIMATION\n return vec4f(linOut,srgbIn.w);;\n#else //MANUAL_SRGB\n return srgbIn;\n#endif //MANUAL_SRGB\n}\n\n// Find the normal for this fragment, pulling either from a predefined normal map\n// or from the interpolated mesh normal and tangent attributes.\nfn getNormal() -> vec3f\n{\n // Retrieve the tangent space matrix\n#ifndef HAS_TANGENTS\n var pos_dx: vec3f = dFdx(pbr_vPosition);\n var pos_dy: vec3f = dFdy(pbr_vPosition);\n var tex_dx: vec3f = dFdx(vec3(pbr_vUV, 0.0));\n var tex_dy: vec3f = dFdy(vec3(pbr_vUV, 0.0));\n var t: vec3f = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t);\n\n#ifdef HAS_NORMALS\n var ng: vec3f = normalize(pbr_vNormal);\n#else\n var ng: vec3f = cross(pos_dx, pos_dy);\n#endif\n\n t = normalize(t - ng * dot(ng, t));\n var b: vec3f = normalize(cross(ng, t));\n var tbn: mat3f = mat3f(t, b, ng);\n#else // HAS_TANGENTS\n var tbn: mat3f = pbr_vTBN;\n#endif\n\n#ifdef HAS_NORMALMAP\n vec3 n = texture(pbr_normalSampler, pbr_vUV).rgb;\n n = normalize(tbn * ((2.0 * n - 1.0) * vec3(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));\n#else\n // The tbn matrix is linearly interpolated, so we need to re-normalize\n vec3 n = normalize(tbn[2].xyz);\n#endif\n\n return n;\n}\n\n// Calculation of the lighting contribution from an optional Image Based Light source.\n// Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].\n// See our README.md on Environment Maps [3] for additional discussion.\n#ifdef USE_IBL\nfn getIBLContribution(PBRInfo pbrInfo, vec3 n, vec3 reflection) -> vec3f\n{\n float mipCount = 9.0; // resolution of 512x512\n float lod = (pbrInfo.perceptualRoughness * mipCount);\n // retrieve a scale and bias to F0. See [1], Figure 3\n vec3 brdf = SRGBtoLINEAR(texture(pbr_brdfLUT,\n vec2(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness))).rgb;\n vec3 diffuseLight = SRGBtoLINEAR(texture(pbr_diffuseEnvSampler, n)).rgb;\n\n#ifdef USE_TEX_LOD\n vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection, lod)).rgb;\n#else\n vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection)).rgb;\n#endif\n\n vec3 diffuse = diffuseLight * pbrInfo.diffuseColor;\n vec3 specular = specularLight * (pbrInfo.specularColor * brdf.x + brdf.y);\n\n // For presentation, this allows us to disable IBL terms\n diffuse *= pbrMaterial.scaleIBLAmbient.x;\n specular *= pbrMaterial.scaleIBLAmbient.y;\n\n return diffuse + specular;\n}\n#endif\n\n// Basic Lambertian diffuse\n// Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog\n// See also [1], Equation 1\nfn diffuse(pbrInfo: PBRInfo) -> vec3<f32> {\n return pbrInfo.diffuseColor / PI;\n}\n\n// The following equation models the Fresnel reflectance term of the spec equation (aka F())\n// Implementation of fresnel from [4], Equation 15\nfn specularReflection(pbrInfo: PBRInfo) -> vec3<f32> {\n return pbrInfo.reflectance0 +\n (pbrInfo.reflectance90 - pbrInfo.reflectance0) *\n pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);\n}\n\n// This calculates the specular geometric attenuation (aka G()),\n// where rougher material will reflect less light back to the viewer.\n// This implementation is based on [1] Equation 4, and we adopt their modifications to\n// alphaRoughness as input as originally proposed in [2].\nfn geometricOcclusion(pbrInfo: PBRInfo) -> f32 {\n let NdotL: f32 = pbrInfo.NdotL;\n let NdotV: f32 = pbrInfo.NdotV;\n let r: f32 = pbrInfo.alphaRoughness;\n\n let attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));\n let attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));\n return attenuationL * attenuationV;\n}\n\n// The following equation(s) model the distribution of microfacet normals across\n// the area being drawn (aka D())\n// Implementation from \"Average Irregularity Representation of a Roughened Surface\n// for Ray Reflection\" by T. S. Trowbridge, and K. P. Reitz\n// Follows the distribution function recommended in the SIGGRAPH 2013 course notes\n// from EPIC Games [1], Equation 3.\nfn microfacetDistribution(pbrInfo: PBRInfo) -> f32 {\n let roughnessSq = pbrInfo.alphaRoughness * pbrInfo.alphaRoughness;\n let f = (pbrInfo.NdotH * roughnessSq - pbrInfo.NdotH) * pbrInfo.NdotH + 1.0;\n return roughnessSq / (PI * f * f);\n}\n\nfn PBRInfo_setAmbientLight(pbrInfo: ptr<function, PBRInfo>) {\n (*pbrInfo).NdotL = 1.0;\n (*pbrInfo).NdotH = 0.0;\n (*pbrInfo).LdotH = 0.0;\n (*pbrInfo).VdotH = 1.0;\n}\n\nfn PBRInfo_setDirectionalLight(pbrInfo: ptr<function, PBRInfo>, lightDirection: vec3<f32>) {\n let n = (*pbrInfo).n;\n let v = (*pbrInfo).v;\n let l = normalize(lightDirection); // Vector from surface point to light\n let h = normalize(l + v); // Half vector between both l and v\n\n (*pbrInfo).NdotL = clamp(dot(n, l), 0.001, 1.0);\n (*pbrInfo).NdotH = clamp(dot(n, h), 0.0, 1.0);\n (*pbrInfo).LdotH = clamp(dot(l, h), 0.0, 1.0);\n (*pbrInfo).VdotH = clamp(dot(v, h), 0.0, 1.0);\n}\n\nfn PBRInfo_setPointLight(pbrInfo: ptr<function, PBRInfo>, pointLight: PointLight) {\n let light_direction = normalize(pointLight.position - pbr_vPosition);\n PBRInfo_setDirectionalLight(pbrInfo, light_direction);\n}\n\nfn calculateFinalColor(pbrInfo: PBRInfo, lightColor: vec3<f32>) -> vec3<f32> {\n // Calculate the shading terms for the microfacet specular shading model\n let F = specularReflection(pbrInfo);\n let G = geometricOcclusion(pbrInfo);\n let D = microfacetDistribution(pbrInfo);\n\n // Calculation of analytical lighting contribution\n let diffuseContrib = (1.0 - F) * diffuse(pbrInfo);\n let specContrib = F * G * D / (4.0 * pbrInfo.NdotL * pbrInfo.NdotV);\n // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)\n return pbrInfo.NdotL * lightColor * (diffuseContrib + specContrib);\n}\n\nfn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {\n // The albedo may be defined from a base texture or a flat color\n var baseColor: vec4<f32>;\n #ifdef HAS_BASECOLORMAP\n baseColor = SRGBtoLINEAR(textureSample(pbr_baseColorSampler, pbr_baseColorSampler, pbr_vUV)) * pbrMaterial.baseColorFactor;\n #else\n baseColor = pbrMaterial.baseColorFactor;\n #endif\n\n #ifdef ALPHA_CUTOFF\n if (baseColor.a < pbrMaterial.alphaCutoff) {\n discard;\n }\n #endif\n\n var color = vec3<f32>(0.0, 0.0, 0.0);\n\n if (pbrMaterial.unlit) {\n color = baseColor.rgb;\n } else {\n // Metallic and Roughness material properties are packed together\n // In glTF, these factors can be specified by fixed scalar values\n // or from a metallic-roughness map\n var perceptualRoughness = pbrMaterial.metallicRoughnessValues.y;\n var metallic = pbrMaterial.metallicRoughnessValues.x;\n #ifdef HAS_METALROUGHNESSMAP\n // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.\n // This layout intentionally reserves the 'r' channel for (optional) occlusion map data\n let mrSample = textureSample(pbr_metallicRoughnessSampler, pbr_metallicRoughnessSampler, pbr_vUV);\n perceptualRoughness = mrSample.g * perceptualRoughness;\n metallic = mrSample.b * metallic;\n #endif\n perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);\n metallic = clamp(metallic, 0.0, 1.0);\n // Roughness is authored as perceptual roughness; as is convention,\n // convert to material roughness by squaring the perceptual roughness [2].\n let alphaRoughness = perceptualRoughness * perceptualRoughness;\n\n let f0 = vec3<f32>(0.04);\n var diffuseColor = baseColor.rgb * (vec3<f32>(1.0) - f0);\n diffuseColor *= 1.0 - metallic;\n let specularColor = mix(f0, baseColor.rgb, metallic);\n\n // Compute reflectance.\n let reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);\n\n // For typical incident reflectance range (between 4% to 100%) set the grazing\n // reflectance to 100% for typical fresnel effect.\n // For very low reflectance range on highly diffuse objects (below 4%),\n // incrementally reduce grazing reflectance to 0%.\n let reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);\n let specularEnvironmentR0 = specularColor;\n let specularEnvironmentR90 = vec3<f32>(1.0, 1.0, 1.0) * reflectance90;\n\n let n = getNormal(); // normal at surface point\n let v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera\n\n let NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);\n let reflection = -normalize(reflect(v, n));\n\n var pbrInfo = PBRInfo(\n 0.0, // NdotL\n NdotV,\n 0.0, // NdotH\n 0.0, // LdotH\n 0.0, // VdotH\n perceptualRoughness,\n metallic,\n specularEnvironmentR0,\n specularEnvironmentR90,\n alphaRoughness,\n diffuseColor,\n specularColor,\n n,\n v\n );\n\n #ifdef USE_LIGHTS\n // Apply ambient light\n PBRInfo_setAmbientLight(&pbrInfo);\n color += calculateFinalColor(pbrInfo, lighting.ambientColor);\n\n // Apply directional light\n for (var i = 0; i < lighting.directionalLightCount; i++) {\n if (i < lighting.directionalLightCount) {\n PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);\n color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);\n }\n }\n\n // Apply point light\n for (var i = 0; i < lighting.pointLightCount; i++) {\n if (i < lighting.pointLightCount) {\n PBRInfo_setPointLight(&pbrInfo, lighting_getPointLight(i));\n let attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));\n color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);\n }\n }\n #endif\n\n // Calculate lighting contribution from image based lighting source (IBL)\n #ifdef USE_IBL\n if (pbrMaterial.IBLenabled) {\n color += getIBLContribution(pbrInfo, n, reflection);\n }\n #endif\n\n // Apply optional PBR terms for additional (optional) shading\n #ifdef HAS_OCCLUSIONMAP\n if (pbrMaterial.occlusionMapEnabled) {\n let ao = textureSample(pbr_occlusionSampler, pbr_occlusionSampler, pbr_vUV).r;\n color = mix(color, color * ao, pbrMaterial.occlusionStrength);\n }\n #endif\n\n #ifdef HAS_EMISSIVEMAP\n if (pbrMaterial.emissiveMapEnabled) {\n let emissive = SRGBtoLINEAR(textureSample(pbr_emissiveSampler, pbr_emissiveSampler, pbr_vUV)).rgb * pbrMaterial.emissiveFactor;\n color += emissive;\n }\n #endif\n\n // This section uses mix to override final color for reference app visualization\n // of various parameters in the lighting equation.\n #ifdef PBR_DEBUG\n // TODO: Figure out how to debug multiple lights\n\n // color = mix(color, F, pbr_scaleFGDSpec.x);\n // color = mix(color, vec3(G), pbr_scaleFGDSpec.y);\n // color = mix(color, vec3(D), pbr_scaleFGDSpec.z);\n // color = mix(color, specContrib, pbr_scaleFGDSpec.w);\n\n // color = mix(color, diffuseContrib, pbr_scaleDiffBaseMR.x);\n color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);\n color = mix(color, vec3<f32>(metallic), pbrMaterial.scaleDiffBaseMR.z);\n color = mix(color, vec3<f32>(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);\n #endif\n }\n\n return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), baseColor.a);\n}\n";
3
+ //# sourceMappingURL=pbr-material-wgsl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbr-material-wgsl.d.ts","sourceRoot":"","sources":["../../../../src/modules/lighting/pbr-material/pbr-material-wgsl.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,mBAAmB,01CA8D/B,CAAC;AAEF,eAAO,MAAM,MAAM,09eA8ZlB,CAAC"}
@@ -0,0 +1,487 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+ // Attribution:
5
+ // MIT license, Copyright (c) 2016-2017 Mohamad Moneimne and Contributors
6
+ // This fragment shader defines a reference implementation for Physically Based Shading of
7
+ // a microfacet surface material defined by a glTF model.
8
+ // TODO - better do the checks outside of shader
9
+ export const pbrMaterialUniforms = /* wgsl */ `\
10
+ uniform Projection {
11
+ // Projection
12
+ vec3 u_Camera;
13
+ };
14
+
15
+ uniform pbrMaterialUniforms {
16
+ // Material is unlit
17
+ bool unlit;
18
+
19
+ // Base color map
20
+ bool baseColorMapEnabled;
21
+ vec4 baseColorFactor;
22
+
23
+ bool normalMapEnabled;
24
+ float normalScale; // #ifdef HAS_NORMALMAP
25
+
26
+ bool emissiveMapEnabled;
27
+ vec3 emissiveFactor; // #ifdef HAS_EMISSIVEMAP
28
+
29
+ vec2 metallicRoughnessValues;
30
+ bool metallicRoughnessMapEnabled;
31
+
32
+ bool occlusionMapEnabled;
33
+ float occlusionStrength; // #ifdef HAS_OCCLUSIONMAP
34
+
35
+ bool alphaCutoffEnabled;
36
+ float alphaCutoff; // #ifdef ALPHA_CUTOFF
37
+
38
+ // IBL
39
+ bool IBLenabled;
40
+ vec2 scaleIBLAmbient; // #ifdef USE_IBL
41
+
42
+ // debugging flags used for shader output of intermediate PBR variables
43
+ // #ifdef PBR_DEBUG
44
+ vec4 scaleDiffBaseMR;
45
+ vec4 scaleFGDSpec;
46
+ // #endif
47
+ };
48
+
49
+ // Samplers
50
+ #ifdef HAS_BASECOLORMAP
51
+ uniform sampler2D u_BaseColorSampler;
52
+ #endif
53
+ #ifdef HAS_NORMALMAP
54
+ uniform sampler2D u_NormalSampler;
55
+ #endif
56
+ #ifdef HAS_EMISSIVEMAP
57
+ uniform sampler2D u_EmissiveSampler;
58
+ #endif
59
+ #ifdef HAS_METALROUGHNESSMAP
60
+ uniform sampler2D u_MetallicRoughnessSampler;
61
+ #endif
62
+ #ifdef HAS_OCCLUSIONMAP
63
+ uniform sampler2D u_OcclusionSampler;
64
+ #endif
65
+ #ifdef USE_IBL
66
+ uniform samplerCube u_DiffuseEnvSampler;
67
+ uniform samplerCube u_SpecularEnvSampler;
68
+ uniform sampler2D u_brdfLUT;
69
+ #endif
70
+
71
+ `;
72
+ export const source = /* wgsl */ `\
73
+ struct PBRFragmentInputs {
74
+ pbr_vPosition: vec3f,
75
+ pbr_vUV: vec2f,
76
+ pbr_vTBN: mat3f,
77
+ pbr_vNormal: vec3f
78
+ };
79
+
80
+ var fragmentInputs: PBRFragmentInputs;
81
+
82
+ fn pbr_setPositionNormalTangentUV(position: vec4f, normal: vec4f, tangent: vec4f, uv: vec2f)
83
+ {
84
+ var pos: vec4f = pbrProjection.modelMatrix * position;
85
+ pbr_vPosition = vec3(pos.xyz) / pos.w;
86
+
87
+ #ifdef HAS_NORMALS
88
+ #ifdef HAS_TANGENTS
89
+ let normalW: vec3f = normalize(vec3(pbrProjection.normalMatrix * vec4(normal.xyz, 0.0)));
90
+ let tangentW: vec3f = normalize(vec3(pbrProjection.modelMatrix * vec4(tangent.xyz, 0.0)));
91
+ let bitangentW: vec3f = cross(normalW, tangentW) * tangent.w;
92
+ fragmentInputs,pbr_vTBN = mat3(tangentW, bitangentW, normalW);
93
+ #else // HAS_TANGENTS != 1
94
+ fragmentInputs.pbr_vNormal = normalize(vec3(pbrProjection.modelMatrix * vec4(normal.xyz, 0.0)));
95
+ #endif
96
+ #endif
97
+
98
+ #ifdef HAS_UV
99
+ pbr_vUV = uv;
100
+ #else
101
+ pbr_vUV = vec2(0.,0.);
102
+ #endif
103
+ }
104
+
105
+ struct pbrMaterialUniforms {
106
+ // Material is unlit
107
+ unlit: uint32,
108
+
109
+ // Base color map
110
+ baseColorMapEnabled: uint32,
111
+ baseColorFactor: vec4f,
112
+
113
+ normalMapEnabled : uint32,
114
+ normalScale: f32, // #ifdef HAS_NORMALMAP
115
+
116
+ emissiveMapEnabled: uint32,
117
+ emissiveFactor: vec3f, // #ifdef HAS_EMISSIVEMAP
118
+
119
+ metallicRoughnessValues: vec2f,
120
+ metallicRoughnessMapEnabled: uint32,
121
+
122
+ occlusionMapEnabled: i32,
123
+ occlusionStrength: f32, // #ifdef HAS_OCCLUSIONMAP
124
+
125
+ alphaCutoffEnabled: i32,
126
+ alphaCutoff: f32, // #ifdef ALPHA_CUTOFF
127
+
128
+ // IBL
129
+ IBLenabled: i32,
130
+ scaleIBLAmbient: vec2f, // #ifdef USE_IBL
131
+
132
+ // debugging flags used for shader output of intermediate PBR variables
133
+ // #ifdef PBR_DEBUG
134
+ scaleDiffBaseMR: vec4f,
135
+ scaleFGDSpec: vec4f
136
+ // #endif
137
+ }
138
+
139
+ @binding(2) @group(0) var<uniform> material : pbrMaterialUniforms;
140
+
141
+ // Samplers
142
+ #ifdef HAS_BASECOLORMAP
143
+ uniform sampler2D pbr_baseColorSampler;
144
+ #endif
145
+ #ifdef HAS_NORMALMAP
146
+ uniform sampler2D pbr_normalSampler;
147
+ #endif
148
+ #ifdef HAS_EMISSIVEMAP
149
+ uniform sampler2D pbr_emissiveSampler;
150
+ #endif
151
+ #ifdef HAS_METALROUGHNESSMAP
152
+ uniform sampler2D pbr_metallicRoughnessSampler;
153
+ #endif
154
+ #ifdef HAS_OCCLUSIONMAP
155
+ uniform sampler2D pbr_occlusionSampler;
156
+ #endif
157
+ #ifdef USE_IBL
158
+ uniform samplerCube pbr_diffuseEnvSampler;
159
+ uniform samplerCube pbr_specularEnvSampler;
160
+ uniform sampler2D pbr_brdfLUT;
161
+ #endif
162
+
163
+ // Encapsulate the various inputs used by the various functions in the shading equation
164
+ // We store values in this struct to simplify the integration of alternative implementations
165
+ // of the shading terms, outlined in the Readme.MD Appendix.
166
+ struct PBRInfo {
167
+ NdotL: f32, // cos angle between normal and light direction
168
+ NdotV: f32, // cos angle between normal and view direction
169
+ NdotH: f32, // cos angle between normal and half vector
170
+ LdotH: f32, // cos angle between light direction and half vector
171
+ VdotH: f32, // cos angle between view direction and half vector
172
+ perceptualRoughness: f32, // roughness value, as authored by the model creator (input to shader)
173
+ metalness: f32, // metallic value at the surface
174
+ reflectance0: vec3f, // full reflectance color (normal incidence angle)
175
+ reflectance90: vec3f, // reflectance color at grazing angle
176
+ alphaRoughness: f32, // roughness mapped to a more linear change in the roughness (proposed by [2])
177
+ diffuseColor: vec3f, // color contribution from diffuse lighting
178
+ specularColor: vec3f, // color contribution from specular lighting
179
+ n: vec3f, // normal at surface point
180
+ v: vec3f, // vector from surface point to camera
181
+ };
182
+
183
+ const M_PI = 3.141592653589793;
184
+ const c_MinRoughness = 0.04;
185
+
186
+ fn SRGBtoLINEAR(srgbIn: vec4f ) -> vec4f
187
+ {
188
+ #ifdef MANUAL_SRGB
189
+ #ifdef SRGB_FAST_APPROXIMATION
190
+ var linOut: vec3f = pow(srgbIn.xyz,vec3(2.2));
191
+ #else // SRGB_FAST_APPROXIMATION
192
+ var bLess: vec3f = step(vec3(0.04045),srgbIn.xyz);
193
+ var linOut: vec3f = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess );
194
+ #endif //SRGB_FAST_APPROXIMATION
195
+ return vec4f(linOut,srgbIn.w);;
196
+ #else //MANUAL_SRGB
197
+ return srgbIn;
198
+ #endif //MANUAL_SRGB
199
+ }
200
+
201
+ // Find the normal for this fragment, pulling either from a predefined normal map
202
+ // or from the interpolated mesh normal and tangent attributes.
203
+ fn getNormal() -> vec3f
204
+ {
205
+ // Retrieve the tangent space matrix
206
+ #ifndef HAS_TANGENTS
207
+ var pos_dx: vec3f = dFdx(pbr_vPosition);
208
+ var pos_dy: vec3f = dFdy(pbr_vPosition);
209
+ var tex_dx: vec3f = dFdx(vec3(pbr_vUV, 0.0));
210
+ var tex_dy: vec3f = dFdy(vec3(pbr_vUV, 0.0));
211
+ var t: vec3f = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t);
212
+
213
+ #ifdef HAS_NORMALS
214
+ var ng: vec3f = normalize(pbr_vNormal);
215
+ #else
216
+ var ng: vec3f = cross(pos_dx, pos_dy);
217
+ #endif
218
+
219
+ t = normalize(t - ng * dot(ng, t));
220
+ var b: vec3f = normalize(cross(ng, t));
221
+ var tbn: mat3f = mat3f(t, b, ng);
222
+ #else // HAS_TANGENTS
223
+ var tbn: mat3f = pbr_vTBN;
224
+ #endif
225
+
226
+ #ifdef HAS_NORMALMAP
227
+ vec3 n = texture(pbr_normalSampler, pbr_vUV).rgb;
228
+ n = normalize(tbn * ((2.0 * n - 1.0) * vec3(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));
229
+ #else
230
+ // The tbn matrix is linearly interpolated, so we need to re-normalize
231
+ vec3 n = normalize(tbn[2].xyz);
232
+ #endif
233
+
234
+ return n;
235
+ }
236
+
237
+ // Calculation of the lighting contribution from an optional Image Based Light source.
238
+ // Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
239
+ // See our README.md on Environment Maps [3] for additional discussion.
240
+ #ifdef USE_IBL
241
+ fn getIBLContribution(PBRInfo pbrInfo, vec3 n, vec3 reflection) -> vec3f
242
+ {
243
+ float mipCount = 9.0; // resolution of 512x512
244
+ float lod = (pbrInfo.perceptualRoughness * mipCount);
245
+ // retrieve a scale and bias to F0. See [1], Figure 3
246
+ vec3 brdf = SRGBtoLINEAR(texture(pbr_brdfLUT,
247
+ vec2(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness))).rgb;
248
+ vec3 diffuseLight = SRGBtoLINEAR(texture(pbr_diffuseEnvSampler, n)).rgb;
249
+
250
+ #ifdef USE_TEX_LOD
251
+ vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection, lod)).rgb;
252
+ #else
253
+ vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection)).rgb;
254
+ #endif
255
+
256
+ vec3 diffuse = diffuseLight * pbrInfo.diffuseColor;
257
+ vec3 specular = specularLight * (pbrInfo.specularColor * brdf.x + brdf.y);
258
+
259
+ // For presentation, this allows us to disable IBL terms
260
+ diffuse *= pbrMaterial.scaleIBLAmbient.x;
261
+ specular *= pbrMaterial.scaleIBLAmbient.y;
262
+
263
+ return diffuse + specular;
264
+ }
265
+ #endif
266
+
267
+ // Basic Lambertian diffuse
268
+ // Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog
269
+ // See also [1], Equation 1
270
+ fn diffuse(pbrInfo: PBRInfo) -> vec3<f32> {
271
+ return pbrInfo.diffuseColor / PI;
272
+ }
273
+
274
+ // The following equation models the Fresnel reflectance term of the spec equation (aka F())
275
+ // Implementation of fresnel from [4], Equation 15
276
+ fn specularReflection(pbrInfo: PBRInfo) -> vec3<f32> {
277
+ return pbrInfo.reflectance0 +
278
+ (pbrInfo.reflectance90 - pbrInfo.reflectance0) *
279
+ pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);
280
+ }
281
+
282
+ // This calculates the specular geometric attenuation (aka G()),
283
+ // where rougher material will reflect less light back to the viewer.
284
+ // This implementation is based on [1] Equation 4, and we adopt their modifications to
285
+ // alphaRoughness as input as originally proposed in [2].
286
+ fn geometricOcclusion(pbrInfo: PBRInfo) -> f32 {
287
+ let NdotL: f32 = pbrInfo.NdotL;
288
+ let NdotV: f32 = pbrInfo.NdotV;
289
+ let r: f32 = pbrInfo.alphaRoughness;
290
+
291
+ let attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));
292
+ let attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));
293
+ return attenuationL * attenuationV;
294
+ }
295
+
296
+ // The following equation(s) model the distribution of microfacet normals across
297
+ // the area being drawn (aka D())
298
+ // Implementation from "Average Irregularity Representation of a Roughened Surface
299
+ // for Ray Reflection" by T. S. Trowbridge, and K. P. Reitz
300
+ // Follows the distribution function recommended in the SIGGRAPH 2013 course notes
301
+ // from EPIC Games [1], Equation 3.
302
+ fn microfacetDistribution(pbrInfo: PBRInfo) -> f32 {
303
+ let roughnessSq = pbrInfo.alphaRoughness * pbrInfo.alphaRoughness;
304
+ let f = (pbrInfo.NdotH * roughnessSq - pbrInfo.NdotH) * pbrInfo.NdotH + 1.0;
305
+ return roughnessSq / (PI * f * f);
306
+ }
307
+
308
+ fn PBRInfo_setAmbientLight(pbrInfo: ptr<function, PBRInfo>) {
309
+ (*pbrInfo).NdotL = 1.0;
310
+ (*pbrInfo).NdotH = 0.0;
311
+ (*pbrInfo).LdotH = 0.0;
312
+ (*pbrInfo).VdotH = 1.0;
313
+ }
314
+
315
+ fn PBRInfo_setDirectionalLight(pbrInfo: ptr<function, PBRInfo>, lightDirection: vec3<f32>) {
316
+ let n = (*pbrInfo).n;
317
+ let v = (*pbrInfo).v;
318
+ let l = normalize(lightDirection); // Vector from surface point to light
319
+ let h = normalize(l + v); // Half vector between both l and v
320
+
321
+ (*pbrInfo).NdotL = clamp(dot(n, l), 0.001, 1.0);
322
+ (*pbrInfo).NdotH = clamp(dot(n, h), 0.0, 1.0);
323
+ (*pbrInfo).LdotH = clamp(dot(l, h), 0.0, 1.0);
324
+ (*pbrInfo).VdotH = clamp(dot(v, h), 0.0, 1.0);
325
+ }
326
+
327
+ fn PBRInfo_setPointLight(pbrInfo: ptr<function, PBRInfo>, pointLight: PointLight) {
328
+ let light_direction = normalize(pointLight.position - pbr_vPosition);
329
+ PBRInfo_setDirectionalLight(pbrInfo, light_direction);
330
+ }
331
+
332
+ fn calculateFinalColor(pbrInfo: PBRInfo, lightColor: vec3<f32>) -> vec3<f32> {
333
+ // Calculate the shading terms for the microfacet specular shading model
334
+ let F = specularReflection(pbrInfo);
335
+ let G = geometricOcclusion(pbrInfo);
336
+ let D = microfacetDistribution(pbrInfo);
337
+
338
+ // Calculation of analytical lighting contribution
339
+ let diffuseContrib = (1.0 - F) * diffuse(pbrInfo);
340
+ let specContrib = F * G * D / (4.0 * pbrInfo.NdotL * pbrInfo.NdotV);
341
+ // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
342
+ return pbrInfo.NdotL * lightColor * (diffuseContrib + specContrib);
343
+ }
344
+
345
+ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
346
+ // The albedo may be defined from a base texture or a flat color
347
+ var baseColor: vec4<f32>;
348
+ #ifdef HAS_BASECOLORMAP
349
+ baseColor = SRGBtoLINEAR(textureSample(pbr_baseColorSampler, pbr_baseColorSampler, pbr_vUV)) * pbrMaterial.baseColorFactor;
350
+ #else
351
+ baseColor = pbrMaterial.baseColorFactor;
352
+ #endif
353
+
354
+ #ifdef ALPHA_CUTOFF
355
+ if (baseColor.a < pbrMaterial.alphaCutoff) {
356
+ discard;
357
+ }
358
+ #endif
359
+
360
+ var color = vec3<f32>(0.0, 0.0, 0.0);
361
+
362
+ if (pbrMaterial.unlit) {
363
+ color = baseColor.rgb;
364
+ } else {
365
+ // Metallic and Roughness material properties are packed together
366
+ // In glTF, these factors can be specified by fixed scalar values
367
+ // or from a metallic-roughness map
368
+ var perceptualRoughness = pbrMaterial.metallicRoughnessValues.y;
369
+ var metallic = pbrMaterial.metallicRoughnessValues.x;
370
+ #ifdef HAS_METALROUGHNESSMAP
371
+ // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
372
+ // This layout intentionally reserves the 'r' channel for (optional) occlusion map data
373
+ let mrSample = textureSample(pbr_metallicRoughnessSampler, pbr_metallicRoughnessSampler, pbr_vUV);
374
+ perceptualRoughness = mrSample.g * perceptualRoughness;
375
+ metallic = mrSample.b * metallic;
376
+ #endif
377
+ perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
378
+ metallic = clamp(metallic, 0.0, 1.0);
379
+ // Roughness is authored as perceptual roughness; as is convention,
380
+ // convert to material roughness by squaring the perceptual roughness [2].
381
+ let alphaRoughness = perceptualRoughness * perceptualRoughness;
382
+
383
+ let f0 = vec3<f32>(0.04);
384
+ var diffuseColor = baseColor.rgb * (vec3<f32>(1.0) - f0);
385
+ diffuseColor *= 1.0 - metallic;
386
+ let specularColor = mix(f0, baseColor.rgb, metallic);
387
+
388
+ // Compute reflectance.
389
+ let reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
390
+
391
+ // For typical incident reflectance range (between 4% to 100%) set the grazing
392
+ // reflectance to 100% for typical fresnel effect.
393
+ // For very low reflectance range on highly diffuse objects (below 4%),
394
+ // incrementally reduce grazing reflectance to 0%.
395
+ let reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
396
+ let specularEnvironmentR0 = specularColor;
397
+ let specularEnvironmentR90 = vec3<f32>(1.0, 1.0, 1.0) * reflectance90;
398
+
399
+ let n = getNormal(); // normal at surface point
400
+ let v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera
401
+
402
+ let NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
403
+ let reflection = -normalize(reflect(v, n));
404
+
405
+ var pbrInfo = PBRInfo(
406
+ 0.0, // NdotL
407
+ NdotV,
408
+ 0.0, // NdotH
409
+ 0.0, // LdotH
410
+ 0.0, // VdotH
411
+ perceptualRoughness,
412
+ metallic,
413
+ specularEnvironmentR0,
414
+ specularEnvironmentR90,
415
+ alphaRoughness,
416
+ diffuseColor,
417
+ specularColor,
418
+ n,
419
+ v
420
+ );
421
+
422
+ #ifdef USE_LIGHTS
423
+ // Apply ambient light
424
+ PBRInfo_setAmbientLight(&pbrInfo);
425
+ color += calculateFinalColor(pbrInfo, lighting.ambientColor);
426
+
427
+ // Apply directional light
428
+ for (var i = 0; i < lighting.directionalLightCount; i++) {
429
+ if (i < lighting.directionalLightCount) {
430
+ PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);
431
+ color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
432
+ }
433
+ }
434
+
435
+ // Apply point light
436
+ for (var i = 0; i < lighting.pointLightCount; i++) {
437
+ if (i < lighting.pointLightCount) {
438
+ PBRInfo_setPointLight(&pbrInfo, lighting_getPointLight(i));
439
+ let attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));
440
+ color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
441
+ }
442
+ }
443
+ #endif
444
+
445
+ // Calculate lighting contribution from image based lighting source (IBL)
446
+ #ifdef USE_IBL
447
+ if (pbrMaterial.IBLenabled) {
448
+ color += getIBLContribution(pbrInfo, n, reflection);
449
+ }
450
+ #endif
451
+
452
+ // Apply optional PBR terms for additional (optional) shading
453
+ #ifdef HAS_OCCLUSIONMAP
454
+ if (pbrMaterial.occlusionMapEnabled) {
455
+ let ao = textureSample(pbr_occlusionSampler, pbr_occlusionSampler, pbr_vUV).r;
456
+ color = mix(color, color * ao, pbrMaterial.occlusionStrength);
457
+ }
458
+ #endif
459
+
460
+ #ifdef HAS_EMISSIVEMAP
461
+ if (pbrMaterial.emissiveMapEnabled) {
462
+ let emissive = SRGBtoLINEAR(textureSample(pbr_emissiveSampler, pbr_emissiveSampler, pbr_vUV)).rgb * pbrMaterial.emissiveFactor;
463
+ color += emissive;
464
+ }
465
+ #endif
466
+
467
+ // This section uses mix to override final color for reference app visualization
468
+ // of various parameters in the lighting equation.
469
+ #ifdef PBR_DEBUG
470
+ // TODO: Figure out how to debug multiple lights
471
+
472
+ // color = mix(color, F, pbr_scaleFGDSpec.x);
473
+ // color = mix(color, vec3(G), pbr_scaleFGDSpec.y);
474
+ // color = mix(color, vec3(D), pbr_scaleFGDSpec.z);
475
+ // color = mix(color, specContrib, pbr_scaleFGDSpec.w);
476
+
477
+ // color = mix(color, diffuseContrib, pbr_scaleDiffBaseMR.x);
478
+ color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);
479
+ color = mix(color, vec3<f32>(metallic), pbrMaterial.scaleDiffBaseMR.z);
480
+ color = mix(color, vec3<f32>(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);
481
+ #endif
482
+ }
483
+
484
+ return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), baseColor.a);
485
+ }
486
+ `;
487
+ //# sourceMappingURL=pbr-material-wgsl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbr-material-wgsl.js","sourceRoot":"","sources":["../../../../src/modules/lighting/pbr-material/pbr-material-wgsl.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,oCAAoC;AAEpC,eAAe;AACf,yEAAyE;AACzE,0FAA0F;AAC1F,yDAAyD;AAEzD,gDAAgD;AAEhD,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8D7C,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8ZhC,CAAC"}
@@ -44,9 +44,7 @@ export declare const pbrMaterial: {
44
44
  readonly props: import("../lights/lighting").LightingProps;
45
45
  readonly uniforms: import("../lights/lighting").LightingUniforms;
46
46
  readonly name: "lighting";
47
- readonly defines: {
48
- readonly MAX_LIGHTS: 3;
49
- };
47
+ readonly defines: {};
50
48
  readonly uniformTypes: {
51
49
  readonly enabled: "i32";
52
50
  readonly lightType: "i32";
@@ -90,10 +88,19 @@ export declare const pbrMaterial: {
90
88
  readonly fs: "precision highp int;\n\n// #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX))\nstruct AmbientLight {\n vec3 color;\n};\n\nstruct PointLight {\n vec3 color;\n vec3 position;\n vec3 attenuation; // 2nd order x:Constant-y:Linear-z:Exponential\n};\n\nstruct DirectionalLight {\n vec3 color;\n vec3 direction;\n};\n\nuniform lightingUniforms {\n int enabled;\n int lightType;\n\n int directionalLightCount;\n int pointLightCount;\n\n vec3 ambientColor;\n\n vec3 lightColor0;\n vec3 lightPosition0;\n vec3 lightDirection0;\n vec3 lightAttenuation0;\n\n vec3 lightColor1;\n vec3 lightPosition1;\n vec3 lightDirection1;\n vec3 lightAttenuation1;\n\n vec3 lightColor2;\n vec3 lightPosition2;\n vec3 lightDirection2;\n vec3 lightAttenuation2;\n} lighting;\n\nPointLight lighting_getPointLight(int index) {\n switch (index) {\n case 0:\n return PointLight(lighting.lightColor0, lighting.lightPosition0, lighting.lightAttenuation0);\n case 1:\n return PointLight(lighting.lightColor1, lighting.lightPosition1, lighting.lightAttenuation1);\n case 2:\n default: \n return PointLight(lighting.lightColor2, lighting.lightPosition2, lighting.lightAttenuation2);\n }\n}\n\nDirectionalLight lighting_getDirectionalLight(int index) {\n switch (index) {\n case 0:\n return DirectionalLight(lighting.lightColor0, lighting.lightDirection0);\n case 1:\n return DirectionalLight(lighting.lightColor1, lighting.lightDirection1);\n case 2:\n default: \n return DirectionalLight(lighting.lightColor2, lighting.lightDirection2);\n }\n} \n\nfloat getPointLightAttenuation(PointLight pointLight, float distance) {\n return pointLight.attenuation.x\n + pointLight.attenuation.y * distance\n + pointLight.attenuation.z * distance * distance;\n}\n\n// #endif\n";
91
89
  readonly getUniforms: (props?: import("../lights/lighting").LightingProps, prevUniforms?: Partial<import("../lights/lighting").LightingUniforms>) => import("../lights/lighting").LightingUniforms;
92
90
  }, ShaderModule<import("./pbr-projection").PBRProjectionProps>];
91
+ readonly source: "struct PBRFragmentInputs {\n pbr_vPosition: vec3f,\n pbr_vUV: vec2f,\n pbr_vTBN: mat3f,\n pbr_vNormal: vec3f\n};\n\nvar fragmentInputs: PBRFragmentInputs;\n\nfn pbr_setPositionNormalTangentUV(position: vec4f, normal: vec4f, tangent: vec4f, uv: vec2f)\n{\n var pos: vec4f = pbrProjection.modelMatrix * position;\n pbr_vPosition = vec3(pos.xyz) / pos.w;\n\n#ifdef HAS_NORMALS\n#ifdef HAS_TANGENTS\n let normalW: vec3f = normalize(vec3(pbrProjection.normalMatrix * vec4(normal.xyz, 0.0)));\n let tangentW: vec3f = normalize(vec3(pbrProjection.modelMatrix * vec4(tangent.xyz, 0.0)));\n let bitangentW: vec3f = cross(normalW, tangentW) * tangent.w;\n fragmentInputs,pbr_vTBN = mat3(tangentW, bitangentW, normalW);\n#else // HAS_TANGENTS != 1\n fragmentInputs.pbr_vNormal = normalize(vec3(pbrProjection.modelMatrix * vec4(normal.xyz, 0.0)));\n#endif\n#endif\n\n#ifdef HAS_UV\n pbr_vUV = uv;\n#else\n pbr_vUV = vec2(0.,0.);\n#endif\n}\n\nstruct pbrMaterialUniforms {\n // Material is unlit\n unlit: uint32,\n\n // Base color map\n baseColorMapEnabled: uint32,\n baseColorFactor: vec4f,\n\n normalMapEnabled : uint32,\n normalScale: f32, // #ifdef HAS_NORMALMAP\n\n emissiveMapEnabled: uint32,\n emissiveFactor: vec3f, // #ifdef HAS_EMISSIVEMAP\n\n metallicRoughnessValues: vec2f,\n metallicRoughnessMapEnabled: uint32,\n\n occlusionMapEnabled: i32,\n occlusionStrength: f32, // #ifdef HAS_OCCLUSIONMAP\n \n alphaCutoffEnabled: i32,\n alphaCutoff: f32, // #ifdef ALPHA_CUTOFF\n \n // IBL\n IBLenabled: i32,\n scaleIBLAmbient: vec2f, // #ifdef USE_IBL\n \n // debugging flags used for shader output of intermediate PBR variables\n // #ifdef PBR_DEBUG\n scaleDiffBaseMR: vec4f,\n scaleFGDSpec: vec4f\n // #endif\n} \n \n@binding(2) @group(0) var<uniform> material : pbrMaterialUniforms;\n\n// Samplers\n#ifdef HAS_BASECOLORMAP\nuniform sampler2D pbr_baseColorSampler;\n#endif\n#ifdef HAS_NORMALMAP\nuniform sampler2D pbr_normalSampler;\n#endif\n#ifdef HAS_EMISSIVEMAP\nuniform sampler2D pbr_emissiveSampler;\n#endif\n#ifdef HAS_METALROUGHNESSMAP\nuniform sampler2D pbr_metallicRoughnessSampler;\n#endif\n#ifdef HAS_OCCLUSIONMAP\nuniform sampler2D pbr_occlusionSampler;\n#endif\n#ifdef USE_IBL\nuniform samplerCube pbr_diffuseEnvSampler;\nuniform samplerCube pbr_specularEnvSampler;\nuniform sampler2D pbr_brdfLUT;\n#endif\n\n// Encapsulate the various inputs used by the various functions in the shading equation\n// We store values in this struct to simplify the integration of alternative implementations\n// of the shading terms, outlined in the Readme.MD Appendix.\nstruct PBRInfo {\n NdotL: f32, // cos angle between normal and light direction\n NdotV: f32, // cos angle between normal and view direction\n NdotH: f32, // cos angle between normal and half vector\n LdotH: f32, // cos angle between light direction and half vector\n VdotH: f32, // cos angle between view direction and half vector\n perceptualRoughness: f32, // roughness value, as authored by the model creator (input to shader)\n metalness: f32, // metallic value at the surface\n reflectance0: vec3f, // full reflectance color (normal incidence angle)\n reflectance90: vec3f, // reflectance color at grazing angle\n alphaRoughness: f32, // roughness mapped to a more linear change in the roughness (proposed by [2])\n diffuseColor: vec3f, // color contribution from diffuse lighting\n specularColor: vec3f, // color contribution from specular lighting\n n: vec3f, // normal at surface point\n v: vec3f, // vector from surface point to camera\n};\n\nconst M_PI = 3.141592653589793;\nconst c_MinRoughness = 0.04;\n\nfn SRGBtoLINEAR(srgbIn: vec4f ) -> vec4f\n{\n#ifdef MANUAL_SRGB\n#ifdef SRGB_FAST_APPROXIMATION\n var linOut: vec3f = pow(srgbIn.xyz,vec3(2.2));\n#else // SRGB_FAST_APPROXIMATION\n var bLess: vec3f = step(vec3(0.04045),srgbIn.xyz);\n var linOut: vec3f = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess );\n#endif //SRGB_FAST_APPROXIMATION\n return vec4f(linOut,srgbIn.w);;\n#else //MANUAL_SRGB\n return srgbIn;\n#endif //MANUAL_SRGB\n}\n\n// Find the normal for this fragment, pulling either from a predefined normal map\n// or from the interpolated mesh normal and tangent attributes.\nfn getNormal() -> vec3f\n{\n // Retrieve the tangent space matrix\n#ifndef HAS_TANGENTS\n var pos_dx: vec3f = dFdx(pbr_vPosition);\n var pos_dy: vec3f = dFdy(pbr_vPosition);\n var tex_dx: vec3f = dFdx(vec3(pbr_vUV, 0.0));\n var tex_dy: vec3f = dFdy(vec3(pbr_vUV, 0.0));\n var t: vec3f = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t);\n\n#ifdef HAS_NORMALS\n var ng: vec3f = normalize(pbr_vNormal);\n#else\n var ng: vec3f = cross(pos_dx, pos_dy);\n#endif\n\n t = normalize(t - ng * dot(ng, t));\n var b: vec3f = normalize(cross(ng, t));\n var tbn: mat3f = mat3f(t, b, ng);\n#else // HAS_TANGENTS\n var tbn: mat3f = pbr_vTBN;\n#endif\n\n#ifdef HAS_NORMALMAP\n vec3 n = texture(pbr_normalSampler, pbr_vUV).rgb;\n n = normalize(tbn * ((2.0 * n - 1.0) * vec3(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));\n#else\n // The tbn matrix is linearly interpolated, so we need to re-normalize\n vec3 n = normalize(tbn[2].xyz);\n#endif\n\n return n;\n}\n\n// Calculation of the lighting contribution from an optional Image Based Light source.\n// Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].\n// See our README.md on Environment Maps [3] for additional discussion.\n#ifdef USE_IBL\nfn getIBLContribution(PBRInfo pbrInfo, vec3 n, vec3 reflection) -> vec3f\n{\n float mipCount = 9.0; // resolution of 512x512\n float lod = (pbrInfo.perceptualRoughness * mipCount);\n // retrieve a scale and bias to F0. See [1], Figure 3\n vec3 brdf = SRGBtoLINEAR(texture(pbr_brdfLUT,\n vec2(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness))).rgb;\n vec3 diffuseLight = SRGBtoLINEAR(texture(pbr_diffuseEnvSampler, n)).rgb;\n\n#ifdef USE_TEX_LOD\n vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection, lod)).rgb;\n#else\n vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection)).rgb;\n#endif\n\n vec3 diffuse = diffuseLight * pbrInfo.diffuseColor;\n vec3 specular = specularLight * (pbrInfo.specularColor * brdf.x + brdf.y);\n\n // For presentation, this allows us to disable IBL terms\n diffuse *= pbrMaterial.scaleIBLAmbient.x;\n specular *= pbrMaterial.scaleIBLAmbient.y;\n\n return diffuse + specular;\n}\n#endif\n\n// Basic Lambertian diffuse\n// Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog\n// See also [1], Equation 1\nfn diffuse(pbrInfo: PBRInfo) -> vec3<f32> {\n return pbrInfo.diffuseColor / PI;\n}\n\n// The following equation models the Fresnel reflectance term of the spec equation (aka F())\n// Implementation of fresnel from [4], Equation 15\nfn specularReflection(pbrInfo: PBRInfo) -> vec3<f32> {\n return pbrInfo.reflectance0 +\n (pbrInfo.reflectance90 - pbrInfo.reflectance0) *\n pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);\n}\n\n// This calculates the specular geometric attenuation (aka G()),\n// where rougher material will reflect less light back to the viewer.\n// This implementation is based on [1] Equation 4, and we adopt their modifications to\n// alphaRoughness as input as originally proposed in [2].\nfn geometricOcclusion(pbrInfo: PBRInfo) -> f32 {\n let NdotL: f32 = pbrInfo.NdotL;\n let NdotV: f32 = pbrInfo.NdotV;\n let r: f32 = pbrInfo.alphaRoughness;\n\n let attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));\n let attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));\n return attenuationL * attenuationV;\n}\n\n// The following equation(s) model the distribution of microfacet normals across\n// the area being drawn (aka D())\n// Implementation from \"Average Irregularity Representation of a Roughened Surface\n// for Ray Reflection\" by T. S. Trowbridge, and K. P. Reitz\n// Follows the distribution function recommended in the SIGGRAPH 2013 course notes\n// from EPIC Games [1], Equation 3.\nfn microfacetDistribution(pbrInfo: PBRInfo) -> f32 {\n let roughnessSq = pbrInfo.alphaRoughness * pbrInfo.alphaRoughness;\n let f = (pbrInfo.NdotH * roughnessSq - pbrInfo.NdotH) * pbrInfo.NdotH + 1.0;\n return roughnessSq / (PI * f * f);\n}\n\nfn PBRInfo_setAmbientLight(pbrInfo: ptr<function, PBRInfo>) {\n (*pbrInfo).NdotL = 1.0;\n (*pbrInfo).NdotH = 0.0;\n (*pbrInfo).LdotH = 0.0;\n (*pbrInfo).VdotH = 1.0;\n}\n\nfn PBRInfo_setDirectionalLight(pbrInfo: ptr<function, PBRInfo>, lightDirection: vec3<f32>) {\n let n = (*pbrInfo).n;\n let v = (*pbrInfo).v;\n let l = normalize(lightDirection); // Vector from surface point to light\n let h = normalize(l + v); // Half vector between both l and v\n\n (*pbrInfo).NdotL = clamp(dot(n, l), 0.001, 1.0);\n (*pbrInfo).NdotH = clamp(dot(n, h), 0.0, 1.0);\n (*pbrInfo).LdotH = clamp(dot(l, h), 0.0, 1.0);\n (*pbrInfo).VdotH = clamp(dot(v, h), 0.0, 1.0);\n}\n\nfn PBRInfo_setPointLight(pbrInfo: ptr<function, PBRInfo>, pointLight: PointLight) {\n let light_direction = normalize(pointLight.position - pbr_vPosition);\n PBRInfo_setDirectionalLight(pbrInfo, light_direction);\n}\n\nfn calculateFinalColor(pbrInfo: PBRInfo, lightColor: vec3<f32>) -> vec3<f32> {\n // Calculate the shading terms for the microfacet specular shading model\n let F = specularReflection(pbrInfo);\n let G = geometricOcclusion(pbrInfo);\n let D = microfacetDistribution(pbrInfo);\n\n // Calculation of analytical lighting contribution\n let diffuseContrib = (1.0 - F) * diffuse(pbrInfo);\n let specContrib = F * G * D / (4.0 * pbrInfo.NdotL * pbrInfo.NdotV);\n // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)\n return pbrInfo.NdotL * lightColor * (diffuseContrib + specContrib);\n}\n\nfn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {\n // The albedo may be defined from a base texture or a flat color\n var baseColor: vec4<f32>;\n #ifdef HAS_BASECOLORMAP\n baseColor = SRGBtoLINEAR(textureSample(pbr_baseColorSampler, pbr_baseColorSampler, pbr_vUV)) * pbrMaterial.baseColorFactor;\n #else\n baseColor = pbrMaterial.baseColorFactor;\n #endif\n\n #ifdef ALPHA_CUTOFF\n if (baseColor.a < pbrMaterial.alphaCutoff) {\n discard;\n }\n #endif\n\n var color = vec3<f32>(0.0, 0.0, 0.0);\n\n if (pbrMaterial.unlit) {\n color = baseColor.rgb;\n } else {\n // Metallic and Roughness material properties are packed together\n // In glTF, these factors can be specified by fixed scalar values\n // or from a metallic-roughness map\n var perceptualRoughness = pbrMaterial.metallicRoughnessValues.y;\n var metallic = pbrMaterial.metallicRoughnessValues.x;\n #ifdef HAS_METALROUGHNESSMAP\n // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.\n // This layout intentionally reserves the 'r' channel for (optional) occlusion map data\n let mrSample = textureSample(pbr_metallicRoughnessSampler, pbr_metallicRoughnessSampler, pbr_vUV);\n perceptualRoughness = mrSample.g * perceptualRoughness;\n metallic = mrSample.b * metallic;\n #endif\n perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);\n metallic = clamp(metallic, 0.0, 1.0);\n // Roughness is authored as perceptual roughness; as is convention,\n // convert to material roughness by squaring the perceptual roughness [2].\n let alphaRoughness = perceptualRoughness * perceptualRoughness;\n\n let f0 = vec3<f32>(0.04);\n var diffuseColor = baseColor.rgb * (vec3<f32>(1.0) - f0);\n diffuseColor *= 1.0 - metallic;\n let specularColor = mix(f0, baseColor.rgb, metallic);\n\n // Compute reflectance.\n let reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);\n\n // For typical incident reflectance range (between 4% to 100%) set the grazing\n // reflectance to 100% for typical fresnel effect.\n // For very low reflectance range on highly diffuse objects (below 4%),\n // incrementally reduce grazing reflectance to 0%.\n let reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);\n let specularEnvironmentR0 = specularColor;\n let specularEnvironmentR90 = vec3<f32>(1.0, 1.0, 1.0) * reflectance90;\n\n let n = getNormal(); // normal at surface point\n let v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera\n\n let NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);\n let reflection = -normalize(reflect(v, n));\n\n var pbrInfo = PBRInfo(\n 0.0, // NdotL\n NdotV,\n 0.0, // NdotH\n 0.0, // LdotH\n 0.0, // VdotH\n perceptualRoughness,\n metallic,\n specularEnvironmentR0,\n specularEnvironmentR90,\n alphaRoughness,\n diffuseColor,\n specularColor,\n n,\n v\n );\n\n #ifdef USE_LIGHTS\n // Apply ambient light\n PBRInfo_setAmbientLight(&pbrInfo);\n color += calculateFinalColor(pbrInfo, lighting.ambientColor);\n\n // Apply directional light\n for (var i = 0; i < lighting.directionalLightCount; i++) {\n if (i < lighting.directionalLightCount) {\n PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);\n color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);\n }\n }\n\n // Apply point light\n for (var i = 0; i < lighting.pointLightCount; i++) {\n if (i < lighting.pointLightCount) {\n PBRInfo_setPointLight(&pbrInfo, lighting_getPointLight(i));\n let attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));\n color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);\n }\n }\n #endif\n\n // Calculate lighting contribution from image based lighting source (IBL)\n #ifdef USE_IBL\n if (pbrMaterial.IBLenabled) {\n color += getIBLContribution(pbrInfo, n, reflection);\n }\n #endif\n\n // Apply optional PBR terms for additional (optional) shading\n #ifdef HAS_OCCLUSIONMAP\n if (pbrMaterial.occlusionMapEnabled) {\n let ao = textureSample(pbr_occlusionSampler, pbr_occlusionSampler, pbr_vUV).r;\n color = mix(color, color * ao, pbrMaterial.occlusionStrength);\n }\n #endif\n\n #ifdef HAS_EMISSIVEMAP\n if (pbrMaterial.emissiveMapEnabled) {\n let emissive = SRGBtoLINEAR(textureSample(pbr_emissiveSampler, pbr_emissiveSampler, pbr_vUV)).rgb * pbrMaterial.emissiveFactor;\n color += emissive;\n }\n #endif\n\n // This section uses mix to override final color for reference app visualization\n // of various parameters in the lighting equation.\n #ifdef PBR_DEBUG\n // TODO: Figure out how to debug multiple lights\n\n // color = mix(color, F, pbr_scaleFGDSpec.x);\n // color = mix(color, vec3(G), pbr_scaleFGDSpec.y);\n // color = mix(color, vec3(D), pbr_scaleFGDSpec.z);\n // color = mix(color, specContrib, pbr_scaleFGDSpec.w);\n\n // color = mix(color, diffuseContrib, pbr_scaleDiffBaseMR.x);\n color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);\n color = mix(color, vec3<f32>(metallic), pbrMaterial.scaleDiffBaseMR.z);\n color = mix(color, vec3<f32>(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);\n #endif\n }\n\n return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), baseColor.a);\n}\n";
93
92
  readonly vs: "out vec3 pbr_vPosition;\nout vec2 pbr_vUV;\n\n#ifdef HAS_NORMALS\n# ifdef HAS_TANGENTS\nout mat3 pbr_vTBN;\n# else\nout vec3 pbr_vNormal;\n# endif\n#endif\n\nvoid pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, vec2 uv)\n{\n vec4 pos = pbrProjection.modelMatrix * position;\n pbr_vPosition = vec3(pos.xyz) / pos.w;\n\n#ifdef HAS_NORMALS\n#ifdef HAS_TANGENTS\n vec3 normalW = normalize(vec3(pbrProjection.normalMatrix * vec4(normal.xyz, 0.0)));\n vec3 tangentW = normalize(vec3(pbrProjection.modelMatrix * vec4(tangent.xyz, 0.0)));\n vec3 bitangentW = cross(normalW, tangentW) * tangent.w;\n pbr_vTBN = mat3(tangentW, bitangentW, normalW);\n#else // HAS_TANGENTS != 1\n pbr_vNormal = normalize(vec3(pbrProjection.modelMatrix * vec4(normal.xyz, 0.0)));\n#endif\n#endif\n\n#ifdef HAS_UV\n pbr_vUV = uv;\n#else\n pbr_vUV = vec2(0.,0.);\n#endif\n}\n";
94
93
  readonly fs: "precision highp float;\n\nuniform pbrMaterialUniforms {\n // Material is unlit\n bool unlit;\n\n // Base color map\n bool baseColorMapEnabled;\n vec4 baseColorFactor;\n\n bool normalMapEnabled; \n float normalScale; // #ifdef HAS_NORMALMAP\n\n bool emissiveMapEnabled;\n vec3 emissiveFactor; // #ifdef HAS_EMISSIVEMAP\n\n vec2 metallicRoughnessValues;\n bool metallicRoughnessMapEnabled;\n\n bool occlusionMapEnabled;\n float occlusionStrength; // #ifdef HAS_OCCLUSIONMAP\n \n bool alphaCutoffEnabled;\n float alphaCutoff; // #ifdef ALPHA_CUTOFF\n \n // IBL\n bool IBLenabled;\n vec2 scaleIBLAmbient; // #ifdef USE_IBL\n \n // debugging flags used for shader output of intermediate PBR variables\n // #ifdef PBR_DEBUG\n vec4 scaleDiffBaseMR;\n vec4 scaleFGDSpec;\n // #endif\n} pbrMaterial;\n\n// Samplers\n#ifdef HAS_BASECOLORMAP\nuniform sampler2D pbr_baseColorSampler;\n#endif\n#ifdef HAS_NORMALMAP\nuniform sampler2D pbr_normalSampler;\n#endif\n#ifdef HAS_EMISSIVEMAP\nuniform sampler2D pbr_emissiveSampler;\n#endif\n#ifdef HAS_METALROUGHNESSMAP\nuniform sampler2D pbr_metallicRoughnessSampler;\n#endif\n#ifdef HAS_OCCLUSIONMAP\nuniform sampler2D pbr_occlusionSampler;\n#endif\n#ifdef USE_IBL\nuniform samplerCube pbr_diffuseEnvSampler;\nuniform samplerCube pbr_specularEnvSampler;\nuniform sampler2D pbr_brdfLUT;\n#endif\n\n// Inputs from vertex shader\n\nin vec3 pbr_vPosition;\nin vec2 pbr_vUV;\n\n#ifdef HAS_NORMALS\n#ifdef HAS_TANGENTS\nin mat3 pbr_vTBN;\n#else\nin vec3 pbr_vNormal;\n#endif\n#endif\n\n// Encapsulate the various inputs used by the various functions in the shading equation\n// We store values in this struct to simplify the integration of alternative implementations\n// of the shading terms, outlined in the Readme.MD Appendix.\nstruct PBRInfo {\n float NdotL; // cos angle between normal and light direction\n float NdotV; // cos angle between normal and view direction\n float NdotH; // cos angle between normal and half vector\n float LdotH; // cos angle between light direction and half vector\n float VdotH; // cos angle between view direction and half vector\n float perceptualRoughness; // roughness value, as authored by the model creator (input to shader)\n float metalness; // metallic value at the surface\n vec3 reflectance0; // full reflectance color (normal incidence angle)\n vec3 reflectance90; // reflectance color at grazing angle\n float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2])\n vec3 diffuseColor; // color contribution from diffuse lighting\n vec3 specularColor; // color contribution from specular lighting\n vec3 n; // normal at surface point\n vec3 v; // vector from surface point to camera\n};\n\nconst float M_PI = 3.141592653589793;\nconst float c_MinRoughness = 0.04;\n\nvec4 SRGBtoLINEAR(vec4 srgbIn)\n{\n#ifdef MANUAL_SRGB\n#ifdef SRGB_FAST_APPROXIMATION\n vec3 linOut = pow(srgbIn.xyz,vec3(2.2));\n#else // SRGB_FAST_APPROXIMATION\n vec3 bLess = step(vec3(0.04045),srgbIn.xyz);\n vec3 linOut = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess );\n#endif //SRGB_FAST_APPROXIMATION\n return vec4(linOut,srgbIn.w);;\n#else //MANUAL_SRGB\n return srgbIn;\n#endif //MANUAL_SRGB\n}\n\n// Find the normal for this fragment, pulling either from a predefined normal map\n// or from the interpolated mesh normal and tangent attributes.\nvec3 getNormal()\n{\n // Retrieve the tangent space matrix\n#ifndef HAS_TANGENTS\n vec3 pos_dx = dFdx(pbr_vPosition);\n vec3 pos_dy = dFdy(pbr_vPosition);\n vec3 tex_dx = dFdx(vec3(pbr_vUV, 0.0));\n vec3 tex_dy = dFdy(vec3(pbr_vUV, 0.0));\n vec3 t = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t);\n\n#ifdef HAS_NORMALS\n vec3 ng = normalize(pbr_vNormal);\n#else\n vec3 ng = cross(pos_dx, pos_dy);\n#endif\n\n t = normalize(t - ng * dot(ng, t));\n vec3 b = normalize(cross(ng, t));\n mat3 tbn = mat3(t, b, ng);\n#else // HAS_TANGENTS\n mat3 tbn = pbr_vTBN;\n#endif\n\n#ifdef HAS_NORMALMAP\n vec3 n = texture(pbr_normalSampler, pbr_vUV).rgb;\n n = normalize(tbn * ((2.0 * n - 1.0) * vec3(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));\n#else\n // The tbn matrix is linearly interpolated, so we need to re-normalize\n vec3 n = normalize(tbn[2].xyz);\n#endif\n\n return n;\n}\n\n// Calculation of the lighting contribution from an optional Image Based Light source.\n// Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].\n// See our README.md on Environment Maps [3] for additional discussion.\n#ifdef USE_IBL\nvec3 getIBLContribution(PBRInfo pbrInfo, vec3 n, vec3 reflection)\n{\n float mipCount = 9.0; // resolution of 512x512\n float lod = (pbrInfo.perceptualRoughness * mipCount);\n // retrieve a scale and bias to F0. See [1], Figure 3\n vec3 brdf = SRGBtoLINEAR(texture(pbr_brdfLUT,\n vec2(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness))).rgb;\n vec3 diffuseLight = SRGBtoLINEAR(texture(pbr_diffuseEnvSampler, n)).rgb;\n\n#ifdef USE_TEX_LOD\n vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection, lod)).rgb;\n#else\n vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection)).rgb;\n#endif\n\n vec3 diffuse = diffuseLight * pbrInfo.diffuseColor;\n vec3 specular = specularLight * (pbrInfo.specularColor * brdf.x + brdf.y);\n\n // For presentation, this allows us to disable IBL terms\n diffuse *= pbrMaterial.scaleIBLAmbient.x;\n specular *= pbrMaterial.scaleIBLAmbient.y;\n\n return diffuse + specular;\n}\n#endif\n\n// Basic Lambertian diffuse\n// Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog\n// See also [1], Equation 1\nvec3 diffuse(PBRInfo pbrInfo)\n{\n return pbrInfo.diffuseColor / M_PI;\n}\n\n// The following equation models the Fresnel reflectance term of the spec equation (aka F())\n// Implementation of fresnel from [4], Equation 15\nvec3 specularReflection(PBRInfo pbrInfo)\n{\n return pbrInfo.reflectance0 +\n (pbrInfo.reflectance90 - pbrInfo.reflectance0) *\n pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);\n}\n\n// This calculates the specular geometric attenuation (aka G()),\n// where rougher material will reflect less light back to the viewer.\n// This implementation is based on [1] Equation 4, and we adopt their modifications to\n// alphaRoughness as input as originally proposed in [2].\nfloat geometricOcclusion(PBRInfo pbrInfo)\n{\n float NdotL = pbrInfo.NdotL;\n float NdotV = pbrInfo.NdotV;\n float r = pbrInfo.alphaRoughness;\n\n float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));\n float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));\n return attenuationL * attenuationV;\n}\n\n// The following equation(s) model the distribution of microfacet normals across\n// the area being drawn (aka D())\n// Implementation from \"Average Irregularity Representation of a Roughened Surface\n// for Ray Reflection\" by T. S. Trowbridge, and K. P. Reitz\n// Follows the distribution function recommended in the SIGGRAPH 2013 course notes\n// from EPIC Games [1], Equation 3.\nfloat microfacetDistribution(PBRInfo pbrInfo)\n{\n float roughnessSq = pbrInfo.alphaRoughness * pbrInfo.alphaRoughness;\n float f = (pbrInfo.NdotH * roughnessSq - pbrInfo.NdotH) * pbrInfo.NdotH + 1.0;\n return roughnessSq / (M_PI * f * f);\n}\n\nvoid PBRInfo_setAmbientLight(inout PBRInfo pbrInfo) {\n pbrInfo.NdotL = 1.0;\n pbrInfo.NdotH = 0.0;\n pbrInfo.LdotH = 0.0;\n pbrInfo.VdotH = 1.0;\n}\n\nvoid PBRInfo_setDirectionalLight(inout PBRInfo pbrInfo, vec3 lightDirection) {\n vec3 n = pbrInfo.n;\n vec3 v = pbrInfo.v;\n vec3 l = normalize(lightDirection); // Vector from surface point to light\n vec3 h = normalize(l+v); // Half vector between both l and v\n\n pbrInfo.NdotL = clamp(dot(n, l), 0.001, 1.0);\n pbrInfo.NdotH = clamp(dot(n, h), 0.0, 1.0);\n pbrInfo.LdotH = clamp(dot(l, h), 0.0, 1.0);\n pbrInfo.VdotH = clamp(dot(v, h), 0.0, 1.0);\n}\n\nvoid PBRInfo_setPointLight(inout PBRInfo pbrInfo, PointLight pointLight) {\n vec3 light_direction = normalize(pointLight.position - pbr_vPosition);\n PBRInfo_setDirectionalLight(pbrInfo, light_direction);\n}\n\nvec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor) {\n // Calculate the shading terms for the microfacet specular shading model\n vec3 F = specularReflection(pbrInfo);\n float G = geometricOcclusion(pbrInfo);\n float D = microfacetDistribution(pbrInfo);\n\n // Calculation of analytical lighting contribution\n vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInfo);\n vec3 specContrib = F * G * D / (4.0 * pbrInfo.NdotL * pbrInfo.NdotV);\n // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)\n return pbrInfo.NdotL * lightColor * (diffuseContrib + specContrib);\n}\n\nvec4 pbr_filterColor(vec4 colorUnused)\n{\n // The albedo may be defined from a base texture or a flat color\n#ifdef HAS_BASECOLORMAP\n vec4 baseColor = SRGBtoLINEAR(texture(pbr_baseColorSampler, pbr_vUV)) * pbrMaterial.baseColorFactor;\n#else\n vec4 baseColor = pbrMaterial.baseColorFactor;\n#endif\n\n#ifdef ALPHA_CUTOFF\n if (baseColor.a < pbrMaterial.alphaCutoff) {\n discard;\n }\n#endif\n\n vec3 color = vec3(0, 0, 0);\n\n if(pbrMaterial.unlit){\n color.rgb = baseColor.rgb;\n }\n else{\n // Metallic and Roughness material properties are packed together\n // In glTF, these factors can be specified by fixed scalar values\n // or from a metallic-roughness map\n float perceptualRoughness = pbrMaterial.metallicRoughnessValues.y;\n float metallic = pbrMaterial.metallicRoughnessValues.x;\n#ifdef HAS_METALROUGHNESSMAP\n // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.\n // This layout intentionally reserves the 'r' channel for (optional) occlusion map data\n vec4 mrSample = texture(pbr_metallicRoughnessSampler, pbr_vUV);\n perceptualRoughness = mrSample.g * perceptualRoughness;\n metallic = mrSample.b * metallic;\n#endif\n perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);\n metallic = clamp(metallic, 0.0, 1.0);\n // Roughness is authored as perceptual roughness; as is convention,\n // convert to material roughness by squaring the perceptual roughness [2].\n float alphaRoughness = perceptualRoughness * perceptualRoughness;\n\n vec3 f0 = vec3(0.04);\n vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);\n diffuseColor *= 1.0 - metallic;\n vec3 specularColor = mix(f0, baseColor.rgb, metallic);\n\n // Compute reflectance.\n float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);\n\n // For typical incident reflectance range (between 4% to 100%) set the grazing\n // reflectance to 100% for typical fresnel effect.\n // For very low reflectance range on highly diffuse objects (below 4%),\n // incrementally reduce grazing reflecance to 0%.\n float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);\n vec3 specularEnvironmentR0 = specularColor.rgb;\n vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;\n\n vec3 n = getNormal(); // normal at surface point\n vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera\n\n float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);\n vec3 reflection = -normalize(reflect(v, n));\n\n PBRInfo pbrInfo = PBRInfo(\n 0.0, // NdotL\n NdotV,\n 0.0, // NdotH\n 0.0, // LdotH\n 0.0, // VdotH\n perceptualRoughness,\n metallic,\n specularEnvironmentR0,\n specularEnvironmentR90,\n alphaRoughness,\n diffuseColor,\n specularColor,\n n,\n v\n );\n\n\n#ifdef USE_LIGHTS\n // Apply ambient light\n PBRInfo_setAmbientLight(pbrInfo);\n color += calculateFinalColor(pbrInfo, lighting.ambientColor);\n\n // Apply directional light\n for(int i = 0; i < lighting.directionalLightCount; i++) {\n if (i < lighting.directionalLightCount) {\n PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);\n color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);\n }\n }\n\n // Apply point light\n for(int i = 0; i < lighting.pointLightCount; i++) {\n if (i < lighting.pointLightCount) {\n PBRInfo_setPointLight(pbrInfo, lighting_getPointLight(i));\n float attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));\n color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);\n }\n }\n#endif\n\n // Calculate lighting contribution from image based lighting source (IBL)\n#ifdef USE_IBL\n if (pbrMaterial.IBLenabled) {\n color += getIBLContribution(pbrInfo, n, reflection);\n }\n#endif\n\n // Apply optional PBR terms for additional (optional) shading\n#ifdef HAS_OCCLUSIONMAP\n if (pbrMaterial.occlusionMapEnabled) {\n float ao = texture(pbr_occlusionSampler, pbr_vUV).r;\n color = mix(color, color * ao, pbrMaterial.occlusionStrength);\n }\n#endif\n\n#ifdef HAS_EMISSIVEMAP\n if (pbrMaterial.emissiveMapEnabled) {\n vec3 emissive = SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb * pbrMaterial.emissiveFactor;\n color += emissive;\n }\n#endif\n\n // This section uses mix to override final color for reference app visualization\n // of various parameters in the lighting equation.\n#ifdef PBR_DEBUG\n // TODO: Figure out how to debug multiple lights\n\n // color = mix(color, F, pbr_scaleFGDSpec.x);\n // color = mix(color, vec3(G), pbr_scaleFGDSpec.y);\n // color = mix(color, vec3(D), pbr_scaleFGDSpec.z);\n // color = mix(color, specContrib, pbr_scaleFGDSpec.w);\n\n // color = mix(color, diffuseContrib, pbr_scaleDiffBaseMR.x);\n color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);\n color = mix(color, vec3(metallic), pbrMaterial.scaleDiffBaseMR.z);\n color = mix(color, vec3(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);\n#endif\n\n }\n\n return vec4(pow(color,vec3(1.0/2.2)), baseColor.a);\n}\n";
95
94
  readonly defines: {
96
- readonly LIGHTING_FRAGMENT: 1;
95
+ readonly LIGHTING_FRAGMENT: true;
96
+ readonly HAS_NORMALMAP: false;
97
+ readonly HAS_EMISSIVEMAP: false;
98
+ readonly HAS_OCCLUSIONMAP: false;
99
+ readonly HAS_BASECOLORMAP: false;
100
+ readonly HAS_METALROUGHNESSMAP: false;
101
+ readonly ALPHA_CUTOFF: false;
102
+ readonly USE_IBL: false;
103
+ readonly PBR_DEBUG: false;
97
104
  };
98
105
  readonly getUniforms: (props: Partial<PBRMaterialProps>) => Partial<PBRMaterialProps>;
99
106
  readonly uniformTypes: {
@@ -1 +1 @@
1
- {"version":3,"file":"pbr-material.d.ts","sourceRoot":"","sources":["../../../../src/modules/lighting/pbr-material/pbr-material.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EACV,OAAO,EACP,OAAO,EACP,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,YAAY,EACb,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAC,YAAY,EAAC,oDAAiD;AAOtE,gDAAgD;AAChD,MAAM,MAAM,mBAAmB,GAAG;IAEhC,oBAAoB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACtC,iBAAiB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,mBAAmB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACrC,4BAA4B,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9C,oBAAoB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAGtC,qBAAqB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACvC,sBAAsB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACxC,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,CAAC,EAAE,OAAO,CAAC;IAGhB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,eAAe,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IAEnD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,cAAc,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IAElD,uBAAuB,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IAC3D,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAEtC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IAInD,eAAe,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IACnD,YAAY,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAEzE;;;GAGG;AACH,eAAO,MAAM,WAAW;oBACT,gBAAgB;uBACb,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoDwD,CAAC"}
1
+ {"version":3,"file":"pbr-material.d.ts","sourceRoot":"","sources":["../../../../src/modules/lighting/pbr-material/pbr-material.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EACV,OAAO,EACP,OAAO,EACP,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,YAAY,EACb,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAC,YAAY,EAAC,oDAAiD;AAOtE,gDAAgD;AAChD,MAAM,MAAM,mBAAmB,GAAG;IAEhC,oBAAoB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACtC,iBAAiB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,mBAAmB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACrC,4BAA4B,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9C,oBAAoB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAGtC,qBAAqB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACvC,sBAAsB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACxC,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,CAAC,EAAE,OAAO,CAAC;IAGhB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,eAAe,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IAEnD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,cAAc,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IAElD,uBAAuB,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IAC3D,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAEtC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IAInD,eAAe,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IACnD,YAAY,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAEzE;;;GAGG;AACH,eAAO,MAAM,WAAW;oBACT,gBAAgB;uBACb,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoDwD,CAAC"}