@luma.gl/shadertools 9.3.0 → 9.3.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.
- package/dist/dist.dev.js +15 -28
- package/dist/dist.min.js +51 -48
- package/dist/index.cjs +15 -22
- package/dist/index.cjs.map +3 -3
- package/dist/modules/lighting/gouraud-material/gouraud-material.d.ts +0 -1
- package/dist/modules/lighting/gouraud-material/gouraud-material.d.ts.map +1 -1
- package/dist/modules/lighting/gouraud-material/gouraud-material.js +6 -11
- package/dist/modules/lighting/gouraud-material/gouraud-material.js.map +1 -1
- package/dist/modules/lighting/phong-material/phong-material.d.ts +0 -1
- package/dist/modules/lighting/phong-material/phong-material.d.ts.map +1 -1
- package/dist/modules/lighting/phong-material/phong-material.js +6 -11
- package/dist/modules/lighting/phong-material/phong-material.js.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.js +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js +4 -1
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js.map +1 -1
- package/package.json +3 -3
- package/src/modules/lighting/gouraud-material/gouraud-material.ts +7 -15
- package/src/modules/lighting/phong-material/phong-material.ts +7 -15
- package/src/modules/lighting/phong-material/phong-shaders-glsl.ts +1 -1
- package/src/modules/lighting/phong-material/phong-shaders-wgsl.ts +4 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts", "../src/lib/utils/assert.ts", "../src/lib/filters/prop-types.ts", "../src/module-injectors.ts", "../src/lib/shader-assembly/shader-injections.ts", "../src/lib/shader-module/shader-module.ts", "../src/lib/shader-module/shader-module-dependencies.ts", "../src/lib/shader-module/shader-module-uniform-layout.ts", "../src/lib/shader-assembly/platform-defines.ts", "../src/lib/shader-transpiler/transpile-glsl-shader.ts", "../src/lib/shader-assembly/shader-hooks.ts", "../src/lib/glsl-utils/get-shader-info.ts", "../src/lib/shader-assembly/wgsl-binding-scan.ts", "../src/lib/shader-assembly/wgsl-binding-debug.ts", "../src/lib/shader-assembly/assemble-shaders.ts", "../src/lib/preprocessor/preprocessor.ts", "../src/lib/shader-assembler.ts", "../src/lib/glsl-utils/shader-utils.ts", "../src/lib/shader-generator/utils/capitalize.ts", "../src/lib/shader-generator/glsl/generate-glsl.ts", "../src/lib/shader-generator/wgsl/generate-wgsl.ts", "../src/lib/shader-generator/generate-shader.ts", "../src/modules/math/fp16/fp16-utils.ts", "../src/modules/math/fp64/fp64-utils.ts", "../src/lib/color/normalize-byte-colors.ts", "../src/modules/math/random/random.ts", "../src/modules/math/fp32/fp32.ts", "../src/modules/math/fp64/fp64-arithmetic-glsl.ts", "../src/modules/math/fp64/fp64-arithmetic-wgsl.ts", "../src/modules/math/fp64/fp64-functions-glsl.ts", "../src/modules/math/fp64/fp64.ts", "../src/modules/color/float-colors.ts", "../src/modules/engine/picking/picking.ts", "../src/modules/engine/skin/skin.ts", "../src/modules/lighting/lights/lighting.ts", "../src/modules/lighting/lights/lighting-glsl.ts", "../src/modules/lighting/lights/lighting-wgsl.ts", "../src/modules/lighting/ibl/ibl.ts", "../src/modules/lighting/no-material/dirlight.ts", "../src/modules/lighting/lambert-material/lambert-shaders-wgsl.ts", "../src/modules/lighting/lambert-material/lambert-shaders-glsl.ts", "../src/modules/lighting/lambert-material/lambert-material.ts", "../src/modules/lighting/phong-material/phong-shaders-glsl.ts", "../src/modules/lighting/phong-material/phong-shaders-wgsl.ts", "../src/modules/lighting/gouraud-material/gouraud-material.ts", "../src/modules/lighting/phong-material/phong-material.ts", "../src/modules/lighting/pbr-material/pbr-material-glsl.ts", "../src/modules/lighting/pbr-material/pbr-material-wgsl.ts", "../src/modules/lighting/pbr-material/pbr-projection.ts", "../src/modules/lighting/pbr-material/pbr-material.ts", "../src/modules/lighting/pbr-material/pbr-scene.ts"],
|
|
4
|
-
"sourcesContent": ["// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// shadertools exports\n\n/**\n * Marks GLSL shaders for syntax highlighting: glsl`...`\n * Install https://marketplace.visualstudio.com/items?itemName=boyswan.glsl-literal\n */\nexport type {PlatformInfo} from './lib/shader-assembly/platform-info';\nexport type {ShaderBindingDebugRow} from './lib/shader-assembly/wgsl-binding-debug';\n\n// ShaderModules\n\nexport type {ShaderModule} from './lib/shader-module/shader-module';\nexport type {ShaderPass} from './lib/shader-module/shader-pass';\nexport type {ShaderModuleUniformValue, UniformTypes} from './lib/utils/uniform-types';\n\nexport {initializeShaderModule, initializeShaderModules} from './lib/shader-module/shader-module';\nexport {getShaderModuleUniforms} from './lib/shader-module/shader-module';\nexport {getShaderModuleDependencies} from './lib/shader-module/shader-module-dependencies';\nexport {checkShaderModuleDeprecations} from './lib/shader-module/shader-module';\nexport type {\n GLSLUniformBlockInfo,\n ShaderModuleUniformLayoutStage,\n ShaderModuleUniformLayoutValidationResult\n} from './lib/shader-module/shader-module-uniform-layout';\nexport {\n getGLSLUniformBlocks,\n getShaderModuleUniformBlockFields,\n getShaderModuleUniformBlockName,\n getShaderModuleUniformLayoutValidationResult,\n validateShaderModuleUniformLayout,\n warnIfGLSLUniformBlocksAreNotStd140\n} from './lib/shader-module/shader-module-uniform-layout';\n\nexport {getShaderModuleSource} from './lib/shader-assembly/assemble-shaders';\n\nexport {resolveModules as _resolveModules} from './lib/shader-module/shader-module-dependencies';\nexport {getDependencyGraph as _getDependencyGraph} from './lib/shader-module/shader-module-dependencies';\n\n// ShaderAssembler\nexport {ShaderAssembler} from './lib/shader-assembler';\nexport type {ShaderHook} from './lib/shader-assembly/shader-hooks';\nexport type {ShaderInjection} from './lib/shader-assembly/shader-injections';\n\n// SHADER HELPERS\n\n// Shader source introspection\nexport {getShaderInfo} from './lib/glsl-utils/get-shader-info';\nexport {\n getQualifierDetails,\n getPassthroughFS,\n typeToChannelSuffix,\n typeToChannelCount,\n convertToVec4\n} from './lib/glsl-utils/shader-utils';\n\n// EXPERIMENTAL - Do not use in production applications\nexport type {ShaderGenerationOptions} from './lib/shader-generator/generate-shader';\nexport {generateShaderForModule} from './lib/shader-generator/generate-shader';\nexport {capitalize} from './lib/shader-generator/utils/capitalize';\n\n// TEST EXPORTS - Do not use in production applications\nexport {preprocess} from './lib/preprocessor/preprocessor';\nexport {assembleGLSLShaderPair} from './lib/shader-assembly/assemble-shaders';\nexport {combineInjects} from './lib/shader-assembly/shader-injections';\n\n// data utils\nexport {toHalfFloat, fromHalfFloat} from './modules/math/fp16/fp16-utils';\nexport {fp64ify, fp64LowPart, fp64ifyMatrix4} from './modules/math/fp64/fp64-utils';\nexport {\n normalizeByteColor3,\n normalizeByteColor4,\n resolveUseByteColors\n} from './lib/color/normalize-byte-colors';\n\n// math libraries\nexport {random} from './modules/math/random/random';\n\nexport {fp32} from './modules/math/fp32/fp32';\nexport {fp64, fp64arithmetic} from './modules/math/fp64/fp64';\nexport type {FloatColorsProps, FloatColorsUniforms} from './modules/color/float-colors';\nexport {floatColors} from './modules/color/float-colors';\n\n// engine shader modules\n\n// projection\n// export type {ProjectionUniforms} from './modules/engine/project/project';\n// export {projection} from './modules/engine/project/project';\nexport type {PickingProps, PickingUniforms} from './modules/engine/picking/picking';\nexport {picking} from './modules/engine/picking/picking';\nexport {skin} from './modules/engine/skin/skin';\n\n// lighting\nexport {\n type Light,\n type AmbientLight,\n type PointLight,\n type SpotLight,\n type DirectionalLight,\n type LightingLightUniform\n} from './modules/lighting/lights/lighting';\n\nexport type {LightingProps, LightingUniforms} from './modules/lighting/lights/lighting';\nexport {lighting} from './modules/lighting/lights/lighting';\nexport type {IBLBindings} from './modules/lighting/ibl/ibl';\nexport {ibl} from './modules/lighting/ibl/ibl';\nexport {dirlight} from './modules/lighting/no-material/dirlight';\nexport type {LambertMaterialProps} from './modules/lighting/lambert-material/lambert-material';\nexport {lambertMaterial} from './modules/lighting/lambert-material/lambert-material';\nexport type {GouraudMaterialProps} from './modules/lighting/gouraud-material/gouraud-material';\nexport {gouraudMaterial} from './modules/lighting/gouraud-material/gouraud-material';\nexport type {PhongMaterialProps} from './modules/lighting/phong-material/phong-material';\nexport {phongMaterial} from './modules/lighting/phong-material/phong-material';\nexport type {\n PBRMaterialBindings,\n PBRMaterialProps,\n PBRMaterialUniforms\n} from './modules/lighting/pbr-material/pbr-material';\nexport type {\n PBRSceneBindings,\n PBRSceneProps,\n PBRSceneUniforms\n} from './modules/lighting/pbr-material/pbr-scene';\nexport type {PBRProjectionProps} from './modules/lighting/pbr-material/pbr-projection';\n\nexport {pbrMaterial} from './modules/lighting/pbr-material/pbr-material';\nexport {pbrScene} from './modules/lighting/pbr-material/pbr-scene';\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// Recommendation is to ignore message but current test suite checks agains the\n// message so keep it for now.\nexport function assert(condition: unknown, message?: string): void {\n if (!condition) {\n const error = new Error(message || 'shadertools: assertion failed.');\n Error.captureStackTrace?.(error, assert);\n throw error;\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {assert} from '../utils/assert';\n\n/**\n * For use by shader module and shader pass writers to describe the types of the\n * properties they expose (properties ultimately map to uniforms).\n */\nexport type PropType =\n | {\n type?: string;\n value?: unknown;\n max?: number;\n min?: number;\n softMax?: number;\n softMin?: number;\n hint?: string;\n /** @deprecated internal uniform */\n private?: boolean;\n }\n | number;\n\n/**\n * Internal property validators generated by processing the prop types ,\n * The `validate()` method can be used to validate the type of properties passed in to\n * shader module or shader pass\n */\nexport type PropValidator = {\n type: string;\n value?: unknown;\n max?: number;\n min?: number;\n private?: boolean;\n validate?(value: unknown, propDef: PropValidator): boolean;\n};\n\n/** Minimal validators for number and array types */\nconst DEFAULT_PROP_VALIDATORS: Record<string, PropValidator> = {\n number: {\n type: 'number',\n validate(value: unknown, propType: PropType) {\n return (\n Number.isFinite(value) &&\n typeof propType === 'object' &&\n (propType.max === undefined || (value as number) <= propType.max) &&\n (propType.min === undefined || (value as number) >= propType.min)\n );\n }\n },\n array: {\n type: 'array',\n validate(value: unknown, propType: PropType) {\n return Array.isArray(value) || ArrayBuffer.isView(value);\n }\n }\n};\n\n/**\n * Parse a list of property types into property definitions that can be used to validate\n * values passed in by applications.\n * @param propTypes\n * @returns\n */\nexport function makePropValidators(\n propTypes: Record<string, PropType>\n): Record<string, PropValidator> {\n const propValidators: Record<string, PropValidator> = {};\n for (const [name, propType] of Object.entries(propTypes)) {\n propValidators[name] = makePropValidator(propType);\n }\n return propValidators;\n}\n\n/**\n * Validate a map of user supplied properties against a map of validators\n * Inject default values when user doesn't supply a property\n * @param properties\n * @param propValidators\n * @returns\n */\nexport function getValidatedProperties(\n properties: Record<string, unknown>,\n propValidators: Record<string, PropValidator>,\n errorMessage: string\n): Record<string, unknown> {\n const validated: Record<string, unknown> = {};\n\n for (const [key, propsValidator] of Object.entries(propValidators)) {\n if (properties && key in properties && !propsValidator.private) {\n if (propsValidator.validate) {\n assert(\n propsValidator.validate(properties[key], propsValidator),\n `${errorMessage}: invalid ${key}`\n );\n }\n validated[key] = properties[key];\n } else {\n // property not supplied - use default value\n validated[key] = propsValidator.value;\n }\n }\n\n // TODO - warn for unused properties that don't match a validator?\n\n return validated;\n}\n\n/**\n * Creates a property validator for a prop type. Either contains:\n * - a valid prop type object ({type, ...})\n * - or just a default value, in which case type and name inference is used\n */\nfunction makePropValidator(propType: PropType): PropValidator {\n let type = getTypeOf(propType);\n\n if (type !== 'object') {\n return {value: propType, ...DEFAULT_PROP_VALIDATORS[type], type};\n }\n\n // Special handling for objects\n if (typeof propType === 'object') {\n if (!propType) {\n return {type: 'object', value: null};\n }\n if (propType.type !== undefined) {\n return {...propType, ...DEFAULT_PROP_VALIDATORS[propType.type], type: propType.type};\n }\n // If no type and value this object is likely the value\n if (propType.value === undefined) {\n return {type: 'object', value: propType};\n }\n\n type = getTypeOf(propType.value);\n return {...propType, ...DEFAULT_PROP_VALIDATORS[type], type};\n }\n\n throw new Error('props');\n}\n\n/**\n * \"improved\" version of javascript typeof that can distinguish arrays and null values\n */\nfunction getTypeOf(value: unknown): string {\n if (Array.isArray(value) || ArrayBuffer.isView(value)) {\n return 'array';\n }\n return typeof value;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const MODULE_INJECTORS_VS = /* glsl */ `\\\n#ifdef MODULE_LOGDEPTH\n logdepth_adjustPosition(gl_Position);\n#endif\n`;\n\nexport const MODULE_INJECTORS_FS = /* glsl */ `\\\n#ifdef MODULE_MATERIAL\n fragColor = material_filterColor(fragColor);\n#endif\n\n#ifdef MODULE_LIGHTING\n fragColor = lighting_filterColor(fragColor);\n#endif\n\n#ifdef MODULE_FOG\n fragColor = fog_filterColor(fragColor);\n#endif\n\n#ifdef MODULE_PICKING\n fragColor = picking_filterHighlightColor(fragColor);\n fragColor = picking_filterPickingColor(fragColor);\n#endif\n\n#ifdef MODULE_LOGDEPTH\n logdepth_setFragDepth();\n#endif\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {MODULE_INJECTORS_VS, MODULE_INJECTORS_FS} from '../../module-injectors';\nimport {assert} from '../utils/assert';\n\n// TODO - experimental\nconst MODULE_INJECTORS = {\n vertex: MODULE_INJECTORS_VS,\n fragment: MODULE_INJECTORS_FS\n};\n\nconst REGEX_START_OF_MAIN = /void\\s+main\\s*\\([^)]*\\)\\s*\\{\\n?/; // Beginning of main\nconst REGEX_END_OF_MAIN = /}\\n?[^{}]*$/; // End of main, assumes main is last function\nconst fragments: string[] = [];\n\nexport const DECLARATION_INJECT_MARKER = '__LUMA_INJECT_DECLARATIONS__';\n\n/**\n *\n */\nexport type ShaderInjection = {\n injection: string;\n order: number;\n};\n\n/**\n * ShaderInjections, parsed and split per shader\n */\nexport type ShaderInjections = {\n vertex: Record<string, ShaderInjection>;\n fragment: Record<string, ShaderInjection>;\n};\n\n/**\n *\n */\nexport function normalizeInjections(\n injections: Record<string, string | ShaderInjection>\n): ShaderInjections {\n const result: ShaderInjections = {vertex: {}, fragment: {}};\n\n for (const hook in injections) {\n let injection = injections[hook];\n const stage = getHookStage(hook);\n if (typeof injection === 'string') {\n injection = {\n order: 0,\n injection\n };\n }\n\n result[stage][hook] = injection;\n }\n\n return result;\n}\n\nfunction getHookStage(hook: string): 'vertex' | 'fragment' {\n const type = hook.slice(0, 2);\n switch (type) {\n case 'vs':\n return 'vertex';\n case 'fs':\n return 'fragment';\n default:\n throw new Error(type);\n }\n}\n\n/**\n// A minimal shader injection/templating system.\n// RFC: https://github.com/visgl/luma.gl/blob/7.0-release/dev-docs/RFCs/v6.0/shader-injection-rfc.md\n * @param source \n * @param type \n * @param inject \n * @param injectStandardStubs \n * @returns \n */\n// eslint-disable-next-line complexity\nexport function injectShader(\n source: string,\n stage: 'vertex' | 'fragment',\n inject: Record<string, ShaderInjection[]>,\n injectStandardStubs = false\n): string {\n const isVertex = stage === 'vertex';\n\n for (const key in inject) {\n const fragmentData = inject[key];\n fragmentData.sort((a: ShaderInjection, b: ShaderInjection): number => a.order - b.order);\n fragments.length = fragmentData.length;\n for (let i = 0, len = fragmentData.length; i < len; ++i) {\n fragments[i] = fragmentData[i].injection;\n }\n const fragmentString = `${fragments.join('\\n')}\\n`;\n switch (key) {\n // declarations are injected before the main function\n case 'vs:#decl':\n if (isVertex) {\n source = source.replace(DECLARATION_INJECT_MARKER, fragmentString);\n }\n break;\n // inject code at the beginning of the main function\n case 'vs:#main-start':\n if (isVertex) {\n source = source.replace(REGEX_START_OF_MAIN, (match: string) => match + fragmentString);\n }\n break;\n // inject code at the end of main function\n case 'vs:#main-end':\n if (isVertex) {\n source = source.replace(REGEX_END_OF_MAIN, (match: string) => fragmentString + match);\n }\n break;\n // declarations are injected before the main function\n case 'fs:#decl':\n if (!isVertex) {\n source = source.replace(DECLARATION_INJECT_MARKER, fragmentString);\n }\n break;\n // inject code at the beginning of the main function\n case 'fs:#main-start':\n if (!isVertex) {\n source = source.replace(REGEX_START_OF_MAIN, (match: string) => match + fragmentString);\n }\n break;\n // inject code at the end of main function\n case 'fs:#main-end':\n if (!isVertex) {\n source = source.replace(REGEX_END_OF_MAIN, (match: string) => fragmentString + match);\n }\n break;\n\n default:\n // TODO(Tarek): I think this usage should be deprecated.\n\n // inject code after key, leaving key in place\n source = source.replace(key, (match: string) => match + fragmentString);\n }\n }\n\n // Remove if it hasn't already been replaced\n source = source.replace(DECLARATION_INJECT_MARKER, '');\n\n // Finally, if requested, insert an automatic module injector chunk\n if (injectStandardStubs) {\n source = source.replace(/\\}\\s*$/, (match: string) => match + MODULE_INJECTORS[stage]);\n }\n\n return source;\n}\n\n// Takes an array of inject objects and combines them into one\nexport function combineInjects(injects: any[]): Record<string, string> {\n const result: Record<string, string> = {};\n assert(Array.isArray(injects) && injects.length > 1);\n injects.forEach(inject => {\n for (const key in inject) {\n result[key] = result[key] ? `${result[key]}\\n${inject[key]}` : inject[key];\n }\n });\n return result;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {UniformFormat} from '../../types';\nimport {\n PropType,\n PropValidator,\n makePropValidators,\n getValidatedProperties\n} from '../filters/prop-types';\nimport type {ShaderModuleUniformValue, UniformTypes, UniformValue} from '../utils/uniform-types';\nimport {ShaderInjection, normalizeInjections} from '../shader-assembly/shader-injections';\n\n// To avoid dependency on core module, do not import `Binding` type.\n// The ShaderModule is not concerned with the type of `Binding`,\n// it is the repsonsibility of `splitUniformsAndBindings` in\n// ShaderInputs to type the result of `getUniforms()`\ntype Binding = unknown; // import type {Binding} from '@luma.gl/core';\n\nexport type UniformInfo = {\n format?: UniformFormat;\n} & PropType;\n\nexport type ShaderModuleBindingLayout = {\n name: string;\n group: number;\n};\n\n// Helper types\ntype BindingKeys<T> = {[K in keyof T]: T[K] extends UniformValue ? never : K}[keyof T];\ntype UniformKeys<T> = {[K in keyof T]: T[K] extends UniformValue ? K : never}[keyof T];\nexport type PickBindings<T> = {[K in BindingKeys<Required<T>>]: T[K]};\nexport type PickUniforms<T> = {[K in UniformKeys<Required<T>>]: T[K]};\n\n/**\n * A shader module definition object\n *\n * @note Needs to be initialized with `initializeShaderModules`\n * @note `UniformsT` & `BindingsT` are deduced from `PropsT` by default. If\n * a custom type for `UniformsT` is used, `BindingsT` should be also be provided.\n */\nexport type ShaderModule<\n PropsT extends Record<string, any> = Record<string, any>,\n UniformsT extends Record<string, ShaderModuleUniformValue> = PickUniforms<PropsT>,\n BindingsT extends Record<string, Binding> = PickBindings<PropsT>\n> = {\n /** Used for type inference not for values */\n props?: PropsT;\n /** Used for type inference, not currently used for values */\n uniforms?: UniformsT;\n /** Used for type inference, not currently used for values */\n bindings?: BindingsT;\n /** Logical bind-group assignment for bindings declared by this module */\n bindingLayout?: readonly ShaderModuleBindingLayout[];\n /** Preferred starting binding slot for this module's WGSL `@binding(auto)` declarations. */\n firstBindingSlot?: number;\n\n name: string;\n\n /** WGSL code */\n source?: string;\n /** GLSL fragment shader code */\n fs?: string;\n /** GLSL vertex shader code */\n vs?: string;\n\n /** Uniform shader types @note: Both order and types MUST match uniform block declarations in shader */\n uniformTypes?: Required<UniformTypes<UniformsT>>; // Record<keyof UniformsT, UniformFormat>;\n /** Uniform JS prop types */\n propTypes?: Record<keyof UniformsT, UniformInfo>;\n /** Default uniform values */\n defaultUniforms?: Required<UniformsT>; // Record<keyof UniformsT, UniformValue>;\n\n /** Function that maps props to uniforms & bindings */\n getUniforms?: (\n props: Partial<PropsT>,\n prevUniforms?: UniformsT\n ) => Partial<UniformsT & BindingsT>;\n\n defines?: Record<string, boolean | number>;\n /** Injections */\n inject?: Record<string, string | {injection: string; order: number}>;\n dependencies?: ShaderModule<any, any>[];\n /** Information on deprecated properties */\n deprecations?: ShaderModuleDeprecation[];\n\n /** The instance field contains information that is generated at run-time */\n instance?: {\n propValidators?: Record<string, PropValidator>;\n parsedDeprecations: ShaderModuleDeprecation[];\n\n normalizedInjections: {\n vertex: Record<string, ShaderInjection>;\n fragment: Record<string, ShaderInjection>;\n };\n };\n};\n\n/** Use to generate deprecations when shader module is used */\nexport type ShaderModuleDeprecation = {\n type: string;\n regex?: RegExp;\n new: string;\n old: string;\n deprecated?: boolean;\n};\n\n// SHNDER MODULE API\n\nexport function initializeShaderModules(modules: ShaderModule[]): void {\n modules.map((module: ShaderModule) => initializeShaderModule(module));\n}\n\nexport function initializeShaderModule(module: ShaderModule): void {\n if (module.instance) {\n return;\n }\n\n initializeShaderModules(module.dependencies || []);\n\n const {\n propTypes = {},\n deprecations = [],\n // defines = {},\n inject = {}\n } = module;\n\n const instance: Required<ShaderModule>['instance'] = {\n normalizedInjections: normalizeInjections(inject),\n parsedDeprecations: parseDeprecationDefinitions(deprecations)\n };\n\n if (propTypes) {\n instance.propValidators = makePropValidators(propTypes);\n }\n\n module.instance = instance;\n\n // TODO(ib) - we need to apply the original prop types to the default uniforms\n let defaultProps: ShaderModule['props'] = {};\n if (propTypes) {\n defaultProps = Object.entries(propTypes).reduce(\n (obj: ShaderModule['props'], [key, propType]) => {\n // @ts-expect-error\n const value = propType?.value;\n if (value) {\n // @ts-expect-error\n obj[key] = value;\n }\n return obj;\n },\n {} as ShaderModule['props']\n );\n }\n\n module.defaultUniforms = {...module.defaultUniforms, ...defaultProps} as any;\n}\n\n/** Convert module props to uniforms */\nexport function getShaderModuleUniforms<\n ShaderModuleT extends ShaderModule<\n Record<string, unknown>,\n Record<string, ShaderModuleUniformValue>\n >\n>(\n module: ShaderModuleT,\n props?: ShaderModuleT['props'],\n oldUniforms?: ShaderModuleT['uniforms']\n): Record<string, Binding | ShaderModuleUniformValue> {\n initializeShaderModule(module);\n\n const uniforms = oldUniforms || {...module.defaultUniforms};\n // If module has a getUniforms function, use it\n if (props && module.getUniforms) {\n return module.getUniforms(props, uniforms);\n }\n\n // Build uniforms from the uniforms array\n // @ts-expect-error\n return getValidatedProperties(props, module.instance?.propValidators, module.name);\n}\n\n/* TODO this looks like it was unused code\n _defaultGetUniforms(opts: Record<string, any> = {}): Record<string, any> {\n const uniforms: Record<string, any> = {};\n const propTypes = this.uniforms;\n\n for (const key in propTypes) {\n const propDef = propTypes[key];\n if (key in opts && !propDef.private) {\n if (propDef.validate) {\n assert(propDef.validate(opts[key], propDef), `${this.name}: invalid ${key}`);\n }\n uniforms[key] = opts[key];\n } else {\n uniforms[key] = propDef.value;\n }\n }\n\n return uniforms;\n }\n}\n*/\n// Warn about deprecated uniforms or functions\nexport function checkShaderModuleDeprecations(\n shaderModule: ShaderModule,\n shaderSource: string,\n log: any\n): void {\n shaderModule.deprecations?.forEach(def => {\n if (def.regex?.test(shaderSource)) {\n if (def.deprecated) {\n log.deprecated(def.old, def.new)();\n } else {\n log.removed(def.old, def.new)();\n }\n }\n });\n}\n\n// HELPERS\n\nfunction parseDeprecationDefinitions(deprecations: ShaderModuleDeprecation[]) {\n deprecations.forEach(def => {\n switch (def.type) {\n case 'function':\n def.regex = new RegExp(`\\\\b${def.old}\\\\(`);\n break;\n default:\n def.regex = new RegExp(`${def.type} ${def.old};`);\n }\n });\n\n return deprecations;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {ShaderModule, initializeShaderModules} from './shader-module';\n\n// import type {ShaderModule} from '../shader-module/shader-module';\n\ntype AbstractModule = {\n name: string;\n dependencies?: AbstractModule[];\n};\n\n/**\n * Takes a list of shader module names and returns a new list of\n * shader module names that includes all dependencies, sorted so\n * that modules that are dependencies of other modules come first.\n *\n * If the shader glsl code from the returned modules is concatenated\n * in the reverse order, it is guaranteed that all functions be resolved and\n * that all function and variable definitions come before use.\n *\n * @param modules - Array of modules (inline modules or module names)\n * @return - Array of modules\n */\nexport function getShaderModuleDependencies<T extends AbstractModule>(modules: T[]): T[] {\n initializeShaderModules(modules);\n const moduleMap: Record<string, T> = {};\n const moduleDepth: Record<string, number> = {};\n getDependencyGraph({modules, level: 0, moduleMap, moduleDepth});\n\n // Return a reverse sort so that dependencies come before the modules that use them\n const dependencies = Object.keys(moduleDepth)\n .sort((a, b) => moduleDepth[b] - moduleDepth[a])\n .map(name => moduleMap[name]);\n initializeShaderModules(dependencies);\n return dependencies;\n}\n\n/**\n * Recursively checks module dependencies to calculate dependency level of each module.\n *\n * @param options.modules - Array of modules\n * @param options.level - Current level\n * @param options.moduleMap -\n * @param options.moduleDepth - Current level\n * @return - Map of module name to its level\n */\n// Adds another level of dependencies to the result map\nexport function getDependencyGraph<T extends AbstractModule>(options: {\n modules: T[];\n level: number;\n moduleMap: Record<string, T>;\n moduleDepth: Record<string, number>;\n}) {\n const {modules, level, moduleMap, moduleDepth} = options;\n if (level >= 5) {\n throw new Error('Possible loop in shader dependency graph');\n }\n\n // Update level on all current modules\n for (const module of modules) {\n moduleMap[module.name] = module;\n if (moduleDepth[module.name] === undefined || moduleDepth[module.name] < level) {\n moduleDepth[module.name] = level;\n }\n }\n\n // Recurse\n for (const module of modules) {\n if (module.dependencies) {\n getDependencyGraph({modules: module.dependencies, level: level + 1, moduleMap, moduleDepth});\n }\n }\n}\n\n/**\n * Takes a list of shader module names and returns a new list of\n * shader module names that includes all dependencies, sorted so\n * that modules that are dependencies of other modules come first.\n *\n * If the shader glsl code from the returned modules is concatenated\n * in the reverse order, it is guaranteed that all functions be resolved and\n * that all function and variable definitions come before use.\n *\n * @param modules - Array of modules (inline modules or module names)\n * @return - Array of modules\n */\nexport function getShaderDependencies(modules: ShaderModule[]): ShaderModule[] {\n initializeShaderModules(modules);\n const moduleMap: Record<string, ShaderModule> = {};\n const moduleDepth: Record<string, number> = {};\n getDependencyGraph({modules, level: 0, moduleMap, moduleDepth});\n\n // Return a reverse sort so that dependencies come before the modules that use them\n modules = Object.keys(moduleDepth)\n .sort((a, b) => moduleDepth[b] - moduleDepth[a])\n .map(name => moduleMap[name]);\n initializeShaderModules(modules);\n return modules;\n}\n\n// DEPRECATED\n\n/**\n * Instantiate shader modules and resolve any dependencies\n * @deprecated Use getShaderDpendencies\n */\nexport function resolveModules(modules: ShaderModule[]): ShaderModule[] {\n return getShaderDependencies(modules);\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderModule} from './shader-module';\nimport {assert} from '../utils/assert';\n\n/**\n * Shader stages supported by shader-module uniform-layout validation helpers.\n */\nexport type ShaderModuleUniformLayoutStage = 'vertex' | 'fragment' | 'wgsl';\n\n/**\n * Describes the result of comparing declared `uniformTypes` with the fields\n * found in a shader uniform block.\n */\nexport type ShaderModuleUniformLayoutValidationResult = {\n /** Name of the shader module being validated. */\n moduleName: string;\n /** Expected block name derived from the shader module name. */\n uniformBlockName: string;\n /** Shader stage that was inspected. */\n stage: ShaderModuleUniformLayoutStage;\n /** Field names declared by the module metadata. */\n expectedUniformNames: string[];\n /** Field names parsed from the shader source. */\n actualUniformNames: string[];\n /** Whether the declared and parsed field lists match exactly. */\n matches: boolean;\n};\n\n/**\n * Parsed information about one GLSL uniform block declaration.\n */\nexport type GLSLUniformBlockInfo = {\n /** Declared block type name. */\n blockName: string;\n /** Optional instance name that follows the block declaration. */\n instanceName: string | null;\n /** Raw layout qualifier text, if present. */\n layoutQualifier: string | null;\n /** Whether any explicit layout qualifier was present. */\n hasLayoutQualifier: boolean;\n /** Whether the block explicitly declares `layout(std140)`. */\n isStd140: boolean;\n /** Raw source text inside the block braces. */\n body: string;\n};\n\n/**\n * Logging surface used by validation and warning helpers.\n */\ntype Logger = {\n /** Error logger compatible with luma's deferred log API. */\n error?: (...args: unknown[]) => () => unknown;\n /** Warning logger compatible with luma's deferred log API. */\n warn?: (...args: unknown[]) => () => unknown;\n};\n\n/**\n * Matches one field declaration inside a GLSL uniform block body.\n */\nconst GLSL_UNIFORM_BLOCK_FIELD_REGEXP =\n /^(?:uniform\\s+)?(?:(?:lowp|mediump|highp)\\s+)?[A-Za-z0-9_]+(?:<[^>]+>)?\\s+([A-Za-z0-9_]+)(?:\\s*\\[[^\\]]+\\])?\\s*;/;\n/**\n * Matches full GLSL uniform block declarations, including optional layout qualifiers.\n */\nconst GLSL_UNIFORM_BLOCK_REGEXP =\n /((?:layout\\s*\\([^)]*\\)\\s*)*)uniform\\s+([A-Za-z_][A-Za-z0-9_]*)\\s*\\{([\\s\\S]*?)\\}\\s*([A-Za-z_][A-Za-z0-9_]*)?\\s*;/g;\n\n/**\n * Returns the uniform block type name expected for the supplied shader module.\n */\nexport function getShaderModuleUniformBlockName(module: ShaderModule): string {\n return `${module.name}Uniforms`;\n}\n\n/**\n * Returns the ordered field names parsed from a shader module's uniform block.\n *\n * @returns `null` when the stage has no source or the expected block is absent.\n */\nexport function getShaderModuleUniformBlockFields(\n module: ShaderModule,\n stage: ShaderModuleUniformLayoutStage\n): string[] | null {\n const shaderSource =\n stage === 'wgsl' ? module.source : stage === 'vertex' ? module.vs : module.fs;\n\n if (!shaderSource) {\n return null;\n }\n\n const uniformBlockName = getShaderModuleUniformBlockName(module);\n return extractShaderUniformBlockFieldNames(\n shaderSource,\n stage === 'wgsl' ? 'wgsl' : 'glsl',\n uniformBlockName\n );\n}\n\n/**\n * Computes the validation result for a shader module's declared and parsed\n * uniform-block field lists.\n *\n * @returns `null` when the module has no declared uniform types or no matching block.\n */\nexport function getShaderModuleUniformLayoutValidationResult(\n module: ShaderModule,\n stage: ShaderModuleUniformLayoutStage\n): ShaderModuleUniformLayoutValidationResult | null {\n const expectedUniformNames = Object.keys(module.uniformTypes || {});\n if (!expectedUniformNames.length) {\n return null;\n }\n\n const actualUniformNames = getShaderModuleUniformBlockFields(module, stage);\n if (!actualUniformNames) {\n return null;\n }\n\n return {\n moduleName: module.name,\n uniformBlockName: getShaderModuleUniformBlockName(module),\n stage,\n expectedUniformNames,\n actualUniformNames,\n matches: areStringArraysEqual(expectedUniformNames, actualUniformNames)\n };\n}\n\n/**\n * Validates that a shader module's parsed uniform block matches `uniformTypes`.\n *\n * When a mismatch is detected, the helper logs a formatted error and optionally\n * throws via {@link assert}.\n */\nexport function validateShaderModuleUniformLayout(\n module: ShaderModule,\n stage: ShaderModuleUniformLayoutStage,\n options: {\n log?: Logger;\n throwOnError?: boolean;\n } = {}\n): ShaderModuleUniformLayoutValidationResult | null {\n const validationResult = getShaderModuleUniformLayoutValidationResult(module, stage);\n if (!validationResult || validationResult.matches) {\n return validationResult;\n }\n\n const message = formatShaderModuleUniformLayoutError(validationResult);\n options.log?.error?.(message, validationResult)();\n\n if (options.throwOnError !== false) {\n assert(false, message);\n }\n\n return validationResult;\n}\n\n/**\n * Parses all GLSL uniform blocks in a shader source string.\n */\nexport function getGLSLUniformBlocks(shaderSource: string): GLSLUniformBlockInfo[] {\n const blocks: GLSLUniformBlockInfo[] = [];\n const uncommentedSource = stripShaderComments(shaderSource);\n\n for (const sourceMatch of uncommentedSource.matchAll(GLSL_UNIFORM_BLOCK_REGEXP)) {\n const layoutQualifier = sourceMatch[1]?.trim() || null;\n blocks.push({\n blockName: sourceMatch[2],\n body: sourceMatch[3],\n instanceName: sourceMatch[4] || null,\n layoutQualifier,\n hasLayoutQualifier: Boolean(layoutQualifier),\n isStd140: Boolean(\n layoutQualifier && /\\blayout\\s*\\([^)]*\\bstd140\\b[^)]*\\)/.exec(layoutQualifier)\n )\n });\n }\n\n return blocks;\n}\n\n/**\n * Emits warnings for GLSL uniform blocks that do not explicitly declare\n * `layout(std140)`.\n *\n * @returns The list of parsed blocks that were considered non-compliant.\n */\nexport function warnIfGLSLUniformBlocksAreNotStd140(\n shaderSource: string,\n stage: Exclude<ShaderModuleUniformLayoutStage, 'wgsl'>,\n log?: Logger,\n context?: {label?: string}\n): GLSLUniformBlockInfo[] {\n const nonStd140Blocks = getGLSLUniformBlocks(shaderSource).filter(block => !block.isStd140);\n const seenBlockNames = new Set<string>();\n\n for (const block of nonStd140Blocks) {\n if (seenBlockNames.has(block.blockName)) {\n continue;\n }\n seenBlockNames.add(block.blockName);\n\n const shaderLabel = context?.label ? `${context.label} ` : '';\n const actualLayout = block.hasLayoutQualifier\n ? `declares ${normalizeWhitespace(block.layoutQualifier!)} instead of layout(std140)`\n : 'does not declare layout(std140)';\n const message = `${shaderLabel}${stage} shader uniform block ${\n block.blockName\n } ${actualLayout}. luma.gl host-side shader block packing assumes explicit layout(std140) for GLSL uniform blocks. Add \\`layout(std140)\\` to the block declaration.`;\n log?.warn?.(message, block)();\n }\n\n return nonStd140Blocks;\n}\n\n/**\n * Extracts field names from the named GLSL or WGSL uniform block/struct.\n */\nfunction extractShaderUniformBlockFieldNames(\n shaderSource: string,\n language: 'glsl' | 'wgsl',\n uniformBlockName: string\n): string[] | null {\n const sourceBody =\n language === 'wgsl'\n ? extractWGSLStructBody(shaderSource, uniformBlockName)\n : extractGLSLUniformBlockBody(shaderSource, uniformBlockName);\n\n if (!sourceBody) {\n return null;\n }\n\n const fieldNames: string[] = [];\n\n for (const sourceLine of sourceBody.split('\\n')) {\n const line = sourceLine.replace(/\\/\\/.*$/, '').trim();\n if (!line || line.startsWith('#')) {\n continue;\n }\n\n const fieldMatch =\n language === 'wgsl'\n ? line.match(/^([A-Za-z0-9_]+)\\s*:/)\n : line.match(GLSL_UNIFORM_BLOCK_FIELD_REGEXP);\n\n if (fieldMatch) {\n fieldNames.push(fieldMatch[1]);\n }\n }\n\n return fieldNames;\n}\n\n/**\n * Extracts the body of a WGSL struct with the supplied name.\n */\nfunction extractWGSLStructBody(shaderSource: string, uniformBlockName: string): string | null {\n const structMatch = new RegExp(`\\\\bstruct\\\\s+${uniformBlockName}\\\\b`, 'm').exec(shaderSource);\n if (!structMatch) {\n return null;\n }\n\n const openBraceIndex = shaderSource.indexOf('{', structMatch.index);\n if (openBraceIndex < 0) {\n return null;\n }\n\n let braceDepth = 0;\n for (let index = openBraceIndex; index < shaderSource.length; index++) {\n const character = shaderSource[index];\n if (character === '{') {\n braceDepth++;\n continue;\n }\n if (character !== '}') {\n continue;\n }\n\n braceDepth--;\n if (braceDepth === 0) {\n return shaderSource.slice(openBraceIndex + 1, index);\n }\n }\n\n return null;\n}\n\n/**\n * Extracts the body of a named GLSL uniform block from shader source.\n */\nfunction extractGLSLUniformBlockBody(\n shaderSource: string,\n uniformBlockName: string\n): string | null {\n const block = getGLSLUniformBlocks(shaderSource).find(\n candidate => candidate.blockName === uniformBlockName\n );\n return block?.body || null;\n}\n\n/**\n * Returns `true` when the two arrays contain the same strings in the same order.\n */\nfunction areStringArraysEqual(leftValues: string[], rightValues: string[]): boolean {\n if (leftValues.length !== rightValues.length) {\n return false;\n }\n\n for (let valueIndex = 0; valueIndex < leftValues.length; valueIndex++) {\n if (leftValues[valueIndex] !== rightValues[valueIndex]) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Formats the standard validation error message for a shader-module layout mismatch.\n */\nfunction formatShaderModuleUniformLayoutError(\n validationResult: ShaderModuleUniformLayoutValidationResult\n): string {\n const {expectedUniformNames, actualUniformNames} = validationResult;\n const missingUniformNames = expectedUniformNames.filter(\n uniformName => !actualUniformNames.includes(uniformName)\n );\n const unexpectedUniformNames = actualUniformNames.filter(\n uniformName => !expectedUniformNames.includes(uniformName)\n );\n const mismatchDetails = [\n `Expected ${expectedUniformNames.length} fields, found ${actualUniformNames.length}.`\n ];\n const firstMismatchDescription = getFirstUniformMismatchDescription(\n expectedUniformNames,\n actualUniformNames\n );\n if (firstMismatchDescription) {\n mismatchDetails.push(firstMismatchDescription);\n }\n if (missingUniformNames.length) {\n mismatchDetails.push(\n `Missing from shader block (${missingUniformNames.length}): ${formatUniformNameList(\n missingUniformNames\n )}.`\n );\n }\n if (unexpectedUniformNames.length) {\n mismatchDetails.push(\n `Unexpected in shader block (${unexpectedUniformNames.length}): ${formatUniformNameList(\n unexpectedUniformNames\n )}.`\n );\n }\n if (\n expectedUniformNames.length <= 12 &&\n actualUniformNames.length <= 12 &&\n (missingUniformNames.length || unexpectedUniformNames.length)\n ) {\n mismatchDetails.push(`Expected: ${expectedUniformNames.join(', ')}.`);\n mismatchDetails.push(`Actual: ${actualUniformNames.join(', ')}.`);\n }\n\n return `${validationResult.moduleName}: ${validationResult.stage} shader uniform block ${\n validationResult.uniformBlockName\n } does not match module.uniformTypes. ${mismatchDetails.join(' ')}`;\n}\n\n/**\n * Removes line and block comments from shader source before lightweight parsing.\n */\nfunction stripShaderComments(shaderSource: string): string {\n return shaderSource.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '').replace(/\\/\\/.*$/gm, '');\n}\n\n/**\n * Collapses repeated whitespace in a layout qualifier for log-friendly output.\n */\nfunction normalizeWhitespace(value: string): string {\n return value.replace(/\\s+/g, ' ').trim();\n}\n\nfunction getFirstUniformMismatchDescription(\n expectedUniformNames: string[],\n actualUniformNames: string[]\n): string | null {\n const minimumLength = Math.min(expectedUniformNames.length, actualUniformNames.length);\n for (let index = 0; index < minimumLength; index++) {\n if (expectedUniformNames[index] !== actualUniformNames[index]) {\n return `First mismatch at field ${index + 1}: expected ${\n expectedUniformNames[index]\n }, found ${actualUniformNames[index]}.`;\n }\n }\n\n if (expectedUniformNames.length > actualUniformNames.length) {\n return `Shader block ends after field ${actualUniformNames.length}; expected next field ${\n expectedUniformNames[actualUniformNames.length]\n }.`;\n }\n if (actualUniformNames.length > expectedUniformNames.length) {\n return `Shader block has extra field ${actualUniformNames.length}: ${\n actualUniformNames[expectedUniformNames.length]\n }.`;\n }\n\n return null;\n}\n\nfunction formatUniformNameList(uniformNames: string[], maxNames = 8): string {\n if (uniformNames.length <= maxNames) {\n return uniformNames.join(', ');\n }\n\n const remainingCount = uniformNames.length - maxNames;\n return `${uniformNames.slice(0, maxNames).join(', ')}, ... (${remainingCount} more)`;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {PlatformInfo} from './platform-info';\n\n/** Adds defines to help identify GPU architecture / platform */\nexport function getPlatformShaderDefines(platformInfo: PlatformInfo): string {\n switch (platformInfo?.gpu.toLowerCase()) {\n case 'apple':\n return /* glsl */ `\\\n#define APPLE_GPU\n// Apple optimizes away the calculation necessary for emulated fp64\n#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1\n#define LUMA_FP32_TAN_PRECISION_WORKAROUND 1\n// Intel GPU doesn't have full 32 bits precision in same cases, causes overflow\n#define LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND 1\n`;\n\n case 'nvidia':\n return /* glsl */ `\\\n#define NVIDIA_GPU\n// Nvidia optimizes away the calculation necessary for emulated fp64\n#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1\n`;\n\n case 'intel':\n return /* glsl */ `\\\n#define INTEL_GPU\n// Intel optimizes away the calculation necessary for emulated fp64\n#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1\n// Intel's built-in 'tan' function doesn't have acceptable precision\n#define LUMA_FP32_TAN_PRECISION_WORKAROUND 1\n// Intel GPU doesn't have full 32 bits precision in same cases, causes overflow\n#define LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND 1\n`;\n\n case 'amd':\n // AMD Does not eliminate fp64 code\n return /* glsl */ `\\\n#define AMD_GPU\n`;\n\n default:\n // We don't know what GPU it is, could be that the GPU driver or\n // browser is not implementing UNMASKED_RENDERER constant and not\n // reporting a correct name\n return /* glsl */ `\\\n#define DEFAULT_GPU\n// Prevent driver from optimizing away the calculation necessary for emulated fp64\n#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1\n// Headless Chrome's software shader 'tan' function doesn't have acceptable precision\n#define LUMA_FP32_TAN_PRECISION_WORKAROUND 1\n// If the GPU doesn't have full 32 bits precision, will causes overflow\n#define LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND 1\n`;\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// TRANSPILATION TABLES\n\n/**\n * Transpiles GLSL 3.00 shader source code to target GLSL version (3.00 or 1.00)\n *\n * @note We always run transpiler even if same version e.g. 3.00 => 3.00\n * @note For texture sampling transpilation, apps need to use non-standard texture* calls in GLSL 3.00 source\n * RFC: https://github.com/visgl/luma.gl/blob/7.0-release/dev-docs/RFCs/v6.0/portable-glsl-300-rfc.md\n */\nexport function transpileGLSLShader(source: string, stage: 'vertex' | 'fragment'): string {\n const sourceGLSLVersion = Number(source.match(/^#version[ \\t]+(\\d+)/m)?.[1] || 100);\n if (sourceGLSLVersion !== 300) {\n // TODO - we splurge on a longer error message to help deck.gl custom layer developers\n throw new Error('luma.gl v9 only supports GLSL 3.00 shader sources');\n }\n\n switch (stage) {\n case 'vertex':\n source = convertShader(source, ES300_VERTEX_REPLACEMENTS);\n return source;\n case 'fragment':\n source = convertShader(source, ES300_FRAGMENT_REPLACEMENTS);\n return source;\n default:\n // Unknown shader stage\n throw new Error(stage);\n }\n}\n\ntype GLSLReplacement = [RegExp, string];\n\n/** Simple regex replacements for GLSL ES 1.00 syntax that has changed in GLSL ES 3.00 */\nconst ES300_REPLACEMENTS: GLSLReplacement[] = [\n // Fix poorly formatted version directive\n [/^(#version[ \\t]+(100|300[ \\t]+es))?[ \\t]*\\n/, '#version 300 es\\n'],\n // The individual `texture...()` functions were replaced with `texture()` overloads\n [/\\btexture(2D|2DProj|Cube)Lod(EXT)?\\(/g, 'textureLod('],\n [/\\btexture(2D|2DProj|Cube)(EXT)?\\(/g, 'texture(']\n];\n\nconst ES300_VERTEX_REPLACEMENTS: GLSLReplacement[] = [\n ...ES300_REPLACEMENTS,\n // `attribute` keyword replaced with `in`\n [makeVariableTextRegExp('attribute'), 'in $1'],\n // `varying` keyword replaced with `out`\n [makeVariableTextRegExp('varying'), 'out $1']\n];\n\n/** Simple regex replacements for GLSL ES 1.00 syntax that has changed in GLSL ES 3.00 */\nconst ES300_FRAGMENT_REPLACEMENTS: GLSLReplacement[] = [\n ...ES300_REPLACEMENTS,\n // `varying` keyword replaced with `in`\n [makeVariableTextRegExp('varying'), 'in $1']\n];\n\nfunction convertShader(source: string, replacements: GLSLReplacement[]) {\n for (const [pattern, replacement] of replacements) {\n source = source.replace(pattern, replacement);\n }\n return source;\n}\n\n/**\n * Creates a regexp that tests for a specific variable type\n * @example\n * should match:\n * in float weight;\n * out vec4 positions[2];\n * should not match:\n * void f(out float a, in float b) {}\n */\nfunction makeVariableTextRegExp(qualifier: 'attribute' | 'varying' | 'in' | 'out'): RegExp {\n return new RegExp(`\\\\b${qualifier}[ \\\\t]+(\\\\w+[ \\\\t]+\\\\w+(\\\\[\\\\w+\\\\])?;)`, 'g');\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {ShaderInjection} from './shader-injections';\n\n// A normalized hook function\n/**\n * The shader hook mechanism allows the application to create shaders\n * that can be automatically extended by the shader modules the application\n * includes.\n *\n * A shader hook function that shader modules can inject code into.\n * Shaders can call these functions, which will be no-ops by default.\n *\n * If a shader module injects code it will be executed upon the hook\n * function call.\n */\nexport type ShaderHook = {\n /** `vs:` or `fs:` followed by the name and arguments of the function, e.g. `vs:MYHOOK_func(inout vec4 value)`. Hook name without arguments\n will also be used as the name of the shader hook */\n hook: string;\n /** Code always included at the beginning of a hook function */\n header: string;\n /** Code always included at the end of a hook function */\n footer: string;\n /** To Be Documented */\n signature?: string;\n};\n\n/** Normalized shader hooks per shader */\nexport type ShaderHooks = {\n /** Normalized shader hooks for vertex shader */\n vertex: Record<string, ShaderHook>;\n /** Normalized shader hooks for fragment shader */\n fragment: Record<string, ShaderHook>;\n};\n\n/** Generate hook source code */\nexport function getShaderHooks(\n hookFunctions: Record<string, ShaderHook>,\n hookInjections: Record<string, ShaderInjection[]>\n): string {\n let result = '';\n for (const hookName in hookFunctions) {\n const hookFunction = hookFunctions[hookName];\n result += `void ${hookFunction.signature} {\\n`;\n if (hookFunction.header) {\n result += ` ${hookFunction.header}`;\n }\n if (hookInjections[hookName]) {\n const injections = hookInjections[hookName];\n injections.sort((a: {order: number}, b: {order: number}): number => a.order - b.order);\n for (const injection of injections) {\n result += ` ${injection.injection}\\n`;\n }\n }\n if (hookFunction.footer) {\n result += ` ${hookFunction.footer}`;\n }\n result += '}\\n';\n }\n\n return result;\n}\n\n/**\n * Parse string based hook functions\n * And split per shader\n */\nexport function normalizeShaderHooks(hookFunctions: (string | ShaderHook)[]): ShaderHooks {\n const result: ShaderHooks = {vertex: {}, fragment: {}};\n\n for (const hookFunction of hookFunctions) {\n let opts: ShaderHook;\n let hook: string;\n if (typeof hookFunction !== 'string') {\n opts = hookFunction;\n hook = opts.hook;\n } else {\n opts = {} as ShaderHook;\n hook = hookFunction;\n }\n hook = hook.trim();\n const [shaderStage, signature] = hook.split(':');\n const name = hook.replace(/\\(.+/, '');\n const normalizedHook: ShaderHook = Object.assign(opts, {signature});\n switch (shaderStage) {\n case 'vs':\n result.vertex[name] = normalizedHook;\n break;\n case 'fs':\n result.fragment[name] = normalizedHook;\n break;\n default:\n throw new Error(shaderStage);\n }\n }\n\n return result;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/** Information extracted from shader source code */\nexport type ShaderInfo = {\n name: string;\n language: 'glsl' | 'wgsl';\n version: number;\n};\n\n/** Extracts information from shader source code */\nexport function getShaderInfo(source: string, defaultName?: string): ShaderInfo {\n return {\n name: getShaderName(source, defaultName),\n language: 'glsl',\n version: getShaderVersion(source)\n };\n}\n\n/** Extracts GLSLIFY style naming of shaders: `#define SHADER_NAME ...` */\nfunction getShaderName(shader: string, defaultName: string = 'unnamed'): string {\n const SHADER_NAME_REGEXP = /#define[^\\S\\r\\n]*SHADER_NAME[^\\S\\r\\n]*([A-Za-z0-9_-]+)\\s*/;\n const match = SHADER_NAME_REGEXP.exec(shader);\n return match ? match[1] : defaultName;\n}\n\n/** returns GLSL shader version of given shader string */\nfunction getShaderVersion(source: string): 100 | 300 {\n let version = 100;\n const words = source.match(/[^\\s]+/g);\n if (words && words.length >= 2 && words[0] === '#version') {\n const parsedVersion = parseInt(words[1], 10);\n if (Number.isFinite(parsedVersion)) {\n version = parsedVersion;\n }\n }\n if (version !== 100 && version !== 300) {\n throw new Error(`Invalid GLSL version ${version}`);\n }\n return version;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const WGSL_BINDABLE_VARIABLE_PATTERN =\n '(?:var<\\\\s*(uniform|storage(?:\\\\s*,\\\\s*[A-Za-z_][A-Za-z0-9_]*)?)\\\\s*>|var)\\\\s+([A-Za-z_][A-Za-z0-9_]*)';\nconst WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN = '\\\\s*';\n\nexport const MODULE_WGSL_BINDING_DECLARATION_REGEXES = [\n new RegExp(\n `@binding\\\\(\\\\s*(auto|\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n ),\n new RegExp(\n `@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}@binding\\\\(\\\\s*(auto|\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n )\n] as const;\n\nexport const WGSL_BINDING_DECLARATION_REGEXES = [\n new RegExp(\n `@binding\\\\(\\\\s*(auto|\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n ),\n new RegExp(\n `@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}@binding\\\\(\\\\s*(auto|\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n )\n] as const;\n\nexport const WGSL_EXPLICIT_BINDING_DECLARATION_REGEXES = [\n new RegExp(\n `@binding\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n ),\n new RegExp(\n `@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}@binding\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n )\n] as const;\n\nconst WGSL_AUTO_BINDING_DECLARATION_REGEXES = [\n new RegExp(\n `@binding\\\\(\\\\s*(auto)\\\\s*\\\\)\\\\s*@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)\\\\s*${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n ),\n new RegExp(\n `@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)\\\\s*@binding\\\\(\\\\s*(auto)\\\\s*\\\\)\\\\s*${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n ),\n new RegExp(\n `@binding\\\\(\\\\s*(auto)\\\\s*\\\\)\\\\s*@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)(?:[\\\\s\\\\n\\\\r]*@[A-Za-z_][^\\\\n\\\\r]*)*[\\\\s\\\\n\\\\r]*${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n ),\n new RegExp(\n `@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)\\\\s*@binding\\\\(\\\\s*(auto)\\\\s*\\\\)(?:[\\\\s\\\\n\\\\r]*@[A-Za-z_][^\\\\n\\\\r]*)*[\\\\s\\\\n\\\\r]*${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n )\n] as const;\n\nexport type WGSLBindingDeclarationMatch = {\n match: string;\n index: number;\n length: number;\n bindingToken: string;\n groupToken: string;\n accessDeclaration?: string;\n name: string;\n};\n\nexport function maskWGSLComments(source: string): string {\n const maskedCharacters = source.split('');\n let index = 0;\n let blockCommentDepth = 0;\n let inLineComment = false;\n let inString = false;\n let isEscaped = false;\n\n while (index < source.length) {\n const character = source[index];\n const nextCharacter = source[index + 1];\n\n if (inString) {\n if (isEscaped) {\n isEscaped = false;\n } else if (character === '\\\\') {\n isEscaped = true;\n } else if (character === '\"') {\n inString = false;\n }\n index++;\n continue;\n }\n\n if (inLineComment) {\n if (character === '\\n' || character === '\\r') {\n inLineComment = false;\n } else {\n maskedCharacters[index] = ' ';\n }\n index++;\n continue;\n }\n\n if (blockCommentDepth > 0) {\n if (character === '/' && nextCharacter === '*') {\n maskedCharacters[index] = ' ';\n maskedCharacters[index + 1] = ' ';\n blockCommentDepth++;\n index += 2;\n continue;\n }\n\n if (character === '*' && nextCharacter === '/') {\n maskedCharacters[index] = ' ';\n maskedCharacters[index + 1] = ' ';\n blockCommentDepth--;\n index += 2;\n continue;\n }\n\n if (character !== '\\n' && character !== '\\r') {\n maskedCharacters[index] = ' ';\n }\n index++;\n continue;\n }\n\n if (character === '\"') {\n inString = true;\n index++;\n continue;\n }\n\n if (character === '/' && nextCharacter === '/') {\n maskedCharacters[index] = ' ';\n maskedCharacters[index + 1] = ' ';\n inLineComment = true;\n index += 2;\n continue;\n }\n\n if (character === '/' && nextCharacter === '*') {\n maskedCharacters[index] = ' ';\n maskedCharacters[index + 1] = ' ';\n blockCommentDepth = 1;\n index += 2;\n continue;\n }\n\n index++;\n }\n\n return maskedCharacters.join('');\n}\n\nexport function getWGSLBindingDeclarationMatches(\n source: string,\n regexes: readonly RegExp[]\n): WGSLBindingDeclarationMatch[] {\n const maskedSource = maskWGSLComments(source);\n const matches: WGSLBindingDeclarationMatch[] = [];\n\n for (const regex of regexes) {\n regex.lastIndex = 0;\n let match: RegExpExecArray | null;\n match = regex.exec(maskedSource);\n while (match) {\n const isBindingFirst = regex === regexes[0];\n const index = match.index;\n const length = match[0].length;\n matches.push({\n match: source.slice(index, index + length),\n index,\n length,\n bindingToken: match[isBindingFirst ? 1 : 2],\n groupToken: match[isBindingFirst ? 2 : 1],\n accessDeclaration: match[3]?.trim(),\n name: match[4]\n });\n match = regex.exec(maskedSource);\n }\n }\n\n return matches.sort((left, right) => left.index - right.index);\n}\n\nexport function replaceWGSLBindingDeclarationMatches(\n source: string,\n regexes: readonly RegExp[],\n replacer: (match: WGSLBindingDeclarationMatch) => string\n): string {\n const matches = getWGSLBindingDeclarationMatches(source, regexes);\n if (!matches.length) {\n return source;\n }\n\n let relocatedSource = '';\n let lastIndex = 0;\n\n for (const match of matches) {\n relocatedSource += source.slice(lastIndex, match.index);\n relocatedSource += replacer(match);\n lastIndex = match.index + match.length;\n }\n\n relocatedSource += source.slice(lastIndex);\n return relocatedSource;\n}\n\nexport function hasWGSLAutoBinding(source: string): boolean {\n return /@binding\\(\\s*auto\\s*\\)/.test(maskWGSLComments(source));\n}\n\nexport function getFirstWGSLAutoBindingDeclarationMatch(\n source: string,\n regexes: readonly RegExp[]\n): WGSLBindingDeclarationMatch | undefined {\n const autoBindingRegexes =\n regexes === MODULE_WGSL_BINDING_DECLARATION_REGEXES ||\n regexes === WGSL_BINDING_DECLARATION_REGEXES\n ? WGSL_AUTO_BINDING_DECLARATION_REGEXES\n : regexes;\n\n return getWGSLBindingDeclarationMatches(source, autoBindingRegexes).find(\n declarationMatch => declarationMatch.bindingToken === 'auto'\n );\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {WGSL_BINDABLE_VARIABLE_PATTERN, maskWGSLComments} from './wgsl-binding-scan';\n\ntype ShaderBindingAssignment = {\n moduleName: string;\n name: string;\n group: number;\n location: number;\n};\n\nconst WGSL_BINDING_DEBUG_REGEXES = [\n new RegExp(\n `@binding\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)\\\\s*@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)\\\\s*${WGSL_BINDABLE_VARIABLE_PATTERN}\\\\s*:\\\\s*([^;]+);`,\n 'g'\n ),\n new RegExp(\n `@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)\\\\s*@binding\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)\\\\s*${WGSL_BINDABLE_VARIABLE_PATTERN}\\\\s*:\\\\s*([^;]+);`,\n 'g'\n )\n] as const;\n\n/** One debug row describing a WGSL binding in the assembled shader source. */\nexport type ShaderBindingDebugRow = {\n /** Binding name as declared in WGSL. */\n name: string;\n /** Bind-group index. */\n group: number;\n /** Binding slot within the bind group. */\n binding: number;\n /** Resource kind inferred from the WGSL declaration. */\n kind:\n | 'uniform'\n | 'storage'\n | 'read-only-storage'\n | 'texture'\n | 'sampler'\n | 'storage-texture'\n | 'unknown';\n /** Whether the binding came from application WGSL or a shader module. */\n owner: 'application' | 'module';\n /** Shader module name when the binding was contributed by a module. */\n moduleName?: string;\n /** Full WGSL resource type text from the declaration. */\n resourceType?: string;\n /** WGSL access mode when cheaply available. */\n access?: string;\n /** Texture view dimension when cheaply available. */\n viewDimension?: string;\n /** Texture sample type when cheaply available. */\n sampleType?: string;\n /** Sampler kind when cheaply available. */\n samplerKind?: string;\n /** Whether the texture is multisampled when cheaply available. */\n multisampled?: boolean;\n};\n\n/** Builds a stable, table-friendly binding summary from assembled WGSL source. */\nexport function getShaderBindingDebugRowsFromWGSL(\n source: string,\n bindingAssignments: ShaderBindingAssignment[] = []\n): ShaderBindingDebugRow[] {\n const maskedSource = maskWGSLComments(source);\n const assignmentMap = new Map<string, string>();\n for (const bindingAssignment of bindingAssignments) {\n assignmentMap.set(\n getBindingAssignmentKey(\n bindingAssignment.name,\n bindingAssignment.group,\n bindingAssignment.location\n ),\n bindingAssignment.moduleName\n );\n }\n\n const rows: ShaderBindingDebugRow[] = [];\n for (const regex of WGSL_BINDING_DEBUG_REGEXES) {\n regex.lastIndex = 0;\n let match: RegExpExecArray | null;\n match = regex.exec(maskedSource);\n while (match) {\n const isBindingFirst = regex === WGSL_BINDING_DEBUG_REGEXES[0];\n const binding = Number(match[isBindingFirst ? 1 : 2]);\n const group = Number(match[isBindingFirst ? 2 : 1]);\n const accessDeclaration = match[3]?.trim();\n const name = match[4];\n const resourceType = match[5].trim();\n const moduleName = assignmentMap.get(getBindingAssignmentKey(name, group, binding));\n\n rows.push(\n normalizeShaderBindingDebugRow({\n name,\n group,\n binding,\n owner: moduleName ? 'module' : 'application',\n moduleName,\n accessDeclaration,\n resourceType\n })\n );\n match = regex.exec(maskedSource);\n }\n }\n\n return rows.sort((left, right) => {\n if (left.group !== right.group) {\n return left.group - right.group;\n }\n if (left.binding !== right.binding) {\n return left.binding - right.binding;\n }\n return left.name.localeCompare(right.name);\n });\n}\n\nfunction normalizeShaderBindingDebugRow(row: {\n name: string;\n group: number;\n binding: number;\n owner: 'application' | 'module';\n moduleName?: string;\n accessDeclaration?: string;\n resourceType: string;\n}): ShaderBindingDebugRow {\n const baseRow: ShaderBindingDebugRow = {\n name: row.name,\n group: row.group,\n binding: row.binding,\n owner: row.owner,\n kind: 'unknown',\n moduleName: row.moduleName,\n resourceType: row.resourceType\n };\n\n if (row.accessDeclaration) {\n const access = row.accessDeclaration.split(',').map(value => value.trim());\n if (access[0] === 'uniform') {\n return {...baseRow, kind: 'uniform', access: 'uniform'};\n }\n if (access[0] === 'storage') {\n const storageAccess = access[1] || 'read_write';\n return {\n ...baseRow,\n kind: storageAccess === 'read' ? 'read-only-storage' : 'storage',\n access: storageAccess\n };\n }\n }\n\n if (row.resourceType === 'sampler' || row.resourceType === 'sampler_comparison') {\n return {\n ...baseRow,\n kind: 'sampler',\n samplerKind: row.resourceType === 'sampler_comparison' ? 'comparison' : 'filtering'\n };\n }\n\n if (row.resourceType.startsWith('texture_storage_')) {\n return {\n ...baseRow,\n kind: 'storage-texture',\n access: getStorageTextureAccess(row.resourceType),\n viewDimension: getTextureViewDimension(row.resourceType)\n };\n }\n\n if (row.resourceType.startsWith('texture_')) {\n return {\n ...baseRow,\n kind: 'texture',\n viewDimension: getTextureViewDimension(row.resourceType),\n sampleType: getTextureSampleType(row.resourceType),\n multisampled: row.resourceType.startsWith('texture_multisampled_')\n };\n }\n\n return baseRow;\n}\n\nfunction getBindingAssignmentKey(name: string, group: number, binding: number): string {\n return `${group}:${binding}:${name}`;\n}\n\nfunction getTextureViewDimension(resourceType: string): string | undefined {\n if (resourceType.includes('cube_array')) {\n return 'cube-array';\n }\n if (resourceType.includes('2d_array')) {\n return '2d-array';\n }\n if (resourceType.includes('cube')) {\n return 'cube';\n }\n if (resourceType.includes('3d')) {\n return '3d';\n }\n if (resourceType.includes('2d')) {\n return '2d';\n }\n if (resourceType.includes('1d')) {\n return '1d';\n }\n return undefined;\n}\n\nfunction getTextureSampleType(resourceType: string): string | undefined {\n if (resourceType.startsWith('texture_depth_')) {\n return 'depth';\n }\n if (resourceType.includes('<i32>')) {\n return 'sint';\n }\n if (resourceType.includes('<u32>')) {\n return 'uint';\n }\n if (resourceType.includes('<f32>')) {\n return 'float';\n }\n return undefined;\n}\n\nfunction getStorageTextureAccess(resourceType: string): string | undefined {\n const match = /,\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*>$/.exec(resourceType);\n return match?.[1];\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {getShaderModuleDependencies} from '../shader-module/shader-module-dependencies';\nimport {PlatformInfo} from './platform-info';\nimport {getPlatformShaderDefines} from './platform-defines';\nimport {injectShader, DECLARATION_INJECT_MARKER} from './shader-injections';\nimport {transpileGLSLShader} from '../shader-transpiler/transpile-glsl-shader';\nimport {checkShaderModuleDeprecations} from '../shader-module/shader-module';\nimport {\n validateShaderModuleUniformLayout,\n warnIfGLSLUniformBlocksAreNotStd140\n} from '../shader-module/shader-module-uniform-layout';\nimport type {ShaderInjection} from './shader-injections';\nimport type {ShaderModule} from '../shader-module/shader-module';\nimport {ShaderHook, normalizeShaderHooks, getShaderHooks} from './shader-hooks';\nimport {assert} from '../utils/assert';\nimport {getShaderInfo} from '../glsl-utils/get-shader-info';\nimport {getShaderBindingDebugRowsFromWGSL, type ShaderBindingDebugRow} from './wgsl-binding-debug';\nimport {\n MODULE_WGSL_BINDING_DECLARATION_REGEXES,\n WGSL_BINDING_DECLARATION_REGEXES,\n WGSL_EXPLICIT_BINDING_DECLARATION_REGEXES,\n getFirstWGSLAutoBindingDeclarationMatch,\n getWGSLBindingDeclarationMatches,\n hasWGSLAutoBinding,\n replaceWGSLBindingDeclarationMatches,\n type WGSLBindingDeclarationMatch\n} from './wgsl-binding-scan';\n\nconst INJECT_SHADER_DECLARATIONS = `\\n\\n${DECLARATION_INJECT_MARKER}\\n`;\nconst RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT = 100;\n\n/**\n * Precision prologue to inject before functions are injected in shader\n * TODO - extract any existing prologue in the fragment source and move it up...\n */\nconst FRAGMENT_SHADER_PROLOGUE = /* glsl */ `\\\nprecision highp float;\n`;\n\n/**\n * Options for `ShaderAssembler.assembleShaders()`\n */\nexport type AssembleShaderProps = AssembleShaderOptions & {\n platformInfo: PlatformInfo;\n /** WGSL: single shader source. */\n source?: string | null;\n /** GLSL vertex shader source. */\n vs?: string | null;\n /** GLSL fragment shader source. */\n fs?: string | null;\n};\n\nexport type AssembleShaderOptions = {\n /** information about the platform (which shader language & version, extensions etc.) */\n platformInfo: PlatformInfo;\n /** Inject shader id #defines */\n id?: string;\n /** Modules to be injected */\n modules?: ShaderModule[];\n /** Defines to be injected */\n defines?: Record<string, boolean>;\n /** GLSL only: Overrides to be injected. In WGSL these are supplied during Pipeline creation time */\n constants?: Record<string, number>;\n /** Hook functions */\n hookFunctions?: (ShaderHook | string)[];\n /** Code injections */\n inject?: Record<string, string | ShaderInjection>;\n /** Whether to inject prologue */\n prologue?: boolean;\n /** logger object */\n log?: any;\n};\n\ntype AssembleStageOptions = {\n /** Inject shader id #defines */\n id?: string;\n /** Vertex shader */\n source: string;\n stage: 'vertex' | 'fragment';\n /** Modules to be injected */\n modules: any[];\n /** Defines to be injected */\n defines?: Record<string, boolean>;\n /** GLSL only: Overrides to be injected. In WGSL these are supplied during Pipeline creation time */\n constants?: Record<string, number>;\n /** Hook functions */\n hookFunctions?: (ShaderHook | string)[];\n /** Code injections */\n inject?: Record<string, string | ShaderInjection>;\n /** Whether to inject prologue */\n prologue?: boolean;\n /** logger object */\n log?: any;\n /** @internal Stable per-assembler WGSL binding assignments. */\n _bindingRegistry?: Map<string, number>;\n};\n\nexport type HookFunction = {hook: string; header: string; footer: string; signature?: string};\n\n/**\n * getUniforms function returned from the shader module system\n */\nexport type GetUniformsFunc = (opts: Record<string, any>) => Record<string, any>;\n\n/**\n * Inject a list of shader modules into a single shader source for WGSL\n */\nexport function assembleWGSLShader(\n options: AssembleShaderOptions & {\n /** Single WGSL shader */\n source: string;\n /** @internal Stable per-assembler WGSL binding assignments. */\n _bindingRegistry?: Map<string, number>;\n }\n): {\n source: string;\n getUniforms: GetUniformsFunc;\n bindingAssignments: {moduleName: string; name: string; group: number; location: number}[];\n bindingTable: ShaderBindingDebugRow[];\n} {\n const modules = getShaderModuleDependencies(options.modules || []);\n const {source, bindingAssignments} = assembleShaderWGSL(options.platformInfo, {\n ...options,\n source: options.source,\n stage: 'vertex',\n modules\n });\n\n return {\n source,\n getUniforms: assembleGetUniforms(modules),\n bindingAssignments,\n bindingTable: getShaderBindingDebugRowsFromWGSL(source, bindingAssignments)\n };\n}\n\n/**\n * Injects dependent shader module sources into pair of main vertex/fragment shader sources for GLSL\n */\nexport function assembleGLSLShaderPair(\n options: AssembleShaderOptions & {\n /** Vertex shader */\n vs: string;\n /** Fragment shader */\n fs?: string;\n }\n): {\n vs: string;\n fs: string;\n getUniforms: GetUniformsFunc;\n} {\n const {vs, fs} = options;\n const modules = getShaderModuleDependencies(options.modules || []);\n\n return {\n vs: assembleShaderGLSL(options.platformInfo, {\n ...options,\n source: vs,\n stage: 'vertex',\n modules\n }),\n fs: assembleShaderGLSL(options.platformInfo, {\n ...options,\n // @ts-expect-error\n source: fs,\n stage: 'fragment',\n modules\n }),\n getUniforms: assembleGetUniforms(modules)\n };\n}\n\n/**\n * Pulls together complete source code for either a vertex or a fragment shader\n * adding prologues, requested module chunks, and any final injections.\n * @param gl\n * @param options\n * @returns\n */\nexport function assembleShaderWGSL(\n platformInfo: PlatformInfo,\n options: AssembleStageOptions\n): {source: string; bindingAssignments: WGSLBindingAssignment[]} {\n const {\n // id,\n source,\n stage,\n modules,\n // defines = {},\n hookFunctions = [],\n inject = {},\n log\n } = options;\n\n assert(typeof source === 'string', 'shader source must be a string');\n\n // const isVertex = type === 'vs';\n // const sourceLines = source.split('\\n');\n\n const coreSource = source;\n\n // Combine Module and Application Defines\n // const allDefines = {};\n // modules.forEach(module => {\n // Object.assign(allDefines, module.getDefines());\n // });\n // Object.assign(allDefines, defines);\n\n // Add platform defines (use these to work around platform-specific bugs and limitations)\n // Add common defines (GLSL version compatibility, feature detection)\n // Add precision declaration for fragment shaders\n let assembledSource = '';\n // prologue\n // ? `\\\n // ${getShaderNameDefine({id, source, type})}\n // ${getShaderType(type)}\n // ${getPlatformShaderDefines(platformInfo)}\n // ${getApplicationDefines(allDefines)}\n // ${isVertex ? '' : FRAGMENT_SHADER_PROLOGUE}\n // `\n // `;\n\n const hookFunctionMap = normalizeShaderHooks(hookFunctions);\n\n // Add source of dependent modules in resolved order\n const hookInjections: Record<string, ShaderInjection[]> = {};\n const declInjections: Record<string, ShaderInjection[]> = {};\n const mainInjections: Record<string, ShaderInjection[]> = {};\n\n for (const key in inject) {\n const injection =\n typeof inject[key] === 'string' ? {injection: inject[key], order: 0} : inject[key];\n const match = /^(v|f)s:(#)?([\\w-]+)$/.exec(key);\n if (match) {\n const hash = match[2];\n const name = match[3];\n if (hash) {\n if (name === 'decl') {\n declInjections[key] = [injection as any];\n } else {\n mainInjections[key] = [injection as any];\n }\n } else {\n hookInjections[key] = [injection as any];\n }\n } else {\n // Regex injection\n mainInjections[key] = [injection as any];\n }\n }\n\n // TODO - hack until shadertool modules support WebGPU\n const modulesToInject = modules;\n const applicationRelocation = relocateWGSLApplicationBindings(coreSource);\n const usedBindingsByGroup = getUsedBindingsByGroupFromApplicationWGSL(\n applicationRelocation.source\n );\n const reservedBindingKeysByGroup = reserveRegisteredModuleBindings(\n modulesToInject,\n options._bindingRegistry,\n usedBindingsByGroup\n );\n const bindingAssignments: WGSLBindingAssignment[] = [];\n\n for (const module of modulesToInject) {\n if (log) {\n checkShaderModuleDeprecations(module, coreSource, log);\n }\n const relocation = relocateWGSLModuleBindings(\n getShaderModuleSource(module, 'wgsl', log),\n module,\n {\n usedBindingsByGroup,\n bindingRegistry: options._bindingRegistry,\n reservedBindingKeysByGroup\n }\n );\n bindingAssignments.push(...relocation.bindingAssignments);\n const moduleSource = relocation.source;\n // Add the module source, and a #define that declares it presence\n assembledSource += moduleSource;\n\n const injections = module.injections?.[stage] || {};\n for (const key in injections) {\n const match = /^(v|f)s:#([\\w-]+)$/.exec(key);\n if (match) {\n const name = match[2];\n const injectionType = name === 'decl' ? declInjections : mainInjections;\n injectionType[key] = injectionType[key] || [];\n injectionType[key].push(injections[key]);\n } else {\n hookInjections[key] = hookInjections[key] || [];\n hookInjections[key].push(injections[key]);\n }\n }\n }\n\n // For injectShader\n assembledSource += INJECT_SHADER_DECLARATIONS;\n\n assembledSource = injectShader(assembledSource, stage, declInjections);\n\n assembledSource += getShaderHooks(hookFunctionMap[stage], hookInjections);\n assembledSource += formatWGSLBindingAssignmentComments(bindingAssignments);\n\n // Add the version directive and actual source of this shader\n assembledSource += applicationRelocation.source;\n\n // Apply any requested shader injections\n assembledSource = injectShader(assembledSource, stage, mainInjections);\n\n assertNoUnresolvedAutoBindings(assembledSource);\n\n return {source: assembledSource, bindingAssignments};\n}\n\n/**\n * Pulls together complete source code for either a vertex or a fragment shader\n * adding prologues, requested module chunks, and any final injections.\n * @param gl\n * @param options\n * @returns\n */\nfunction assembleShaderGLSL(\n platformInfo: PlatformInfo,\n options: {\n id?: string;\n source: string;\n language?: 'glsl' | 'wgsl';\n stage: 'vertex' | 'fragment';\n modules: ShaderModule[];\n defines?: Record<string, boolean>;\n hookFunctions?: any[];\n inject?: Record<string, string | ShaderInjection>;\n prologue?: boolean;\n log?: any;\n }\n) {\n const {\n source,\n stage,\n language = 'glsl',\n modules,\n defines = {},\n hookFunctions = [],\n inject = {},\n prologue = true,\n log\n } = options;\n\n assert(typeof source === 'string', 'shader source must be a string');\n\n const sourceVersion = language === 'glsl' ? getShaderInfo(source).version : -1;\n const targetVersion = platformInfo.shaderLanguageVersion;\n\n const sourceVersionDirective = sourceVersion === 100 ? '#version 100' : '#version 300 es';\n\n const sourceLines = source.split('\\n');\n // TODO : keep all pre-processor statements at the beginning of the shader.\n const coreSource = sourceLines.slice(1).join('\\n');\n\n // Combine Module and Application Defines\n const allDefines = {};\n modules.forEach(module => {\n Object.assign(allDefines, module.defines);\n });\n Object.assign(allDefines, defines);\n\n // Add platform defines (use these to work around platform-specific bugs and limitations)\n // Add common defines (GLSL version compatibility, feature detection)\n // Add precision declaration for fragment shaders\n let assembledSource = '';\n switch (language) {\n case 'wgsl':\n break;\n case 'glsl':\n assembledSource = prologue\n ? `\\\n${sourceVersionDirective}\n\n// ----- PROLOGUE -------------------------\n${`#define SHADER_TYPE_${stage.toUpperCase()}`}\n\n${getPlatformShaderDefines(platformInfo)}\n${stage === 'fragment' ? FRAGMENT_SHADER_PROLOGUE : ''}\n\n// ----- APPLICATION DEFINES -------------------------\n\n${getApplicationDefines(allDefines)}\n\n`\n : `${sourceVersionDirective}\n`;\n break;\n }\n\n const hookFunctionMap = normalizeShaderHooks(hookFunctions);\n\n // Add source of dependent modules in resolved order\n const hookInjections: Record<string, ShaderInjection[]> = {};\n const declInjections: Record<string, ShaderInjection[]> = {};\n const mainInjections: Record<string, ShaderInjection[]> = {};\n\n for (const key in inject) {\n const injection: ShaderInjection =\n typeof inject[key] === 'string' ? {injection: inject[key], order: 0} : inject[key];\n const match = /^(v|f)s:(#)?([\\w-]+)$/.exec(key);\n if (match) {\n const hash = match[2];\n const name = match[3];\n if (hash) {\n if (name === 'decl') {\n declInjections[key] = [injection];\n } else {\n mainInjections[key] = [injection];\n }\n } else {\n hookInjections[key] = [injection];\n }\n } else {\n // Regex injection\n mainInjections[key] = [injection];\n }\n }\n\n for (const module of modules) {\n if (log) {\n checkShaderModuleDeprecations(module, coreSource, log);\n }\n const moduleSource = getShaderModuleSource(module, stage, log);\n // Add the module source, and a #define that declares it presence\n assembledSource += moduleSource;\n\n const injections = module.instance?.normalizedInjections[stage] || {};\n for (const key in injections) {\n const match = /^(v|f)s:#([\\w-]+)$/.exec(key);\n if (match) {\n const name = match[2];\n const injectionType = name === 'decl' ? declInjections : mainInjections;\n injectionType[key] = injectionType[key] || [];\n injectionType[key].push(injections[key]);\n } else {\n hookInjections[key] = hookInjections[key] || [];\n hookInjections[key].push(injections[key]);\n }\n }\n }\n\n assembledSource += '// ----- MAIN SHADER SOURCE -------------------------';\n\n // For injectShader\n assembledSource += INJECT_SHADER_DECLARATIONS;\n\n assembledSource = injectShader(assembledSource, stage, declInjections);\n\n assembledSource += getShaderHooks(hookFunctionMap[stage], hookInjections);\n\n // Add the version directive and actual source of this shader\n assembledSource += coreSource;\n\n // Apply any requested shader injections\n assembledSource = injectShader(assembledSource, stage, mainInjections);\n\n if (language === 'glsl' && sourceVersion !== targetVersion) {\n assembledSource = transpileGLSLShader(assembledSource, stage);\n }\n\n if (language === 'glsl') {\n warnIfGLSLUniformBlocksAreNotStd140(assembledSource, stage, log);\n }\n\n return assembledSource.trim();\n}\n\n/**\n * Returns a combined `getUniforms` covering the options for all the modules,\n * the created function will pass on options to the inidividual `getUniforms`\n * function of each shader module and combine the results into one object that\n * can be passed to setUniforms.\n * @param modules\n * @returns\n */\nexport function assembleGetUniforms(modules: ShaderModule[]) {\n return function getUniforms(opts: Record<string, any>): Record<string, any> {\n const uniforms = {};\n for (const module of modules) {\n // `modules` is already sorted by dependency level. This guarantees that\n // modules have access to the uniforms that are generated by their dependencies.\n const moduleUniforms = module.getUniforms?.(opts, uniforms);\n Object.assign(uniforms, moduleUniforms);\n }\n return uniforms;\n };\n}\n\n/**\n * NOTE: Removed as id injection defeated caching of shaders\n * \n * Generate \"glslify-compatible\" SHADER_NAME defines\n * These are understood by the GLSL error parsing function\n * If id is provided and no SHADER_NAME constant is present in source, create one\n unction getShaderNameDefine(options: {\n id?: string;\n source: string;\n stage: 'vertex' | 'fragment';\n}): string {\n const {id, source, stage} = options;\n const injectShaderName = id && source.indexOf('SHADER_NAME') === -1;\n return injectShaderName\n ? `\n#define SHADER_NAME ${id}_${stage}`\n : '';\n}\n*/\n\n/** Generates application defines from an object of key value pairs */\nfunction getApplicationDefines(defines: Record<string, boolean> = {}): string {\n let sourceText = '';\n for (const define in defines) {\n const value = defines[define];\n if (value || Number.isFinite(value)) {\n sourceText += `#define ${define.toUpperCase()} ${defines[define]}\\n`;\n }\n }\n return sourceText;\n}\n\n/** Extracts the source code chunk for the specified shader type from the named shader module */\nexport function getShaderModuleSource(\n module: ShaderModule,\n stage: 'vertex' | 'fragment' | 'wgsl',\n log?: any\n): string {\n let moduleSource;\n switch (stage) {\n case 'vertex':\n moduleSource = module.vs || '';\n break;\n case 'fragment':\n moduleSource = module.fs || '';\n break;\n case 'wgsl':\n moduleSource = module.source || '';\n break;\n default:\n assert(false);\n }\n\n if (!module.name) {\n throw new Error('Shader module must have a name');\n }\n\n validateShaderModuleUniformLayout(module, stage, {log});\n\n const moduleName = module.name.toUpperCase().replace(/[^0-9a-z]/gi, '_');\n let source = `\\\n// ----- MODULE ${module.name} ---------------\n\n`;\n if (stage !== 'wgsl') {\n source += `#define MODULE_${moduleName}\\n`;\n }\n source += `${moduleSource}\\n`;\n return source;\n}\n\ntype BindingRelocationContext = {\n usedBindingsByGroup: Map<number, Set<number>>;\n bindingRegistry?: Map<string, number>;\n reservedBindingKeysByGroup: Map<number, Map<number, string>>;\n};\n\ntype WGSLBindingAssignment = {\n moduleName: string;\n name: string;\n group: number;\n location: number;\n};\n\ntype WGSLApplicationRelocationState = {\n sawSupportedBindingDeclaration: boolean;\n};\n\ntype WGSLRelocationState = {\n sawSupportedBindingDeclaration: boolean;\n nextHintedBindingLocation: number | null;\n};\n\ntype WGSLRelocationParams = {\n module: ShaderModule;\n context: BindingRelocationContext;\n bindingAssignments: WGSLBindingAssignment[];\n relocationState: WGSLRelocationState;\n};\n\nfunction getUsedBindingsByGroupFromApplicationWGSL(source: string): Map<number, Set<number>> {\n const usedBindingsByGroup = new Map<number, Set<number>>();\n\n for (const match of getWGSLBindingDeclarationMatches(\n source,\n WGSL_EXPLICIT_BINDING_DECLARATION_REGEXES\n )) {\n const location = Number(match.bindingToken);\n const group = Number(match.groupToken);\n\n validateApplicationWGSLBinding(group, location, match.name);\n registerUsedBindingLocation(\n usedBindingsByGroup,\n group,\n location,\n `application binding \"${match.name}\"`\n );\n }\n\n return usedBindingsByGroup;\n}\n\nfunction relocateWGSLApplicationBindings(source: string): {source: string} {\n const declarationMatches = getWGSLBindingDeclarationMatches(\n source,\n WGSL_BINDING_DECLARATION_REGEXES\n );\n const usedBindingsByGroup = new Map<number, Set<number>>();\n\n for (const declarationMatch of declarationMatches) {\n if (declarationMatch.bindingToken === 'auto') {\n continue;\n }\n\n const location = Number(declarationMatch.bindingToken);\n const group = Number(declarationMatch.groupToken);\n\n validateApplicationWGSLBinding(group, location, declarationMatch.name);\n registerUsedBindingLocation(\n usedBindingsByGroup,\n group,\n location,\n `application binding \"${declarationMatch.name}\"`\n );\n }\n\n const relocationState: WGSLApplicationRelocationState = {\n sawSupportedBindingDeclaration: declarationMatches.length > 0\n };\n\n const relocatedSource = replaceWGSLBindingDeclarationMatches(\n source,\n WGSL_BINDING_DECLARATION_REGEXES,\n declarationMatch =>\n relocateWGSLApplicationBindingMatch(declarationMatch, usedBindingsByGroup, relocationState)\n );\n\n if (hasWGSLAutoBinding(source) && !relocationState.sawSupportedBindingDeclaration) {\n throw new Error(\n 'Unsupported @binding(auto) declaration form in application WGSL. ' +\n 'Use adjacent \"@group(N)\" and \"@binding(auto)\" decorators followed by a bindable \"var\" declaration.'\n );\n }\n\n return {source: relocatedSource};\n}\n\nfunction relocateWGSLModuleBindings(\n moduleSource: string,\n module: ShaderModule,\n context: BindingRelocationContext\n): {source: string; bindingAssignments: WGSLBindingAssignment[]} {\n const bindingAssignments: WGSLBindingAssignment[] = [];\n const declarationMatches = getWGSLBindingDeclarationMatches(\n moduleSource,\n MODULE_WGSL_BINDING_DECLARATION_REGEXES\n );\n const relocationState: WGSLRelocationState = {\n sawSupportedBindingDeclaration: declarationMatches.length > 0,\n nextHintedBindingLocation:\n typeof module.firstBindingSlot === 'number' ? module.firstBindingSlot : null\n };\n\n const relocatedSource = replaceWGSLBindingDeclarationMatches(\n moduleSource,\n MODULE_WGSL_BINDING_DECLARATION_REGEXES,\n declarationMatch =>\n relocateWGSLModuleBindingMatch(declarationMatch, {\n module,\n context,\n bindingAssignments,\n relocationState\n })\n );\n\n if (hasWGSLAutoBinding(moduleSource) && !relocationState.sawSupportedBindingDeclaration) {\n throw new Error(\n `Unsupported @binding(auto) declaration form in module \"${module.name}\". ` +\n 'Use adjacent \"@group(N)\" and \"@binding(auto)\" decorators followed by a bindable \"var\" declaration.'\n );\n }\n\n return {source: relocatedSource, bindingAssignments};\n}\n\nfunction relocateWGSLModuleBindingMatch(\n declarationMatch: WGSLBindingDeclarationMatch,\n params: WGSLRelocationParams\n): string {\n const {module, context, bindingAssignments, relocationState} = params;\n\n const {match, bindingToken, groupToken, name} = declarationMatch;\n const group = Number(groupToken);\n\n if (bindingToken === 'auto') {\n const registryKey = getBindingRegistryKey(group, module.name, name);\n const registryLocation = context.bindingRegistry?.get(registryKey);\n const location =\n registryLocation !== undefined\n ? registryLocation\n : relocationState.nextHintedBindingLocation === null\n ? allocateAutoBindingLocation(group, context.usedBindingsByGroup)\n : allocateAutoBindingLocation(\n group,\n context.usedBindingsByGroup,\n relocationState.nextHintedBindingLocation\n );\n validateModuleWGSLBinding(module.name, group, location, name);\n if (\n registryLocation !== undefined &&\n claimReservedBindingLocation(context.reservedBindingKeysByGroup, group, location, registryKey)\n ) {\n bindingAssignments.push({moduleName: module.name, name, group, location});\n return match.replace(/@binding\\(\\s*auto\\s*\\)/, `@binding(${location})`);\n }\n registerUsedBindingLocation(\n context.usedBindingsByGroup,\n group,\n location,\n `module \"${module.name}\" binding \"${name}\"`\n );\n context.bindingRegistry?.set(registryKey, location);\n bindingAssignments.push({moduleName: module.name, name, group, location});\n if (relocationState.nextHintedBindingLocation !== null && registryLocation === undefined) {\n relocationState.nextHintedBindingLocation = location + 1;\n }\n return match.replace(/@binding\\(\\s*auto\\s*\\)/, `@binding(${location})`);\n }\n\n const location = Number(bindingToken);\n validateModuleWGSLBinding(module.name, group, location, name);\n registerUsedBindingLocation(\n context.usedBindingsByGroup,\n group,\n location,\n `module \"${module.name}\" binding \"${name}\"`\n );\n bindingAssignments.push({moduleName: module.name, name, group, location});\n return match;\n}\n\nfunction relocateWGSLApplicationBindingMatch(\n declarationMatch: WGSLBindingDeclarationMatch,\n usedBindingsByGroup: Map<number, Set<number>>,\n relocationState: WGSLApplicationRelocationState\n): string {\n const {match, bindingToken, groupToken, name} = declarationMatch;\n const group = Number(groupToken);\n\n if (bindingToken === 'auto') {\n const location = allocateApplicationAutoBindingLocation(group, usedBindingsByGroup);\n validateApplicationWGSLBinding(group, location, name);\n registerUsedBindingLocation(\n usedBindingsByGroup,\n group,\n location,\n `application binding \"${name}\"`\n );\n return match.replace(/@binding\\(\\s*auto\\s*\\)/, `@binding(${location})`);\n }\n\n relocationState.sawSupportedBindingDeclaration = true;\n return match;\n}\n\nfunction reserveRegisteredModuleBindings(\n modules: ShaderModule[],\n bindingRegistry: Map<string, number> | undefined,\n usedBindingsByGroup: Map<number, Set<number>>\n): Map<number, Map<number, string>> {\n const reservedBindingKeysByGroup = new Map<number, Map<number, string>>();\n if (!bindingRegistry) {\n return reservedBindingKeysByGroup;\n }\n\n for (const module of modules) {\n for (const binding of getModuleWGSLBindingDeclarations(module)) {\n const registryKey = getBindingRegistryKey(binding.group, module.name, binding.name);\n const location = bindingRegistry.get(registryKey);\n if (location !== undefined) {\n const reservedBindingKeys =\n reservedBindingKeysByGroup.get(binding.group) || new Map<number, string>();\n const existingReservation = reservedBindingKeys.get(location);\n if (existingReservation && existingReservation !== registryKey) {\n throw new Error(\n `Duplicate WGSL binding reservation for modules \"${existingReservation}\" and \"${registryKey}\": group ${binding.group}, binding ${location}.`\n );\n }\n\n registerUsedBindingLocation(\n usedBindingsByGroup,\n binding.group,\n location,\n `registered module binding \"${registryKey}\"`\n );\n reservedBindingKeys.set(location, registryKey);\n reservedBindingKeysByGroup.set(binding.group, reservedBindingKeys);\n }\n }\n }\n\n return reservedBindingKeysByGroup;\n}\n\nfunction claimReservedBindingLocation(\n reservedBindingKeysByGroup: Map<number, Map<number, string>>,\n group: number,\n location: number,\n registryKey: string\n): boolean {\n const reservedBindingKeys = reservedBindingKeysByGroup.get(group);\n if (!reservedBindingKeys) {\n return false;\n }\n\n const reservedKey = reservedBindingKeys.get(location);\n if (!reservedKey) {\n return false;\n }\n if (reservedKey !== registryKey) {\n throw new Error(\n `Registered module binding \"${registryKey}\" collided with \"${reservedKey}\": group ${group}, binding ${location}.`\n );\n }\n return true;\n}\n\nfunction getModuleWGSLBindingDeclarations(module: ShaderModule): {name: string; group: number}[] {\n const declarations: {name: string; group: number}[] = [];\n const moduleSource = module.source || '';\n\n for (const match of getWGSLBindingDeclarationMatches(\n moduleSource,\n MODULE_WGSL_BINDING_DECLARATION_REGEXES\n )) {\n declarations.push({\n name: match.name,\n group: Number(match.groupToken)\n });\n }\n\n return declarations;\n}\n\nfunction validateApplicationWGSLBinding(group: number, location: number, name: string): void {\n if (group === 0 && location >= RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT) {\n throw new Error(\n `Application binding \"${name}\" in group 0 uses reserved binding ${location}. ` +\n `Application-owned explicit group-0 bindings must stay below ${RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT}.`\n );\n }\n}\n\nfunction validateModuleWGSLBinding(\n moduleName: string,\n group: number,\n location: number,\n name: string\n): void {\n if (group === 0 && location < RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT) {\n throw new Error(\n `Module \"${moduleName}\" binding \"${name}\" in group 0 uses reserved application binding ${location}. ` +\n `Module-owned explicit group-0 bindings must be ${RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT} or higher.`\n );\n }\n}\n\nfunction registerUsedBindingLocation(\n usedBindingsByGroup: Map<number, Set<number>>,\n group: number,\n location: number,\n label: string\n): void {\n const usedBindings = usedBindingsByGroup.get(group) || new Set<number>();\n if (usedBindings.has(location)) {\n throw new Error(\n `Duplicate WGSL binding assignment for ${label}: group ${group}, binding ${location}.`\n );\n }\n usedBindings.add(location);\n usedBindingsByGroup.set(group, usedBindings);\n}\n\nfunction allocateAutoBindingLocation(\n group: number,\n usedBindingsByGroup: Map<number, Set<number>>,\n preferredBindingLocation?: number\n): number {\n const usedBindings = usedBindingsByGroup.get(group) || new Set<number>();\n let nextBinding =\n preferredBindingLocation ??\n (group === 0\n ? RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT\n : usedBindings.size > 0\n ? Math.max(...usedBindings) + 1\n : 0);\n\n while (usedBindings.has(nextBinding)) {\n nextBinding++;\n }\n\n return nextBinding;\n}\n\nfunction allocateApplicationAutoBindingLocation(\n group: number,\n usedBindingsByGroup: Map<number, Set<number>>\n): number {\n const usedBindings = usedBindingsByGroup.get(group) || new Set<number>();\n let nextBinding = 0;\n\n while (usedBindings.has(nextBinding)) {\n nextBinding++;\n }\n\n return nextBinding;\n}\n\nfunction assertNoUnresolvedAutoBindings(source: string): void {\n const unresolvedBinding = getFirstWGSLAutoBindingDeclarationMatch(\n source,\n MODULE_WGSL_BINDING_DECLARATION_REGEXES\n );\n if (!unresolvedBinding) {\n return;\n }\n\n const moduleName = getWGSLModuleNameAtIndex(source, unresolvedBinding.index);\n if (moduleName) {\n throw new Error(\n `Unresolved @binding(auto) for module \"${moduleName}\" binding \"${unresolvedBinding.name}\" remained in assembled WGSL source.`\n );\n }\n\n if (isInApplicationWGSLSection(source, unresolvedBinding.index)) {\n throw new Error(\n `Unresolved @binding(auto) for application binding \"${unresolvedBinding.name}\" remained in assembled WGSL source.`\n );\n }\n\n throw new Error(\n `Unresolved @binding(auto) remained in assembled WGSL source near \"${formatWGSLSourceSnippet(unresolvedBinding.match)}\".`\n );\n}\n\nfunction formatWGSLBindingAssignmentComments(bindingAssignments: WGSLBindingAssignment[]): string {\n if (bindingAssignments.length === 0) {\n return '';\n }\n\n let source = '// ----- MODULE WGSL BINDING ASSIGNMENTS ---------------\\n';\n for (const bindingAssignment of bindingAssignments) {\n source += `// ${bindingAssignment.moduleName}.${bindingAssignment.name} -> @group(${bindingAssignment.group}) @binding(${bindingAssignment.location})\\n`;\n }\n source += '\\n';\n return source;\n}\n\nfunction getBindingRegistryKey(group: number, moduleName: string, bindingName: string): string {\n return `${group}:${moduleName}:${bindingName}`;\n}\n\nfunction getWGSLModuleNameAtIndex(source: string, index: number): string | undefined {\n const moduleHeaderRegex = /^\\/\\/ ----- MODULE ([^\\n]+) ---------------$/gm;\n let moduleName: string | undefined;\n let match: RegExpExecArray | null;\n\n match = moduleHeaderRegex.exec(source);\n while (match && match.index <= index) {\n moduleName = match[1];\n match = moduleHeaderRegex.exec(source);\n }\n\n return moduleName;\n}\n\nfunction isInApplicationWGSLSection(source: string, index: number): boolean {\n const injectionMarkerIndex = source.indexOf(INJECT_SHADER_DECLARATIONS);\n return injectionMarkerIndex >= 0 ? index > injectionMarkerIndex : true;\n}\n\nfunction formatWGSLSourceSnippet(source: string): string {\n return source.replace(/\\s+/g, ' ').trim();\n}\n\n/*\nfunction getHookFunctions(\n hookFunctions: Record<string, HookFunction>,\n hookInjections: Record<string, Injection[]>\n): string {\n let result = '';\n for (const hookName in hookFunctions) {\n const hookFunction = hookFunctions[hookName];\n result += `void ${hookFunction.signature} {\\n`;\n if (hookFunction.header) {\n result += ` ${hookFunction.header}`;\n }\n if (hookInjections[hookName]) {\n const injections = hookInjections[hookName];\n injections.sort((a: {order: number}, b: {order: number}): number => a.order - b.order);\n for (const injection of injections) {\n result += ` ${injection.injection}\\n`;\n }\n }\n if (hookFunction.footer) {\n result += ` ${hookFunction.footer}`;\n }\n result += '}\\n';\n }\n\n return result;\n}\n\nfunction normalizeHookFunctions(hookFunctions: (string | HookFunction)[]): {\n vs: Record<string, HookFunction>;\n fs: Record<string, HookFunction>;\n} {\n const result: {vs: Record<string, any>; fs: Record<string, any>} = {\n vs: {},\n fs: {}\n };\n\n hookFunctions.forEach((hookFunction: string | HookFunction) => {\n let opts: HookFunction;\n let hook: string;\n if (typeof hookFunction !== 'string') {\n opts = hookFunction;\n hook = opts.hook;\n } else {\n opts = {} as HookFunction;\n hook = hookFunction;\n }\n hook = hook.trim();\n const [stage, signature] = hook.split(':');\n const name = hook.replace(/\\(.+/, '');\n if (stage !== 'vs' && stage !== 'fs') {\n throw new Error(stage);\n }\n result[stage][name] = Object.assign(opts, {signature});\n });\n\n return result;\n}\n*/\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nconst DEFINE_NAME_PATTERN = '([a-zA-Z_][a-zA-Z0-9_]*)';\nconst IFDEF_REGEXP = new RegExp(`^\\\\s*\\\\#\\\\s*ifdef\\\\s*${DEFINE_NAME_PATTERN}\\\\s*$`);\nconst IFNDEF_REGEXP = new RegExp(`^\\\\s*\\\\#\\\\s*ifndef\\\\s*${DEFINE_NAME_PATTERN}\\\\s*(?:\\\\/\\\\/.*)?$`);\nconst ELSE_REGEXP = /^\\s*\\#\\s*else\\s*(?:\\/\\/.*)?$/;\nconst ENDIF_REGEXP = /^\\s*\\#\\s*endif\\s*$/;\nconst IFDEF_WITH_COMMENT_REGEXP = new RegExp(\n `^\\\\s*\\\\#\\\\s*ifdef\\\\s*${DEFINE_NAME_PATTERN}\\\\s*(?:\\\\/\\\\/.*)?$`\n);\nconst ENDIF_WITH_COMMENT_REGEXP = /^\\s*\\#\\s*endif\\s*(?:\\/\\/.*)?$/;\n\nexport type PreprocessorOptions = {\n defines?: Record<string, boolean>;\n};\n\nexport function preprocess(source: string, options?: PreprocessorOptions): string {\n const lines = source.split('\\n');\n const output: string[] = [];\n\n const conditionalStack: Array<{\n parentActive: boolean;\n branchTaken: boolean;\n active: boolean;\n }> = [];\n let conditional = true;\n\n for (const line of lines) {\n const matchIf = line.match(IFDEF_WITH_COMMENT_REGEXP) || line.match(IFDEF_REGEXP);\n const matchIfNot = line.match(IFNDEF_REGEXP);\n const matchElse = line.match(ELSE_REGEXP);\n const matchEnd = line.match(ENDIF_WITH_COMMENT_REGEXP) || line.match(ENDIF_REGEXP);\n\n if (matchIf || matchIfNot) {\n const defineName = (matchIf || matchIfNot)?.[1];\n const defineValue: boolean = Boolean(options?.defines?.[defineName!]);\n const branchTaken: boolean = matchIf ? defineValue : !defineValue;\n const active: boolean = conditional && branchTaken;\n conditionalStack.push({parentActive: conditional, branchTaken, active});\n conditional = active;\n } else if (matchElse) {\n const currentConditional = conditionalStack[conditionalStack.length - 1];\n if (!currentConditional) {\n throw new Error('Encountered #else without matching #ifdef or #ifndef');\n }\n currentConditional.active =\n currentConditional.parentActive && !currentConditional.branchTaken;\n currentConditional.branchTaken = true;\n conditional = currentConditional.active;\n } else if (matchEnd) {\n conditionalStack.pop();\n conditional = conditionalStack.length\n ? conditionalStack[conditionalStack.length - 1].active\n : true;\n } else if (conditional) {\n output.push(line);\n }\n }\n\n if (conditionalStack.length > 0) {\n throw new Error('Unterminated conditional block in shader source');\n }\n\n return output.join('\\n');\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderModule} from './shader-module/shader-module';\nimport {initializeShaderModules} from './shader-module/shader-module';\nimport {\n AssembleShaderProps,\n GetUniformsFunc,\n assembleWGSLShader,\n assembleGLSLShaderPair\n} from './shader-assembly/assemble-shaders';\nimport {\n getShaderBindingDebugRowsFromWGSL,\n type ShaderBindingDebugRow\n} from './shader-assembly/wgsl-binding-debug';\nimport {preprocess} from './preprocessor/preprocessor';\n\n/**\n * A stateful version of `assembleShaders` that can be used to assemble shaders.\n * Supports setting of default modules and hooks.\n */\nexport class ShaderAssembler {\n /** Default ShaderAssembler instance */\n static defaultShaderAssembler: ShaderAssembler;\n /** Hook functions */\n private readonly _hookFunctions: any[] = [];\n /** Shader modules */\n private _defaultModules: ShaderModule[] = [];\n /** Stable per-run WGSL auto-binding assignments keyed by group/module/binding. */\n private readonly _wgslBindingRegistry = new Map<string, number>();\n\n /**\n * A default shader assembler instance - the natural place to register default modules and hooks\n * @returns\n */\n static getDefaultShaderAssembler(): ShaderAssembler {\n ShaderAssembler.defaultShaderAssembler =\n ShaderAssembler.defaultShaderAssembler || new ShaderAssembler();\n return ShaderAssembler.defaultShaderAssembler;\n }\n\n /**\n * Add a default module that does not have to be provided with every call to assembleShaders()\n */\n addDefaultModule(module: ShaderModule): void {\n if (\n !this._defaultModules.find(\n m => m.name === (typeof module === 'string' ? module : module.name)\n )\n ) {\n this._defaultModules.push(module);\n }\n }\n\n /**\n * Remove a default module\n */\n removeDefaultModule(module: ShaderModule): void {\n const moduleName = typeof module === 'string' ? module : module.name;\n this._defaultModules = this._defaultModules.filter(m => m.name !== moduleName);\n }\n\n /**\n * Register a shader hook\n * @param hook\n * @param opts\n */\n addShaderHook(hook: string, opts?: any): void {\n if (opts) {\n hook = Object.assign(opts, {hook});\n }\n this._hookFunctions.push(hook);\n }\n\n /**\n * Assemble a WGSL unified shader\n * @param platformInfo\n * @param props\n * @returns\n */\n assembleWGSLShader(props: AssembleShaderProps): {\n source: string;\n getUniforms: GetUniformsFunc;\n modules: ShaderModule[];\n bindingAssignments: {moduleName: string; name: string; group: number; location: number}[];\n bindingTable: ShaderBindingDebugRow[];\n } {\n const modules = this._getModuleList(props.modules); // Combine with default modules\n const hookFunctions = this._hookFunctions; // TODO - combine with default hook functions\n const {source, getUniforms, bindingAssignments} = assembleWGSLShader({\n ...props,\n // @ts-expect-error\n source: props.source,\n _bindingRegistry: this._wgslBindingRegistry,\n modules,\n hookFunctions\n });\n const defines = {\n ...modules.reduce<Record<string, boolean>>((accumulator, module) => {\n Object.assign(accumulator, module.defines);\n return accumulator;\n }, {}),\n ...props.defines\n };\n // WGSL does not have built-in preprocessing support (just compile time constants)\n const preprocessedSource =\n props.platformInfo.shaderLanguage === 'wgsl' ? preprocess(source, {defines}) : source;\n return {\n source: preprocessedSource,\n getUniforms,\n modules,\n bindingAssignments,\n bindingTable: getShaderBindingDebugRowsFromWGSL(preprocessedSource, bindingAssignments)\n };\n }\n\n /**\n * Assemble a pair of shaders into a single shader program\n * @param platformInfo\n * @param props\n * @returns\n */\n assembleGLSLShaderPair(props: AssembleShaderProps): {\n vs: string;\n fs: string;\n getUniforms: GetUniformsFunc;\n modules: ShaderModule[];\n } {\n const modules = this._getModuleList(props.modules); // Combine with default modules\n const hookFunctions = this._hookFunctions; // TODO - combine with default hook functions\n const assembled = assembleGLSLShaderPair({\n ...props,\n // @ts-expect-error\n vs: props.vs,\n // @ts-expect-error\n fs: props.fs,\n modules,\n hookFunctions\n });\n\n return {...assembled, modules};\n }\n\n /**\n * Dedupe and combine with default modules\n */\n _getModuleList(appModules: ShaderModule[] = []): ShaderModule[] {\n const modules = new Array<ShaderModule>(this._defaultModules.length + appModules.length);\n const seen: Record<string, boolean> = {};\n let count = 0;\n\n for (let i = 0, len = this._defaultModules.length; i < len; ++i) {\n const module = this._defaultModules[i];\n const name = module.name;\n modules[count++] = module;\n seen[name] = true;\n }\n\n for (let i = 0, len = appModules.length; i < len; ++i) {\n const module = appModules[i];\n const name = module.name;\n if (!seen[name]) {\n modules[count++] = module;\n seen[name] = true;\n }\n }\n\n modules.length = count;\n\n initializeShaderModules(modules);\n return modules;\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nconst FS_GLES = /* glsl */ `\\\nout vec4 transform_output;\nvoid main() {\n transform_output = vec4(0);\n}`;\nconst FS300 = `#version 300 es\\n${FS_GLES}`;\n\ntype QualifierInfo = {\n qualifier: string;\n type: string;\n name: string;\n};\n\n// Prase given glsl line and return qualifier details or null\nexport function getQualifierDetails(\n line: string,\n qualifiers: string | string[]\n): QualifierInfo | null {\n qualifiers = Array.isArray(qualifiers) ? qualifiers : [qualifiers];\n const words = line.replace(/^\\s+/, '').split(/\\s+/);\n // TODO add support for precession qualifiers (highp, mediump and lowp)\n const [qualifier, type, definition] = words;\n if (!qualifiers.includes(qualifier) || !type || !definition) {\n return null;\n }\n const name = definition.split(';')[0];\n return {qualifier, type, name};\n}\n\n/**\n * Given the shader input and output variable names,\n * builds and return a pass through fragment shader.\n */\nexport function getPassthroughFS(options?: {\n input?: string;\n inputChannels?: 1 | 2 | 3 | 4;\n output?: string;\n}): string {\n const {input, inputChannels, output} = options || {};\n if (!input) {\n // Default shader\n return FS300;\n }\n if (!inputChannels) {\n throw new Error('inputChannels');\n }\n const inputType = channelCountToType(inputChannels);\n const outputValue = convertToVec4(input, inputChannels);\n return `\\\n#version 300 es\nin ${inputType} ${input};\nout vec4 ${output};\nvoid main() {\n ${output} = ${outputValue};\n}`;\n}\n\n/** convert glsl type to suffix */\nexport function typeToChannelSuffix(type: string): 'x' | 'xy' | 'xyz' | 'xyzw' {\n // biome-ignore format: preserve layout\n switch (type) {\n case 'float': return 'x';\n case 'vec2': return 'xy';\n case 'vec3': return 'xyz';\n case 'vec4': return 'xyzw';\n default:\n throw new Error(type);\n }\n}\n\n/** convert glsl type to channel count */\nexport function typeToChannelCount(type: string): 1 | 2 | 3 | 4 {\n // biome-ignore format: preserve layout\n switch (type) {\n case 'float': return 1;\n case 'vec2': return 2;\n case 'vec3': return 3;\n case 'vec4': return 4;\n default:\n throw new Error(type);\n }\n}\nfunction channelCountToType(channels: 1 | 2 | 3 | 4): 'float' | 'vec2' | 'vec3' | 'vec4' {\n // biome-ignore format: preserve layout\n switch (channels) {\n case 1: return 'float';\n case 2: return 'vec2';\n case 3: return 'vec3';\n case 4: return 'vec4';\n default:\n throw new Error(`invalid channels: ${channels}`);\n }\n}\n\n/** Returns glsl instruction for converting to vec4 */\nexport function convertToVec4(variable: string, channels: 1 | 2 | 3 | 4): string {\n // biome-ignore format: preserve layout\n switch (channels) {\n case 1: return `vec4(${variable}, 0.0, 0.0, 1.0)`;\n case 2: return `vec4(${variable}, 0.0, 1.0)`;\n case 3: return `vec4(${variable}, 1.0)`;\n case 4: return variable;\n default:\n throw new Error(`invalid channels: ${channels}`);\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/**\n * Capitalize first letter of a string\n * @param {string} str\n * @returns {string}\n */\nexport function capitalize(str: string): string {\n return typeof str === 'string' ? str.charAt(0).toUpperCase() + str.slice(1) : str;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {UniformFormat} from '../../../types';\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\nimport {capitalize} from '../utils/capitalize';\n\nexport type GLSLGenerationOptions = {\n shaderLanguage: 'glsl';\n uniforms: 'scoped-interface-blocks' | 'unscoped-interface-blocks' | 'uniforms';\n};\n\nexport function generateGLSLForModule(module: ShaderModule, options: GLSLGenerationOptions) {\n return generateGLSLUniformDeclarations(module, options);\n}\n\nfunction generateGLSLUniformDeclarations(\n module: ShaderModule,\n options: GLSLGenerationOptions\n): string {\n const glsl: string[] = [];\n\n // => layout(std140) uniform UniformBlockName {\n switch (options.uniforms) {\n case 'scoped-interface-blocks':\n case 'unscoped-interface-blocks':\n glsl.push(`layout(std140) uniform ${capitalize(module.name)} {`);\n break;\n case 'uniforms':\n // ignore\n }\n\n for (const [uniformName, uniformFormat] of Object.entries(module.uniformTypes || {})) {\n if (typeof uniformFormat !== 'string') {\n throw new Error(\n `Composite uniform types are not supported by GLSL shader generation: ${module.name}.${uniformName}`\n );\n }\n\n const glslUniformType = getGLSLUniformType(uniformFormat as UniformFormat);\n switch (options.uniforms) {\n case 'scoped-interface-blocks':\n // => layout(std140) uniform UniformBlockName {\n glsl.push(` ${glslUniformType} ${uniformName};`);\n break;\n case 'unscoped-interface-blocks':\n // => layout(std140) uniform UniformBlockName {\n glsl.push(` ${glslUniformType} ${module.name}_${uniformName};`);\n break;\n case 'uniforms':\n glsl.push(`uniform ${glslUniformType} ${module.name}_${uniformName};`);\n }\n }\n\n switch (options.uniforms) {\n case 'scoped-interface-blocks':\n glsl.push(`} ${module.name};`);\n break;\n case 'unscoped-interface-blocks':\n glsl.push('};');\n break;\n case 'uniforms':\n // ignore\n }\n\n // final new line\n glsl.push('');\n\n return glsl.join('\\n');\n}\n\n/** Map a luma.gl WebGPU style uniform type to GLSL */\nfunction getGLSLUniformType(uniformFormat: UniformFormat): string {\n const UNIFORM_TYPE_TO_GLSL: Record<UniformFormat, string> = {\n f32: 'float',\n i32: 'int',\n u32: 'uint',\n 'vec2<f32>': 'vec2',\n 'vec3<f32>': 'vec3',\n 'vec4<f32>': 'vec4',\n 'vec2<i32>': 'ivec2',\n 'vec3<i32>': 'ivec3',\n 'vec4<i32>': 'ivec4',\n 'vec2<u32>': 'uvec2',\n 'vec3<u32>': 'uvec3',\n 'vec4<u32>': 'uvec4',\n 'mat2x2<f32>': 'mat2',\n 'mat2x3<f32>': 'mat2x3',\n 'mat2x4<f32>': 'mat2x4',\n 'mat3x2<f32>': 'mat3x2',\n 'mat3x3<f32>': 'mat3',\n 'mat3x4<f32>': 'mat3x4',\n 'mat4x2<f32>': 'mat4x2',\n 'mat4x3<f32>': 'mat4x3',\n 'mat4x4<f32>': 'mat4'\n };\n\n const glsl = UNIFORM_TYPE_TO_GLSL[uniformFormat];\n return glsl;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\nimport {capitalize} from '../utils/capitalize';\n\nexport type WGSLGenerationOptions = {\n shaderLanguage: 'wgsl';\n};\n\nexport function generateWGSLForModule(module: ShaderModule, options: WGSLGenerationOptions) {\n return generateWGSLUniformDeclarations(module, options);\n}\n\nexport function generateWGSLUniformDeclarations(\n module: ShaderModule,\n options: WGSLGenerationOptions\n) {\n const wgsl: string[] = [];\n\n // => uniform UniformBlockName {\n wgsl.push(`struct ${capitalize(module.name)} {`);\n\n for (const [uniformName, uniformFormat] of Object.entries(module?.uniformTypes || {})) {\n if (typeof uniformFormat !== 'string') {\n throw new Error(\n `Composite uniform types are not supported by WGSL shader generation: ${module.name}.${uniformName}`\n );\n }\n\n const wgslUniformType = uniformFormat;\n wgsl.push(` ${uniformName} : ${wgslUniformType};`);\n }\n wgsl.push('};');\n\n wgsl.push(`var<uniform> ${module.name} : ${capitalize(module.name)};`);\n\n return wgsl.join('\\n');\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {ShaderModule} from '../shader-module/shader-module';\n\nimport type {GLSLGenerationOptions} from './glsl/generate-glsl';\nimport {generateGLSLForModule} from './glsl/generate-glsl';\n\nimport type {WGSLGenerationOptions} from './wgsl/generate-wgsl';\nimport {generateWGSLForModule} from './wgsl/generate-wgsl';\n\n/** Options for how to generate shader code from a module */\nexport type ShaderGenerationOptions = GLSLGenerationOptions | WGSLGenerationOptions;\n\n/** Generates shader code for a module */\nexport function generateShaderForModule(\n module: ShaderModule<Record<string, unknown>>,\n options: ShaderGenerationOptions\n): string {\n switch (options.shaderLanguage) {\n case 'glsl':\n return generateGLSLForModule(module, options);\n case 'wgsl':\n return generateWGSLForModule(module, options);\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// Forked from THREE.js under MIT license\n// Fast Half Float Conversions, http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf\n\nimport {clamp} from '@math.gl/core';\n\n/** Pre-calculated tables for float16 conversion */\ntype Float16Tables = {\n // float32 to float16 helpers\n baseTable: Uint32Array;\n shiftTable: Uint32Array;\n // float16 to float32 helpers\n mantissaTable: Uint32Array;\n exponentTable: Uint32Array;\n offsetTable: Uint32Array;\n};\n\n/** */\nlet float16Tables: Float16Tables | null = null;\n\n/** Storage that can be viewed both as float and integer */\nconst buffer = new ArrayBuffer(4);\nconst floatView = new Float32Array(buffer);\nconst uint32View = new Uint32Array(buffer);\n\n/**\n * float32 to float16\n * @param val\n * @returns\n */\nexport function toHalfFloat(val: number): number {\n float16Tables ||= generateFloat16Tables();\n\n // if ( Math.abs( val ) > 65504 ) console.warn( 'toHalfFloat(): Value out of range.' );\n\n val = clamp(val, -65504, 65504);\n\n floatView[0] = val;\n const f = uint32View[0];\n const e = (f >> 23) & 0x1ff;\n return float16Tables.baseTable[e] + ((f & 0x007fffff) >> float16Tables.shiftTable[e]);\n}\n\n/**\n * float16 to float32\n * @param val\n * @returns\n */\nexport function fromHalfFloat(val: number): number {\n float16Tables ||= generateFloat16Tables();\n\n const m = val >> 10;\n uint32View[0] =\n float16Tables.mantissaTable[float16Tables.offsetTable[m] + (val & 0x3ff)] +\n float16Tables.exponentTable[m];\n return floatView[0];\n}\n\nfunction generateFloat16Tables(): Float16Tables {\n // float32 to float16 helpers\n\n const baseTable = new Uint32Array(512);\n const shiftTable = new Uint32Array(512);\n\n for (let i = 0; i < 256; ++i) {\n const e = i - 127;\n\n // very small number (0, -0)\n\n if (e < -27) {\n baseTable[i] = 0x0000;\n baseTable[i | 0x100] = 0x8000;\n shiftTable[i] = 24;\n shiftTable[i | 0x100] = 24;\n\n // small number (denorm)\n } else if (e < -14) {\n baseTable[i] = 0x0400 >> (-e - 14);\n baseTable[i | 0x100] = (0x0400 >> (-e - 14)) | 0x8000;\n shiftTable[i] = -e - 1;\n shiftTable[i | 0x100] = -e - 1;\n\n // normal number\n } else if (e <= 15) {\n baseTable[i] = (e + 15) << 10;\n baseTable[i | 0x100] = ((e + 15) << 10) | 0x8000;\n shiftTable[i] = 13;\n shiftTable[i | 0x100] = 13;\n\n // large number (Infinity, -Infinity)\n } else if (e < 128) {\n baseTable[i] = 0x7c00;\n baseTable[i | 0x100] = 0xfc00;\n shiftTable[i] = 24;\n shiftTable[i | 0x100] = 24;\n\n // stay (NaN, Infinity, -Infinity)\n } else {\n baseTable[i] = 0x7c00;\n baseTable[i | 0x100] = 0xfc00;\n shiftTable[i] = 13;\n shiftTable[i | 0x100] = 13;\n }\n }\n\n // float16 to float32 helpers\n\n const mantissaTable = new Uint32Array(2048);\n const exponentTable = new Uint32Array(64);\n const offsetTable = new Uint32Array(64);\n\n for (let i = 1; i < 1024; ++i) {\n let m = i << 13; // zero pad mantissa bits\n let e = 0; // zero exponent\n\n // normalized\n while ((m & 0x00800000) === 0) {\n m <<= 1;\n e -= 0x00800000; // decrement exponent\n }\n\n m &= ~0x00800000; // clear leading 1 bit\n e += 0x38800000; // adjust bias\n\n mantissaTable[i] = m | e;\n }\n\n for (let i = 1024; i < 2048; ++i) {\n mantissaTable[i] = 0x38000000 + ((i - 1024) << 13);\n }\n\n for (let i = 1; i < 31; ++i) {\n exponentTable[i] = i << 23;\n }\n\n exponentTable[31] = 0x47800000;\n exponentTable[32] = 0x80000000;\n\n for (let i = 33; i < 63; ++i) {\n exponentTable[i] = 0x80000000 + ((i - 32) << 23);\n }\n\n exponentTable[63] = 0xc7800000;\n\n for (let i = 1; i < 64; ++i) {\n if (i !== 32) {\n offsetTable[i] = 1024;\n }\n }\n\n return {baseTable, shiftTable, mantissaTable, exponentTable, offsetTable};\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {NumericArray} from '@math.gl/types';\n\n/**\n * Calculate WebGL 64 bit float\n * @param a - the input float number\n * @param out - the output array. If not supplied, a new array is created.\n * @param startIndex - the index in the output array to fill from. Default 0.\n * @returns - the fp64 representation of the input number\n */\nexport function fp64ify(a: number, out: NumericArray = [], startIndex: number = 0): NumericArray {\n const hiPart = Math.fround(a);\n const loPart = a - hiPart;\n out[startIndex] = hiPart;\n out[startIndex + 1] = loPart;\n return out;\n}\n\n/**\n * Calculate the low part of a WebGL 64 bit float\n * @param a the input float number\n * @returns the lower 32 bit of the number\n */\nexport function fp64LowPart(a: number): number {\n return a - Math.fround(a);\n}\n\n/**\n * Calculate WebGL 64 bit matrix (transposed \"Float64Array\")\n * @param matrix the input matrix\n * @returns the fp64 representation of the input matrix\n */\nexport function fp64ifyMatrix4(matrix: NumericArray): Float32Array {\n // Transpose the projection matrix to column major for GLSL.\n const matrixFP64 = new Float32Array(32);\n for (let i = 0; i < 4; ++i) {\n for (let j = 0; j < 4; ++j) {\n const index = i * 4 + j;\n fp64ify(matrix[j * 4 + i], matrixFP64, index * 2);\n }\n }\n return matrixFP64;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {NumberArray3, NumberArray4} from '@math.gl/types';\n\n/**\n * Resolves whether semantic colors should be interpreted as byte-style `0..255` values.\n * @param useByteColors - Explicit color interpretation flag.\n * @param defaultUseByteColors - Fallback value when `useByteColors` is omitted.\n * @returns `true` when semantic colors should be normalized from bytes, otherwise `false`.\n */\nexport function resolveUseByteColors(\n useByteColors?: boolean,\n defaultUseByteColors: boolean = true\n): boolean {\n return useByteColors ?? defaultUseByteColors;\n}\n\n/**\n * Normalizes an RGB semantic color to float space when byte-style colors are enabled.\n * @param color - Input RGB semantic color.\n * @param useByteColors - When `true`, divide components by `255`.\n * @returns The normalized RGB color.\n */\nexport function normalizeByteColor3(\n color: Readonly<NumberArray3> = [0, 0, 0],\n useByteColors: boolean = true\n): NumberArray3 {\n if (!useByteColors) {\n return [...color] as NumberArray3;\n }\n\n return color.map(component => component / 255) as NumberArray3;\n}\n\n/**\n * Normalizes an RGBA semantic color to float space when byte-style colors are enabled.\n * @param color - Input RGB or RGBA semantic color.\n * @param useByteColors - When `true`, divide components by `255`.\n * @returns The normalized RGBA color, adding an opaque alpha channel when needed.\n */\nexport function normalizeByteColor4(\n color: Readonly<NumberArray4> | Readonly<NumberArray3>,\n useByteColors: boolean = true\n): NumberArray4 {\n const normalizedColor = normalizeByteColor3(color.slice(0, 3) as NumberArray3, useByteColors);\n const hasAlpha = Number.isFinite(color[3]);\n const alpha = hasAlpha ? (color[3] as number) : 1;\n\n return [\n normalizedColor[0],\n normalizedColor[1],\n normalizedColor[2],\n useByteColors && hasAlpha ? alpha / 255 : alpha\n ] as NumberArray4;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\n\nconst source = /* wgsl */ `\\\nfn random(scale: vec3f, seed: f32) -> f32 {\n return fract(sin(dot(scale + vec3f(seed), vec3f(12.9898, 78.233, 151.7182))) * 43758.5453 + seed);\n}\n`;\n\nconst fs = /* glsl */ `\\\nfloat random(vec3 scale, float seed) {\n /* use the fragment position for a different seed per-pixel */\n return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);\n}\n`;\n\n/** Quick random generator for fragment shaders */\nexport const random = {\n name: 'random',\n source,\n fs\n} as const satisfies ShaderModule<{}, {}>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// import {ShaderModule} from '../../types';\n\nconst fp32shader = /* glsl */ `\\\n#ifdef LUMA_FP32_TAN_PRECISION_WORKAROUND\n\n// All these functions are for substituting tan() function from Intel GPU only\nconst float TWO_PI = 6.2831854820251465;\nconst float PI_2 = 1.5707963705062866;\nconst float PI_16 = 0.1963495463132858;\n\nconst float SIN_TABLE_0 = 0.19509032368659973;\nconst float SIN_TABLE_1 = 0.3826834261417389;\nconst float SIN_TABLE_2 = 0.5555702447891235;\nconst float SIN_TABLE_3 = 0.7071067690849304;\n\nconst float COS_TABLE_0 = 0.9807852506637573;\nconst float COS_TABLE_1 = 0.9238795042037964;\nconst float COS_TABLE_2 = 0.8314695954322815;\nconst float COS_TABLE_3 = 0.7071067690849304;\n\nconst float INVERSE_FACTORIAL_3 = 1.666666716337204e-01; // 1/3!\nconst float INVERSE_FACTORIAL_5 = 8.333333767950535e-03; // 1/5!\nconst float INVERSE_FACTORIAL_7 = 1.9841270113829523e-04; // 1/7!\nconst float INVERSE_FACTORIAL_9 = 2.75573188446287533e-06; // 1/9!\n\nfloat sin_taylor_fp32(float a) {\n float r, s, t, x;\n\n if (a == 0.0) {\n return 0.0;\n }\n\n x = -a * a;\n s = a;\n r = a;\n\n r = r * x;\n t = r * INVERSE_FACTORIAL_3;\n s = s + t;\n\n r = r * x;\n t = r * INVERSE_FACTORIAL_5;\n s = s + t;\n\n r = r * x;\n t = r * INVERSE_FACTORIAL_7;\n s = s + t;\n\n r = r * x;\n t = r * INVERSE_FACTORIAL_9;\n s = s + t;\n\n return s;\n}\n\nvoid sincos_taylor_fp32(float a, out float sin_t, out float cos_t) {\n if (a == 0.0) {\n sin_t = 0.0;\n cos_t = 1.0;\n }\n sin_t = sin_taylor_fp32(a);\n cos_t = sqrt(1.0 - sin_t * sin_t);\n}\n\nfloat tan_taylor_fp32(float a) {\n float sin_a;\n float cos_a;\n\n if (a == 0.0) {\n return 0.0;\n }\n\n // 2pi range reduction\n float z = floor(a / TWO_PI);\n float r = a - TWO_PI * z;\n\n float t;\n float q = floor(r / PI_2 + 0.5);\n int j = int(q);\n\n if (j < -2 || j > 2) {\n return 1.0 / 0.0;\n }\n\n t = r - PI_2 * q;\n\n q = floor(t / PI_16 + 0.5);\n int k = int(q);\n int abs_k = int(abs(float(k)));\n\n if (abs_k > 4) {\n return 1.0 / 0.0;\n } else {\n t = t - PI_16 * q;\n }\n\n float u = 0.0;\n float v = 0.0;\n\n float sin_t, cos_t;\n float s, c;\n sincos_taylor_fp32(t, sin_t, cos_t);\n\n if (k == 0) {\n s = sin_t;\n c = cos_t;\n } else {\n if (abs(float(abs_k) - 1.0) < 0.5) {\n u = COS_TABLE_0;\n v = SIN_TABLE_0;\n } else if (abs(float(abs_k) - 2.0) < 0.5) {\n u = COS_TABLE_1;\n v = SIN_TABLE_1;\n } else if (abs(float(abs_k) - 3.0) < 0.5) {\n u = COS_TABLE_2;\n v = SIN_TABLE_2;\n } else if (abs(float(abs_k) - 4.0) < 0.5) {\n u = COS_TABLE_3;\n v = SIN_TABLE_3;\n }\n if (k > 0) {\n s = u * sin_t + v * cos_t;\n c = u * cos_t - v * sin_t;\n } else {\n s = u * sin_t - v * cos_t;\n c = u * cos_t + v * sin_t;\n }\n }\n\n if (j == 0) {\n sin_a = s;\n cos_a = c;\n } else if (j == 1) {\n sin_a = c;\n cos_a = -s;\n } else if (j == -1) {\n sin_a = -c;\n cos_a = s;\n } else {\n sin_a = -s;\n cos_a = -c;\n }\n return sin_a / cos_a;\n}\n#endif\n\nfloat tan_fp32(float a) {\n#ifdef LUMA_FP32_TAN_PRECISION_WORKAROUND\n return tan_taylor_fp32(a);\n#else\n return tan(a);\n#endif\n}\n`;\n\n/**\n * 32 bit math library (fixups for GPUs)\n */\nexport const fp32 = {\n name: 'fp32',\n vs: fp32shader\n};\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const fp64arithmeticShader = /* glsl */ `\\\n\nlayout(std140) uniform fp64arithmeticUniforms {\n uniform float ONE;\n uniform float SPLIT;\n} fp64;\n\n/*\nAbout LUMA_FP64_CODE_ELIMINATION_WORKAROUND\n\nThe purpose of this workaround is to prevent shader compilers from\noptimizing away necessary arithmetic operations by swapping their sequences\nor transform the equation to some 'equivalent' form.\n\nThese helpers implement Dekker/Veltkamp-style error tracking. If the compiler\nfolds constants or reassociates the arithmetic, the high/low split can stop\ntracking the rounding error correctly. That failure mode tends to look fine in\nsimple coordinate setup, but then breaks down inside iterative arithmetic such\nas fp64 Mandelbrot loops.\n\nThe method is to multiply an artifical variable, ONE, which will be known to\nthe compiler to be 1 only at runtime. The whole expression is then represented\nas a polynomial with respective to ONE. In the coefficients of all terms, only one a\nand one b should appear\n\nerr = (a + b) * ONE^6 - a * ONE^5 - (a + b) * ONE^4 + a * ONE^3 - b - (a + b) * ONE^2 + a * ONE\n*/\n\nfloat prevent_fp64_optimization(float value) {\n#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)\n return value + fp64.ONE * 0.0;\n#else\n return value;\n#endif\n}\n\n// Divide float number to high and low floats to extend fraction bits\nvec2 split(float a) {\n // Keep SPLIT as a runtime uniform so the compiler cannot fold the Dekker\n // split into a constant expression and reassociate the recovery steps.\n float split = prevent_fp64_optimization(fp64.SPLIT);\n float t = prevent_fp64_optimization(a * split);\n float temp = t - a;\n float a_hi = t - temp;\n float a_lo = a - a_hi;\n return vec2(a_hi, a_lo);\n}\n\n// Divide float number again when high float uses too many fraction bits\nvec2 split2(vec2 a) {\n vec2 b = split(a.x);\n b.y += a.y;\n return b;\n}\n\n// Special sum operation when a > b\nvec2 quickTwoSum(float a, float b) {\n#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)\n float sum = (a + b) * fp64.ONE;\n float err = b - (sum - a) * fp64.ONE;\n#else\n float sum = a + b;\n float err = b - (sum - a);\n#endif\n return vec2(sum, err);\n}\n\n// General sum operation\nvec2 twoSum(float a, float b) {\n float s = (a + b);\n#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)\n float v = (s * fp64.ONE - a) * fp64.ONE;\n float err = (a - (s - v) * fp64.ONE) * fp64.ONE * fp64.ONE * fp64.ONE + (b - v);\n#else\n float v = s - a;\n float err = (a - (s - v)) + (b - v);\n#endif\n return vec2(s, err);\n}\n\nvec2 twoSub(float a, float b) {\n float s = (a - b);\n#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)\n float v = (s * fp64.ONE - a) * fp64.ONE;\n float err = (a - (s - v) * fp64.ONE) * fp64.ONE * fp64.ONE * fp64.ONE - (b + v);\n#else\n float v = s - a;\n float err = (a - (s - v)) - (b + v);\n#endif\n return vec2(s, err);\n}\n\nvec2 twoSqr(float a) {\n float prod = a * a;\n vec2 a_fp64 = split(a);\n#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)\n float err = ((a_fp64.x * a_fp64.x - prod) * fp64.ONE + 2.0 * a_fp64.x *\n a_fp64.y * fp64.ONE * fp64.ONE) + a_fp64.y * a_fp64.y * fp64.ONE * fp64.ONE * fp64.ONE;\n#else\n float err = ((a_fp64.x * a_fp64.x - prod) + 2.0 * a_fp64.x * a_fp64.y) + a_fp64.y * a_fp64.y;\n#endif\n return vec2(prod, err);\n}\n\nvec2 twoProd(float a, float b) {\n float prod = a * b;\n vec2 a_fp64 = split(a);\n vec2 b_fp64 = split(b);\n // twoProd is especially sensitive because mul_fp64 and div_fp64 both depend\n // on the split terms and cross terms staying in the original evaluation\n // order. If the compiler folds or reassociates them, the low part tends to\n // collapse to zero or NaN on some drivers.\n float highProduct = prevent_fp64_optimization(a_fp64.x * b_fp64.x);\n float crossProduct1 = prevent_fp64_optimization(a_fp64.x * b_fp64.y);\n float crossProduct2 = prevent_fp64_optimization(a_fp64.y * b_fp64.x);\n float lowProduct = prevent_fp64_optimization(a_fp64.y * b_fp64.y);\n#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)\n float err1 = (highProduct - prod) * fp64.ONE;\n float err2 = crossProduct1 * fp64.ONE * fp64.ONE;\n float err3 = crossProduct2 * fp64.ONE * fp64.ONE * fp64.ONE;\n float err4 = lowProduct * fp64.ONE * fp64.ONE * fp64.ONE * fp64.ONE;\n#else\n float err1 = highProduct - prod;\n float err2 = crossProduct1;\n float err3 = crossProduct2;\n float err4 = lowProduct;\n#endif\n float err = ((err1 + err2) + err3) + err4;\n return vec2(prod, err);\n}\n\nvec2 sum_fp64(vec2 a, vec2 b) {\n vec2 s, t;\n s = twoSum(a.x, b.x);\n t = twoSum(a.y, b.y);\n s.y += t.x;\n s = quickTwoSum(s.x, s.y);\n s.y += t.y;\n s = quickTwoSum(s.x, s.y);\n return s;\n}\n\nvec2 sub_fp64(vec2 a, vec2 b) {\n vec2 s, t;\n s = twoSub(a.x, b.x);\n t = twoSub(a.y, b.y);\n s.y += t.x;\n s = quickTwoSum(s.x, s.y);\n s.y += t.y;\n s = quickTwoSum(s.x, s.y);\n return s;\n}\n\nvec2 mul_fp64(vec2 a, vec2 b) {\n vec2 prod = twoProd(a.x, b.x);\n // y component is for the error\n prod.y += a.x * b.y;\n#if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND)\n prod = split2(prod);\n#endif\n prod = quickTwoSum(prod.x, prod.y);\n prod.y += a.y * b.x;\n#if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND)\n prod = split2(prod);\n#endif\n prod = quickTwoSum(prod.x, prod.y);\n return prod;\n}\n\nvec2 div_fp64(vec2 a, vec2 b) {\n float xn = 1.0 / b.x;\n#if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND)\n vec2 yn = mul_fp64(a, vec2(xn, 0));\n#else\n vec2 yn = a * xn;\n#endif\n float diff = (sub_fp64(a, mul_fp64(b, yn))).x;\n vec2 prod = twoProd(xn, diff);\n return sum_fp64(yn, prod);\n}\n\nvec2 sqrt_fp64(vec2 a) {\n if (a.x == 0.0 && a.y == 0.0) return vec2(0.0, 0.0);\n if (a.x < 0.0) return vec2(0.0 / 0.0, 0.0 / 0.0);\n\n float x = 1.0 / sqrt(a.x);\n float yn = a.x * x;\n#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)\n vec2 yn_sqr = twoSqr(yn) * fp64.ONE;\n#else\n vec2 yn_sqr = twoSqr(yn);\n#endif\n float diff = sub_fp64(a, yn_sqr).x;\n vec2 prod = twoProd(x * 0.5, diff);\n#if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND)\n return sum_fp64(split(yn), prod);\n#else\n return sum_fp64(vec2(yn, 0.0), prod);\n#endif\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const fp64arithmeticWGSL = /* wgsl */ `\\\nstruct Fp64ArithmeticUniforms {\n ONE: f32,\n SPLIT: f32,\n};\n\n@group(0) @binding(auto) var<uniform> fp64arithmetic : Fp64ArithmeticUniforms;\n\nfn fp64_nan(seed: f32) -> f32 {\n let nanBits = 0x7fc00000u | select(0u, 1u, seed < 0.0);\n return bitcast<f32>(nanBits);\n}\n\nfn fp64_runtime_zero() -> f32 {\n return fp64arithmetic.ONE * 0.0;\n}\n\nfn prevent_fp64_optimization(value: f32) -> f32 {\n#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND\n return value + fp64_runtime_zero();\n#else\n return value;\n#endif\n}\n\nfn split(a: f32) -> vec2f {\n let splitValue = prevent_fp64_optimization(fp64arithmetic.SPLIT + fp64_runtime_zero());\n let t = prevent_fp64_optimization(a * splitValue);\n let temp = prevent_fp64_optimization(t - a);\n let aHi = prevent_fp64_optimization(t - temp);\n let aLo = prevent_fp64_optimization(a - aHi);\n return vec2f(aHi, aLo);\n}\n\nfn split2(a: vec2f) -> vec2f {\n var b = split(a.x);\n b.y = b.y + a.y;\n return b;\n}\n\nfn quickTwoSum(a: f32, b: f32) -> vec2f {\n#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND\n let sum = prevent_fp64_optimization((a + b) * fp64arithmetic.ONE);\n let err = prevent_fp64_optimization(b - (sum - a) * fp64arithmetic.ONE);\n#else\n let sum = prevent_fp64_optimization(a + b);\n let err = prevent_fp64_optimization(b - (sum - a));\n#endif\n return vec2f(sum, err);\n}\n\nfn twoSum(a: f32, b: f32) -> vec2f {\n let s = prevent_fp64_optimization(a + b);\n#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND\n let v = prevent_fp64_optimization((s * fp64arithmetic.ONE - a) * fp64arithmetic.ONE);\n let err =\n prevent_fp64_optimization((a - (s - v) * fp64arithmetic.ONE) *\n fp64arithmetic.ONE *\n fp64arithmetic.ONE *\n fp64arithmetic.ONE) +\n prevent_fp64_optimization(b - v);\n#else\n let v = prevent_fp64_optimization(s - a);\n let err = prevent_fp64_optimization(a - (s - v)) + prevent_fp64_optimization(b - v);\n#endif\n return vec2f(s, err);\n}\n\nfn twoSub(a: f32, b: f32) -> vec2f {\n let s = prevent_fp64_optimization(a - b);\n#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND\n let v = prevent_fp64_optimization((s * fp64arithmetic.ONE - a) * fp64arithmetic.ONE);\n let err =\n prevent_fp64_optimization((a - (s - v) * fp64arithmetic.ONE) *\n fp64arithmetic.ONE *\n fp64arithmetic.ONE *\n fp64arithmetic.ONE) -\n prevent_fp64_optimization(b + v);\n#else\n let v = prevent_fp64_optimization(s - a);\n let err = prevent_fp64_optimization(a - (s - v)) - prevent_fp64_optimization(b + v);\n#endif\n return vec2f(s, err);\n}\n\nfn twoSqr(a: f32) -> vec2f {\n let prod = prevent_fp64_optimization(a * a);\n let aFp64 = split(a);\n let highProduct = prevent_fp64_optimization(aFp64.x * aFp64.x);\n let crossProduct = prevent_fp64_optimization(2.0 * aFp64.x * aFp64.y);\n let lowProduct = prevent_fp64_optimization(aFp64.y * aFp64.y);\n#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND\n let err =\n (prevent_fp64_optimization(highProduct - prod) * fp64arithmetic.ONE +\n crossProduct * fp64arithmetic.ONE * fp64arithmetic.ONE) +\n lowProduct * fp64arithmetic.ONE * fp64arithmetic.ONE * fp64arithmetic.ONE;\n#else\n let err = ((prevent_fp64_optimization(highProduct - prod) + crossProduct) + lowProduct);\n#endif\n return vec2f(prod, err);\n}\n\nfn twoProd(a: f32, b: f32) -> vec2f {\n let prod = prevent_fp64_optimization(a * b);\n let aFp64 = split(a);\n let bFp64 = split(b);\n let highProduct = prevent_fp64_optimization(aFp64.x * bFp64.x);\n let crossProduct1 = prevent_fp64_optimization(aFp64.x * bFp64.y);\n let crossProduct2 = prevent_fp64_optimization(aFp64.y * bFp64.x);\n let lowProduct = prevent_fp64_optimization(aFp64.y * bFp64.y);\n#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND\n let err1 = (highProduct - prod) * fp64arithmetic.ONE;\n let err2 = crossProduct1 * fp64arithmetic.ONE * fp64arithmetic.ONE;\n let err3 = crossProduct2 * fp64arithmetic.ONE * fp64arithmetic.ONE * fp64arithmetic.ONE;\n let err4 =\n lowProduct *\n fp64arithmetic.ONE *\n fp64arithmetic.ONE *\n fp64arithmetic.ONE *\n fp64arithmetic.ONE;\n#else\n let err1 = highProduct - prod;\n let err2 = crossProduct1;\n let err3 = crossProduct2;\n let err4 = lowProduct;\n#endif\n let err12InputA = prevent_fp64_optimization(err1);\n let err12InputB = prevent_fp64_optimization(err2);\n let err12 = prevent_fp64_optimization(err12InputA + err12InputB);\n let err123InputA = prevent_fp64_optimization(err12);\n let err123InputB = prevent_fp64_optimization(err3);\n let err123 = prevent_fp64_optimization(err123InputA + err123InputB);\n let err1234InputA = prevent_fp64_optimization(err123);\n let err1234InputB = prevent_fp64_optimization(err4);\n let err = prevent_fp64_optimization(err1234InputA + err1234InputB);\n return vec2f(prod, err);\n}\n\nfn sum_fp64(a: vec2f, b: vec2f) -> vec2f {\n var s = twoSum(a.x, b.x);\n let t = twoSum(a.y, b.y);\n s.y = prevent_fp64_optimization(s.y + t.x);\n s = quickTwoSum(s.x, s.y);\n s.y = prevent_fp64_optimization(s.y + t.y);\n s = quickTwoSum(s.x, s.y);\n return s;\n}\n\nfn sub_fp64(a: vec2f, b: vec2f) -> vec2f {\n var s = twoSub(a.x, b.x);\n let t = twoSub(a.y, b.y);\n s.y = prevent_fp64_optimization(s.y + t.x);\n s = quickTwoSum(s.x, s.y);\n s.y = prevent_fp64_optimization(s.y + t.y);\n s = quickTwoSum(s.x, s.y);\n return s;\n}\n\nfn mul_fp64(a: vec2f, b: vec2f) -> vec2f {\n var prod = twoProd(a.x, b.x);\n let crossProduct1 = prevent_fp64_optimization(a.x * b.y);\n prod.y = prevent_fp64_optimization(prod.y + crossProduct1);\n#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND\n prod = split2(prod);\n#endif\n prod = quickTwoSum(prod.x, prod.y);\n let crossProduct2 = prevent_fp64_optimization(a.y * b.x);\n prod.y = prevent_fp64_optimization(prod.y + crossProduct2);\n#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND\n prod = split2(prod);\n#endif\n prod = quickTwoSum(prod.x, prod.y);\n return prod;\n}\n\nfn div_fp64(a: vec2f, b: vec2f) -> vec2f {\n let xn = prevent_fp64_optimization(1.0 / b.x);\n let yn = mul_fp64(a, vec2f(xn, fp64_runtime_zero()));\n let diff = prevent_fp64_optimization(sub_fp64(a, mul_fp64(b, yn)).x);\n let prod = twoProd(xn, diff);\n return sum_fp64(yn, prod);\n}\n\nfn sqrt_fp64(a: vec2f) -> vec2f {\n if (a.x == 0.0 && a.y == 0.0) {\n return vec2f(0.0, 0.0);\n }\n if (a.x < 0.0) {\n let nanValue = fp64_nan(a.x);\n return vec2f(nanValue, nanValue);\n }\n\n let x = prevent_fp64_optimization(1.0 / sqrt(a.x));\n let yn = prevent_fp64_optimization(a.x * x);\n#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND\n let ynSqr = twoSqr(yn) * fp64arithmetic.ONE;\n#else\n let ynSqr = twoSqr(yn);\n#endif\n let diff = prevent_fp64_optimization(sub_fp64(a, ynSqr).x);\n let prod = twoProd(prevent_fp64_optimization(x * 0.5), diff);\n#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND\n return sum_fp64(split(yn), prod);\n#else\n return sum_fp64(vec2f(yn, 0.0), prod);\n#endif\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const fp64functionShader = /* glsl */ `\\\nconst vec2 E_FP64 = vec2(2.7182817459106445e+00, 8.254840366817007e-08);\nconst vec2 LOG2_FP64 = vec2(0.6931471824645996e+00, -1.9046542121259336e-09);\nconst vec2 PI_FP64 = vec2(3.1415927410125732, -8.742278012618954e-8);\nconst vec2 TWO_PI_FP64 = vec2(6.2831854820251465, -1.7484556025237907e-7);\nconst vec2 PI_2_FP64 = vec2(1.5707963705062866, -4.371139006309477e-8);\nconst vec2 PI_4_FP64 = vec2(0.7853981852531433, -2.1855695031547384e-8);\nconst vec2 PI_16_FP64 = vec2(0.19634954631328583, -5.463923757886846e-9);\nconst vec2 PI_16_2_FP64 = vec2(0.39269909262657166, -1.0927847515773692e-8);\nconst vec2 PI_16_3_FP64 = vec2(0.5890486240386963, -1.4906100798128818e-9);\nconst vec2 PI_180_FP64 = vec2(0.01745329238474369, 1.3519960498364902e-10);\n\nconst vec2 SIN_TABLE_0_FP64 = vec2(0.19509032368659973, -1.6704714833615242e-9);\nconst vec2 SIN_TABLE_1_FP64 = vec2(0.3826834261417389, 6.22335089017767e-9);\nconst vec2 SIN_TABLE_2_FP64 = vec2(0.5555702447891235, -1.1769521357507529e-8);\nconst vec2 SIN_TABLE_3_FP64 = vec2(0.7071067690849304, 1.2101617041793133e-8);\n\nconst vec2 COS_TABLE_0_FP64 = vec2(0.9807852506637573, 2.9739473106360492e-8);\nconst vec2 COS_TABLE_1_FP64 = vec2(0.9238795042037964, 2.8307490351764386e-8);\nconst vec2 COS_TABLE_2_FP64 = vec2(0.8314695954322815, 1.6870263741530778e-8);\nconst vec2 COS_TABLE_3_FP64 = vec2(0.7071067690849304, 1.2101617152815436e-8);\n\nconst vec2 INVERSE_FACTORIAL_3_FP64 = vec2(1.666666716337204e-01, -4.967053879312289e-09); // 1/3!\nconst vec2 INVERSE_FACTORIAL_4_FP64 = vec2(4.16666679084301e-02, -1.2417634698280722e-09); // 1/4!\nconst vec2 INVERSE_FACTORIAL_5_FP64 = vec2(8.333333767950535e-03, -4.34617203337595e-10); // 1/5!\nconst vec2 INVERSE_FACTORIAL_6_FP64 = vec2(1.3888889225199819e-03, -3.3631094437103215e-11); // 1/6!\nconst vec2 INVERSE_FACTORIAL_7_FP64 = vec2(1.9841270113829523e-04, -2.725596874933456e-12); // 1/7!\nconst vec2 INVERSE_FACTORIAL_8_FP64 = vec2(2.4801587642286904e-05, -3.406996025904184e-13); // 1/8!\nconst vec2 INVERSE_FACTORIAL_9_FP64 = vec2(2.75573188446287533e-06, 3.7935713937038186e-14); // 1/9!\nconst vec2 INVERSE_FACTORIAL_10_FP64 = vec2(2.755731998149713e-07, -7.575112367869873e-15); // 1/10!\n\nfloat nint(float d) {\n if (d == floor(d)) return d;\n return floor(d + 0.5);\n}\n\nvec2 nint_fp64(vec2 a) {\n float hi = nint(a.x);\n float lo;\n vec2 tmp;\n if (hi == a.x) {\n lo = nint(a.y);\n tmp = quickTwoSum(hi, lo);\n } else {\n lo = 0.0;\n if (abs(hi - a.x) == 0.5 && a.y < 0.0) {\n hi -= 1.0;\n }\n tmp = vec2(hi, lo);\n }\n return tmp;\n}\n\n/* k_power controls how much range reduction we would like to have\nRange reduction uses the following method:\nassume a = k_power * r + m * log(2), k and m being integers.\nSet k_power = 4 (we can choose other k to trade accuracy with performance.\nwe only need to calculate exp(r) and using exp(a) = 2^m * exp(r)^k_power;\n*/\n\nvec2 exp_fp64(vec2 a) {\n // We need to make sure these two numbers match\n // as bit-wise shift is not available in GLSL 1.0\n const int k_power = 4;\n const float k = 16.0;\n\n const float inv_k = 1.0 / k;\n\n if (a.x <= -88.0) return vec2(0.0, 0.0);\n if (a.x >= 88.0) return vec2(1.0 / 0.0, 1.0 / 0.0);\n if (a.x == 0.0 && a.y == 0.0) return vec2(1.0, 0.0);\n if (a.x == 1.0 && a.y == 0.0) return E_FP64;\n\n float m = floor(a.x / LOG2_FP64.x + 0.5);\n vec2 r = sub_fp64(a, mul_fp64(LOG2_FP64, vec2(m, 0.0))) * inv_k;\n vec2 s, t, p;\n\n p = mul_fp64(r, r);\n s = sum_fp64(r, p * 0.5);\n p = mul_fp64(p, r);\n t = mul_fp64(p, INVERSE_FACTORIAL_3_FP64);\n\n s = sum_fp64(s, t);\n p = mul_fp64(p, r);\n t = mul_fp64(p, INVERSE_FACTORIAL_4_FP64);\n\n s = sum_fp64(s, t);\n p = mul_fp64(p, r);\n t = mul_fp64(p, INVERSE_FACTORIAL_5_FP64);\n\n // s = sum_fp64(s, t);\n // p = mul_fp64(p, r);\n // t = mul_fp64(p, INVERSE_FACTORIAL_6_FP64);\n\n // s = sum_fp64(s, t);\n // p = mul_fp64(p, r);\n // t = mul_fp64(p, INVERSE_FACTORIAL_7_FP64);\n\n s = sum_fp64(s, t);\n\n\n // At this point, s = exp(r) - 1; but after following 4 recursions, we will get exp(r) ^ 512 - 1.\n for (int i = 0; i < k_power; i++) {\n s = sum_fp64(s * 2.0, mul_fp64(s, s));\n }\n\n#if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND)\n s = sum_fp64(s, vec2(fp64.ONE, 0.0));\n#else\n s = sum_fp64(s, vec2(1.0, 0.0));\n#endif\n\n return s * pow(2.0, m);\n// return r;\n}\n\nvec2 log_fp64(vec2 a)\n{\n if (a.x == 1.0 && a.y == 0.0) return vec2(0.0, 0.0);\n if (a.x <= 0.0) return vec2(0.0 / 0.0, 0.0 / 0.0);\n vec2 x = vec2(log(a.x), 0.0);\n vec2 s;\n#if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND)\n s = vec2(fp64.ONE, 0.0);\n#else\n s = vec2(1.0, 0.0);\n#endif\n\n x = sub_fp64(sum_fp64(x, mul_fp64(a, exp_fp64(-x))), s);\n return x;\n}\n\nvec2 sin_taylor_fp64(vec2 a) {\n vec2 r, s, t, x;\n\n if (a.x == 0.0 && a.y == 0.0) {\n return vec2(0.0, 0.0);\n }\n\n x = -mul_fp64(a, a);\n s = a;\n r = a;\n\n r = mul_fp64(r, x);\n t = mul_fp64(r, INVERSE_FACTORIAL_3_FP64);\n s = sum_fp64(s, t);\n\n r = mul_fp64(r, x);\n t = mul_fp64(r, INVERSE_FACTORIAL_5_FP64);\n s = sum_fp64(s, t);\n\n /* keep the following commented code in case we need them\n for extra accuracy from the Taylor expansion*/\n\n // r = mul_fp64(r, x);\n // t = mul_fp64(r, INVERSE_FACTORIAL_7_FP64);\n // s = sum_fp64(s, t);\n\n // r = mul_fp64(r, x);\n // t = mul_fp64(r, INVERSE_FACTORIAL_9_FP64);\n // s = sum_fp64(s, t);\n\n return s;\n}\n\nvec2 cos_taylor_fp64(vec2 a) {\n vec2 r, s, t, x;\n\n if (a.x == 0.0 && a.y == 0.0) {\n return vec2(1.0, 0.0);\n }\n\n x = -mul_fp64(a, a);\n r = x;\n s = sum_fp64(vec2(1.0, 0.0), r * 0.5);\n\n r = mul_fp64(r, x);\n t = mul_fp64(r, INVERSE_FACTORIAL_4_FP64);\n s = sum_fp64(s, t);\n\n r = mul_fp64(r, x);\n t = mul_fp64(r, INVERSE_FACTORIAL_6_FP64);\n s = sum_fp64(s, t);\n\n /* keep the following commented code in case we need them\n for extra accuracy from the Taylor expansion*/\n\n // r = mul_fp64(r, x);\n // t = mul_fp64(r, INVERSE_FACTORIAL_8_FP64);\n // s = sum_fp64(s, t);\n\n // r = mul_fp64(r, x);\n // t = mul_fp64(r, INVERSE_FACTORIAL_10_FP64);\n // s = sum_fp64(s, t);\n\n return s;\n}\n\nvoid sincos_taylor_fp64(vec2 a, out vec2 sin_t, out vec2 cos_t) {\n if (a.x == 0.0 && a.y == 0.0) {\n sin_t = vec2(0.0, 0.0);\n cos_t = vec2(1.0, 0.0);\n }\n\n sin_t = sin_taylor_fp64(a);\n cos_t = sqrt_fp64(sub_fp64(vec2(1.0, 0.0), mul_fp64(sin_t, sin_t)));\n}\n\nvec2 sin_fp64(vec2 a) {\n if (a.x == 0.0 && a.y == 0.0) {\n return vec2(0.0, 0.0);\n }\n\n // 2pi range reduction\n vec2 z = nint_fp64(div_fp64(a, TWO_PI_FP64));\n vec2 r = sub_fp64(a, mul_fp64(TWO_PI_FP64, z));\n\n vec2 t;\n float q = floor(r.x / PI_2_FP64.x + 0.5);\n int j = int(q);\n\n if (j < -2 || j > 2) {\n return vec2(0.0 / 0.0, 0.0 / 0.0);\n }\n\n t = sub_fp64(r, mul_fp64(PI_2_FP64, vec2(q, 0.0)));\n\n q = floor(t.x / PI_16_FP64.x + 0.5);\n int k = int(q);\n\n if (k == 0) {\n if (j == 0) {\n return sin_taylor_fp64(t);\n } else if (j == 1) {\n return cos_taylor_fp64(t);\n } else if (j == -1) {\n return -cos_taylor_fp64(t);\n } else {\n return -sin_taylor_fp64(t);\n }\n }\n\n int abs_k = int(abs(float(k)));\n\n if (abs_k > 4) {\n return vec2(0.0 / 0.0, 0.0 / 0.0);\n } else {\n t = sub_fp64(t, mul_fp64(PI_16_FP64, vec2(q, 0.0)));\n }\n\n vec2 u = vec2(0.0, 0.0);\n vec2 v = vec2(0.0, 0.0);\n\n#if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND)\n if (abs(float(abs_k) - 1.0) < 0.5) {\n u = COS_TABLE_0_FP64;\n v = SIN_TABLE_0_FP64;\n } else if (abs(float(abs_k) - 2.0) < 0.5) {\n u = COS_TABLE_1_FP64;\n v = SIN_TABLE_1_FP64;\n } else if (abs(float(abs_k) - 3.0) < 0.5) {\n u = COS_TABLE_2_FP64;\n v = SIN_TABLE_2_FP64;\n } else if (abs(float(abs_k) - 4.0) < 0.5) {\n u = COS_TABLE_3_FP64;\n v = SIN_TABLE_3_FP64;\n }\n#else\n if (abs_k == 1) {\n u = COS_TABLE_0_FP64;\n v = SIN_TABLE_0_FP64;\n } else if (abs_k == 2) {\n u = COS_TABLE_1_FP64;\n v = SIN_TABLE_1_FP64;\n } else if (abs_k == 3) {\n u = COS_TABLE_2_FP64;\n v = SIN_TABLE_2_FP64;\n } else if (abs_k == 4) {\n u = COS_TABLE_3_FP64;\n v = SIN_TABLE_3_FP64;\n }\n#endif\n\n vec2 sin_t, cos_t;\n sincos_taylor_fp64(t, sin_t, cos_t);\n\n\n\n vec2 result = vec2(0.0, 0.0);\n if (j == 0) {\n if (k > 0) {\n result = sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t));\n } else {\n result = sub_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t));\n }\n } else if (j == 1) {\n if (k > 0) {\n result = sub_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t));\n } else {\n result = sum_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t));\n }\n } else if (j == -1) {\n if (k > 0) {\n result = sub_fp64(mul_fp64(v, sin_t), mul_fp64(u, cos_t));\n } else {\n result = -sum_fp64(mul_fp64(v, sin_t), mul_fp64(u, cos_t));\n }\n } else {\n if (k > 0) {\n result = -sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t));\n } else {\n result = sub_fp64(mul_fp64(v, cos_t), mul_fp64(u, sin_t));\n }\n }\n\n return result;\n}\n\nvec2 cos_fp64(vec2 a) {\n if (a.x == 0.0 && a.y == 0.0) {\n return vec2(1.0, 0.0);\n }\n\n // 2pi range reduction\n vec2 z = nint_fp64(div_fp64(a, TWO_PI_FP64));\n vec2 r = sub_fp64(a, mul_fp64(TWO_PI_FP64, z));\n\n vec2 t;\n float q = floor(r.x / PI_2_FP64.x + 0.5);\n int j = int(q);\n\n if (j < -2 || j > 2) {\n return vec2(0.0 / 0.0, 0.0 / 0.0);\n }\n\n t = sub_fp64(r, mul_fp64(PI_2_FP64, vec2(q, 0.0)));\n\n q = floor(t.x / PI_16_FP64.x + 0.5);\n int k = int(q);\n\n if (k == 0) {\n if (j == 0) {\n return cos_taylor_fp64(t);\n } else if (j == 1) {\n return -sin_taylor_fp64(t);\n } else if (j == -1) {\n return sin_taylor_fp64(t);\n } else {\n return -cos_taylor_fp64(t);\n }\n }\n\n int abs_k = int(abs(float(k)));\n\n if (abs_k > 4) {\n return vec2(0.0 / 0.0, 0.0 / 0.0);\n } else {\n t = sub_fp64(t, mul_fp64(PI_16_FP64, vec2(q, 0.0)));\n }\n\n vec2 u = vec2(0.0, 0.0);\n vec2 v = vec2(0.0, 0.0);\n\n#if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND)\n if (abs(float(abs_k) - 1.0) < 0.5) {\n u = COS_TABLE_0_FP64;\n v = SIN_TABLE_0_FP64;\n } else if (abs(float(abs_k) - 2.0) < 0.5) {\n u = COS_TABLE_1_FP64;\n v = SIN_TABLE_1_FP64;\n } else if (abs(float(abs_k) - 3.0) < 0.5) {\n u = COS_TABLE_2_FP64;\n v = SIN_TABLE_2_FP64;\n } else if (abs(float(abs_k) - 4.0) < 0.5) {\n u = COS_TABLE_3_FP64;\n v = SIN_TABLE_3_FP64;\n }\n#else\n if (abs_k == 1) {\n u = COS_TABLE_0_FP64;\n v = SIN_TABLE_0_FP64;\n } else if (abs_k == 2) {\n u = COS_TABLE_1_FP64;\n v = SIN_TABLE_1_FP64;\n } else if (abs_k == 3) {\n u = COS_TABLE_2_FP64;\n v = SIN_TABLE_2_FP64;\n } else if (abs_k == 4) {\n u = COS_TABLE_3_FP64;\n v = SIN_TABLE_3_FP64;\n }\n#endif\n\n vec2 sin_t, cos_t;\n sincos_taylor_fp64(t, sin_t, cos_t);\n\n vec2 result = vec2(0.0, 0.0);\n if (j == 0) {\n if (k > 0) {\n result = sub_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t));\n } else {\n result = sum_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t));\n }\n } else if (j == 1) {\n if (k > 0) {\n result = -sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t));\n } else {\n result = sub_fp64(mul_fp64(v, cos_t), mul_fp64(u, sin_t));\n }\n } else if (j == -1) {\n if (k > 0) {\n result = sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t));\n } else {\n result = sub_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t));\n }\n } else {\n if (k > 0) {\n result = sub_fp64(mul_fp64(v, sin_t), mul_fp64(u, cos_t));\n } else {\n result = -sum_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t));\n }\n }\n\n return result;\n}\n\nvec2 tan_fp64(vec2 a) {\n vec2 sin_a;\n vec2 cos_a;\n\n if (a.x == 0.0 && a.y == 0.0) {\n return vec2(0.0, 0.0);\n }\n\n // 2pi range reduction\n vec2 z = nint_fp64(div_fp64(a, TWO_PI_FP64));\n vec2 r = sub_fp64(a, mul_fp64(TWO_PI_FP64, z));\n\n vec2 t;\n float q = floor(r.x / PI_2_FP64.x + 0.5);\n int j = int(q);\n\n\n if (j < -2 || j > 2) {\n return vec2(0.0 / 0.0, 0.0 / 0.0);\n }\n\n t = sub_fp64(r, mul_fp64(PI_2_FP64, vec2(q, 0.0)));\n\n q = floor(t.x / PI_16_FP64.x + 0.5);\n int k = int(q);\n int abs_k = int(abs(float(k)));\n\n // We just can't get PI/16 * 3.0 very accurately.\n // so let's just store it\n if (abs_k > 4) {\n return vec2(0.0 / 0.0, 0.0 / 0.0);\n } else {\n t = sub_fp64(t, mul_fp64(PI_16_FP64, vec2(q, 0.0)));\n }\n\n\n vec2 u = vec2(0.0, 0.0);\n vec2 v = vec2(0.0, 0.0);\n\n vec2 sin_t, cos_t;\n vec2 s, c;\n sincos_taylor_fp64(t, sin_t, cos_t);\n\n if (k == 0) {\n s = sin_t;\n c = cos_t;\n } else {\n#if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND)\n if (abs(float(abs_k) - 1.0) < 0.5) {\n u = COS_TABLE_0_FP64;\n v = SIN_TABLE_0_FP64;\n } else if (abs(float(abs_k) - 2.0) < 0.5) {\n u = COS_TABLE_1_FP64;\n v = SIN_TABLE_1_FP64;\n } else if (abs(float(abs_k) - 3.0) < 0.5) {\n u = COS_TABLE_2_FP64;\n v = SIN_TABLE_2_FP64;\n } else if (abs(float(abs_k) - 4.0) < 0.5) {\n u = COS_TABLE_3_FP64;\n v = SIN_TABLE_3_FP64;\n }\n#else\n if (abs_k == 1) {\n u = COS_TABLE_0_FP64;\n v = SIN_TABLE_0_FP64;\n } else if (abs_k == 2) {\n u = COS_TABLE_1_FP64;\n v = SIN_TABLE_1_FP64;\n } else if (abs_k == 3) {\n u = COS_TABLE_2_FP64;\n v = SIN_TABLE_2_FP64;\n } else if (abs_k == 4) {\n u = COS_TABLE_3_FP64;\n v = SIN_TABLE_3_FP64;\n }\n#endif\n if (k > 0) {\n s = sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t));\n c = sub_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t));\n } else {\n s = sub_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t));\n c = sum_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t));\n }\n }\n\n if (j == 0) {\n sin_a = s;\n cos_a = c;\n } else if (j == 1) {\n sin_a = c;\n cos_a = -s;\n } else if (j == -1) {\n sin_a = -c;\n cos_a = s;\n } else {\n sin_a = -s;\n cos_a = -c;\n }\n return div_fp64(sin_a, cos_a);\n}\n\nvec2 radians_fp64(vec2 degree) {\n return mul_fp64(degree, PI_180_FP64);\n}\n\nvec2 mix_fp64(vec2 a, vec2 b, float x) {\n vec2 range = sub_fp64(b, a);\n return sum_fp64(a, mul_fp64(range, vec2(x, 0.0)));\n}\n\n// Vector functions\n// vec2 functions\nvoid vec2_sum_fp64(vec2 a[2], vec2 b[2], out vec2 out_val[2]) {\n out_val[0] = sum_fp64(a[0], b[0]);\n out_val[1] = sum_fp64(a[1], b[1]);\n}\n\nvoid vec2_sub_fp64(vec2 a[2], vec2 b[2], out vec2 out_val[2]) {\n out_val[0] = sub_fp64(a[0], b[0]);\n out_val[1] = sub_fp64(a[1], b[1]);\n}\n\nvoid vec2_mul_fp64(vec2 a[2], vec2 b[2], out vec2 out_val[2]) {\n out_val[0] = mul_fp64(a[0], b[0]);\n out_val[1] = mul_fp64(a[1], b[1]);\n}\n\nvoid vec2_div_fp64(vec2 a[2], vec2 b[2], out vec2 out_val[2]) {\n out_val[0] = div_fp64(a[0], b[0]);\n out_val[1] = div_fp64(a[1], b[1]);\n}\n\nvoid vec2_mix_fp64(vec2 x[2], vec2 y[2], float a, out vec2 out_val[2]) {\n vec2 range[2];\n vec2_sub_fp64(y, x, range);\n vec2 portion[2];\n portion[0] = range[0] * a;\n portion[1] = range[1] * a;\n vec2_sum_fp64(x, portion, out_val);\n}\n\nvec2 vec2_length_fp64(vec2 x[2]) {\n return sqrt_fp64(sum_fp64(mul_fp64(x[0], x[0]), mul_fp64(x[1], x[1])));\n}\n\nvoid vec2_normalize_fp64(vec2 x[2], out vec2 out_val[2]) {\n vec2 length = vec2_length_fp64(x);\n vec2 length_vec2[2];\n length_vec2[0] = length;\n length_vec2[1] = length;\n\n vec2_div_fp64(x, length_vec2, out_val);\n}\n\nvec2 vec2_distance_fp64(vec2 x[2], vec2 y[2]) {\n vec2 diff[2];\n vec2_sub_fp64(x, y, diff);\n return vec2_length_fp64(diff);\n}\n\nvec2 vec2_dot_fp64(vec2 a[2], vec2 b[2]) {\n vec2 v[2];\n\n v[0] = mul_fp64(a[0], b[0]);\n v[1] = mul_fp64(a[1], b[1]);\n\n return sum_fp64(v[0], v[1]);\n}\n\n// vec3 functions\nvoid vec3_sub_fp64(vec2 a[3], vec2 b[3], out vec2 out_val[3]) {\n for (int i = 0; i < 3; i++) {\n out_val[i] = sum_fp64(a[i], b[i]);\n }\n}\n\nvoid vec3_sum_fp64(vec2 a[3], vec2 b[3], out vec2 out_val[3]) {\n for (int i = 0; i < 3; i++) {\n out_val[i] = sum_fp64(a[i], b[i]);\n }\n}\n\nvec2 vec3_length_fp64(vec2 x[3]) {\n return sqrt_fp64(sum_fp64(sum_fp64(mul_fp64(x[0], x[0]), mul_fp64(x[1], x[1])),\n mul_fp64(x[2], x[2])));\n}\n\nvec2 vec3_distance_fp64(vec2 x[3], vec2 y[3]) {\n vec2 diff[3];\n vec3_sub_fp64(x, y, diff);\n return vec3_length_fp64(diff);\n}\n\n// vec4 functions\nvoid vec4_fp64(vec4 a, out vec2 out_val[4]) {\n out_val[0].x = a[0];\n out_val[0].y = 0.0;\n\n out_val[1].x = a[1];\n out_val[1].y = 0.0;\n\n out_val[2].x = a[2];\n out_val[2].y = 0.0;\n\n out_val[3].x = a[3];\n out_val[3].y = 0.0;\n}\n\nvoid vec4_scalar_mul_fp64(vec2 a[4], vec2 b, out vec2 out_val[4]) {\n out_val[0] = mul_fp64(a[0], b);\n out_val[1] = mul_fp64(a[1], b);\n out_val[2] = mul_fp64(a[2], b);\n out_val[3] = mul_fp64(a[3], b);\n}\n\nvoid vec4_sum_fp64(vec2 a[4], vec2 b[4], out vec2 out_val[4]) {\n for (int i = 0; i < 4; i++) {\n out_val[i] = sum_fp64(a[i], b[i]);\n }\n}\n\nvoid vec4_dot_fp64(vec2 a[4], vec2 b[4], out vec2 out_val) {\n vec2 v[4];\n\n v[0] = mul_fp64(a[0], b[0]);\n v[1] = mul_fp64(a[1], b[1]);\n v[2] = mul_fp64(a[2], b[2]);\n v[3] = mul_fp64(a[3], b[3]);\n\n out_val = sum_fp64(sum_fp64(v[0], v[1]), sum_fp64(v[2], v[3]));\n}\n\nvoid mat4_vec4_mul_fp64(vec2 b[16], vec2 a[4], out vec2 out_val[4]) {\n vec2 tmp[4];\n\n for (int i = 0; i < 4; i++)\n {\n for (int j = 0; j < 4; j++)\n {\n tmp[j] = b[j + i * 4];\n }\n vec4_dot_fp64(a, tmp, out_val[i]);\n }\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\n\nimport {fp64ify, fp64LowPart, fp64ifyMatrix4} from '../../../modules/math/fp64/fp64-utils';\nimport {fp64arithmeticShader} from './fp64-arithmetic-glsl';\nimport {fp64arithmeticWGSL} from './fp64-arithmetic-wgsl';\nimport {fp64functionShader} from './fp64-functions-glsl';\n\ntype FP64Props = {};\ntype FP64Uniforms = {ONE: number; SPLIT: number};\ntype FP64Bindings = {};\n\ntype FP64Utilities = {\n fp64ify: typeof fp64ify;\n fp64LowPart: typeof fp64LowPart;\n fp64ifyMatrix4: typeof fp64ifyMatrix4;\n};\n\nconst defaultUniforms: FP64Uniforms = {\n // Used in LUMA_FP64_CODE_ELIMINATION_WORKAROUND\n ONE: 1.0,\n // Runtime split factor for Dekker splitting. Keeping this as a uniform helps\n // prevent aggressive constant folding in shader compilers.\n SPLIT: 4097.0\n};\n\n/**\n * 64bit arithmetic: add, sub, mul, div (small subset of fp64 module)\n */\nexport const fp64arithmetic: ShaderModule<FP64Props, FP64Uniforms, FP64Bindings> & FP64Utilities = {\n name: 'fp64arithmetic',\n source: fp64arithmeticWGSL,\n fs: fp64arithmeticShader,\n vs: fp64arithmeticShader,\n defaultUniforms,\n uniformTypes: {ONE: 'f32', SPLIT: 'f32'},\n\n // Additional Functions\n fp64ify,\n fp64LowPart,\n fp64ifyMatrix4\n};\n\n/**\n * Full 64 bit math library\n */\nexport const fp64: ShaderModule<{}> & FP64Utilities = {\n name: 'fp64',\n vs: fp64functionShader,\n dependencies: [fp64arithmetic],\n\n // Additional Functions\n fp64ify,\n fp64LowPart,\n fp64ifyMatrix4\n};\n\nexport {fp64ify, fp64LowPart, fp64ifyMatrix4};\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {ShaderModule} from '../../lib/shader-module/shader-module';\n\nexport type FloatColorsProps = {\n /**\n * When true, semantic colors are interpreted as 0-255 byte-style values and normalized in shader code.\n * When false, semantic colors are interpreted directly as floats.\n */\n useByteColors?: boolean;\n};\n\nexport type FloatColorsUniforms = {\n /** Controls whether shader helpers normalize semantic colors from byte space. */\n useByteColors: boolean;\n};\n\nconst GLSL_UNIFORMS = /* glsl */ `\\\nlayout(std140) uniform floatColorsUniforms {\n float useByteColors;\n} floatColors;\n\nvec3 floatColors_normalize(vec3 inputColor) {\n return floatColors.useByteColors > 0.5 ? inputColor / 255.0 : inputColor;\n}\n\nvec4 floatColors_normalize(vec4 inputColor) {\n return floatColors.useByteColors > 0.5 ? inputColor / 255.0 : inputColor;\n}\n\nvec4 floatColors_premultiplyAlpha(vec4 inputColor) {\n return vec4(inputColor.rgb * inputColor.a, inputColor.a);\n}\n\nvec4 floatColors_unpremultiplyAlpha(vec4 inputColor) {\n return inputColor.a > 0.0 ? vec4(inputColor.rgb / inputColor.a, inputColor.a) : vec4(0.0);\n}\n\nvec4 floatColors_premultiply_alpha(vec4 inputColor) {\n return floatColors_premultiplyAlpha(inputColor);\n}\n\nvec4 floatColors_unpremultiply_alpha(vec4 inputColor) {\n return floatColors_unpremultiplyAlpha(inputColor);\n}\n`;\n\nconst WGSL_UNIFORMS = /* wgsl */ `\\\nstruct floatColorsUniforms {\n useByteColors: f32\n};\n\n@group(0) @binding(auto) var<uniform> floatColors : floatColorsUniforms;\n\nfn floatColors_normalize(inputColor: vec3<f32>) -> vec3<f32> {\n return select(inputColor, inputColor / 255.0, floatColors.useByteColors > 0.5);\n}\n\nfn floatColors_normalize4(inputColor: vec4<f32>) -> vec4<f32> {\n return select(inputColor, inputColor / 255.0, floatColors.useByteColors > 0.5);\n}\n\nfn floatColors_premultiplyAlpha(inputColor: vec4<f32>) -> vec4<f32> {\n return vec4<f32>(inputColor.rgb * inputColor.a, inputColor.a);\n}\n\nfn floatColors_unpremultiplyAlpha(inputColor: vec4<f32>) -> vec4<f32> {\n return select(\n vec4<f32>(0.0),\n vec4<f32>(inputColor.rgb / inputColor.a, inputColor.a),\n inputColor.a > 0.0\n );\n}\n\nfn floatColors_premultiply_alpha(inputColor: vec4<f32>) -> vec4<f32> {\n return floatColors_premultiplyAlpha(inputColor);\n}\n\nfn floatColors_unpremultiply_alpha(inputColor: vec4<f32>) -> vec4<f32> {\n return floatColors_unpremultiplyAlpha(inputColor);\n}\n`;\n\nexport const floatColors = {\n name: 'floatColors',\n props: {} as FloatColorsProps,\n uniforms: {} as FloatColorsUniforms,\n vs: GLSL_UNIFORMS,\n fs: GLSL_UNIFORMS,\n source: WGSL_UNIFORMS,\n uniformTypes: {\n useByteColors: 'f32'\n },\n defaultUniforms: {\n useByteColors: true\n }\n} as const satisfies ShaderModule<FloatColorsProps, FloatColorsUniforms>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\nimport type {NumberArray3, NumberArray4} from '@math.gl/core';\nimport {normalizeByteColor4, resolveUseByteColors} from '../../../lib/color/normalize-byte-colors';\n\n// cyan color\nconst DEFAULT_HIGHLIGHT_COLOR: NumberArray4 = [0, 1, 1, 1];\n\n/**\n * Props for the picking module, which depending on mode renders picking colors or highlighted item.\n * When active, renders picking colors, assumed to be rendered to off-screen \"picking\" buffer.\n * When inactive, renders normal colors, with the exception of selected object which is rendered with highlight\n */\nexport type PickingProps = {\n /** Are we picking? I.e. rendering picking colors? */\n isActive?: boolean;\n /** Set to true when picking an attribute value instead of object index */\n isAttribute?: boolean;\n /** Set to a picking color to visually highlight that item, or `null` to explicitly clear **/\n highlightedObjectColor?: NumberArray3 | null;\n /** Color of visual highlight of \"selected\" item */\n highlightColor?: NumberArray3 | NumberArray4;\n /** Interpret highlight colors as byte-style 0-255 values. */\n useByteColors?: boolean;\n};\n\n/**\n * Uniforms for the picking module, which renders picking colors and highlighted item.\n * When active, renders picking colors, assumed to be rendered to off-screen \"picking\" buffer.\n * When inactive, renders normal colors, with the exception of selected object which is rendered with highlight\n */\nexport type PickingUniforms = {\n /**\n * When true, renders picking colors. Set when rendering to off-screen \"picking\" buffer.\n * When false, renders normal colors, with the exception of selected object which is rendered with highlight\n */\n isActive?: boolean;\n /** Set to true when picking an attribute value instead of object index */\n isAttribute?: boolean;\n /** Interpret highlight colors as byte-style 0-255 values. */\n useByteColors?: boolean;\n /** Do we have a highlighted item? */\n isHighlightActive?: boolean;\n /** Set to a picking color to visually highlight that item */\n highlightedObjectColor?: NumberArray3;\n /** Color of visual highlight of \"selected\" item */\n highlightColor?: NumberArray4;\n};\n\nconst vs = /* glsl */ `\\\nlayout(std140) uniform pickingUniforms {\n float isActive;\n float isAttribute;\n float isHighlightActive;\n float useByteColors;\n vec3 highlightedObjectColor;\n vec4 highlightColor;\n} picking;\n\nout vec4 picking_vRGBcolor_Avalid;\n\n// Normalize unsigned byte color to 0-1 range\nvec3 picking_normalizeColor(vec3 color) {\n return picking.useByteColors > 0.5 ? color / 255.0 : color;\n}\n\n// Normalize unsigned byte color to 0-1 range\nvec4 picking_normalizeColor(vec4 color) {\n return picking.useByteColors > 0.5 ? color / 255.0 : color;\n}\n\nbool picking_isColorZero(vec3 color) {\n return dot(color, vec3(1.0)) < 0.00001;\n}\n\nbool picking_isColorValid(vec3 color) {\n return dot(color, vec3(1.0)) > 0.00001;\n}\n\n// Check if this vertex is highlighted \nbool isVertexHighlighted(vec3 vertexColor) {\n vec3 highlightedObjectColor = picking_normalizeColor(picking.highlightedObjectColor);\n return\n bool(picking.isHighlightActive) && picking_isColorZero(abs(vertexColor - highlightedObjectColor));\n}\n\n// Set the current picking color\nvoid picking_setPickingColor(vec3 pickingColor) {\n pickingColor = picking_normalizeColor(pickingColor);\n\n if (bool(picking.isActive)) {\n // Use alpha as the validity flag. If pickingColor is [0, 0, 0] fragment is non-pickable\n picking_vRGBcolor_Avalid.a = float(picking_isColorValid(pickingColor));\n\n if (!bool(picking.isAttribute)) {\n // Stores the picking color so that the fragment shader can render it during picking\n picking_vRGBcolor_Avalid.rgb = pickingColor;\n }\n } else {\n // Do the comparison with selected item color in vertex shader as it should mean fewer compares\n picking_vRGBcolor_Avalid.a = float(isVertexHighlighted(pickingColor));\n }\n}\n\nvoid picking_setPickingAttribute(float value) {\n if (bool(picking.isAttribute)) {\n picking_vRGBcolor_Avalid.r = value;\n }\n}\n\nvoid picking_setPickingAttribute(vec2 value) {\n if (bool(picking.isAttribute)) {\n picking_vRGBcolor_Avalid.rg = value;\n }\n}\n\nvoid picking_setPickingAttribute(vec3 value) {\n if (bool(picking.isAttribute)) {\n picking_vRGBcolor_Avalid.rgb = value;\n }\n}\n`;\n\nconst fs = /* glsl */ `\\\nlayout(std140) uniform pickingUniforms {\n float isActive;\n float isAttribute;\n float isHighlightActive;\n float useByteColors;\n vec3 highlightedObjectColor;\n vec4 highlightColor;\n} picking;\n\nin vec4 picking_vRGBcolor_Avalid;\n\n/*\n * Returns highlight color if this item is selected.\n */\nvec4 picking_filterHighlightColor(vec4 color) {\n // If we are still picking, we don't highlight\n if (picking.isActive > 0.5) {\n return color;\n }\n\n bool selected = bool(picking_vRGBcolor_Avalid.a);\n\n if (selected) {\n // Blend in highlight color based on its alpha value\n float highLightAlpha = picking.highlightColor.a;\n float blendedAlpha = highLightAlpha + color.a * (1.0 - highLightAlpha);\n float highLightRatio = highLightAlpha / blendedAlpha;\n\n vec3 blendedRGB = mix(color.rgb, picking.highlightColor.rgb, highLightRatio);\n return vec4(blendedRGB, blendedAlpha);\n } else {\n return color;\n }\n}\n\n/*\n * Returns picking color if picking enabled else unmodified argument.\n */\nvec4 picking_filterPickingColor(vec4 color) {\n if (bool(picking.isActive)) {\n if (picking_vRGBcolor_Avalid.a == 0.0) {\n discard;\n }\n return picking_vRGBcolor_Avalid;\n }\n return color;\n}\n\n/*\n * Returns picking color if picking is enabled if not\n * highlight color if this item is selected, otherwise unmodified argument.\n */\nvec4 picking_filterColor(vec4 color) {\n vec4 highlightColor = picking_filterHighlightColor(color);\n return picking_filterPickingColor(highlightColor);\n}\n`;\n\n/**\n * Deprecated legacy picking module retained for compatibility with existing\n * shadertools users such as deck.gl. Keep the shader contract stable.\n *\n * Provides support for color-coding-based picking and highlighting.\n * In particular, supports picking a specific instance in an instanced\n * draw call and highlighting an instance based on its picking color,\n * and correspondingly, supports picking and highlighting groups of\n * primitives with the same picking color in non-instanced draw-calls\n */\nexport const picking = {\n props: {} as PickingProps,\n uniforms: {} as PickingUniforms,\n\n name: 'picking',\n\n uniformTypes: {\n isActive: 'f32',\n isAttribute: 'f32',\n isHighlightActive: 'f32',\n useByteColors: 'f32',\n highlightedObjectColor: 'vec3<f32>',\n highlightColor: 'vec4<f32>'\n },\n defaultUniforms: {\n isActive: false,\n isAttribute: false,\n isHighlightActive: false,\n useByteColors: true,\n highlightedObjectColor: [0, 0, 0],\n highlightColor: DEFAULT_HIGHLIGHT_COLOR\n },\n\n vs,\n fs,\n getUniforms\n} as const satisfies ShaderModule<PickingProps, PickingUniforms>;\n\nfunction getUniforms(opts: PickingProps = {}, prevUniforms?: PickingUniforms): PickingUniforms {\n const uniforms = {} as PickingUniforms;\n const useByteColors = resolveUseByteColors(opts.useByteColors, true);\n\n if (opts.highlightedObjectColor === undefined) {\n // Unless highlightedObjectColor explicitly null or set, do not update state\n } else if (opts.highlightedObjectColor === null) {\n uniforms.isHighlightActive = false;\n } else {\n uniforms.isHighlightActive = true;\n const highlightedObjectColor = opts.highlightedObjectColor.slice(0, 3) as NumberArray3;\n uniforms.highlightedObjectColor = highlightedObjectColor;\n }\n\n if (opts.highlightColor) {\n uniforms.highlightColor = normalizeByteColor4(opts.highlightColor, useByteColors);\n }\n\n if (opts.isActive !== undefined) {\n uniforms.isActive = Boolean(opts.isActive);\n uniforms.isAttribute = Boolean(opts.isAttribute);\n }\n\n if (opts.useByteColors !== undefined) {\n uniforms.useByteColors = Boolean(opts.useByteColors);\n }\n\n return uniforms;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Matrix4} from '@math.gl/core';\n\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\n\nconst SKIN_MAX_JOINTS = 20;\n\nexport const source = /* wgsl */ `\nstruct skinUniforms {\n jointMatrix: array<mat4x4<f32>, ${SKIN_MAX_JOINTS}>,\n};\n\n@group(0) @binding(auto) var<uniform> skin: skinUniforms;\n\nfn getSkinMatrix(weights: vec4f, joints: vec4u) -> mat4x4<f32> {\n return (weights.x * skin.jointMatrix[joints.x])\n + (weights.y * skin.jointMatrix[joints.y])\n + (weights.z * skin.jointMatrix[joints.z])\n + (weights.w * skin.jointMatrix[joints.w]);\n}\n`;\n\nexport const vs = /* glsl */ `\\\n\nlayout(std140) uniform skinUniforms {\n mat4 jointMatrix[SKIN_MAX_JOINTS];\n} skin;\n\nmat4 getSkinMatrix(vec4 weights, uvec4 joints) {\n return (weights.x * skin.jointMatrix[joints.x])\n + (weights.y * skin.jointMatrix[joints.y])\n + (weights.z * skin.jointMatrix[joints.z])\n + (weights.w * skin.jointMatrix[joints.w]);\n}\n\n`;\n\nexport const fs = /* glsl */ `\\\n`;\n\nexport type SkinProps = {\n scenegraphsFromGLTF?: any;\n};\n\nexport type SkinUniforms = {\n jointMatrix?: any;\n};\n\nexport const skin = {\n props: {} as SkinProps,\n uniforms: {} as SkinUniforms,\n\n name: 'skin',\n bindingLayout: [{name: 'skin', group: 0}],\n dependencies: [],\n source,\n vs,\n fs,\n\n defines: {\n SKIN_MAX_JOINTS\n },\n\n getUniforms: (props: SkinProps = {}, prevUniforms?: SkinUniforms): SkinUniforms => {\n const {scenegraphsFromGLTF} = props;\n\n if (!scenegraphsFromGLTF?.gltf?.skins?.[0]) {\n return {jointMatrix: []};\n }\n\n const {inverseBindMatrices, joints, skeleton} = scenegraphsFromGLTF.gltf.skins[0];\n\n const matsib = [];\n const countib = inverseBindMatrices.value.length / 16;\n for (let i = 0; i < countib; i++) {\n const slice = inverseBindMatrices.value.subarray(i * 16, i * 16 + 16);\n matsib.push(new Matrix4(Array.from(slice)));\n }\n\n const top = scenegraphsFromGLTF.gltfNodeIndexToNodeMap.get(skeleton);\n const matrices: Record<string, Matrix4> = {};\n top.preorderTraversal((node: any, {worldMatrix}: any) => {\n matrices[node.id] = worldMatrix;\n });\n\n const mats = new Float32Array(SKIN_MAX_JOINTS * 16); // 16 floats per 4x4 matrix\n for (let i = 0; i < SKIN_MAX_JOINTS; ++i) {\n const nodeIndex = joints[i];\n if (nodeIndex === undefined) break;\n\n const worldMat = matrices[scenegraphsFromGLTF.gltfNodeIndexToNodeMap.get(nodeIndex).id];\n const invBindMat = matsib[i];\n\n const Z = new Matrix4().copy(worldMat).multiplyRight(invBindMat);\n\n const off = i * 16;\n\n for (let j = 0; j < 16; j++) {\n mats[off + j] = Z[j];\n }\n }\n\n return {\n jointMatrix: mats\n };\n },\n\n uniformTypes: {\n jointMatrix: ['mat4x4<f32>', SKIN_MAX_JOINTS]\n }\n} as const satisfies ShaderModule<SkinProps, SkinUniforms>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {log} from '@luma.gl/core';\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\nimport {lightingUniformsGLSL} from './lighting-glsl';\nimport {lightingUniformsWGSL} from './lighting-wgsl';\nimport type {NumberArray2, NumberArray3} from '@math.gl/core';\nimport {normalizeByteColor3, resolveUseByteColors} from '../../../lib/color/normalize-byte-colors';\n\n/** Max number of supported lights (in addition to ambient light */\nconst MAX_LIGHTS = 5;\n\n/** Supported light source descriptions accepted by the lighting shader module. */\nexport type Light = AmbientLight | PointLight | SpotLight | DirectionalLight;\n\n/** Ambient light contribution shared across the entire scene. */\nexport type AmbientLight = {\n /** Discriminator used to identify ambient lights in `lights: Light[]`. */\n type: 'ambient';\n /** RGB light color in the existing `0..255` convention used by luma.gl materials. */\n color?: Readonly<NumberArray3>;\n /** Scalar intensity multiplier applied to the light color. */\n intensity?: number;\n};\n\n/** Omnidirectional point light emitted from a world-space position. */\nexport type PointLight = {\n /** Discriminator used to identify point lights in `lights: Light[]`. */\n type: 'point';\n /** World-space light position. */\n position: Readonly<NumberArray3>;\n /** RGB light color in the existing `0..255` convention used by luma.gl materials. */\n color?: Readonly<NumberArray3>;\n /** Scalar intensity multiplier applied to the light color. */\n intensity?: number;\n /** Constant, linear, and quadratic attenuation coefficients. */\n attenuation?: Readonly<NumberArray3>;\n};\n\n/** Directional light defined only by its incoming world-space direction. */\nexport type DirectionalLight = {\n /** Discriminator used to identify directional lights in `lights: Light[]`. */\n type: 'directional';\n /** World-space light direction. */\n direction: Readonly<NumberArray3>;\n /** RGB light color in the existing `0..255` convention used by luma.gl materials. */\n color?: Readonly<NumberArray3>;\n /** Scalar intensity multiplier applied to the light color. */\n intensity?: number;\n};\n\n/** Cone-shaped light emitted from a position and focused along a direction. */\nexport type SpotLight = {\n /** Discriminator used to identify spot lights in `lights: Light[]`. */\n type: 'spot';\n /** World-space light position. */\n position: Readonly<NumberArray3>;\n /** World-space light direction. */\n direction: Readonly<NumberArray3>;\n /** RGB light color in the existing `0..255` convention used by luma.gl materials. */\n color?: Readonly<NumberArray3>;\n /** Scalar intensity multiplier applied to the light color. */\n intensity?: number;\n /** Constant, linear, and quadratic attenuation coefficients. */\n attenuation?: Readonly<NumberArray3>;\n /** Inner spotlight cone angle in radians. */\n innerConeAngle?: number;\n /** Outer spotlight cone angle in radians. */\n outerConeAngle?: number;\n};\n\n/** Public JavaScript props accepted by the `lighting` shader module. */\nexport type LightingProps = {\n /** Enables or disables lighting calculations for the module. */\n enabled?: boolean;\n /** When true, light colors are interpreted as byte-style 0-255 values. */\n useByteColors?: boolean;\n /** Preferred API for supplying mixed ambient, point, spot, and directional lights. */\n lights?: Light[];\n /**\n * Legacy ambient-light prop.\n * @deprecated Use `lights` with `{type: 'ambient', ...}` entries instead.\n */\n ambientLight?: AmbientLight;\n /**\n * Legacy point-light prop.\n * @deprecated Use `lights` with `{type: 'point', ...}` entries instead.\n */\n pointLights?: PointLight[];\n /**\n * Legacy spot-light prop.\n * @deprecated Use `lights` with `{type: 'spot', ...}` entries instead.\n */\n spotLights?: SpotLight[];\n /**\n * Legacy directional-light prop.\n * @deprecated Use `lights` with `{type: 'directional', ...}` entries instead.\n */\n directionalLights?: DirectionalLight[];\n};\n\n/** Packed per-light data written into the module's fixed-size uniform array. */\nexport type LightingLightUniform = {\n /** Light color converted to normalized shader-space RGB. */\n color: Readonly<NumberArray3>;\n /** World-space light position or a default placeholder for non-positional lights. */\n position: Readonly<NumberArray3>;\n /** World-space light direction or a default placeholder for positional lights. */\n direction: Readonly<NumberArray3>;\n /** Constant, linear, and quadratic attenuation coefficients. */\n attenuation: Readonly<NumberArray3>;\n /** Cosines of the inner and outer spotlight cone angles. */\n coneCos: Readonly<NumberArray2>;\n};\n\n/** Fully normalized uniform values produced by the `lighting` shader module. */\nexport type LightingUniforms = {\n /** `1` when lighting is enabled, otherwise `0`. */\n enabled: number;\n /** Number of packed directional lights in the `lights` array. */\n directionalLightCount: number;\n /** Number of packed point lights in the `lights` array. */\n pointLightCount: number;\n /** Number of packed spot lights in the `lights` array. */\n spotLightCount: number;\n /** Accumulated ambient color converted to normalized shader-space RGB. */\n ambientColor: Readonly<NumberArray3>;\n /** Packed trailing array of non-ambient light structs. */\n lights: ReadonlyArray<LightingLightUniform>;\n};\n\nconst LIGHT_UNIFORM_TYPE = {\n color: 'vec3<f32>',\n position: 'vec3<f32>',\n direction: 'vec3<f32>',\n attenuation: 'vec3<f32>',\n coneCos: 'vec2<f32>'\n} as const;\n\n/**\n * Portable lighting shader module shared by the Phong, Gouraud, and PBR material modules.\n *\n * The public JavaScript API accepts `lights: Light[]`, while the uniform buffer packs\n * non-ambient lights into a fixed-size trailing array for portability across WebGL2 and WebGPU.\n */\nexport const lighting = {\n props: {} as LightingProps,\n uniforms: {} as LightingUniforms,\n\n name: 'lighting',\n\n defines: {\n // MAX_LIGHTS\n },\n\n uniformTypes: {\n enabled: 'i32',\n directionalLightCount: 'i32',\n pointLightCount: 'i32',\n spotLightCount: 'i32',\n ambientColor: 'vec3<f32>',\n lights: [LIGHT_UNIFORM_TYPE, MAX_LIGHTS]\n },\n\n defaultUniforms: createDefaultLightingUniforms(),\n bindingLayout: [{name: 'lighting', group: 2}],\n firstBindingSlot: 0,\n source: lightingUniformsWGSL,\n vs: lightingUniformsGLSL,\n fs: lightingUniformsGLSL,\n\n getUniforms\n} as const satisfies ShaderModule<LightingProps, LightingUniforms, {}>;\n\nfunction getUniforms(\n props?: LightingProps,\n _prevUniforms: Partial<LightingUniforms> = {}\n): LightingUniforms {\n // Copy props so we can modify\n props = props ? {...props} : props;\n\n // TODO legacy\n if (!props) {\n return createDefaultLightingUniforms();\n }\n // Support for array of lights. Type of light is detected by type field\n if (props.lights) {\n props = {...props, ...extractLightTypes(props.lights), lights: undefined};\n }\n\n // Specify lights separately\n const {useByteColors, ambientLight, pointLights, spotLights, directionalLights} = props || {};\n const hasLights =\n ambientLight ||\n (pointLights && pointLights.length > 0) ||\n (spotLights && spotLights.length > 0) ||\n (directionalLights && directionalLights.length > 0);\n\n // TODO - this may not be the correct decision\n if (!hasLights) {\n return {\n ...createDefaultLightingUniforms(),\n enabled: 0\n };\n }\n\n const uniforms = {\n ...createDefaultLightingUniforms(),\n ...getLightSourceUniforms({\n useByteColors,\n ambientLight,\n pointLights,\n spotLights,\n directionalLights\n })\n };\n\n if (props.enabled !== undefined) {\n uniforms.enabled = props.enabled ? 1 : 0;\n }\n\n return uniforms;\n}\n\nfunction getLightSourceUniforms({\n useByteColors,\n ambientLight,\n pointLights = [],\n spotLights = [],\n directionalLights = []\n}: LightingProps): Omit<LightingUniforms, 'enabled'> {\n const lights = createDefaultLightUniforms();\n\n let currentLight = 0;\n let pointLightCount = 0;\n let spotLightCount = 0;\n let directionalLightCount = 0;\n\n for (const pointLight of pointLights) {\n if (currentLight >= MAX_LIGHTS) {\n break;\n }\n\n lights[currentLight] = {\n ...lights[currentLight],\n color: convertColor(pointLight, useByteColors),\n position: pointLight.position,\n attenuation: pointLight.attenuation || [1, 0, 0]\n };\n currentLight++;\n pointLightCount++;\n }\n\n for (const spotLight of spotLights) {\n if (currentLight >= MAX_LIGHTS) {\n break;\n }\n\n lights[currentLight] = {\n ...lights[currentLight],\n color: convertColor(spotLight, useByteColors),\n position: spotLight.position,\n direction: spotLight.direction,\n attenuation: spotLight.attenuation || [1, 0, 0],\n coneCos: getSpotConeCos(spotLight)\n };\n currentLight++;\n spotLightCount++;\n }\n\n for (const directionalLight of directionalLights) {\n if (currentLight >= MAX_LIGHTS) {\n break;\n }\n\n lights[currentLight] = {\n ...lights[currentLight],\n color: convertColor(directionalLight, useByteColors),\n direction: directionalLight.direction\n };\n currentLight++;\n directionalLightCount++;\n }\n\n if (pointLights.length + spotLights.length + directionalLights.length > MAX_LIGHTS) {\n log.warn(`MAX_LIGHTS exceeded, truncating to ${MAX_LIGHTS}`)();\n }\n\n return {\n ambientColor: convertColor(ambientLight, useByteColors),\n directionalLightCount,\n pointLightCount,\n spotLightCount,\n lights\n };\n}\n\nfunction extractLightTypes(lights: Light[]): LightingProps {\n const lightSources: LightingProps = {pointLights: [], spotLights: [], directionalLights: []};\n for (const light of lights || []) {\n switch (light.type) {\n case 'ambient':\n // Note: Only uses last ambient light\n // TODO - add ambient light sources on CPU?\n lightSources.ambientLight = light;\n break;\n case 'directional':\n lightSources.directionalLights?.push(light);\n break;\n case 'point':\n lightSources.pointLights?.push(light);\n break;\n case 'spot':\n lightSources.spotLights?.push(light);\n break;\n default:\n // eslint-disable-next-line\n // console.warn(light.type);\n }\n }\n return lightSources;\n}\n\n/** Take color 0-255 and intensity as input and output 0.0-1.0 range */\nfunction convertColor(\n colorDef: {color?: Readonly<NumberArray3>; intensity?: number} = {},\n useByteColors?: boolean\n): NumberArray3 {\n const {color = [0, 0, 0], intensity = 1.0} = colorDef;\n const normalizedColor = normalizeByteColor3(color, resolveUseByteColors(useByteColors, true));\n return normalizedColor.map(component => component * intensity) as NumberArray3;\n}\n\nfunction createDefaultLightingUniforms(): LightingUniforms {\n return {\n enabled: 1,\n directionalLightCount: 0,\n pointLightCount: 0,\n spotLightCount: 0,\n ambientColor: [0.1, 0.1, 0.1],\n lights: createDefaultLightUniforms()\n };\n}\n\nfunction createDefaultLightUniforms(): LightingLightUniform[] {\n return Array.from({length: MAX_LIGHTS}, () => createDefaultLightUniform());\n}\n\nfunction createDefaultLightUniform(): LightingLightUniform {\n return {\n color: [1, 1, 1],\n position: [1, 1, 2],\n direction: [1, 1, 1],\n attenuation: [1, 0, 0],\n coneCos: [1, 0]\n };\n}\n\nfunction getSpotConeCos(spotLight: SpotLight): NumberArray2 {\n const innerConeAngle = spotLight.innerConeAngle ?? 0;\n const outerConeAngle = spotLight.outerConeAngle ?? Math.PI / 4;\n return [Math.cos(innerConeAngle), Math.cos(outerConeAngle)];\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const lightingUniformsGLSL = /* glsl */ `\\\nprecision 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 SpotLight {\n vec3 color;\n vec3 position;\n vec3 direction;\n vec3 attenuation;\n vec2 coneCos;\n};\n\nstruct DirectionalLight {\n vec3 color;\n vec3 direction;\n};\n\nstruct UniformLight {\n vec3 color;\n vec3 position;\n vec3 direction;\n vec3 attenuation;\n vec2 coneCos;\n};\n\nlayout(std140) uniform lightingUniforms {\n int enabled;\n int directionalLightCount;\n int pointLightCount;\n int spotLightCount;\n vec3 ambientColor;\n UniformLight lights[5];\n} lighting;\n\nPointLight lighting_getPointLight(int index) {\n UniformLight light = lighting.lights[index];\n return PointLight(light.color, light.position, light.attenuation);\n}\n\nSpotLight lighting_getSpotLight(int index) {\n UniformLight light = lighting.lights[lighting.pointLightCount + index];\n return SpotLight(light.color, light.position, light.direction, light.attenuation, light.coneCos);\n}\n\nDirectionalLight lighting_getDirectionalLight(int index) {\n UniformLight light =\n lighting.lights[lighting.pointLightCount + lighting.spotLightCount + index];\n return DirectionalLight(light.color, light.direction);\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\nfloat getSpotLightAttenuation(SpotLight spotLight, vec3 positionWorldspace) {\n vec3 light_direction = normalize(positionWorldspace - spotLight.position);\n float coneFactor = smoothstep(\n spotLight.coneCos.y,\n spotLight.coneCos.x,\n dot(normalize(spotLight.direction), light_direction)\n );\n float distanceAttenuation = getPointLightAttenuation(\n PointLight(spotLight.color, spotLight.position, spotLight.attenuation),\n distance(spotLight.position, positionWorldspace)\n );\n return distanceAttenuation / max(coneFactor, 0.0001);\n}\n\n// #endif\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const lightingUniformsWGSL = /* wgsl */ `\\\n// #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX))\nconst MAX_LIGHTS: i32 = 5;\n\nstruct AmbientLight {\n color: vec3<f32>,\n};\n\nstruct PointLight {\n color: vec3<f32>,\n position: vec3<f32>,\n attenuation: vec3<f32>, // 2nd order x:Constant-y:Linear-z:Exponential\n};\n\nstruct SpotLight {\n color: vec3<f32>,\n position: vec3<f32>,\n direction: vec3<f32>,\n attenuation: vec3<f32>,\n coneCos: vec2<f32>,\n};\n\nstruct DirectionalLight {\n color: vec3<f32>,\n direction: vec3<f32>,\n};\n\nstruct UniformLight {\n color: vec3<f32>,\n position: vec3<f32>,\n direction: vec3<f32>,\n attenuation: vec3<f32>,\n coneCos: vec2<f32>,\n};\n\nstruct lightingUniforms {\n enabled: i32,\n directionalLightCount: i32,\n pointLightCount: i32,\n spotLightCount: i32,\n ambientColor: vec3<f32>,\n lights: array<UniformLight, 5>,\n};\n\n@group(2) @binding(auto) var<uniform> lighting : lightingUniforms;\n\nfn lighting_getPointLight(index: i32) -> PointLight {\n let light = lighting.lights[index];\n return PointLight(light.color, light.position, light.attenuation);\n}\n\nfn lighting_getSpotLight(index: i32) -> SpotLight {\n let light = lighting.lights[lighting.pointLightCount + index];\n return SpotLight(light.color, light.position, light.direction, light.attenuation, light.coneCos);\n}\n\nfn lighting_getDirectionalLight(index: i32) -> DirectionalLight {\n let light = lighting.lights[lighting.pointLightCount + lighting.spotLightCount + index];\n return DirectionalLight(light.color, light.direction);\n}\n\nfn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {\n return pointLight.attenuation.x\n + pointLight.attenuation.y * distance\n + pointLight.attenuation.z * distance * distance;\n}\n\nfn getSpotLightAttenuation(spotLight: SpotLight, positionWorldspace: vec3<f32>) -> f32 {\n let lightDirection = normalize(positionWorldspace - spotLight.position);\n let coneFactor = smoothstep(\n spotLight.coneCos.y,\n spotLight.coneCos.x,\n dot(normalize(spotLight.direction), lightDirection)\n );\n let distanceAttenuation = getPointLightAttenuation(\n PointLight(spotLight.color, spotLight.position, spotLight.attenuation),\n distance(spotLight.position, positionWorldspace)\n );\n return distanceAttenuation / max(coneFactor, 0.0001);\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {Texture} from '@luma.gl/core';\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\n\nexport type IBLBindings = {\n pbr_diffuseEnvSampler?: Texture | null;\n pbr_specularEnvSampler?: Texture | null;\n pbr_brdfLUT?: Texture | null;\n};\n\nexport const iblWGSL = /* wgsl */ `\\\n#ifdef USE_IBL\n@group(2) @binding(auto) var pbr_diffuseEnvSampler: texture_cube<f32>;\n@group(2) @binding(auto) var pbr_diffuseEnvSamplerSampler: sampler;\n@group(2) @binding(auto) var pbr_specularEnvSampler: texture_cube<f32>;\n@group(2) @binding(auto) var pbr_specularEnvSamplerSampler: sampler;\n@group(2) @binding(auto) var pbr_brdfLUT: texture_2d<f32>;\n@group(2) @binding(auto) var pbr_brdfLUTSampler: sampler;\n#endif\n`;\n\nexport const iblGLSL = /* glsl */ `\\\n#ifdef USE_IBL\nuniform samplerCube pbr_diffuseEnvSampler;\nuniform samplerCube pbr_specularEnvSampler;\nuniform sampler2D pbr_brdfLUT;\n#endif\n`;\n\nexport const ibl = {\n name: 'ibl',\n firstBindingSlot: 32,\n bindingLayout: [\n {name: 'pbr_diffuseEnvSampler', group: 2},\n {name: 'pbr_specularEnvSampler', group: 2},\n {name: 'pbr_brdfLUT', group: 2}\n ],\n source: iblWGSL,\n vs: iblGLSL,\n fs: iblGLSL\n} as const satisfies ShaderModule<IBLBindings, {}, IBLBindings>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {NumberArray3} from '@math.gl/core';\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\n\nexport type DirlightProps = {\n lightDirection?: NumberArray3;\n};\n\nexport type DirlightUniforms = DirlightProps;\n\n// TODO\nexport const SOURCE_WGSL = /* WGSL */ `\\\nstruct dirlightUniforms {\n lightDirection: vec3<f32>,\n};\n\nalias DirlightNormal = vec3<f32>;\n\nstruct DirlightInputs {\n normal: DirlightNormal,\n};\n\n@group(2) @binding(auto) var<uniform> dirlight : dirlightUniforms;\n\n// For vertex\nfn dirlight_setNormal(normal: vec3<f32>) -> DirlightNormal {\n return normalize(normal);\n}\n\n// Returns color attenuated by angle from light source\nfn dirlight_filterColor(color: vec4<f32>, inputs: DirlightInputs) -> vec4<f32> {\n // TODO - fix default light direction\n // let lightDirection = dirlight.lightDirection;\n let lightDirection = vec3<f32>(1, 1, 1);\n let d: f32 = abs(dot(inputs.normal, normalize(lightDirection)));\n return vec4<f32>(color.rgb * d, color.a);\n}\n`;\n\nconst VS_GLSL = /* glsl */ `\\\nout vec3 dirlight_vNormal;\n\nvoid dirlight_setNormal(vec3 normal) {\n dirlight_vNormal = normalize(normal);\n}\n`;\n\nconst FS_GLSL = /* glsl */ `\\\nlayout(std140) uniform dirlightUniforms {\n vec3 lightDirection;\n} dirlight;\n\nin vec3 dirlight_vNormal;\n\n// Returns color attenuated by angle from light source\nvec4 dirlight_filterColor(vec4 color) {\n float d = abs(dot(dirlight_vNormal, normalize(dirlight.lightDirection)));\n return vec4(color.rgb * d, color.a);\n}\n`;\n\n/**\n * Cheap lighting - single directional light, single dot product, one uniform\n */\nexport const dirlight = {\n props: {} as DirlightProps,\n uniforms: {} as DirlightUniforms,\n\n name: 'dirlight',\n bindingLayout: [{name: 'dirlight', group: 2}],\n firstBindingSlot: 16,\n dependencies: [],\n source: SOURCE_WGSL,\n vs: VS_GLSL,\n fs: FS_GLSL,\n\n // fragmentInputs: [\n // {\n // name: 'dirlight_vNormal',\n // type: 'vec3<f32>'\n // }\n // ],\n uniformTypes: {\n lightDirection: 'vec3<f32>'\n },\n defaultUniforms: {\n lightDirection: [1, 1, 2]\n },\n getUniforms\n} as const satisfies ShaderModule<DirlightProps, DirlightUniforms>;\n\nfunction getUniforms(opts: DirlightProps = dirlight.defaultUniforms): DirlightUniforms {\n const uniforms: DirlightUniforms = {};\n if (opts.lightDirection) {\n uniforms.lightDirection = opts.lightDirection;\n }\n return uniforms;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const LAMBERT_WGSL = /* wgsl */ `\\\nstruct lambertMaterialUniforms {\n unlit: u32,\n ambient: f32,\n diffuse: f32,\n};\n\n@group(3) @binding(auto) var<uniform> lambertMaterial : lambertMaterialUniforms;\n\nfn lighting_getLightColor(surfaceColor: vec3<f32>, light_direction: vec3<f32>, normal_worldspace: vec3<f32>, color: vec3<f32>) -> vec3<f32> {\n let lambertian: f32 = max(dot(light_direction, normal_worldspace), 0.0);\n return lambertian * lambertMaterial.diffuse * surfaceColor * color;\n}\n\nfn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, position_worldspace: vec3<f32>, normal_worldspace: vec3<f32>) -> vec3<f32> {\n var lightColor: vec3<f32> = surfaceColor;\n\n if (lambertMaterial.unlit != 0u) {\n return surfaceColor;\n }\n\n if (lighting.enabled == 0) {\n return lightColor;\n }\n\n lightColor = lambertMaterial.ambient * surfaceColor * lighting.ambientColor;\n\n for (var i: i32 = 0; i < lighting.pointLightCount; i++) {\n let pointLight: PointLight = lighting_getPointLight(i);\n let light_position_worldspace: vec3<f32> = pointLight.position;\n let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);\n let light_attenuation = getPointLightAttenuation(\n pointLight,\n distance(light_position_worldspace, position_worldspace)\n );\n lightColor += lighting_getLightColor(\n surfaceColor,\n light_direction,\n normal_worldspace,\n pointLight.color / light_attenuation\n );\n }\n\n for (var i: i32 = 0; i < lighting.spotLightCount; i++) {\n let spotLight: SpotLight = lighting_getSpotLight(i);\n let light_position_worldspace: vec3<f32> = spotLight.position;\n let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);\n let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);\n lightColor += lighting_getLightColor(\n surfaceColor,\n light_direction,\n normal_worldspace,\n spotLight.color / light_attenuation\n );\n }\n\n for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {\n let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);\n lightColor += lighting_getLightColor(\n surfaceColor,\n -directionalLight.direction,\n normal_worldspace,\n directionalLight.color\n );\n }\n\n return lightColor;\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const LAMBERT_VS = /* glsl */ `\\\nlayout(std140) uniform lambertMaterialUniforms {\n uniform bool unlit;\n uniform float ambient;\n uniform float diffuse;\n} material;\n`;\n\nexport const LAMBERT_FS = /* glsl */ `\\\nlayout(std140) uniform lambertMaterialUniforms {\n uniform bool unlit;\n uniform float ambient;\n uniform float diffuse;\n} material;\n\nvec3 lighting_getLightColor(vec3 surfaceColor, vec3 light_direction, vec3 normal_worldspace, vec3 color) {\n float lambertian = max(dot(light_direction, normal_worldspace), 0.0);\n return lambertian * material.diffuse * surfaceColor * color;\n}\n\nvec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) {\n vec3 lightColor = surfaceColor;\n\n if (material.unlit) {\n return surfaceColor;\n }\n\n if (lighting.enabled == 0) {\n return lightColor;\n }\n\n lightColor = material.ambient * surfaceColor * lighting.ambientColor;\n\n for (int i = 0; i < lighting.pointLightCount; i++) {\n PointLight pointLight = lighting_getPointLight(i);\n vec3 light_position_worldspace = pointLight.position;\n vec3 light_direction = normalize(light_position_worldspace - position_worldspace);\n float light_attenuation = getPointLightAttenuation(pointLight, distance(light_position_worldspace, position_worldspace));\n lightColor += lighting_getLightColor(surfaceColor, light_direction, normal_worldspace, pointLight.color / light_attenuation);\n }\n\n for (int i = 0; i < lighting.spotLightCount; i++) {\n SpotLight spotLight = lighting_getSpotLight(i);\n vec3 light_position_worldspace = spotLight.position;\n vec3 light_direction = normalize(light_position_worldspace - position_worldspace);\n float light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);\n lightColor += lighting_getLightColor(surfaceColor, light_direction, normal_worldspace, spotLight.color / light_attenuation);\n }\n\n for (int i = 0; i < lighting.directionalLightCount; i++) {\n DirectionalLight directionalLight = lighting_getDirectionalLight(i);\n lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, normal_worldspace, directionalLight.color);\n }\n\n return lightColor;\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\nimport {lighting} from '../lights/lighting';\nimport {LAMBERT_WGSL} from './lambert-shaders-wgsl';\nimport {LAMBERT_VS, LAMBERT_FS} from './lambert-shaders-glsl';\n\n/** Uniform props for the built-in diffuse-only Lambert material model. */\nexport type LambertMaterialProps = {\n unlit?: boolean;\n ambient?: number;\n diffuse?: number;\n};\n\n/** A matte material model that applies diffuse-only Lambert lighting per fragment. */\nexport const lambertMaterial: ShaderModule<LambertMaterialProps> = {\n name: 'lambertMaterial',\n firstBindingSlot: 0,\n bindingLayout: [{name: 'lambertMaterial', group: 3}],\n dependencies: [lighting],\n source: LAMBERT_WGSL,\n vs: LAMBERT_VS,\n fs: LAMBERT_FS,\n defines: {\n LIGHTING_FRAGMENT: true\n },\n uniformTypes: {\n unlit: 'i32',\n ambient: 'f32',\n diffuse: 'f32'\n },\n defaultUniforms: {\n unlit: false,\n ambient: 0.35,\n diffuse: 0.6\n },\n getUniforms(props?: LambertMaterialProps) {\n return {...lambertMaterial.defaultUniforms, ...props};\n }\n};\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const PHONG_VS = /* glsl */ `\\\nlayout(std140) uniform phongMaterialUniforms {\n uniform bool unlit;\n uniform float ambient;\n uniform float diffuse;\n uniform float shininess;\n uniform vec3 specularColor;\n} material;\n`;\n\nexport const PHONG_FS = /* glsl */ `\\\nlayout(std140) uniform phongMaterialUniforms {\n uniform bool unlit;\n uniform float ambient;\n uniform float diffuse;\n uniform float shininess;\n uniform vec3 specularColor;\n} material;\n\nvec3 lighting_getLightColor(vec3 surfaceColor, vec3 light_direction, vec3 view_direction, vec3 normal_worldspace, vec3 color) {\n vec3 halfway_direction = normalize(light_direction + view_direction);\n float lambertian = dot(light_direction, normal_worldspace);\n float specular = 0.0;\n if (lambertian > 0.0) {\n float specular_angle = max(dot(normal_worldspace, halfway_direction), 0.0);\n specular = pow(specular_angle, material.shininess);\n }\n lambertian = max(lambertian, 0.0);\n return (lambertian * material.diffuse * surfaceColor + specular * material.specularColor) * color;\n}\n\nvec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) {\n vec3 lightColor = surfaceColor;\n\n if (material.unlit) {\n return surfaceColor;\n }\n\n if (lighting.enabled == 0) {\n return lightColor;\n }\n\n vec3 view_direction = normalize(cameraPosition - position_worldspace);\n lightColor = material.ambient * surfaceColor * lighting.ambientColor;\n\n for (int i = 0; i < lighting.pointLightCount; i++) {\n PointLight pointLight = lighting_getPointLight(i);\n vec3 light_position_worldspace = pointLight.position;\n vec3 light_direction = normalize(light_position_worldspace - position_worldspace);\n float light_attenuation = getPointLightAttenuation(pointLight, distance(light_position_worldspace, position_worldspace));\n lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, pointLight.color / light_attenuation);\n }\n\n for (int i = 0; i < lighting.spotLightCount; i++) {\n SpotLight spotLight = lighting_getSpotLight(i);\n vec3 light_position_worldspace = spotLight.position;\n vec3 light_direction = normalize(light_position_worldspace - position_worldspace);\n float light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);\n lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, spotLight.color / light_attenuation);\n }\n\n for (int i = 0; i < lighting.directionalLightCount; i++) {\n DirectionalLight directionalLight = lighting_getDirectionalLight(i);\n lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);\n }\n \n return lightColor;\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const PHONG_WGSL = /* wgsl */ `\\\nstruct phongMaterialUniforms {\n unlit: u32,\n ambient: f32,\n diffuse: f32,\n shininess: f32,\n specularColor: vec3<f32>,\n};\n\n@group(3) @binding(auto) var<uniform> phongMaterial : phongMaterialUniforms;\n\nfn lighting_getLightColor(surfaceColor: vec3<f32>, light_direction: vec3<f32>, view_direction: vec3<f32>, normal_worldspace: vec3<f32>, color: vec3<f32>) -> vec3<f32> {\n let halfway_direction: vec3<f32> = normalize(light_direction + view_direction);\n var lambertian: f32 = dot(light_direction, normal_worldspace);\n var specular: f32 = 0.0;\n if (lambertian > 0.0) {\n let specular_angle = max(dot(normal_worldspace, halfway_direction), 0.0);\n specular = pow(specular_angle, phongMaterial.shininess);\n }\n lambertian = max(lambertian, 0.0);\n return (lambertian * phongMaterial.diffuse * surfaceColor + specular * phongMaterial.specularColor) * color;\n}\n\nfn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, position_worldspace: vec3<f32>, normal_worldspace: vec3<f32>) -> vec3<f32> {\n var lightColor: vec3<f32> = surfaceColor;\n\n if (phongMaterial.unlit != 0u) {\n return surfaceColor;\n }\n\n if (lighting.enabled == 0) {\n return lightColor;\n }\n\n let view_direction: vec3<f32> = normalize(cameraPosition - position_worldspace);\n lightColor = phongMaterial.ambient * surfaceColor * lighting.ambientColor;\n\n for (var i: i32 = 0; i < lighting.pointLightCount; i++) {\n let pointLight: PointLight = lighting_getPointLight(i);\n let light_position_worldspace: vec3<f32> = pointLight.position;\n let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);\n let light_attenuation = getPointLightAttenuation(\n pointLight,\n distance(light_position_worldspace, position_worldspace)\n );\n lightColor += lighting_getLightColor(\n surfaceColor,\n light_direction,\n view_direction,\n normal_worldspace,\n pointLight.color / light_attenuation\n );\n }\n\n for (var i: i32 = 0; i < lighting.spotLightCount; i++) {\n let spotLight: SpotLight = lighting_getSpotLight(i);\n let light_position_worldspace: vec3<f32> = spotLight.position;\n let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);\n let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);\n lightColor += lighting_getLightColor(\n surfaceColor,\n light_direction,\n view_direction,\n normal_worldspace,\n spotLight.color / light_attenuation\n );\n }\n\n for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {\n let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);\n lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);\n } \n \n return lightColor;\n}\n\nfn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace: vec3<f32>, normal_worldspace: vec3<f32>) -> vec3<f32>{\n var lightColor = vec3<f32>(0, 0, 0);\n let surfaceColor = vec3<f32>(0, 0, 0);\n\n if (lighting.enabled != 0) {\n let view_direction = normalize(cameraPosition - position_worldspace);\n\n for (var i: i32 = 0; i < lighting.pointLightCount; i++) {\n let pointLight: PointLight = lighting_getPointLight(i);\n let light_position_worldspace: vec3<f32> = pointLight.position;\n let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);\n let light_attenuation = getPointLightAttenuation(\n pointLight,\n distance(light_position_worldspace, position_worldspace)\n );\n lightColor += lighting_getLightColor(\n surfaceColor,\n light_direction,\n view_direction,\n normal_worldspace,\n pointLight.color / light_attenuation\n );\n }\n\n for (var i: i32 = 0; i < lighting.spotLightCount; i++) {\n let spotLight: SpotLight = lighting_getSpotLight(i);\n let light_position_worldspace: vec3<f32> = spotLight.position;\n let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);\n let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);\n lightColor += lighting_getLightColor(\n surfaceColor,\n light_direction,\n view_direction,\n normal_worldspace,\n spotLight.color / light_attenuation\n );\n }\n\n for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {\n let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);\n lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);\n }\n }\n return lightColor;\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {NumberArray3} from '@math.gl/types';\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\nimport {lighting} from '../lights/lighting';\nimport {PHONG_VS, PHONG_FS} from '../phong-material/phong-shaders-glsl';\nimport {PHONG_WGSL} from '../phong-material/phong-shaders-wgsl';\nimport {normalizeByteColor3, resolveUseByteColors} from '../../../lib/color/normalize-byte-colors';\n\nexport type GouraudMaterialProps = {\n unlit?: boolean;\n ambient?: number;\n diffuse?: number;\n /** Specularity exponent */\n shininess?: number;\n specularColor?: [number, number, number];\n useByteColors?: boolean;\n};\n\n/** In Gouraud shading, color is calculated for each triangle vertex normal, and then color is interpolated colors across the triangle */\nexport const gouraudMaterial: ShaderModule<GouraudMaterialProps> = {\n props: {} as GouraudMaterialProps,\n\n name: 'gouraudMaterial',\n bindingLayout: [{name: 'gouraudMaterial', group: 3}],\n // Note these are switched between phong and gouraud\n vs: PHONG_FS.replace('phongMaterial', 'gouraudMaterial'),\n fs: PHONG_VS.replace('phongMaterial', 'gouraudMaterial'),\n source: PHONG_WGSL.replaceAll('phongMaterial', 'gouraudMaterial'),\n defines: {\n LIGHTING_VERTEX: true\n },\n dependencies: [lighting],\n uniformTypes: {\n unlit: 'i32',\n ambient: 'f32',\n diffuse: 'f32',\n shininess: 'f32',\n specularColor: 'vec3<f32>',\n useByteColors: 'i32'\n },\n defaultUniforms: {\n unlit: false,\n ambient: 0.35,\n diffuse: 0.6,\n shininess: 32,\n specularColor: [0.15, 0.15, 0.15],\n useByteColors: true\n },\n\n getUniforms(props: GouraudMaterialProps) {\n const uniforms = {...props};\n if (uniforms.specularColor) {\n uniforms.specularColor = normalizeByteColor3(\n uniforms.specularColor,\n resolveUseByteColors(uniforms.useByteColors, true)\n ) as NumberArray3;\n }\n return {...gouraudMaterial.defaultUniforms, ...uniforms};\n }\n};\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {NumberArray3} from '@math.gl/types';\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\nimport {lighting} from '../lights/lighting';\nimport {PHONG_WGSL} from './phong-shaders-wgsl';\nimport {PHONG_VS, PHONG_FS} from './phong-shaders-glsl';\nimport {normalizeByteColor3, resolveUseByteColors} from '../../../lib/color/normalize-byte-colors';\n\nexport type PhongMaterialProps = {\n unlit?: boolean;\n ambient?: number;\n diffuse?: number;\n /** Specularity exponent */\n shininess?: number;\n specularColor?: NumberArray3;\n useByteColors?: boolean;\n};\n\n/** In Phong shading, the normal vector is linearly interpolated across the surface of the polygon from the polygon's vertex normals. */\nexport const phongMaterial: ShaderModule<PhongMaterialProps> = {\n name: 'phongMaterial',\n firstBindingSlot: 0,\n bindingLayout: [{name: 'phongMaterial', group: 3}],\n dependencies: [lighting],\n // Note these are switched between phong and gouraud\n source: PHONG_WGSL,\n vs: PHONG_VS,\n fs: PHONG_FS,\n defines: {\n LIGHTING_FRAGMENT: true\n },\n uniformTypes: {\n unlit: 'i32',\n ambient: 'f32',\n diffuse: 'f32',\n shininess: 'f32',\n specularColor: 'vec3<f32>',\n useByteColors: 'i32'\n },\n defaultUniforms: {\n unlit: false,\n ambient: 0.35,\n diffuse: 0.6,\n shininess: 32,\n specularColor: [0.15, 0.15, 0.15],\n useByteColors: true\n },\n getUniforms(props?: PhongMaterialProps) {\n const uniforms = {...props};\n if (uniforms.specularColor) {\n uniforms.specularColor = normalizeByteColor3(\n uniforms.specularColor,\n resolveUseByteColors(uniforms.useByteColors, true)\n ) as NumberArray3;\n }\n return {...phongMaterial.defaultUniforms, ...uniforms};\n }\n};\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// Attribution:\n// MIT license, Copyright (c) 2016-2017 Mohamad Moneimne and Contributors\n// This fragment shader defines a reference implementation for Physically Based Shading of\n// a microfacet surface material defined by a glTF model.\n\n// TODO - better do the checks outside of shader\n\nexport const vs = /* glsl */ `\\\nout vec3 pbr_vPosition;\nout vec2 pbr_vUV0;\nout vec2 pbr_vUV1;\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(\n vec4 position,\n vec4 normal,\n vec4 tangent,\n vec2 uv0,\n vec2 uv1\n)\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_vUV0 = uv0;\n#else\n pbr_vUV0 = vec2(0.,0.);\n#endif\n\n pbr_vUV1 = uv1;\n}\n`;\n\nexport const fs = /* glsl */ `\\\nprecision highp float;\n\nlayout(std140) uniform 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 vec3 specularColorFactor;\n float specularIntensityFactor;\n bool specularColorMapEnabled;\n bool specularIntensityMapEnabled;\n\n float ior;\n\n float transmissionFactor;\n bool transmissionMapEnabled;\n\n float thicknessFactor;\n float attenuationDistance;\n vec3 attenuationColor;\n\n float clearcoatFactor;\n float clearcoatRoughnessFactor;\n bool clearcoatMapEnabled;\n bool clearcoatRoughnessMapEnabled;\n\n vec3 sheenColorFactor;\n float sheenRoughnessFactor;\n bool sheenColorMapEnabled;\n bool sheenRoughnessMapEnabled;\n\n float iridescenceFactor;\n float iridescenceIor;\n vec2 iridescenceThicknessRange;\n bool iridescenceMapEnabled;\n\n float anisotropyStrength;\n float anisotropyRotation;\n vec2 anisotropyDirection;\n bool anisotropyMapEnabled;\n\n float emissiveStrength;\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 int baseColorUVSet;\n mat3 baseColorUVTransform;\n int metallicRoughnessUVSet;\n mat3 metallicRoughnessUVTransform;\n int normalUVSet;\n mat3 normalUVTransform;\n int occlusionUVSet;\n mat3 occlusionUVTransform;\n int emissiveUVSet;\n mat3 emissiveUVTransform;\n int specularColorUVSet;\n mat3 specularColorUVTransform;\n int specularIntensityUVSet;\n mat3 specularIntensityUVTransform;\n int transmissionUVSet;\n mat3 transmissionUVTransform;\n int thicknessUVSet;\n mat3 thicknessUVTransform;\n int clearcoatUVSet;\n mat3 clearcoatUVTransform;\n int clearcoatRoughnessUVSet;\n mat3 clearcoatRoughnessUVTransform;\n int clearcoatNormalUVSet;\n mat3 clearcoatNormalUVTransform;\n int sheenColorUVSet;\n mat3 sheenColorUVTransform;\n int sheenRoughnessUVSet;\n mat3 sheenRoughnessUVTransform;\n int iridescenceUVSet;\n mat3 iridescenceUVTransform;\n int iridescenceThicknessUVSet;\n mat3 iridescenceThicknessUVTransform;\n int anisotropyUVSet;\n mat3 anisotropyUVTransform;\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 HAS_SPECULARCOLORMAP\nuniform sampler2D pbr_specularColorSampler;\n#endif\n#ifdef HAS_SPECULARINTENSITYMAP\nuniform sampler2D pbr_specularIntensitySampler;\n#endif\n#ifdef HAS_TRANSMISSIONMAP\nuniform sampler2D pbr_transmissionSampler;\n#endif\n#ifdef HAS_THICKNESSMAP\nuniform sampler2D pbr_thicknessSampler;\n#endif\n#ifdef HAS_CLEARCOATMAP\nuniform sampler2D pbr_clearcoatSampler;\n#endif\n#ifdef HAS_CLEARCOATROUGHNESSMAP\nuniform sampler2D pbr_clearcoatRoughnessSampler;\n#endif\n#ifdef HAS_CLEARCOATNORMALMAP\nuniform sampler2D pbr_clearcoatNormalSampler;\n#endif\n#ifdef HAS_SHEENCOLORMAP\nuniform sampler2D pbr_sheenColorSampler;\n#endif\n#ifdef HAS_SHEENROUGHNESSMAP\nuniform sampler2D pbr_sheenRoughnessSampler;\n#endif\n#ifdef HAS_IRIDESCENCEMAP\nuniform sampler2D pbr_iridescenceSampler;\n#endif\n#ifdef HAS_IRIDESCENCETHICKNESSMAP\nuniform sampler2D pbr_iridescenceThicknessSampler;\n#endif\n#ifdef HAS_ANISOTROPYMAP\nuniform sampler2D pbr_anisotropySampler;\n#endif\n// Inputs from vertex shader\n\nin vec3 pbr_vPosition;\nin vec2 pbr_vUV0;\nin vec2 pbr_vUV1;\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\nvec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor);\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\nvec2 getMaterialUV(int uvSet, mat3 uvTransform)\n{\n vec2 baseUV = uvSet == 1 ? pbr_vUV1 : pbr_vUV0;\n return (uvTransform * vec3(baseUV, 1.0)).xy;\n}\n\n// Build the tangent basis from interpolated attributes or screen-space derivatives.\nmat3 getTBN(vec2 uv)\n{\n#ifndef HAS_TANGENTS\n vec3 pos_dx = dFdx(pbr_vPosition);\n vec3 pos_dy = dFdy(pbr_vPosition);\n vec3 tex_dx = dFdx(vec3(uv, 0.0));\n vec3 tex_dy = dFdy(vec3(uv, 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 return tbn;\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 getMappedNormal(sampler2D normalSampler, mat3 tbn, float normalScale, vec2 uv)\n{\n vec3 n = texture(normalSampler, uv).rgb;\n return normalize(tbn * ((2.0 * n - 1.0) * vec3(normalScale, normalScale, 1.0)));\n}\n\nvec3 getNormal(mat3 tbn, vec2 uv)\n{\n#ifdef HAS_NORMALMAP\n vec3 n = getMappedNormal(pbr_normalSampler, tbn, pbrMaterial.normalScale, uv);\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\nvec3 getClearcoatNormal(mat3 tbn, vec3 baseNormal, vec2 uv)\n{\n#ifdef HAS_CLEARCOATNORMALMAP\n return getMappedNormal(pbr_clearcoatNormalSampler, tbn, 1.0, uv);\n#else\n return baseNormal;\n#endif\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\nfloat maxComponent(vec3 value)\n{\n return max(max(value.r, value.g), value.b);\n}\n\nfloat getDielectricF0(float ior)\n{\n float clampedIor = max(ior, 1.0);\n float ratio = (clampedIor - 1.0) / (clampedIor + 1.0);\n return ratio * ratio;\n}\n\nvec2 normalizeDirection(vec2 direction)\n{\n float directionLength = length(direction);\n return directionLength > 0.0001 ? direction / directionLength : vec2(1.0, 0.0);\n}\n\nvec2 rotateDirection(vec2 direction, float rotation)\n{\n float s = sin(rotation);\n float c = cos(rotation);\n return vec2(direction.x * c - direction.y * s, direction.x * s + direction.y * c);\n}\n\nvec3 getIridescenceTint(float iridescence, float thickness, float NdotV)\n{\n if (iridescence <= 0.0) {\n return vec3(1.0);\n }\n\n float phase = 0.015 * thickness * pbrMaterial.iridescenceIor + (1.0 - NdotV) * 6.0;\n vec3 thinFilmTint =\n 0.5 + 0.5 * cos(vec3(phase, phase + 2.0943951, phase + 4.1887902));\n return mix(vec3(1.0), thinFilmTint, iridescence);\n}\n\nvec3 getVolumeAttenuation(float thickness)\n{\n if (thickness <= 0.0) {\n return vec3(1.0);\n }\n\n vec3 attenuationCoefficient =\n -log(max(pbrMaterial.attenuationColor, vec3(0.0001))) /\n max(pbrMaterial.attenuationDistance, 0.0001);\n return exp(-attenuationCoefficient * thickness);\n}\n\nPBRInfo createClearcoatPBRInfo(PBRInfo basePBRInfo, vec3 clearcoatNormal, float clearcoatRoughness)\n{\n float perceptualRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);\n float alphaRoughness = perceptualRoughness * perceptualRoughness;\n float NdotV = clamp(abs(dot(clearcoatNormal, basePBRInfo.v)), 0.001, 1.0);\n\n return PBRInfo(\n basePBRInfo.NdotL,\n NdotV,\n basePBRInfo.NdotH,\n basePBRInfo.LdotH,\n basePBRInfo.VdotH,\n perceptualRoughness,\n 0.0,\n vec3(0.04),\n vec3(1.0),\n alphaRoughness,\n vec3(0.0),\n vec3(0.04),\n clearcoatNormal,\n basePBRInfo.v\n );\n}\n\nvec3 calculateClearcoatContribution(\n PBRInfo pbrInfo,\n vec3 lightColor,\n vec3 clearcoatNormal,\n float clearcoatFactor,\n float clearcoatRoughness\n) {\n if (clearcoatFactor <= 0.0) {\n return vec3(0.0);\n }\n\n PBRInfo clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);\n return calculateFinalColor(clearcoatPBRInfo, lightColor) * clearcoatFactor;\n}\n\n#ifdef USE_IBL\nvec3 calculateClearcoatIBLContribution(\n PBRInfo pbrInfo,\n vec3 clearcoatNormal,\n vec3 reflection,\n float clearcoatFactor,\n float clearcoatRoughness\n) {\n if (clearcoatFactor <= 0.0) {\n return vec3(0.0);\n }\n\n PBRInfo clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);\n return getIBLContribution(clearcoatPBRInfo, clearcoatNormal, reflection) * clearcoatFactor;\n}\n#endif\n\nvec3 calculateSheenContribution(\n PBRInfo pbrInfo,\n vec3 lightColor,\n vec3 sheenColor,\n float sheenRoughness\n) {\n if (maxComponent(sheenColor) <= 0.0) {\n return vec3(0.0);\n }\n\n float sheenFresnel = pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);\n float sheenVisibility = mix(1.0, pbrInfo.NdotL * pbrInfo.NdotV, sheenRoughness);\n return pbrInfo.NdotL *\n lightColor *\n sheenColor *\n (0.25 + 0.75 * sheenFresnel) *\n sheenVisibility *\n (1.0 - pbrInfo.metalness);\n}\n\nfloat calculateAnisotropyBoost(\n PBRInfo pbrInfo,\n vec3 anisotropyTangent,\n float anisotropyStrength\n) {\n if (anisotropyStrength <= 0.0) {\n return 1.0;\n }\n\n vec3 anisotropyBitangent = normalize(cross(pbrInfo.n, anisotropyTangent));\n float bitangentViewAlignment = abs(dot(pbrInfo.v, anisotropyBitangent));\n return mix(1.0, 0.65 + 0.7 * bitangentViewAlignment, anisotropyStrength);\n}\n\nvec3 calculateMaterialLightColor(\n PBRInfo pbrInfo,\n vec3 lightColor,\n vec3 clearcoatNormal,\n float clearcoatFactor,\n float clearcoatRoughness,\n vec3 sheenColor,\n float sheenRoughness,\n vec3 anisotropyTangent,\n float anisotropyStrength\n) {\n float anisotropyBoost = calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);\n vec3 color = calculateFinalColor(pbrInfo, lightColor) * anisotropyBoost;\n color += calculateClearcoatContribution(\n pbrInfo,\n lightColor,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness\n );\n color += calculateSheenContribution(pbrInfo, lightColor, sheenColor, sheenRoughness);\n return color;\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\nvoid PBRInfo_setSpotLight(inout PBRInfo pbrInfo, SpotLight spotLight) {\n vec3 light_direction = normalize(spotLight.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 vec2 baseColorUV = getMaterialUV(pbrMaterial.baseColorUVSet, pbrMaterial.baseColorUVTransform);\n vec2 metallicRoughnessUV = getMaterialUV(\n pbrMaterial.metallicRoughnessUVSet,\n pbrMaterial.metallicRoughnessUVTransform\n );\n vec2 normalUV = getMaterialUV(pbrMaterial.normalUVSet, pbrMaterial.normalUVTransform);\n vec2 occlusionUV = getMaterialUV(pbrMaterial.occlusionUVSet, pbrMaterial.occlusionUVTransform);\n vec2 emissiveUV = getMaterialUV(pbrMaterial.emissiveUVSet, pbrMaterial.emissiveUVTransform);\n vec2 specularColorUV = getMaterialUV(\n pbrMaterial.specularColorUVSet,\n pbrMaterial.specularColorUVTransform\n );\n vec2 specularIntensityUV = getMaterialUV(\n pbrMaterial.specularIntensityUVSet,\n pbrMaterial.specularIntensityUVTransform\n );\n vec2 transmissionUV = getMaterialUV(\n pbrMaterial.transmissionUVSet,\n pbrMaterial.transmissionUVTransform\n );\n vec2 thicknessUV = getMaterialUV(pbrMaterial.thicknessUVSet, pbrMaterial.thicknessUVTransform);\n vec2 clearcoatUV = getMaterialUV(pbrMaterial.clearcoatUVSet, pbrMaterial.clearcoatUVTransform);\n vec2 clearcoatRoughnessUV = getMaterialUV(\n pbrMaterial.clearcoatRoughnessUVSet,\n pbrMaterial.clearcoatRoughnessUVTransform\n );\n vec2 clearcoatNormalUV = getMaterialUV(\n pbrMaterial.clearcoatNormalUVSet,\n pbrMaterial.clearcoatNormalUVTransform\n );\n vec2 sheenColorUV = getMaterialUV(\n pbrMaterial.sheenColorUVSet,\n pbrMaterial.sheenColorUVTransform\n );\n vec2 sheenRoughnessUV = getMaterialUV(\n pbrMaterial.sheenRoughnessUVSet,\n pbrMaterial.sheenRoughnessUVTransform\n );\n vec2 iridescenceUV = getMaterialUV(\n pbrMaterial.iridescenceUVSet,\n pbrMaterial.iridescenceUVTransform\n );\n vec2 iridescenceThicknessUV = getMaterialUV(\n pbrMaterial.iridescenceThicknessUVSet,\n pbrMaterial.iridescenceThicknessUVTransform\n );\n vec2 anisotropyUV = getMaterialUV(\n pbrMaterial.anisotropyUVSet,\n pbrMaterial.anisotropyUVTransform\n );\n\n // The albedo may be defined from a base texture or a flat color\n#ifdef HAS_BASECOLORMAP\n vec4 baseColor =\n SRGBtoLINEAR(texture(pbr_baseColorSampler, baseColorUV)) * 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 float transmission = 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, metallicRoughnessUV);\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 mat3 tbn = getTBN(normalUV);\n vec3 n = getNormal(tbn, normalUV); // normal at surface point\n vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera\n float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);\n#ifdef USE_MATERIAL_EXTENSIONS\n bool useExtendedPBR =\n pbrMaterial.specularColorMapEnabled ||\n pbrMaterial.specularIntensityMapEnabled ||\n abs(pbrMaterial.specularIntensityFactor - 1.0) > 0.0001 ||\n maxComponent(abs(pbrMaterial.specularColorFactor - vec3(1.0))) > 0.0001 ||\n abs(pbrMaterial.ior - 1.5) > 0.0001 ||\n pbrMaterial.transmissionMapEnabled ||\n pbrMaterial.transmissionFactor > 0.0001 ||\n pbrMaterial.clearcoatMapEnabled ||\n pbrMaterial.clearcoatRoughnessMapEnabled ||\n pbrMaterial.clearcoatFactor > 0.0001 ||\n pbrMaterial.clearcoatRoughnessFactor > 0.0001 ||\n pbrMaterial.sheenColorMapEnabled ||\n pbrMaterial.sheenRoughnessMapEnabled ||\n maxComponent(pbrMaterial.sheenColorFactor) > 0.0001 ||\n pbrMaterial.sheenRoughnessFactor > 0.0001 ||\n pbrMaterial.iridescenceMapEnabled ||\n pbrMaterial.iridescenceFactor > 0.0001 ||\n abs(pbrMaterial.iridescenceIor - 1.3) > 0.0001 ||\n abs(pbrMaterial.iridescenceThicknessRange.x - 100.0) > 0.0001 ||\n abs(pbrMaterial.iridescenceThicknessRange.y - 400.0) > 0.0001 ||\n pbrMaterial.anisotropyMapEnabled ||\n pbrMaterial.anisotropyStrength > 0.0001 ||\n abs(pbrMaterial.anisotropyRotation) > 0.0001 ||\n length(pbrMaterial.anisotropyDirection - vec2(1.0, 0.0)) > 0.0001;\n#else\n bool useExtendedPBR = false;\n#endif\n\n if (!useExtendedPBR) {\n // Keep the baseline metallic-roughness implementation byte-for-byte equivalent in behavior.\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 float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);\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 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#ifdef USE_LIGHTS\n PBRInfo_setAmbientLight(pbrInfo);\n color += calculateFinalColor(pbrInfo, lighting.ambientColor);\n\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 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\n for(int i = 0; i < lighting.spotLightCount; i++) {\n if (i < lighting.spotLightCount) {\n PBRInfo_setSpotLight(pbrInfo, lighting_getSpotLight(i));\n float attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), pbr_vPosition);\n color += calculateFinalColor(pbrInfo, lighting_getSpotLight(i).color / attenuation);\n }\n }\n#endif\n\n#ifdef USE_IBL\n if (pbrMaterial.IBLenabled) {\n color += getIBLContribution(pbrInfo, n, reflection);\n }\n#endif\n\n#ifdef HAS_OCCLUSIONMAP\n if (pbrMaterial.occlusionMapEnabled) {\n float ao = texture(pbr_occlusionSampler, occlusionUV).r;\n color = mix(color, color * ao, pbrMaterial.occlusionStrength);\n }\n#endif\n\n vec3 emissive = pbrMaterial.emissiveFactor;\n#ifdef HAS_EMISSIVEMAP\n if (pbrMaterial.emissiveMapEnabled) {\n emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, emissiveUV)).rgb;\n }\n#endif\n color += emissive * pbrMaterial.emissiveStrength;\n\n#ifdef PBR_DEBUG\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 return vec4(pow(color, vec3(1.0 / 2.2)), baseColor.a);\n }\n\n float specularIntensity = pbrMaterial.specularIntensityFactor;\n#ifdef HAS_SPECULARINTENSITYMAP\n if (pbrMaterial.specularIntensityMapEnabled) {\n specularIntensity *= texture(pbr_specularIntensitySampler, specularIntensityUV).a;\n }\n#endif\n\n vec3 specularFactor = pbrMaterial.specularColorFactor;\n#ifdef HAS_SPECULARCOLORMAP\n if (pbrMaterial.specularColorMapEnabled) {\n specularFactor *= SRGBtoLINEAR(texture(pbr_specularColorSampler, specularColorUV)).rgb;\n }\n#endif\n\n transmission = pbrMaterial.transmissionFactor;\n#ifdef HAS_TRANSMISSIONMAP\n if (pbrMaterial.transmissionMapEnabled) {\n transmission *= texture(pbr_transmissionSampler, transmissionUV).r;\n }\n#endif\n transmission = clamp(transmission * (1.0 - metallic), 0.0, 1.0);\n float thickness = max(pbrMaterial.thicknessFactor, 0.0);\n#ifdef HAS_THICKNESSMAP\n thickness *= texture(pbr_thicknessSampler, thicknessUV).g;\n#endif\n\n float clearcoatFactor = pbrMaterial.clearcoatFactor;\n float clearcoatRoughness = pbrMaterial.clearcoatRoughnessFactor;\n#ifdef HAS_CLEARCOATMAP\n if (pbrMaterial.clearcoatMapEnabled) {\n clearcoatFactor *= texture(pbr_clearcoatSampler, clearcoatUV).r;\n }\n#endif\n#ifdef HAS_CLEARCOATROUGHNESSMAP\n if (pbrMaterial.clearcoatRoughnessMapEnabled) {\n clearcoatRoughness *= texture(pbr_clearcoatRoughnessSampler, clearcoatRoughnessUV).g;\n }\n#endif\n clearcoatFactor = clamp(clearcoatFactor, 0.0, 1.0);\n clearcoatRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);\n vec3 clearcoatNormal = getClearcoatNormal(getTBN(clearcoatNormalUV), n, clearcoatNormalUV);\n\n vec3 sheenColor = pbrMaterial.sheenColorFactor;\n float sheenRoughness = pbrMaterial.sheenRoughnessFactor;\n#ifdef HAS_SHEENCOLORMAP\n if (pbrMaterial.sheenColorMapEnabled) {\n sheenColor *= SRGBtoLINEAR(texture(pbr_sheenColorSampler, sheenColorUV)).rgb;\n }\n#endif\n#ifdef HAS_SHEENROUGHNESSMAP\n if (pbrMaterial.sheenRoughnessMapEnabled) {\n sheenRoughness *= texture(pbr_sheenRoughnessSampler, sheenRoughnessUV).a;\n }\n#endif\n sheenRoughness = clamp(sheenRoughness, c_MinRoughness, 1.0);\n\n float iridescence = pbrMaterial.iridescenceFactor;\n#ifdef HAS_IRIDESCENCEMAP\n if (pbrMaterial.iridescenceMapEnabled) {\n iridescence *= texture(pbr_iridescenceSampler, iridescenceUV).r;\n }\n#endif\n iridescence = clamp(iridescence, 0.0, 1.0);\n float iridescenceThickness = mix(\n pbrMaterial.iridescenceThicknessRange.x,\n pbrMaterial.iridescenceThicknessRange.y,\n 0.5\n );\n#ifdef HAS_IRIDESCENCETHICKNESSMAP\n iridescenceThickness = mix(\n pbrMaterial.iridescenceThicknessRange.x,\n pbrMaterial.iridescenceThicknessRange.y,\n texture(pbr_iridescenceThicknessSampler, iridescenceThicknessUV).g\n );\n#endif\n\n float anisotropyStrength = clamp(pbrMaterial.anisotropyStrength, 0.0, 1.0);\n vec2 anisotropyDirection = normalizeDirection(pbrMaterial.anisotropyDirection);\n#ifdef HAS_ANISOTROPYMAP\n if (pbrMaterial.anisotropyMapEnabled) {\n vec3 anisotropySample = texture(pbr_anisotropySampler, anisotropyUV).rgb;\n anisotropyStrength *= anisotropySample.b;\n vec2 mappedDirection = anisotropySample.rg * 2.0 - 1.0;\n if (length(mappedDirection) > 0.0001) {\n anisotropyDirection = normalize(mappedDirection);\n }\n }\n#endif\n anisotropyDirection = rotateDirection(anisotropyDirection, pbrMaterial.anisotropyRotation);\n vec3 anisotropyTangent = normalize(tbn[0] * anisotropyDirection.x + tbn[1] * anisotropyDirection.y);\n if (length(anisotropyTangent) < 0.0001) {\n anisotropyTangent = normalize(tbn[0]);\n }\n float anisotropyViewAlignment = abs(dot(v, anisotropyTangent));\n perceptualRoughness = mix(\n perceptualRoughness,\n clamp(perceptualRoughness * (1.0 - 0.6 * anisotropyViewAlignment), c_MinRoughness, 1.0),\n anisotropyStrength\n );\n\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 float dielectricF0 = getDielectricF0(pbrMaterial.ior);\n vec3 dielectricSpecularF0 = min(\n vec3(dielectricF0) * specularFactor * specularIntensity,\n vec3(1.0)\n );\n vec3 iridescenceTint = getIridescenceTint(iridescence, iridescenceThickness, NdotV);\n dielectricSpecularF0 = mix(\n dielectricSpecularF0,\n dielectricSpecularF0 * iridescenceTint,\n iridescence\n );\n vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - dielectricSpecularF0);\n diffuseColor *= (1.0 - metallic) * (1.0 - transmission);\n vec3 specularColor = mix(dielectricSpecularF0, baseColor.rgb, metallic);\n\n float baseLayerEnergy = 1.0 - clearcoatFactor * 0.25;\n diffuseColor *= baseLayerEnergy;\n specularColor *= baseLayerEnergy;\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 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 += calculateMaterialLightColor(\n pbrInfo,\n lighting.ambientColor,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness,\n sheenColor,\n sheenRoughness,\n anisotropyTangent,\n anisotropyStrength\n );\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 += calculateMaterialLightColor(\n pbrInfo,\n lighting_getDirectionalLight(i).color,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness,\n sheenColor,\n sheenRoughness,\n anisotropyTangent,\n anisotropyStrength\n );\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 += calculateMaterialLightColor(\n pbrInfo,\n lighting_getPointLight(i).color / attenuation,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness,\n sheenColor,\n sheenRoughness,\n anisotropyTangent,\n anisotropyStrength\n );\n }\n }\n\n for(int i = 0; i < lighting.spotLightCount; i++) {\n if (i < lighting.spotLightCount) {\n PBRInfo_setSpotLight(pbrInfo, lighting_getSpotLight(i));\n float attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), pbr_vPosition);\n color += calculateMaterialLightColor(\n pbrInfo,\n lighting_getSpotLight(i).color / attenuation,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness,\n sheenColor,\n sheenRoughness,\n anisotropyTangent,\n anisotropyStrength\n );\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 calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);\n color += calculateClearcoatIBLContribution(\n pbrInfo,\n clearcoatNormal,\n -normalize(reflect(v, clearcoatNormal)),\n clearcoatFactor,\n clearcoatRoughness\n );\n color += sheenColor * pbrMaterial.scaleIBLAmbient.x * (1.0 - sheenRoughness) * 0.25;\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, occlusionUV).r;\n color = mix(color, color * ao, pbrMaterial.occlusionStrength);\n }\n#endif\n\n vec3 emissive = pbrMaterial.emissiveFactor;\n#ifdef HAS_EMISSIVEMAP\n if (pbrMaterial.emissiveMapEnabled) {\n emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, emissiveUV)).rgb;\n }\n#endif\n color += emissive * pbrMaterial.emissiveStrength;\n\n if (transmission > 0.0) {\n color = mix(color, color * getVolumeAttenuation(thickness), transmission);\n }\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 float alpha = clamp(baseColor.a * (1.0 - transmission), 0.0, 1.0);\n return vec4(pow(color,vec3(1.0/2.2)), alpha);\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// Attribution:\n// MIT license, Copyright (c) 2016-2017 Mohamad Moneimne and Contributors\n// This fragment shader defines a reference implementation for Physically Based Shading of\n// a microfacet surface material defined by a glTF model.\n\n// TODO - better do the checks outside of shader\n\nexport const pbrMaterialUniforms = /* wgsl */ `\\\nuniform 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 vec3 specularColorFactor;\n float specularIntensityFactor;\n bool specularColorMapEnabled;\n bool specularIntensityMapEnabled;\n\n float ior;\n\n float transmissionFactor;\n bool transmissionMapEnabled;\n\n float thicknessFactor;\n float attenuationDistance;\n vec3 attenuationColor;\n\n float clearcoatFactor;\n float clearcoatRoughnessFactor;\n bool clearcoatMapEnabled;\n bool clearcoatRoughnessMapEnabled;\n\n vec3 sheenColorFactor;\n float sheenRoughnessFactor;\n bool sheenColorMapEnabled;\n bool sheenRoughnessMapEnabled;\n\n float iridescenceFactor;\n float iridescenceIor;\n vec2 iridescenceThicknessRange;\n bool iridescenceMapEnabled;\n\n float anisotropyStrength;\n float anisotropyRotation;\n vec2 anisotropyDirection;\n bool anisotropyMapEnabled;\n\n float emissiveStrength;\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 HAS_SPECULARCOLORMAP\nuniform sampler2D u_SpecularColorSampler;\n#endif\n#ifdef HAS_SPECULARINTENSITYMAP\nuniform sampler2D u_SpecularIntensitySampler;\n#endif\n#ifdef HAS_TRANSMISSIONMAP\nuniform sampler2D u_TransmissionSampler;\n#endif\n#ifdef HAS_THICKNESSMAP\nuniform sampler2D u_ThicknessSampler;\n#endif\n#ifdef HAS_CLEARCOATMAP\nuniform sampler2D u_ClearcoatSampler;\n#endif\n#ifdef HAS_CLEARCOATROUGHNESSMAP\nuniform sampler2D u_ClearcoatRoughnessSampler;\n#endif\n#ifdef HAS_CLEARCOATNORMALMAP\nuniform sampler2D u_ClearcoatNormalSampler;\n#endif\n#ifdef HAS_SHEENCOLORMAP\nuniform sampler2D u_SheenColorSampler;\n#endif\n#ifdef HAS_SHEENROUGHNESSMAP\nuniform sampler2D u_SheenRoughnessSampler;\n#endif\n#ifdef HAS_IRIDESCENCEMAP\nuniform sampler2D u_IridescenceSampler;\n#endif\n#ifdef HAS_IRIDESCENCETHICKNESSMAP\nuniform sampler2D u_IridescenceThicknessSampler;\n#endif\n#ifdef HAS_ANISOTROPYMAP\nuniform sampler2D u_AnisotropySampler;\n#endif\n#ifdef USE_IBL\nuniform samplerCube u_DiffuseEnvSampler;\nuniform samplerCube u_SpecularEnvSampler;\nuniform sampler2D u_brdfLUT;\n#endif\n\n`;\n\nexport const source = /* wgsl */ `\\\nstruct PBRFragmentInputs {\n pbr_vPosition: vec3f,\n pbr_vUV0: vec2f,\n pbr_vUV1: vec2f,\n pbr_vTBN: mat3x3f,\n pbr_vNormal: vec3f\n};\n\nvar<private> fragmentInputs: PBRFragmentInputs;\n\nfn pbr_setPositionNormalTangentUV(\n position: vec4f,\n normal: vec4f,\n tangent: vec4f,\n uv0: vec2f,\n uv1: vec2f\n)\n{\n var pos: vec4f = pbrProjection.modelMatrix * position;\n fragmentInputs.pbr_vPosition = pos.xyz / pos.w;\n fragmentInputs.pbr_vNormal = vec3f(0.0, 0.0, 1.0);\n fragmentInputs.pbr_vTBN = mat3x3f(\n vec3f(1.0, 0.0, 0.0),\n vec3f(0.0, 1.0, 0.0),\n vec3f(0.0, 0.0, 1.0)\n );\n fragmentInputs.pbr_vUV0 = vec2f(0.0, 0.0);\n fragmentInputs.pbr_vUV1 = uv1;\n\n#ifdef HAS_NORMALS\n let normalW: vec3f = normalize((pbrProjection.normalMatrix * vec4f(normal.xyz, 0.0)).xyz);\n fragmentInputs.pbr_vNormal = normalW;\n#ifdef HAS_TANGENTS\n let tangentW: vec3f = normalize((pbrProjection.modelMatrix * vec4f(tangent.xyz, 0.0)).xyz);\n let bitangentW: vec3f = cross(normalW, tangentW) * tangent.w;\n fragmentInputs.pbr_vTBN = mat3x3f(tangentW, bitangentW, normalW);\n#endif\n#endif\n\n#ifdef HAS_UV\n fragmentInputs.pbr_vUV0 = uv0;\n#endif\n}\n\nstruct pbrMaterialUniforms {\n // Material is unlit\n unlit: u32,\n\n // Base color map\n baseColorMapEnabled: u32,\n baseColorFactor: vec4f,\n\n normalMapEnabled : u32,\n normalScale: f32, // #ifdef HAS_NORMALMAP\n\n emissiveMapEnabled: u32,\n emissiveFactor: vec3f, // #ifdef HAS_EMISSIVEMAP\n\n metallicRoughnessValues: vec2f,\n metallicRoughnessMapEnabled: u32,\n\n occlusionMapEnabled: i32,\n occlusionStrength: f32, // #ifdef HAS_OCCLUSIONMAP\n \n alphaCutoffEnabled: i32,\n alphaCutoff: f32, // #ifdef ALPHA_CUTOFF\n\n specularColorFactor: vec3f,\n specularIntensityFactor: f32,\n specularColorMapEnabled: i32,\n specularIntensityMapEnabled: i32,\n\n ior: f32,\n\n transmissionFactor: f32,\n transmissionMapEnabled: i32,\n\n thicknessFactor: f32,\n attenuationDistance: f32,\n attenuationColor: vec3f,\n\n clearcoatFactor: f32,\n clearcoatRoughnessFactor: f32,\n clearcoatMapEnabled: i32,\n clearcoatRoughnessMapEnabled: i32,\n\n sheenColorFactor: vec3f,\n sheenRoughnessFactor: f32,\n sheenColorMapEnabled: i32,\n sheenRoughnessMapEnabled: i32,\n\n iridescenceFactor: f32,\n iridescenceIor: f32,\n iridescenceThicknessRange: vec2f,\n iridescenceMapEnabled: i32,\n\n anisotropyStrength: f32,\n anisotropyRotation: f32,\n anisotropyDirection: vec2f,\n anisotropyMapEnabled: i32,\n\n emissiveStrength: f32,\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 baseColorUVSet: i32,\n baseColorUVTransform: mat3x3f,\n metallicRoughnessUVSet: i32,\n metallicRoughnessUVTransform: mat3x3f,\n normalUVSet: i32,\n normalUVTransform: mat3x3f,\n occlusionUVSet: i32,\n occlusionUVTransform: mat3x3f,\n emissiveUVSet: i32,\n emissiveUVTransform: mat3x3f,\n specularColorUVSet: i32,\n specularColorUVTransform: mat3x3f,\n specularIntensityUVSet: i32,\n specularIntensityUVTransform: mat3x3f,\n transmissionUVSet: i32,\n transmissionUVTransform: mat3x3f,\n thicknessUVSet: i32,\n thicknessUVTransform: mat3x3f,\n clearcoatUVSet: i32,\n clearcoatUVTransform: mat3x3f,\n clearcoatRoughnessUVSet: i32,\n clearcoatRoughnessUVTransform: mat3x3f,\n clearcoatNormalUVSet: i32,\n clearcoatNormalUVTransform: mat3x3f,\n sheenColorUVSet: i32,\n sheenColorUVTransform: mat3x3f,\n sheenRoughnessUVSet: i32,\n sheenRoughnessUVTransform: mat3x3f,\n iridescenceUVSet: i32,\n iridescenceUVTransform: mat3x3f,\n iridescenceThicknessUVSet: i32,\n iridescenceThicknessUVTransform: mat3x3f,\n anisotropyUVSet: i32,\n anisotropyUVTransform: mat3x3f,\n}\n\n@group(3) @binding(auto) var<uniform> pbrMaterial : pbrMaterialUniforms;\n\n// Samplers\n#ifdef HAS_BASECOLORMAP\n@group(3) @binding(auto) var pbr_baseColorSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_baseColorSamplerSampler: sampler;\n#endif\n#ifdef HAS_NORMALMAP\n@group(3) @binding(auto) var pbr_normalSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_normalSamplerSampler: sampler;\n#endif\n#ifdef HAS_EMISSIVEMAP\n@group(3) @binding(auto) var pbr_emissiveSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_emissiveSamplerSampler: sampler;\n#endif\n#ifdef HAS_METALROUGHNESSMAP\n@group(3) @binding(auto) var pbr_metallicRoughnessSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_metallicRoughnessSamplerSampler: sampler;\n#endif\n#ifdef HAS_OCCLUSIONMAP\n@group(3) @binding(auto) var pbr_occlusionSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_occlusionSamplerSampler: sampler;\n#endif\n#ifdef HAS_SPECULARCOLORMAP\n@group(3) @binding(auto) var pbr_specularColorSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_specularColorSamplerSampler: sampler;\n#endif\n#ifdef HAS_SPECULARINTENSITYMAP\n@group(3) @binding(auto) var pbr_specularIntensitySampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_specularIntensitySamplerSampler: sampler;\n#endif\n#ifdef HAS_TRANSMISSIONMAP\n@group(3) @binding(auto) var pbr_transmissionSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_transmissionSamplerSampler: sampler;\n#endif\n#ifdef HAS_THICKNESSMAP\n@group(3) @binding(auto) var pbr_thicknessSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_thicknessSamplerSampler: sampler;\n#endif\n#ifdef HAS_CLEARCOATMAP\n@group(3) @binding(auto) var pbr_clearcoatSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_clearcoatSamplerSampler: sampler;\n#endif\n#ifdef HAS_CLEARCOATROUGHNESSMAP\n@group(3) @binding(auto) var pbr_clearcoatRoughnessSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_clearcoatRoughnessSamplerSampler: sampler;\n#endif\n#ifdef HAS_CLEARCOATNORMALMAP\n@group(3) @binding(auto) var pbr_clearcoatNormalSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_clearcoatNormalSamplerSampler: sampler;\n#endif\n#ifdef HAS_SHEENCOLORMAP\n@group(3) @binding(auto) var pbr_sheenColorSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_sheenColorSamplerSampler: sampler;\n#endif\n#ifdef HAS_SHEENROUGHNESSMAP\n@group(3) @binding(auto) var pbr_sheenRoughnessSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_sheenRoughnessSamplerSampler: sampler;\n#endif\n#ifdef HAS_IRIDESCENCEMAP\n@group(3) @binding(auto) var pbr_iridescenceSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_iridescenceSamplerSampler: sampler;\n#endif\n#ifdef HAS_IRIDESCENCETHICKNESSMAP\n@group(3) @binding(auto) var pbr_iridescenceThicknessSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_iridescenceThicknessSamplerSampler: sampler;\n#endif\n#ifdef HAS_ANISOTROPYMAP\n@group(3) @binding(auto) var pbr_anisotropySampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_anisotropySamplerSampler: sampler;\n#endif\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 var linOut: vec3f = srgbIn.xyz;\n#ifdef MANUAL_SRGB\n let bLess: vec3f = step(vec3f(0.04045), srgbIn.xyz);\n linOut = mix(\n srgbIn.xyz / vec3f(12.92),\n pow((srgbIn.xyz + vec3f(0.055)) / vec3f(1.055), vec3f(2.4)),\n bLess\n );\n#ifdef SRGB_FAST_APPROXIMATION\n linOut = pow(srgbIn.xyz, vec3f(2.2));\n#endif\n#endif\n return vec4f(linOut, srgbIn.w);\n}\n\nfn getMaterialUV(uvSet: i32, uvTransform: mat3x3f) -> vec2f\n{\n var baseUV = fragmentInputs.pbr_vUV0;\n if (uvSet == 1) {\n baseUV = fragmentInputs.pbr_vUV1;\n }\n return (uvTransform * vec3f(baseUV, 1.0)).xy;\n}\n\n// Build the tangent basis from interpolated attributes or screen-space derivatives.\nfn getTBN(uv: vec2f) -> mat3x3f\n{\n let pos_dx: vec3f = dpdx(fragmentInputs.pbr_vPosition);\n let pos_dy: vec3f = dpdy(fragmentInputs.pbr_vPosition);\n let tex_dx: vec3f = dpdx(vec3f(uv, 0.0));\n let tex_dy: vec3f = dpdy(vec3f(uv, 0.0));\n var t: vec3f = (tex_dy.y * pos_dx - tex_dx.y * pos_dy) / (tex_dx.x * tex_dy.y - tex_dy.x * tex_dx.y);\n\n var ng: vec3f = cross(pos_dx, pos_dy);\n#ifdef HAS_NORMALS\n ng = normalize(fragmentInputs.pbr_vNormal);\n#endif\n t = normalize(t - ng * dot(ng, t));\n var b: vec3f = normalize(cross(ng, t));\n var tbn: mat3x3f = mat3x3f(t, b, ng);\n#ifdef HAS_TANGENTS\n tbn = fragmentInputs.pbr_vTBN;\n#endif\n\n return tbn;\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 getMappedNormal(\n normalSampler: texture_2d<f32>,\n normalSamplerBinding: sampler,\n tbn: mat3x3f,\n normalScale: f32,\n uv: vec2f\n) -> vec3f\n{\n let n = textureSample(normalSampler, normalSamplerBinding, uv).rgb;\n return normalize(tbn * ((2.0 * n - 1.0) * vec3f(normalScale, normalScale, 1.0)));\n}\n\nfn getNormal(tbn: mat3x3f, uv: vec2f) -> vec3f\n{\n // The tbn matrix is linearly interpolated, so we need to re-normalize\n var n: vec3f = normalize(tbn[2].xyz);\n#ifdef HAS_NORMALMAP\n n = getMappedNormal(\n pbr_normalSampler,\n pbr_normalSamplerSampler,\n tbn,\n pbrMaterial.normalScale,\n uv\n );\n#endif\n\n return n;\n}\n\nfn getClearcoatNormal(tbn: mat3x3f, baseNormal: vec3f, uv: vec2f) -> vec3f\n{\n#ifdef HAS_CLEARCOATNORMALMAP\n return getMappedNormal(\n pbr_clearcoatNormalSampler,\n pbr_clearcoatNormalSamplerSampler,\n tbn,\n 1.0,\n uv\n );\n#else\n return baseNormal;\n#endif\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, n: vec3f, reflection: vec3f) -> vec3f\n{\n let mipCount: f32 = 9.0; // resolution of 512x512\n let lod: f32 = pbrInfo.perceptualRoughness * mipCount;\n // retrieve a scale and bias to F0. See [1], Figure 3\n let brdf = SRGBtoLINEAR(\n textureSampleLevel(\n pbr_brdfLUT,\n pbr_brdfLUTSampler,\n vec2f(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness),\n 0.0\n )\n ).rgb;\n let diffuseLight =\n SRGBtoLINEAR(\n textureSampleLevel(pbr_diffuseEnvSampler, pbr_diffuseEnvSamplerSampler, n, 0.0)\n ).rgb;\n var specularLight = SRGBtoLINEAR(\n textureSampleLevel(\n pbr_specularEnvSampler,\n pbr_specularEnvSamplerSampler,\n reflection,\n 0.0\n )\n ).rgb;\n#ifdef USE_TEX_LOD\n specularLight = SRGBtoLINEAR(\n textureSampleLevel(\n pbr_specularEnvSampler,\n pbr_specularEnvSamplerSampler,\n reflection,\n lod\n )\n ).rgb;\n#endif\n\n let diffuse = diffuseLight * pbrInfo.diffuseColor * pbrMaterial.scaleIBLAmbient.x;\n let specular =\n specularLight * (pbrInfo.specularColor * brdf.x + brdf.y) * 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 / 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\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 / (M_PI * f * f);\n}\n\nfn maxComponent(value: vec3f) -> f32 {\n return max(max(value.r, value.g), value.b);\n}\n\nfn getDielectricF0(ior: f32) -> f32 {\n let clampedIor = max(ior, 1.0);\n let ratio = (clampedIor - 1.0) / (clampedIor + 1.0);\n return ratio * ratio;\n}\n\nfn normalizeDirection(direction: vec2f) -> vec2f {\n let directionLength = length(direction);\n if (directionLength > 0.0001) {\n return direction / directionLength;\n }\n\n return vec2f(1.0, 0.0);\n}\n\nfn rotateDirection(direction: vec2f, rotation: f32) -> vec2f {\n let s = sin(rotation);\n let c = cos(rotation);\n return vec2f(direction.x * c - direction.y * s, direction.x * s + direction.y * c);\n}\n\nfn getIridescenceTint(iridescence: f32, thickness: f32, NdotV: f32) -> vec3f {\n if (iridescence <= 0.0) {\n return vec3f(1.0);\n }\n\n let phase = 0.015 * thickness * pbrMaterial.iridescenceIor + (1.0 - NdotV) * 6.0;\n let thinFilmTint =\n 0.5 +\n 0.5 *\n cos(vec3f(phase, phase + 2.0943951, phase + 4.1887902));\n return mix(vec3f(1.0), thinFilmTint, iridescence);\n}\n\nfn getVolumeAttenuation(thickness: f32) -> vec3f {\n if (thickness <= 0.0) {\n return vec3f(1.0);\n }\n\n let attenuationCoefficient =\n -log(max(pbrMaterial.attenuationColor, vec3f(0.0001))) /\n max(pbrMaterial.attenuationDistance, 0.0001);\n return exp(-attenuationCoefficient * thickness);\n}\n\nfn createClearcoatPBRInfo(\n basePBRInfo: PBRInfo,\n clearcoatNormal: vec3f,\n clearcoatRoughness: f32\n) -> PBRInfo {\n let perceptualRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);\n let alphaRoughness = perceptualRoughness * perceptualRoughness;\n let NdotV = clamp(abs(dot(clearcoatNormal, basePBRInfo.v)), 0.001, 1.0);\n\n return PBRInfo(\n basePBRInfo.NdotL,\n NdotV,\n basePBRInfo.NdotH,\n basePBRInfo.LdotH,\n basePBRInfo.VdotH,\n perceptualRoughness,\n 0.0,\n vec3f(0.04),\n vec3f(1.0),\n alphaRoughness,\n vec3f(0.0),\n vec3f(0.04),\n clearcoatNormal,\n basePBRInfo.v\n );\n}\n\nfn calculateClearcoatContribution(\n pbrInfo: PBRInfo,\n lightColor: vec3f,\n clearcoatNormal: vec3f,\n clearcoatFactor: f32,\n clearcoatRoughness: f32\n) -> vec3f {\n if (clearcoatFactor <= 0.0) {\n return vec3f(0.0);\n }\n\n let clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);\n return calculateFinalColor(clearcoatPBRInfo, lightColor) * clearcoatFactor;\n}\n\n#ifdef USE_IBL\nfn calculateClearcoatIBLContribution(\n pbrInfo: PBRInfo,\n clearcoatNormal: vec3f,\n reflection: vec3f,\n clearcoatFactor: f32,\n clearcoatRoughness: f32\n) -> vec3f {\n if (clearcoatFactor <= 0.0) {\n return vec3f(0.0);\n }\n\n let clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);\n return getIBLContribution(clearcoatPBRInfo, clearcoatNormal, reflection) * clearcoatFactor;\n}\n#endif\n\nfn calculateSheenContribution(\n pbrInfo: PBRInfo,\n lightColor: vec3f,\n sheenColor: vec3f,\n sheenRoughness: f32\n) -> vec3f {\n if (maxComponent(sheenColor) <= 0.0) {\n return vec3f(0.0);\n }\n\n let sheenFresnel = pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);\n let sheenVisibility = mix(1.0, pbrInfo.NdotL * pbrInfo.NdotV, sheenRoughness);\n return pbrInfo.NdotL *\n lightColor *\n sheenColor *\n (0.25 + 0.75 * sheenFresnel) *\n sheenVisibility *\n (1.0 - pbrInfo.metalness);\n}\n\nfn calculateAnisotropyBoost(\n pbrInfo: PBRInfo,\n anisotropyTangent: vec3f,\n anisotropyStrength: f32\n) -> f32 {\n if (anisotropyStrength <= 0.0) {\n return 1.0;\n }\n\n let anisotropyBitangent = normalize(cross(pbrInfo.n, anisotropyTangent));\n let bitangentViewAlignment = abs(dot(pbrInfo.v, anisotropyBitangent));\n return mix(1.0, 0.65 + 0.7 * bitangentViewAlignment, anisotropyStrength);\n}\n\nfn calculateMaterialLightColor(\n pbrInfo: PBRInfo,\n lightColor: vec3f,\n clearcoatNormal: vec3f,\n clearcoatFactor: f32,\n clearcoatRoughness: f32,\n sheenColor: vec3f,\n sheenRoughness: f32,\n anisotropyTangent: vec3f,\n anisotropyStrength: f32\n) -> vec3f {\n let anisotropyBoost = calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);\n var color = calculateFinalColor(pbrInfo, lightColor) * anisotropyBoost;\n color += calculateClearcoatContribution(\n pbrInfo,\n lightColor,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness\n );\n color += calculateSheenContribution(pbrInfo, lightColor, sheenColor, sheenRoughness);\n return color;\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 - fragmentInputs.pbr_vPosition);\n PBRInfo_setDirectionalLight(pbrInfo, light_direction);\n}\n\nfn PBRInfo_setSpotLight(pbrInfo: ptr<function, PBRInfo>, spotLight: SpotLight) {\n let light_direction = normalize(spotLight.position - fragmentInputs.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 let baseColorUV = getMaterialUV(pbrMaterial.baseColorUVSet, pbrMaterial.baseColorUVTransform);\n let metallicRoughnessUV = getMaterialUV(\n pbrMaterial.metallicRoughnessUVSet,\n pbrMaterial.metallicRoughnessUVTransform\n );\n let normalUV = getMaterialUV(pbrMaterial.normalUVSet, pbrMaterial.normalUVTransform);\n let occlusionUV = getMaterialUV(pbrMaterial.occlusionUVSet, pbrMaterial.occlusionUVTransform);\n let emissiveUV = getMaterialUV(pbrMaterial.emissiveUVSet, pbrMaterial.emissiveUVTransform);\n let specularColorUV = getMaterialUV(\n pbrMaterial.specularColorUVSet,\n pbrMaterial.specularColorUVTransform\n );\n let specularIntensityUV = getMaterialUV(\n pbrMaterial.specularIntensityUVSet,\n pbrMaterial.specularIntensityUVTransform\n );\n let transmissionUV = getMaterialUV(\n pbrMaterial.transmissionUVSet,\n pbrMaterial.transmissionUVTransform\n );\n let thicknessUV = getMaterialUV(pbrMaterial.thicknessUVSet, pbrMaterial.thicknessUVTransform);\n let clearcoatUV = getMaterialUV(pbrMaterial.clearcoatUVSet, pbrMaterial.clearcoatUVTransform);\n let clearcoatRoughnessUV = getMaterialUV(\n pbrMaterial.clearcoatRoughnessUVSet,\n pbrMaterial.clearcoatRoughnessUVTransform\n );\n let clearcoatNormalUV = getMaterialUV(\n pbrMaterial.clearcoatNormalUVSet,\n pbrMaterial.clearcoatNormalUVTransform\n );\n let sheenColorUV = getMaterialUV(\n pbrMaterial.sheenColorUVSet,\n pbrMaterial.sheenColorUVTransform\n );\n let sheenRoughnessUV = getMaterialUV(\n pbrMaterial.sheenRoughnessUVSet,\n pbrMaterial.sheenRoughnessUVTransform\n );\n let iridescenceUV = getMaterialUV(\n pbrMaterial.iridescenceUVSet,\n pbrMaterial.iridescenceUVTransform\n );\n let iridescenceThicknessUV = getMaterialUV(\n pbrMaterial.iridescenceThicknessUVSet,\n pbrMaterial.iridescenceThicknessUVTransform\n );\n let anisotropyUV = getMaterialUV(\n pbrMaterial.anisotropyUVSet,\n pbrMaterial.anisotropyUVTransform\n );\n\n // The albedo may be defined from a base texture or a flat color\n var baseColor: vec4<f32> = pbrMaterial.baseColorFactor;\n #ifdef HAS_BASECOLORMAP\n baseColor = SRGBtoLINEAR(\n textureSample(pbr_baseColorSampler, pbr_baseColorSamplerSampler, baseColorUV)\n ) * 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 var transmission = 0.0;\n\n if (pbrMaterial.unlit != 0u) {\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(\n pbr_metallicRoughnessSampler,\n pbr_metallicRoughnessSamplerSampler,\n metallicRoughnessUV\n );\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 let tbn = getTBN(normalUV);\n let n = getNormal(tbn, normalUV); // normal at surface point\n let v = normalize(pbrProjection.camera - fragmentInputs.pbr_vPosition); // Vector from surface point to camera\n let NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);\n var useExtendedPBR = false;\n #ifdef USE_MATERIAL_EXTENSIONS\n useExtendedPBR =\n pbrMaterial.specularColorMapEnabled != 0 ||\n pbrMaterial.specularIntensityMapEnabled != 0 ||\n abs(pbrMaterial.specularIntensityFactor - 1.0) > 0.0001 ||\n maxComponent(abs(pbrMaterial.specularColorFactor - vec3f(1.0))) > 0.0001 ||\n abs(pbrMaterial.ior - 1.5) > 0.0001 ||\n pbrMaterial.transmissionMapEnabled != 0 ||\n pbrMaterial.transmissionFactor > 0.0001 ||\n pbrMaterial.clearcoatMapEnabled != 0 ||\n pbrMaterial.clearcoatRoughnessMapEnabled != 0 ||\n pbrMaterial.clearcoatFactor > 0.0001 ||\n pbrMaterial.clearcoatRoughnessFactor > 0.0001 ||\n pbrMaterial.sheenColorMapEnabled != 0 ||\n pbrMaterial.sheenRoughnessMapEnabled != 0 ||\n maxComponent(pbrMaterial.sheenColorFactor) > 0.0001 ||\n pbrMaterial.sheenRoughnessFactor > 0.0001 ||\n pbrMaterial.iridescenceMapEnabled != 0 ||\n pbrMaterial.iridescenceFactor > 0.0001 ||\n abs(pbrMaterial.iridescenceIor - 1.3) > 0.0001 ||\n abs(pbrMaterial.iridescenceThicknessRange.x - 100.0) > 0.0001 ||\n abs(pbrMaterial.iridescenceThicknessRange.y - 400.0) > 0.0001 ||\n pbrMaterial.anisotropyMapEnabled != 0 ||\n pbrMaterial.anisotropyStrength > 0.0001 ||\n abs(pbrMaterial.anisotropyRotation) > 0.0001 ||\n length(pbrMaterial.anisotropyDirection - vec2f(1.0, 0.0)) > 0.0001;\n #endif\n\n if (!useExtendedPBR) {\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 let reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);\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 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 PBRInfo_setAmbientLight(&pbrInfo);\n color += calculateFinalColor(pbrInfo, lighting.ambientColor);\n\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 for (var i = 0; i < lighting.pointLightCount; i++) {\n if (i < lighting.pointLightCount) {\n PBRInfo_setPointLight(&pbrInfo, lighting_getPointLight(i));\n let attenuation = getPointLightAttenuation(\n lighting_getPointLight(i),\n distance(lighting_getPointLight(i).position, fragmentInputs.pbr_vPosition)\n );\n color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);\n }\n }\n\n for (var i = 0; i < lighting.spotLightCount; i++) {\n if (i < lighting.spotLightCount) {\n PBRInfo_setSpotLight(&pbrInfo, lighting_getSpotLight(i));\n let attenuation = getSpotLightAttenuation(\n lighting_getSpotLight(i),\n fragmentInputs.pbr_vPosition\n );\n color += calculateFinalColor(pbrInfo, lighting_getSpotLight(i).color / attenuation);\n }\n }\n #endif\n\n #ifdef USE_IBL\n if (pbrMaterial.IBLenabled != 0) {\n color += getIBLContribution(pbrInfo, n, reflection);\n }\n #endif\n\n #ifdef HAS_OCCLUSIONMAP\n if (pbrMaterial.occlusionMapEnabled != 0) {\n let ao = textureSample(pbr_occlusionSampler, pbr_occlusionSamplerSampler, occlusionUV).r;\n color = mix(color, color * ao, pbrMaterial.occlusionStrength);\n }\n #endif\n\n var emissive = pbrMaterial.emissiveFactor;\n #ifdef HAS_EMISSIVEMAP\n if (pbrMaterial.emissiveMapEnabled != 0u) {\n emissive *= SRGBtoLINEAR(\n textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, emissiveUV)\n ).rgb;\n }\n #endif\n color += emissive * pbrMaterial.emissiveStrength;\n\n #ifdef PBR_DEBUG\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 return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), baseColor.a);\n }\n\n var specularIntensity = pbrMaterial.specularIntensityFactor;\n #ifdef HAS_SPECULARINTENSITYMAP\n if (pbrMaterial.specularIntensityMapEnabled != 0) {\n specularIntensity *= textureSample(\n pbr_specularIntensitySampler,\n pbr_specularIntensitySamplerSampler,\n specularIntensityUV\n ).a;\n }\n #endif\n\n var specularFactor = pbrMaterial.specularColorFactor;\n #ifdef HAS_SPECULARCOLORMAP\n if (pbrMaterial.specularColorMapEnabled != 0) {\n specularFactor *= SRGBtoLINEAR(\n textureSample(\n pbr_specularColorSampler,\n pbr_specularColorSamplerSampler,\n specularColorUV\n )\n ).rgb;\n }\n #endif\n\n transmission = pbrMaterial.transmissionFactor;\n #ifdef HAS_TRANSMISSIONMAP\n if (pbrMaterial.transmissionMapEnabled != 0) {\n transmission *= textureSample(\n pbr_transmissionSampler,\n pbr_transmissionSamplerSampler,\n transmissionUV\n ).r;\n }\n #endif\n transmission = clamp(transmission * (1.0 - metallic), 0.0, 1.0);\n var thickness = max(pbrMaterial.thicknessFactor, 0.0);\n #ifdef HAS_THICKNESSMAP\n thickness *= textureSample(\n pbr_thicknessSampler,\n pbr_thicknessSamplerSampler,\n thicknessUV\n ).g;\n #endif\n\n var clearcoatFactor = pbrMaterial.clearcoatFactor;\n var clearcoatRoughness = pbrMaterial.clearcoatRoughnessFactor;\n #ifdef HAS_CLEARCOATMAP\n if (pbrMaterial.clearcoatMapEnabled != 0) {\n clearcoatFactor *= textureSample(\n pbr_clearcoatSampler,\n pbr_clearcoatSamplerSampler,\n clearcoatUV\n ).r;\n }\n #endif\n #ifdef HAS_CLEARCOATROUGHNESSMAP\n if (pbrMaterial.clearcoatRoughnessMapEnabled != 0) {\n clearcoatRoughness *= textureSample(\n pbr_clearcoatRoughnessSampler,\n pbr_clearcoatRoughnessSamplerSampler,\n clearcoatRoughnessUV\n ).g;\n }\n #endif\n clearcoatFactor = clamp(clearcoatFactor, 0.0, 1.0);\n clearcoatRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);\n let clearcoatNormal = getClearcoatNormal(getTBN(clearcoatNormalUV), n, clearcoatNormalUV);\n\n var sheenColor = pbrMaterial.sheenColorFactor;\n var sheenRoughness = pbrMaterial.sheenRoughnessFactor;\n #ifdef HAS_SHEENCOLORMAP\n if (pbrMaterial.sheenColorMapEnabled != 0) {\n sheenColor *= SRGBtoLINEAR(\n textureSample(\n pbr_sheenColorSampler,\n pbr_sheenColorSamplerSampler,\n sheenColorUV\n )\n ).rgb;\n }\n #endif\n #ifdef HAS_SHEENROUGHNESSMAP\n if (pbrMaterial.sheenRoughnessMapEnabled != 0) {\n sheenRoughness *= textureSample(\n pbr_sheenRoughnessSampler,\n pbr_sheenRoughnessSamplerSampler,\n sheenRoughnessUV\n ).a;\n }\n #endif\n sheenRoughness = clamp(sheenRoughness, c_MinRoughness, 1.0);\n\n var iridescence = pbrMaterial.iridescenceFactor;\n #ifdef HAS_IRIDESCENCEMAP\n if (pbrMaterial.iridescenceMapEnabled != 0) {\n iridescence *= textureSample(\n pbr_iridescenceSampler,\n pbr_iridescenceSamplerSampler,\n iridescenceUV\n ).r;\n }\n #endif\n iridescence = clamp(iridescence, 0.0, 1.0);\n var iridescenceThickness = mix(\n pbrMaterial.iridescenceThicknessRange.x,\n pbrMaterial.iridescenceThicknessRange.y,\n 0.5\n );\n #ifdef HAS_IRIDESCENCETHICKNESSMAP\n iridescenceThickness = mix(\n pbrMaterial.iridescenceThicknessRange.x,\n pbrMaterial.iridescenceThicknessRange.y,\n textureSample(\n pbr_iridescenceThicknessSampler,\n pbr_iridescenceThicknessSamplerSampler,\n iridescenceThicknessUV\n ).g\n );\n #endif\n\n var anisotropyStrength = clamp(pbrMaterial.anisotropyStrength, 0.0, 1.0);\n var anisotropyDirection = normalizeDirection(pbrMaterial.anisotropyDirection);\n #ifdef HAS_ANISOTROPYMAP\n if (pbrMaterial.anisotropyMapEnabled != 0) {\n let anisotropySample = textureSample(\n pbr_anisotropySampler,\n pbr_anisotropySamplerSampler,\n anisotropyUV\n ).rgb;\n anisotropyStrength *= anisotropySample.b;\n let mappedDirection = anisotropySample.rg * 2.0 - 1.0;\n if (length(mappedDirection) > 0.0001) {\n anisotropyDirection = normalize(mappedDirection);\n }\n }\n #endif\n anisotropyDirection = rotateDirection(anisotropyDirection, pbrMaterial.anisotropyRotation);\n var anisotropyTangent =\n normalize(tbn[0] * anisotropyDirection.x + tbn[1] * anisotropyDirection.y);\n if (length(anisotropyTangent) < 0.0001) {\n anisotropyTangent = normalize(tbn[0]);\n }\n let anisotropyViewAlignment = abs(dot(v, anisotropyTangent));\n perceptualRoughness = mix(\n perceptualRoughness,\n clamp(perceptualRoughness * (1.0 - 0.6 * anisotropyViewAlignment), c_MinRoughness, 1.0),\n anisotropyStrength\n );\n\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 dielectricF0 = getDielectricF0(pbrMaterial.ior);\n var dielectricSpecularF0 = min(\n vec3f(dielectricF0) * specularFactor * specularIntensity,\n vec3f(1.0)\n );\n let iridescenceTint = getIridescenceTint(iridescence, iridescenceThickness, NdotV);\n dielectricSpecularF0 = mix(\n dielectricSpecularF0,\n dielectricSpecularF0 * iridescenceTint,\n iridescence\n );\n var diffuseColor = baseColor.rgb * (vec3f(1.0) - dielectricSpecularF0);\n diffuseColor *= (1.0 - metallic) * (1.0 - transmission);\n var specularColor = mix(dielectricSpecularF0, baseColor.rgb, metallic);\n\n let baseLayerEnergy = 1.0 - clearcoatFactor * 0.25;\n diffuseColor *= baseLayerEnergy;\n specularColor *= baseLayerEnergy;\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 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 += calculateMaterialLightColor(\n pbrInfo,\n lighting.ambientColor,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness,\n sheenColor,\n sheenRoughness,\n anisotropyTangent,\n anisotropyStrength\n );\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 += calculateMaterialLightColor(\n pbrInfo,\n lighting_getDirectionalLight(i).color,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness,\n sheenColor,\n sheenRoughness,\n anisotropyTangent,\n anisotropyStrength\n );\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(\n lighting_getPointLight(i),\n distance(lighting_getPointLight(i).position, fragmentInputs.pbr_vPosition)\n );\n color += calculateMaterialLightColor(\n pbrInfo,\n lighting_getPointLight(i).color / attenuation,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness,\n sheenColor,\n sheenRoughness,\n anisotropyTangent,\n anisotropyStrength\n );\n }\n }\n\n for (var i = 0; i < lighting.spotLightCount; i++) {\n if (i < lighting.spotLightCount) {\n PBRInfo_setSpotLight(&pbrInfo, lighting_getSpotLight(i));\n let attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), fragmentInputs.pbr_vPosition);\n color += calculateMaterialLightColor(\n pbrInfo,\n lighting_getSpotLight(i).color / attenuation,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness,\n sheenColor,\n sheenRoughness,\n anisotropyTangent,\n anisotropyStrength\n );\n }\n }\n #endif\n\n // Calculate lighting contribution from image based lighting source (IBL)\n #ifdef USE_IBL\n if (pbrMaterial.IBLenabled != 0) {\n color += getIBLContribution(pbrInfo, n, reflection) *\n calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);\n color += calculateClearcoatIBLContribution(\n pbrInfo,\n clearcoatNormal,\n -normalize(reflect(v, clearcoatNormal)),\n clearcoatFactor,\n clearcoatRoughness\n );\n color += sheenColor * pbrMaterial.scaleIBLAmbient.x * (1.0 - sheenRoughness) * 0.25;\n }\n #endif\n\n // Apply optional PBR terms for additional (optional) shading\n #ifdef HAS_OCCLUSIONMAP\n if (pbrMaterial.occlusionMapEnabled != 0) {\n let ao = textureSample(pbr_occlusionSampler, pbr_occlusionSamplerSampler, occlusionUV).r;\n color = mix(color, color * ao, pbrMaterial.occlusionStrength);\n }\n #endif\n\n var emissive = pbrMaterial.emissiveFactor;\n #ifdef HAS_EMISSIVEMAP\n if (pbrMaterial.emissiveMapEnabled != 0u) {\n emissive *= SRGBtoLINEAR(\n textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, emissiveUV)\n ).rgb;\n }\n #endif\n color += emissive * pbrMaterial.emissiveStrength;\n\n if (transmission > 0.0) {\n color = mix(color, color * getVolumeAttenuation(thickness), transmission);\n }\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 let alpha = clamp(baseColor.a * (1.0 - transmission), 0.0, 1.0);\n return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), alpha);\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {NumberArray3, NumberArray16} from '@math.gl/core';\n\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\n\nconst uniformBlock = /* glsl */ `\\\nlayout(std140) uniform pbrProjectionUniforms {\n mat4 modelViewProjectionMatrix;\n mat4 modelMatrix;\n mat4 normalMatrix;\n vec3 camera;\n} pbrProjection;\n`;\n\nconst wgslUniformBlock = /* wgsl */ `\\\nstruct pbrProjectionUniforms {\n modelViewProjectionMatrix: mat4x4<f32>,\n modelMatrix: mat4x4<f32>,\n normalMatrix: mat4x4<f32>,\n camera: vec3<f32>\n};\n\n@group(0) @binding(auto) var<uniform> pbrProjection: pbrProjectionUniforms;\n`;\n\nexport type PBRProjectionProps = {\n modelViewProjectionMatrix: NumberArray16;\n modelMatrix: NumberArray16;\n normalMatrix: NumberArray16;\n camera: NumberArray3;\n};\n\nexport const pbrProjection: ShaderModule<PBRProjectionProps> = {\n name: 'pbrProjection',\n bindingLayout: [{name: 'pbrProjection', group: 0}],\n source: wgslUniformBlock,\n vs: uniformBlock,\n fs: uniformBlock,\n // TODO why is this needed?\n getUniforms: props => props,\n uniformTypes: {\n modelViewProjectionMatrix: 'mat4x4<f32>',\n modelMatrix: 'mat4x4<f32>',\n normalMatrix: 'mat4x4<f32>',\n camera: 'vec3<f32>'\n }\n};\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* eslint-disable camelcase */\n\nimport type {Texture} from '@luma.gl/core';\nimport type {\n Matrix3,\n Vector2,\n Vector3,\n Vector4,\n NumberArray2,\n NumberArray3,\n NumberArray4,\n NumberArray9\n} from '@math.gl/core';\n\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\nimport {lighting} from '../lights/lighting';\nimport {ibl} from '../ibl/ibl';\n\nimport {vs, fs} from './pbr-material-glsl';\nimport {source} from './pbr-material-wgsl';\nimport {pbrProjection} from './pbr-projection';\n\n/** Non-uniform block bindings for pbr module */\nexport type PBRMaterialBindings = {\n // Samplers\n pbr_baseColorSampler?: Texture | null; // #ifdef HAS_BASECOLORMAP\n pbr_normalSampler?: Texture | null; // #ifdef HAS_NORMALMAP\n pbr_emissiveSampler?: Texture | null; // #ifdef HAS_EMISSIVEMAP\n pbr_metallicRoughnessSampler?: Texture | null; // #ifdef HAS_METALROUGHNESSMAP\n pbr_occlusionSampler?: Texture | null; // #ifdef HAS_OCCLUSIONMAP\n\n pbr_specularColorSampler?: Texture | null; // #ifdef HAS_SPECULARCOLORMAP\n pbr_specularIntensitySampler?: Texture | null; // #ifdef HAS_SPECULARINTENSITYMAP\n pbr_transmissionSampler?: Texture | null; // #ifdef HAS_TRANSMISSIONMAP\n pbr_thicknessSampler?: Texture | null; // #ifdef HAS_THICKNESSMAP\n\n pbr_clearcoatSampler?: Texture | null; // #ifdef HAS_CLEARCOATMAP\n pbr_clearcoatRoughnessSampler?: Texture | null; // #ifdef HAS_CLEARCOATROUGHNESSMAP\n pbr_clearcoatNormalSampler?: Texture | null; // #ifdef HAS_CLEARCOATNORMALMAP\n pbr_sheenColorSampler?: Texture | null; // #ifdef HAS_SHEENCOLORMAP\n pbr_sheenRoughnessSampler?: Texture | null; // #ifdef HAS_SHEENROUGHNESSMAP\n pbr_iridescenceSampler?: Texture | null; // #ifdef HAS_IRIDESCENCEMAP\n pbr_iridescenceThicknessSampler?: Texture | null; // #ifdef HAS_IRIDESCENCETHICKNESSMAP\n pbr_anisotropySampler?: Texture | null; // #ifdef HAS_ANISOTROPYMAP\n};\n\nexport type PBRMaterialUniforms = {\n unlit?: boolean;\n\n // Base color map\n baseColorMapEnabled?: boolean;\n baseColorFactor?: Readonly<Vector4 | NumberArray4>;\n\n normalMapEnabled?: boolean;\n normalScale?: number; // #ifdef HAS_NORMALMAP\n\n emissiveMapEnabled?: boolean;\n emissiveFactor?: Readonly<Vector3 | NumberArray3>; // #ifdef HAS_EMISSIVEMAP\n\n metallicRoughnessValues?: Readonly<Vector2 | NumberArray2>;\n metallicRoughnessMapEnabled?: boolean;\n\n occlusionMapEnabled?: boolean;\n occlusionStrength?: number; // #ifdef HAS_OCCLUSIONMAP\n\n alphaCutoffEnabled?: boolean;\n alphaCutoff?: number; // #ifdef ALPHA_CUTOFF\n\n // IBL\n IBLenabled?: boolean;\n scaleIBLAmbient?: Readonly<Vector2 | NumberArray2>; // #ifdef USE_IBL\n\n // debugging flags used for shader output of intermediate PBR variables\n // #ifdef PBR_DEBUG\n scaleDiffBaseMR?: Readonly<Vector4 | NumberArray4>;\n scaleFGDSpec?: Readonly<Vector4 | NumberArray4>;\n\n // glTF material extensions\n specularColorFactor?: Readonly<Vector3 | NumberArray3>;\n specularIntensityFactor?: number;\n specularColorMapEnabled?: boolean;\n specularIntensityMapEnabled?: boolean;\n\n ior?: number;\n\n transmissionFactor?: number;\n transmissionMapEnabled?: boolean;\n\n thicknessFactor?: number;\n attenuationDistance?: number;\n attenuationColor?: Readonly<Vector3 | NumberArray3>;\n\n clearcoatFactor?: number;\n clearcoatRoughnessFactor?: number;\n clearcoatMapEnabled?: boolean;\n clearcoatRoughnessMapEnabled?: boolean;\n\n sheenColorFactor?: Readonly<Vector3 | NumberArray3>;\n sheenRoughnessFactor?: number;\n sheenColorMapEnabled?: boolean;\n sheenRoughnessMapEnabled?: boolean;\n\n iridescenceFactor?: number;\n iridescenceIor?: number;\n iridescenceThicknessRange?: Readonly<Vector2 | NumberArray2>;\n iridescenceMapEnabled?: boolean;\n\n anisotropyStrength?: number;\n anisotropyRotation?: number;\n anisotropyDirection?: Readonly<Vector2 | NumberArray2>;\n anisotropyMapEnabled?: boolean;\n\n emissiveStrength?: number;\n\n baseColorUVSet?: number;\n baseColorUVTransform?: Readonly<NumberArray9 | Matrix3>;\n metallicRoughnessUVSet?: number;\n metallicRoughnessUVTransform?: Readonly<NumberArray9 | Matrix3>;\n normalUVSet?: number;\n normalUVTransform?: Readonly<NumberArray9 | Matrix3>;\n occlusionUVSet?: number;\n occlusionUVTransform?: Readonly<NumberArray9 | Matrix3>;\n emissiveUVSet?: number;\n emissiveUVTransform?: Readonly<NumberArray9 | Matrix3>;\n specularColorUVSet?: number;\n specularColorUVTransform?: Readonly<NumberArray9 | Matrix3>;\n specularIntensityUVSet?: number;\n specularIntensityUVTransform?: Readonly<NumberArray9 | Matrix3>;\n transmissionUVSet?: number;\n transmissionUVTransform?: Readonly<NumberArray9 | Matrix3>;\n thicknessUVSet?: number;\n thicknessUVTransform?: Readonly<NumberArray9 | Matrix3>;\n clearcoatUVSet?: number;\n clearcoatUVTransform?: Readonly<NumberArray9 | Matrix3>;\n clearcoatRoughnessUVSet?: number;\n clearcoatRoughnessUVTransform?: Readonly<NumberArray9 | Matrix3>;\n clearcoatNormalUVSet?: number;\n clearcoatNormalUVTransform?: Readonly<NumberArray9 | Matrix3>;\n sheenColorUVSet?: number;\n sheenColorUVTransform?: Readonly<NumberArray9 | Matrix3>;\n sheenRoughnessUVSet?: number;\n sheenRoughnessUVTransform?: Readonly<NumberArray9 | Matrix3>;\n iridescenceUVSet?: number;\n iridescenceUVTransform?: Readonly<NumberArray9 | Matrix3>;\n iridescenceThicknessUVSet?: number;\n iridescenceThicknessUVTransform?: Readonly<NumberArray9 | Matrix3>;\n anisotropyUVSet?: number;\n anisotropyUVTransform?: Readonly<NumberArray9 | Matrix3>;\n};\n\nexport type PBRMaterialProps = PBRMaterialBindings & PBRMaterialUniforms;\n\n/**\n * An implementation of PBR (Physically-Based Rendering).\n * Physically Based Shading of a microfacet surface defined by a glTF material.\n */\nexport const pbrMaterial = {\n props: {} as PBRMaterialProps,\n uniforms: {} as PBRMaterialUniforms,\n defaultUniforms: {\n unlit: false,\n\n baseColorMapEnabled: false,\n baseColorFactor: [1, 1, 1, 1],\n\n normalMapEnabled: false,\n normalScale: 1,\n\n emissiveMapEnabled: false,\n emissiveFactor: [0, 0, 0],\n\n metallicRoughnessValues: [1, 1],\n metallicRoughnessMapEnabled: false,\n\n occlusionMapEnabled: false,\n occlusionStrength: 1,\n\n alphaCutoffEnabled: false,\n alphaCutoff: 0.5,\n\n IBLenabled: false,\n scaleIBLAmbient: [1, 1],\n\n scaleDiffBaseMR: [0, 0, 0, 0],\n scaleFGDSpec: [0, 0, 0, 0],\n\n specularColorFactor: [1, 1, 1],\n specularIntensityFactor: 1,\n specularColorMapEnabled: false,\n specularIntensityMapEnabled: false,\n\n ior: 1.5,\n\n transmissionFactor: 0,\n transmissionMapEnabled: false,\n\n thicknessFactor: 0,\n attenuationDistance: 1e9,\n attenuationColor: [1, 1, 1],\n\n clearcoatFactor: 0,\n clearcoatRoughnessFactor: 0,\n clearcoatMapEnabled: false,\n clearcoatRoughnessMapEnabled: false,\n\n sheenColorFactor: [0, 0, 0],\n sheenRoughnessFactor: 0,\n sheenColorMapEnabled: false,\n sheenRoughnessMapEnabled: false,\n\n iridescenceFactor: 0,\n iridescenceIor: 1.3,\n iridescenceThicknessRange: [100, 400],\n iridescenceMapEnabled: false,\n\n anisotropyStrength: 0,\n anisotropyRotation: 0,\n anisotropyDirection: [1, 0],\n anisotropyMapEnabled: false,\n\n emissiveStrength: 1,\n\n baseColorUVSet: 0,\n baseColorUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n metallicRoughnessUVSet: 0,\n metallicRoughnessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n normalUVSet: 0,\n normalUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n occlusionUVSet: 0,\n occlusionUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n emissiveUVSet: 0,\n emissiveUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n specularColorUVSet: 0,\n specularColorUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n specularIntensityUVSet: 0,\n specularIntensityUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n transmissionUVSet: 0,\n transmissionUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n thicknessUVSet: 0,\n thicknessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n clearcoatUVSet: 0,\n clearcoatUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n clearcoatRoughnessUVSet: 0,\n clearcoatRoughnessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n clearcoatNormalUVSet: 0,\n clearcoatNormalUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n sheenColorUVSet: 0,\n sheenColorUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n sheenRoughnessUVSet: 0,\n sheenRoughnessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n iridescenceUVSet: 0,\n iridescenceUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n iridescenceThicknessUVSet: 0,\n iridescenceThicknessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n anisotropyUVSet: 0,\n anisotropyUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1]\n } as Required<PBRMaterialUniforms>,\n\n name: 'pbrMaterial',\n firstBindingSlot: 0,\n bindingLayout: [\n {name: 'pbrMaterial', group: 3},\n {name: 'pbr_baseColorSampler', group: 3},\n {name: 'pbr_normalSampler', group: 3},\n {name: 'pbr_emissiveSampler', group: 3},\n {name: 'pbr_metallicRoughnessSampler', group: 3},\n {name: 'pbr_occlusionSampler', group: 3},\n {name: 'pbr_specularColorSampler', group: 3},\n {name: 'pbr_specularIntensitySampler', group: 3},\n {name: 'pbr_transmissionSampler', group: 3},\n {name: 'pbr_thicknessSampler', group: 3},\n {name: 'pbr_clearcoatSampler', group: 3},\n {name: 'pbr_clearcoatRoughnessSampler', group: 3},\n {name: 'pbr_clearcoatNormalSampler', group: 3},\n {name: 'pbr_sheenColorSampler', group: 3},\n {name: 'pbr_sheenRoughnessSampler', group: 3},\n {name: 'pbr_iridescenceSampler', group: 3},\n {name: 'pbr_iridescenceThicknessSampler', group: 3},\n {name: 'pbr_anisotropySampler', group: 3}\n ],\n dependencies: [lighting, ibl, pbrProjection],\n source,\n vs,\n fs,\n\n defines: {\n LIGHTING_FRAGMENT: true,\n HAS_NORMALMAP: false,\n HAS_EMISSIVEMAP: false,\n HAS_OCCLUSIONMAP: false,\n HAS_BASECOLORMAP: false,\n HAS_METALROUGHNESSMAP: false,\n HAS_SPECULARCOLORMAP: false,\n HAS_SPECULARINTENSITYMAP: false,\n HAS_TRANSMISSIONMAP: false,\n HAS_THICKNESSMAP: false,\n HAS_CLEARCOATMAP: false,\n HAS_CLEARCOATROUGHNESSMAP: false,\n HAS_CLEARCOATNORMALMAP: false,\n HAS_SHEENCOLORMAP: false,\n HAS_SHEENROUGHNESSMAP: false,\n HAS_IRIDESCENCEMAP: false,\n HAS_IRIDESCENCETHICKNESSMAP: false,\n HAS_ANISOTROPYMAP: false,\n USE_MATERIAL_EXTENSIONS: false,\n ALPHA_CUTOFF: false,\n USE_IBL: false,\n PBR_DEBUG: false\n },\n getUniforms: props => props,\n uniformTypes: {\n // Material is unlit\n unlit: 'i32',\n\n // Base color map\n baseColorMapEnabled: 'i32',\n baseColorFactor: 'vec4<f32>',\n\n normalMapEnabled: 'i32',\n normalScale: 'f32', // #ifdef HAS_NORMALMAP\n\n emissiveMapEnabled: 'i32',\n emissiveFactor: 'vec3<f32>', // #ifdef HAS_EMISSIVEMAP\n\n metallicRoughnessValues: 'vec2<f32>',\n metallicRoughnessMapEnabled: 'i32',\n\n occlusionMapEnabled: 'i32',\n occlusionStrength: 'f32', // #ifdef HAS_OCCLUSIONMAP\n\n alphaCutoffEnabled: 'i32',\n alphaCutoff: 'f32', // #ifdef ALPHA_CUTOFF\n\n specularColorFactor: 'vec3<f32>',\n specularIntensityFactor: 'f32',\n specularColorMapEnabled: 'i32',\n specularIntensityMapEnabled: 'i32',\n\n ior: 'f32',\n\n transmissionFactor: 'f32',\n transmissionMapEnabled: 'i32',\n\n thicknessFactor: 'f32',\n attenuationDistance: 'f32',\n attenuationColor: 'vec3<f32>',\n\n clearcoatFactor: 'f32',\n clearcoatRoughnessFactor: 'f32',\n clearcoatMapEnabled: 'i32',\n clearcoatRoughnessMapEnabled: 'i32',\n\n sheenColorFactor: 'vec3<f32>',\n sheenRoughnessFactor: 'f32',\n sheenColorMapEnabled: 'i32',\n sheenRoughnessMapEnabled: 'i32',\n\n iridescenceFactor: 'f32',\n iridescenceIor: 'f32',\n iridescenceThicknessRange: 'vec2<f32>',\n iridescenceMapEnabled: 'i32',\n\n anisotropyStrength: 'f32',\n anisotropyRotation: 'f32',\n anisotropyDirection: 'vec2<f32>',\n anisotropyMapEnabled: 'i32',\n\n emissiveStrength: 'f32',\n\n // IBL\n IBLenabled: 'i32',\n scaleIBLAmbient: 'vec2<f32>', // #ifdef USE_IBL\n\n // debugging flags used for shader output of intermediate PBR variables\n // #ifdef PBR_DEBUG\n scaleDiffBaseMR: 'vec4<f32>',\n scaleFGDSpec: 'vec4<f32>',\n\n baseColorUVSet: 'i32',\n baseColorUVTransform: 'mat3x3<f32>',\n metallicRoughnessUVSet: 'i32',\n metallicRoughnessUVTransform: 'mat3x3<f32>',\n normalUVSet: 'i32',\n normalUVTransform: 'mat3x3<f32>',\n occlusionUVSet: 'i32',\n occlusionUVTransform: 'mat3x3<f32>',\n emissiveUVSet: 'i32',\n emissiveUVTransform: 'mat3x3<f32>',\n specularColorUVSet: 'i32',\n specularColorUVTransform: 'mat3x3<f32>',\n specularIntensityUVSet: 'i32',\n specularIntensityUVTransform: 'mat3x3<f32>',\n transmissionUVSet: 'i32',\n transmissionUVTransform: 'mat3x3<f32>',\n thicknessUVSet: 'i32',\n thicknessUVTransform: 'mat3x3<f32>',\n clearcoatUVSet: 'i32',\n clearcoatUVTransform: 'mat3x3<f32>',\n clearcoatRoughnessUVSet: 'i32',\n clearcoatRoughnessUVTransform: 'mat3x3<f32>',\n clearcoatNormalUVSet: 'i32',\n clearcoatNormalUVTransform: 'mat3x3<f32>',\n sheenColorUVSet: 'i32',\n sheenColorUVTransform: 'mat3x3<f32>',\n sheenRoughnessUVSet: 'i32',\n sheenRoughnessUVTransform: 'mat3x3<f32>',\n iridescenceUVSet: 'i32',\n iridescenceUVTransform: 'mat3x3<f32>',\n iridescenceThicknessUVSet: 'i32',\n iridescenceThicknessUVTransform: 'mat3x3<f32>',\n anisotropyUVSet: 'i32',\n anisotropyUVTransform: 'mat3x3<f32>'\n }\n} as const satisfies ShaderModule<PBRMaterialProps, PBRMaterialUniforms, PBRMaterialBindings>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {Texture} from '@luma.gl/core';\nimport type {NumberArray2, NumberArray16} from '@math.gl/core';\n\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\n\nexport type PBRSceneBindings = {\n pbr_transmissionFramebufferSampler?: Texture | null;\n};\n\nexport type PBRSceneUniforms = {\n exposure?: number;\n toneMapMode?: number;\n environmentIntensity?: number;\n environmentRotation?: number;\n framebufferSize?: NumberArray2;\n viewMatrix?: NumberArray16;\n projectionMatrix?: NumberArray16;\n};\n\nexport type PBRSceneProps = PBRSceneBindings & PBRSceneUniforms;\n\nconst IDENTITY_MATRIX: NumberArray16 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];\n\nconst uniformBlock = /* glsl */ `\\\nlayout(std140) uniform pbrSceneUniforms {\n float exposure;\n int toneMapMode;\n float environmentIntensity;\n float environmentRotation;\n vec2 framebufferSize;\n mat4 viewMatrix;\n mat4 projectionMatrix;\n} pbrScene;\n\n#ifdef USE_TRANSMISSION_FRAMEBUFFER\nuniform sampler2D pbr_transmissionFramebufferSampler;\n#endif\n`;\n\nconst wgslUniformBlock = /* wgsl */ `\\\nstruct pbrSceneUniforms {\n exposure: f32,\n toneMapMode: i32,\n environmentIntensity: f32,\n environmentRotation: f32,\n framebufferSize: vec2<f32>,\n viewMatrix: mat4x4<f32>,\n projectionMatrix: mat4x4<f32>\n};\n\n@group(1) @binding(auto) var<uniform> pbrScene: pbrSceneUniforms;\n\n#ifdef USE_TRANSMISSION_FRAMEBUFFER\n@group(1) @binding(auto) var pbr_transmissionFramebufferSampler: texture_2d<f32>;\n@group(1) @binding(auto) var pbr_transmissionFramebufferSamplerSampler: sampler;\n#endif\n`;\n\nexport const pbrScene = {\n name: 'pbrScene',\n bindingLayout: [\n {name: 'pbrScene', group: 1},\n {name: 'pbr_transmissionFramebufferSampler', group: 1}\n ],\n source: wgslUniformBlock,\n vs: uniformBlock,\n fs: uniformBlock,\n getUniforms: (props: PBRSceneProps) => props,\n uniformTypes: {\n exposure: 'f32',\n toneMapMode: 'i32',\n environmentIntensity: 'f32',\n environmentRotation: 'f32',\n framebufferSize: 'vec2<f32>',\n viewMatrix: 'mat4x4<f32>',\n projectionMatrix: 'mat4x4<f32>'\n },\n defaultUniforms: {\n exposure: 1,\n toneMapMode: 2,\n environmentIntensity: 1,\n environmentRotation: Math.PI * 0.5,\n framebufferSize: [1, 1],\n viewMatrix: IDENTITY_MATRIX,\n projectionMatrix: IDENTITY_MATRIX\n } as Required<PBRSceneUniforms>\n} as const satisfies ShaderModule<PBRSceneProps, PBRSceneUniforms, PBRSceneBindings>;\n"],
|
|
5
|
-
"mappings": "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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC2FtB,IAAMC;;EAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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",
|
|
6
|
-
"names": ["source", "module", "log", "_a", "module", "module", "log", "source", "source", "source", "source", "source", "vs", "fs", "log", "module", "getUniforms", "location", "source", "module", "source", "getUniforms", "module", "module", "module", "fs", "import_core", "source", "vs", "fs", "import_core", "getUniforms", "getUniforms", "vs", "fs", "source", "source", "vs", "fs", "uniformBlock", "wgslUniformBlock"]
|
|
4
|
+
"sourcesContent": ["// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// shadertools exports\n\n/**\n * Marks GLSL shaders for syntax highlighting: glsl`...`\n * Install https://marketplace.visualstudio.com/items?itemName=boyswan.glsl-literal\n */\nexport type {PlatformInfo} from './lib/shader-assembly/platform-info';\nexport type {ShaderBindingDebugRow} from './lib/shader-assembly/wgsl-binding-debug';\n\n// ShaderModules\n\nexport type {ShaderModule} from './lib/shader-module/shader-module';\nexport type {ShaderPass} from './lib/shader-module/shader-pass';\nexport type {ShaderModuleUniformValue, UniformTypes} from './lib/utils/uniform-types';\n\nexport {initializeShaderModule, initializeShaderModules} from './lib/shader-module/shader-module';\nexport {getShaderModuleUniforms} from './lib/shader-module/shader-module';\nexport {getShaderModuleDependencies} from './lib/shader-module/shader-module-dependencies';\nexport {checkShaderModuleDeprecations} from './lib/shader-module/shader-module';\nexport type {\n GLSLUniformBlockInfo,\n ShaderModuleUniformLayoutStage,\n ShaderModuleUniformLayoutValidationResult\n} from './lib/shader-module/shader-module-uniform-layout';\nexport {\n getGLSLUniformBlocks,\n getShaderModuleUniformBlockFields,\n getShaderModuleUniformBlockName,\n getShaderModuleUniformLayoutValidationResult,\n validateShaderModuleUniformLayout,\n warnIfGLSLUniformBlocksAreNotStd140\n} from './lib/shader-module/shader-module-uniform-layout';\n\nexport {getShaderModuleSource} from './lib/shader-assembly/assemble-shaders';\n\nexport {resolveModules as _resolveModules} from './lib/shader-module/shader-module-dependencies';\nexport {getDependencyGraph as _getDependencyGraph} from './lib/shader-module/shader-module-dependencies';\n\n// ShaderAssembler\nexport {ShaderAssembler} from './lib/shader-assembler';\nexport type {ShaderHook} from './lib/shader-assembly/shader-hooks';\nexport type {ShaderInjection} from './lib/shader-assembly/shader-injections';\n\n// SHADER HELPERS\n\n// Shader source introspection\nexport {getShaderInfo} from './lib/glsl-utils/get-shader-info';\nexport {\n getQualifierDetails,\n getPassthroughFS,\n typeToChannelSuffix,\n typeToChannelCount,\n convertToVec4\n} from './lib/glsl-utils/shader-utils';\n\n// EXPERIMENTAL - Do not use in production applications\nexport type {ShaderGenerationOptions} from './lib/shader-generator/generate-shader';\nexport {generateShaderForModule} from './lib/shader-generator/generate-shader';\nexport {capitalize} from './lib/shader-generator/utils/capitalize';\n\n// TEST EXPORTS - Do not use in production applications\nexport {preprocess} from './lib/preprocessor/preprocessor';\nexport {assembleGLSLShaderPair} from './lib/shader-assembly/assemble-shaders';\nexport {combineInjects} from './lib/shader-assembly/shader-injections';\n\n// data utils\nexport {toHalfFloat, fromHalfFloat} from './modules/math/fp16/fp16-utils';\nexport {fp64ify, fp64LowPart, fp64ifyMatrix4} from './modules/math/fp64/fp64-utils';\nexport {\n normalizeByteColor3,\n normalizeByteColor4,\n resolveUseByteColors\n} from './lib/color/normalize-byte-colors';\n\n// math libraries\nexport {random} from './modules/math/random/random';\n\nexport {fp32} from './modules/math/fp32/fp32';\nexport {fp64, fp64arithmetic} from './modules/math/fp64/fp64';\nexport type {FloatColorsProps, FloatColorsUniforms} from './modules/color/float-colors';\nexport {floatColors} from './modules/color/float-colors';\n\n// engine shader modules\n\n// projection\n// export type {ProjectionUniforms} from './modules/engine/project/project';\n// export {projection} from './modules/engine/project/project';\nexport type {PickingProps, PickingUniforms} from './modules/engine/picking/picking';\nexport {picking} from './modules/engine/picking/picking';\nexport {skin} from './modules/engine/skin/skin';\n\n// lighting\nexport {\n type Light,\n type AmbientLight,\n type PointLight,\n type SpotLight,\n type DirectionalLight,\n type LightingLightUniform\n} from './modules/lighting/lights/lighting';\n\nexport type {LightingProps, LightingUniforms} from './modules/lighting/lights/lighting';\nexport {lighting} from './modules/lighting/lights/lighting';\nexport type {IBLBindings} from './modules/lighting/ibl/ibl';\nexport {ibl} from './modules/lighting/ibl/ibl';\nexport {dirlight} from './modules/lighting/no-material/dirlight';\nexport type {LambertMaterialProps} from './modules/lighting/lambert-material/lambert-material';\nexport {lambertMaterial} from './modules/lighting/lambert-material/lambert-material';\nexport type {GouraudMaterialProps} from './modules/lighting/gouraud-material/gouraud-material';\nexport {gouraudMaterial} from './modules/lighting/gouraud-material/gouraud-material';\nexport type {PhongMaterialProps} from './modules/lighting/phong-material/phong-material';\nexport {phongMaterial} from './modules/lighting/phong-material/phong-material';\nexport type {\n PBRMaterialBindings,\n PBRMaterialProps,\n PBRMaterialUniforms\n} from './modules/lighting/pbr-material/pbr-material';\nexport type {\n PBRSceneBindings,\n PBRSceneProps,\n PBRSceneUniforms\n} from './modules/lighting/pbr-material/pbr-scene';\nexport type {PBRProjectionProps} from './modules/lighting/pbr-material/pbr-projection';\n\nexport {pbrMaterial} from './modules/lighting/pbr-material/pbr-material';\nexport {pbrScene} from './modules/lighting/pbr-material/pbr-scene';\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// Recommendation is to ignore message but current test suite checks agains the\n// message so keep it for now.\nexport function assert(condition: unknown, message?: string): void {\n if (!condition) {\n const error = new Error(message || 'shadertools: assertion failed.');\n Error.captureStackTrace?.(error, assert);\n throw error;\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {assert} from '../utils/assert';\n\n/**\n * For use by shader module and shader pass writers to describe the types of the\n * properties they expose (properties ultimately map to uniforms).\n */\nexport type PropType =\n | {\n type?: string;\n value?: unknown;\n max?: number;\n min?: number;\n softMax?: number;\n softMin?: number;\n hint?: string;\n /** @deprecated internal uniform */\n private?: boolean;\n }\n | number;\n\n/**\n * Internal property validators generated by processing the prop types ,\n * The `validate()` method can be used to validate the type of properties passed in to\n * shader module or shader pass\n */\nexport type PropValidator = {\n type: string;\n value?: unknown;\n max?: number;\n min?: number;\n private?: boolean;\n validate?(value: unknown, propDef: PropValidator): boolean;\n};\n\n/** Minimal validators for number and array types */\nconst DEFAULT_PROP_VALIDATORS: Record<string, PropValidator> = {\n number: {\n type: 'number',\n validate(value: unknown, propType: PropType) {\n return (\n Number.isFinite(value) &&\n typeof propType === 'object' &&\n (propType.max === undefined || (value as number) <= propType.max) &&\n (propType.min === undefined || (value as number) >= propType.min)\n );\n }\n },\n array: {\n type: 'array',\n validate(value: unknown, propType: PropType) {\n return Array.isArray(value) || ArrayBuffer.isView(value);\n }\n }\n};\n\n/**\n * Parse a list of property types into property definitions that can be used to validate\n * values passed in by applications.\n * @param propTypes\n * @returns\n */\nexport function makePropValidators(\n propTypes: Record<string, PropType>\n): Record<string, PropValidator> {\n const propValidators: Record<string, PropValidator> = {};\n for (const [name, propType] of Object.entries(propTypes)) {\n propValidators[name] = makePropValidator(propType);\n }\n return propValidators;\n}\n\n/**\n * Validate a map of user supplied properties against a map of validators\n * Inject default values when user doesn't supply a property\n * @param properties\n * @param propValidators\n * @returns\n */\nexport function getValidatedProperties(\n properties: Record<string, unknown>,\n propValidators: Record<string, PropValidator>,\n errorMessage: string\n): Record<string, unknown> {\n const validated: Record<string, unknown> = {};\n\n for (const [key, propsValidator] of Object.entries(propValidators)) {\n if (properties && key in properties && !propsValidator.private) {\n if (propsValidator.validate) {\n assert(\n propsValidator.validate(properties[key], propsValidator),\n `${errorMessage}: invalid ${key}`\n );\n }\n validated[key] = properties[key];\n } else {\n // property not supplied - use default value\n validated[key] = propsValidator.value;\n }\n }\n\n // TODO - warn for unused properties that don't match a validator?\n\n return validated;\n}\n\n/**\n * Creates a property validator for a prop type. Either contains:\n * - a valid prop type object ({type, ...})\n * - or just a default value, in which case type and name inference is used\n */\nfunction makePropValidator(propType: PropType): PropValidator {\n let type = getTypeOf(propType);\n\n if (type !== 'object') {\n return {value: propType, ...DEFAULT_PROP_VALIDATORS[type], type};\n }\n\n // Special handling for objects\n if (typeof propType === 'object') {\n if (!propType) {\n return {type: 'object', value: null};\n }\n if (propType.type !== undefined) {\n return {...propType, ...DEFAULT_PROP_VALIDATORS[propType.type], type: propType.type};\n }\n // If no type and value this object is likely the value\n if (propType.value === undefined) {\n return {type: 'object', value: propType};\n }\n\n type = getTypeOf(propType.value);\n return {...propType, ...DEFAULT_PROP_VALIDATORS[type], type};\n }\n\n throw new Error('props');\n}\n\n/**\n * \"improved\" version of javascript typeof that can distinguish arrays and null values\n */\nfunction getTypeOf(value: unknown): string {\n if (Array.isArray(value) || ArrayBuffer.isView(value)) {\n return 'array';\n }\n return typeof value;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const MODULE_INJECTORS_VS = /* glsl */ `\\\n#ifdef MODULE_LOGDEPTH\n logdepth_adjustPosition(gl_Position);\n#endif\n`;\n\nexport const MODULE_INJECTORS_FS = /* glsl */ `\\\n#ifdef MODULE_MATERIAL\n fragColor = material_filterColor(fragColor);\n#endif\n\n#ifdef MODULE_LIGHTING\n fragColor = lighting_filterColor(fragColor);\n#endif\n\n#ifdef MODULE_FOG\n fragColor = fog_filterColor(fragColor);\n#endif\n\n#ifdef MODULE_PICKING\n fragColor = picking_filterHighlightColor(fragColor);\n fragColor = picking_filterPickingColor(fragColor);\n#endif\n\n#ifdef MODULE_LOGDEPTH\n logdepth_setFragDepth();\n#endif\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {MODULE_INJECTORS_VS, MODULE_INJECTORS_FS} from '../../module-injectors';\nimport {assert} from '../utils/assert';\n\n// TODO - experimental\nconst MODULE_INJECTORS = {\n vertex: MODULE_INJECTORS_VS,\n fragment: MODULE_INJECTORS_FS\n};\n\nconst REGEX_START_OF_MAIN = /void\\s+main\\s*\\([^)]*\\)\\s*\\{\\n?/; // Beginning of main\nconst REGEX_END_OF_MAIN = /}\\n?[^{}]*$/; // End of main, assumes main is last function\nconst fragments: string[] = [];\n\nexport const DECLARATION_INJECT_MARKER = '__LUMA_INJECT_DECLARATIONS__';\n\n/**\n *\n */\nexport type ShaderInjection = {\n injection: string;\n order: number;\n};\n\n/**\n * ShaderInjections, parsed and split per shader\n */\nexport type ShaderInjections = {\n vertex: Record<string, ShaderInjection>;\n fragment: Record<string, ShaderInjection>;\n};\n\n/**\n *\n */\nexport function normalizeInjections(\n injections: Record<string, string | ShaderInjection>\n): ShaderInjections {\n const result: ShaderInjections = {vertex: {}, fragment: {}};\n\n for (const hook in injections) {\n let injection = injections[hook];\n const stage = getHookStage(hook);\n if (typeof injection === 'string') {\n injection = {\n order: 0,\n injection\n };\n }\n\n result[stage][hook] = injection;\n }\n\n return result;\n}\n\nfunction getHookStage(hook: string): 'vertex' | 'fragment' {\n const type = hook.slice(0, 2);\n switch (type) {\n case 'vs':\n return 'vertex';\n case 'fs':\n return 'fragment';\n default:\n throw new Error(type);\n }\n}\n\n/**\n// A minimal shader injection/templating system.\n// RFC: https://github.com/visgl/luma.gl/blob/7.0-release/dev-docs/RFCs/v6.0/shader-injection-rfc.md\n * @param source \n * @param type \n * @param inject \n * @param injectStandardStubs \n * @returns \n */\n// eslint-disable-next-line complexity\nexport function injectShader(\n source: string,\n stage: 'vertex' | 'fragment',\n inject: Record<string, ShaderInjection[]>,\n injectStandardStubs = false\n): string {\n const isVertex = stage === 'vertex';\n\n for (const key in inject) {\n const fragmentData = inject[key];\n fragmentData.sort((a: ShaderInjection, b: ShaderInjection): number => a.order - b.order);\n fragments.length = fragmentData.length;\n for (let i = 0, len = fragmentData.length; i < len; ++i) {\n fragments[i] = fragmentData[i].injection;\n }\n const fragmentString = `${fragments.join('\\n')}\\n`;\n switch (key) {\n // declarations are injected before the main function\n case 'vs:#decl':\n if (isVertex) {\n source = source.replace(DECLARATION_INJECT_MARKER, fragmentString);\n }\n break;\n // inject code at the beginning of the main function\n case 'vs:#main-start':\n if (isVertex) {\n source = source.replace(REGEX_START_OF_MAIN, (match: string) => match + fragmentString);\n }\n break;\n // inject code at the end of main function\n case 'vs:#main-end':\n if (isVertex) {\n source = source.replace(REGEX_END_OF_MAIN, (match: string) => fragmentString + match);\n }\n break;\n // declarations are injected before the main function\n case 'fs:#decl':\n if (!isVertex) {\n source = source.replace(DECLARATION_INJECT_MARKER, fragmentString);\n }\n break;\n // inject code at the beginning of the main function\n case 'fs:#main-start':\n if (!isVertex) {\n source = source.replace(REGEX_START_OF_MAIN, (match: string) => match + fragmentString);\n }\n break;\n // inject code at the end of main function\n case 'fs:#main-end':\n if (!isVertex) {\n source = source.replace(REGEX_END_OF_MAIN, (match: string) => fragmentString + match);\n }\n break;\n\n default:\n // TODO(Tarek): I think this usage should be deprecated.\n\n // inject code after key, leaving key in place\n source = source.replace(key, (match: string) => match + fragmentString);\n }\n }\n\n // Remove if it hasn't already been replaced\n source = source.replace(DECLARATION_INJECT_MARKER, '');\n\n // Finally, if requested, insert an automatic module injector chunk\n if (injectStandardStubs) {\n source = source.replace(/\\}\\s*$/, (match: string) => match + MODULE_INJECTORS[stage]);\n }\n\n return source;\n}\n\n// Takes an array of inject objects and combines them into one\nexport function combineInjects(injects: any[]): Record<string, string> {\n const result: Record<string, string> = {};\n assert(Array.isArray(injects) && injects.length > 1);\n injects.forEach(inject => {\n for (const key in inject) {\n result[key] = result[key] ? `${result[key]}\\n${inject[key]}` : inject[key];\n }\n });\n return result;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {UniformFormat} from '../../types';\nimport {\n PropType,\n PropValidator,\n makePropValidators,\n getValidatedProperties\n} from '../filters/prop-types';\nimport type {ShaderModuleUniformValue, UniformTypes, UniformValue} from '../utils/uniform-types';\nimport {ShaderInjection, normalizeInjections} from '../shader-assembly/shader-injections';\n\n// To avoid dependency on core module, do not import `Binding` type.\n// The ShaderModule is not concerned with the type of `Binding`,\n// it is the repsonsibility of `splitUniformsAndBindings` in\n// ShaderInputs to type the result of `getUniforms()`\ntype Binding = unknown; // import type {Binding} from '@luma.gl/core';\n\nexport type UniformInfo = {\n format?: UniformFormat;\n} & PropType;\n\nexport type ShaderModuleBindingLayout = {\n name: string;\n group: number;\n};\n\n// Helper types\ntype BindingKeys<T> = {[K in keyof T]: T[K] extends UniformValue ? never : K}[keyof T];\ntype UniformKeys<T> = {[K in keyof T]: T[K] extends UniformValue ? K : never}[keyof T];\nexport type PickBindings<T> = {[K in BindingKeys<Required<T>>]: T[K]};\nexport type PickUniforms<T> = {[K in UniformKeys<Required<T>>]: T[K]};\n\n/**\n * A shader module definition object\n *\n * @note Needs to be initialized with `initializeShaderModules`\n * @note `UniformsT` & `BindingsT` are deduced from `PropsT` by default. If\n * a custom type for `UniformsT` is used, `BindingsT` should be also be provided.\n */\nexport type ShaderModule<\n PropsT extends Record<string, any> = Record<string, any>,\n UniformsT extends Record<string, ShaderModuleUniformValue> = PickUniforms<PropsT>,\n BindingsT extends Record<string, Binding> = PickBindings<PropsT>\n> = {\n /** Used for type inference not for values */\n props?: PropsT;\n /** Used for type inference, not currently used for values */\n uniforms?: UniformsT;\n /** Used for type inference, not currently used for values */\n bindings?: BindingsT;\n /** Logical bind-group assignment for bindings declared by this module */\n bindingLayout?: readonly ShaderModuleBindingLayout[];\n /** Preferred starting binding slot for this module's WGSL `@binding(auto)` declarations. */\n firstBindingSlot?: number;\n\n name: string;\n\n /** WGSL code */\n source?: string;\n /** GLSL fragment shader code */\n fs?: string;\n /** GLSL vertex shader code */\n vs?: string;\n\n /** Uniform shader types @note: Both order and types MUST match uniform block declarations in shader */\n uniformTypes?: Required<UniformTypes<UniformsT>>; // Record<keyof UniformsT, UniformFormat>;\n /** Uniform JS prop types */\n propTypes?: Record<keyof UniformsT, UniformInfo>;\n /** Default uniform values */\n defaultUniforms?: Required<UniformsT>; // Record<keyof UniformsT, UniformValue>;\n\n /** Function that maps props to uniforms & bindings */\n getUniforms?: (\n props: Partial<PropsT>,\n prevUniforms?: UniformsT\n ) => Partial<UniformsT & BindingsT>;\n\n defines?: Record<string, boolean | number>;\n /** Injections */\n inject?: Record<string, string | {injection: string; order: number}>;\n dependencies?: ShaderModule<any, any>[];\n /** Information on deprecated properties */\n deprecations?: ShaderModuleDeprecation[];\n\n /** The instance field contains information that is generated at run-time */\n instance?: {\n propValidators?: Record<string, PropValidator>;\n parsedDeprecations: ShaderModuleDeprecation[];\n\n normalizedInjections: {\n vertex: Record<string, ShaderInjection>;\n fragment: Record<string, ShaderInjection>;\n };\n };\n};\n\n/** Use to generate deprecations when shader module is used */\nexport type ShaderModuleDeprecation = {\n type: string;\n regex?: RegExp;\n new: string;\n old: string;\n deprecated?: boolean;\n};\n\n// SHNDER MODULE API\n\nexport function initializeShaderModules(modules: ShaderModule[]): void {\n modules.map((module: ShaderModule) => initializeShaderModule(module));\n}\n\nexport function initializeShaderModule(module: ShaderModule): void {\n if (module.instance) {\n return;\n }\n\n initializeShaderModules(module.dependencies || []);\n\n const {\n propTypes = {},\n deprecations = [],\n // defines = {},\n inject = {}\n } = module;\n\n const instance: Required<ShaderModule>['instance'] = {\n normalizedInjections: normalizeInjections(inject),\n parsedDeprecations: parseDeprecationDefinitions(deprecations)\n };\n\n if (propTypes) {\n instance.propValidators = makePropValidators(propTypes);\n }\n\n module.instance = instance;\n\n // TODO(ib) - we need to apply the original prop types to the default uniforms\n let defaultProps: ShaderModule['props'] = {};\n if (propTypes) {\n defaultProps = Object.entries(propTypes).reduce(\n (obj: ShaderModule['props'], [key, propType]) => {\n // @ts-expect-error\n const value = propType?.value;\n if (value) {\n // @ts-expect-error\n obj[key] = value;\n }\n return obj;\n },\n {} as ShaderModule['props']\n );\n }\n\n module.defaultUniforms = {...module.defaultUniforms, ...defaultProps} as any;\n}\n\n/** Convert module props to uniforms */\nexport function getShaderModuleUniforms<\n ShaderModuleT extends ShaderModule<\n Record<string, unknown>,\n Record<string, ShaderModuleUniformValue>\n >\n>(\n module: ShaderModuleT,\n props?: ShaderModuleT['props'],\n oldUniforms?: ShaderModuleT['uniforms']\n): Record<string, Binding | ShaderModuleUniformValue> {\n initializeShaderModule(module);\n\n const uniforms = oldUniforms || {...module.defaultUniforms};\n // If module has a getUniforms function, use it\n if (props && module.getUniforms) {\n return module.getUniforms(props, uniforms);\n }\n\n // Build uniforms from the uniforms array\n // @ts-expect-error\n return getValidatedProperties(props, module.instance?.propValidators, module.name);\n}\n\n/* TODO this looks like it was unused code\n _defaultGetUniforms(opts: Record<string, any> = {}): Record<string, any> {\n const uniforms: Record<string, any> = {};\n const propTypes = this.uniforms;\n\n for (const key in propTypes) {\n const propDef = propTypes[key];\n if (key in opts && !propDef.private) {\n if (propDef.validate) {\n assert(propDef.validate(opts[key], propDef), `${this.name}: invalid ${key}`);\n }\n uniforms[key] = opts[key];\n } else {\n uniforms[key] = propDef.value;\n }\n }\n\n return uniforms;\n }\n}\n*/\n// Warn about deprecated uniforms or functions\nexport function checkShaderModuleDeprecations(\n shaderModule: ShaderModule,\n shaderSource: string,\n log: any\n): void {\n shaderModule.deprecations?.forEach(def => {\n if (def.regex?.test(shaderSource)) {\n if (def.deprecated) {\n log.deprecated(def.old, def.new)();\n } else {\n log.removed(def.old, def.new)();\n }\n }\n });\n}\n\n// HELPERS\n\nfunction parseDeprecationDefinitions(deprecations: ShaderModuleDeprecation[]) {\n deprecations.forEach(def => {\n switch (def.type) {\n case 'function':\n def.regex = new RegExp(`\\\\b${def.old}\\\\(`);\n break;\n default:\n def.regex = new RegExp(`${def.type} ${def.old};`);\n }\n });\n\n return deprecations;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {ShaderModule, initializeShaderModules} from './shader-module';\n\n// import type {ShaderModule} from '../shader-module/shader-module';\n\ntype AbstractModule = {\n name: string;\n dependencies?: AbstractModule[];\n};\n\n/**\n * Takes a list of shader module names and returns a new list of\n * shader module names that includes all dependencies, sorted so\n * that modules that are dependencies of other modules come first.\n *\n * If the shader glsl code from the returned modules is concatenated\n * in the reverse order, it is guaranteed that all functions be resolved and\n * that all function and variable definitions come before use.\n *\n * @param modules - Array of modules (inline modules or module names)\n * @return - Array of modules\n */\nexport function getShaderModuleDependencies<T extends AbstractModule>(modules: T[]): T[] {\n initializeShaderModules(modules);\n const moduleMap: Record<string, T> = {};\n const moduleDepth: Record<string, number> = {};\n getDependencyGraph({modules, level: 0, moduleMap, moduleDepth});\n\n // Return a reverse sort so that dependencies come before the modules that use them\n const dependencies = Object.keys(moduleDepth)\n .sort((a, b) => moduleDepth[b] - moduleDepth[a])\n .map(name => moduleMap[name]);\n initializeShaderModules(dependencies);\n return dependencies;\n}\n\n/**\n * Recursively checks module dependencies to calculate dependency level of each module.\n *\n * @param options.modules - Array of modules\n * @param options.level - Current level\n * @param options.moduleMap -\n * @param options.moduleDepth - Current level\n * @return - Map of module name to its level\n */\n// Adds another level of dependencies to the result map\nexport function getDependencyGraph<T extends AbstractModule>(options: {\n modules: T[];\n level: number;\n moduleMap: Record<string, T>;\n moduleDepth: Record<string, number>;\n}) {\n const {modules, level, moduleMap, moduleDepth} = options;\n if (level >= 5) {\n throw new Error('Possible loop in shader dependency graph');\n }\n\n // Update level on all current modules\n for (const module of modules) {\n moduleMap[module.name] = module;\n if (moduleDepth[module.name] === undefined || moduleDepth[module.name] < level) {\n moduleDepth[module.name] = level;\n }\n }\n\n // Recurse\n for (const module of modules) {\n if (module.dependencies) {\n getDependencyGraph({modules: module.dependencies, level: level + 1, moduleMap, moduleDepth});\n }\n }\n}\n\n/**\n * Takes a list of shader module names and returns a new list of\n * shader module names that includes all dependencies, sorted so\n * that modules that are dependencies of other modules come first.\n *\n * If the shader glsl code from the returned modules is concatenated\n * in the reverse order, it is guaranteed that all functions be resolved and\n * that all function and variable definitions come before use.\n *\n * @param modules - Array of modules (inline modules or module names)\n * @return - Array of modules\n */\nexport function getShaderDependencies(modules: ShaderModule[]): ShaderModule[] {\n initializeShaderModules(modules);\n const moduleMap: Record<string, ShaderModule> = {};\n const moduleDepth: Record<string, number> = {};\n getDependencyGraph({modules, level: 0, moduleMap, moduleDepth});\n\n // Return a reverse sort so that dependencies come before the modules that use them\n modules = Object.keys(moduleDepth)\n .sort((a, b) => moduleDepth[b] - moduleDepth[a])\n .map(name => moduleMap[name]);\n initializeShaderModules(modules);\n return modules;\n}\n\n// DEPRECATED\n\n/**\n * Instantiate shader modules and resolve any dependencies\n * @deprecated Use getShaderDpendencies\n */\nexport function resolveModules(modules: ShaderModule[]): ShaderModule[] {\n return getShaderDependencies(modules);\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderModule} from './shader-module';\nimport {assert} from '../utils/assert';\n\n/**\n * Shader stages supported by shader-module uniform-layout validation helpers.\n */\nexport type ShaderModuleUniformLayoutStage = 'vertex' | 'fragment' | 'wgsl';\n\n/**\n * Describes the result of comparing declared `uniformTypes` with the fields\n * found in a shader uniform block.\n */\nexport type ShaderModuleUniformLayoutValidationResult = {\n /** Name of the shader module being validated. */\n moduleName: string;\n /** Expected block name derived from the shader module name. */\n uniformBlockName: string;\n /** Shader stage that was inspected. */\n stage: ShaderModuleUniformLayoutStage;\n /** Field names declared by the module metadata. */\n expectedUniformNames: string[];\n /** Field names parsed from the shader source. */\n actualUniformNames: string[];\n /** Whether the declared and parsed field lists match exactly. */\n matches: boolean;\n};\n\n/**\n * Parsed information about one GLSL uniform block declaration.\n */\nexport type GLSLUniformBlockInfo = {\n /** Declared block type name. */\n blockName: string;\n /** Optional instance name that follows the block declaration. */\n instanceName: string | null;\n /** Raw layout qualifier text, if present. */\n layoutQualifier: string | null;\n /** Whether any explicit layout qualifier was present. */\n hasLayoutQualifier: boolean;\n /** Whether the block explicitly declares `layout(std140)`. */\n isStd140: boolean;\n /** Raw source text inside the block braces. */\n body: string;\n};\n\n/**\n * Logging surface used by validation and warning helpers.\n */\ntype Logger = {\n /** Error logger compatible with luma's deferred log API. */\n error?: (...args: unknown[]) => () => unknown;\n /** Warning logger compatible with luma's deferred log API. */\n warn?: (...args: unknown[]) => () => unknown;\n};\n\n/**\n * Matches one field declaration inside a GLSL uniform block body.\n */\nconst GLSL_UNIFORM_BLOCK_FIELD_REGEXP =\n /^(?:uniform\\s+)?(?:(?:lowp|mediump|highp)\\s+)?[A-Za-z0-9_]+(?:<[^>]+>)?\\s+([A-Za-z0-9_]+)(?:\\s*\\[[^\\]]+\\])?\\s*;/;\n/**\n * Matches full GLSL uniform block declarations, including optional layout qualifiers.\n */\nconst GLSL_UNIFORM_BLOCK_REGEXP =\n /((?:layout\\s*\\([^)]*\\)\\s*)*)uniform\\s+([A-Za-z_][A-Za-z0-9_]*)\\s*\\{([\\s\\S]*?)\\}\\s*([A-Za-z_][A-Za-z0-9_]*)?\\s*;/g;\n\n/**\n * Returns the uniform block type name expected for the supplied shader module.\n */\nexport function getShaderModuleUniformBlockName(module: ShaderModule): string {\n return `${module.name}Uniforms`;\n}\n\n/**\n * Returns the ordered field names parsed from a shader module's uniform block.\n *\n * @returns `null` when the stage has no source or the expected block is absent.\n */\nexport function getShaderModuleUniformBlockFields(\n module: ShaderModule,\n stage: ShaderModuleUniformLayoutStage\n): string[] | null {\n const shaderSource =\n stage === 'wgsl' ? module.source : stage === 'vertex' ? module.vs : module.fs;\n\n if (!shaderSource) {\n return null;\n }\n\n const uniformBlockName = getShaderModuleUniformBlockName(module);\n return extractShaderUniformBlockFieldNames(\n shaderSource,\n stage === 'wgsl' ? 'wgsl' : 'glsl',\n uniformBlockName\n );\n}\n\n/**\n * Computes the validation result for a shader module's declared and parsed\n * uniform-block field lists.\n *\n * @returns `null` when the module has no declared uniform types or no matching block.\n */\nexport function getShaderModuleUniformLayoutValidationResult(\n module: ShaderModule,\n stage: ShaderModuleUniformLayoutStage\n): ShaderModuleUniformLayoutValidationResult | null {\n const expectedUniformNames = Object.keys(module.uniformTypes || {});\n if (!expectedUniformNames.length) {\n return null;\n }\n\n const actualUniformNames = getShaderModuleUniformBlockFields(module, stage);\n if (!actualUniformNames) {\n return null;\n }\n\n return {\n moduleName: module.name,\n uniformBlockName: getShaderModuleUniformBlockName(module),\n stage,\n expectedUniformNames,\n actualUniformNames,\n matches: areStringArraysEqual(expectedUniformNames, actualUniformNames)\n };\n}\n\n/**\n * Validates that a shader module's parsed uniform block matches `uniformTypes`.\n *\n * When a mismatch is detected, the helper logs a formatted error and optionally\n * throws via {@link assert}.\n */\nexport function validateShaderModuleUniformLayout(\n module: ShaderModule,\n stage: ShaderModuleUniformLayoutStage,\n options: {\n log?: Logger;\n throwOnError?: boolean;\n } = {}\n): ShaderModuleUniformLayoutValidationResult | null {\n const validationResult = getShaderModuleUniformLayoutValidationResult(module, stage);\n if (!validationResult || validationResult.matches) {\n return validationResult;\n }\n\n const message = formatShaderModuleUniformLayoutError(validationResult);\n options.log?.error?.(message, validationResult)();\n\n if (options.throwOnError !== false) {\n assert(false, message);\n }\n\n return validationResult;\n}\n\n/**\n * Parses all GLSL uniform blocks in a shader source string.\n */\nexport function getGLSLUniformBlocks(shaderSource: string): GLSLUniformBlockInfo[] {\n const blocks: GLSLUniformBlockInfo[] = [];\n const uncommentedSource = stripShaderComments(shaderSource);\n\n for (const sourceMatch of uncommentedSource.matchAll(GLSL_UNIFORM_BLOCK_REGEXP)) {\n const layoutQualifier = sourceMatch[1]?.trim() || null;\n blocks.push({\n blockName: sourceMatch[2],\n body: sourceMatch[3],\n instanceName: sourceMatch[4] || null,\n layoutQualifier,\n hasLayoutQualifier: Boolean(layoutQualifier),\n isStd140: Boolean(\n layoutQualifier && /\\blayout\\s*\\([^)]*\\bstd140\\b[^)]*\\)/.exec(layoutQualifier)\n )\n });\n }\n\n return blocks;\n}\n\n/**\n * Emits warnings for GLSL uniform blocks that do not explicitly declare\n * `layout(std140)`.\n *\n * @returns The list of parsed blocks that were considered non-compliant.\n */\nexport function warnIfGLSLUniformBlocksAreNotStd140(\n shaderSource: string,\n stage: Exclude<ShaderModuleUniformLayoutStage, 'wgsl'>,\n log?: Logger,\n context?: {label?: string}\n): GLSLUniformBlockInfo[] {\n const nonStd140Blocks = getGLSLUniformBlocks(shaderSource).filter(block => !block.isStd140);\n const seenBlockNames = new Set<string>();\n\n for (const block of nonStd140Blocks) {\n if (seenBlockNames.has(block.blockName)) {\n continue;\n }\n seenBlockNames.add(block.blockName);\n\n const shaderLabel = context?.label ? `${context.label} ` : '';\n const actualLayout = block.hasLayoutQualifier\n ? `declares ${normalizeWhitespace(block.layoutQualifier!)} instead of layout(std140)`\n : 'does not declare layout(std140)';\n const message = `${shaderLabel}${stage} shader uniform block ${\n block.blockName\n } ${actualLayout}. luma.gl host-side shader block packing assumes explicit layout(std140) for GLSL uniform blocks. Add \\`layout(std140)\\` to the block declaration.`;\n log?.warn?.(message, block)();\n }\n\n return nonStd140Blocks;\n}\n\n/**\n * Extracts field names from the named GLSL or WGSL uniform block/struct.\n */\nfunction extractShaderUniformBlockFieldNames(\n shaderSource: string,\n language: 'glsl' | 'wgsl',\n uniformBlockName: string\n): string[] | null {\n const sourceBody =\n language === 'wgsl'\n ? extractWGSLStructBody(shaderSource, uniformBlockName)\n : extractGLSLUniformBlockBody(shaderSource, uniformBlockName);\n\n if (!sourceBody) {\n return null;\n }\n\n const fieldNames: string[] = [];\n\n for (const sourceLine of sourceBody.split('\\n')) {\n const line = sourceLine.replace(/\\/\\/.*$/, '').trim();\n if (!line || line.startsWith('#')) {\n continue;\n }\n\n const fieldMatch =\n language === 'wgsl'\n ? line.match(/^([A-Za-z0-9_]+)\\s*:/)\n : line.match(GLSL_UNIFORM_BLOCK_FIELD_REGEXP);\n\n if (fieldMatch) {\n fieldNames.push(fieldMatch[1]);\n }\n }\n\n return fieldNames;\n}\n\n/**\n * Extracts the body of a WGSL struct with the supplied name.\n */\nfunction extractWGSLStructBody(shaderSource: string, uniformBlockName: string): string | null {\n const structMatch = new RegExp(`\\\\bstruct\\\\s+${uniformBlockName}\\\\b`, 'm').exec(shaderSource);\n if (!structMatch) {\n return null;\n }\n\n const openBraceIndex = shaderSource.indexOf('{', structMatch.index);\n if (openBraceIndex < 0) {\n return null;\n }\n\n let braceDepth = 0;\n for (let index = openBraceIndex; index < shaderSource.length; index++) {\n const character = shaderSource[index];\n if (character === '{') {\n braceDepth++;\n continue;\n }\n if (character !== '}') {\n continue;\n }\n\n braceDepth--;\n if (braceDepth === 0) {\n return shaderSource.slice(openBraceIndex + 1, index);\n }\n }\n\n return null;\n}\n\n/**\n * Extracts the body of a named GLSL uniform block from shader source.\n */\nfunction extractGLSLUniformBlockBody(\n shaderSource: string,\n uniformBlockName: string\n): string | null {\n const block = getGLSLUniformBlocks(shaderSource).find(\n candidate => candidate.blockName === uniformBlockName\n );\n return block?.body || null;\n}\n\n/**\n * Returns `true` when the two arrays contain the same strings in the same order.\n */\nfunction areStringArraysEqual(leftValues: string[], rightValues: string[]): boolean {\n if (leftValues.length !== rightValues.length) {\n return false;\n }\n\n for (let valueIndex = 0; valueIndex < leftValues.length; valueIndex++) {\n if (leftValues[valueIndex] !== rightValues[valueIndex]) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Formats the standard validation error message for a shader-module layout mismatch.\n */\nfunction formatShaderModuleUniformLayoutError(\n validationResult: ShaderModuleUniformLayoutValidationResult\n): string {\n const {expectedUniformNames, actualUniformNames} = validationResult;\n const missingUniformNames = expectedUniformNames.filter(\n uniformName => !actualUniformNames.includes(uniformName)\n );\n const unexpectedUniformNames = actualUniformNames.filter(\n uniformName => !expectedUniformNames.includes(uniformName)\n );\n const mismatchDetails = [\n `Expected ${expectedUniformNames.length} fields, found ${actualUniformNames.length}.`\n ];\n const firstMismatchDescription = getFirstUniformMismatchDescription(\n expectedUniformNames,\n actualUniformNames\n );\n if (firstMismatchDescription) {\n mismatchDetails.push(firstMismatchDescription);\n }\n if (missingUniformNames.length) {\n mismatchDetails.push(\n `Missing from shader block (${missingUniformNames.length}): ${formatUniformNameList(\n missingUniformNames\n )}.`\n );\n }\n if (unexpectedUniformNames.length) {\n mismatchDetails.push(\n `Unexpected in shader block (${unexpectedUniformNames.length}): ${formatUniformNameList(\n unexpectedUniformNames\n )}.`\n );\n }\n if (\n expectedUniformNames.length <= 12 &&\n actualUniformNames.length <= 12 &&\n (missingUniformNames.length || unexpectedUniformNames.length)\n ) {\n mismatchDetails.push(`Expected: ${expectedUniformNames.join(', ')}.`);\n mismatchDetails.push(`Actual: ${actualUniformNames.join(', ')}.`);\n }\n\n return `${validationResult.moduleName}: ${validationResult.stage} shader uniform block ${\n validationResult.uniformBlockName\n } does not match module.uniformTypes. ${mismatchDetails.join(' ')}`;\n}\n\n/**\n * Removes line and block comments from shader source before lightweight parsing.\n */\nfunction stripShaderComments(shaderSource: string): string {\n return shaderSource.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '').replace(/\\/\\/.*$/gm, '');\n}\n\n/**\n * Collapses repeated whitespace in a layout qualifier for log-friendly output.\n */\nfunction normalizeWhitespace(value: string): string {\n return value.replace(/\\s+/g, ' ').trim();\n}\n\nfunction getFirstUniformMismatchDescription(\n expectedUniformNames: string[],\n actualUniformNames: string[]\n): string | null {\n const minimumLength = Math.min(expectedUniformNames.length, actualUniformNames.length);\n for (let index = 0; index < minimumLength; index++) {\n if (expectedUniformNames[index] !== actualUniformNames[index]) {\n return `First mismatch at field ${index + 1}: expected ${\n expectedUniformNames[index]\n }, found ${actualUniformNames[index]}.`;\n }\n }\n\n if (expectedUniformNames.length > actualUniformNames.length) {\n return `Shader block ends after field ${actualUniformNames.length}; expected next field ${\n expectedUniformNames[actualUniformNames.length]\n }.`;\n }\n if (actualUniformNames.length > expectedUniformNames.length) {\n return `Shader block has extra field ${actualUniformNames.length}: ${\n actualUniformNames[expectedUniformNames.length]\n }.`;\n }\n\n return null;\n}\n\nfunction formatUniformNameList(uniformNames: string[], maxNames = 8): string {\n if (uniformNames.length <= maxNames) {\n return uniformNames.join(', ');\n }\n\n const remainingCount = uniformNames.length - maxNames;\n return `${uniformNames.slice(0, maxNames).join(', ')}, ... (${remainingCount} more)`;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {PlatformInfo} from './platform-info';\n\n/** Adds defines to help identify GPU architecture / platform */\nexport function getPlatformShaderDefines(platformInfo: PlatformInfo): string {\n switch (platformInfo?.gpu.toLowerCase()) {\n case 'apple':\n return /* glsl */ `\\\n#define APPLE_GPU\n// Apple optimizes away the calculation necessary for emulated fp64\n#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1\n#define LUMA_FP32_TAN_PRECISION_WORKAROUND 1\n// Intel GPU doesn't have full 32 bits precision in same cases, causes overflow\n#define LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND 1\n`;\n\n case 'nvidia':\n return /* glsl */ `\\\n#define NVIDIA_GPU\n// Nvidia optimizes away the calculation necessary for emulated fp64\n#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1\n`;\n\n case 'intel':\n return /* glsl */ `\\\n#define INTEL_GPU\n// Intel optimizes away the calculation necessary for emulated fp64\n#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1\n// Intel's built-in 'tan' function doesn't have acceptable precision\n#define LUMA_FP32_TAN_PRECISION_WORKAROUND 1\n// Intel GPU doesn't have full 32 bits precision in same cases, causes overflow\n#define LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND 1\n`;\n\n case 'amd':\n // AMD Does not eliminate fp64 code\n return /* glsl */ `\\\n#define AMD_GPU\n`;\n\n default:\n // We don't know what GPU it is, could be that the GPU driver or\n // browser is not implementing UNMASKED_RENDERER constant and not\n // reporting a correct name\n return /* glsl */ `\\\n#define DEFAULT_GPU\n// Prevent driver from optimizing away the calculation necessary for emulated fp64\n#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1\n// Headless Chrome's software shader 'tan' function doesn't have acceptable precision\n#define LUMA_FP32_TAN_PRECISION_WORKAROUND 1\n// If the GPU doesn't have full 32 bits precision, will causes overflow\n#define LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND 1\n`;\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// TRANSPILATION TABLES\n\n/**\n * Transpiles GLSL 3.00 shader source code to target GLSL version (3.00 or 1.00)\n *\n * @note We always run transpiler even if same version e.g. 3.00 => 3.00\n * @note For texture sampling transpilation, apps need to use non-standard texture* calls in GLSL 3.00 source\n * RFC: https://github.com/visgl/luma.gl/blob/7.0-release/dev-docs/RFCs/v6.0/portable-glsl-300-rfc.md\n */\nexport function transpileGLSLShader(source: string, stage: 'vertex' | 'fragment'): string {\n const sourceGLSLVersion = Number(source.match(/^#version[ \\t]+(\\d+)/m)?.[1] || 100);\n if (sourceGLSLVersion !== 300) {\n // TODO - we splurge on a longer error message to help deck.gl custom layer developers\n throw new Error('luma.gl v9 only supports GLSL 3.00 shader sources');\n }\n\n switch (stage) {\n case 'vertex':\n source = convertShader(source, ES300_VERTEX_REPLACEMENTS);\n return source;\n case 'fragment':\n source = convertShader(source, ES300_FRAGMENT_REPLACEMENTS);\n return source;\n default:\n // Unknown shader stage\n throw new Error(stage);\n }\n}\n\ntype GLSLReplacement = [RegExp, string];\n\n/** Simple regex replacements for GLSL ES 1.00 syntax that has changed in GLSL ES 3.00 */\nconst ES300_REPLACEMENTS: GLSLReplacement[] = [\n // Fix poorly formatted version directive\n [/^(#version[ \\t]+(100|300[ \\t]+es))?[ \\t]*\\n/, '#version 300 es\\n'],\n // The individual `texture...()` functions were replaced with `texture()` overloads\n [/\\btexture(2D|2DProj|Cube)Lod(EXT)?\\(/g, 'textureLod('],\n [/\\btexture(2D|2DProj|Cube)(EXT)?\\(/g, 'texture(']\n];\n\nconst ES300_VERTEX_REPLACEMENTS: GLSLReplacement[] = [\n ...ES300_REPLACEMENTS,\n // `attribute` keyword replaced with `in`\n [makeVariableTextRegExp('attribute'), 'in $1'],\n // `varying` keyword replaced with `out`\n [makeVariableTextRegExp('varying'), 'out $1']\n];\n\n/** Simple regex replacements for GLSL ES 1.00 syntax that has changed in GLSL ES 3.00 */\nconst ES300_FRAGMENT_REPLACEMENTS: GLSLReplacement[] = [\n ...ES300_REPLACEMENTS,\n // `varying` keyword replaced with `in`\n [makeVariableTextRegExp('varying'), 'in $1']\n];\n\nfunction convertShader(source: string, replacements: GLSLReplacement[]) {\n for (const [pattern, replacement] of replacements) {\n source = source.replace(pattern, replacement);\n }\n return source;\n}\n\n/**\n * Creates a regexp that tests for a specific variable type\n * @example\n * should match:\n * in float weight;\n * out vec4 positions[2];\n * should not match:\n * void f(out float a, in float b) {}\n */\nfunction makeVariableTextRegExp(qualifier: 'attribute' | 'varying' | 'in' | 'out'): RegExp {\n return new RegExp(`\\\\b${qualifier}[ \\\\t]+(\\\\w+[ \\\\t]+\\\\w+(\\\\[\\\\w+\\\\])?;)`, 'g');\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {ShaderInjection} from './shader-injections';\n\n// A normalized hook function\n/**\n * The shader hook mechanism allows the application to create shaders\n * that can be automatically extended by the shader modules the application\n * includes.\n *\n * A shader hook function that shader modules can inject code into.\n * Shaders can call these functions, which will be no-ops by default.\n *\n * If a shader module injects code it will be executed upon the hook\n * function call.\n */\nexport type ShaderHook = {\n /** `vs:` or `fs:` followed by the name and arguments of the function, e.g. `vs:MYHOOK_func(inout vec4 value)`. Hook name without arguments\n will also be used as the name of the shader hook */\n hook: string;\n /** Code always included at the beginning of a hook function */\n header: string;\n /** Code always included at the end of a hook function */\n footer: string;\n /** To Be Documented */\n signature?: string;\n};\n\n/** Normalized shader hooks per shader */\nexport type ShaderHooks = {\n /** Normalized shader hooks for vertex shader */\n vertex: Record<string, ShaderHook>;\n /** Normalized shader hooks for fragment shader */\n fragment: Record<string, ShaderHook>;\n};\n\n/** Generate hook source code */\nexport function getShaderHooks(\n hookFunctions: Record<string, ShaderHook>,\n hookInjections: Record<string, ShaderInjection[]>\n): string {\n let result = '';\n for (const hookName in hookFunctions) {\n const hookFunction = hookFunctions[hookName];\n result += `void ${hookFunction.signature} {\\n`;\n if (hookFunction.header) {\n result += ` ${hookFunction.header}`;\n }\n if (hookInjections[hookName]) {\n const injections = hookInjections[hookName];\n injections.sort((a: {order: number}, b: {order: number}): number => a.order - b.order);\n for (const injection of injections) {\n result += ` ${injection.injection}\\n`;\n }\n }\n if (hookFunction.footer) {\n result += ` ${hookFunction.footer}`;\n }\n result += '}\\n';\n }\n\n return result;\n}\n\n/**\n * Parse string based hook functions\n * And split per shader\n */\nexport function normalizeShaderHooks(hookFunctions: (string | ShaderHook)[]): ShaderHooks {\n const result: ShaderHooks = {vertex: {}, fragment: {}};\n\n for (const hookFunction of hookFunctions) {\n let opts: ShaderHook;\n let hook: string;\n if (typeof hookFunction !== 'string') {\n opts = hookFunction;\n hook = opts.hook;\n } else {\n opts = {} as ShaderHook;\n hook = hookFunction;\n }\n hook = hook.trim();\n const [shaderStage, signature] = hook.split(':');\n const name = hook.replace(/\\(.+/, '');\n const normalizedHook: ShaderHook = Object.assign(opts, {signature});\n switch (shaderStage) {\n case 'vs':\n result.vertex[name] = normalizedHook;\n break;\n case 'fs':\n result.fragment[name] = normalizedHook;\n break;\n default:\n throw new Error(shaderStage);\n }\n }\n\n return result;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/** Information extracted from shader source code */\nexport type ShaderInfo = {\n name: string;\n language: 'glsl' | 'wgsl';\n version: number;\n};\n\n/** Extracts information from shader source code */\nexport function getShaderInfo(source: string, defaultName?: string): ShaderInfo {\n return {\n name: getShaderName(source, defaultName),\n language: 'glsl',\n version: getShaderVersion(source)\n };\n}\n\n/** Extracts GLSLIFY style naming of shaders: `#define SHADER_NAME ...` */\nfunction getShaderName(shader: string, defaultName: string = 'unnamed'): string {\n const SHADER_NAME_REGEXP = /#define[^\\S\\r\\n]*SHADER_NAME[^\\S\\r\\n]*([A-Za-z0-9_-]+)\\s*/;\n const match = SHADER_NAME_REGEXP.exec(shader);\n return match ? match[1] : defaultName;\n}\n\n/** returns GLSL shader version of given shader string */\nfunction getShaderVersion(source: string): 100 | 300 {\n let version = 100;\n const words = source.match(/[^\\s]+/g);\n if (words && words.length >= 2 && words[0] === '#version') {\n const parsedVersion = parseInt(words[1], 10);\n if (Number.isFinite(parsedVersion)) {\n version = parsedVersion;\n }\n }\n if (version !== 100 && version !== 300) {\n throw new Error(`Invalid GLSL version ${version}`);\n }\n return version;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const WGSL_BINDABLE_VARIABLE_PATTERN =\n '(?:var<\\\\s*(uniform|storage(?:\\\\s*,\\\\s*[A-Za-z_][A-Za-z0-9_]*)?)\\\\s*>|var)\\\\s+([A-Za-z_][A-Za-z0-9_]*)';\nconst WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN = '\\\\s*';\n\nexport const MODULE_WGSL_BINDING_DECLARATION_REGEXES = [\n new RegExp(\n `@binding\\\\(\\\\s*(auto|\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n ),\n new RegExp(\n `@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}@binding\\\\(\\\\s*(auto|\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n )\n] as const;\n\nexport const WGSL_BINDING_DECLARATION_REGEXES = [\n new RegExp(\n `@binding\\\\(\\\\s*(auto|\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n ),\n new RegExp(\n `@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}@binding\\\\(\\\\s*(auto|\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n )\n] as const;\n\nexport const WGSL_EXPLICIT_BINDING_DECLARATION_REGEXES = [\n new RegExp(\n `@binding\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n ),\n new RegExp(\n `@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}@binding\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n )\n] as const;\n\nconst WGSL_AUTO_BINDING_DECLARATION_REGEXES = [\n new RegExp(\n `@binding\\\\(\\\\s*(auto)\\\\s*\\\\)\\\\s*@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)\\\\s*${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n ),\n new RegExp(\n `@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)\\\\s*@binding\\\\(\\\\s*(auto)\\\\s*\\\\)\\\\s*${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n ),\n new RegExp(\n `@binding\\\\(\\\\s*(auto)\\\\s*\\\\)\\\\s*@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)(?:[\\\\s\\\\n\\\\r]*@[A-Za-z_][^\\\\n\\\\r]*)*[\\\\s\\\\n\\\\r]*${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n ),\n new RegExp(\n `@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)\\\\s*@binding\\\\(\\\\s*(auto)\\\\s*\\\\)(?:[\\\\s\\\\n\\\\r]*@[A-Za-z_][^\\\\n\\\\r]*)*[\\\\s\\\\n\\\\r]*${WGSL_BINDABLE_VARIABLE_PATTERN}`,\n 'g'\n )\n] as const;\n\nexport type WGSLBindingDeclarationMatch = {\n match: string;\n index: number;\n length: number;\n bindingToken: string;\n groupToken: string;\n accessDeclaration?: string;\n name: string;\n};\n\nexport function maskWGSLComments(source: string): string {\n const maskedCharacters = source.split('');\n let index = 0;\n let blockCommentDepth = 0;\n let inLineComment = false;\n let inString = false;\n let isEscaped = false;\n\n while (index < source.length) {\n const character = source[index];\n const nextCharacter = source[index + 1];\n\n if (inString) {\n if (isEscaped) {\n isEscaped = false;\n } else if (character === '\\\\') {\n isEscaped = true;\n } else if (character === '\"') {\n inString = false;\n }\n index++;\n continue;\n }\n\n if (inLineComment) {\n if (character === '\\n' || character === '\\r') {\n inLineComment = false;\n } else {\n maskedCharacters[index] = ' ';\n }\n index++;\n continue;\n }\n\n if (blockCommentDepth > 0) {\n if (character === '/' && nextCharacter === '*') {\n maskedCharacters[index] = ' ';\n maskedCharacters[index + 1] = ' ';\n blockCommentDepth++;\n index += 2;\n continue;\n }\n\n if (character === '*' && nextCharacter === '/') {\n maskedCharacters[index] = ' ';\n maskedCharacters[index + 1] = ' ';\n blockCommentDepth--;\n index += 2;\n continue;\n }\n\n if (character !== '\\n' && character !== '\\r') {\n maskedCharacters[index] = ' ';\n }\n index++;\n continue;\n }\n\n if (character === '\"') {\n inString = true;\n index++;\n continue;\n }\n\n if (character === '/' && nextCharacter === '/') {\n maskedCharacters[index] = ' ';\n maskedCharacters[index + 1] = ' ';\n inLineComment = true;\n index += 2;\n continue;\n }\n\n if (character === '/' && nextCharacter === '*') {\n maskedCharacters[index] = ' ';\n maskedCharacters[index + 1] = ' ';\n blockCommentDepth = 1;\n index += 2;\n continue;\n }\n\n index++;\n }\n\n return maskedCharacters.join('');\n}\n\nexport function getWGSLBindingDeclarationMatches(\n source: string,\n regexes: readonly RegExp[]\n): WGSLBindingDeclarationMatch[] {\n const maskedSource = maskWGSLComments(source);\n const matches: WGSLBindingDeclarationMatch[] = [];\n\n for (const regex of regexes) {\n regex.lastIndex = 0;\n let match: RegExpExecArray | null;\n match = regex.exec(maskedSource);\n while (match) {\n const isBindingFirst = regex === regexes[0];\n const index = match.index;\n const length = match[0].length;\n matches.push({\n match: source.slice(index, index + length),\n index,\n length,\n bindingToken: match[isBindingFirst ? 1 : 2],\n groupToken: match[isBindingFirst ? 2 : 1],\n accessDeclaration: match[3]?.trim(),\n name: match[4]\n });\n match = regex.exec(maskedSource);\n }\n }\n\n return matches.sort((left, right) => left.index - right.index);\n}\n\nexport function replaceWGSLBindingDeclarationMatches(\n source: string,\n regexes: readonly RegExp[],\n replacer: (match: WGSLBindingDeclarationMatch) => string\n): string {\n const matches = getWGSLBindingDeclarationMatches(source, regexes);\n if (!matches.length) {\n return source;\n }\n\n let relocatedSource = '';\n let lastIndex = 0;\n\n for (const match of matches) {\n relocatedSource += source.slice(lastIndex, match.index);\n relocatedSource += replacer(match);\n lastIndex = match.index + match.length;\n }\n\n relocatedSource += source.slice(lastIndex);\n return relocatedSource;\n}\n\nexport function hasWGSLAutoBinding(source: string): boolean {\n return /@binding\\(\\s*auto\\s*\\)/.test(maskWGSLComments(source));\n}\n\nexport function getFirstWGSLAutoBindingDeclarationMatch(\n source: string,\n regexes: readonly RegExp[]\n): WGSLBindingDeclarationMatch | undefined {\n const autoBindingRegexes =\n regexes === MODULE_WGSL_BINDING_DECLARATION_REGEXES ||\n regexes === WGSL_BINDING_DECLARATION_REGEXES\n ? WGSL_AUTO_BINDING_DECLARATION_REGEXES\n : regexes;\n\n return getWGSLBindingDeclarationMatches(source, autoBindingRegexes).find(\n declarationMatch => declarationMatch.bindingToken === 'auto'\n );\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {WGSL_BINDABLE_VARIABLE_PATTERN, maskWGSLComments} from './wgsl-binding-scan';\n\ntype ShaderBindingAssignment = {\n moduleName: string;\n name: string;\n group: number;\n location: number;\n};\n\nconst WGSL_BINDING_DEBUG_REGEXES = [\n new RegExp(\n `@binding\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)\\\\s*@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)\\\\s*${WGSL_BINDABLE_VARIABLE_PATTERN}\\\\s*:\\\\s*([^;]+);`,\n 'g'\n ),\n new RegExp(\n `@group\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)\\\\s*@binding\\\\(\\\\s*(\\\\d+)\\\\s*\\\\)\\\\s*${WGSL_BINDABLE_VARIABLE_PATTERN}\\\\s*:\\\\s*([^;]+);`,\n 'g'\n )\n] as const;\n\n/** One debug row describing a WGSL binding in the assembled shader source. */\nexport type ShaderBindingDebugRow = {\n /** Binding name as declared in WGSL. */\n name: string;\n /** Bind-group index. */\n group: number;\n /** Binding slot within the bind group. */\n binding: number;\n /** Resource kind inferred from the WGSL declaration. */\n kind:\n | 'uniform'\n | 'storage'\n | 'read-only-storage'\n | 'texture'\n | 'sampler'\n | 'storage-texture'\n | 'unknown';\n /** Whether the binding came from application WGSL or a shader module. */\n owner: 'application' | 'module';\n /** Shader module name when the binding was contributed by a module. */\n moduleName?: string;\n /** Full WGSL resource type text from the declaration. */\n resourceType?: string;\n /** WGSL access mode when cheaply available. */\n access?: string;\n /** Texture view dimension when cheaply available. */\n viewDimension?: string;\n /** Texture sample type when cheaply available. */\n sampleType?: string;\n /** Sampler kind when cheaply available. */\n samplerKind?: string;\n /** Whether the texture is multisampled when cheaply available. */\n multisampled?: boolean;\n};\n\n/** Builds a stable, table-friendly binding summary from assembled WGSL source. */\nexport function getShaderBindingDebugRowsFromWGSL(\n source: string,\n bindingAssignments: ShaderBindingAssignment[] = []\n): ShaderBindingDebugRow[] {\n const maskedSource = maskWGSLComments(source);\n const assignmentMap = new Map<string, string>();\n for (const bindingAssignment of bindingAssignments) {\n assignmentMap.set(\n getBindingAssignmentKey(\n bindingAssignment.name,\n bindingAssignment.group,\n bindingAssignment.location\n ),\n bindingAssignment.moduleName\n );\n }\n\n const rows: ShaderBindingDebugRow[] = [];\n for (const regex of WGSL_BINDING_DEBUG_REGEXES) {\n regex.lastIndex = 0;\n let match: RegExpExecArray | null;\n match = regex.exec(maskedSource);\n while (match) {\n const isBindingFirst = regex === WGSL_BINDING_DEBUG_REGEXES[0];\n const binding = Number(match[isBindingFirst ? 1 : 2]);\n const group = Number(match[isBindingFirst ? 2 : 1]);\n const accessDeclaration = match[3]?.trim();\n const name = match[4];\n const resourceType = match[5].trim();\n const moduleName = assignmentMap.get(getBindingAssignmentKey(name, group, binding));\n\n rows.push(\n normalizeShaderBindingDebugRow({\n name,\n group,\n binding,\n owner: moduleName ? 'module' : 'application',\n moduleName,\n accessDeclaration,\n resourceType\n })\n );\n match = regex.exec(maskedSource);\n }\n }\n\n return rows.sort((left, right) => {\n if (left.group !== right.group) {\n return left.group - right.group;\n }\n if (left.binding !== right.binding) {\n return left.binding - right.binding;\n }\n return left.name.localeCompare(right.name);\n });\n}\n\nfunction normalizeShaderBindingDebugRow(row: {\n name: string;\n group: number;\n binding: number;\n owner: 'application' | 'module';\n moduleName?: string;\n accessDeclaration?: string;\n resourceType: string;\n}): ShaderBindingDebugRow {\n const baseRow: ShaderBindingDebugRow = {\n name: row.name,\n group: row.group,\n binding: row.binding,\n owner: row.owner,\n kind: 'unknown',\n moduleName: row.moduleName,\n resourceType: row.resourceType\n };\n\n if (row.accessDeclaration) {\n const access = row.accessDeclaration.split(',').map(value => value.trim());\n if (access[0] === 'uniform') {\n return {...baseRow, kind: 'uniform', access: 'uniform'};\n }\n if (access[0] === 'storage') {\n const storageAccess = access[1] || 'read_write';\n return {\n ...baseRow,\n kind: storageAccess === 'read' ? 'read-only-storage' : 'storage',\n access: storageAccess\n };\n }\n }\n\n if (row.resourceType === 'sampler' || row.resourceType === 'sampler_comparison') {\n return {\n ...baseRow,\n kind: 'sampler',\n samplerKind: row.resourceType === 'sampler_comparison' ? 'comparison' : 'filtering'\n };\n }\n\n if (row.resourceType.startsWith('texture_storage_')) {\n return {\n ...baseRow,\n kind: 'storage-texture',\n access: getStorageTextureAccess(row.resourceType),\n viewDimension: getTextureViewDimension(row.resourceType)\n };\n }\n\n if (row.resourceType.startsWith('texture_')) {\n return {\n ...baseRow,\n kind: 'texture',\n viewDimension: getTextureViewDimension(row.resourceType),\n sampleType: getTextureSampleType(row.resourceType),\n multisampled: row.resourceType.startsWith('texture_multisampled_')\n };\n }\n\n return baseRow;\n}\n\nfunction getBindingAssignmentKey(name: string, group: number, binding: number): string {\n return `${group}:${binding}:${name}`;\n}\n\nfunction getTextureViewDimension(resourceType: string): string | undefined {\n if (resourceType.includes('cube_array')) {\n return 'cube-array';\n }\n if (resourceType.includes('2d_array')) {\n return '2d-array';\n }\n if (resourceType.includes('cube')) {\n return 'cube';\n }\n if (resourceType.includes('3d')) {\n return '3d';\n }\n if (resourceType.includes('2d')) {\n return '2d';\n }\n if (resourceType.includes('1d')) {\n return '1d';\n }\n return undefined;\n}\n\nfunction getTextureSampleType(resourceType: string): string | undefined {\n if (resourceType.startsWith('texture_depth_')) {\n return 'depth';\n }\n if (resourceType.includes('<i32>')) {\n return 'sint';\n }\n if (resourceType.includes('<u32>')) {\n return 'uint';\n }\n if (resourceType.includes('<f32>')) {\n return 'float';\n }\n return undefined;\n}\n\nfunction getStorageTextureAccess(resourceType: string): string | undefined {\n const match = /,\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*>$/.exec(resourceType);\n return match?.[1];\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {getShaderModuleDependencies} from '../shader-module/shader-module-dependencies';\nimport {PlatformInfo} from './platform-info';\nimport {getPlatformShaderDefines} from './platform-defines';\nimport {injectShader, DECLARATION_INJECT_MARKER} from './shader-injections';\nimport {transpileGLSLShader} from '../shader-transpiler/transpile-glsl-shader';\nimport {checkShaderModuleDeprecations} from '../shader-module/shader-module';\nimport {\n validateShaderModuleUniformLayout,\n warnIfGLSLUniformBlocksAreNotStd140\n} from '../shader-module/shader-module-uniform-layout';\nimport type {ShaderInjection} from './shader-injections';\nimport type {ShaderModule} from '../shader-module/shader-module';\nimport {ShaderHook, normalizeShaderHooks, getShaderHooks} from './shader-hooks';\nimport {assert} from '../utils/assert';\nimport {getShaderInfo} from '../glsl-utils/get-shader-info';\nimport {getShaderBindingDebugRowsFromWGSL, type ShaderBindingDebugRow} from './wgsl-binding-debug';\nimport {\n MODULE_WGSL_BINDING_DECLARATION_REGEXES,\n WGSL_BINDING_DECLARATION_REGEXES,\n WGSL_EXPLICIT_BINDING_DECLARATION_REGEXES,\n getFirstWGSLAutoBindingDeclarationMatch,\n getWGSLBindingDeclarationMatches,\n hasWGSLAutoBinding,\n replaceWGSLBindingDeclarationMatches,\n type WGSLBindingDeclarationMatch\n} from './wgsl-binding-scan';\n\nconst INJECT_SHADER_DECLARATIONS = `\\n\\n${DECLARATION_INJECT_MARKER}\\n`;\nconst RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT = 100;\n\n/**\n * Precision prologue to inject before functions are injected in shader\n * TODO - extract any existing prologue in the fragment source and move it up...\n */\nconst FRAGMENT_SHADER_PROLOGUE = /* glsl */ `\\\nprecision highp float;\n`;\n\n/**\n * Options for `ShaderAssembler.assembleShaders()`\n */\nexport type AssembleShaderProps = AssembleShaderOptions & {\n platformInfo: PlatformInfo;\n /** WGSL: single shader source. */\n source?: string | null;\n /** GLSL vertex shader source. */\n vs?: string | null;\n /** GLSL fragment shader source. */\n fs?: string | null;\n};\n\nexport type AssembleShaderOptions = {\n /** information about the platform (which shader language & version, extensions etc.) */\n platformInfo: PlatformInfo;\n /** Inject shader id #defines */\n id?: string;\n /** Modules to be injected */\n modules?: ShaderModule[];\n /** Defines to be injected */\n defines?: Record<string, boolean>;\n /** GLSL only: Overrides to be injected. In WGSL these are supplied during Pipeline creation time */\n constants?: Record<string, number>;\n /** Hook functions */\n hookFunctions?: (ShaderHook | string)[];\n /** Code injections */\n inject?: Record<string, string | ShaderInjection>;\n /** Whether to inject prologue */\n prologue?: boolean;\n /** logger object */\n log?: any;\n};\n\ntype AssembleStageOptions = {\n /** Inject shader id #defines */\n id?: string;\n /** Vertex shader */\n source: string;\n stage: 'vertex' | 'fragment';\n /** Modules to be injected */\n modules: any[];\n /** Defines to be injected */\n defines?: Record<string, boolean>;\n /** GLSL only: Overrides to be injected. In WGSL these are supplied during Pipeline creation time */\n constants?: Record<string, number>;\n /** Hook functions */\n hookFunctions?: (ShaderHook | string)[];\n /** Code injections */\n inject?: Record<string, string | ShaderInjection>;\n /** Whether to inject prologue */\n prologue?: boolean;\n /** logger object */\n log?: any;\n /** @internal Stable per-assembler WGSL binding assignments. */\n _bindingRegistry?: Map<string, number>;\n};\n\nexport type HookFunction = {hook: string; header: string; footer: string; signature?: string};\n\n/**\n * getUniforms function returned from the shader module system\n */\nexport type GetUniformsFunc = (opts: Record<string, any>) => Record<string, any>;\n\n/**\n * Inject a list of shader modules into a single shader source for WGSL\n */\nexport function assembleWGSLShader(\n options: AssembleShaderOptions & {\n /** Single WGSL shader */\n source: string;\n /** @internal Stable per-assembler WGSL binding assignments. */\n _bindingRegistry?: Map<string, number>;\n }\n): {\n source: string;\n getUniforms: GetUniformsFunc;\n bindingAssignments: {moduleName: string; name: string; group: number; location: number}[];\n bindingTable: ShaderBindingDebugRow[];\n} {\n const modules = getShaderModuleDependencies(options.modules || []);\n const {source, bindingAssignments} = assembleShaderWGSL(options.platformInfo, {\n ...options,\n source: options.source,\n stage: 'vertex',\n modules\n });\n\n return {\n source,\n getUniforms: assembleGetUniforms(modules),\n bindingAssignments,\n bindingTable: getShaderBindingDebugRowsFromWGSL(source, bindingAssignments)\n };\n}\n\n/**\n * Injects dependent shader module sources into pair of main vertex/fragment shader sources for GLSL\n */\nexport function assembleGLSLShaderPair(\n options: AssembleShaderOptions & {\n /** Vertex shader */\n vs: string;\n /** Fragment shader */\n fs?: string;\n }\n): {\n vs: string;\n fs: string;\n getUniforms: GetUniformsFunc;\n} {\n const {vs, fs} = options;\n const modules = getShaderModuleDependencies(options.modules || []);\n\n return {\n vs: assembleShaderGLSL(options.platformInfo, {\n ...options,\n source: vs,\n stage: 'vertex',\n modules\n }),\n fs: assembleShaderGLSL(options.platformInfo, {\n ...options,\n // @ts-expect-error\n source: fs,\n stage: 'fragment',\n modules\n }),\n getUniforms: assembleGetUniforms(modules)\n };\n}\n\n/**\n * Pulls together complete source code for either a vertex or a fragment shader\n * adding prologues, requested module chunks, and any final injections.\n * @param gl\n * @param options\n * @returns\n */\nexport function assembleShaderWGSL(\n platformInfo: PlatformInfo,\n options: AssembleStageOptions\n): {source: string; bindingAssignments: WGSLBindingAssignment[]} {\n const {\n // id,\n source,\n stage,\n modules,\n // defines = {},\n hookFunctions = [],\n inject = {},\n log\n } = options;\n\n assert(typeof source === 'string', 'shader source must be a string');\n\n // const isVertex = type === 'vs';\n // const sourceLines = source.split('\\n');\n\n const coreSource = source;\n\n // Combine Module and Application Defines\n // const allDefines = {};\n // modules.forEach(module => {\n // Object.assign(allDefines, module.getDefines());\n // });\n // Object.assign(allDefines, defines);\n\n // Add platform defines (use these to work around platform-specific bugs and limitations)\n // Add common defines (GLSL version compatibility, feature detection)\n // Add precision declaration for fragment shaders\n let assembledSource = '';\n // prologue\n // ? `\\\n // ${getShaderNameDefine({id, source, type})}\n // ${getShaderType(type)}\n // ${getPlatformShaderDefines(platformInfo)}\n // ${getApplicationDefines(allDefines)}\n // ${isVertex ? '' : FRAGMENT_SHADER_PROLOGUE}\n // `\n // `;\n\n const hookFunctionMap = normalizeShaderHooks(hookFunctions);\n\n // Add source of dependent modules in resolved order\n const hookInjections: Record<string, ShaderInjection[]> = {};\n const declInjections: Record<string, ShaderInjection[]> = {};\n const mainInjections: Record<string, ShaderInjection[]> = {};\n\n for (const key in inject) {\n const injection =\n typeof inject[key] === 'string' ? {injection: inject[key], order: 0} : inject[key];\n const match = /^(v|f)s:(#)?([\\w-]+)$/.exec(key);\n if (match) {\n const hash = match[2];\n const name = match[3];\n if (hash) {\n if (name === 'decl') {\n declInjections[key] = [injection as any];\n } else {\n mainInjections[key] = [injection as any];\n }\n } else {\n hookInjections[key] = [injection as any];\n }\n } else {\n // Regex injection\n mainInjections[key] = [injection as any];\n }\n }\n\n // TODO - hack until shadertool modules support WebGPU\n const modulesToInject = modules;\n const applicationRelocation = relocateWGSLApplicationBindings(coreSource);\n const usedBindingsByGroup = getUsedBindingsByGroupFromApplicationWGSL(\n applicationRelocation.source\n );\n const reservedBindingKeysByGroup = reserveRegisteredModuleBindings(\n modulesToInject,\n options._bindingRegistry,\n usedBindingsByGroup\n );\n const bindingAssignments: WGSLBindingAssignment[] = [];\n\n for (const module of modulesToInject) {\n if (log) {\n checkShaderModuleDeprecations(module, coreSource, log);\n }\n const relocation = relocateWGSLModuleBindings(\n getShaderModuleSource(module, 'wgsl', log),\n module,\n {\n usedBindingsByGroup,\n bindingRegistry: options._bindingRegistry,\n reservedBindingKeysByGroup\n }\n );\n bindingAssignments.push(...relocation.bindingAssignments);\n const moduleSource = relocation.source;\n // Add the module source, and a #define that declares it presence\n assembledSource += moduleSource;\n\n const injections = module.injections?.[stage] || {};\n for (const key in injections) {\n const match = /^(v|f)s:#([\\w-]+)$/.exec(key);\n if (match) {\n const name = match[2];\n const injectionType = name === 'decl' ? declInjections : mainInjections;\n injectionType[key] = injectionType[key] || [];\n injectionType[key].push(injections[key]);\n } else {\n hookInjections[key] = hookInjections[key] || [];\n hookInjections[key].push(injections[key]);\n }\n }\n }\n\n // For injectShader\n assembledSource += INJECT_SHADER_DECLARATIONS;\n\n assembledSource = injectShader(assembledSource, stage, declInjections);\n\n assembledSource += getShaderHooks(hookFunctionMap[stage], hookInjections);\n assembledSource += formatWGSLBindingAssignmentComments(bindingAssignments);\n\n // Add the version directive and actual source of this shader\n assembledSource += applicationRelocation.source;\n\n // Apply any requested shader injections\n assembledSource = injectShader(assembledSource, stage, mainInjections);\n\n assertNoUnresolvedAutoBindings(assembledSource);\n\n return {source: assembledSource, bindingAssignments};\n}\n\n/**\n * Pulls together complete source code for either a vertex or a fragment shader\n * adding prologues, requested module chunks, and any final injections.\n * @param gl\n * @param options\n * @returns\n */\nfunction assembleShaderGLSL(\n platformInfo: PlatformInfo,\n options: {\n id?: string;\n source: string;\n language?: 'glsl' | 'wgsl';\n stage: 'vertex' | 'fragment';\n modules: ShaderModule[];\n defines?: Record<string, boolean>;\n hookFunctions?: any[];\n inject?: Record<string, string | ShaderInjection>;\n prologue?: boolean;\n log?: any;\n }\n) {\n const {\n source,\n stage,\n language = 'glsl',\n modules,\n defines = {},\n hookFunctions = [],\n inject = {},\n prologue = true,\n log\n } = options;\n\n assert(typeof source === 'string', 'shader source must be a string');\n\n const sourceVersion = language === 'glsl' ? getShaderInfo(source).version : -1;\n const targetVersion = platformInfo.shaderLanguageVersion;\n\n const sourceVersionDirective = sourceVersion === 100 ? '#version 100' : '#version 300 es';\n\n const sourceLines = source.split('\\n');\n // TODO : keep all pre-processor statements at the beginning of the shader.\n const coreSource = sourceLines.slice(1).join('\\n');\n\n // Combine Module and Application Defines\n const allDefines = {};\n modules.forEach(module => {\n Object.assign(allDefines, module.defines);\n });\n Object.assign(allDefines, defines);\n\n // Add platform defines (use these to work around platform-specific bugs and limitations)\n // Add common defines (GLSL version compatibility, feature detection)\n // Add precision declaration for fragment shaders\n let assembledSource = '';\n switch (language) {\n case 'wgsl':\n break;\n case 'glsl':\n assembledSource = prologue\n ? `\\\n${sourceVersionDirective}\n\n// ----- PROLOGUE -------------------------\n${`#define SHADER_TYPE_${stage.toUpperCase()}`}\n\n${getPlatformShaderDefines(platformInfo)}\n${stage === 'fragment' ? FRAGMENT_SHADER_PROLOGUE : ''}\n\n// ----- APPLICATION DEFINES -------------------------\n\n${getApplicationDefines(allDefines)}\n\n`\n : `${sourceVersionDirective}\n`;\n break;\n }\n\n const hookFunctionMap = normalizeShaderHooks(hookFunctions);\n\n // Add source of dependent modules in resolved order\n const hookInjections: Record<string, ShaderInjection[]> = {};\n const declInjections: Record<string, ShaderInjection[]> = {};\n const mainInjections: Record<string, ShaderInjection[]> = {};\n\n for (const key in inject) {\n const injection: ShaderInjection =\n typeof inject[key] === 'string' ? {injection: inject[key], order: 0} : inject[key];\n const match = /^(v|f)s:(#)?([\\w-]+)$/.exec(key);\n if (match) {\n const hash = match[2];\n const name = match[3];\n if (hash) {\n if (name === 'decl') {\n declInjections[key] = [injection];\n } else {\n mainInjections[key] = [injection];\n }\n } else {\n hookInjections[key] = [injection];\n }\n } else {\n // Regex injection\n mainInjections[key] = [injection];\n }\n }\n\n for (const module of modules) {\n if (log) {\n checkShaderModuleDeprecations(module, coreSource, log);\n }\n const moduleSource = getShaderModuleSource(module, stage, log);\n // Add the module source, and a #define that declares it presence\n assembledSource += moduleSource;\n\n const injections = module.instance?.normalizedInjections[stage] || {};\n for (const key in injections) {\n const match = /^(v|f)s:#([\\w-]+)$/.exec(key);\n if (match) {\n const name = match[2];\n const injectionType = name === 'decl' ? declInjections : mainInjections;\n injectionType[key] = injectionType[key] || [];\n injectionType[key].push(injections[key]);\n } else {\n hookInjections[key] = hookInjections[key] || [];\n hookInjections[key].push(injections[key]);\n }\n }\n }\n\n assembledSource += '// ----- MAIN SHADER SOURCE -------------------------';\n\n // For injectShader\n assembledSource += INJECT_SHADER_DECLARATIONS;\n\n assembledSource = injectShader(assembledSource, stage, declInjections);\n\n assembledSource += getShaderHooks(hookFunctionMap[stage], hookInjections);\n\n // Add the version directive and actual source of this shader\n assembledSource += coreSource;\n\n // Apply any requested shader injections\n assembledSource = injectShader(assembledSource, stage, mainInjections);\n\n if (language === 'glsl' && sourceVersion !== targetVersion) {\n assembledSource = transpileGLSLShader(assembledSource, stage);\n }\n\n if (language === 'glsl') {\n warnIfGLSLUniformBlocksAreNotStd140(assembledSource, stage, log);\n }\n\n return assembledSource.trim();\n}\n\n/**\n * Returns a combined `getUniforms` covering the options for all the modules,\n * the created function will pass on options to the inidividual `getUniforms`\n * function of each shader module and combine the results into one object that\n * can be passed to setUniforms.\n * @param modules\n * @returns\n */\nexport function assembleGetUniforms(modules: ShaderModule[]) {\n return function getUniforms(opts: Record<string, any>): Record<string, any> {\n const uniforms = {};\n for (const module of modules) {\n // `modules` is already sorted by dependency level. This guarantees that\n // modules have access to the uniforms that are generated by their dependencies.\n const moduleUniforms = module.getUniforms?.(opts, uniforms);\n Object.assign(uniforms, moduleUniforms);\n }\n return uniforms;\n };\n}\n\n/**\n * NOTE: Removed as id injection defeated caching of shaders\n * \n * Generate \"glslify-compatible\" SHADER_NAME defines\n * These are understood by the GLSL error parsing function\n * If id is provided and no SHADER_NAME constant is present in source, create one\n unction getShaderNameDefine(options: {\n id?: string;\n source: string;\n stage: 'vertex' | 'fragment';\n}): string {\n const {id, source, stage} = options;\n const injectShaderName = id && source.indexOf('SHADER_NAME') === -1;\n return injectShaderName\n ? `\n#define SHADER_NAME ${id}_${stage}`\n : '';\n}\n*/\n\n/** Generates application defines from an object of key value pairs */\nfunction getApplicationDefines(defines: Record<string, boolean> = {}): string {\n let sourceText = '';\n for (const define in defines) {\n const value = defines[define];\n if (value || Number.isFinite(value)) {\n sourceText += `#define ${define.toUpperCase()} ${defines[define]}\\n`;\n }\n }\n return sourceText;\n}\n\n/** Extracts the source code chunk for the specified shader type from the named shader module */\nexport function getShaderModuleSource(\n module: ShaderModule,\n stage: 'vertex' | 'fragment' | 'wgsl',\n log?: any\n): string {\n let moduleSource;\n switch (stage) {\n case 'vertex':\n moduleSource = module.vs || '';\n break;\n case 'fragment':\n moduleSource = module.fs || '';\n break;\n case 'wgsl':\n moduleSource = module.source || '';\n break;\n default:\n assert(false);\n }\n\n if (!module.name) {\n throw new Error('Shader module must have a name');\n }\n\n validateShaderModuleUniformLayout(module, stage, {log});\n\n const moduleName = module.name.toUpperCase().replace(/[^0-9a-z]/gi, '_');\n let source = `\\\n// ----- MODULE ${module.name} ---------------\n\n`;\n if (stage !== 'wgsl') {\n source += `#define MODULE_${moduleName}\\n`;\n }\n source += `${moduleSource}\\n`;\n return source;\n}\n\ntype BindingRelocationContext = {\n usedBindingsByGroup: Map<number, Set<number>>;\n bindingRegistry?: Map<string, number>;\n reservedBindingKeysByGroup: Map<number, Map<number, string>>;\n};\n\ntype WGSLBindingAssignment = {\n moduleName: string;\n name: string;\n group: number;\n location: number;\n};\n\ntype WGSLApplicationRelocationState = {\n sawSupportedBindingDeclaration: boolean;\n};\n\ntype WGSLRelocationState = {\n sawSupportedBindingDeclaration: boolean;\n nextHintedBindingLocation: number | null;\n};\n\ntype WGSLRelocationParams = {\n module: ShaderModule;\n context: BindingRelocationContext;\n bindingAssignments: WGSLBindingAssignment[];\n relocationState: WGSLRelocationState;\n};\n\nfunction getUsedBindingsByGroupFromApplicationWGSL(source: string): Map<number, Set<number>> {\n const usedBindingsByGroup = new Map<number, Set<number>>();\n\n for (const match of getWGSLBindingDeclarationMatches(\n source,\n WGSL_EXPLICIT_BINDING_DECLARATION_REGEXES\n )) {\n const location = Number(match.bindingToken);\n const group = Number(match.groupToken);\n\n validateApplicationWGSLBinding(group, location, match.name);\n registerUsedBindingLocation(\n usedBindingsByGroup,\n group,\n location,\n `application binding \"${match.name}\"`\n );\n }\n\n return usedBindingsByGroup;\n}\n\nfunction relocateWGSLApplicationBindings(source: string): {source: string} {\n const declarationMatches = getWGSLBindingDeclarationMatches(\n source,\n WGSL_BINDING_DECLARATION_REGEXES\n );\n const usedBindingsByGroup = new Map<number, Set<number>>();\n\n for (const declarationMatch of declarationMatches) {\n if (declarationMatch.bindingToken === 'auto') {\n continue;\n }\n\n const location = Number(declarationMatch.bindingToken);\n const group = Number(declarationMatch.groupToken);\n\n validateApplicationWGSLBinding(group, location, declarationMatch.name);\n registerUsedBindingLocation(\n usedBindingsByGroup,\n group,\n location,\n `application binding \"${declarationMatch.name}\"`\n );\n }\n\n const relocationState: WGSLApplicationRelocationState = {\n sawSupportedBindingDeclaration: declarationMatches.length > 0\n };\n\n const relocatedSource = replaceWGSLBindingDeclarationMatches(\n source,\n WGSL_BINDING_DECLARATION_REGEXES,\n declarationMatch =>\n relocateWGSLApplicationBindingMatch(declarationMatch, usedBindingsByGroup, relocationState)\n );\n\n if (hasWGSLAutoBinding(source) && !relocationState.sawSupportedBindingDeclaration) {\n throw new Error(\n 'Unsupported @binding(auto) declaration form in application WGSL. ' +\n 'Use adjacent \"@group(N)\" and \"@binding(auto)\" decorators followed by a bindable \"var\" declaration.'\n );\n }\n\n return {source: relocatedSource};\n}\n\nfunction relocateWGSLModuleBindings(\n moduleSource: string,\n module: ShaderModule,\n context: BindingRelocationContext\n): {source: string; bindingAssignments: WGSLBindingAssignment[]} {\n const bindingAssignments: WGSLBindingAssignment[] = [];\n const declarationMatches = getWGSLBindingDeclarationMatches(\n moduleSource,\n MODULE_WGSL_BINDING_DECLARATION_REGEXES\n );\n const relocationState: WGSLRelocationState = {\n sawSupportedBindingDeclaration: declarationMatches.length > 0,\n nextHintedBindingLocation:\n typeof module.firstBindingSlot === 'number' ? module.firstBindingSlot : null\n };\n\n const relocatedSource = replaceWGSLBindingDeclarationMatches(\n moduleSource,\n MODULE_WGSL_BINDING_DECLARATION_REGEXES,\n declarationMatch =>\n relocateWGSLModuleBindingMatch(declarationMatch, {\n module,\n context,\n bindingAssignments,\n relocationState\n })\n );\n\n if (hasWGSLAutoBinding(moduleSource) && !relocationState.sawSupportedBindingDeclaration) {\n throw new Error(\n `Unsupported @binding(auto) declaration form in module \"${module.name}\". ` +\n 'Use adjacent \"@group(N)\" and \"@binding(auto)\" decorators followed by a bindable \"var\" declaration.'\n );\n }\n\n return {source: relocatedSource, bindingAssignments};\n}\n\nfunction relocateWGSLModuleBindingMatch(\n declarationMatch: WGSLBindingDeclarationMatch,\n params: WGSLRelocationParams\n): string {\n const {module, context, bindingAssignments, relocationState} = params;\n\n const {match, bindingToken, groupToken, name} = declarationMatch;\n const group = Number(groupToken);\n\n if (bindingToken === 'auto') {\n const registryKey = getBindingRegistryKey(group, module.name, name);\n const registryLocation = context.bindingRegistry?.get(registryKey);\n const location =\n registryLocation !== undefined\n ? registryLocation\n : relocationState.nextHintedBindingLocation === null\n ? allocateAutoBindingLocation(group, context.usedBindingsByGroup)\n : allocateAutoBindingLocation(\n group,\n context.usedBindingsByGroup,\n relocationState.nextHintedBindingLocation\n );\n validateModuleWGSLBinding(module.name, group, location, name);\n if (\n registryLocation !== undefined &&\n claimReservedBindingLocation(context.reservedBindingKeysByGroup, group, location, registryKey)\n ) {\n bindingAssignments.push({moduleName: module.name, name, group, location});\n return match.replace(/@binding\\(\\s*auto\\s*\\)/, `@binding(${location})`);\n }\n registerUsedBindingLocation(\n context.usedBindingsByGroup,\n group,\n location,\n `module \"${module.name}\" binding \"${name}\"`\n );\n context.bindingRegistry?.set(registryKey, location);\n bindingAssignments.push({moduleName: module.name, name, group, location});\n if (relocationState.nextHintedBindingLocation !== null && registryLocation === undefined) {\n relocationState.nextHintedBindingLocation = location + 1;\n }\n return match.replace(/@binding\\(\\s*auto\\s*\\)/, `@binding(${location})`);\n }\n\n const location = Number(bindingToken);\n validateModuleWGSLBinding(module.name, group, location, name);\n registerUsedBindingLocation(\n context.usedBindingsByGroup,\n group,\n location,\n `module \"${module.name}\" binding \"${name}\"`\n );\n bindingAssignments.push({moduleName: module.name, name, group, location});\n return match;\n}\n\nfunction relocateWGSLApplicationBindingMatch(\n declarationMatch: WGSLBindingDeclarationMatch,\n usedBindingsByGroup: Map<number, Set<number>>,\n relocationState: WGSLApplicationRelocationState\n): string {\n const {match, bindingToken, groupToken, name} = declarationMatch;\n const group = Number(groupToken);\n\n if (bindingToken === 'auto') {\n const location = allocateApplicationAutoBindingLocation(group, usedBindingsByGroup);\n validateApplicationWGSLBinding(group, location, name);\n registerUsedBindingLocation(\n usedBindingsByGroup,\n group,\n location,\n `application binding \"${name}\"`\n );\n return match.replace(/@binding\\(\\s*auto\\s*\\)/, `@binding(${location})`);\n }\n\n relocationState.sawSupportedBindingDeclaration = true;\n return match;\n}\n\nfunction reserveRegisteredModuleBindings(\n modules: ShaderModule[],\n bindingRegistry: Map<string, number> | undefined,\n usedBindingsByGroup: Map<number, Set<number>>\n): Map<number, Map<number, string>> {\n const reservedBindingKeysByGroup = new Map<number, Map<number, string>>();\n if (!bindingRegistry) {\n return reservedBindingKeysByGroup;\n }\n\n for (const module of modules) {\n for (const binding of getModuleWGSLBindingDeclarations(module)) {\n const registryKey = getBindingRegistryKey(binding.group, module.name, binding.name);\n const location = bindingRegistry.get(registryKey);\n if (location !== undefined) {\n const reservedBindingKeys =\n reservedBindingKeysByGroup.get(binding.group) || new Map<number, string>();\n const existingReservation = reservedBindingKeys.get(location);\n if (existingReservation && existingReservation !== registryKey) {\n throw new Error(\n `Duplicate WGSL binding reservation for modules \"${existingReservation}\" and \"${registryKey}\": group ${binding.group}, binding ${location}.`\n );\n }\n\n registerUsedBindingLocation(\n usedBindingsByGroup,\n binding.group,\n location,\n `registered module binding \"${registryKey}\"`\n );\n reservedBindingKeys.set(location, registryKey);\n reservedBindingKeysByGroup.set(binding.group, reservedBindingKeys);\n }\n }\n }\n\n return reservedBindingKeysByGroup;\n}\n\nfunction claimReservedBindingLocation(\n reservedBindingKeysByGroup: Map<number, Map<number, string>>,\n group: number,\n location: number,\n registryKey: string\n): boolean {\n const reservedBindingKeys = reservedBindingKeysByGroup.get(group);\n if (!reservedBindingKeys) {\n return false;\n }\n\n const reservedKey = reservedBindingKeys.get(location);\n if (!reservedKey) {\n return false;\n }\n if (reservedKey !== registryKey) {\n throw new Error(\n `Registered module binding \"${registryKey}\" collided with \"${reservedKey}\": group ${group}, binding ${location}.`\n );\n }\n return true;\n}\n\nfunction getModuleWGSLBindingDeclarations(module: ShaderModule): {name: string; group: number}[] {\n const declarations: {name: string; group: number}[] = [];\n const moduleSource = module.source || '';\n\n for (const match of getWGSLBindingDeclarationMatches(\n moduleSource,\n MODULE_WGSL_BINDING_DECLARATION_REGEXES\n )) {\n declarations.push({\n name: match.name,\n group: Number(match.groupToken)\n });\n }\n\n return declarations;\n}\n\nfunction validateApplicationWGSLBinding(group: number, location: number, name: string): void {\n if (group === 0 && location >= RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT) {\n throw new Error(\n `Application binding \"${name}\" in group 0 uses reserved binding ${location}. ` +\n `Application-owned explicit group-0 bindings must stay below ${RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT}.`\n );\n }\n}\n\nfunction validateModuleWGSLBinding(\n moduleName: string,\n group: number,\n location: number,\n name: string\n): void {\n if (group === 0 && location < RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT) {\n throw new Error(\n `Module \"${moduleName}\" binding \"${name}\" in group 0 uses reserved application binding ${location}. ` +\n `Module-owned explicit group-0 bindings must be ${RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT} or higher.`\n );\n }\n}\n\nfunction registerUsedBindingLocation(\n usedBindingsByGroup: Map<number, Set<number>>,\n group: number,\n location: number,\n label: string\n): void {\n const usedBindings = usedBindingsByGroup.get(group) || new Set<number>();\n if (usedBindings.has(location)) {\n throw new Error(\n `Duplicate WGSL binding assignment for ${label}: group ${group}, binding ${location}.`\n );\n }\n usedBindings.add(location);\n usedBindingsByGroup.set(group, usedBindings);\n}\n\nfunction allocateAutoBindingLocation(\n group: number,\n usedBindingsByGroup: Map<number, Set<number>>,\n preferredBindingLocation?: number\n): number {\n const usedBindings = usedBindingsByGroup.get(group) || new Set<number>();\n let nextBinding =\n preferredBindingLocation ??\n (group === 0\n ? RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT\n : usedBindings.size > 0\n ? Math.max(...usedBindings) + 1\n : 0);\n\n while (usedBindings.has(nextBinding)) {\n nextBinding++;\n }\n\n return nextBinding;\n}\n\nfunction allocateApplicationAutoBindingLocation(\n group: number,\n usedBindingsByGroup: Map<number, Set<number>>\n): number {\n const usedBindings = usedBindingsByGroup.get(group) || new Set<number>();\n let nextBinding = 0;\n\n while (usedBindings.has(nextBinding)) {\n nextBinding++;\n }\n\n return nextBinding;\n}\n\nfunction assertNoUnresolvedAutoBindings(source: string): void {\n const unresolvedBinding = getFirstWGSLAutoBindingDeclarationMatch(\n source,\n MODULE_WGSL_BINDING_DECLARATION_REGEXES\n );\n if (!unresolvedBinding) {\n return;\n }\n\n const moduleName = getWGSLModuleNameAtIndex(source, unresolvedBinding.index);\n if (moduleName) {\n throw new Error(\n `Unresolved @binding(auto) for module \"${moduleName}\" binding \"${unresolvedBinding.name}\" remained in assembled WGSL source.`\n );\n }\n\n if (isInApplicationWGSLSection(source, unresolvedBinding.index)) {\n throw new Error(\n `Unresolved @binding(auto) for application binding \"${unresolvedBinding.name}\" remained in assembled WGSL source.`\n );\n }\n\n throw new Error(\n `Unresolved @binding(auto) remained in assembled WGSL source near \"${formatWGSLSourceSnippet(unresolvedBinding.match)}\".`\n );\n}\n\nfunction formatWGSLBindingAssignmentComments(bindingAssignments: WGSLBindingAssignment[]): string {\n if (bindingAssignments.length === 0) {\n return '';\n }\n\n let source = '// ----- MODULE WGSL BINDING ASSIGNMENTS ---------------\\n';\n for (const bindingAssignment of bindingAssignments) {\n source += `// ${bindingAssignment.moduleName}.${bindingAssignment.name} -> @group(${bindingAssignment.group}) @binding(${bindingAssignment.location})\\n`;\n }\n source += '\\n';\n return source;\n}\n\nfunction getBindingRegistryKey(group: number, moduleName: string, bindingName: string): string {\n return `${group}:${moduleName}:${bindingName}`;\n}\n\nfunction getWGSLModuleNameAtIndex(source: string, index: number): string | undefined {\n const moduleHeaderRegex = /^\\/\\/ ----- MODULE ([^\\n]+) ---------------$/gm;\n let moduleName: string | undefined;\n let match: RegExpExecArray | null;\n\n match = moduleHeaderRegex.exec(source);\n while (match && match.index <= index) {\n moduleName = match[1];\n match = moduleHeaderRegex.exec(source);\n }\n\n return moduleName;\n}\n\nfunction isInApplicationWGSLSection(source: string, index: number): boolean {\n const injectionMarkerIndex = source.indexOf(INJECT_SHADER_DECLARATIONS);\n return injectionMarkerIndex >= 0 ? index > injectionMarkerIndex : true;\n}\n\nfunction formatWGSLSourceSnippet(source: string): string {\n return source.replace(/\\s+/g, ' ').trim();\n}\n\n/*\nfunction getHookFunctions(\n hookFunctions: Record<string, HookFunction>,\n hookInjections: Record<string, Injection[]>\n): string {\n let result = '';\n for (const hookName in hookFunctions) {\n const hookFunction = hookFunctions[hookName];\n result += `void ${hookFunction.signature} {\\n`;\n if (hookFunction.header) {\n result += ` ${hookFunction.header}`;\n }\n if (hookInjections[hookName]) {\n const injections = hookInjections[hookName];\n injections.sort((a: {order: number}, b: {order: number}): number => a.order - b.order);\n for (const injection of injections) {\n result += ` ${injection.injection}\\n`;\n }\n }\n if (hookFunction.footer) {\n result += ` ${hookFunction.footer}`;\n }\n result += '}\\n';\n }\n\n return result;\n}\n\nfunction normalizeHookFunctions(hookFunctions: (string | HookFunction)[]): {\n vs: Record<string, HookFunction>;\n fs: Record<string, HookFunction>;\n} {\n const result: {vs: Record<string, any>; fs: Record<string, any>} = {\n vs: {},\n fs: {}\n };\n\n hookFunctions.forEach((hookFunction: string | HookFunction) => {\n let opts: HookFunction;\n let hook: string;\n if (typeof hookFunction !== 'string') {\n opts = hookFunction;\n hook = opts.hook;\n } else {\n opts = {} as HookFunction;\n hook = hookFunction;\n }\n hook = hook.trim();\n const [stage, signature] = hook.split(':');\n const name = hook.replace(/\\(.+/, '');\n if (stage !== 'vs' && stage !== 'fs') {\n throw new Error(stage);\n }\n result[stage][name] = Object.assign(opts, {signature});\n });\n\n return result;\n}\n*/\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nconst DEFINE_NAME_PATTERN = '([a-zA-Z_][a-zA-Z0-9_]*)';\nconst IFDEF_REGEXP = new RegExp(`^\\\\s*\\\\#\\\\s*ifdef\\\\s*${DEFINE_NAME_PATTERN}\\\\s*$`);\nconst IFNDEF_REGEXP = new RegExp(`^\\\\s*\\\\#\\\\s*ifndef\\\\s*${DEFINE_NAME_PATTERN}\\\\s*(?:\\\\/\\\\/.*)?$`);\nconst ELSE_REGEXP = /^\\s*\\#\\s*else\\s*(?:\\/\\/.*)?$/;\nconst ENDIF_REGEXP = /^\\s*\\#\\s*endif\\s*$/;\nconst IFDEF_WITH_COMMENT_REGEXP = new RegExp(\n `^\\\\s*\\\\#\\\\s*ifdef\\\\s*${DEFINE_NAME_PATTERN}\\\\s*(?:\\\\/\\\\/.*)?$`\n);\nconst ENDIF_WITH_COMMENT_REGEXP = /^\\s*\\#\\s*endif\\s*(?:\\/\\/.*)?$/;\n\nexport type PreprocessorOptions = {\n defines?: Record<string, boolean>;\n};\n\nexport function preprocess(source: string, options?: PreprocessorOptions): string {\n const lines = source.split('\\n');\n const output: string[] = [];\n\n const conditionalStack: Array<{\n parentActive: boolean;\n branchTaken: boolean;\n active: boolean;\n }> = [];\n let conditional = true;\n\n for (const line of lines) {\n const matchIf = line.match(IFDEF_WITH_COMMENT_REGEXP) || line.match(IFDEF_REGEXP);\n const matchIfNot = line.match(IFNDEF_REGEXP);\n const matchElse = line.match(ELSE_REGEXP);\n const matchEnd = line.match(ENDIF_WITH_COMMENT_REGEXP) || line.match(ENDIF_REGEXP);\n\n if (matchIf || matchIfNot) {\n const defineName = (matchIf || matchIfNot)?.[1];\n const defineValue: boolean = Boolean(options?.defines?.[defineName!]);\n const branchTaken: boolean = matchIf ? defineValue : !defineValue;\n const active: boolean = conditional && branchTaken;\n conditionalStack.push({parentActive: conditional, branchTaken, active});\n conditional = active;\n } else if (matchElse) {\n const currentConditional = conditionalStack[conditionalStack.length - 1];\n if (!currentConditional) {\n throw new Error('Encountered #else without matching #ifdef or #ifndef');\n }\n currentConditional.active =\n currentConditional.parentActive && !currentConditional.branchTaken;\n currentConditional.branchTaken = true;\n conditional = currentConditional.active;\n } else if (matchEnd) {\n conditionalStack.pop();\n conditional = conditionalStack.length\n ? conditionalStack[conditionalStack.length - 1].active\n : true;\n } else if (conditional) {\n output.push(line);\n }\n }\n\n if (conditionalStack.length > 0) {\n throw new Error('Unterminated conditional block in shader source');\n }\n\n return output.join('\\n');\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderModule} from './shader-module/shader-module';\nimport {initializeShaderModules} from './shader-module/shader-module';\nimport {\n AssembleShaderProps,\n GetUniformsFunc,\n assembleWGSLShader,\n assembleGLSLShaderPair\n} from './shader-assembly/assemble-shaders';\nimport {\n getShaderBindingDebugRowsFromWGSL,\n type ShaderBindingDebugRow\n} from './shader-assembly/wgsl-binding-debug';\nimport {preprocess} from './preprocessor/preprocessor';\n\n/**\n * A stateful version of `assembleShaders` that can be used to assemble shaders.\n * Supports setting of default modules and hooks.\n */\nexport class ShaderAssembler {\n /** Default ShaderAssembler instance */\n static defaultShaderAssembler: ShaderAssembler;\n /** Hook functions */\n private readonly _hookFunctions: any[] = [];\n /** Shader modules */\n private _defaultModules: ShaderModule[] = [];\n /** Stable per-run WGSL auto-binding assignments keyed by group/module/binding. */\n private readonly _wgslBindingRegistry = new Map<string, number>();\n\n /**\n * A default shader assembler instance - the natural place to register default modules and hooks\n * @returns\n */\n static getDefaultShaderAssembler(): ShaderAssembler {\n ShaderAssembler.defaultShaderAssembler =\n ShaderAssembler.defaultShaderAssembler || new ShaderAssembler();\n return ShaderAssembler.defaultShaderAssembler;\n }\n\n /**\n * Add a default module that does not have to be provided with every call to assembleShaders()\n */\n addDefaultModule(module: ShaderModule): void {\n if (\n !this._defaultModules.find(\n m => m.name === (typeof module === 'string' ? module : module.name)\n )\n ) {\n this._defaultModules.push(module);\n }\n }\n\n /**\n * Remove a default module\n */\n removeDefaultModule(module: ShaderModule): void {\n const moduleName = typeof module === 'string' ? module : module.name;\n this._defaultModules = this._defaultModules.filter(m => m.name !== moduleName);\n }\n\n /**\n * Register a shader hook\n * @param hook\n * @param opts\n */\n addShaderHook(hook: string, opts?: any): void {\n if (opts) {\n hook = Object.assign(opts, {hook});\n }\n this._hookFunctions.push(hook);\n }\n\n /**\n * Assemble a WGSL unified shader\n * @param platformInfo\n * @param props\n * @returns\n */\n assembleWGSLShader(props: AssembleShaderProps): {\n source: string;\n getUniforms: GetUniformsFunc;\n modules: ShaderModule[];\n bindingAssignments: {moduleName: string; name: string; group: number; location: number}[];\n bindingTable: ShaderBindingDebugRow[];\n } {\n const modules = this._getModuleList(props.modules); // Combine with default modules\n const hookFunctions = this._hookFunctions; // TODO - combine with default hook functions\n const {source, getUniforms, bindingAssignments} = assembleWGSLShader({\n ...props,\n // @ts-expect-error\n source: props.source,\n _bindingRegistry: this._wgslBindingRegistry,\n modules,\n hookFunctions\n });\n const defines = {\n ...modules.reduce<Record<string, boolean>>((accumulator, module) => {\n Object.assign(accumulator, module.defines);\n return accumulator;\n }, {}),\n ...props.defines\n };\n // WGSL does not have built-in preprocessing support (just compile time constants)\n const preprocessedSource =\n props.platformInfo.shaderLanguage === 'wgsl' ? preprocess(source, {defines}) : source;\n return {\n source: preprocessedSource,\n getUniforms,\n modules,\n bindingAssignments,\n bindingTable: getShaderBindingDebugRowsFromWGSL(preprocessedSource, bindingAssignments)\n };\n }\n\n /**\n * Assemble a pair of shaders into a single shader program\n * @param platformInfo\n * @param props\n * @returns\n */\n assembleGLSLShaderPair(props: AssembleShaderProps): {\n vs: string;\n fs: string;\n getUniforms: GetUniformsFunc;\n modules: ShaderModule[];\n } {\n const modules = this._getModuleList(props.modules); // Combine with default modules\n const hookFunctions = this._hookFunctions; // TODO - combine with default hook functions\n const assembled = assembleGLSLShaderPair({\n ...props,\n // @ts-expect-error\n vs: props.vs,\n // @ts-expect-error\n fs: props.fs,\n modules,\n hookFunctions\n });\n\n return {...assembled, modules};\n }\n\n /**\n * Dedupe and combine with default modules\n */\n _getModuleList(appModules: ShaderModule[] = []): ShaderModule[] {\n const modules = new Array<ShaderModule>(this._defaultModules.length + appModules.length);\n const seen: Record<string, boolean> = {};\n let count = 0;\n\n for (let i = 0, len = this._defaultModules.length; i < len; ++i) {\n const module = this._defaultModules[i];\n const name = module.name;\n modules[count++] = module;\n seen[name] = true;\n }\n\n for (let i = 0, len = appModules.length; i < len; ++i) {\n const module = appModules[i];\n const name = module.name;\n if (!seen[name]) {\n modules[count++] = module;\n seen[name] = true;\n }\n }\n\n modules.length = count;\n\n initializeShaderModules(modules);\n return modules;\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nconst FS_GLES = /* glsl */ `\\\nout vec4 transform_output;\nvoid main() {\n transform_output = vec4(0);\n}`;\nconst FS300 = `#version 300 es\\n${FS_GLES}`;\n\ntype QualifierInfo = {\n qualifier: string;\n type: string;\n name: string;\n};\n\n// Prase given glsl line and return qualifier details or null\nexport function getQualifierDetails(\n line: string,\n qualifiers: string | string[]\n): QualifierInfo | null {\n qualifiers = Array.isArray(qualifiers) ? qualifiers : [qualifiers];\n const words = line.replace(/^\\s+/, '').split(/\\s+/);\n // TODO add support for precession qualifiers (highp, mediump and lowp)\n const [qualifier, type, definition] = words;\n if (!qualifiers.includes(qualifier) || !type || !definition) {\n return null;\n }\n const name = definition.split(';')[0];\n return {qualifier, type, name};\n}\n\n/**\n * Given the shader input and output variable names,\n * builds and return a pass through fragment shader.\n */\nexport function getPassthroughFS(options?: {\n input?: string;\n inputChannels?: 1 | 2 | 3 | 4;\n output?: string;\n}): string {\n const {input, inputChannels, output} = options || {};\n if (!input) {\n // Default shader\n return FS300;\n }\n if (!inputChannels) {\n throw new Error('inputChannels');\n }\n const inputType = channelCountToType(inputChannels);\n const outputValue = convertToVec4(input, inputChannels);\n return `\\\n#version 300 es\nin ${inputType} ${input};\nout vec4 ${output};\nvoid main() {\n ${output} = ${outputValue};\n}`;\n}\n\n/** convert glsl type to suffix */\nexport function typeToChannelSuffix(type: string): 'x' | 'xy' | 'xyz' | 'xyzw' {\n // biome-ignore format: preserve layout\n switch (type) {\n case 'float': return 'x';\n case 'vec2': return 'xy';\n case 'vec3': return 'xyz';\n case 'vec4': return 'xyzw';\n default:\n throw new Error(type);\n }\n}\n\n/** convert glsl type to channel count */\nexport function typeToChannelCount(type: string): 1 | 2 | 3 | 4 {\n // biome-ignore format: preserve layout\n switch (type) {\n case 'float': return 1;\n case 'vec2': return 2;\n case 'vec3': return 3;\n case 'vec4': return 4;\n default:\n throw new Error(type);\n }\n}\nfunction channelCountToType(channels: 1 | 2 | 3 | 4): 'float' | 'vec2' | 'vec3' | 'vec4' {\n // biome-ignore format: preserve layout\n switch (channels) {\n case 1: return 'float';\n case 2: return 'vec2';\n case 3: return 'vec3';\n case 4: return 'vec4';\n default:\n throw new Error(`invalid channels: ${channels}`);\n }\n}\n\n/** Returns glsl instruction for converting to vec4 */\nexport function convertToVec4(variable: string, channels: 1 | 2 | 3 | 4): string {\n // biome-ignore format: preserve layout\n switch (channels) {\n case 1: return `vec4(${variable}, 0.0, 0.0, 1.0)`;\n case 2: return `vec4(${variable}, 0.0, 1.0)`;\n case 3: return `vec4(${variable}, 1.0)`;\n case 4: return variable;\n default:\n throw new Error(`invalid channels: ${channels}`);\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/**\n * Capitalize first letter of a string\n * @param {string} str\n * @returns {string}\n */\nexport function capitalize(str: string): string {\n return typeof str === 'string' ? str.charAt(0).toUpperCase() + str.slice(1) : str;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {UniformFormat} from '../../../types';\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\nimport {capitalize} from '../utils/capitalize';\n\nexport type GLSLGenerationOptions = {\n shaderLanguage: 'glsl';\n uniforms: 'scoped-interface-blocks' | 'unscoped-interface-blocks' | 'uniforms';\n};\n\nexport function generateGLSLForModule(module: ShaderModule, options: GLSLGenerationOptions) {\n return generateGLSLUniformDeclarations(module, options);\n}\n\nfunction generateGLSLUniformDeclarations(\n module: ShaderModule,\n options: GLSLGenerationOptions\n): string {\n const glsl: string[] = [];\n\n // => layout(std140) uniform UniformBlockName {\n switch (options.uniforms) {\n case 'scoped-interface-blocks':\n case 'unscoped-interface-blocks':\n glsl.push(`layout(std140) uniform ${capitalize(module.name)} {`);\n break;\n case 'uniforms':\n // ignore\n }\n\n for (const [uniformName, uniformFormat] of Object.entries(module.uniformTypes || {})) {\n if (typeof uniformFormat !== 'string') {\n throw new Error(\n `Composite uniform types are not supported by GLSL shader generation: ${module.name}.${uniformName}`\n );\n }\n\n const glslUniformType = getGLSLUniformType(uniformFormat as UniformFormat);\n switch (options.uniforms) {\n case 'scoped-interface-blocks':\n // => layout(std140) uniform UniformBlockName {\n glsl.push(` ${glslUniformType} ${uniformName};`);\n break;\n case 'unscoped-interface-blocks':\n // => layout(std140) uniform UniformBlockName {\n glsl.push(` ${glslUniformType} ${module.name}_${uniformName};`);\n break;\n case 'uniforms':\n glsl.push(`uniform ${glslUniformType} ${module.name}_${uniformName};`);\n }\n }\n\n switch (options.uniforms) {\n case 'scoped-interface-blocks':\n glsl.push(`} ${module.name};`);\n break;\n case 'unscoped-interface-blocks':\n glsl.push('};');\n break;\n case 'uniforms':\n // ignore\n }\n\n // final new line\n glsl.push('');\n\n return glsl.join('\\n');\n}\n\n/** Map a luma.gl WebGPU style uniform type to GLSL */\nfunction getGLSLUniformType(uniformFormat: UniformFormat): string {\n const UNIFORM_TYPE_TO_GLSL: Record<UniformFormat, string> = {\n f32: 'float',\n i32: 'int',\n u32: 'uint',\n 'vec2<f32>': 'vec2',\n 'vec3<f32>': 'vec3',\n 'vec4<f32>': 'vec4',\n 'vec2<i32>': 'ivec2',\n 'vec3<i32>': 'ivec3',\n 'vec4<i32>': 'ivec4',\n 'vec2<u32>': 'uvec2',\n 'vec3<u32>': 'uvec3',\n 'vec4<u32>': 'uvec4',\n 'mat2x2<f32>': 'mat2',\n 'mat2x3<f32>': 'mat2x3',\n 'mat2x4<f32>': 'mat2x4',\n 'mat3x2<f32>': 'mat3x2',\n 'mat3x3<f32>': 'mat3',\n 'mat3x4<f32>': 'mat3x4',\n 'mat4x2<f32>': 'mat4x2',\n 'mat4x3<f32>': 'mat4x3',\n 'mat4x4<f32>': 'mat4'\n };\n\n const glsl = UNIFORM_TYPE_TO_GLSL[uniformFormat];\n return glsl;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\nimport {capitalize} from '../utils/capitalize';\n\nexport type WGSLGenerationOptions = {\n shaderLanguage: 'wgsl';\n};\n\nexport function generateWGSLForModule(module: ShaderModule, options: WGSLGenerationOptions) {\n return generateWGSLUniformDeclarations(module, options);\n}\n\nexport function generateWGSLUniformDeclarations(\n module: ShaderModule,\n options: WGSLGenerationOptions\n) {\n const wgsl: string[] = [];\n\n // => uniform UniformBlockName {\n wgsl.push(`struct ${capitalize(module.name)} {`);\n\n for (const [uniformName, uniformFormat] of Object.entries(module?.uniformTypes || {})) {\n if (typeof uniformFormat !== 'string') {\n throw new Error(\n `Composite uniform types are not supported by WGSL shader generation: ${module.name}.${uniformName}`\n );\n }\n\n const wgslUniformType = uniformFormat;\n wgsl.push(` ${uniformName} : ${wgslUniformType};`);\n }\n wgsl.push('};');\n\n wgsl.push(`var<uniform> ${module.name} : ${capitalize(module.name)};`);\n\n return wgsl.join('\\n');\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {ShaderModule} from '../shader-module/shader-module';\n\nimport type {GLSLGenerationOptions} from './glsl/generate-glsl';\nimport {generateGLSLForModule} from './glsl/generate-glsl';\n\nimport type {WGSLGenerationOptions} from './wgsl/generate-wgsl';\nimport {generateWGSLForModule} from './wgsl/generate-wgsl';\n\n/** Options for how to generate shader code from a module */\nexport type ShaderGenerationOptions = GLSLGenerationOptions | WGSLGenerationOptions;\n\n/** Generates shader code for a module */\nexport function generateShaderForModule(\n module: ShaderModule<Record<string, unknown>>,\n options: ShaderGenerationOptions\n): string {\n switch (options.shaderLanguage) {\n case 'glsl':\n return generateGLSLForModule(module, options);\n case 'wgsl':\n return generateWGSLForModule(module, options);\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// Forked from THREE.js under MIT license\n// Fast Half Float Conversions, http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf\n\nimport {clamp} from '@math.gl/core';\n\n/** Pre-calculated tables for float16 conversion */\ntype Float16Tables = {\n // float32 to float16 helpers\n baseTable: Uint32Array;\n shiftTable: Uint32Array;\n // float16 to float32 helpers\n mantissaTable: Uint32Array;\n exponentTable: Uint32Array;\n offsetTable: Uint32Array;\n};\n\n/** */\nlet float16Tables: Float16Tables | null = null;\n\n/** Storage that can be viewed both as float and integer */\nconst buffer = new ArrayBuffer(4);\nconst floatView = new Float32Array(buffer);\nconst uint32View = new Uint32Array(buffer);\n\n/**\n * float32 to float16\n * @param val\n * @returns\n */\nexport function toHalfFloat(val: number): number {\n float16Tables ||= generateFloat16Tables();\n\n // if ( Math.abs( val ) > 65504 ) console.warn( 'toHalfFloat(): Value out of range.' );\n\n val = clamp(val, -65504, 65504);\n\n floatView[0] = val;\n const f = uint32View[0];\n const e = (f >> 23) & 0x1ff;\n return float16Tables.baseTable[e] + ((f & 0x007fffff) >> float16Tables.shiftTable[e]);\n}\n\n/**\n * float16 to float32\n * @param val\n * @returns\n */\nexport function fromHalfFloat(val: number): number {\n float16Tables ||= generateFloat16Tables();\n\n const m = val >> 10;\n uint32View[0] =\n float16Tables.mantissaTable[float16Tables.offsetTable[m] + (val & 0x3ff)] +\n float16Tables.exponentTable[m];\n return floatView[0];\n}\n\nfunction generateFloat16Tables(): Float16Tables {\n // float32 to float16 helpers\n\n const baseTable = new Uint32Array(512);\n const shiftTable = new Uint32Array(512);\n\n for (let i = 0; i < 256; ++i) {\n const e = i - 127;\n\n // very small number (0, -0)\n\n if (e < -27) {\n baseTable[i] = 0x0000;\n baseTable[i | 0x100] = 0x8000;\n shiftTable[i] = 24;\n shiftTable[i | 0x100] = 24;\n\n // small number (denorm)\n } else if (e < -14) {\n baseTable[i] = 0x0400 >> (-e - 14);\n baseTable[i | 0x100] = (0x0400 >> (-e - 14)) | 0x8000;\n shiftTable[i] = -e - 1;\n shiftTable[i | 0x100] = -e - 1;\n\n // normal number\n } else if (e <= 15) {\n baseTable[i] = (e + 15) << 10;\n baseTable[i | 0x100] = ((e + 15) << 10) | 0x8000;\n shiftTable[i] = 13;\n shiftTable[i | 0x100] = 13;\n\n // large number (Infinity, -Infinity)\n } else if (e < 128) {\n baseTable[i] = 0x7c00;\n baseTable[i | 0x100] = 0xfc00;\n shiftTable[i] = 24;\n shiftTable[i | 0x100] = 24;\n\n // stay (NaN, Infinity, -Infinity)\n } else {\n baseTable[i] = 0x7c00;\n baseTable[i | 0x100] = 0xfc00;\n shiftTable[i] = 13;\n shiftTable[i | 0x100] = 13;\n }\n }\n\n // float16 to float32 helpers\n\n const mantissaTable = new Uint32Array(2048);\n const exponentTable = new Uint32Array(64);\n const offsetTable = new Uint32Array(64);\n\n for (let i = 1; i < 1024; ++i) {\n let m = i << 13; // zero pad mantissa bits\n let e = 0; // zero exponent\n\n // normalized\n while ((m & 0x00800000) === 0) {\n m <<= 1;\n e -= 0x00800000; // decrement exponent\n }\n\n m &= ~0x00800000; // clear leading 1 bit\n e += 0x38800000; // adjust bias\n\n mantissaTable[i] = m | e;\n }\n\n for (let i = 1024; i < 2048; ++i) {\n mantissaTable[i] = 0x38000000 + ((i - 1024) << 13);\n }\n\n for (let i = 1; i < 31; ++i) {\n exponentTable[i] = i << 23;\n }\n\n exponentTable[31] = 0x47800000;\n exponentTable[32] = 0x80000000;\n\n for (let i = 33; i < 63; ++i) {\n exponentTable[i] = 0x80000000 + ((i - 32) << 23);\n }\n\n exponentTable[63] = 0xc7800000;\n\n for (let i = 1; i < 64; ++i) {\n if (i !== 32) {\n offsetTable[i] = 1024;\n }\n }\n\n return {baseTable, shiftTable, mantissaTable, exponentTable, offsetTable};\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {NumericArray} from '@math.gl/types';\n\n/**\n * Calculate WebGL 64 bit float\n * @param a - the input float number\n * @param out - the output array. If not supplied, a new array is created.\n * @param startIndex - the index in the output array to fill from. Default 0.\n * @returns - the fp64 representation of the input number\n */\nexport function fp64ify(a: number, out: NumericArray = [], startIndex: number = 0): NumericArray {\n const hiPart = Math.fround(a);\n const loPart = a - hiPart;\n out[startIndex] = hiPart;\n out[startIndex + 1] = loPart;\n return out;\n}\n\n/**\n * Calculate the low part of a WebGL 64 bit float\n * @param a the input float number\n * @returns the lower 32 bit of the number\n */\nexport function fp64LowPart(a: number): number {\n return a - Math.fround(a);\n}\n\n/**\n * Calculate WebGL 64 bit matrix (transposed \"Float64Array\")\n * @param matrix the input matrix\n * @returns the fp64 representation of the input matrix\n */\nexport function fp64ifyMatrix4(matrix: NumericArray): Float32Array {\n // Transpose the projection matrix to column major for GLSL.\n const matrixFP64 = new Float32Array(32);\n for (let i = 0; i < 4; ++i) {\n for (let j = 0; j < 4; ++j) {\n const index = i * 4 + j;\n fp64ify(matrix[j * 4 + i], matrixFP64, index * 2);\n }\n }\n return matrixFP64;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {NumberArray3, NumberArray4} from '@math.gl/types';\n\n/**\n * Resolves whether semantic colors should be interpreted as byte-style `0..255` values.\n * @param useByteColors - Explicit color interpretation flag.\n * @param defaultUseByteColors - Fallback value when `useByteColors` is omitted.\n * @returns `true` when semantic colors should be normalized from bytes, otherwise `false`.\n */\nexport function resolveUseByteColors(\n useByteColors?: boolean,\n defaultUseByteColors: boolean = true\n): boolean {\n return useByteColors ?? defaultUseByteColors;\n}\n\n/**\n * Normalizes an RGB semantic color to float space when byte-style colors are enabled.\n * @param color - Input RGB semantic color.\n * @param useByteColors - When `true`, divide components by `255`.\n * @returns The normalized RGB color.\n */\nexport function normalizeByteColor3(\n color: Readonly<NumberArray3> = [0, 0, 0],\n useByteColors: boolean = true\n): NumberArray3 {\n if (!useByteColors) {\n return [...color] as NumberArray3;\n }\n\n return color.map(component => component / 255) as NumberArray3;\n}\n\n/**\n * Normalizes an RGBA semantic color to float space when byte-style colors are enabled.\n * @param color - Input RGB or RGBA semantic color.\n * @param useByteColors - When `true`, divide components by `255`.\n * @returns The normalized RGBA color, adding an opaque alpha channel when needed.\n */\nexport function normalizeByteColor4(\n color: Readonly<NumberArray4> | Readonly<NumberArray3>,\n useByteColors: boolean = true\n): NumberArray4 {\n const normalizedColor = normalizeByteColor3(color.slice(0, 3) as NumberArray3, useByteColors);\n const hasAlpha = Number.isFinite(color[3]);\n const alpha = hasAlpha ? (color[3] as number) : 1;\n\n return [\n normalizedColor[0],\n normalizedColor[1],\n normalizedColor[2],\n useByteColors && hasAlpha ? alpha / 255 : alpha\n ] as NumberArray4;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\n\nconst source = /* wgsl */ `\\\nfn random(scale: vec3f, seed: f32) -> f32 {\n return fract(sin(dot(scale + vec3f(seed), vec3f(12.9898, 78.233, 151.7182))) * 43758.5453 + seed);\n}\n`;\n\nconst fs = /* glsl */ `\\\nfloat random(vec3 scale, float seed) {\n /* use the fragment position for a different seed per-pixel */\n return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);\n}\n`;\n\n/** Quick random generator for fragment shaders */\nexport const random = {\n name: 'random',\n source,\n fs\n} as const satisfies ShaderModule<{}, {}>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// import {ShaderModule} from '../../types';\n\nconst fp32shader = /* glsl */ `\\\n#ifdef LUMA_FP32_TAN_PRECISION_WORKAROUND\n\n// All these functions are for substituting tan() function from Intel GPU only\nconst float TWO_PI = 6.2831854820251465;\nconst float PI_2 = 1.5707963705062866;\nconst float PI_16 = 0.1963495463132858;\n\nconst float SIN_TABLE_0 = 0.19509032368659973;\nconst float SIN_TABLE_1 = 0.3826834261417389;\nconst float SIN_TABLE_2 = 0.5555702447891235;\nconst float SIN_TABLE_3 = 0.7071067690849304;\n\nconst float COS_TABLE_0 = 0.9807852506637573;\nconst float COS_TABLE_1 = 0.9238795042037964;\nconst float COS_TABLE_2 = 0.8314695954322815;\nconst float COS_TABLE_3 = 0.7071067690849304;\n\nconst float INVERSE_FACTORIAL_3 = 1.666666716337204e-01; // 1/3!\nconst float INVERSE_FACTORIAL_5 = 8.333333767950535e-03; // 1/5!\nconst float INVERSE_FACTORIAL_7 = 1.9841270113829523e-04; // 1/7!\nconst float INVERSE_FACTORIAL_9 = 2.75573188446287533e-06; // 1/9!\n\nfloat sin_taylor_fp32(float a) {\n float r, s, t, x;\n\n if (a == 0.0) {\n return 0.0;\n }\n\n x = -a * a;\n s = a;\n r = a;\n\n r = r * x;\n t = r * INVERSE_FACTORIAL_3;\n s = s + t;\n\n r = r * x;\n t = r * INVERSE_FACTORIAL_5;\n s = s + t;\n\n r = r * x;\n t = r * INVERSE_FACTORIAL_7;\n s = s + t;\n\n r = r * x;\n t = r * INVERSE_FACTORIAL_9;\n s = s + t;\n\n return s;\n}\n\nvoid sincos_taylor_fp32(float a, out float sin_t, out float cos_t) {\n if (a == 0.0) {\n sin_t = 0.0;\n cos_t = 1.0;\n }\n sin_t = sin_taylor_fp32(a);\n cos_t = sqrt(1.0 - sin_t * sin_t);\n}\n\nfloat tan_taylor_fp32(float a) {\n float sin_a;\n float cos_a;\n\n if (a == 0.0) {\n return 0.0;\n }\n\n // 2pi range reduction\n float z = floor(a / TWO_PI);\n float r = a - TWO_PI * z;\n\n float t;\n float q = floor(r / PI_2 + 0.5);\n int j = int(q);\n\n if (j < -2 || j > 2) {\n return 1.0 / 0.0;\n }\n\n t = r - PI_2 * q;\n\n q = floor(t / PI_16 + 0.5);\n int k = int(q);\n int abs_k = int(abs(float(k)));\n\n if (abs_k > 4) {\n return 1.0 / 0.0;\n } else {\n t = t - PI_16 * q;\n }\n\n float u = 0.0;\n float v = 0.0;\n\n float sin_t, cos_t;\n float s, c;\n sincos_taylor_fp32(t, sin_t, cos_t);\n\n if (k == 0) {\n s = sin_t;\n c = cos_t;\n } else {\n if (abs(float(abs_k) - 1.0) < 0.5) {\n u = COS_TABLE_0;\n v = SIN_TABLE_0;\n } else if (abs(float(abs_k) - 2.0) < 0.5) {\n u = COS_TABLE_1;\n v = SIN_TABLE_1;\n } else if (abs(float(abs_k) - 3.0) < 0.5) {\n u = COS_TABLE_2;\n v = SIN_TABLE_2;\n } else if (abs(float(abs_k) - 4.0) < 0.5) {\n u = COS_TABLE_3;\n v = SIN_TABLE_3;\n }\n if (k > 0) {\n s = u * sin_t + v * cos_t;\n c = u * cos_t - v * sin_t;\n } else {\n s = u * sin_t - v * cos_t;\n c = u * cos_t + v * sin_t;\n }\n }\n\n if (j == 0) {\n sin_a = s;\n cos_a = c;\n } else if (j == 1) {\n sin_a = c;\n cos_a = -s;\n } else if (j == -1) {\n sin_a = -c;\n cos_a = s;\n } else {\n sin_a = -s;\n cos_a = -c;\n }\n return sin_a / cos_a;\n}\n#endif\n\nfloat tan_fp32(float a) {\n#ifdef LUMA_FP32_TAN_PRECISION_WORKAROUND\n return tan_taylor_fp32(a);\n#else\n return tan(a);\n#endif\n}\n`;\n\n/**\n * 32 bit math library (fixups for GPUs)\n */\nexport const fp32 = {\n name: 'fp32',\n vs: fp32shader\n};\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const fp64arithmeticShader = /* glsl */ `\\\n\nlayout(std140) uniform fp64arithmeticUniforms {\n uniform float ONE;\n uniform float SPLIT;\n} fp64;\n\n/*\nAbout LUMA_FP64_CODE_ELIMINATION_WORKAROUND\n\nThe purpose of this workaround is to prevent shader compilers from\noptimizing away necessary arithmetic operations by swapping their sequences\nor transform the equation to some 'equivalent' form.\n\nThese helpers implement Dekker/Veltkamp-style error tracking. If the compiler\nfolds constants or reassociates the arithmetic, the high/low split can stop\ntracking the rounding error correctly. That failure mode tends to look fine in\nsimple coordinate setup, but then breaks down inside iterative arithmetic such\nas fp64 Mandelbrot loops.\n\nThe method is to multiply an artifical variable, ONE, which will be known to\nthe compiler to be 1 only at runtime. The whole expression is then represented\nas a polynomial with respective to ONE. In the coefficients of all terms, only one a\nand one b should appear\n\nerr = (a + b) * ONE^6 - a * ONE^5 - (a + b) * ONE^4 + a * ONE^3 - b - (a + b) * ONE^2 + a * ONE\n*/\n\nfloat prevent_fp64_optimization(float value) {\n#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)\n return value + fp64.ONE * 0.0;\n#else\n return value;\n#endif\n}\n\n// Divide float number to high and low floats to extend fraction bits\nvec2 split(float a) {\n // Keep SPLIT as a runtime uniform so the compiler cannot fold the Dekker\n // split into a constant expression and reassociate the recovery steps.\n float split = prevent_fp64_optimization(fp64.SPLIT);\n float t = prevent_fp64_optimization(a * split);\n float temp = t - a;\n float a_hi = t - temp;\n float a_lo = a - a_hi;\n return vec2(a_hi, a_lo);\n}\n\n// Divide float number again when high float uses too many fraction bits\nvec2 split2(vec2 a) {\n vec2 b = split(a.x);\n b.y += a.y;\n return b;\n}\n\n// Special sum operation when a > b\nvec2 quickTwoSum(float a, float b) {\n#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)\n float sum = (a + b) * fp64.ONE;\n float err = b - (sum - a) * fp64.ONE;\n#else\n float sum = a + b;\n float err = b - (sum - a);\n#endif\n return vec2(sum, err);\n}\n\n// General sum operation\nvec2 twoSum(float a, float b) {\n float s = (a + b);\n#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)\n float v = (s * fp64.ONE - a) * fp64.ONE;\n float err = (a - (s - v) * fp64.ONE) * fp64.ONE * fp64.ONE * fp64.ONE + (b - v);\n#else\n float v = s - a;\n float err = (a - (s - v)) + (b - v);\n#endif\n return vec2(s, err);\n}\n\nvec2 twoSub(float a, float b) {\n float s = (a - b);\n#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)\n float v = (s * fp64.ONE - a) * fp64.ONE;\n float err = (a - (s - v) * fp64.ONE) * fp64.ONE * fp64.ONE * fp64.ONE - (b + v);\n#else\n float v = s - a;\n float err = (a - (s - v)) - (b + v);\n#endif\n return vec2(s, err);\n}\n\nvec2 twoSqr(float a) {\n float prod = a * a;\n vec2 a_fp64 = split(a);\n#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)\n float err = ((a_fp64.x * a_fp64.x - prod) * fp64.ONE + 2.0 * a_fp64.x *\n a_fp64.y * fp64.ONE * fp64.ONE) + a_fp64.y * a_fp64.y * fp64.ONE * fp64.ONE * fp64.ONE;\n#else\n float err = ((a_fp64.x * a_fp64.x - prod) + 2.0 * a_fp64.x * a_fp64.y) + a_fp64.y * a_fp64.y;\n#endif\n return vec2(prod, err);\n}\n\nvec2 twoProd(float a, float b) {\n float prod = a * b;\n vec2 a_fp64 = split(a);\n vec2 b_fp64 = split(b);\n // twoProd is especially sensitive because mul_fp64 and div_fp64 both depend\n // on the split terms and cross terms staying in the original evaluation\n // order. If the compiler folds or reassociates them, the low part tends to\n // collapse to zero or NaN on some drivers.\n float highProduct = prevent_fp64_optimization(a_fp64.x * b_fp64.x);\n float crossProduct1 = prevent_fp64_optimization(a_fp64.x * b_fp64.y);\n float crossProduct2 = prevent_fp64_optimization(a_fp64.y * b_fp64.x);\n float lowProduct = prevent_fp64_optimization(a_fp64.y * b_fp64.y);\n#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)\n float err1 = (highProduct - prod) * fp64.ONE;\n float err2 = crossProduct1 * fp64.ONE * fp64.ONE;\n float err3 = crossProduct2 * fp64.ONE * fp64.ONE * fp64.ONE;\n float err4 = lowProduct * fp64.ONE * fp64.ONE * fp64.ONE * fp64.ONE;\n#else\n float err1 = highProduct - prod;\n float err2 = crossProduct1;\n float err3 = crossProduct2;\n float err4 = lowProduct;\n#endif\n float err = ((err1 + err2) + err3) + err4;\n return vec2(prod, err);\n}\n\nvec2 sum_fp64(vec2 a, vec2 b) {\n vec2 s, t;\n s = twoSum(a.x, b.x);\n t = twoSum(a.y, b.y);\n s.y += t.x;\n s = quickTwoSum(s.x, s.y);\n s.y += t.y;\n s = quickTwoSum(s.x, s.y);\n return s;\n}\n\nvec2 sub_fp64(vec2 a, vec2 b) {\n vec2 s, t;\n s = twoSub(a.x, b.x);\n t = twoSub(a.y, b.y);\n s.y += t.x;\n s = quickTwoSum(s.x, s.y);\n s.y += t.y;\n s = quickTwoSum(s.x, s.y);\n return s;\n}\n\nvec2 mul_fp64(vec2 a, vec2 b) {\n vec2 prod = twoProd(a.x, b.x);\n // y component is for the error\n prod.y += a.x * b.y;\n#if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND)\n prod = split2(prod);\n#endif\n prod = quickTwoSum(prod.x, prod.y);\n prod.y += a.y * b.x;\n#if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND)\n prod = split2(prod);\n#endif\n prod = quickTwoSum(prod.x, prod.y);\n return prod;\n}\n\nvec2 div_fp64(vec2 a, vec2 b) {\n float xn = 1.0 / b.x;\n#if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND)\n vec2 yn = mul_fp64(a, vec2(xn, 0));\n#else\n vec2 yn = a * xn;\n#endif\n float diff = (sub_fp64(a, mul_fp64(b, yn))).x;\n vec2 prod = twoProd(xn, diff);\n return sum_fp64(yn, prod);\n}\n\nvec2 sqrt_fp64(vec2 a) {\n if (a.x == 0.0 && a.y == 0.0) return vec2(0.0, 0.0);\n if (a.x < 0.0) return vec2(0.0 / 0.0, 0.0 / 0.0);\n\n float x = 1.0 / sqrt(a.x);\n float yn = a.x * x;\n#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)\n vec2 yn_sqr = twoSqr(yn) * fp64.ONE;\n#else\n vec2 yn_sqr = twoSqr(yn);\n#endif\n float diff = sub_fp64(a, yn_sqr).x;\n vec2 prod = twoProd(x * 0.5, diff);\n#if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND)\n return sum_fp64(split(yn), prod);\n#else\n return sum_fp64(vec2(yn, 0.0), prod);\n#endif\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const fp64arithmeticWGSL = /* wgsl */ `\\\nstruct Fp64ArithmeticUniforms {\n ONE: f32,\n SPLIT: f32,\n};\n\n@group(0) @binding(auto) var<uniform> fp64arithmetic : Fp64ArithmeticUniforms;\n\nfn fp64_nan(seed: f32) -> f32 {\n let nanBits = 0x7fc00000u | select(0u, 1u, seed < 0.0);\n return bitcast<f32>(nanBits);\n}\n\nfn fp64_runtime_zero() -> f32 {\n return fp64arithmetic.ONE * 0.0;\n}\n\nfn prevent_fp64_optimization(value: f32) -> f32 {\n#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND\n return value + fp64_runtime_zero();\n#else\n return value;\n#endif\n}\n\nfn split(a: f32) -> vec2f {\n let splitValue = prevent_fp64_optimization(fp64arithmetic.SPLIT + fp64_runtime_zero());\n let t = prevent_fp64_optimization(a * splitValue);\n let temp = prevent_fp64_optimization(t - a);\n let aHi = prevent_fp64_optimization(t - temp);\n let aLo = prevent_fp64_optimization(a - aHi);\n return vec2f(aHi, aLo);\n}\n\nfn split2(a: vec2f) -> vec2f {\n var b = split(a.x);\n b.y = b.y + a.y;\n return b;\n}\n\nfn quickTwoSum(a: f32, b: f32) -> vec2f {\n#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND\n let sum = prevent_fp64_optimization((a + b) * fp64arithmetic.ONE);\n let err = prevent_fp64_optimization(b - (sum - a) * fp64arithmetic.ONE);\n#else\n let sum = prevent_fp64_optimization(a + b);\n let err = prevent_fp64_optimization(b - (sum - a));\n#endif\n return vec2f(sum, err);\n}\n\nfn twoSum(a: f32, b: f32) -> vec2f {\n let s = prevent_fp64_optimization(a + b);\n#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND\n let v = prevent_fp64_optimization((s * fp64arithmetic.ONE - a) * fp64arithmetic.ONE);\n let err =\n prevent_fp64_optimization((a - (s - v) * fp64arithmetic.ONE) *\n fp64arithmetic.ONE *\n fp64arithmetic.ONE *\n fp64arithmetic.ONE) +\n prevent_fp64_optimization(b - v);\n#else\n let v = prevent_fp64_optimization(s - a);\n let err = prevent_fp64_optimization(a - (s - v)) + prevent_fp64_optimization(b - v);\n#endif\n return vec2f(s, err);\n}\n\nfn twoSub(a: f32, b: f32) -> vec2f {\n let s = prevent_fp64_optimization(a - b);\n#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND\n let v = prevent_fp64_optimization((s * fp64arithmetic.ONE - a) * fp64arithmetic.ONE);\n let err =\n prevent_fp64_optimization((a - (s - v) * fp64arithmetic.ONE) *\n fp64arithmetic.ONE *\n fp64arithmetic.ONE *\n fp64arithmetic.ONE) -\n prevent_fp64_optimization(b + v);\n#else\n let v = prevent_fp64_optimization(s - a);\n let err = prevent_fp64_optimization(a - (s - v)) - prevent_fp64_optimization(b + v);\n#endif\n return vec2f(s, err);\n}\n\nfn twoSqr(a: f32) -> vec2f {\n let prod = prevent_fp64_optimization(a * a);\n let aFp64 = split(a);\n let highProduct = prevent_fp64_optimization(aFp64.x * aFp64.x);\n let crossProduct = prevent_fp64_optimization(2.0 * aFp64.x * aFp64.y);\n let lowProduct = prevent_fp64_optimization(aFp64.y * aFp64.y);\n#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND\n let err =\n (prevent_fp64_optimization(highProduct - prod) * fp64arithmetic.ONE +\n crossProduct * fp64arithmetic.ONE * fp64arithmetic.ONE) +\n lowProduct * fp64arithmetic.ONE * fp64arithmetic.ONE * fp64arithmetic.ONE;\n#else\n let err = ((prevent_fp64_optimization(highProduct - prod) + crossProduct) + lowProduct);\n#endif\n return vec2f(prod, err);\n}\n\nfn twoProd(a: f32, b: f32) -> vec2f {\n let prod = prevent_fp64_optimization(a * b);\n let aFp64 = split(a);\n let bFp64 = split(b);\n let highProduct = prevent_fp64_optimization(aFp64.x * bFp64.x);\n let crossProduct1 = prevent_fp64_optimization(aFp64.x * bFp64.y);\n let crossProduct2 = prevent_fp64_optimization(aFp64.y * bFp64.x);\n let lowProduct = prevent_fp64_optimization(aFp64.y * bFp64.y);\n#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND\n let err1 = (highProduct - prod) * fp64arithmetic.ONE;\n let err2 = crossProduct1 * fp64arithmetic.ONE * fp64arithmetic.ONE;\n let err3 = crossProduct2 * fp64arithmetic.ONE * fp64arithmetic.ONE * fp64arithmetic.ONE;\n let err4 =\n lowProduct *\n fp64arithmetic.ONE *\n fp64arithmetic.ONE *\n fp64arithmetic.ONE *\n fp64arithmetic.ONE;\n#else\n let err1 = highProduct - prod;\n let err2 = crossProduct1;\n let err3 = crossProduct2;\n let err4 = lowProduct;\n#endif\n let err12InputA = prevent_fp64_optimization(err1);\n let err12InputB = prevent_fp64_optimization(err2);\n let err12 = prevent_fp64_optimization(err12InputA + err12InputB);\n let err123InputA = prevent_fp64_optimization(err12);\n let err123InputB = prevent_fp64_optimization(err3);\n let err123 = prevent_fp64_optimization(err123InputA + err123InputB);\n let err1234InputA = prevent_fp64_optimization(err123);\n let err1234InputB = prevent_fp64_optimization(err4);\n let err = prevent_fp64_optimization(err1234InputA + err1234InputB);\n return vec2f(prod, err);\n}\n\nfn sum_fp64(a: vec2f, b: vec2f) -> vec2f {\n var s = twoSum(a.x, b.x);\n let t = twoSum(a.y, b.y);\n s.y = prevent_fp64_optimization(s.y + t.x);\n s = quickTwoSum(s.x, s.y);\n s.y = prevent_fp64_optimization(s.y + t.y);\n s = quickTwoSum(s.x, s.y);\n return s;\n}\n\nfn sub_fp64(a: vec2f, b: vec2f) -> vec2f {\n var s = twoSub(a.x, b.x);\n let t = twoSub(a.y, b.y);\n s.y = prevent_fp64_optimization(s.y + t.x);\n s = quickTwoSum(s.x, s.y);\n s.y = prevent_fp64_optimization(s.y + t.y);\n s = quickTwoSum(s.x, s.y);\n return s;\n}\n\nfn mul_fp64(a: vec2f, b: vec2f) -> vec2f {\n var prod = twoProd(a.x, b.x);\n let crossProduct1 = prevent_fp64_optimization(a.x * b.y);\n prod.y = prevent_fp64_optimization(prod.y + crossProduct1);\n#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND\n prod = split2(prod);\n#endif\n prod = quickTwoSum(prod.x, prod.y);\n let crossProduct2 = prevent_fp64_optimization(a.y * b.x);\n prod.y = prevent_fp64_optimization(prod.y + crossProduct2);\n#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND\n prod = split2(prod);\n#endif\n prod = quickTwoSum(prod.x, prod.y);\n return prod;\n}\n\nfn div_fp64(a: vec2f, b: vec2f) -> vec2f {\n let xn = prevent_fp64_optimization(1.0 / b.x);\n let yn = mul_fp64(a, vec2f(xn, fp64_runtime_zero()));\n let diff = prevent_fp64_optimization(sub_fp64(a, mul_fp64(b, yn)).x);\n let prod = twoProd(xn, diff);\n return sum_fp64(yn, prod);\n}\n\nfn sqrt_fp64(a: vec2f) -> vec2f {\n if (a.x == 0.0 && a.y == 0.0) {\n return vec2f(0.0, 0.0);\n }\n if (a.x < 0.0) {\n let nanValue = fp64_nan(a.x);\n return vec2f(nanValue, nanValue);\n }\n\n let x = prevent_fp64_optimization(1.0 / sqrt(a.x));\n let yn = prevent_fp64_optimization(a.x * x);\n#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND\n let ynSqr = twoSqr(yn) * fp64arithmetic.ONE;\n#else\n let ynSqr = twoSqr(yn);\n#endif\n let diff = prevent_fp64_optimization(sub_fp64(a, ynSqr).x);\n let prod = twoProd(prevent_fp64_optimization(x * 0.5), diff);\n#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND\n return sum_fp64(split(yn), prod);\n#else\n return sum_fp64(vec2f(yn, 0.0), prod);\n#endif\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const fp64functionShader = /* glsl */ `\\\nconst vec2 E_FP64 = vec2(2.7182817459106445e+00, 8.254840366817007e-08);\nconst vec2 LOG2_FP64 = vec2(0.6931471824645996e+00, -1.9046542121259336e-09);\nconst vec2 PI_FP64 = vec2(3.1415927410125732, -8.742278012618954e-8);\nconst vec2 TWO_PI_FP64 = vec2(6.2831854820251465, -1.7484556025237907e-7);\nconst vec2 PI_2_FP64 = vec2(1.5707963705062866, -4.371139006309477e-8);\nconst vec2 PI_4_FP64 = vec2(0.7853981852531433, -2.1855695031547384e-8);\nconst vec2 PI_16_FP64 = vec2(0.19634954631328583, -5.463923757886846e-9);\nconst vec2 PI_16_2_FP64 = vec2(0.39269909262657166, -1.0927847515773692e-8);\nconst vec2 PI_16_3_FP64 = vec2(0.5890486240386963, -1.4906100798128818e-9);\nconst vec2 PI_180_FP64 = vec2(0.01745329238474369, 1.3519960498364902e-10);\n\nconst vec2 SIN_TABLE_0_FP64 = vec2(0.19509032368659973, -1.6704714833615242e-9);\nconst vec2 SIN_TABLE_1_FP64 = vec2(0.3826834261417389, 6.22335089017767e-9);\nconst vec2 SIN_TABLE_2_FP64 = vec2(0.5555702447891235, -1.1769521357507529e-8);\nconst vec2 SIN_TABLE_3_FP64 = vec2(0.7071067690849304, 1.2101617041793133e-8);\n\nconst vec2 COS_TABLE_0_FP64 = vec2(0.9807852506637573, 2.9739473106360492e-8);\nconst vec2 COS_TABLE_1_FP64 = vec2(0.9238795042037964, 2.8307490351764386e-8);\nconst vec2 COS_TABLE_2_FP64 = vec2(0.8314695954322815, 1.6870263741530778e-8);\nconst vec2 COS_TABLE_3_FP64 = vec2(0.7071067690849304, 1.2101617152815436e-8);\n\nconst vec2 INVERSE_FACTORIAL_3_FP64 = vec2(1.666666716337204e-01, -4.967053879312289e-09); // 1/3!\nconst vec2 INVERSE_FACTORIAL_4_FP64 = vec2(4.16666679084301e-02, -1.2417634698280722e-09); // 1/4!\nconst vec2 INVERSE_FACTORIAL_5_FP64 = vec2(8.333333767950535e-03, -4.34617203337595e-10); // 1/5!\nconst vec2 INVERSE_FACTORIAL_6_FP64 = vec2(1.3888889225199819e-03, -3.3631094437103215e-11); // 1/6!\nconst vec2 INVERSE_FACTORIAL_7_FP64 = vec2(1.9841270113829523e-04, -2.725596874933456e-12); // 1/7!\nconst vec2 INVERSE_FACTORIAL_8_FP64 = vec2(2.4801587642286904e-05, -3.406996025904184e-13); // 1/8!\nconst vec2 INVERSE_FACTORIAL_9_FP64 = vec2(2.75573188446287533e-06, 3.7935713937038186e-14); // 1/9!\nconst vec2 INVERSE_FACTORIAL_10_FP64 = vec2(2.755731998149713e-07, -7.575112367869873e-15); // 1/10!\n\nfloat nint(float d) {\n if (d == floor(d)) return d;\n return floor(d + 0.5);\n}\n\nvec2 nint_fp64(vec2 a) {\n float hi = nint(a.x);\n float lo;\n vec2 tmp;\n if (hi == a.x) {\n lo = nint(a.y);\n tmp = quickTwoSum(hi, lo);\n } else {\n lo = 0.0;\n if (abs(hi - a.x) == 0.5 && a.y < 0.0) {\n hi -= 1.0;\n }\n tmp = vec2(hi, lo);\n }\n return tmp;\n}\n\n/* k_power controls how much range reduction we would like to have\nRange reduction uses the following method:\nassume a = k_power * r + m * log(2), k and m being integers.\nSet k_power = 4 (we can choose other k to trade accuracy with performance.\nwe only need to calculate exp(r) and using exp(a) = 2^m * exp(r)^k_power;\n*/\n\nvec2 exp_fp64(vec2 a) {\n // We need to make sure these two numbers match\n // as bit-wise shift is not available in GLSL 1.0\n const int k_power = 4;\n const float k = 16.0;\n\n const float inv_k = 1.0 / k;\n\n if (a.x <= -88.0) return vec2(0.0, 0.0);\n if (a.x >= 88.0) return vec2(1.0 / 0.0, 1.0 / 0.0);\n if (a.x == 0.0 && a.y == 0.0) return vec2(1.0, 0.0);\n if (a.x == 1.0 && a.y == 0.0) return E_FP64;\n\n float m = floor(a.x / LOG2_FP64.x + 0.5);\n vec2 r = sub_fp64(a, mul_fp64(LOG2_FP64, vec2(m, 0.0))) * inv_k;\n vec2 s, t, p;\n\n p = mul_fp64(r, r);\n s = sum_fp64(r, p * 0.5);\n p = mul_fp64(p, r);\n t = mul_fp64(p, INVERSE_FACTORIAL_3_FP64);\n\n s = sum_fp64(s, t);\n p = mul_fp64(p, r);\n t = mul_fp64(p, INVERSE_FACTORIAL_4_FP64);\n\n s = sum_fp64(s, t);\n p = mul_fp64(p, r);\n t = mul_fp64(p, INVERSE_FACTORIAL_5_FP64);\n\n // s = sum_fp64(s, t);\n // p = mul_fp64(p, r);\n // t = mul_fp64(p, INVERSE_FACTORIAL_6_FP64);\n\n // s = sum_fp64(s, t);\n // p = mul_fp64(p, r);\n // t = mul_fp64(p, INVERSE_FACTORIAL_7_FP64);\n\n s = sum_fp64(s, t);\n\n\n // At this point, s = exp(r) - 1; but after following 4 recursions, we will get exp(r) ^ 512 - 1.\n for (int i = 0; i < k_power; i++) {\n s = sum_fp64(s * 2.0, mul_fp64(s, s));\n }\n\n#if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND)\n s = sum_fp64(s, vec2(fp64.ONE, 0.0));\n#else\n s = sum_fp64(s, vec2(1.0, 0.0));\n#endif\n\n return s * pow(2.0, m);\n// return r;\n}\n\nvec2 log_fp64(vec2 a)\n{\n if (a.x == 1.0 && a.y == 0.0) return vec2(0.0, 0.0);\n if (a.x <= 0.0) return vec2(0.0 / 0.0, 0.0 / 0.0);\n vec2 x = vec2(log(a.x), 0.0);\n vec2 s;\n#if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND)\n s = vec2(fp64.ONE, 0.0);\n#else\n s = vec2(1.0, 0.0);\n#endif\n\n x = sub_fp64(sum_fp64(x, mul_fp64(a, exp_fp64(-x))), s);\n return x;\n}\n\nvec2 sin_taylor_fp64(vec2 a) {\n vec2 r, s, t, x;\n\n if (a.x == 0.0 && a.y == 0.0) {\n return vec2(0.0, 0.0);\n }\n\n x = -mul_fp64(a, a);\n s = a;\n r = a;\n\n r = mul_fp64(r, x);\n t = mul_fp64(r, INVERSE_FACTORIAL_3_FP64);\n s = sum_fp64(s, t);\n\n r = mul_fp64(r, x);\n t = mul_fp64(r, INVERSE_FACTORIAL_5_FP64);\n s = sum_fp64(s, t);\n\n /* keep the following commented code in case we need them\n for extra accuracy from the Taylor expansion*/\n\n // r = mul_fp64(r, x);\n // t = mul_fp64(r, INVERSE_FACTORIAL_7_FP64);\n // s = sum_fp64(s, t);\n\n // r = mul_fp64(r, x);\n // t = mul_fp64(r, INVERSE_FACTORIAL_9_FP64);\n // s = sum_fp64(s, t);\n\n return s;\n}\n\nvec2 cos_taylor_fp64(vec2 a) {\n vec2 r, s, t, x;\n\n if (a.x == 0.0 && a.y == 0.0) {\n return vec2(1.0, 0.0);\n }\n\n x = -mul_fp64(a, a);\n r = x;\n s = sum_fp64(vec2(1.0, 0.0), r * 0.5);\n\n r = mul_fp64(r, x);\n t = mul_fp64(r, INVERSE_FACTORIAL_4_FP64);\n s = sum_fp64(s, t);\n\n r = mul_fp64(r, x);\n t = mul_fp64(r, INVERSE_FACTORIAL_6_FP64);\n s = sum_fp64(s, t);\n\n /* keep the following commented code in case we need them\n for extra accuracy from the Taylor expansion*/\n\n // r = mul_fp64(r, x);\n // t = mul_fp64(r, INVERSE_FACTORIAL_8_FP64);\n // s = sum_fp64(s, t);\n\n // r = mul_fp64(r, x);\n // t = mul_fp64(r, INVERSE_FACTORIAL_10_FP64);\n // s = sum_fp64(s, t);\n\n return s;\n}\n\nvoid sincos_taylor_fp64(vec2 a, out vec2 sin_t, out vec2 cos_t) {\n if (a.x == 0.0 && a.y == 0.0) {\n sin_t = vec2(0.0, 0.0);\n cos_t = vec2(1.0, 0.0);\n }\n\n sin_t = sin_taylor_fp64(a);\n cos_t = sqrt_fp64(sub_fp64(vec2(1.0, 0.0), mul_fp64(sin_t, sin_t)));\n}\n\nvec2 sin_fp64(vec2 a) {\n if (a.x == 0.0 && a.y == 0.0) {\n return vec2(0.0, 0.0);\n }\n\n // 2pi range reduction\n vec2 z = nint_fp64(div_fp64(a, TWO_PI_FP64));\n vec2 r = sub_fp64(a, mul_fp64(TWO_PI_FP64, z));\n\n vec2 t;\n float q = floor(r.x / PI_2_FP64.x + 0.5);\n int j = int(q);\n\n if (j < -2 || j > 2) {\n return vec2(0.0 / 0.0, 0.0 / 0.0);\n }\n\n t = sub_fp64(r, mul_fp64(PI_2_FP64, vec2(q, 0.0)));\n\n q = floor(t.x / PI_16_FP64.x + 0.5);\n int k = int(q);\n\n if (k == 0) {\n if (j == 0) {\n return sin_taylor_fp64(t);\n } else if (j == 1) {\n return cos_taylor_fp64(t);\n } else if (j == -1) {\n return -cos_taylor_fp64(t);\n } else {\n return -sin_taylor_fp64(t);\n }\n }\n\n int abs_k = int(abs(float(k)));\n\n if (abs_k > 4) {\n return vec2(0.0 / 0.0, 0.0 / 0.0);\n } else {\n t = sub_fp64(t, mul_fp64(PI_16_FP64, vec2(q, 0.0)));\n }\n\n vec2 u = vec2(0.0, 0.0);\n vec2 v = vec2(0.0, 0.0);\n\n#if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND)\n if (abs(float(abs_k) - 1.0) < 0.5) {\n u = COS_TABLE_0_FP64;\n v = SIN_TABLE_0_FP64;\n } else if (abs(float(abs_k) - 2.0) < 0.5) {\n u = COS_TABLE_1_FP64;\n v = SIN_TABLE_1_FP64;\n } else if (abs(float(abs_k) - 3.0) < 0.5) {\n u = COS_TABLE_2_FP64;\n v = SIN_TABLE_2_FP64;\n } else if (abs(float(abs_k) - 4.0) < 0.5) {\n u = COS_TABLE_3_FP64;\n v = SIN_TABLE_3_FP64;\n }\n#else\n if (abs_k == 1) {\n u = COS_TABLE_0_FP64;\n v = SIN_TABLE_0_FP64;\n } else if (abs_k == 2) {\n u = COS_TABLE_1_FP64;\n v = SIN_TABLE_1_FP64;\n } else if (abs_k == 3) {\n u = COS_TABLE_2_FP64;\n v = SIN_TABLE_2_FP64;\n } else if (abs_k == 4) {\n u = COS_TABLE_3_FP64;\n v = SIN_TABLE_3_FP64;\n }\n#endif\n\n vec2 sin_t, cos_t;\n sincos_taylor_fp64(t, sin_t, cos_t);\n\n\n\n vec2 result = vec2(0.0, 0.0);\n if (j == 0) {\n if (k > 0) {\n result = sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t));\n } else {\n result = sub_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t));\n }\n } else if (j == 1) {\n if (k > 0) {\n result = sub_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t));\n } else {\n result = sum_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t));\n }\n } else if (j == -1) {\n if (k > 0) {\n result = sub_fp64(mul_fp64(v, sin_t), mul_fp64(u, cos_t));\n } else {\n result = -sum_fp64(mul_fp64(v, sin_t), mul_fp64(u, cos_t));\n }\n } else {\n if (k > 0) {\n result = -sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t));\n } else {\n result = sub_fp64(mul_fp64(v, cos_t), mul_fp64(u, sin_t));\n }\n }\n\n return result;\n}\n\nvec2 cos_fp64(vec2 a) {\n if (a.x == 0.0 && a.y == 0.0) {\n return vec2(1.0, 0.0);\n }\n\n // 2pi range reduction\n vec2 z = nint_fp64(div_fp64(a, TWO_PI_FP64));\n vec2 r = sub_fp64(a, mul_fp64(TWO_PI_FP64, z));\n\n vec2 t;\n float q = floor(r.x / PI_2_FP64.x + 0.5);\n int j = int(q);\n\n if (j < -2 || j > 2) {\n return vec2(0.0 / 0.0, 0.0 / 0.0);\n }\n\n t = sub_fp64(r, mul_fp64(PI_2_FP64, vec2(q, 0.0)));\n\n q = floor(t.x / PI_16_FP64.x + 0.5);\n int k = int(q);\n\n if (k == 0) {\n if (j == 0) {\n return cos_taylor_fp64(t);\n } else if (j == 1) {\n return -sin_taylor_fp64(t);\n } else if (j == -1) {\n return sin_taylor_fp64(t);\n } else {\n return -cos_taylor_fp64(t);\n }\n }\n\n int abs_k = int(abs(float(k)));\n\n if (abs_k > 4) {\n return vec2(0.0 / 0.0, 0.0 / 0.0);\n } else {\n t = sub_fp64(t, mul_fp64(PI_16_FP64, vec2(q, 0.0)));\n }\n\n vec2 u = vec2(0.0, 0.0);\n vec2 v = vec2(0.0, 0.0);\n\n#if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND)\n if (abs(float(abs_k) - 1.0) < 0.5) {\n u = COS_TABLE_0_FP64;\n v = SIN_TABLE_0_FP64;\n } else if (abs(float(abs_k) - 2.0) < 0.5) {\n u = COS_TABLE_1_FP64;\n v = SIN_TABLE_1_FP64;\n } else if (abs(float(abs_k) - 3.0) < 0.5) {\n u = COS_TABLE_2_FP64;\n v = SIN_TABLE_2_FP64;\n } else if (abs(float(abs_k) - 4.0) < 0.5) {\n u = COS_TABLE_3_FP64;\n v = SIN_TABLE_3_FP64;\n }\n#else\n if (abs_k == 1) {\n u = COS_TABLE_0_FP64;\n v = SIN_TABLE_0_FP64;\n } else if (abs_k == 2) {\n u = COS_TABLE_1_FP64;\n v = SIN_TABLE_1_FP64;\n } else if (abs_k == 3) {\n u = COS_TABLE_2_FP64;\n v = SIN_TABLE_2_FP64;\n } else if (abs_k == 4) {\n u = COS_TABLE_3_FP64;\n v = SIN_TABLE_3_FP64;\n }\n#endif\n\n vec2 sin_t, cos_t;\n sincos_taylor_fp64(t, sin_t, cos_t);\n\n vec2 result = vec2(0.0, 0.0);\n if (j == 0) {\n if (k > 0) {\n result = sub_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t));\n } else {\n result = sum_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t));\n }\n } else if (j == 1) {\n if (k > 0) {\n result = -sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t));\n } else {\n result = sub_fp64(mul_fp64(v, cos_t), mul_fp64(u, sin_t));\n }\n } else if (j == -1) {\n if (k > 0) {\n result = sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t));\n } else {\n result = sub_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t));\n }\n } else {\n if (k > 0) {\n result = sub_fp64(mul_fp64(v, sin_t), mul_fp64(u, cos_t));\n } else {\n result = -sum_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t));\n }\n }\n\n return result;\n}\n\nvec2 tan_fp64(vec2 a) {\n vec2 sin_a;\n vec2 cos_a;\n\n if (a.x == 0.0 && a.y == 0.0) {\n return vec2(0.0, 0.0);\n }\n\n // 2pi range reduction\n vec2 z = nint_fp64(div_fp64(a, TWO_PI_FP64));\n vec2 r = sub_fp64(a, mul_fp64(TWO_PI_FP64, z));\n\n vec2 t;\n float q = floor(r.x / PI_2_FP64.x + 0.5);\n int j = int(q);\n\n\n if (j < -2 || j > 2) {\n return vec2(0.0 / 0.0, 0.0 / 0.0);\n }\n\n t = sub_fp64(r, mul_fp64(PI_2_FP64, vec2(q, 0.0)));\n\n q = floor(t.x / PI_16_FP64.x + 0.5);\n int k = int(q);\n int abs_k = int(abs(float(k)));\n\n // We just can't get PI/16 * 3.0 very accurately.\n // so let's just store it\n if (abs_k > 4) {\n return vec2(0.0 / 0.0, 0.0 / 0.0);\n } else {\n t = sub_fp64(t, mul_fp64(PI_16_FP64, vec2(q, 0.0)));\n }\n\n\n vec2 u = vec2(0.0, 0.0);\n vec2 v = vec2(0.0, 0.0);\n\n vec2 sin_t, cos_t;\n vec2 s, c;\n sincos_taylor_fp64(t, sin_t, cos_t);\n\n if (k == 0) {\n s = sin_t;\n c = cos_t;\n } else {\n#if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND)\n if (abs(float(abs_k) - 1.0) < 0.5) {\n u = COS_TABLE_0_FP64;\n v = SIN_TABLE_0_FP64;\n } else if (abs(float(abs_k) - 2.0) < 0.5) {\n u = COS_TABLE_1_FP64;\n v = SIN_TABLE_1_FP64;\n } else if (abs(float(abs_k) - 3.0) < 0.5) {\n u = COS_TABLE_2_FP64;\n v = SIN_TABLE_2_FP64;\n } else if (abs(float(abs_k) - 4.0) < 0.5) {\n u = COS_TABLE_3_FP64;\n v = SIN_TABLE_3_FP64;\n }\n#else\n if (abs_k == 1) {\n u = COS_TABLE_0_FP64;\n v = SIN_TABLE_0_FP64;\n } else if (abs_k == 2) {\n u = COS_TABLE_1_FP64;\n v = SIN_TABLE_1_FP64;\n } else if (abs_k == 3) {\n u = COS_TABLE_2_FP64;\n v = SIN_TABLE_2_FP64;\n } else if (abs_k == 4) {\n u = COS_TABLE_3_FP64;\n v = SIN_TABLE_3_FP64;\n }\n#endif\n if (k > 0) {\n s = sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t));\n c = sub_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t));\n } else {\n s = sub_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t));\n c = sum_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t));\n }\n }\n\n if (j == 0) {\n sin_a = s;\n cos_a = c;\n } else if (j == 1) {\n sin_a = c;\n cos_a = -s;\n } else if (j == -1) {\n sin_a = -c;\n cos_a = s;\n } else {\n sin_a = -s;\n cos_a = -c;\n }\n return div_fp64(sin_a, cos_a);\n}\n\nvec2 radians_fp64(vec2 degree) {\n return mul_fp64(degree, PI_180_FP64);\n}\n\nvec2 mix_fp64(vec2 a, vec2 b, float x) {\n vec2 range = sub_fp64(b, a);\n return sum_fp64(a, mul_fp64(range, vec2(x, 0.0)));\n}\n\n// Vector functions\n// vec2 functions\nvoid vec2_sum_fp64(vec2 a[2], vec2 b[2], out vec2 out_val[2]) {\n out_val[0] = sum_fp64(a[0], b[0]);\n out_val[1] = sum_fp64(a[1], b[1]);\n}\n\nvoid vec2_sub_fp64(vec2 a[2], vec2 b[2], out vec2 out_val[2]) {\n out_val[0] = sub_fp64(a[0], b[0]);\n out_val[1] = sub_fp64(a[1], b[1]);\n}\n\nvoid vec2_mul_fp64(vec2 a[2], vec2 b[2], out vec2 out_val[2]) {\n out_val[0] = mul_fp64(a[0], b[0]);\n out_val[1] = mul_fp64(a[1], b[1]);\n}\n\nvoid vec2_div_fp64(vec2 a[2], vec2 b[2], out vec2 out_val[2]) {\n out_val[0] = div_fp64(a[0], b[0]);\n out_val[1] = div_fp64(a[1], b[1]);\n}\n\nvoid vec2_mix_fp64(vec2 x[2], vec2 y[2], float a, out vec2 out_val[2]) {\n vec2 range[2];\n vec2_sub_fp64(y, x, range);\n vec2 portion[2];\n portion[0] = range[0] * a;\n portion[1] = range[1] * a;\n vec2_sum_fp64(x, portion, out_val);\n}\n\nvec2 vec2_length_fp64(vec2 x[2]) {\n return sqrt_fp64(sum_fp64(mul_fp64(x[0], x[0]), mul_fp64(x[1], x[1])));\n}\n\nvoid vec2_normalize_fp64(vec2 x[2], out vec2 out_val[2]) {\n vec2 length = vec2_length_fp64(x);\n vec2 length_vec2[2];\n length_vec2[0] = length;\n length_vec2[1] = length;\n\n vec2_div_fp64(x, length_vec2, out_val);\n}\n\nvec2 vec2_distance_fp64(vec2 x[2], vec2 y[2]) {\n vec2 diff[2];\n vec2_sub_fp64(x, y, diff);\n return vec2_length_fp64(diff);\n}\n\nvec2 vec2_dot_fp64(vec2 a[2], vec2 b[2]) {\n vec2 v[2];\n\n v[0] = mul_fp64(a[0], b[0]);\n v[1] = mul_fp64(a[1], b[1]);\n\n return sum_fp64(v[0], v[1]);\n}\n\n// vec3 functions\nvoid vec3_sub_fp64(vec2 a[3], vec2 b[3], out vec2 out_val[3]) {\n for (int i = 0; i < 3; i++) {\n out_val[i] = sum_fp64(a[i], b[i]);\n }\n}\n\nvoid vec3_sum_fp64(vec2 a[3], vec2 b[3], out vec2 out_val[3]) {\n for (int i = 0; i < 3; i++) {\n out_val[i] = sum_fp64(a[i], b[i]);\n }\n}\n\nvec2 vec3_length_fp64(vec2 x[3]) {\n return sqrt_fp64(sum_fp64(sum_fp64(mul_fp64(x[0], x[0]), mul_fp64(x[1], x[1])),\n mul_fp64(x[2], x[2])));\n}\n\nvec2 vec3_distance_fp64(vec2 x[3], vec2 y[3]) {\n vec2 diff[3];\n vec3_sub_fp64(x, y, diff);\n return vec3_length_fp64(diff);\n}\n\n// vec4 functions\nvoid vec4_fp64(vec4 a, out vec2 out_val[4]) {\n out_val[0].x = a[0];\n out_val[0].y = 0.0;\n\n out_val[1].x = a[1];\n out_val[1].y = 0.0;\n\n out_val[2].x = a[2];\n out_val[2].y = 0.0;\n\n out_val[3].x = a[3];\n out_val[3].y = 0.0;\n}\n\nvoid vec4_scalar_mul_fp64(vec2 a[4], vec2 b, out vec2 out_val[4]) {\n out_val[0] = mul_fp64(a[0], b);\n out_val[1] = mul_fp64(a[1], b);\n out_val[2] = mul_fp64(a[2], b);\n out_val[3] = mul_fp64(a[3], b);\n}\n\nvoid vec4_sum_fp64(vec2 a[4], vec2 b[4], out vec2 out_val[4]) {\n for (int i = 0; i < 4; i++) {\n out_val[i] = sum_fp64(a[i], b[i]);\n }\n}\n\nvoid vec4_dot_fp64(vec2 a[4], vec2 b[4], out vec2 out_val) {\n vec2 v[4];\n\n v[0] = mul_fp64(a[0], b[0]);\n v[1] = mul_fp64(a[1], b[1]);\n v[2] = mul_fp64(a[2], b[2]);\n v[3] = mul_fp64(a[3], b[3]);\n\n out_val = sum_fp64(sum_fp64(v[0], v[1]), sum_fp64(v[2], v[3]));\n}\n\nvoid mat4_vec4_mul_fp64(vec2 b[16], vec2 a[4], out vec2 out_val[4]) {\n vec2 tmp[4];\n\n for (int i = 0; i < 4; i++)\n {\n for (int j = 0; j < 4; j++)\n {\n tmp[j] = b[j + i * 4];\n }\n vec4_dot_fp64(a, tmp, out_val[i]);\n }\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\n\nimport {fp64ify, fp64LowPart, fp64ifyMatrix4} from '../../../modules/math/fp64/fp64-utils';\nimport {fp64arithmeticShader} from './fp64-arithmetic-glsl';\nimport {fp64arithmeticWGSL} from './fp64-arithmetic-wgsl';\nimport {fp64functionShader} from './fp64-functions-glsl';\n\ntype FP64Props = {};\ntype FP64Uniforms = {ONE: number; SPLIT: number};\ntype FP64Bindings = {};\n\ntype FP64Utilities = {\n fp64ify: typeof fp64ify;\n fp64LowPart: typeof fp64LowPart;\n fp64ifyMatrix4: typeof fp64ifyMatrix4;\n};\n\nconst defaultUniforms: FP64Uniforms = {\n // Used in LUMA_FP64_CODE_ELIMINATION_WORKAROUND\n ONE: 1.0,\n // Runtime split factor for Dekker splitting. Keeping this as a uniform helps\n // prevent aggressive constant folding in shader compilers.\n SPLIT: 4097.0\n};\n\n/**\n * 64bit arithmetic: add, sub, mul, div (small subset of fp64 module)\n */\nexport const fp64arithmetic: ShaderModule<FP64Props, FP64Uniforms, FP64Bindings> & FP64Utilities = {\n name: 'fp64arithmetic',\n source: fp64arithmeticWGSL,\n fs: fp64arithmeticShader,\n vs: fp64arithmeticShader,\n defaultUniforms,\n uniformTypes: {ONE: 'f32', SPLIT: 'f32'},\n\n // Additional Functions\n fp64ify,\n fp64LowPart,\n fp64ifyMatrix4\n};\n\n/**\n * Full 64 bit math library\n */\nexport const fp64: ShaderModule<{}> & FP64Utilities = {\n name: 'fp64',\n vs: fp64functionShader,\n dependencies: [fp64arithmetic],\n\n // Additional Functions\n fp64ify,\n fp64LowPart,\n fp64ifyMatrix4\n};\n\nexport {fp64ify, fp64LowPart, fp64ifyMatrix4};\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {ShaderModule} from '../../lib/shader-module/shader-module';\n\nexport type FloatColorsProps = {\n /**\n * When true, semantic colors are interpreted as 0-255 byte-style values and normalized in shader code.\n * When false, semantic colors are interpreted directly as floats.\n */\n useByteColors?: boolean;\n};\n\nexport type FloatColorsUniforms = {\n /** Controls whether shader helpers normalize semantic colors from byte space. */\n useByteColors: boolean;\n};\n\nconst GLSL_UNIFORMS = /* glsl */ `\\\nlayout(std140) uniform floatColorsUniforms {\n float useByteColors;\n} floatColors;\n\nvec3 floatColors_normalize(vec3 inputColor) {\n return floatColors.useByteColors > 0.5 ? inputColor / 255.0 : inputColor;\n}\n\nvec4 floatColors_normalize(vec4 inputColor) {\n return floatColors.useByteColors > 0.5 ? inputColor / 255.0 : inputColor;\n}\n\nvec4 floatColors_premultiplyAlpha(vec4 inputColor) {\n return vec4(inputColor.rgb * inputColor.a, inputColor.a);\n}\n\nvec4 floatColors_unpremultiplyAlpha(vec4 inputColor) {\n return inputColor.a > 0.0 ? vec4(inputColor.rgb / inputColor.a, inputColor.a) : vec4(0.0);\n}\n\nvec4 floatColors_premultiply_alpha(vec4 inputColor) {\n return floatColors_premultiplyAlpha(inputColor);\n}\n\nvec4 floatColors_unpremultiply_alpha(vec4 inputColor) {\n return floatColors_unpremultiplyAlpha(inputColor);\n}\n`;\n\nconst WGSL_UNIFORMS = /* wgsl */ `\\\nstruct floatColorsUniforms {\n useByteColors: f32\n};\n\n@group(0) @binding(auto) var<uniform> floatColors : floatColorsUniforms;\n\nfn floatColors_normalize(inputColor: vec3<f32>) -> vec3<f32> {\n return select(inputColor, inputColor / 255.0, floatColors.useByteColors > 0.5);\n}\n\nfn floatColors_normalize4(inputColor: vec4<f32>) -> vec4<f32> {\n return select(inputColor, inputColor / 255.0, floatColors.useByteColors > 0.5);\n}\n\nfn floatColors_premultiplyAlpha(inputColor: vec4<f32>) -> vec4<f32> {\n return vec4<f32>(inputColor.rgb * inputColor.a, inputColor.a);\n}\n\nfn floatColors_unpremultiplyAlpha(inputColor: vec4<f32>) -> vec4<f32> {\n return select(\n vec4<f32>(0.0),\n vec4<f32>(inputColor.rgb / inputColor.a, inputColor.a),\n inputColor.a > 0.0\n );\n}\n\nfn floatColors_premultiply_alpha(inputColor: vec4<f32>) -> vec4<f32> {\n return floatColors_premultiplyAlpha(inputColor);\n}\n\nfn floatColors_unpremultiply_alpha(inputColor: vec4<f32>) -> vec4<f32> {\n return floatColors_unpremultiplyAlpha(inputColor);\n}\n`;\n\nexport const floatColors = {\n name: 'floatColors',\n props: {} as FloatColorsProps,\n uniforms: {} as FloatColorsUniforms,\n vs: GLSL_UNIFORMS,\n fs: GLSL_UNIFORMS,\n source: WGSL_UNIFORMS,\n uniformTypes: {\n useByteColors: 'f32'\n },\n defaultUniforms: {\n useByteColors: true\n }\n} as const satisfies ShaderModule<FloatColorsProps, FloatColorsUniforms>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\nimport type {NumberArray3, NumberArray4} from '@math.gl/core';\nimport {normalizeByteColor4, resolveUseByteColors} from '../../../lib/color/normalize-byte-colors';\n\n// cyan color\nconst DEFAULT_HIGHLIGHT_COLOR: NumberArray4 = [0, 1, 1, 1];\n\n/**\n * Props for the picking module, which depending on mode renders picking colors or highlighted item.\n * When active, renders picking colors, assumed to be rendered to off-screen \"picking\" buffer.\n * When inactive, renders normal colors, with the exception of selected object which is rendered with highlight\n */\nexport type PickingProps = {\n /** Are we picking? I.e. rendering picking colors? */\n isActive?: boolean;\n /** Set to true when picking an attribute value instead of object index */\n isAttribute?: boolean;\n /** Set to a picking color to visually highlight that item, or `null` to explicitly clear **/\n highlightedObjectColor?: NumberArray3 | null;\n /** Color of visual highlight of \"selected\" item */\n highlightColor?: NumberArray3 | NumberArray4;\n /** Interpret highlight colors as byte-style 0-255 values. */\n useByteColors?: boolean;\n};\n\n/**\n * Uniforms for the picking module, which renders picking colors and highlighted item.\n * When active, renders picking colors, assumed to be rendered to off-screen \"picking\" buffer.\n * When inactive, renders normal colors, with the exception of selected object which is rendered with highlight\n */\nexport type PickingUniforms = {\n /**\n * When true, renders picking colors. Set when rendering to off-screen \"picking\" buffer.\n * When false, renders normal colors, with the exception of selected object which is rendered with highlight\n */\n isActive?: boolean;\n /** Set to true when picking an attribute value instead of object index */\n isAttribute?: boolean;\n /** Interpret highlight colors as byte-style 0-255 values. */\n useByteColors?: boolean;\n /** Do we have a highlighted item? */\n isHighlightActive?: boolean;\n /** Set to a picking color to visually highlight that item */\n highlightedObjectColor?: NumberArray3;\n /** Color of visual highlight of \"selected\" item */\n highlightColor?: NumberArray4;\n};\n\nconst vs = /* glsl */ `\\\nlayout(std140) uniform pickingUniforms {\n float isActive;\n float isAttribute;\n float isHighlightActive;\n float useByteColors;\n vec3 highlightedObjectColor;\n vec4 highlightColor;\n} picking;\n\nout vec4 picking_vRGBcolor_Avalid;\n\n// Normalize unsigned byte color to 0-1 range\nvec3 picking_normalizeColor(vec3 color) {\n return picking.useByteColors > 0.5 ? color / 255.0 : color;\n}\n\n// Normalize unsigned byte color to 0-1 range\nvec4 picking_normalizeColor(vec4 color) {\n return picking.useByteColors > 0.5 ? color / 255.0 : color;\n}\n\nbool picking_isColorZero(vec3 color) {\n return dot(color, vec3(1.0)) < 0.00001;\n}\n\nbool picking_isColorValid(vec3 color) {\n return dot(color, vec3(1.0)) > 0.00001;\n}\n\n// Check if this vertex is highlighted \nbool isVertexHighlighted(vec3 vertexColor) {\n vec3 highlightedObjectColor = picking_normalizeColor(picking.highlightedObjectColor);\n return\n bool(picking.isHighlightActive) && picking_isColorZero(abs(vertexColor - highlightedObjectColor));\n}\n\n// Set the current picking color\nvoid picking_setPickingColor(vec3 pickingColor) {\n pickingColor = picking_normalizeColor(pickingColor);\n\n if (bool(picking.isActive)) {\n // Use alpha as the validity flag. If pickingColor is [0, 0, 0] fragment is non-pickable\n picking_vRGBcolor_Avalid.a = float(picking_isColorValid(pickingColor));\n\n if (!bool(picking.isAttribute)) {\n // Stores the picking color so that the fragment shader can render it during picking\n picking_vRGBcolor_Avalid.rgb = pickingColor;\n }\n } else {\n // Do the comparison with selected item color in vertex shader as it should mean fewer compares\n picking_vRGBcolor_Avalid.a = float(isVertexHighlighted(pickingColor));\n }\n}\n\nvoid picking_setPickingAttribute(float value) {\n if (bool(picking.isAttribute)) {\n picking_vRGBcolor_Avalid.r = value;\n }\n}\n\nvoid picking_setPickingAttribute(vec2 value) {\n if (bool(picking.isAttribute)) {\n picking_vRGBcolor_Avalid.rg = value;\n }\n}\n\nvoid picking_setPickingAttribute(vec3 value) {\n if (bool(picking.isAttribute)) {\n picking_vRGBcolor_Avalid.rgb = value;\n }\n}\n`;\n\nconst fs = /* glsl */ `\\\nlayout(std140) uniform pickingUniforms {\n float isActive;\n float isAttribute;\n float isHighlightActive;\n float useByteColors;\n vec3 highlightedObjectColor;\n vec4 highlightColor;\n} picking;\n\nin vec4 picking_vRGBcolor_Avalid;\n\n/*\n * Returns highlight color if this item is selected.\n */\nvec4 picking_filterHighlightColor(vec4 color) {\n // If we are still picking, we don't highlight\n if (picking.isActive > 0.5) {\n return color;\n }\n\n bool selected = bool(picking_vRGBcolor_Avalid.a);\n\n if (selected) {\n // Blend in highlight color based on its alpha value\n float highLightAlpha = picking.highlightColor.a;\n float blendedAlpha = highLightAlpha + color.a * (1.0 - highLightAlpha);\n float highLightRatio = highLightAlpha / blendedAlpha;\n\n vec3 blendedRGB = mix(color.rgb, picking.highlightColor.rgb, highLightRatio);\n return vec4(blendedRGB, blendedAlpha);\n } else {\n return color;\n }\n}\n\n/*\n * Returns picking color if picking enabled else unmodified argument.\n */\nvec4 picking_filterPickingColor(vec4 color) {\n if (bool(picking.isActive)) {\n if (picking_vRGBcolor_Avalid.a == 0.0) {\n discard;\n }\n return picking_vRGBcolor_Avalid;\n }\n return color;\n}\n\n/*\n * Returns picking color if picking is enabled if not\n * highlight color if this item is selected, otherwise unmodified argument.\n */\nvec4 picking_filterColor(vec4 color) {\n vec4 highlightColor = picking_filterHighlightColor(color);\n return picking_filterPickingColor(highlightColor);\n}\n`;\n\n/**\n * Deprecated legacy picking module retained for compatibility with existing\n * shadertools users such as deck.gl. Keep the shader contract stable.\n *\n * Provides support for color-coding-based picking and highlighting.\n * In particular, supports picking a specific instance in an instanced\n * draw call and highlighting an instance based on its picking color,\n * and correspondingly, supports picking and highlighting groups of\n * primitives with the same picking color in non-instanced draw-calls\n */\nexport const picking = {\n props: {} as PickingProps,\n uniforms: {} as PickingUniforms,\n\n name: 'picking',\n\n uniformTypes: {\n isActive: 'f32',\n isAttribute: 'f32',\n isHighlightActive: 'f32',\n useByteColors: 'f32',\n highlightedObjectColor: 'vec3<f32>',\n highlightColor: 'vec4<f32>'\n },\n defaultUniforms: {\n isActive: false,\n isAttribute: false,\n isHighlightActive: false,\n useByteColors: true,\n highlightedObjectColor: [0, 0, 0],\n highlightColor: DEFAULT_HIGHLIGHT_COLOR\n },\n\n vs,\n fs,\n getUniforms\n} as const satisfies ShaderModule<PickingProps, PickingUniforms>;\n\nfunction getUniforms(opts: PickingProps = {}, prevUniforms?: PickingUniforms): PickingUniforms {\n const uniforms = {} as PickingUniforms;\n const useByteColors = resolveUseByteColors(opts.useByteColors, true);\n\n if (opts.highlightedObjectColor === undefined) {\n // Unless highlightedObjectColor explicitly null or set, do not update state\n } else if (opts.highlightedObjectColor === null) {\n uniforms.isHighlightActive = false;\n } else {\n uniforms.isHighlightActive = true;\n const highlightedObjectColor = opts.highlightedObjectColor.slice(0, 3) as NumberArray3;\n uniforms.highlightedObjectColor = highlightedObjectColor;\n }\n\n if (opts.highlightColor) {\n uniforms.highlightColor = normalizeByteColor4(opts.highlightColor, useByteColors);\n }\n\n if (opts.isActive !== undefined) {\n uniforms.isActive = Boolean(opts.isActive);\n uniforms.isAttribute = Boolean(opts.isAttribute);\n }\n\n if (opts.useByteColors !== undefined) {\n uniforms.useByteColors = Boolean(opts.useByteColors);\n }\n\n return uniforms;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Matrix4} from '@math.gl/core';\n\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\n\nconst SKIN_MAX_JOINTS = 20;\n\nexport const source = /* wgsl */ `\nstruct skinUniforms {\n jointMatrix: array<mat4x4<f32>, ${SKIN_MAX_JOINTS}>,\n};\n\n@group(0) @binding(auto) var<uniform> skin: skinUniforms;\n\nfn getSkinMatrix(weights: vec4f, joints: vec4u) -> mat4x4<f32> {\n return (weights.x * skin.jointMatrix[joints.x])\n + (weights.y * skin.jointMatrix[joints.y])\n + (weights.z * skin.jointMatrix[joints.z])\n + (weights.w * skin.jointMatrix[joints.w]);\n}\n`;\n\nexport const vs = /* glsl */ `\\\n\nlayout(std140) uniform skinUniforms {\n mat4 jointMatrix[SKIN_MAX_JOINTS];\n} skin;\n\nmat4 getSkinMatrix(vec4 weights, uvec4 joints) {\n return (weights.x * skin.jointMatrix[joints.x])\n + (weights.y * skin.jointMatrix[joints.y])\n + (weights.z * skin.jointMatrix[joints.z])\n + (weights.w * skin.jointMatrix[joints.w]);\n}\n\n`;\n\nexport const fs = /* glsl */ `\\\n`;\n\nexport type SkinProps = {\n scenegraphsFromGLTF?: any;\n};\n\nexport type SkinUniforms = {\n jointMatrix?: any;\n};\n\nexport const skin = {\n props: {} as SkinProps,\n uniforms: {} as SkinUniforms,\n\n name: 'skin',\n bindingLayout: [{name: 'skin', group: 0}],\n dependencies: [],\n source,\n vs,\n fs,\n\n defines: {\n SKIN_MAX_JOINTS\n },\n\n getUniforms: (props: SkinProps = {}, prevUniforms?: SkinUniforms): SkinUniforms => {\n const {scenegraphsFromGLTF} = props;\n\n if (!scenegraphsFromGLTF?.gltf?.skins?.[0]) {\n return {jointMatrix: []};\n }\n\n const {inverseBindMatrices, joints, skeleton} = scenegraphsFromGLTF.gltf.skins[0];\n\n const matsib = [];\n const countib = inverseBindMatrices.value.length / 16;\n for (let i = 0; i < countib; i++) {\n const slice = inverseBindMatrices.value.subarray(i * 16, i * 16 + 16);\n matsib.push(new Matrix4(Array.from(slice)));\n }\n\n const top = scenegraphsFromGLTF.gltfNodeIndexToNodeMap.get(skeleton);\n const matrices: Record<string, Matrix4> = {};\n top.preorderTraversal((node: any, {worldMatrix}: any) => {\n matrices[node.id] = worldMatrix;\n });\n\n const mats = new Float32Array(SKIN_MAX_JOINTS * 16); // 16 floats per 4x4 matrix\n for (let i = 0; i < SKIN_MAX_JOINTS; ++i) {\n const nodeIndex = joints[i];\n if (nodeIndex === undefined) break;\n\n const worldMat = matrices[scenegraphsFromGLTF.gltfNodeIndexToNodeMap.get(nodeIndex).id];\n const invBindMat = matsib[i];\n\n const Z = new Matrix4().copy(worldMat).multiplyRight(invBindMat);\n\n const off = i * 16;\n\n for (let j = 0; j < 16; j++) {\n mats[off + j] = Z[j];\n }\n }\n\n return {\n jointMatrix: mats\n };\n },\n\n uniformTypes: {\n jointMatrix: ['mat4x4<f32>', SKIN_MAX_JOINTS]\n }\n} as const satisfies ShaderModule<SkinProps, SkinUniforms>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {log} from '@luma.gl/core';\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\nimport {lightingUniformsGLSL} from './lighting-glsl';\nimport {lightingUniformsWGSL} from './lighting-wgsl';\nimport type {NumberArray2, NumberArray3} from '@math.gl/core';\nimport {normalizeByteColor3, resolveUseByteColors} from '../../../lib/color/normalize-byte-colors';\n\n/** Max number of supported lights (in addition to ambient light */\nconst MAX_LIGHTS = 5;\n\n/** Supported light source descriptions accepted by the lighting shader module. */\nexport type Light = AmbientLight | PointLight | SpotLight | DirectionalLight;\n\n/** Ambient light contribution shared across the entire scene. */\nexport type AmbientLight = {\n /** Discriminator used to identify ambient lights in `lights: Light[]`. */\n type: 'ambient';\n /** RGB light color in the existing `0..255` convention used by luma.gl materials. */\n color?: Readonly<NumberArray3>;\n /** Scalar intensity multiplier applied to the light color. */\n intensity?: number;\n};\n\n/** Omnidirectional point light emitted from a world-space position. */\nexport type PointLight = {\n /** Discriminator used to identify point lights in `lights: Light[]`. */\n type: 'point';\n /** World-space light position. */\n position: Readonly<NumberArray3>;\n /** RGB light color in the existing `0..255` convention used by luma.gl materials. */\n color?: Readonly<NumberArray3>;\n /** Scalar intensity multiplier applied to the light color. */\n intensity?: number;\n /** Constant, linear, and quadratic attenuation coefficients. */\n attenuation?: Readonly<NumberArray3>;\n};\n\n/** Directional light defined only by its incoming world-space direction. */\nexport type DirectionalLight = {\n /** Discriminator used to identify directional lights in `lights: Light[]`. */\n type: 'directional';\n /** World-space light direction. */\n direction: Readonly<NumberArray3>;\n /** RGB light color in the existing `0..255` convention used by luma.gl materials. */\n color?: Readonly<NumberArray3>;\n /** Scalar intensity multiplier applied to the light color. */\n intensity?: number;\n};\n\n/** Cone-shaped light emitted from a position and focused along a direction. */\nexport type SpotLight = {\n /** Discriminator used to identify spot lights in `lights: Light[]`. */\n type: 'spot';\n /** World-space light position. */\n position: Readonly<NumberArray3>;\n /** World-space light direction. */\n direction: Readonly<NumberArray3>;\n /** RGB light color in the existing `0..255` convention used by luma.gl materials. */\n color?: Readonly<NumberArray3>;\n /** Scalar intensity multiplier applied to the light color. */\n intensity?: number;\n /** Constant, linear, and quadratic attenuation coefficients. */\n attenuation?: Readonly<NumberArray3>;\n /** Inner spotlight cone angle in radians. */\n innerConeAngle?: number;\n /** Outer spotlight cone angle in radians. */\n outerConeAngle?: number;\n};\n\n/** Public JavaScript props accepted by the `lighting` shader module. */\nexport type LightingProps = {\n /** Enables or disables lighting calculations for the module. */\n enabled?: boolean;\n /** When true, light colors are interpreted as byte-style 0-255 values. */\n useByteColors?: boolean;\n /** Preferred API for supplying mixed ambient, point, spot, and directional lights. */\n lights?: Light[];\n /**\n * Legacy ambient-light prop.\n * @deprecated Use `lights` with `{type: 'ambient', ...}` entries instead.\n */\n ambientLight?: AmbientLight;\n /**\n * Legacy point-light prop.\n * @deprecated Use `lights` with `{type: 'point', ...}` entries instead.\n */\n pointLights?: PointLight[];\n /**\n * Legacy spot-light prop.\n * @deprecated Use `lights` with `{type: 'spot', ...}` entries instead.\n */\n spotLights?: SpotLight[];\n /**\n * Legacy directional-light prop.\n * @deprecated Use `lights` with `{type: 'directional', ...}` entries instead.\n */\n directionalLights?: DirectionalLight[];\n};\n\n/** Packed per-light data written into the module's fixed-size uniform array. */\nexport type LightingLightUniform = {\n /** Light color converted to normalized shader-space RGB. */\n color: Readonly<NumberArray3>;\n /** World-space light position or a default placeholder for non-positional lights. */\n position: Readonly<NumberArray3>;\n /** World-space light direction or a default placeholder for positional lights. */\n direction: Readonly<NumberArray3>;\n /** Constant, linear, and quadratic attenuation coefficients. */\n attenuation: Readonly<NumberArray3>;\n /** Cosines of the inner and outer spotlight cone angles. */\n coneCos: Readonly<NumberArray2>;\n};\n\n/** Fully normalized uniform values produced by the `lighting` shader module. */\nexport type LightingUniforms = {\n /** `1` when lighting is enabled, otherwise `0`. */\n enabled: number;\n /** Number of packed directional lights in the `lights` array. */\n directionalLightCount: number;\n /** Number of packed point lights in the `lights` array. */\n pointLightCount: number;\n /** Number of packed spot lights in the `lights` array. */\n spotLightCount: number;\n /** Accumulated ambient color converted to normalized shader-space RGB. */\n ambientColor: Readonly<NumberArray3>;\n /** Packed trailing array of non-ambient light structs. */\n lights: ReadonlyArray<LightingLightUniform>;\n};\n\nconst LIGHT_UNIFORM_TYPE = {\n color: 'vec3<f32>',\n position: 'vec3<f32>',\n direction: 'vec3<f32>',\n attenuation: 'vec3<f32>',\n coneCos: 'vec2<f32>'\n} as const;\n\n/**\n * Portable lighting shader module shared by the Phong, Gouraud, and PBR material modules.\n *\n * The public JavaScript API accepts `lights: Light[]`, while the uniform buffer packs\n * non-ambient lights into a fixed-size trailing array for portability across WebGL2 and WebGPU.\n */\nexport const lighting = {\n props: {} as LightingProps,\n uniforms: {} as LightingUniforms,\n\n name: 'lighting',\n\n defines: {\n // MAX_LIGHTS\n },\n\n uniformTypes: {\n enabled: 'i32',\n directionalLightCount: 'i32',\n pointLightCount: 'i32',\n spotLightCount: 'i32',\n ambientColor: 'vec3<f32>',\n lights: [LIGHT_UNIFORM_TYPE, MAX_LIGHTS]\n },\n\n defaultUniforms: createDefaultLightingUniforms(),\n bindingLayout: [{name: 'lighting', group: 2}],\n firstBindingSlot: 0,\n source: lightingUniformsWGSL,\n vs: lightingUniformsGLSL,\n fs: lightingUniformsGLSL,\n\n getUniforms\n} as const satisfies ShaderModule<LightingProps, LightingUniforms, {}>;\n\nfunction getUniforms(\n props?: LightingProps,\n _prevUniforms: Partial<LightingUniforms> = {}\n): LightingUniforms {\n // Copy props so we can modify\n props = props ? {...props} : props;\n\n // TODO legacy\n if (!props) {\n return createDefaultLightingUniforms();\n }\n // Support for array of lights. Type of light is detected by type field\n if (props.lights) {\n props = {...props, ...extractLightTypes(props.lights), lights: undefined};\n }\n\n // Specify lights separately\n const {useByteColors, ambientLight, pointLights, spotLights, directionalLights} = props || {};\n const hasLights =\n ambientLight ||\n (pointLights && pointLights.length > 0) ||\n (spotLights && spotLights.length > 0) ||\n (directionalLights && directionalLights.length > 0);\n\n // TODO - this may not be the correct decision\n if (!hasLights) {\n return {\n ...createDefaultLightingUniforms(),\n enabled: 0\n };\n }\n\n const uniforms = {\n ...createDefaultLightingUniforms(),\n ...getLightSourceUniforms({\n useByteColors,\n ambientLight,\n pointLights,\n spotLights,\n directionalLights\n })\n };\n\n if (props.enabled !== undefined) {\n uniforms.enabled = props.enabled ? 1 : 0;\n }\n\n return uniforms;\n}\n\nfunction getLightSourceUniforms({\n useByteColors,\n ambientLight,\n pointLights = [],\n spotLights = [],\n directionalLights = []\n}: LightingProps): Omit<LightingUniforms, 'enabled'> {\n const lights = createDefaultLightUniforms();\n\n let currentLight = 0;\n let pointLightCount = 0;\n let spotLightCount = 0;\n let directionalLightCount = 0;\n\n for (const pointLight of pointLights) {\n if (currentLight >= MAX_LIGHTS) {\n break;\n }\n\n lights[currentLight] = {\n ...lights[currentLight],\n color: convertColor(pointLight, useByteColors),\n position: pointLight.position,\n attenuation: pointLight.attenuation || [1, 0, 0]\n };\n currentLight++;\n pointLightCount++;\n }\n\n for (const spotLight of spotLights) {\n if (currentLight >= MAX_LIGHTS) {\n break;\n }\n\n lights[currentLight] = {\n ...lights[currentLight],\n color: convertColor(spotLight, useByteColors),\n position: spotLight.position,\n direction: spotLight.direction,\n attenuation: spotLight.attenuation || [1, 0, 0],\n coneCos: getSpotConeCos(spotLight)\n };\n currentLight++;\n spotLightCount++;\n }\n\n for (const directionalLight of directionalLights) {\n if (currentLight >= MAX_LIGHTS) {\n break;\n }\n\n lights[currentLight] = {\n ...lights[currentLight],\n color: convertColor(directionalLight, useByteColors),\n direction: directionalLight.direction\n };\n currentLight++;\n directionalLightCount++;\n }\n\n if (pointLights.length + spotLights.length + directionalLights.length > MAX_LIGHTS) {\n log.warn(`MAX_LIGHTS exceeded, truncating to ${MAX_LIGHTS}`)();\n }\n\n return {\n ambientColor: convertColor(ambientLight, useByteColors),\n directionalLightCount,\n pointLightCount,\n spotLightCount,\n lights\n };\n}\n\nfunction extractLightTypes(lights: Light[]): LightingProps {\n const lightSources: LightingProps = {pointLights: [], spotLights: [], directionalLights: []};\n for (const light of lights || []) {\n switch (light.type) {\n case 'ambient':\n // Note: Only uses last ambient light\n // TODO - add ambient light sources on CPU?\n lightSources.ambientLight = light;\n break;\n case 'directional':\n lightSources.directionalLights?.push(light);\n break;\n case 'point':\n lightSources.pointLights?.push(light);\n break;\n case 'spot':\n lightSources.spotLights?.push(light);\n break;\n default:\n // eslint-disable-next-line\n // console.warn(light.type);\n }\n }\n return lightSources;\n}\n\n/** Take color 0-255 and intensity as input and output 0.0-1.0 range */\nfunction convertColor(\n colorDef: {color?: Readonly<NumberArray3>; intensity?: number} = {},\n useByteColors?: boolean\n): NumberArray3 {\n const {color = [0, 0, 0], intensity = 1.0} = colorDef;\n const normalizedColor = normalizeByteColor3(color, resolveUseByteColors(useByteColors, true));\n return normalizedColor.map(component => component * intensity) as NumberArray3;\n}\n\nfunction createDefaultLightingUniforms(): LightingUniforms {\n return {\n enabled: 1,\n directionalLightCount: 0,\n pointLightCount: 0,\n spotLightCount: 0,\n ambientColor: [0.1, 0.1, 0.1],\n lights: createDefaultLightUniforms()\n };\n}\n\nfunction createDefaultLightUniforms(): LightingLightUniform[] {\n return Array.from({length: MAX_LIGHTS}, () => createDefaultLightUniform());\n}\n\nfunction createDefaultLightUniform(): LightingLightUniform {\n return {\n color: [1, 1, 1],\n position: [1, 1, 2],\n direction: [1, 1, 1],\n attenuation: [1, 0, 0],\n coneCos: [1, 0]\n };\n}\n\nfunction getSpotConeCos(spotLight: SpotLight): NumberArray2 {\n const innerConeAngle = spotLight.innerConeAngle ?? 0;\n const outerConeAngle = spotLight.outerConeAngle ?? Math.PI / 4;\n return [Math.cos(innerConeAngle), Math.cos(outerConeAngle)];\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const lightingUniformsGLSL = /* glsl */ `\\\nprecision 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 SpotLight {\n vec3 color;\n vec3 position;\n vec3 direction;\n vec3 attenuation;\n vec2 coneCos;\n};\n\nstruct DirectionalLight {\n vec3 color;\n vec3 direction;\n};\n\nstruct UniformLight {\n vec3 color;\n vec3 position;\n vec3 direction;\n vec3 attenuation;\n vec2 coneCos;\n};\n\nlayout(std140) uniform lightingUniforms {\n int enabled;\n int directionalLightCount;\n int pointLightCount;\n int spotLightCount;\n vec3 ambientColor;\n UniformLight lights[5];\n} lighting;\n\nPointLight lighting_getPointLight(int index) {\n UniformLight light = lighting.lights[index];\n return PointLight(light.color, light.position, light.attenuation);\n}\n\nSpotLight lighting_getSpotLight(int index) {\n UniformLight light = lighting.lights[lighting.pointLightCount + index];\n return SpotLight(light.color, light.position, light.direction, light.attenuation, light.coneCos);\n}\n\nDirectionalLight lighting_getDirectionalLight(int index) {\n UniformLight light =\n lighting.lights[lighting.pointLightCount + lighting.spotLightCount + index];\n return DirectionalLight(light.color, light.direction);\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\nfloat getSpotLightAttenuation(SpotLight spotLight, vec3 positionWorldspace) {\n vec3 light_direction = normalize(positionWorldspace - spotLight.position);\n float coneFactor = smoothstep(\n spotLight.coneCos.y,\n spotLight.coneCos.x,\n dot(normalize(spotLight.direction), light_direction)\n );\n float distanceAttenuation = getPointLightAttenuation(\n PointLight(spotLight.color, spotLight.position, spotLight.attenuation),\n distance(spotLight.position, positionWorldspace)\n );\n return distanceAttenuation / max(coneFactor, 0.0001);\n}\n\n// #endif\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const lightingUniformsWGSL = /* wgsl */ `\\\n// #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX))\nconst MAX_LIGHTS: i32 = 5;\n\nstruct AmbientLight {\n color: vec3<f32>,\n};\n\nstruct PointLight {\n color: vec3<f32>,\n position: vec3<f32>,\n attenuation: vec3<f32>, // 2nd order x:Constant-y:Linear-z:Exponential\n};\n\nstruct SpotLight {\n color: vec3<f32>,\n position: vec3<f32>,\n direction: vec3<f32>,\n attenuation: vec3<f32>,\n coneCos: vec2<f32>,\n};\n\nstruct DirectionalLight {\n color: vec3<f32>,\n direction: vec3<f32>,\n};\n\nstruct UniformLight {\n color: vec3<f32>,\n position: vec3<f32>,\n direction: vec3<f32>,\n attenuation: vec3<f32>,\n coneCos: vec2<f32>,\n};\n\nstruct lightingUniforms {\n enabled: i32,\n directionalLightCount: i32,\n pointLightCount: i32,\n spotLightCount: i32,\n ambientColor: vec3<f32>,\n lights: array<UniformLight, 5>,\n};\n\n@group(2) @binding(auto) var<uniform> lighting : lightingUniforms;\n\nfn lighting_getPointLight(index: i32) -> PointLight {\n let light = lighting.lights[index];\n return PointLight(light.color, light.position, light.attenuation);\n}\n\nfn lighting_getSpotLight(index: i32) -> SpotLight {\n let light = lighting.lights[lighting.pointLightCount + index];\n return SpotLight(light.color, light.position, light.direction, light.attenuation, light.coneCos);\n}\n\nfn lighting_getDirectionalLight(index: i32) -> DirectionalLight {\n let light = lighting.lights[lighting.pointLightCount + lighting.spotLightCount + index];\n return DirectionalLight(light.color, light.direction);\n}\n\nfn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {\n return pointLight.attenuation.x\n + pointLight.attenuation.y * distance\n + pointLight.attenuation.z * distance * distance;\n}\n\nfn getSpotLightAttenuation(spotLight: SpotLight, positionWorldspace: vec3<f32>) -> f32 {\n let lightDirection = normalize(positionWorldspace - spotLight.position);\n let coneFactor = smoothstep(\n spotLight.coneCos.y,\n spotLight.coneCos.x,\n dot(normalize(spotLight.direction), lightDirection)\n );\n let distanceAttenuation = getPointLightAttenuation(\n PointLight(spotLight.color, spotLight.position, spotLight.attenuation),\n distance(spotLight.position, positionWorldspace)\n );\n return distanceAttenuation / max(coneFactor, 0.0001);\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {Texture} from '@luma.gl/core';\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\n\nexport type IBLBindings = {\n pbr_diffuseEnvSampler?: Texture | null;\n pbr_specularEnvSampler?: Texture | null;\n pbr_brdfLUT?: Texture | null;\n};\n\nexport const iblWGSL = /* wgsl */ `\\\n#ifdef USE_IBL\n@group(2) @binding(auto) var pbr_diffuseEnvSampler: texture_cube<f32>;\n@group(2) @binding(auto) var pbr_diffuseEnvSamplerSampler: sampler;\n@group(2) @binding(auto) var pbr_specularEnvSampler: texture_cube<f32>;\n@group(2) @binding(auto) var pbr_specularEnvSamplerSampler: sampler;\n@group(2) @binding(auto) var pbr_brdfLUT: texture_2d<f32>;\n@group(2) @binding(auto) var pbr_brdfLUTSampler: sampler;\n#endif\n`;\n\nexport const iblGLSL = /* glsl */ `\\\n#ifdef USE_IBL\nuniform samplerCube pbr_diffuseEnvSampler;\nuniform samplerCube pbr_specularEnvSampler;\nuniform sampler2D pbr_brdfLUT;\n#endif\n`;\n\nexport const ibl = {\n name: 'ibl',\n firstBindingSlot: 32,\n bindingLayout: [\n {name: 'pbr_diffuseEnvSampler', group: 2},\n {name: 'pbr_specularEnvSampler', group: 2},\n {name: 'pbr_brdfLUT', group: 2}\n ],\n source: iblWGSL,\n vs: iblGLSL,\n fs: iblGLSL\n} as const satisfies ShaderModule<IBLBindings, {}, IBLBindings>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {NumberArray3} from '@math.gl/core';\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\n\nexport type DirlightProps = {\n lightDirection?: NumberArray3;\n};\n\nexport type DirlightUniforms = DirlightProps;\n\n// TODO\nexport const SOURCE_WGSL = /* WGSL */ `\\\nstruct dirlightUniforms {\n lightDirection: vec3<f32>,\n};\n\nalias DirlightNormal = vec3<f32>;\n\nstruct DirlightInputs {\n normal: DirlightNormal,\n};\n\n@group(2) @binding(auto) var<uniform> dirlight : dirlightUniforms;\n\n// For vertex\nfn dirlight_setNormal(normal: vec3<f32>) -> DirlightNormal {\n return normalize(normal);\n}\n\n// Returns color attenuated by angle from light source\nfn dirlight_filterColor(color: vec4<f32>, inputs: DirlightInputs) -> vec4<f32> {\n // TODO - fix default light direction\n // let lightDirection = dirlight.lightDirection;\n let lightDirection = vec3<f32>(1, 1, 1);\n let d: f32 = abs(dot(inputs.normal, normalize(lightDirection)));\n return vec4<f32>(color.rgb * d, color.a);\n}\n`;\n\nconst VS_GLSL = /* glsl */ `\\\nout vec3 dirlight_vNormal;\n\nvoid dirlight_setNormal(vec3 normal) {\n dirlight_vNormal = normalize(normal);\n}\n`;\n\nconst FS_GLSL = /* glsl */ `\\\nlayout(std140) uniform dirlightUniforms {\n vec3 lightDirection;\n} dirlight;\n\nin vec3 dirlight_vNormal;\n\n// Returns color attenuated by angle from light source\nvec4 dirlight_filterColor(vec4 color) {\n float d = abs(dot(dirlight_vNormal, normalize(dirlight.lightDirection)));\n return vec4(color.rgb * d, color.a);\n}\n`;\n\n/**\n * Cheap lighting - single directional light, single dot product, one uniform\n */\nexport const dirlight = {\n props: {} as DirlightProps,\n uniforms: {} as DirlightUniforms,\n\n name: 'dirlight',\n bindingLayout: [{name: 'dirlight', group: 2}],\n firstBindingSlot: 16,\n dependencies: [],\n source: SOURCE_WGSL,\n vs: VS_GLSL,\n fs: FS_GLSL,\n\n // fragmentInputs: [\n // {\n // name: 'dirlight_vNormal',\n // type: 'vec3<f32>'\n // }\n // ],\n uniformTypes: {\n lightDirection: 'vec3<f32>'\n },\n defaultUniforms: {\n lightDirection: [1, 1, 2]\n },\n getUniforms\n} as const satisfies ShaderModule<DirlightProps, DirlightUniforms>;\n\nfunction getUniforms(opts: DirlightProps = dirlight.defaultUniforms): DirlightUniforms {\n const uniforms: DirlightUniforms = {};\n if (opts.lightDirection) {\n uniforms.lightDirection = opts.lightDirection;\n }\n return uniforms;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const LAMBERT_WGSL = /* wgsl */ `\\\nstruct lambertMaterialUniforms {\n unlit: u32,\n ambient: f32,\n diffuse: f32,\n};\n\n@group(3) @binding(auto) var<uniform> lambertMaterial : lambertMaterialUniforms;\n\nfn lighting_getLightColor(surfaceColor: vec3<f32>, light_direction: vec3<f32>, normal_worldspace: vec3<f32>, color: vec3<f32>) -> vec3<f32> {\n let lambertian: f32 = max(dot(light_direction, normal_worldspace), 0.0);\n return lambertian * lambertMaterial.diffuse * surfaceColor * color;\n}\n\nfn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, position_worldspace: vec3<f32>, normal_worldspace: vec3<f32>) -> vec3<f32> {\n var lightColor: vec3<f32> = surfaceColor;\n\n if (lambertMaterial.unlit != 0u) {\n return surfaceColor;\n }\n\n if (lighting.enabled == 0) {\n return lightColor;\n }\n\n lightColor = lambertMaterial.ambient * surfaceColor * lighting.ambientColor;\n\n for (var i: i32 = 0; i < lighting.pointLightCount; i++) {\n let pointLight: PointLight = lighting_getPointLight(i);\n let light_position_worldspace: vec3<f32> = pointLight.position;\n let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);\n let light_attenuation = getPointLightAttenuation(\n pointLight,\n distance(light_position_worldspace, position_worldspace)\n );\n lightColor += lighting_getLightColor(\n surfaceColor,\n light_direction,\n normal_worldspace,\n pointLight.color / light_attenuation\n );\n }\n\n for (var i: i32 = 0; i < lighting.spotLightCount; i++) {\n let spotLight: SpotLight = lighting_getSpotLight(i);\n let light_position_worldspace: vec3<f32> = spotLight.position;\n let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);\n let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);\n lightColor += lighting_getLightColor(\n surfaceColor,\n light_direction,\n normal_worldspace,\n spotLight.color / light_attenuation\n );\n }\n\n for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {\n let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);\n lightColor += lighting_getLightColor(\n surfaceColor,\n -directionalLight.direction,\n normal_worldspace,\n directionalLight.color\n );\n }\n\n return lightColor;\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const LAMBERT_VS = /* glsl */ `\\\nlayout(std140) uniform lambertMaterialUniforms {\n uniform bool unlit;\n uniform float ambient;\n uniform float diffuse;\n} material;\n`;\n\nexport const LAMBERT_FS = /* glsl */ `\\\nlayout(std140) uniform lambertMaterialUniforms {\n uniform bool unlit;\n uniform float ambient;\n uniform float diffuse;\n} material;\n\nvec3 lighting_getLightColor(vec3 surfaceColor, vec3 light_direction, vec3 normal_worldspace, vec3 color) {\n float lambertian = max(dot(light_direction, normal_worldspace), 0.0);\n return lambertian * material.diffuse * surfaceColor * color;\n}\n\nvec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) {\n vec3 lightColor = surfaceColor;\n\n if (material.unlit) {\n return surfaceColor;\n }\n\n if (lighting.enabled == 0) {\n return lightColor;\n }\n\n lightColor = material.ambient * surfaceColor * lighting.ambientColor;\n\n for (int i = 0; i < lighting.pointLightCount; i++) {\n PointLight pointLight = lighting_getPointLight(i);\n vec3 light_position_worldspace = pointLight.position;\n vec3 light_direction = normalize(light_position_worldspace - position_worldspace);\n float light_attenuation = getPointLightAttenuation(pointLight, distance(light_position_worldspace, position_worldspace));\n lightColor += lighting_getLightColor(surfaceColor, light_direction, normal_worldspace, pointLight.color / light_attenuation);\n }\n\n for (int i = 0; i < lighting.spotLightCount; i++) {\n SpotLight spotLight = lighting_getSpotLight(i);\n vec3 light_position_worldspace = spotLight.position;\n vec3 light_direction = normalize(light_position_worldspace - position_worldspace);\n float light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);\n lightColor += lighting_getLightColor(surfaceColor, light_direction, normal_worldspace, spotLight.color / light_attenuation);\n }\n\n for (int i = 0; i < lighting.directionalLightCount; i++) {\n DirectionalLight directionalLight = lighting_getDirectionalLight(i);\n lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, normal_worldspace, directionalLight.color);\n }\n\n return lightColor;\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\nimport {lighting} from '../lights/lighting';\nimport {LAMBERT_WGSL} from './lambert-shaders-wgsl';\nimport {LAMBERT_VS, LAMBERT_FS} from './lambert-shaders-glsl';\n\n/** Uniform props for the built-in diffuse-only Lambert material model. */\nexport type LambertMaterialProps = {\n unlit?: boolean;\n ambient?: number;\n diffuse?: number;\n};\n\n/** A matte material model that applies diffuse-only Lambert lighting per fragment. */\nexport const lambertMaterial: ShaderModule<LambertMaterialProps> = {\n name: 'lambertMaterial',\n firstBindingSlot: 0,\n bindingLayout: [{name: 'lambertMaterial', group: 3}],\n dependencies: [lighting],\n source: LAMBERT_WGSL,\n vs: LAMBERT_VS,\n fs: LAMBERT_FS,\n defines: {\n LIGHTING_FRAGMENT: true\n },\n uniformTypes: {\n unlit: 'i32',\n ambient: 'f32',\n diffuse: 'f32'\n },\n defaultUniforms: {\n unlit: false,\n ambient: 0.35,\n diffuse: 0.6\n },\n getUniforms(props?: LambertMaterialProps) {\n return {...lambertMaterial.defaultUniforms, ...props};\n }\n};\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const PHONG_VS = /* glsl */ `\\\nlayout(std140) uniform phongMaterialUniforms {\n uniform bool unlit;\n uniform float ambient;\n uniform float diffuse;\n uniform float shininess;\n uniform vec3 specularColor;\n} material;\n`;\n\nexport const PHONG_FS = /* glsl */ `\\\nlayout(std140) uniform phongMaterialUniforms {\n uniform bool unlit;\n uniform float ambient;\n uniform float diffuse;\n uniform float shininess;\n uniform vec3 specularColor;\n} material;\n\nvec3 lighting_getLightColor(vec3 surfaceColor, vec3 light_direction, vec3 view_direction, vec3 normal_worldspace, vec3 color) {\n vec3 halfway_direction = normalize(light_direction + view_direction);\n float lambertian = dot(light_direction, normal_worldspace);\n float specular = 0.0;\n if (lambertian > 0.0) {\n float specular_angle = max(dot(normal_worldspace, halfway_direction), 0.0);\n specular = pow(specular_angle, material.shininess);\n }\n lambertian = max(lambertian, 0.0);\n return (lambertian * material.diffuse * surfaceColor + specular * floatColors_normalize(material.specularColor)) * color;\n}\n\nvec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) {\n vec3 lightColor = surfaceColor;\n\n if (material.unlit) {\n return surfaceColor;\n }\n\n if (lighting.enabled == 0) {\n return lightColor;\n }\n\n vec3 view_direction = normalize(cameraPosition - position_worldspace);\n lightColor = material.ambient * surfaceColor * lighting.ambientColor;\n\n for (int i = 0; i < lighting.pointLightCount; i++) {\n PointLight pointLight = lighting_getPointLight(i);\n vec3 light_position_worldspace = pointLight.position;\n vec3 light_direction = normalize(light_position_worldspace - position_worldspace);\n float light_attenuation = getPointLightAttenuation(pointLight, distance(light_position_worldspace, position_worldspace));\n lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, pointLight.color / light_attenuation);\n }\n\n for (int i = 0; i < lighting.spotLightCount; i++) {\n SpotLight spotLight = lighting_getSpotLight(i);\n vec3 light_position_worldspace = spotLight.position;\n vec3 light_direction = normalize(light_position_worldspace - position_worldspace);\n float light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);\n lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, spotLight.color / light_attenuation);\n }\n\n for (int i = 0; i < lighting.directionalLightCount; i++) {\n DirectionalLight directionalLight = lighting_getDirectionalLight(i);\n lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);\n }\n \n return lightColor;\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport const PHONG_WGSL = /* wgsl */ `\\\nstruct phongMaterialUniforms {\n unlit: u32,\n ambient: f32,\n diffuse: f32,\n shininess: f32,\n specularColor: vec3<f32>,\n};\n\n@group(3) @binding(auto) var<uniform> phongMaterial : phongMaterialUniforms;\n\nfn lighting_getLightColor(surfaceColor: vec3<f32>, light_direction: vec3<f32>, view_direction: vec3<f32>, normal_worldspace: vec3<f32>, color: vec3<f32>) -> vec3<f32> {\n let halfway_direction: vec3<f32> = normalize(light_direction + view_direction);\n var lambertian: f32 = dot(light_direction, normal_worldspace);\n var specular: f32 = 0.0;\n if (lambertian > 0.0) {\n let specular_angle = max(dot(normal_worldspace, halfway_direction), 0.0);\n specular = pow(specular_angle, phongMaterial.shininess);\n }\n lambertian = max(lambertian, 0.0);\n return (\n lambertian * phongMaterial.diffuse * surfaceColor +\n specular * floatColors_normalize(phongMaterial.specularColor)\n ) * color;\n}\n\nfn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, position_worldspace: vec3<f32>, normal_worldspace: vec3<f32>) -> vec3<f32> {\n var lightColor: vec3<f32> = surfaceColor;\n\n if (phongMaterial.unlit != 0u) {\n return surfaceColor;\n }\n\n if (lighting.enabled == 0) {\n return lightColor;\n }\n\n let view_direction: vec3<f32> = normalize(cameraPosition - position_worldspace);\n lightColor = phongMaterial.ambient * surfaceColor * lighting.ambientColor;\n\n for (var i: i32 = 0; i < lighting.pointLightCount; i++) {\n let pointLight: PointLight = lighting_getPointLight(i);\n let light_position_worldspace: vec3<f32> = pointLight.position;\n let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);\n let light_attenuation = getPointLightAttenuation(\n pointLight,\n distance(light_position_worldspace, position_worldspace)\n );\n lightColor += lighting_getLightColor(\n surfaceColor,\n light_direction,\n view_direction,\n normal_worldspace,\n pointLight.color / light_attenuation\n );\n }\n\n for (var i: i32 = 0; i < lighting.spotLightCount; i++) {\n let spotLight: SpotLight = lighting_getSpotLight(i);\n let light_position_worldspace: vec3<f32> = spotLight.position;\n let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);\n let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);\n lightColor += lighting_getLightColor(\n surfaceColor,\n light_direction,\n view_direction,\n normal_worldspace,\n spotLight.color / light_attenuation\n );\n }\n\n for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {\n let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);\n lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);\n } \n \n return lightColor;\n}\n\nfn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace: vec3<f32>, normal_worldspace: vec3<f32>) -> vec3<f32>{\n var lightColor = vec3<f32>(0, 0, 0);\n let surfaceColor = vec3<f32>(0, 0, 0);\n\n if (lighting.enabled != 0) {\n let view_direction = normalize(cameraPosition - position_worldspace);\n\n for (var i: i32 = 0; i < lighting.pointLightCount; i++) {\n let pointLight: PointLight = lighting_getPointLight(i);\n let light_position_worldspace: vec3<f32> = pointLight.position;\n let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);\n let light_attenuation = getPointLightAttenuation(\n pointLight,\n distance(light_position_worldspace, position_worldspace)\n );\n lightColor += lighting_getLightColor(\n surfaceColor,\n light_direction,\n view_direction,\n normal_worldspace,\n pointLight.color / light_attenuation\n );\n }\n\n for (var i: i32 = 0; i < lighting.spotLightCount; i++) {\n let spotLight: SpotLight = lighting_getSpotLight(i);\n let light_position_worldspace: vec3<f32> = spotLight.position;\n let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);\n let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);\n lightColor += lighting_getLightColor(\n surfaceColor,\n light_direction,\n view_direction,\n normal_worldspace,\n spotLight.color / light_attenuation\n );\n }\n\n for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {\n let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);\n lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);\n }\n }\n return lightColor;\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {NumberArray3} from '@math.gl/types';\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\nimport {floatColors} from '../../color/float-colors';\nimport {lighting} from '../lights/lighting';\nimport {PHONG_VS, PHONG_FS} from '../phong-material/phong-shaders-glsl';\nimport {PHONG_WGSL} from '../phong-material/phong-shaders-wgsl';\n\nexport type GouraudMaterialProps = {\n unlit?: boolean;\n ambient?: number;\n diffuse?: number;\n /** Specularity exponent */\n shininess?: number;\n specularColor?: [number, number, number];\n};\n\nconst DEFAULT_SPECULAR_COLOR: NumberArray3 = [38.25, 38.25, 38.25];\n\n/** In Gouraud shading, color is calculated for each triangle vertex normal, and then color is interpolated colors across the triangle */\nexport const gouraudMaterial: ShaderModule<GouraudMaterialProps> = {\n props: {} as GouraudMaterialProps,\n\n name: 'gouraudMaterial',\n bindingLayout: [{name: 'gouraudMaterial', group: 3}],\n // Note these are switched between phong and gouraud\n vs: PHONG_FS.replace('phongMaterial', 'gouraudMaterial'),\n fs: PHONG_VS.replace('phongMaterial', 'gouraudMaterial'),\n source: PHONG_WGSL.replaceAll('phongMaterial', 'gouraudMaterial'),\n defines: {\n LIGHTING_VERTEX: true\n },\n dependencies: [lighting, floatColors],\n uniformTypes: {\n unlit: 'i32',\n ambient: 'f32',\n diffuse: 'f32',\n shininess: 'f32',\n specularColor: 'vec3<f32>'\n },\n defaultUniforms: {\n unlit: false,\n ambient: 0.35,\n diffuse: 0.6,\n shininess: 32,\n specularColor: DEFAULT_SPECULAR_COLOR\n },\n\n getUniforms(props: GouraudMaterialProps) {\n return {...gouraudMaterial.defaultUniforms, ...props};\n }\n};\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {NumberArray3} from '@math.gl/types';\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\nimport {floatColors} from '../../color/float-colors';\nimport {lighting} from '../lights/lighting';\nimport {PHONG_WGSL} from './phong-shaders-wgsl';\nimport {PHONG_VS, PHONG_FS} from './phong-shaders-glsl';\n\nexport type PhongMaterialProps = {\n unlit?: boolean;\n ambient?: number;\n diffuse?: number;\n /** Specularity exponent */\n shininess?: number;\n specularColor?: NumberArray3;\n};\n\nconst DEFAULT_SPECULAR_COLOR: NumberArray3 = [38.25, 38.25, 38.25];\n\n/** In Phong shading, the normal vector is linearly interpolated across the surface of the polygon from the polygon's vertex normals. */\nexport const phongMaterial: ShaderModule<PhongMaterialProps> = {\n name: 'phongMaterial',\n firstBindingSlot: 0,\n bindingLayout: [{name: 'phongMaterial', group: 3}],\n dependencies: [lighting, floatColors],\n // Note these are switched between phong and gouraud\n source: PHONG_WGSL,\n vs: PHONG_VS,\n fs: PHONG_FS,\n defines: {\n LIGHTING_FRAGMENT: true\n },\n uniformTypes: {\n unlit: 'i32',\n ambient: 'f32',\n diffuse: 'f32',\n shininess: 'f32',\n specularColor: 'vec3<f32>'\n },\n defaultUniforms: {\n unlit: false,\n ambient: 0.35,\n diffuse: 0.6,\n shininess: 32,\n specularColor: DEFAULT_SPECULAR_COLOR\n },\n getUniforms(props?: PhongMaterialProps) {\n return {...phongMaterial.defaultUniforms, ...props};\n }\n};\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// Attribution:\n// MIT license, Copyright (c) 2016-2017 Mohamad Moneimne and Contributors\n// This fragment shader defines a reference implementation for Physically Based Shading of\n// a microfacet surface material defined by a glTF model.\n\n// TODO - better do the checks outside of shader\n\nexport const vs = /* glsl */ `\\\nout vec3 pbr_vPosition;\nout vec2 pbr_vUV0;\nout vec2 pbr_vUV1;\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(\n vec4 position,\n vec4 normal,\n vec4 tangent,\n vec2 uv0,\n vec2 uv1\n)\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_vUV0 = uv0;\n#else\n pbr_vUV0 = vec2(0.,0.);\n#endif\n\n pbr_vUV1 = uv1;\n}\n`;\n\nexport const fs = /* glsl */ `\\\nprecision highp float;\n\nlayout(std140) uniform 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 vec3 specularColorFactor;\n float specularIntensityFactor;\n bool specularColorMapEnabled;\n bool specularIntensityMapEnabled;\n\n float ior;\n\n float transmissionFactor;\n bool transmissionMapEnabled;\n\n float thicknessFactor;\n float attenuationDistance;\n vec3 attenuationColor;\n\n float clearcoatFactor;\n float clearcoatRoughnessFactor;\n bool clearcoatMapEnabled;\n bool clearcoatRoughnessMapEnabled;\n\n vec3 sheenColorFactor;\n float sheenRoughnessFactor;\n bool sheenColorMapEnabled;\n bool sheenRoughnessMapEnabled;\n\n float iridescenceFactor;\n float iridescenceIor;\n vec2 iridescenceThicknessRange;\n bool iridescenceMapEnabled;\n\n float anisotropyStrength;\n float anisotropyRotation;\n vec2 anisotropyDirection;\n bool anisotropyMapEnabled;\n\n float emissiveStrength;\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 int baseColorUVSet;\n mat3 baseColorUVTransform;\n int metallicRoughnessUVSet;\n mat3 metallicRoughnessUVTransform;\n int normalUVSet;\n mat3 normalUVTransform;\n int occlusionUVSet;\n mat3 occlusionUVTransform;\n int emissiveUVSet;\n mat3 emissiveUVTransform;\n int specularColorUVSet;\n mat3 specularColorUVTransform;\n int specularIntensityUVSet;\n mat3 specularIntensityUVTransform;\n int transmissionUVSet;\n mat3 transmissionUVTransform;\n int thicknessUVSet;\n mat3 thicknessUVTransform;\n int clearcoatUVSet;\n mat3 clearcoatUVTransform;\n int clearcoatRoughnessUVSet;\n mat3 clearcoatRoughnessUVTransform;\n int clearcoatNormalUVSet;\n mat3 clearcoatNormalUVTransform;\n int sheenColorUVSet;\n mat3 sheenColorUVTransform;\n int sheenRoughnessUVSet;\n mat3 sheenRoughnessUVTransform;\n int iridescenceUVSet;\n mat3 iridescenceUVTransform;\n int iridescenceThicknessUVSet;\n mat3 iridescenceThicknessUVTransform;\n int anisotropyUVSet;\n mat3 anisotropyUVTransform;\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 HAS_SPECULARCOLORMAP\nuniform sampler2D pbr_specularColorSampler;\n#endif\n#ifdef HAS_SPECULARINTENSITYMAP\nuniform sampler2D pbr_specularIntensitySampler;\n#endif\n#ifdef HAS_TRANSMISSIONMAP\nuniform sampler2D pbr_transmissionSampler;\n#endif\n#ifdef HAS_THICKNESSMAP\nuniform sampler2D pbr_thicknessSampler;\n#endif\n#ifdef HAS_CLEARCOATMAP\nuniform sampler2D pbr_clearcoatSampler;\n#endif\n#ifdef HAS_CLEARCOATROUGHNESSMAP\nuniform sampler2D pbr_clearcoatRoughnessSampler;\n#endif\n#ifdef HAS_CLEARCOATNORMALMAP\nuniform sampler2D pbr_clearcoatNormalSampler;\n#endif\n#ifdef HAS_SHEENCOLORMAP\nuniform sampler2D pbr_sheenColorSampler;\n#endif\n#ifdef HAS_SHEENROUGHNESSMAP\nuniform sampler2D pbr_sheenRoughnessSampler;\n#endif\n#ifdef HAS_IRIDESCENCEMAP\nuniform sampler2D pbr_iridescenceSampler;\n#endif\n#ifdef HAS_IRIDESCENCETHICKNESSMAP\nuniform sampler2D pbr_iridescenceThicknessSampler;\n#endif\n#ifdef HAS_ANISOTROPYMAP\nuniform sampler2D pbr_anisotropySampler;\n#endif\n// Inputs from vertex shader\n\nin vec3 pbr_vPosition;\nin vec2 pbr_vUV0;\nin vec2 pbr_vUV1;\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\nvec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor);\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\nvec2 getMaterialUV(int uvSet, mat3 uvTransform)\n{\n vec2 baseUV = uvSet == 1 ? pbr_vUV1 : pbr_vUV0;\n return (uvTransform * vec3(baseUV, 1.0)).xy;\n}\n\n// Build the tangent basis from interpolated attributes or screen-space derivatives.\nmat3 getTBN(vec2 uv)\n{\n#ifndef HAS_TANGENTS\n vec3 pos_dx = dFdx(pbr_vPosition);\n vec3 pos_dy = dFdy(pbr_vPosition);\n vec3 tex_dx = dFdx(vec3(uv, 0.0));\n vec3 tex_dy = dFdy(vec3(uv, 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 return tbn;\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 getMappedNormal(sampler2D normalSampler, mat3 tbn, float normalScale, vec2 uv)\n{\n vec3 n = texture(normalSampler, uv).rgb;\n return normalize(tbn * ((2.0 * n - 1.0) * vec3(normalScale, normalScale, 1.0)));\n}\n\nvec3 getNormal(mat3 tbn, vec2 uv)\n{\n#ifdef HAS_NORMALMAP\n vec3 n = getMappedNormal(pbr_normalSampler, tbn, pbrMaterial.normalScale, uv);\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\nvec3 getClearcoatNormal(mat3 tbn, vec3 baseNormal, vec2 uv)\n{\n#ifdef HAS_CLEARCOATNORMALMAP\n return getMappedNormal(pbr_clearcoatNormalSampler, tbn, 1.0, uv);\n#else\n return baseNormal;\n#endif\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\nfloat maxComponent(vec3 value)\n{\n return max(max(value.r, value.g), value.b);\n}\n\nfloat getDielectricF0(float ior)\n{\n float clampedIor = max(ior, 1.0);\n float ratio = (clampedIor - 1.0) / (clampedIor + 1.0);\n return ratio * ratio;\n}\n\nvec2 normalizeDirection(vec2 direction)\n{\n float directionLength = length(direction);\n return directionLength > 0.0001 ? direction / directionLength : vec2(1.0, 0.0);\n}\n\nvec2 rotateDirection(vec2 direction, float rotation)\n{\n float s = sin(rotation);\n float c = cos(rotation);\n return vec2(direction.x * c - direction.y * s, direction.x * s + direction.y * c);\n}\n\nvec3 getIridescenceTint(float iridescence, float thickness, float NdotV)\n{\n if (iridescence <= 0.0) {\n return vec3(1.0);\n }\n\n float phase = 0.015 * thickness * pbrMaterial.iridescenceIor + (1.0 - NdotV) * 6.0;\n vec3 thinFilmTint =\n 0.5 + 0.5 * cos(vec3(phase, phase + 2.0943951, phase + 4.1887902));\n return mix(vec3(1.0), thinFilmTint, iridescence);\n}\n\nvec3 getVolumeAttenuation(float thickness)\n{\n if (thickness <= 0.0) {\n return vec3(1.0);\n }\n\n vec3 attenuationCoefficient =\n -log(max(pbrMaterial.attenuationColor, vec3(0.0001))) /\n max(pbrMaterial.attenuationDistance, 0.0001);\n return exp(-attenuationCoefficient * thickness);\n}\n\nPBRInfo createClearcoatPBRInfo(PBRInfo basePBRInfo, vec3 clearcoatNormal, float clearcoatRoughness)\n{\n float perceptualRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);\n float alphaRoughness = perceptualRoughness * perceptualRoughness;\n float NdotV = clamp(abs(dot(clearcoatNormal, basePBRInfo.v)), 0.001, 1.0);\n\n return PBRInfo(\n basePBRInfo.NdotL,\n NdotV,\n basePBRInfo.NdotH,\n basePBRInfo.LdotH,\n basePBRInfo.VdotH,\n perceptualRoughness,\n 0.0,\n vec3(0.04),\n vec3(1.0),\n alphaRoughness,\n vec3(0.0),\n vec3(0.04),\n clearcoatNormal,\n basePBRInfo.v\n );\n}\n\nvec3 calculateClearcoatContribution(\n PBRInfo pbrInfo,\n vec3 lightColor,\n vec3 clearcoatNormal,\n float clearcoatFactor,\n float clearcoatRoughness\n) {\n if (clearcoatFactor <= 0.0) {\n return vec3(0.0);\n }\n\n PBRInfo clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);\n return calculateFinalColor(clearcoatPBRInfo, lightColor) * clearcoatFactor;\n}\n\n#ifdef USE_IBL\nvec3 calculateClearcoatIBLContribution(\n PBRInfo pbrInfo,\n vec3 clearcoatNormal,\n vec3 reflection,\n float clearcoatFactor,\n float clearcoatRoughness\n) {\n if (clearcoatFactor <= 0.0) {\n return vec3(0.0);\n }\n\n PBRInfo clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);\n return getIBLContribution(clearcoatPBRInfo, clearcoatNormal, reflection) * clearcoatFactor;\n}\n#endif\n\nvec3 calculateSheenContribution(\n PBRInfo pbrInfo,\n vec3 lightColor,\n vec3 sheenColor,\n float sheenRoughness\n) {\n if (maxComponent(sheenColor) <= 0.0) {\n return vec3(0.0);\n }\n\n float sheenFresnel = pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);\n float sheenVisibility = mix(1.0, pbrInfo.NdotL * pbrInfo.NdotV, sheenRoughness);\n return pbrInfo.NdotL *\n lightColor *\n sheenColor *\n (0.25 + 0.75 * sheenFresnel) *\n sheenVisibility *\n (1.0 - pbrInfo.metalness);\n}\n\nfloat calculateAnisotropyBoost(\n PBRInfo pbrInfo,\n vec3 anisotropyTangent,\n float anisotropyStrength\n) {\n if (anisotropyStrength <= 0.0) {\n return 1.0;\n }\n\n vec3 anisotropyBitangent = normalize(cross(pbrInfo.n, anisotropyTangent));\n float bitangentViewAlignment = abs(dot(pbrInfo.v, anisotropyBitangent));\n return mix(1.0, 0.65 + 0.7 * bitangentViewAlignment, anisotropyStrength);\n}\n\nvec3 calculateMaterialLightColor(\n PBRInfo pbrInfo,\n vec3 lightColor,\n vec3 clearcoatNormal,\n float clearcoatFactor,\n float clearcoatRoughness,\n vec3 sheenColor,\n float sheenRoughness,\n vec3 anisotropyTangent,\n float anisotropyStrength\n) {\n float anisotropyBoost = calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);\n vec3 color = calculateFinalColor(pbrInfo, lightColor) * anisotropyBoost;\n color += calculateClearcoatContribution(\n pbrInfo,\n lightColor,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness\n );\n color += calculateSheenContribution(pbrInfo, lightColor, sheenColor, sheenRoughness);\n return color;\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\nvoid PBRInfo_setSpotLight(inout PBRInfo pbrInfo, SpotLight spotLight) {\n vec3 light_direction = normalize(spotLight.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 vec2 baseColorUV = getMaterialUV(pbrMaterial.baseColorUVSet, pbrMaterial.baseColorUVTransform);\n vec2 metallicRoughnessUV = getMaterialUV(\n pbrMaterial.metallicRoughnessUVSet,\n pbrMaterial.metallicRoughnessUVTransform\n );\n vec2 normalUV = getMaterialUV(pbrMaterial.normalUVSet, pbrMaterial.normalUVTransform);\n vec2 occlusionUV = getMaterialUV(pbrMaterial.occlusionUVSet, pbrMaterial.occlusionUVTransform);\n vec2 emissiveUV = getMaterialUV(pbrMaterial.emissiveUVSet, pbrMaterial.emissiveUVTransform);\n vec2 specularColorUV = getMaterialUV(\n pbrMaterial.specularColorUVSet,\n pbrMaterial.specularColorUVTransform\n );\n vec2 specularIntensityUV = getMaterialUV(\n pbrMaterial.specularIntensityUVSet,\n pbrMaterial.specularIntensityUVTransform\n );\n vec2 transmissionUV = getMaterialUV(\n pbrMaterial.transmissionUVSet,\n pbrMaterial.transmissionUVTransform\n );\n vec2 thicknessUV = getMaterialUV(pbrMaterial.thicknessUVSet, pbrMaterial.thicknessUVTransform);\n vec2 clearcoatUV = getMaterialUV(pbrMaterial.clearcoatUVSet, pbrMaterial.clearcoatUVTransform);\n vec2 clearcoatRoughnessUV = getMaterialUV(\n pbrMaterial.clearcoatRoughnessUVSet,\n pbrMaterial.clearcoatRoughnessUVTransform\n );\n vec2 clearcoatNormalUV = getMaterialUV(\n pbrMaterial.clearcoatNormalUVSet,\n pbrMaterial.clearcoatNormalUVTransform\n );\n vec2 sheenColorUV = getMaterialUV(\n pbrMaterial.sheenColorUVSet,\n pbrMaterial.sheenColorUVTransform\n );\n vec2 sheenRoughnessUV = getMaterialUV(\n pbrMaterial.sheenRoughnessUVSet,\n pbrMaterial.sheenRoughnessUVTransform\n );\n vec2 iridescenceUV = getMaterialUV(\n pbrMaterial.iridescenceUVSet,\n pbrMaterial.iridescenceUVTransform\n );\n vec2 iridescenceThicknessUV = getMaterialUV(\n pbrMaterial.iridescenceThicknessUVSet,\n pbrMaterial.iridescenceThicknessUVTransform\n );\n vec2 anisotropyUV = getMaterialUV(\n pbrMaterial.anisotropyUVSet,\n pbrMaterial.anisotropyUVTransform\n );\n\n // The albedo may be defined from a base texture or a flat color\n#ifdef HAS_BASECOLORMAP\n vec4 baseColor =\n SRGBtoLINEAR(texture(pbr_baseColorSampler, baseColorUV)) * 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 float transmission = 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, metallicRoughnessUV);\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 mat3 tbn = getTBN(normalUV);\n vec3 n = getNormal(tbn, normalUV); // normal at surface point\n vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera\n float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);\n#ifdef USE_MATERIAL_EXTENSIONS\n bool useExtendedPBR =\n pbrMaterial.specularColorMapEnabled ||\n pbrMaterial.specularIntensityMapEnabled ||\n abs(pbrMaterial.specularIntensityFactor - 1.0) > 0.0001 ||\n maxComponent(abs(pbrMaterial.specularColorFactor - vec3(1.0))) > 0.0001 ||\n abs(pbrMaterial.ior - 1.5) > 0.0001 ||\n pbrMaterial.transmissionMapEnabled ||\n pbrMaterial.transmissionFactor > 0.0001 ||\n pbrMaterial.clearcoatMapEnabled ||\n pbrMaterial.clearcoatRoughnessMapEnabled ||\n pbrMaterial.clearcoatFactor > 0.0001 ||\n pbrMaterial.clearcoatRoughnessFactor > 0.0001 ||\n pbrMaterial.sheenColorMapEnabled ||\n pbrMaterial.sheenRoughnessMapEnabled ||\n maxComponent(pbrMaterial.sheenColorFactor) > 0.0001 ||\n pbrMaterial.sheenRoughnessFactor > 0.0001 ||\n pbrMaterial.iridescenceMapEnabled ||\n pbrMaterial.iridescenceFactor > 0.0001 ||\n abs(pbrMaterial.iridescenceIor - 1.3) > 0.0001 ||\n abs(pbrMaterial.iridescenceThicknessRange.x - 100.0) > 0.0001 ||\n abs(pbrMaterial.iridescenceThicknessRange.y - 400.0) > 0.0001 ||\n pbrMaterial.anisotropyMapEnabled ||\n pbrMaterial.anisotropyStrength > 0.0001 ||\n abs(pbrMaterial.anisotropyRotation) > 0.0001 ||\n length(pbrMaterial.anisotropyDirection - vec2(1.0, 0.0)) > 0.0001;\n#else\n bool useExtendedPBR = false;\n#endif\n\n if (!useExtendedPBR) {\n // Keep the baseline metallic-roughness implementation byte-for-byte equivalent in behavior.\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 float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);\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 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#ifdef USE_LIGHTS\n PBRInfo_setAmbientLight(pbrInfo);\n color += calculateFinalColor(pbrInfo, lighting.ambientColor);\n\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 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\n for(int i = 0; i < lighting.spotLightCount; i++) {\n if (i < lighting.spotLightCount) {\n PBRInfo_setSpotLight(pbrInfo, lighting_getSpotLight(i));\n float attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), pbr_vPosition);\n color += calculateFinalColor(pbrInfo, lighting_getSpotLight(i).color / attenuation);\n }\n }\n#endif\n\n#ifdef USE_IBL\n if (pbrMaterial.IBLenabled) {\n color += getIBLContribution(pbrInfo, n, reflection);\n }\n#endif\n\n#ifdef HAS_OCCLUSIONMAP\n if (pbrMaterial.occlusionMapEnabled) {\n float ao = texture(pbr_occlusionSampler, occlusionUV).r;\n color = mix(color, color * ao, pbrMaterial.occlusionStrength);\n }\n#endif\n\n vec3 emissive = pbrMaterial.emissiveFactor;\n#ifdef HAS_EMISSIVEMAP\n if (pbrMaterial.emissiveMapEnabled) {\n emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, emissiveUV)).rgb;\n }\n#endif\n color += emissive * pbrMaterial.emissiveStrength;\n\n#ifdef PBR_DEBUG\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 return vec4(pow(color, vec3(1.0 / 2.2)), baseColor.a);\n }\n\n float specularIntensity = pbrMaterial.specularIntensityFactor;\n#ifdef HAS_SPECULARINTENSITYMAP\n if (pbrMaterial.specularIntensityMapEnabled) {\n specularIntensity *= texture(pbr_specularIntensitySampler, specularIntensityUV).a;\n }\n#endif\n\n vec3 specularFactor = pbrMaterial.specularColorFactor;\n#ifdef HAS_SPECULARCOLORMAP\n if (pbrMaterial.specularColorMapEnabled) {\n specularFactor *= SRGBtoLINEAR(texture(pbr_specularColorSampler, specularColorUV)).rgb;\n }\n#endif\n\n transmission = pbrMaterial.transmissionFactor;\n#ifdef HAS_TRANSMISSIONMAP\n if (pbrMaterial.transmissionMapEnabled) {\n transmission *= texture(pbr_transmissionSampler, transmissionUV).r;\n }\n#endif\n transmission = clamp(transmission * (1.0 - metallic), 0.0, 1.0);\n float thickness = max(pbrMaterial.thicknessFactor, 0.0);\n#ifdef HAS_THICKNESSMAP\n thickness *= texture(pbr_thicknessSampler, thicknessUV).g;\n#endif\n\n float clearcoatFactor = pbrMaterial.clearcoatFactor;\n float clearcoatRoughness = pbrMaterial.clearcoatRoughnessFactor;\n#ifdef HAS_CLEARCOATMAP\n if (pbrMaterial.clearcoatMapEnabled) {\n clearcoatFactor *= texture(pbr_clearcoatSampler, clearcoatUV).r;\n }\n#endif\n#ifdef HAS_CLEARCOATROUGHNESSMAP\n if (pbrMaterial.clearcoatRoughnessMapEnabled) {\n clearcoatRoughness *= texture(pbr_clearcoatRoughnessSampler, clearcoatRoughnessUV).g;\n }\n#endif\n clearcoatFactor = clamp(clearcoatFactor, 0.0, 1.0);\n clearcoatRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);\n vec3 clearcoatNormal = getClearcoatNormal(getTBN(clearcoatNormalUV), n, clearcoatNormalUV);\n\n vec3 sheenColor = pbrMaterial.sheenColorFactor;\n float sheenRoughness = pbrMaterial.sheenRoughnessFactor;\n#ifdef HAS_SHEENCOLORMAP\n if (pbrMaterial.sheenColorMapEnabled) {\n sheenColor *= SRGBtoLINEAR(texture(pbr_sheenColorSampler, sheenColorUV)).rgb;\n }\n#endif\n#ifdef HAS_SHEENROUGHNESSMAP\n if (pbrMaterial.sheenRoughnessMapEnabled) {\n sheenRoughness *= texture(pbr_sheenRoughnessSampler, sheenRoughnessUV).a;\n }\n#endif\n sheenRoughness = clamp(sheenRoughness, c_MinRoughness, 1.0);\n\n float iridescence = pbrMaterial.iridescenceFactor;\n#ifdef HAS_IRIDESCENCEMAP\n if (pbrMaterial.iridescenceMapEnabled) {\n iridescence *= texture(pbr_iridescenceSampler, iridescenceUV).r;\n }\n#endif\n iridescence = clamp(iridescence, 0.0, 1.0);\n float iridescenceThickness = mix(\n pbrMaterial.iridescenceThicknessRange.x,\n pbrMaterial.iridescenceThicknessRange.y,\n 0.5\n );\n#ifdef HAS_IRIDESCENCETHICKNESSMAP\n iridescenceThickness = mix(\n pbrMaterial.iridescenceThicknessRange.x,\n pbrMaterial.iridescenceThicknessRange.y,\n texture(pbr_iridescenceThicknessSampler, iridescenceThicknessUV).g\n );\n#endif\n\n float anisotropyStrength = clamp(pbrMaterial.anisotropyStrength, 0.0, 1.0);\n vec2 anisotropyDirection = normalizeDirection(pbrMaterial.anisotropyDirection);\n#ifdef HAS_ANISOTROPYMAP\n if (pbrMaterial.anisotropyMapEnabled) {\n vec3 anisotropySample = texture(pbr_anisotropySampler, anisotropyUV).rgb;\n anisotropyStrength *= anisotropySample.b;\n vec2 mappedDirection = anisotropySample.rg * 2.0 - 1.0;\n if (length(mappedDirection) > 0.0001) {\n anisotropyDirection = normalize(mappedDirection);\n }\n }\n#endif\n anisotropyDirection = rotateDirection(anisotropyDirection, pbrMaterial.anisotropyRotation);\n vec3 anisotropyTangent = normalize(tbn[0] * anisotropyDirection.x + tbn[1] * anisotropyDirection.y);\n if (length(anisotropyTangent) < 0.0001) {\n anisotropyTangent = normalize(tbn[0]);\n }\n float anisotropyViewAlignment = abs(dot(v, anisotropyTangent));\n perceptualRoughness = mix(\n perceptualRoughness,\n clamp(perceptualRoughness * (1.0 - 0.6 * anisotropyViewAlignment), c_MinRoughness, 1.0),\n anisotropyStrength\n );\n\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 float dielectricF0 = getDielectricF0(pbrMaterial.ior);\n vec3 dielectricSpecularF0 = min(\n vec3(dielectricF0) * specularFactor * specularIntensity,\n vec3(1.0)\n );\n vec3 iridescenceTint = getIridescenceTint(iridescence, iridescenceThickness, NdotV);\n dielectricSpecularF0 = mix(\n dielectricSpecularF0,\n dielectricSpecularF0 * iridescenceTint,\n iridescence\n );\n vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - dielectricSpecularF0);\n diffuseColor *= (1.0 - metallic) * (1.0 - transmission);\n vec3 specularColor = mix(dielectricSpecularF0, baseColor.rgb, metallic);\n\n float baseLayerEnergy = 1.0 - clearcoatFactor * 0.25;\n diffuseColor *= baseLayerEnergy;\n specularColor *= baseLayerEnergy;\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 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 += calculateMaterialLightColor(\n pbrInfo,\n lighting.ambientColor,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness,\n sheenColor,\n sheenRoughness,\n anisotropyTangent,\n anisotropyStrength\n );\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 += calculateMaterialLightColor(\n pbrInfo,\n lighting_getDirectionalLight(i).color,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness,\n sheenColor,\n sheenRoughness,\n anisotropyTangent,\n anisotropyStrength\n );\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 += calculateMaterialLightColor(\n pbrInfo,\n lighting_getPointLight(i).color / attenuation,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness,\n sheenColor,\n sheenRoughness,\n anisotropyTangent,\n anisotropyStrength\n );\n }\n }\n\n for(int i = 0; i < lighting.spotLightCount; i++) {\n if (i < lighting.spotLightCount) {\n PBRInfo_setSpotLight(pbrInfo, lighting_getSpotLight(i));\n float attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), pbr_vPosition);\n color += calculateMaterialLightColor(\n pbrInfo,\n lighting_getSpotLight(i).color / attenuation,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness,\n sheenColor,\n sheenRoughness,\n anisotropyTangent,\n anisotropyStrength\n );\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 calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);\n color += calculateClearcoatIBLContribution(\n pbrInfo,\n clearcoatNormal,\n -normalize(reflect(v, clearcoatNormal)),\n clearcoatFactor,\n clearcoatRoughness\n );\n color += sheenColor * pbrMaterial.scaleIBLAmbient.x * (1.0 - sheenRoughness) * 0.25;\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, occlusionUV).r;\n color = mix(color, color * ao, pbrMaterial.occlusionStrength);\n }\n#endif\n\n vec3 emissive = pbrMaterial.emissiveFactor;\n#ifdef HAS_EMISSIVEMAP\n if (pbrMaterial.emissiveMapEnabled) {\n emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, emissiveUV)).rgb;\n }\n#endif\n color += emissive * pbrMaterial.emissiveStrength;\n\n if (transmission > 0.0) {\n color = mix(color, color * getVolumeAttenuation(thickness), transmission);\n }\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 float alpha = clamp(baseColor.a * (1.0 - transmission), 0.0, 1.0);\n return vec4(pow(color,vec3(1.0/2.2)), alpha);\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// Attribution:\n// MIT license, Copyright (c) 2016-2017 Mohamad Moneimne and Contributors\n// This fragment shader defines a reference implementation for Physically Based Shading of\n// a microfacet surface material defined by a glTF model.\n\n// TODO - better do the checks outside of shader\n\nexport const pbrMaterialUniforms = /* wgsl */ `\\\nuniform 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 vec3 specularColorFactor;\n float specularIntensityFactor;\n bool specularColorMapEnabled;\n bool specularIntensityMapEnabled;\n\n float ior;\n\n float transmissionFactor;\n bool transmissionMapEnabled;\n\n float thicknessFactor;\n float attenuationDistance;\n vec3 attenuationColor;\n\n float clearcoatFactor;\n float clearcoatRoughnessFactor;\n bool clearcoatMapEnabled;\n bool clearcoatRoughnessMapEnabled;\n\n vec3 sheenColorFactor;\n float sheenRoughnessFactor;\n bool sheenColorMapEnabled;\n bool sheenRoughnessMapEnabled;\n\n float iridescenceFactor;\n float iridescenceIor;\n vec2 iridescenceThicknessRange;\n bool iridescenceMapEnabled;\n\n float anisotropyStrength;\n float anisotropyRotation;\n vec2 anisotropyDirection;\n bool anisotropyMapEnabled;\n\n float emissiveStrength;\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 HAS_SPECULARCOLORMAP\nuniform sampler2D u_SpecularColorSampler;\n#endif\n#ifdef HAS_SPECULARINTENSITYMAP\nuniform sampler2D u_SpecularIntensitySampler;\n#endif\n#ifdef HAS_TRANSMISSIONMAP\nuniform sampler2D u_TransmissionSampler;\n#endif\n#ifdef HAS_THICKNESSMAP\nuniform sampler2D u_ThicknessSampler;\n#endif\n#ifdef HAS_CLEARCOATMAP\nuniform sampler2D u_ClearcoatSampler;\n#endif\n#ifdef HAS_CLEARCOATROUGHNESSMAP\nuniform sampler2D u_ClearcoatRoughnessSampler;\n#endif\n#ifdef HAS_CLEARCOATNORMALMAP\nuniform sampler2D u_ClearcoatNormalSampler;\n#endif\n#ifdef HAS_SHEENCOLORMAP\nuniform sampler2D u_SheenColorSampler;\n#endif\n#ifdef HAS_SHEENROUGHNESSMAP\nuniform sampler2D u_SheenRoughnessSampler;\n#endif\n#ifdef HAS_IRIDESCENCEMAP\nuniform sampler2D u_IridescenceSampler;\n#endif\n#ifdef HAS_IRIDESCENCETHICKNESSMAP\nuniform sampler2D u_IridescenceThicknessSampler;\n#endif\n#ifdef HAS_ANISOTROPYMAP\nuniform sampler2D u_AnisotropySampler;\n#endif\n#ifdef USE_IBL\nuniform samplerCube u_DiffuseEnvSampler;\nuniform samplerCube u_SpecularEnvSampler;\nuniform sampler2D u_brdfLUT;\n#endif\n\n`;\n\nexport const source = /* wgsl */ `\\\nstruct PBRFragmentInputs {\n pbr_vPosition: vec3f,\n pbr_vUV0: vec2f,\n pbr_vUV1: vec2f,\n pbr_vTBN: mat3x3f,\n pbr_vNormal: vec3f\n};\n\nvar<private> fragmentInputs: PBRFragmentInputs;\n\nfn pbr_setPositionNormalTangentUV(\n position: vec4f,\n normal: vec4f,\n tangent: vec4f,\n uv0: vec2f,\n uv1: vec2f\n)\n{\n var pos: vec4f = pbrProjection.modelMatrix * position;\n fragmentInputs.pbr_vPosition = pos.xyz / pos.w;\n fragmentInputs.pbr_vNormal = vec3f(0.0, 0.0, 1.0);\n fragmentInputs.pbr_vTBN = mat3x3f(\n vec3f(1.0, 0.0, 0.0),\n vec3f(0.0, 1.0, 0.0),\n vec3f(0.0, 0.0, 1.0)\n );\n fragmentInputs.pbr_vUV0 = vec2f(0.0, 0.0);\n fragmentInputs.pbr_vUV1 = uv1;\n\n#ifdef HAS_NORMALS\n let normalW: vec3f = normalize((pbrProjection.normalMatrix * vec4f(normal.xyz, 0.0)).xyz);\n fragmentInputs.pbr_vNormal = normalW;\n#ifdef HAS_TANGENTS\n let tangentW: vec3f = normalize((pbrProjection.modelMatrix * vec4f(tangent.xyz, 0.0)).xyz);\n let bitangentW: vec3f = cross(normalW, tangentW) * tangent.w;\n fragmentInputs.pbr_vTBN = mat3x3f(tangentW, bitangentW, normalW);\n#endif\n#endif\n\n#ifdef HAS_UV\n fragmentInputs.pbr_vUV0 = uv0;\n#endif\n}\n\nstruct pbrMaterialUniforms {\n // Material is unlit\n unlit: u32,\n\n // Base color map\n baseColorMapEnabled: u32,\n baseColorFactor: vec4f,\n\n normalMapEnabled : u32,\n normalScale: f32, // #ifdef HAS_NORMALMAP\n\n emissiveMapEnabled: u32,\n emissiveFactor: vec3f, // #ifdef HAS_EMISSIVEMAP\n\n metallicRoughnessValues: vec2f,\n metallicRoughnessMapEnabled: u32,\n\n occlusionMapEnabled: i32,\n occlusionStrength: f32, // #ifdef HAS_OCCLUSIONMAP\n \n alphaCutoffEnabled: i32,\n alphaCutoff: f32, // #ifdef ALPHA_CUTOFF\n\n specularColorFactor: vec3f,\n specularIntensityFactor: f32,\n specularColorMapEnabled: i32,\n specularIntensityMapEnabled: i32,\n\n ior: f32,\n\n transmissionFactor: f32,\n transmissionMapEnabled: i32,\n\n thicknessFactor: f32,\n attenuationDistance: f32,\n attenuationColor: vec3f,\n\n clearcoatFactor: f32,\n clearcoatRoughnessFactor: f32,\n clearcoatMapEnabled: i32,\n clearcoatRoughnessMapEnabled: i32,\n\n sheenColorFactor: vec3f,\n sheenRoughnessFactor: f32,\n sheenColorMapEnabled: i32,\n sheenRoughnessMapEnabled: i32,\n\n iridescenceFactor: f32,\n iridescenceIor: f32,\n iridescenceThicknessRange: vec2f,\n iridescenceMapEnabled: i32,\n\n anisotropyStrength: f32,\n anisotropyRotation: f32,\n anisotropyDirection: vec2f,\n anisotropyMapEnabled: i32,\n\n emissiveStrength: f32,\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 baseColorUVSet: i32,\n baseColorUVTransform: mat3x3f,\n metallicRoughnessUVSet: i32,\n metallicRoughnessUVTransform: mat3x3f,\n normalUVSet: i32,\n normalUVTransform: mat3x3f,\n occlusionUVSet: i32,\n occlusionUVTransform: mat3x3f,\n emissiveUVSet: i32,\n emissiveUVTransform: mat3x3f,\n specularColorUVSet: i32,\n specularColorUVTransform: mat3x3f,\n specularIntensityUVSet: i32,\n specularIntensityUVTransform: mat3x3f,\n transmissionUVSet: i32,\n transmissionUVTransform: mat3x3f,\n thicknessUVSet: i32,\n thicknessUVTransform: mat3x3f,\n clearcoatUVSet: i32,\n clearcoatUVTransform: mat3x3f,\n clearcoatRoughnessUVSet: i32,\n clearcoatRoughnessUVTransform: mat3x3f,\n clearcoatNormalUVSet: i32,\n clearcoatNormalUVTransform: mat3x3f,\n sheenColorUVSet: i32,\n sheenColorUVTransform: mat3x3f,\n sheenRoughnessUVSet: i32,\n sheenRoughnessUVTransform: mat3x3f,\n iridescenceUVSet: i32,\n iridescenceUVTransform: mat3x3f,\n iridescenceThicknessUVSet: i32,\n iridescenceThicknessUVTransform: mat3x3f,\n anisotropyUVSet: i32,\n anisotropyUVTransform: mat3x3f,\n}\n\n@group(3) @binding(auto) var<uniform> pbrMaterial : pbrMaterialUniforms;\n\n// Samplers\n#ifdef HAS_BASECOLORMAP\n@group(3) @binding(auto) var pbr_baseColorSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_baseColorSamplerSampler: sampler;\n#endif\n#ifdef HAS_NORMALMAP\n@group(3) @binding(auto) var pbr_normalSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_normalSamplerSampler: sampler;\n#endif\n#ifdef HAS_EMISSIVEMAP\n@group(3) @binding(auto) var pbr_emissiveSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_emissiveSamplerSampler: sampler;\n#endif\n#ifdef HAS_METALROUGHNESSMAP\n@group(3) @binding(auto) var pbr_metallicRoughnessSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_metallicRoughnessSamplerSampler: sampler;\n#endif\n#ifdef HAS_OCCLUSIONMAP\n@group(3) @binding(auto) var pbr_occlusionSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_occlusionSamplerSampler: sampler;\n#endif\n#ifdef HAS_SPECULARCOLORMAP\n@group(3) @binding(auto) var pbr_specularColorSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_specularColorSamplerSampler: sampler;\n#endif\n#ifdef HAS_SPECULARINTENSITYMAP\n@group(3) @binding(auto) var pbr_specularIntensitySampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_specularIntensitySamplerSampler: sampler;\n#endif\n#ifdef HAS_TRANSMISSIONMAP\n@group(3) @binding(auto) var pbr_transmissionSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_transmissionSamplerSampler: sampler;\n#endif\n#ifdef HAS_THICKNESSMAP\n@group(3) @binding(auto) var pbr_thicknessSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_thicknessSamplerSampler: sampler;\n#endif\n#ifdef HAS_CLEARCOATMAP\n@group(3) @binding(auto) var pbr_clearcoatSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_clearcoatSamplerSampler: sampler;\n#endif\n#ifdef HAS_CLEARCOATROUGHNESSMAP\n@group(3) @binding(auto) var pbr_clearcoatRoughnessSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_clearcoatRoughnessSamplerSampler: sampler;\n#endif\n#ifdef HAS_CLEARCOATNORMALMAP\n@group(3) @binding(auto) var pbr_clearcoatNormalSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_clearcoatNormalSamplerSampler: sampler;\n#endif\n#ifdef HAS_SHEENCOLORMAP\n@group(3) @binding(auto) var pbr_sheenColorSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_sheenColorSamplerSampler: sampler;\n#endif\n#ifdef HAS_SHEENROUGHNESSMAP\n@group(3) @binding(auto) var pbr_sheenRoughnessSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_sheenRoughnessSamplerSampler: sampler;\n#endif\n#ifdef HAS_IRIDESCENCEMAP\n@group(3) @binding(auto) var pbr_iridescenceSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_iridescenceSamplerSampler: sampler;\n#endif\n#ifdef HAS_IRIDESCENCETHICKNESSMAP\n@group(3) @binding(auto) var pbr_iridescenceThicknessSampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_iridescenceThicknessSamplerSampler: sampler;\n#endif\n#ifdef HAS_ANISOTROPYMAP\n@group(3) @binding(auto) var pbr_anisotropySampler: texture_2d<f32>;\n@group(3) @binding(auto) var pbr_anisotropySamplerSampler: sampler;\n#endif\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 var linOut: vec3f = srgbIn.xyz;\n#ifdef MANUAL_SRGB\n let bLess: vec3f = step(vec3f(0.04045), srgbIn.xyz);\n linOut = mix(\n srgbIn.xyz / vec3f(12.92),\n pow((srgbIn.xyz + vec3f(0.055)) / vec3f(1.055), vec3f(2.4)),\n bLess\n );\n#ifdef SRGB_FAST_APPROXIMATION\n linOut = pow(srgbIn.xyz, vec3f(2.2));\n#endif\n#endif\n return vec4f(linOut, srgbIn.w);\n}\n\nfn getMaterialUV(uvSet: i32, uvTransform: mat3x3f) -> vec2f\n{\n var baseUV = fragmentInputs.pbr_vUV0;\n if (uvSet == 1) {\n baseUV = fragmentInputs.pbr_vUV1;\n }\n return (uvTransform * vec3f(baseUV, 1.0)).xy;\n}\n\n// Build the tangent basis from interpolated attributes or screen-space derivatives.\nfn getTBN(uv: vec2f) -> mat3x3f\n{\n let pos_dx: vec3f = dpdx(fragmentInputs.pbr_vPosition);\n let pos_dy: vec3f = dpdy(fragmentInputs.pbr_vPosition);\n let tex_dx: vec3f = dpdx(vec3f(uv, 0.0));\n let tex_dy: vec3f = dpdy(vec3f(uv, 0.0));\n var t: vec3f = (tex_dy.y * pos_dx - tex_dx.y * pos_dy) / (tex_dx.x * tex_dy.y - tex_dy.x * tex_dx.y);\n\n var ng: vec3f = cross(pos_dx, pos_dy);\n#ifdef HAS_NORMALS\n ng = normalize(fragmentInputs.pbr_vNormal);\n#endif\n t = normalize(t - ng * dot(ng, t));\n var b: vec3f = normalize(cross(ng, t));\n var tbn: mat3x3f = mat3x3f(t, b, ng);\n#ifdef HAS_TANGENTS\n tbn = fragmentInputs.pbr_vTBN;\n#endif\n\n return tbn;\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 getMappedNormal(\n normalSampler: texture_2d<f32>,\n normalSamplerBinding: sampler,\n tbn: mat3x3f,\n normalScale: f32,\n uv: vec2f\n) -> vec3f\n{\n let n = textureSample(normalSampler, normalSamplerBinding, uv).rgb;\n return normalize(tbn * ((2.0 * n - 1.0) * vec3f(normalScale, normalScale, 1.0)));\n}\n\nfn getNormal(tbn: mat3x3f, uv: vec2f) -> vec3f\n{\n // The tbn matrix is linearly interpolated, so we need to re-normalize\n var n: vec3f = normalize(tbn[2].xyz);\n#ifdef HAS_NORMALMAP\n n = getMappedNormal(\n pbr_normalSampler,\n pbr_normalSamplerSampler,\n tbn,\n pbrMaterial.normalScale,\n uv\n );\n#endif\n\n return n;\n}\n\nfn getClearcoatNormal(tbn: mat3x3f, baseNormal: vec3f, uv: vec2f) -> vec3f\n{\n#ifdef HAS_CLEARCOATNORMALMAP\n return getMappedNormal(\n pbr_clearcoatNormalSampler,\n pbr_clearcoatNormalSamplerSampler,\n tbn,\n 1.0,\n uv\n );\n#else\n return baseNormal;\n#endif\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, n: vec3f, reflection: vec3f) -> vec3f\n{\n let mipCount: f32 = 9.0; // resolution of 512x512\n let lod: f32 = pbrInfo.perceptualRoughness * mipCount;\n // retrieve a scale and bias to F0. See [1], Figure 3\n let brdf = SRGBtoLINEAR(\n textureSampleLevel(\n pbr_brdfLUT,\n pbr_brdfLUTSampler,\n vec2f(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness),\n 0.0\n )\n ).rgb;\n let diffuseLight =\n SRGBtoLINEAR(\n textureSampleLevel(pbr_diffuseEnvSampler, pbr_diffuseEnvSamplerSampler, n, 0.0)\n ).rgb;\n var specularLight = SRGBtoLINEAR(\n textureSampleLevel(\n pbr_specularEnvSampler,\n pbr_specularEnvSamplerSampler,\n reflection,\n 0.0\n )\n ).rgb;\n#ifdef USE_TEX_LOD\n specularLight = SRGBtoLINEAR(\n textureSampleLevel(\n pbr_specularEnvSampler,\n pbr_specularEnvSamplerSampler,\n reflection,\n lod\n )\n ).rgb;\n#endif\n\n let diffuse = diffuseLight * pbrInfo.diffuseColor * pbrMaterial.scaleIBLAmbient.x;\n let specular =\n specularLight * (pbrInfo.specularColor * brdf.x + brdf.y) * 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 / 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\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 / (M_PI * f * f);\n}\n\nfn maxComponent(value: vec3f) -> f32 {\n return max(max(value.r, value.g), value.b);\n}\n\nfn getDielectricF0(ior: f32) -> f32 {\n let clampedIor = max(ior, 1.0);\n let ratio = (clampedIor - 1.0) / (clampedIor + 1.0);\n return ratio * ratio;\n}\n\nfn normalizeDirection(direction: vec2f) -> vec2f {\n let directionLength = length(direction);\n if (directionLength > 0.0001) {\n return direction / directionLength;\n }\n\n return vec2f(1.0, 0.0);\n}\n\nfn rotateDirection(direction: vec2f, rotation: f32) -> vec2f {\n let s = sin(rotation);\n let c = cos(rotation);\n return vec2f(direction.x * c - direction.y * s, direction.x * s + direction.y * c);\n}\n\nfn getIridescenceTint(iridescence: f32, thickness: f32, NdotV: f32) -> vec3f {\n if (iridescence <= 0.0) {\n return vec3f(1.0);\n }\n\n let phase = 0.015 * thickness * pbrMaterial.iridescenceIor + (1.0 - NdotV) * 6.0;\n let thinFilmTint =\n 0.5 +\n 0.5 *\n cos(vec3f(phase, phase + 2.0943951, phase + 4.1887902));\n return mix(vec3f(1.0), thinFilmTint, iridescence);\n}\n\nfn getVolumeAttenuation(thickness: f32) -> vec3f {\n if (thickness <= 0.0) {\n return vec3f(1.0);\n }\n\n let attenuationCoefficient =\n -log(max(pbrMaterial.attenuationColor, vec3f(0.0001))) /\n max(pbrMaterial.attenuationDistance, 0.0001);\n return exp(-attenuationCoefficient * thickness);\n}\n\nfn createClearcoatPBRInfo(\n basePBRInfo: PBRInfo,\n clearcoatNormal: vec3f,\n clearcoatRoughness: f32\n) -> PBRInfo {\n let perceptualRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);\n let alphaRoughness = perceptualRoughness * perceptualRoughness;\n let NdotV = clamp(abs(dot(clearcoatNormal, basePBRInfo.v)), 0.001, 1.0);\n\n return PBRInfo(\n basePBRInfo.NdotL,\n NdotV,\n basePBRInfo.NdotH,\n basePBRInfo.LdotH,\n basePBRInfo.VdotH,\n perceptualRoughness,\n 0.0,\n vec3f(0.04),\n vec3f(1.0),\n alphaRoughness,\n vec3f(0.0),\n vec3f(0.04),\n clearcoatNormal,\n basePBRInfo.v\n );\n}\n\nfn calculateClearcoatContribution(\n pbrInfo: PBRInfo,\n lightColor: vec3f,\n clearcoatNormal: vec3f,\n clearcoatFactor: f32,\n clearcoatRoughness: f32\n) -> vec3f {\n if (clearcoatFactor <= 0.0) {\n return vec3f(0.0);\n }\n\n let clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);\n return calculateFinalColor(clearcoatPBRInfo, lightColor) * clearcoatFactor;\n}\n\n#ifdef USE_IBL\nfn calculateClearcoatIBLContribution(\n pbrInfo: PBRInfo,\n clearcoatNormal: vec3f,\n reflection: vec3f,\n clearcoatFactor: f32,\n clearcoatRoughness: f32\n) -> vec3f {\n if (clearcoatFactor <= 0.0) {\n return vec3f(0.0);\n }\n\n let clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);\n return getIBLContribution(clearcoatPBRInfo, clearcoatNormal, reflection) * clearcoatFactor;\n}\n#endif\n\nfn calculateSheenContribution(\n pbrInfo: PBRInfo,\n lightColor: vec3f,\n sheenColor: vec3f,\n sheenRoughness: f32\n) -> vec3f {\n if (maxComponent(sheenColor) <= 0.0) {\n return vec3f(0.0);\n }\n\n let sheenFresnel = pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);\n let sheenVisibility = mix(1.0, pbrInfo.NdotL * pbrInfo.NdotV, sheenRoughness);\n return pbrInfo.NdotL *\n lightColor *\n sheenColor *\n (0.25 + 0.75 * sheenFresnel) *\n sheenVisibility *\n (1.0 - pbrInfo.metalness);\n}\n\nfn calculateAnisotropyBoost(\n pbrInfo: PBRInfo,\n anisotropyTangent: vec3f,\n anisotropyStrength: f32\n) -> f32 {\n if (anisotropyStrength <= 0.0) {\n return 1.0;\n }\n\n let anisotropyBitangent = normalize(cross(pbrInfo.n, anisotropyTangent));\n let bitangentViewAlignment = abs(dot(pbrInfo.v, anisotropyBitangent));\n return mix(1.0, 0.65 + 0.7 * bitangentViewAlignment, anisotropyStrength);\n}\n\nfn calculateMaterialLightColor(\n pbrInfo: PBRInfo,\n lightColor: vec3f,\n clearcoatNormal: vec3f,\n clearcoatFactor: f32,\n clearcoatRoughness: f32,\n sheenColor: vec3f,\n sheenRoughness: f32,\n anisotropyTangent: vec3f,\n anisotropyStrength: f32\n) -> vec3f {\n let anisotropyBoost = calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);\n var color = calculateFinalColor(pbrInfo, lightColor) * anisotropyBoost;\n color += calculateClearcoatContribution(\n pbrInfo,\n lightColor,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness\n );\n color += calculateSheenContribution(pbrInfo, lightColor, sheenColor, sheenRoughness);\n return color;\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 - fragmentInputs.pbr_vPosition);\n PBRInfo_setDirectionalLight(pbrInfo, light_direction);\n}\n\nfn PBRInfo_setSpotLight(pbrInfo: ptr<function, PBRInfo>, spotLight: SpotLight) {\n let light_direction = normalize(spotLight.position - fragmentInputs.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 let baseColorUV = getMaterialUV(pbrMaterial.baseColorUVSet, pbrMaterial.baseColorUVTransform);\n let metallicRoughnessUV = getMaterialUV(\n pbrMaterial.metallicRoughnessUVSet,\n pbrMaterial.metallicRoughnessUVTransform\n );\n let normalUV = getMaterialUV(pbrMaterial.normalUVSet, pbrMaterial.normalUVTransform);\n let occlusionUV = getMaterialUV(pbrMaterial.occlusionUVSet, pbrMaterial.occlusionUVTransform);\n let emissiveUV = getMaterialUV(pbrMaterial.emissiveUVSet, pbrMaterial.emissiveUVTransform);\n let specularColorUV = getMaterialUV(\n pbrMaterial.specularColorUVSet,\n pbrMaterial.specularColorUVTransform\n );\n let specularIntensityUV = getMaterialUV(\n pbrMaterial.specularIntensityUVSet,\n pbrMaterial.specularIntensityUVTransform\n );\n let transmissionUV = getMaterialUV(\n pbrMaterial.transmissionUVSet,\n pbrMaterial.transmissionUVTransform\n );\n let thicknessUV = getMaterialUV(pbrMaterial.thicknessUVSet, pbrMaterial.thicknessUVTransform);\n let clearcoatUV = getMaterialUV(pbrMaterial.clearcoatUVSet, pbrMaterial.clearcoatUVTransform);\n let clearcoatRoughnessUV = getMaterialUV(\n pbrMaterial.clearcoatRoughnessUVSet,\n pbrMaterial.clearcoatRoughnessUVTransform\n );\n let clearcoatNormalUV = getMaterialUV(\n pbrMaterial.clearcoatNormalUVSet,\n pbrMaterial.clearcoatNormalUVTransform\n );\n let sheenColorUV = getMaterialUV(\n pbrMaterial.sheenColorUVSet,\n pbrMaterial.sheenColorUVTransform\n );\n let sheenRoughnessUV = getMaterialUV(\n pbrMaterial.sheenRoughnessUVSet,\n pbrMaterial.sheenRoughnessUVTransform\n );\n let iridescenceUV = getMaterialUV(\n pbrMaterial.iridescenceUVSet,\n pbrMaterial.iridescenceUVTransform\n );\n let iridescenceThicknessUV = getMaterialUV(\n pbrMaterial.iridescenceThicknessUVSet,\n pbrMaterial.iridescenceThicknessUVTransform\n );\n let anisotropyUV = getMaterialUV(\n pbrMaterial.anisotropyUVSet,\n pbrMaterial.anisotropyUVTransform\n );\n\n // The albedo may be defined from a base texture or a flat color\n var baseColor: vec4<f32> = pbrMaterial.baseColorFactor;\n #ifdef HAS_BASECOLORMAP\n baseColor = SRGBtoLINEAR(\n textureSample(pbr_baseColorSampler, pbr_baseColorSamplerSampler, baseColorUV)\n ) * 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 var transmission = 0.0;\n\n if (pbrMaterial.unlit != 0u) {\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(\n pbr_metallicRoughnessSampler,\n pbr_metallicRoughnessSamplerSampler,\n metallicRoughnessUV\n );\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 let tbn = getTBN(normalUV);\n let n = getNormal(tbn, normalUV); // normal at surface point\n let v = normalize(pbrProjection.camera - fragmentInputs.pbr_vPosition); // Vector from surface point to camera\n let NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);\n var useExtendedPBR = false;\n #ifdef USE_MATERIAL_EXTENSIONS\n useExtendedPBR =\n pbrMaterial.specularColorMapEnabled != 0 ||\n pbrMaterial.specularIntensityMapEnabled != 0 ||\n abs(pbrMaterial.specularIntensityFactor - 1.0) > 0.0001 ||\n maxComponent(abs(pbrMaterial.specularColorFactor - vec3f(1.0))) > 0.0001 ||\n abs(pbrMaterial.ior - 1.5) > 0.0001 ||\n pbrMaterial.transmissionMapEnabled != 0 ||\n pbrMaterial.transmissionFactor > 0.0001 ||\n pbrMaterial.clearcoatMapEnabled != 0 ||\n pbrMaterial.clearcoatRoughnessMapEnabled != 0 ||\n pbrMaterial.clearcoatFactor > 0.0001 ||\n pbrMaterial.clearcoatRoughnessFactor > 0.0001 ||\n pbrMaterial.sheenColorMapEnabled != 0 ||\n pbrMaterial.sheenRoughnessMapEnabled != 0 ||\n maxComponent(pbrMaterial.sheenColorFactor) > 0.0001 ||\n pbrMaterial.sheenRoughnessFactor > 0.0001 ||\n pbrMaterial.iridescenceMapEnabled != 0 ||\n pbrMaterial.iridescenceFactor > 0.0001 ||\n abs(pbrMaterial.iridescenceIor - 1.3) > 0.0001 ||\n abs(pbrMaterial.iridescenceThicknessRange.x - 100.0) > 0.0001 ||\n abs(pbrMaterial.iridescenceThicknessRange.y - 400.0) > 0.0001 ||\n pbrMaterial.anisotropyMapEnabled != 0 ||\n pbrMaterial.anisotropyStrength > 0.0001 ||\n abs(pbrMaterial.anisotropyRotation) > 0.0001 ||\n length(pbrMaterial.anisotropyDirection - vec2f(1.0, 0.0)) > 0.0001;\n #endif\n\n if (!useExtendedPBR) {\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 let reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);\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 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 PBRInfo_setAmbientLight(&pbrInfo);\n color += calculateFinalColor(pbrInfo, lighting.ambientColor);\n\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 for (var i = 0; i < lighting.pointLightCount; i++) {\n if (i < lighting.pointLightCount) {\n PBRInfo_setPointLight(&pbrInfo, lighting_getPointLight(i));\n let attenuation = getPointLightAttenuation(\n lighting_getPointLight(i),\n distance(lighting_getPointLight(i).position, fragmentInputs.pbr_vPosition)\n );\n color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);\n }\n }\n\n for (var i = 0; i < lighting.spotLightCount; i++) {\n if (i < lighting.spotLightCount) {\n PBRInfo_setSpotLight(&pbrInfo, lighting_getSpotLight(i));\n let attenuation = getSpotLightAttenuation(\n lighting_getSpotLight(i),\n fragmentInputs.pbr_vPosition\n );\n color += calculateFinalColor(pbrInfo, lighting_getSpotLight(i).color / attenuation);\n }\n }\n #endif\n\n #ifdef USE_IBL\n if (pbrMaterial.IBLenabled != 0) {\n color += getIBLContribution(pbrInfo, n, reflection);\n }\n #endif\n\n #ifdef HAS_OCCLUSIONMAP\n if (pbrMaterial.occlusionMapEnabled != 0) {\n let ao = textureSample(pbr_occlusionSampler, pbr_occlusionSamplerSampler, occlusionUV).r;\n color = mix(color, color * ao, pbrMaterial.occlusionStrength);\n }\n #endif\n\n var emissive = pbrMaterial.emissiveFactor;\n #ifdef HAS_EMISSIVEMAP\n if (pbrMaterial.emissiveMapEnabled != 0u) {\n emissive *= SRGBtoLINEAR(\n textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, emissiveUV)\n ).rgb;\n }\n #endif\n color += emissive * pbrMaterial.emissiveStrength;\n\n #ifdef PBR_DEBUG\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 return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), baseColor.a);\n }\n\n var specularIntensity = pbrMaterial.specularIntensityFactor;\n #ifdef HAS_SPECULARINTENSITYMAP\n if (pbrMaterial.specularIntensityMapEnabled != 0) {\n specularIntensity *= textureSample(\n pbr_specularIntensitySampler,\n pbr_specularIntensitySamplerSampler,\n specularIntensityUV\n ).a;\n }\n #endif\n\n var specularFactor = pbrMaterial.specularColorFactor;\n #ifdef HAS_SPECULARCOLORMAP\n if (pbrMaterial.specularColorMapEnabled != 0) {\n specularFactor *= SRGBtoLINEAR(\n textureSample(\n pbr_specularColorSampler,\n pbr_specularColorSamplerSampler,\n specularColorUV\n )\n ).rgb;\n }\n #endif\n\n transmission = pbrMaterial.transmissionFactor;\n #ifdef HAS_TRANSMISSIONMAP\n if (pbrMaterial.transmissionMapEnabled != 0) {\n transmission *= textureSample(\n pbr_transmissionSampler,\n pbr_transmissionSamplerSampler,\n transmissionUV\n ).r;\n }\n #endif\n transmission = clamp(transmission * (1.0 - metallic), 0.0, 1.0);\n var thickness = max(pbrMaterial.thicknessFactor, 0.0);\n #ifdef HAS_THICKNESSMAP\n thickness *= textureSample(\n pbr_thicknessSampler,\n pbr_thicknessSamplerSampler,\n thicknessUV\n ).g;\n #endif\n\n var clearcoatFactor = pbrMaterial.clearcoatFactor;\n var clearcoatRoughness = pbrMaterial.clearcoatRoughnessFactor;\n #ifdef HAS_CLEARCOATMAP\n if (pbrMaterial.clearcoatMapEnabled != 0) {\n clearcoatFactor *= textureSample(\n pbr_clearcoatSampler,\n pbr_clearcoatSamplerSampler,\n clearcoatUV\n ).r;\n }\n #endif\n #ifdef HAS_CLEARCOATROUGHNESSMAP\n if (pbrMaterial.clearcoatRoughnessMapEnabled != 0) {\n clearcoatRoughness *= textureSample(\n pbr_clearcoatRoughnessSampler,\n pbr_clearcoatRoughnessSamplerSampler,\n clearcoatRoughnessUV\n ).g;\n }\n #endif\n clearcoatFactor = clamp(clearcoatFactor, 0.0, 1.0);\n clearcoatRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);\n let clearcoatNormal = getClearcoatNormal(getTBN(clearcoatNormalUV), n, clearcoatNormalUV);\n\n var sheenColor = pbrMaterial.sheenColorFactor;\n var sheenRoughness = pbrMaterial.sheenRoughnessFactor;\n #ifdef HAS_SHEENCOLORMAP\n if (pbrMaterial.sheenColorMapEnabled != 0) {\n sheenColor *= SRGBtoLINEAR(\n textureSample(\n pbr_sheenColorSampler,\n pbr_sheenColorSamplerSampler,\n sheenColorUV\n )\n ).rgb;\n }\n #endif\n #ifdef HAS_SHEENROUGHNESSMAP\n if (pbrMaterial.sheenRoughnessMapEnabled != 0) {\n sheenRoughness *= textureSample(\n pbr_sheenRoughnessSampler,\n pbr_sheenRoughnessSamplerSampler,\n sheenRoughnessUV\n ).a;\n }\n #endif\n sheenRoughness = clamp(sheenRoughness, c_MinRoughness, 1.0);\n\n var iridescence = pbrMaterial.iridescenceFactor;\n #ifdef HAS_IRIDESCENCEMAP\n if (pbrMaterial.iridescenceMapEnabled != 0) {\n iridescence *= textureSample(\n pbr_iridescenceSampler,\n pbr_iridescenceSamplerSampler,\n iridescenceUV\n ).r;\n }\n #endif\n iridescence = clamp(iridescence, 0.0, 1.0);\n var iridescenceThickness = mix(\n pbrMaterial.iridescenceThicknessRange.x,\n pbrMaterial.iridescenceThicknessRange.y,\n 0.5\n );\n #ifdef HAS_IRIDESCENCETHICKNESSMAP\n iridescenceThickness = mix(\n pbrMaterial.iridescenceThicknessRange.x,\n pbrMaterial.iridescenceThicknessRange.y,\n textureSample(\n pbr_iridescenceThicknessSampler,\n pbr_iridescenceThicknessSamplerSampler,\n iridescenceThicknessUV\n ).g\n );\n #endif\n\n var anisotropyStrength = clamp(pbrMaterial.anisotropyStrength, 0.0, 1.0);\n var anisotropyDirection = normalizeDirection(pbrMaterial.anisotropyDirection);\n #ifdef HAS_ANISOTROPYMAP\n if (pbrMaterial.anisotropyMapEnabled != 0) {\n let anisotropySample = textureSample(\n pbr_anisotropySampler,\n pbr_anisotropySamplerSampler,\n anisotropyUV\n ).rgb;\n anisotropyStrength *= anisotropySample.b;\n let mappedDirection = anisotropySample.rg * 2.0 - 1.0;\n if (length(mappedDirection) > 0.0001) {\n anisotropyDirection = normalize(mappedDirection);\n }\n }\n #endif\n anisotropyDirection = rotateDirection(anisotropyDirection, pbrMaterial.anisotropyRotation);\n var anisotropyTangent =\n normalize(tbn[0] * anisotropyDirection.x + tbn[1] * anisotropyDirection.y);\n if (length(anisotropyTangent) < 0.0001) {\n anisotropyTangent = normalize(tbn[0]);\n }\n let anisotropyViewAlignment = abs(dot(v, anisotropyTangent));\n perceptualRoughness = mix(\n perceptualRoughness,\n clamp(perceptualRoughness * (1.0 - 0.6 * anisotropyViewAlignment), c_MinRoughness, 1.0),\n anisotropyStrength\n );\n\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 dielectricF0 = getDielectricF0(pbrMaterial.ior);\n var dielectricSpecularF0 = min(\n vec3f(dielectricF0) * specularFactor * specularIntensity,\n vec3f(1.0)\n );\n let iridescenceTint = getIridescenceTint(iridescence, iridescenceThickness, NdotV);\n dielectricSpecularF0 = mix(\n dielectricSpecularF0,\n dielectricSpecularF0 * iridescenceTint,\n iridescence\n );\n var diffuseColor = baseColor.rgb * (vec3f(1.0) - dielectricSpecularF0);\n diffuseColor *= (1.0 - metallic) * (1.0 - transmission);\n var specularColor = mix(dielectricSpecularF0, baseColor.rgb, metallic);\n\n let baseLayerEnergy = 1.0 - clearcoatFactor * 0.25;\n diffuseColor *= baseLayerEnergy;\n specularColor *= baseLayerEnergy;\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 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 += calculateMaterialLightColor(\n pbrInfo,\n lighting.ambientColor,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness,\n sheenColor,\n sheenRoughness,\n anisotropyTangent,\n anisotropyStrength\n );\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 += calculateMaterialLightColor(\n pbrInfo,\n lighting_getDirectionalLight(i).color,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness,\n sheenColor,\n sheenRoughness,\n anisotropyTangent,\n anisotropyStrength\n );\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(\n lighting_getPointLight(i),\n distance(lighting_getPointLight(i).position, fragmentInputs.pbr_vPosition)\n );\n color += calculateMaterialLightColor(\n pbrInfo,\n lighting_getPointLight(i).color / attenuation,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness,\n sheenColor,\n sheenRoughness,\n anisotropyTangent,\n anisotropyStrength\n );\n }\n }\n\n for (var i = 0; i < lighting.spotLightCount; i++) {\n if (i < lighting.spotLightCount) {\n PBRInfo_setSpotLight(&pbrInfo, lighting_getSpotLight(i));\n let attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), fragmentInputs.pbr_vPosition);\n color += calculateMaterialLightColor(\n pbrInfo,\n lighting_getSpotLight(i).color / attenuation,\n clearcoatNormal,\n clearcoatFactor,\n clearcoatRoughness,\n sheenColor,\n sheenRoughness,\n anisotropyTangent,\n anisotropyStrength\n );\n }\n }\n #endif\n\n // Calculate lighting contribution from image based lighting source (IBL)\n #ifdef USE_IBL\n if (pbrMaterial.IBLenabled != 0) {\n color += getIBLContribution(pbrInfo, n, reflection) *\n calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);\n color += calculateClearcoatIBLContribution(\n pbrInfo,\n clearcoatNormal,\n -normalize(reflect(v, clearcoatNormal)),\n clearcoatFactor,\n clearcoatRoughness\n );\n color += sheenColor * pbrMaterial.scaleIBLAmbient.x * (1.0 - sheenRoughness) * 0.25;\n }\n #endif\n\n // Apply optional PBR terms for additional (optional) shading\n #ifdef HAS_OCCLUSIONMAP\n if (pbrMaterial.occlusionMapEnabled != 0) {\n let ao = textureSample(pbr_occlusionSampler, pbr_occlusionSamplerSampler, occlusionUV).r;\n color = mix(color, color * ao, pbrMaterial.occlusionStrength);\n }\n #endif\n\n var emissive = pbrMaterial.emissiveFactor;\n #ifdef HAS_EMISSIVEMAP\n if (pbrMaterial.emissiveMapEnabled != 0u) {\n emissive *= SRGBtoLINEAR(\n textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, emissiveUV)\n ).rgb;\n }\n #endif\n color += emissive * pbrMaterial.emissiveStrength;\n\n if (transmission > 0.0) {\n color = mix(color, color * getVolumeAttenuation(thickness), transmission);\n }\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 let alpha = clamp(baseColor.a * (1.0 - transmission), 0.0, 1.0);\n return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), alpha);\n}\n`;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {NumberArray3, NumberArray16} from '@math.gl/core';\n\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\n\nconst uniformBlock = /* glsl */ `\\\nlayout(std140) uniform pbrProjectionUniforms {\n mat4 modelViewProjectionMatrix;\n mat4 modelMatrix;\n mat4 normalMatrix;\n vec3 camera;\n} pbrProjection;\n`;\n\nconst wgslUniformBlock = /* wgsl */ `\\\nstruct pbrProjectionUniforms {\n modelViewProjectionMatrix: mat4x4<f32>,\n modelMatrix: mat4x4<f32>,\n normalMatrix: mat4x4<f32>,\n camera: vec3<f32>\n};\n\n@group(0) @binding(auto) var<uniform> pbrProjection: pbrProjectionUniforms;\n`;\n\nexport type PBRProjectionProps = {\n modelViewProjectionMatrix: NumberArray16;\n modelMatrix: NumberArray16;\n normalMatrix: NumberArray16;\n camera: NumberArray3;\n};\n\nexport const pbrProjection: ShaderModule<PBRProjectionProps> = {\n name: 'pbrProjection',\n bindingLayout: [{name: 'pbrProjection', group: 0}],\n source: wgslUniformBlock,\n vs: uniformBlock,\n fs: uniformBlock,\n // TODO why is this needed?\n getUniforms: props => props,\n uniformTypes: {\n modelViewProjectionMatrix: 'mat4x4<f32>',\n modelMatrix: 'mat4x4<f32>',\n normalMatrix: 'mat4x4<f32>',\n camera: 'vec3<f32>'\n }\n};\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* eslint-disable camelcase */\n\nimport type {Texture} from '@luma.gl/core';\nimport type {\n Matrix3,\n Vector2,\n Vector3,\n Vector4,\n NumberArray2,\n NumberArray3,\n NumberArray4,\n NumberArray9\n} from '@math.gl/core';\n\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\nimport {lighting} from '../lights/lighting';\nimport {ibl} from '../ibl/ibl';\n\nimport {vs, fs} from './pbr-material-glsl';\nimport {source} from './pbr-material-wgsl';\nimport {pbrProjection} from './pbr-projection';\n\n/** Non-uniform block bindings for pbr module */\nexport type PBRMaterialBindings = {\n // Samplers\n pbr_baseColorSampler?: Texture | null; // #ifdef HAS_BASECOLORMAP\n pbr_normalSampler?: Texture | null; // #ifdef HAS_NORMALMAP\n pbr_emissiveSampler?: Texture | null; // #ifdef HAS_EMISSIVEMAP\n pbr_metallicRoughnessSampler?: Texture | null; // #ifdef HAS_METALROUGHNESSMAP\n pbr_occlusionSampler?: Texture | null; // #ifdef HAS_OCCLUSIONMAP\n\n pbr_specularColorSampler?: Texture | null; // #ifdef HAS_SPECULARCOLORMAP\n pbr_specularIntensitySampler?: Texture | null; // #ifdef HAS_SPECULARINTENSITYMAP\n pbr_transmissionSampler?: Texture | null; // #ifdef HAS_TRANSMISSIONMAP\n pbr_thicknessSampler?: Texture | null; // #ifdef HAS_THICKNESSMAP\n\n pbr_clearcoatSampler?: Texture | null; // #ifdef HAS_CLEARCOATMAP\n pbr_clearcoatRoughnessSampler?: Texture | null; // #ifdef HAS_CLEARCOATROUGHNESSMAP\n pbr_clearcoatNormalSampler?: Texture | null; // #ifdef HAS_CLEARCOATNORMALMAP\n pbr_sheenColorSampler?: Texture | null; // #ifdef HAS_SHEENCOLORMAP\n pbr_sheenRoughnessSampler?: Texture | null; // #ifdef HAS_SHEENROUGHNESSMAP\n pbr_iridescenceSampler?: Texture | null; // #ifdef HAS_IRIDESCENCEMAP\n pbr_iridescenceThicknessSampler?: Texture | null; // #ifdef HAS_IRIDESCENCETHICKNESSMAP\n pbr_anisotropySampler?: Texture | null; // #ifdef HAS_ANISOTROPYMAP\n};\n\nexport type PBRMaterialUniforms = {\n unlit?: boolean;\n\n // Base color map\n baseColorMapEnabled?: boolean;\n baseColorFactor?: Readonly<Vector4 | NumberArray4>;\n\n normalMapEnabled?: boolean;\n normalScale?: number; // #ifdef HAS_NORMALMAP\n\n emissiveMapEnabled?: boolean;\n emissiveFactor?: Readonly<Vector3 | NumberArray3>; // #ifdef HAS_EMISSIVEMAP\n\n metallicRoughnessValues?: Readonly<Vector2 | NumberArray2>;\n metallicRoughnessMapEnabled?: boolean;\n\n occlusionMapEnabled?: boolean;\n occlusionStrength?: number; // #ifdef HAS_OCCLUSIONMAP\n\n alphaCutoffEnabled?: boolean;\n alphaCutoff?: number; // #ifdef ALPHA_CUTOFF\n\n // IBL\n IBLenabled?: boolean;\n scaleIBLAmbient?: Readonly<Vector2 | NumberArray2>; // #ifdef USE_IBL\n\n // debugging flags used for shader output of intermediate PBR variables\n // #ifdef PBR_DEBUG\n scaleDiffBaseMR?: Readonly<Vector4 | NumberArray4>;\n scaleFGDSpec?: Readonly<Vector4 | NumberArray4>;\n\n // glTF material extensions\n specularColorFactor?: Readonly<Vector3 | NumberArray3>;\n specularIntensityFactor?: number;\n specularColorMapEnabled?: boolean;\n specularIntensityMapEnabled?: boolean;\n\n ior?: number;\n\n transmissionFactor?: number;\n transmissionMapEnabled?: boolean;\n\n thicknessFactor?: number;\n attenuationDistance?: number;\n attenuationColor?: Readonly<Vector3 | NumberArray3>;\n\n clearcoatFactor?: number;\n clearcoatRoughnessFactor?: number;\n clearcoatMapEnabled?: boolean;\n clearcoatRoughnessMapEnabled?: boolean;\n\n sheenColorFactor?: Readonly<Vector3 | NumberArray3>;\n sheenRoughnessFactor?: number;\n sheenColorMapEnabled?: boolean;\n sheenRoughnessMapEnabled?: boolean;\n\n iridescenceFactor?: number;\n iridescenceIor?: number;\n iridescenceThicknessRange?: Readonly<Vector2 | NumberArray2>;\n iridescenceMapEnabled?: boolean;\n\n anisotropyStrength?: number;\n anisotropyRotation?: number;\n anisotropyDirection?: Readonly<Vector2 | NumberArray2>;\n anisotropyMapEnabled?: boolean;\n\n emissiveStrength?: number;\n\n baseColorUVSet?: number;\n baseColorUVTransform?: Readonly<NumberArray9 | Matrix3>;\n metallicRoughnessUVSet?: number;\n metallicRoughnessUVTransform?: Readonly<NumberArray9 | Matrix3>;\n normalUVSet?: number;\n normalUVTransform?: Readonly<NumberArray9 | Matrix3>;\n occlusionUVSet?: number;\n occlusionUVTransform?: Readonly<NumberArray9 | Matrix3>;\n emissiveUVSet?: number;\n emissiveUVTransform?: Readonly<NumberArray9 | Matrix3>;\n specularColorUVSet?: number;\n specularColorUVTransform?: Readonly<NumberArray9 | Matrix3>;\n specularIntensityUVSet?: number;\n specularIntensityUVTransform?: Readonly<NumberArray9 | Matrix3>;\n transmissionUVSet?: number;\n transmissionUVTransform?: Readonly<NumberArray9 | Matrix3>;\n thicknessUVSet?: number;\n thicknessUVTransform?: Readonly<NumberArray9 | Matrix3>;\n clearcoatUVSet?: number;\n clearcoatUVTransform?: Readonly<NumberArray9 | Matrix3>;\n clearcoatRoughnessUVSet?: number;\n clearcoatRoughnessUVTransform?: Readonly<NumberArray9 | Matrix3>;\n clearcoatNormalUVSet?: number;\n clearcoatNormalUVTransform?: Readonly<NumberArray9 | Matrix3>;\n sheenColorUVSet?: number;\n sheenColorUVTransform?: Readonly<NumberArray9 | Matrix3>;\n sheenRoughnessUVSet?: number;\n sheenRoughnessUVTransform?: Readonly<NumberArray9 | Matrix3>;\n iridescenceUVSet?: number;\n iridescenceUVTransform?: Readonly<NumberArray9 | Matrix3>;\n iridescenceThicknessUVSet?: number;\n iridescenceThicknessUVTransform?: Readonly<NumberArray9 | Matrix3>;\n anisotropyUVSet?: number;\n anisotropyUVTransform?: Readonly<NumberArray9 | Matrix3>;\n};\n\nexport type PBRMaterialProps = PBRMaterialBindings & PBRMaterialUniforms;\n\n/**\n * An implementation of PBR (Physically-Based Rendering).\n * Physically Based Shading of a microfacet surface defined by a glTF material.\n */\nexport const pbrMaterial = {\n props: {} as PBRMaterialProps,\n uniforms: {} as PBRMaterialUniforms,\n defaultUniforms: {\n unlit: false,\n\n baseColorMapEnabled: false,\n baseColorFactor: [1, 1, 1, 1],\n\n normalMapEnabled: false,\n normalScale: 1,\n\n emissiveMapEnabled: false,\n emissiveFactor: [0, 0, 0],\n\n metallicRoughnessValues: [1, 1],\n metallicRoughnessMapEnabled: false,\n\n occlusionMapEnabled: false,\n occlusionStrength: 1,\n\n alphaCutoffEnabled: false,\n alphaCutoff: 0.5,\n\n IBLenabled: false,\n scaleIBLAmbient: [1, 1],\n\n scaleDiffBaseMR: [0, 0, 0, 0],\n scaleFGDSpec: [0, 0, 0, 0],\n\n specularColorFactor: [1, 1, 1],\n specularIntensityFactor: 1,\n specularColorMapEnabled: false,\n specularIntensityMapEnabled: false,\n\n ior: 1.5,\n\n transmissionFactor: 0,\n transmissionMapEnabled: false,\n\n thicknessFactor: 0,\n attenuationDistance: 1e9,\n attenuationColor: [1, 1, 1],\n\n clearcoatFactor: 0,\n clearcoatRoughnessFactor: 0,\n clearcoatMapEnabled: false,\n clearcoatRoughnessMapEnabled: false,\n\n sheenColorFactor: [0, 0, 0],\n sheenRoughnessFactor: 0,\n sheenColorMapEnabled: false,\n sheenRoughnessMapEnabled: false,\n\n iridescenceFactor: 0,\n iridescenceIor: 1.3,\n iridescenceThicknessRange: [100, 400],\n iridescenceMapEnabled: false,\n\n anisotropyStrength: 0,\n anisotropyRotation: 0,\n anisotropyDirection: [1, 0],\n anisotropyMapEnabled: false,\n\n emissiveStrength: 1,\n\n baseColorUVSet: 0,\n baseColorUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n metallicRoughnessUVSet: 0,\n metallicRoughnessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n normalUVSet: 0,\n normalUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n occlusionUVSet: 0,\n occlusionUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n emissiveUVSet: 0,\n emissiveUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n specularColorUVSet: 0,\n specularColorUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n specularIntensityUVSet: 0,\n specularIntensityUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n transmissionUVSet: 0,\n transmissionUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n thicknessUVSet: 0,\n thicknessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n clearcoatUVSet: 0,\n clearcoatUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n clearcoatRoughnessUVSet: 0,\n clearcoatRoughnessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n clearcoatNormalUVSet: 0,\n clearcoatNormalUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n sheenColorUVSet: 0,\n sheenColorUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n sheenRoughnessUVSet: 0,\n sheenRoughnessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n iridescenceUVSet: 0,\n iridescenceUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n iridescenceThicknessUVSet: 0,\n iridescenceThicknessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n anisotropyUVSet: 0,\n anisotropyUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1]\n } as Required<PBRMaterialUniforms>,\n\n name: 'pbrMaterial',\n firstBindingSlot: 0,\n bindingLayout: [\n {name: 'pbrMaterial', group: 3},\n {name: 'pbr_baseColorSampler', group: 3},\n {name: 'pbr_normalSampler', group: 3},\n {name: 'pbr_emissiveSampler', group: 3},\n {name: 'pbr_metallicRoughnessSampler', group: 3},\n {name: 'pbr_occlusionSampler', group: 3},\n {name: 'pbr_specularColorSampler', group: 3},\n {name: 'pbr_specularIntensitySampler', group: 3},\n {name: 'pbr_transmissionSampler', group: 3},\n {name: 'pbr_thicknessSampler', group: 3},\n {name: 'pbr_clearcoatSampler', group: 3},\n {name: 'pbr_clearcoatRoughnessSampler', group: 3},\n {name: 'pbr_clearcoatNormalSampler', group: 3},\n {name: 'pbr_sheenColorSampler', group: 3},\n {name: 'pbr_sheenRoughnessSampler', group: 3},\n {name: 'pbr_iridescenceSampler', group: 3},\n {name: 'pbr_iridescenceThicknessSampler', group: 3},\n {name: 'pbr_anisotropySampler', group: 3}\n ],\n dependencies: [lighting, ibl, pbrProjection],\n source,\n vs,\n fs,\n\n defines: {\n LIGHTING_FRAGMENT: true,\n HAS_NORMALMAP: false,\n HAS_EMISSIVEMAP: false,\n HAS_OCCLUSIONMAP: false,\n HAS_BASECOLORMAP: false,\n HAS_METALROUGHNESSMAP: false,\n HAS_SPECULARCOLORMAP: false,\n HAS_SPECULARINTENSITYMAP: false,\n HAS_TRANSMISSIONMAP: false,\n HAS_THICKNESSMAP: false,\n HAS_CLEARCOATMAP: false,\n HAS_CLEARCOATROUGHNESSMAP: false,\n HAS_CLEARCOATNORMALMAP: false,\n HAS_SHEENCOLORMAP: false,\n HAS_SHEENROUGHNESSMAP: false,\n HAS_IRIDESCENCEMAP: false,\n HAS_IRIDESCENCETHICKNESSMAP: false,\n HAS_ANISOTROPYMAP: false,\n USE_MATERIAL_EXTENSIONS: false,\n ALPHA_CUTOFF: false,\n USE_IBL: false,\n PBR_DEBUG: false\n },\n getUniforms: props => props,\n uniformTypes: {\n // Material is unlit\n unlit: 'i32',\n\n // Base color map\n baseColorMapEnabled: 'i32',\n baseColorFactor: 'vec4<f32>',\n\n normalMapEnabled: 'i32',\n normalScale: 'f32', // #ifdef HAS_NORMALMAP\n\n emissiveMapEnabled: 'i32',\n emissiveFactor: 'vec3<f32>', // #ifdef HAS_EMISSIVEMAP\n\n metallicRoughnessValues: 'vec2<f32>',\n metallicRoughnessMapEnabled: 'i32',\n\n occlusionMapEnabled: 'i32',\n occlusionStrength: 'f32', // #ifdef HAS_OCCLUSIONMAP\n\n alphaCutoffEnabled: 'i32',\n alphaCutoff: 'f32', // #ifdef ALPHA_CUTOFF\n\n specularColorFactor: 'vec3<f32>',\n specularIntensityFactor: 'f32',\n specularColorMapEnabled: 'i32',\n specularIntensityMapEnabled: 'i32',\n\n ior: 'f32',\n\n transmissionFactor: 'f32',\n transmissionMapEnabled: 'i32',\n\n thicknessFactor: 'f32',\n attenuationDistance: 'f32',\n attenuationColor: 'vec3<f32>',\n\n clearcoatFactor: 'f32',\n clearcoatRoughnessFactor: 'f32',\n clearcoatMapEnabled: 'i32',\n clearcoatRoughnessMapEnabled: 'i32',\n\n sheenColorFactor: 'vec3<f32>',\n sheenRoughnessFactor: 'f32',\n sheenColorMapEnabled: 'i32',\n sheenRoughnessMapEnabled: 'i32',\n\n iridescenceFactor: 'f32',\n iridescenceIor: 'f32',\n iridescenceThicknessRange: 'vec2<f32>',\n iridescenceMapEnabled: 'i32',\n\n anisotropyStrength: 'f32',\n anisotropyRotation: 'f32',\n anisotropyDirection: 'vec2<f32>',\n anisotropyMapEnabled: 'i32',\n\n emissiveStrength: 'f32',\n\n // IBL\n IBLenabled: 'i32',\n scaleIBLAmbient: 'vec2<f32>', // #ifdef USE_IBL\n\n // debugging flags used for shader output of intermediate PBR variables\n // #ifdef PBR_DEBUG\n scaleDiffBaseMR: 'vec4<f32>',\n scaleFGDSpec: 'vec4<f32>',\n\n baseColorUVSet: 'i32',\n baseColorUVTransform: 'mat3x3<f32>',\n metallicRoughnessUVSet: 'i32',\n metallicRoughnessUVTransform: 'mat3x3<f32>',\n normalUVSet: 'i32',\n normalUVTransform: 'mat3x3<f32>',\n occlusionUVSet: 'i32',\n occlusionUVTransform: 'mat3x3<f32>',\n emissiveUVSet: 'i32',\n emissiveUVTransform: 'mat3x3<f32>',\n specularColorUVSet: 'i32',\n specularColorUVTransform: 'mat3x3<f32>',\n specularIntensityUVSet: 'i32',\n specularIntensityUVTransform: 'mat3x3<f32>',\n transmissionUVSet: 'i32',\n transmissionUVTransform: 'mat3x3<f32>',\n thicknessUVSet: 'i32',\n thicknessUVTransform: 'mat3x3<f32>',\n clearcoatUVSet: 'i32',\n clearcoatUVTransform: 'mat3x3<f32>',\n clearcoatRoughnessUVSet: 'i32',\n clearcoatRoughnessUVTransform: 'mat3x3<f32>',\n clearcoatNormalUVSet: 'i32',\n clearcoatNormalUVTransform: 'mat3x3<f32>',\n sheenColorUVSet: 'i32',\n sheenColorUVTransform: 'mat3x3<f32>',\n sheenRoughnessUVSet: 'i32',\n sheenRoughnessUVTransform: 'mat3x3<f32>',\n iridescenceUVSet: 'i32',\n iridescenceUVTransform: 'mat3x3<f32>',\n iridescenceThicknessUVSet: 'i32',\n iridescenceThicknessUVTransform: 'mat3x3<f32>',\n anisotropyUVSet: 'i32',\n anisotropyUVTransform: 'mat3x3<f32>'\n }\n} as const satisfies ShaderModule<PBRMaterialProps, PBRMaterialUniforms, PBRMaterialBindings>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {Texture} from '@luma.gl/core';\nimport type {NumberArray2, NumberArray16} from '@math.gl/core';\n\nimport {ShaderModule} from '../../../lib/shader-module/shader-module';\n\nexport type PBRSceneBindings = {\n pbr_transmissionFramebufferSampler?: Texture | null;\n};\n\nexport type PBRSceneUniforms = {\n exposure?: number;\n toneMapMode?: number;\n environmentIntensity?: number;\n environmentRotation?: number;\n framebufferSize?: NumberArray2;\n viewMatrix?: NumberArray16;\n projectionMatrix?: NumberArray16;\n};\n\nexport type PBRSceneProps = PBRSceneBindings & PBRSceneUniforms;\n\nconst IDENTITY_MATRIX: NumberArray16 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];\n\nconst uniformBlock = /* glsl */ `\\\nlayout(std140) uniform pbrSceneUniforms {\n float exposure;\n int toneMapMode;\n float environmentIntensity;\n float environmentRotation;\n vec2 framebufferSize;\n mat4 viewMatrix;\n mat4 projectionMatrix;\n} pbrScene;\n\n#ifdef USE_TRANSMISSION_FRAMEBUFFER\nuniform sampler2D pbr_transmissionFramebufferSampler;\n#endif\n`;\n\nconst wgslUniformBlock = /* wgsl */ `\\\nstruct pbrSceneUniforms {\n exposure: f32,\n toneMapMode: i32,\n environmentIntensity: f32,\n environmentRotation: f32,\n framebufferSize: vec2<f32>,\n viewMatrix: mat4x4<f32>,\n projectionMatrix: mat4x4<f32>\n};\n\n@group(1) @binding(auto) var<uniform> pbrScene: pbrSceneUniforms;\n\n#ifdef USE_TRANSMISSION_FRAMEBUFFER\n@group(1) @binding(auto) var pbr_transmissionFramebufferSampler: texture_2d<f32>;\n@group(1) @binding(auto) var pbr_transmissionFramebufferSamplerSampler: sampler;\n#endif\n`;\n\nexport const pbrScene = {\n name: 'pbrScene',\n bindingLayout: [\n {name: 'pbrScene', group: 1},\n {name: 'pbr_transmissionFramebufferSampler', group: 1}\n ],\n source: wgslUniformBlock,\n vs: uniformBlock,\n fs: uniformBlock,\n getUniforms: (props: PBRSceneProps) => props,\n uniformTypes: {\n exposure: 'f32',\n toneMapMode: 'i32',\n environmentIntensity: 'f32',\n environmentRotation: 'f32',\n framebufferSize: 'vec2<f32>',\n viewMatrix: 'mat4x4<f32>',\n projectionMatrix: 'mat4x4<f32>'\n },\n defaultUniforms: {\n exposure: 1,\n toneMapMode: 2,\n environmentIntensity: 1,\n environmentRotation: Math.PI * 0.5,\n framebufferSize: [1, 1],\n viewMatrix: IDENTITY_MATRIX,\n projectionMatrix: IDENTITY_MATRIX\n } as Required<PBRSceneUniforms>\n} as const satisfies ShaderModule<PBRSceneProps, PBRSceneUniforms, PBRSceneBindings>;\n"],
|
|
5
|
+
"mappings": "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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC2FtB,IAAMC;;EAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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",
|
|
6
|
+
"names": ["source", "module", "log", "_a", "module", "module", "log", "source", "source", "source", "source", "source", "vs", "fs", "log", "module", "getUniforms", "location", "source", "module", "source", "getUniforms", "module", "module", "module", "fs", "import_core", "source", "vs", "fs", "import_core", "getUniforms", "getUniforms", "DEFAULT_SPECULAR_COLOR", "vs", "fs", "source", "source", "vs", "fs", "uniformBlock", "wgslUniformBlock"]
|
|
7
7
|
}
|