three-gpu-pathtracer 0.0.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.module.js","sources":["../src/core/PathTracingRenderer.js","../src/utils/GeometryPreparationUtils.js","../src/core/PathTracingSceneGenerator.js","../src/core/MaterialReducer.js","../src/uniforms/MaterialStructUniform.js","../src/uniforms/MaterialStructArrayUniform.js","../src/uniforms/RenderTarget2DArray.js","../src/materials/MaterialBase.js","../src/shader/shaderStructs.js","../src/shader/shaderGGXFunctions.js","../src/shader/shaderMaterialSampling.js","../src/shader/shaderUtils.js","../src/materials/PhysicalPathTracingMaterial.js","../src/index.js"],"sourcesContent":["import { RGBAFormat, FloatType, Color, Vector2, WebGLRenderTarget } from 'three';\nimport { FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass.js';\n\nfunction* renderTask() {\n\n\tconst { _fsQuad, _renderer, target, camera, material } = this;\n\twhile ( true ) {\n\n\t\tmaterial.opacity = 1 / ( this.samples + 1 );\n\t\tmaterial.seed ++;\n\n\t\tconst w = target.width;\n\t\tconst h = target.height;\n\t\tcamera.setViewOffset(\n\t\t\tw, h,\n\t\t\tMath.random() - 0.5, Math.random() - 0.5,\n\t\t\tw, h,\n\t\t);\n\t\tcamera.updateProjectionMatrix();\n\n\t\tconst tx = this.tiles.x || 1;\n\t\tconst ty = this.tiles.y || 1;\n\t\tconst totalTiles = tx * ty;\n\t\tconst dprInv = ( 1 / _renderer.getPixelRatio() );\n\t\tfor ( let y = 0; y < ty; y ++ ) {\n\n\t\t\tfor ( let x = 0; x < tx; x ++ ) {\n\n\t\t\t\tmaterial.cameraWorldMatrix.copy( camera.matrixWorld );\n\t\t\t\tmaterial.invProjectionMatrix.copy( camera.projectionMatrixInverse );\n\n\t\t\t\tconst ogRenderTarget = _renderer.getRenderTarget();\n\t\t\t\tconst ogAutoClear = _renderer.autoClear;\n\n\t\t\t\t// three.js renderer takes values relative to the current pixel ratio\n\t\t\t\t_renderer.setRenderTarget( target );\n\t\t\t\t_renderer.setScissorTest( true );\n\t\t\t\t_renderer.setScissor(\n\t\t\t\t\tdprInv * Math.ceil( x * w / tx ),\n\t\t\t\t\tdprInv * Math.ceil( ( ty - y - 1 ) * h / ty ),\n\t\t\t\t\tdprInv * Math.ceil( w / tx ),\n\t\t\t\t\tdprInv * Math.ceil( h / ty ) );\n\t\t\t\t_renderer.autoClear = false;\n\t\t\t\t_fsQuad.render( _renderer );\n\n\t\t\t\t_renderer.setScissorTest( false );\n\t\t\t\t_renderer.setRenderTarget( ogRenderTarget );\n\t\t\t\t_renderer.autoClear = ogAutoClear;\n\n\t\t\t\tthis.samples += ( 1 / totalTiles );\n\n\t\t\t\tyield;\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.samples = Math.round( this.samples );\n\n\t}\n\n}\n\nconst ogClearColor = new Color();\nexport class PathTracingRenderer {\n\n\tget material() {\n\n\t\treturn this._fsQuad.material;\n\n\t}\n\n\tset material( v ) {\n\n\t\tthis._fsQuad.material = v;\n\n\t}\n\n\tconstructor( renderer ) {\n\n\t\tthis.camera = null;\n\t\tthis.tiles = new Vector2( 1, 1 );\n\t\tthis.target = new WebGLRenderTarget( 1, 1, {\n\t\t\tformat: RGBAFormat,\n\t\t\ttype: FloatType,\n\t\t} );\n\t\tthis.samples = 0;\n\t\tthis.stableNoise = false;\n\t\tthis._renderer = renderer;\n\t\tthis._fsQuad = new FullScreenQuad( null );\n\t\tthis._task = null;\n\n\t}\n\n\tsetSize( w, h ) {\n\n\t\tthis.target.setSize( w, h );\n\t\tthis.reset();\n\n\t}\n\n\treset() {\n\n\t\tconst renderer = this._renderer;\n\t\tconst target = this.target;\n\t\tconst ogRenderTarget = renderer.getRenderTarget();\n\t\tconst ogClearAlpha = renderer.getClearAlpha();\n\t\trenderer.getClearColor( ogClearColor );\n\n\t\trenderer.setRenderTarget( target );\n\t\trenderer.setClearColor( 0, 0 );\n\t\trenderer.clearColor();\n\n\t\trenderer.setClearColor( ogClearColor, ogClearAlpha );\n\t\trenderer.setRenderTarget( ogRenderTarget );\n\n\t\tthis.samples = 0;\n\t\tthis._task = null;\n\n\t\tif ( this.stableNoise ) {\n\n\t\t\tthis.material.seed = 0;\n\n\t\t}\n\n\t}\n\n\tupdate() {\n\n\t\tif ( ! this._task ) {\n\n\t\t\tthis._task = renderTask.call( this );\n\n\t\t}\n\n\t\tthis._task.next();\n\n\t}\n\n}\n","import { BufferAttribute } from 'three';\r\nimport { mergeBufferGeometries, mergeVertices } from 'three/examples/jsm/utils/BufferGeometryUtils.js';\r\nfunction getGroupMaterialIndicesAttribute( geometry, materials, allMaterials ) {\r\n\r\n\tif ( ! Array.isArray( materials ) ) {\r\n\r\n\t\tmaterials = [ materials ];\r\n\r\n\t}\r\n\r\n\tconst vertCount = geometry.attributes.position.count;\r\n\tconst materialArray = new Uint8Array( vertCount );\r\n\tlet groups = geometry.groups;\r\n\tif ( groups.length === 0 ) {\r\n\r\n\t\tgroups = [ { count: vertCount, start: 0, materialIndex: 0 } ];\r\n\r\n\t}\r\n\r\n\tfor ( let i = 0; i < groups.length; i ++ ) {\r\n\r\n\t\tconst group = groups[ i ];\r\n\t\tconst { count, start } = group;\r\n\t\tconst endCount = Math.min( count, vertCount - start );\r\n\t\tconst mat = materials[ group.materialIndex ];\r\n\t\tconst materialIndex = allMaterials.indexOf( mat );\r\n\r\n\t\tfor ( let j = 0; j < endCount; j ++ ) {\r\n\r\n\t\t\tmaterialArray[ start + j ] = materialIndex;\r\n\r\n\t\t}\r\n\r\n\t}\r\n\r\n\treturn new BufferAttribute( materialArray, 1, false );\r\n\r\n}\r\n\r\nexport function mergeMeshes( meshes, options = {} ) {\r\n\r\n\toptions = { attributes: null, cloneGeometry: true, ...options };\r\n\r\n\tconst transformedGeometry = [];\r\n\tconst materialSet = new Set();\r\n\tfor ( let i = 0, l = meshes.length; i < l; i ++ ) {\r\n\r\n\t\t// save any materials\r\n\t\tconst mesh = meshes[ i ];\r\n\t\tif ( mesh.visible === false ) continue;\r\n\r\n\t\tif ( Array.isArray( mesh.material ) ) {\r\n\r\n\t\t\tmesh.material.forEach( m => materialSet.add( m ) );\r\n\r\n\t\t} else {\r\n\r\n\t\t\tmaterialSet.add( mesh.material );\r\n\r\n\t\t}\r\n\r\n\t}\r\n\r\n\tconst materials = Array.from( materialSet );\r\n\tfor ( let i = 0, l = meshes.length; i < l; i ++ ) {\r\n\r\n\t\t// ensure the matrix world is up to date\r\n\t\tconst mesh = meshes[ i ];\r\n\t\tif ( mesh.visible === false ) continue;\r\n\r\n\t\tmesh.updateMatrixWorld();\r\n\r\n\t\t// apply the matrix world to the geometry\r\n\t\tconst originalGeometry = meshes[ i ].geometry;\r\n\t\tlet geometry = options.cloneGeometry ? originalGeometry.clone() : originalGeometry;\r\n\t\tgeometry.applyMatrix4( mesh.matrixWorld );\r\n\r\n\t\tconst attrs = options.attributes;\r\n\t\tif ( ! geometry.attributes.normal && ( attrs && attrs.includes( 'normal' ) ) ) {\r\n\r\n\t\t\tgeometry.computeVertexNormals();\r\n\r\n\t\t}\r\n\r\n\t\tif ( ! geometry.attributes.uv && ( attrs && attrs.includes( 'uv' ) ) ) {\r\n\r\n\t\t\tconst vertCount = geometry.attributes.position.count;\r\n\t\t\tgeometry.setAttribute( 'uv', new BufferAttribute( new Float32Array( vertCount * 2 ), 2, false ) );\r\n\r\n\t\t}\r\n\r\n\t\tif ( ! geometry.attributes.tangent && ( attrs && attrs.includes( 'tangent' ) ) ) {\r\n\r\n\t\t\tif ( mesh.material.normalMap ) {\r\n\r\n\t\t\t\t// computeTangents requires an index buffer\r\n\t\t\t\tif ( geometry.index === null ) {\r\n\r\n\t\t\t\t\tgeometry = mergeVertices( geometry );\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t\tgeometry.computeTangents();\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tconst vertCount = geometry.attributes.position.count;\r\n\t\t\t\tgeometry.setAttribute( 'tangent', new BufferAttribute( new Float32Array( vertCount * 4 ), 4, false ) );\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\tif ( ! geometry.index ) {\r\n\r\n\t\t\t// TODO: compute a typed array\r\n\t\t\tconst indexCount = geometry.attributes.position.count;\r\n\t\t\tconst array = new Array( indexCount );\r\n\t\t\tfor ( let i = 0; i < indexCount; i ++ ) {\r\n\r\n\t\t\t\tarray[ i ] = i;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tgeometry.setIndex( array );\r\n\r\n\t\t}\r\n\r\n\t\t// trim any unneeded attributes\r\n\t\tif ( options.attributes ) {\r\n\r\n\t\t\tfor ( const key in geometry.attributes ) {\r\n\r\n\t\t\t\tif ( ! options.attributes.includes( key ) ) {\r\n\r\n\t\t\t\t\tgeometry.deleteAttribute( key );\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\t// create the material index attribute\r\n\t\tconst materialIndexAttribute = getGroupMaterialIndicesAttribute( geometry, mesh.material, materials );\r\n\t\tgeometry.setAttribute( 'materialIndex', materialIndexAttribute );\r\n\r\n\t\ttransformedGeometry.push( geometry );\r\n\r\n\t}\r\n\r\n\tconst textureSet = new Set();\r\n\tmaterials.forEach( material => {\r\n\r\n\t\tfor ( const key in material ) {\r\n\r\n\t\t\tconst value = material[ key ];\r\n\t\t\tif ( value && value.isTexture ) {\r\n\r\n\t\t\t\ttextureSet.add( value );\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t} );\r\n\r\n\tconst geometry = mergeBufferGeometries( transformedGeometry, false );\r\n\tconst textures = Array.from( textureSet );\r\n\treturn { geometry, materials, textures };\r\n\r\n}\r\n","import { SAH } from 'three-mesh-bvh';\r\nimport { GenerateMeshBVHWorker } from 'three-mesh-bvh/src/workers/GenerateMeshBVHWorker.js';\r\nimport { mergeMeshes } from '../utils/GeometryPreparationUtils.js';\r\n\r\nexport class PathTracingSceneGenerator {\r\n\r\n\tconstructor() {\r\n\r\n\t\tthis.bvhGenerator = new GenerateMeshBVHWorker();\r\n\r\n\t}\r\n\r\n\tasync generate( scene, options = {} ) {\r\n\r\n\t\tconst { bvhGenerator } = this;\r\n\t\tconst meshes = [];\r\n\r\n\t\tscene.traverse( c => {\r\n\r\n\t\t\tif ( c.isMesh ) {\r\n\r\n\t\t\t\tmeshes.push( c );\r\n\r\n\t\t\t}\r\n\r\n\t\t} );\r\n\r\n\t\tconst { geometry, materials, textures } = mergeMeshes( meshes, { attributes: [ 'position', 'normal', 'tangent', 'uv' ] } );\r\n\t\tconst bvhPromise = bvhGenerator.generate( geometry, { strategy: SAH, ...options, maxLeafTris: 1 } );\r\n\r\n\t\treturn {\r\n\t\t\tscene,\r\n\t\t\tmaterials,\r\n\t\t\ttextures,\r\n\t\t\tbvh: await bvhPromise,\r\n\t\t};\r\n\r\n\t}\r\n\r\n\tdispose() {\r\n\r\n\t\tthis.bvhGenerator.terminate();\r\n\r\n\t}\r\n\r\n}\r\n","// https://github.com/gkjohnson/webxr-sandbox/blob/main/skinned-mesh-batching/src/MaterialReducer.js\r\n\r\nfunction isTypedArray( arr ) {\r\n\r\n\treturn arr.buffer instanceof ArrayBuffer && 'BYTES_PER_ELEMENT' in arr;\r\n\r\n}\r\n\r\nexport class MaterialReducer {\r\n\r\n\tconstructor() {\r\n\r\n\t\tconst ignoreKeys = new Set();\r\n\t\tignoreKeys.add( 'uuid' );\r\n\r\n\t\tthis.ignoreKeys = ignoreKeys;\r\n\t\tthis.shareTextures = true;\r\n\t\tthis.textures = [];\r\n\t\tthis.materials = [];\r\n\r\n\t}\r\n\r\n\tareEqual( objectA, objectB ) {\r\n\r\n\t\tconst keySet = new Set();\r\n\t\tconst traverseSet = new Set();\r\n\t\tconst ignoreKeys = this.ignoreKeys;\r\n\r\n\t\tconst traverse = ( a, b ) => {\r\n\r\n\t\t\tif ( a === b ) {\r\n\r\n\t\t\t\treturn true;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tif ( a && b && a instanceof Object && b instanceof Object ) {\r\n\r\n\t\t\t\tif ( traverseSet.has( a ) || traverseSet.has( b ) ) {\r\n\r\n\t\t\t\t\tthrow new Error( 'MaterialReducer: Material is recursive.' );\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst aIsElement = a instanceof Element;\r\n\t\t\t\tconst bIsElement = b instanceof Element;\r\n\t\t\t\tif ( aIsElement || bIsElement ) {\r\n\r\n\t\t\t\t\tif ( aIsElement !== bIsElement || ! ( a instanceof Image ) || ! ( b instanceof Image ) ) {\r\n\r\n\t\t\t\t\t\treturn false;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\treturn a.src === b.src;\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst aIsImageBitmap = a instanceof ImageBitmap;\r\n\t\t\t\tconst bIsImageBitmap = b instanceof ImageBitmap;\r\n\t\t\t\tif ( aIsImageBitmap || bIsImageBitmap ) {\r\n\r\n\t\t\t\t\treturn false;\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif ( a.equals ) {\r\n\r\n\t\t\t\t\treturn a.equals( b );\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst aIsTypedArray = isTypedArray( a );\r\n\t\t\t\tconst bIsTypedArray = isTypedArray( b );\r\n\t\t\t\tif ( aIsTypedArray || bIsTypedArray ) {\r\n\r\n\t\t\t\t\tif ( aIsTypedArray !== bIsTypedArray || a.constructor !== b.constructor || a.length !== b.length ) {\r\n\r\n\t\t\t\t\t\treturn false;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tfor ( let i = 0, l = a.length; i < l; i ++ ) {\r\n\r\n\t\t\t\t\t\tif ( a[ i ] !== b[ i ] ) return false;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\treturn true;\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t\ttraverseSet.add( a );\r\n\t\t\t\ttraverseSet.add( b );\r\n\r\n\t\t\t\tkeySet.clear();\r\n\t\t\t\tfor ( const key in a ) {\r\n\r\n\t\t\t\t\tif ( ! a.hasOwnProperty( key ) || a[ key ] instanceof Function || ignoreKeys.has( key ) ) {\r\n\r\n\t\t\t\t\t\tcontinue;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tkeySet.add( key );\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t\tfor ( const key in b ) {\r\n\r\n\t\t\t\t\tif ( ! b.hasOwnProperty( key ) || b[ key ] instanceof Function || ignoreKeys.has( key ) ) {\r\n\r\n\t\t\t\t\t\tcontinue;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tkeySet.add( key );\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst keys = Array.from( keySet.values() );\r\n\t\t\t\tlet result = true;\r\n\t\t\t\tfor ( const i in keys ) {\r\n\r\n\t\t\t\t\tconst key = keys[ i ];\r\n\t\t\t\t\tif ( ignoreKeys.has( key ) ) {\r\n\r\n\t\t\t\t\t\tcontinue;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tresult = traverse( a[ key ], b[ key ] );\r\n\t\t\t\t\tif ( ! result ) {\r\n\r\n\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t\ttraverseSet.delete( a );\r\n\t\t\t\ttraverseSet.delete( b );\r\n\t\t\t\treturn result;\r\n\r\n\t\t\t}\r\n\r\n\t\t\treturn false;\r\n\r\n\t\t};\r\n\r\n\t\treturn traverse( objectA, objectB );\r\n\r\n\t}\r\n\r\n\tprocess( object ) {\r\n\r\n\t\tconst { textures, materials } = this;\r\n\t\tlet replaced = 0;\r\n\r\n\t\tconst processMaterial = material => {\r\n\r\n\t\t\t// Check if another material matches this one\r\n\t\t\tlet foundMaterial = null;\r\n\t\t\tfor ( const i in materials ) {\r\n\r\n\t\t\t\tconst otherMaterial = materials[ i ];\r\n\t\t\t\tif ( this.areEqual( material, otherMaterial ) ) {\r\n\r\n\t\t\t\t\tfoundMaterial = otherMaterial;\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t}\r\n\r\n\t\t\tif ( foundMaterial ) {\r\n\r\n\t\t\t\treplaced ++;\r\n\t\t\t\treturn foundMaterial;\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tmaterials.push( material );\r\n\r\n\t\t\t\tif ( this.shareTextures ) {\r\n\r\n\t\t\t\t\t// See if there's another texture that matches the ones on this material\r\n\t\t\t\t\tfor ( const key in material ) {\r\n\r\n\t\t\t\t\t\tif ( ! material.hasOwnProperty( key ) ) continue;\r\n\r\n\t\t\t\t\t\tconst value = material[ key ];\r\n\t\t\t\t\t\tif ( value && value.isTexture && value.image instanceof Image ) {\r\n\r\n\t\t\t\t\t\t\tlet foundTexture = null;\r\n\t\t\t\t\t\t\tfor ( const i in textures ) {\r\n\r\n\t\t\t\t\t\t\t\tconst texture = textures[ i ];\r\n\t\t\t\t\t\t\t\tif ( this.areEqual( texture, value ) ) {\r\n\r\n\t\t\t\t\t\t\t\t\tfoundTexture = texture;\r\n\t\t\t\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\tif ( foundTexture ) {\r\n\r\n\t\t\t\t\t\t\t\tmaterial[ key ] = foundTexture;\r\n\r\n\t\t\t\t\t\t\t} else {\r\n\r\n\t\t\t\t\t\t\t\ttextures.push( value );\r\n\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn material;\r\n\r\n\t\t\t}\r\n\r\n\t\t};\r\n\r\n\t\tobject.traverse( c => {\r\n\r\n\t\t\tif ( c.isMesh && c.material ) {\r\n\r\n\t\t\t\tconst material = c.material;\r\n\t\t\t\tif ( Array.isArray( material ) ) {\r\n\r\n\t\t\t\t\tfor ( let i = 0; i < material.length; i ++ ) {\r\n\r\n\t\t\t\t\t\tmaterial[ i ] = processMaterial( material[ i ] );\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t} else {\r\n\r\n\t\t\t\t\tc.material = processMaterial( material );\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t}\r\n\r\n\t\t} );\r\n\r\n\t\treturn { replaced, retained: materials.length };\r\n\r\n\t}\r\n\r\n}\r\n","import { Color, Vector2 } from 'three';\r\nexport class MaterialStructUniform {\r\n\r\n\tconstructor() {\r\n\r\n\t\tthis.init();\r\n\r\n\t}\r\n\r\n\tinit() {\r\n\r\n\t\tthis.color = new Color( 0xffffff );\r\n\t\tthis.map = - 1;\r\n\r\n\t\tthis.metalness = 1.0;\r\n\t\tthis.metalnessMap = - 1;\r\n\r\n\t\tthis.roughness = 1.0;\r\n\t\tthis.roughnessMap = - 1;\r\n\r\n\t\tthis.ior = 1.0;\r\n\t\tthis.transmission = 0.0;\r\n\t\tthis.transmissionMap = - 1;\r\n\r\n\t\tthis.emissive = new Color( 0 );\r\n\t\tthis.emissiveIntensity = 1.0;\r\n\t\tthis.emissiveMap = - 1;\r\n\r\n\t\tthis.normalMap = - 1;\r\n\t\tthis.normalScale = new Vector2( 1, 1 );\r\n\r\n\t\tthis.opacity = 1.0;\r\n\t\tthis.alphaTest = 0.0;\r\n\r\n\t\t// TODO: Clearcoat\r\n\r\n\t\t// TODO: Sheen\r\n\r\n\t}\r\n\r\n\tupdateFrom( material, textures = [] ) {\r\n\r\n\t\tthis.init();\r\n\r\n\t\t// color\r\n\t\tif ( 'color' in material ) this.color.copy( material.color );\r\n\t\telse material.color.set( 0xffffff );\r\n\r\n\t\tthis.map = textures.indexOf( material.map );\r\n\r\n\t\t// metalness\r\n\t\tif ( 'metalness' in material ) this.metalness = material.metalness;\r\n\t\telse this.metalness = 1.0;\r\n\r\n\t\tthis.metalnessMap = textures.indexOf( material.metalnessMap );\r\n\r\n\t\t// roughness\r\n\t\tif ( 'roughness' in material ) this.roughness = material.roughness;\r\n\t\telse this.roughness = 1.0;\r\n\r\n\t\tthis.roughnessMap = textures.indexOf( material.roughnessMap );\r\n\r\n\t\t// transmission\r\n\t\tif ( 'ior' in material ) this.ior = material.ior;\r\n\t\telse this.ior = 1.0;\r\n\r\n\t\tif ( 'transmission' in material ) this.transmission = material.transmission;\r\n\t\telse this.transmission = 0.0;\r\n\r\n\t\tif ( 'transmissionMap' in material ) this.transmissionMap = textures.indexOf( material.transmissionMap );\r\n\r\n\t\t// emission\r\n\t\tif ( 'emissive' in material ) this.emissive.copy( material.emissive );\r\n\t\telse this.emissive.set( 0 );\r\n\r\n\t\tif ( 'emissiveIntensity' in material ) this.emissiveIntensity = material.emissiveIntensity;\r\n\t\telse this.emissiveIntensity = 1.0;\r\n\r\n\t\tthis.emissiveMap = textures.indexOf( material.emissiveMap );\r\n\r\n\t\t// normals\r\n\t\tthis.normalMap = textures.indexOf( material.normalMap );\r\n\t\tif ( 'normalScale' in material ) this.normalScale.copy( material.normalScale );\r\n\t\telse this.normalScale.set( 1, 1 );\r\n\r\n\t\t// opacity\r\n\t\tthis.opacity = material.opacity;\r\n\r\n\t\t// alpha test\r\n\t\tthis.alphaTest = material.alphaTest;\r\n\r\n\t}\r\n\r\n}\r\n","import { MaterialStructUniform } from './MaterialStructUniform.js';\r\n\r\nexport class MaterialStructArrayUniform extends Array {\r\n\r\n\tupdateFrom( materials, textures ) {\r\n\r\n\t\twhile ( this.length > materials.length ) this.pop();\r\n\t\twhile ( this.length < materials.length ) this.push( new MaterialStructUniform() );\r\n\r\n\t\tfor ( let i = 0, l = this.length; i < l; i ++ ) {\r\n\r\n\t\t\tthis[ i ].updateFrom( materials[ i ], textures );\r\n\r\n\t\t}\r\n\r\n\t}\r\n\r\n}\r\n","import {\r\n\tWebGLArrayRenderTarget,\r\n\tRGBAFormat,\r\n\tUnsignedByteType,\r\n\tMeshBasicMaterial,\r\n\tColor,\r\n\tRepeatWrapping,\r\n\tLinearFilter,\r\n\tNoToneMapping,\r\n} from 'three';\r\nimport { FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass.js';\r\n\r\nconst prevColor = new Color();\r\nexport class RenderTarget2DArray extends WebGLArrayRenderTarget {\r\n\r\n\tconstructor( ...args ) {\r\n\r\n\t\tsuper( ...args );\r\n\r\n\t\tconst tex = this.texture;\r\n\t\ttex.format = RGBAFormat;\r\n\t\ttex.type = UnsignedByteType;\r\n\t\ttex.minFilter = LinearFilter;\r\n\t\ttex.magFilter = LinearFilter;\r\n\t\ttex.wrapS = RepeatWrapping;\r\n\t\ttex.wrapT = RepeatWrapping;\r\n\t\ttex.setTextures = ( ...args ) => {\r\n\r\n\t\t\tthis.setTextures( ...args );\r\n\r\n\t\t};\r\n\r\n\t\tconst fsQuad = new FullScreenQuad( new MeshBasicMaterial() );\r\n\t\tthis.fsQuad = fsQuad;\r\n\r\n\t}\r\n\r\n\tsetTextures( renderer, width, height, textures ) {\r\n\r\n\t\t// save previous renderer state\r\n\t\tconst prevRenderTarget = renderer.getRenderTarget();\r\n\t\tconst prevToneMapping = renderer.toneMapping;\r\n\t\tconst prevAlpha = renderer.getClearAlpha();\r\n\t\trenderer.getClearColor( prevColor );\r\n\r\n\t\t// resize the render target\r\n\t\tconst depth = textures.length;\r\n\t\tthis.setSize( width, height, depth );\r\n\t\trenderer.setClearColor( 0, 0 );\r\n\t\trenderer.toneMapping = NoToneMapping;\r\n\r\n\t\t// render each texture into each layer of the target\r\n\t\tconst fsQuad = this.fsQuad;\r\n\t\tfor ( let i = 0, l = depth; i < l; i ++ ) {\r\n\r\n\t\t\tconst texture = textures[ i ];\r\n\t\t\tfsQuad.material.map = texture;\r\n\t\t\tfsQuad.material.transparent = true;\r\n\r\n\t\t\trenderer.setRenderTarget( this, i );\r\n\t\t\tfsQuad.render( renderer );\r\n\r\n\t\t}\r\n\r\n\t\t// reset the renderer\r\n\t\tfsQuad.material.map = null;\r\n\t\trenderer.setClearColor( prevColor, prevAlpha );\r\n\t\trenderer.setRenderTarget( prevRenderTarget );\r\n\t\trenderer.toneMapping = prevToneMapping;\r\n\r\n\t}\r\n\r\n\tdispose() {\r\n\r\n\t\tsuper.dispose();\r\n\t\tthis.fsQuad.dispose();\r\n\r\n\t}\r\n\r\n}\r\n","import { ShaderMaterial } from 'three';\r\n\r\nexport class MaterialBase extends ShaderMaterial {\r\n\r\n\tconstructor( shader ) {\r\n\r\n\t\tsuper( shader );\r\n\r\n\t\tfor ( const key in this.uniforms ) {\r\n\r\n\t\t\tObject.defineProperty( this, key, {\r\n\r\n\t\t\t\tget() {\r\n\r\n\t\t\t\t\treturn this.uniforms[ key ].value;\r\n\r\n\t\t\t\t},\r\n\r\n\t\t\t\tset( v ) {\r\n\r\n\t\t\t\t\tthis.uniforms[ key ].value = v;\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t} );\r\n\r\n\t\t}\r\n\r\n\t}\r\n\r\n\t// sets the given named define value and sets \"needsUpdate\" to true if it's different\r\n\tsetDefine( name, value = undefined ) {\r\n\r\n\t\tif ( value === undefined || value === null ) {\r\n\r\n\t\t\tif ( name in this.defines ) {\r\n\r\n\t\t\t\tdelete this.defines[ name ];\r\n\t\t\t\tthis.needsUpdate = true;\r\n\r\n\t\t\t}\r\n\r\n\t\t} else {\r\n\r\n\t\t\tif ( this.defines[ name ] !== value ) {\r\n\r\n\t\t\t\tthis.defines[ name ] = value;\r\n\t\t\t\tthis.needsUpdate = true;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t}\r\n\r\n}\r\n","export const shaderMaterialStructs = /* glsl */ `\r\n\r\n\tstruct Material {\r\n\r\n\t\tvec3 color;\r\n\t\tint map;\r\n\r\n\t\tfloat metalness;\r\n\t\tint metalnessMap;\r\n\r\n\t\tfloat roughness;\r\n\t\tint roughnessMap;\r\n\r\n\t\tfloat ior;\r\n\t\tfloat transmission;\r\n\t\tint transmissionMap;\r\n\r\n\t\tvec3 emissive;\r\n\t\tfloat emissiveIntensity;\r\n\t\tint emissiveMap;\r\n\r\n\t\tint normalMap;\r\n\t\tvec2 normalScale;\r\n\r\n\t\tfloat opacity;\r\n\t\tfloat alphaTest;\r\n\r\n\t};\r\n\r\n`;\r\n","export const shaderGGXFunctions = /* glsl */`\r\n// The GGX functions provide sampling and distribution information for normals as output so\r\n// in order to get probability of scatter direction the half vector must be computed and provided.\r\n// [0] https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf\r\n// [1] https://hal.archives-ouvertes.fr/hal-01509746/document\r\n// [2] http://jcgt.org/published/0007/04/01/\r\n// [4] http://jcgt.org/published/0003/02/03/\r\n\r\n// trowbridge-reitz === GGX === GTR\r\n\r\nvec3 ggxDirection( vec3 incidentDir, float roughnessX, float roughnessY, float random1, float random2 ) {\r\n\r\n\t// TODO: try GGXVNDF implementation from reference [2], here. Needs to update ggxDistribution\r\n\t// function below, as well\r\n\r\n\t// Implementation from reference [1]\r\n\t// stretch view\r\n\tvec3 V = normalize( vec3( roughnessX * incidentDir.x, roughnessY * incidentDir.y, incidentDir.z ) );\r\n\r\n\t// orthonormal basis\r\n\tvec3 T1 = ( V.z < 0.9999 ) ? normalize( cross( V, vec3( 0.0, 0.0, 1.0 ) ) ) : vec3( 1.0, 0.0, 0.0 );\r\n\tvec3 T2 = cross( T1, V );\r\n\r\n\t// sample point with polar coordinates (r, phi)\r\n\tfloat a = 1.0 / ( 1.0 + V.z );\r\n\tfloat r = sqrt( random1 );\r\n\tfloat phi = ( random2 < a ) ? random2 / a * PI : PI + ( random2 - a ) / ( 1.0 - a ) * PI;\r\n\tfloat P1 = r * cos( phi );\r\n\tfloat P2 = r * sin( phi ) * ( ( random2 < a ) ? 1.0 : V.z );\r\n\r\n\t// compute normal\r\n\tvec3 N = P1 * T1 + P2 * T2 + V * sqrt( max( 0.0, 1.0 - P1 * P1 - P2 * P2 ) );\r\n\r\n\t// unstretch\r\n\tN = normalize( vec3( roughnessX * N.x, roughnessY * N.y, max( 0.0, N.z ) ) );\r\n\r\n\treturn N;\r\n\r\n}\r\n\r\n// Below are PDF and related functions for use in a Monte Carlo path tracer\r\n// as specified in Appendix B of the following paper\r\n// See equation (2) from reference [2]\r\nfloat ggxLamda( float theta, float roughness ) {\r\n\r\n\tfloat tanTheta = tan( theta );\r\n\tfloat tanTheta2 = tanTheta * tanTheta;\r\n\tfloat alpha2 = roughness * roughness;\r\n\r\n\tfloat numerator = - 1.0 + sqrt( 1.0 + alpha2 * tanTheta2 );\r\n\treturn numerator / 2.0;\r\n\r\n}\r\n\r\n// See equation (2) from reference [2]\r\nfloat ggxShadowMaskG1( float theta, float roughness ) {\r\n\r\n\treturn 1.0 / ( 1.0 + ggxLamda( theta, roughness ) );\r\n\r\n}\r\n\r\n// See equation (125) from reference [4]\r\nfloat ggxShadowMaskG2( vec3 wi, vec3 wo, float roughness ) {\r\n\r\n\tfloat incidentTheta = acos( wi.z );\r\n\tfloat scatterTheta = acos( wo.z );\r\n\treturn 1.0 / ( 1.0 + ggxLamda( incidentTheta, roughness ) + ggxLamda( scatterTheta, roughness ) );\r\n\r\n}\r\n\r\nfloat ggxDistribution( vec3 halfVector, float roughness ) {\r\n\r\n\t// See equation (33) from reference [0]\r\n\tfloat a2 = roughness * roughness;\r\n\tfloat cosTheta = halfVector.z;\r\n\tfloat cosTheta4 = pow( cosTheta, 4.0 );\r\n\r\n\tif ( cosTheta == 0.0 ) return 0.0;\r\n\r\n\tfloat theta = acos( halfVector.z );\r\n\tfloat tanTheta = tan( theta );\r\n\tfloat tanTheta2 = pow( tanTheta, 2.0 );\r\n\r\n\tfloat denom = PI * cosTheta4 * pow( a2 + tanTheta2, 2.0 );\r\n\treturn a2 / denom;\r\n\r\n\t// See equation (1) from reference [2]\r\n\t// const { x, y, z } = halfVector;\r\n\t// const a2 = roughness * roughness;\r\n\t// const mult = x * x / a2 + y * y / a2 + z * z;\r\n\t// const mult2 = mult * mult;\r\n\r\n\t// return 1.0 / Math.PI * a2 * mult2;\r\n\r\n}\r\n\r\n// See equation (3) from reference [2]\r\nfloat ggxPDF( vec3 wi, vec3 halfVector, float roughness ) {\r\n\r\n\tfloat incidentTheta = acos( wi.z );\r\n\tfloat D = ggxDistribution( halfVector, roughness );\r\n\tfloat G1 = ggxShadowMaskG1( incidentTheta, roughness );\r\n\r\n\treturn D * G1 * max( 0.0, dot( wi, halfVector ) ) / wi.z;\r\n\r\n}\r\n`;\r\n","import { shaderGGXFunctions } from './shaderGGXFunctions.js';\r\n\r\nexport const shaderMaterialSampling = /* glsl */`\r\n\r\nstruct SurfaceRec {\r\n\tvec3 normal;\r\n\tvec3 faceNormal;\r\n\tbool frontFace;\r\n\tfloat roughness;\r\n\tfloat filteredRoughness;\r\n\tfloat metalness;\r\n\tvec3 color;\r\n\tvec3 emission;\r\n\tfloat transmission;\r\n\tfloat ior;\r\n};\r\n\r\nstruct SampleRec {\r\n\tfloat pdf;\r\n\tvec3 direction;\r\n\tvec3 color;\r\n};\r\n\r\n${ shaderGGXFunctions }\r\n\r\n// diffuse\r\nfloat diffusePDF( vec3 wo, vec3 wi, SurfaceRec surf ) {\r\n\r\n\t// https://raytracing.github.io/books/RayTracingTheRestOfYourLife.html#lightscattering/thescatteringpdf\r\n\tfloat cosValue = wi.z;\r\n\treturn cosValue / PI;\r\n\r\n}\r\n\r\nvec3 diffuseDirection( vec3 wo, SurfaceRec surf ) {\r\n\r\n\tvec3 lightDirection = randDirection();\r\n\tlightDirection.z += 1.0;\r\n\tlightDirection = normalize( lightDirection );\r\n\r\n\treturn lightDirection;\r\n\r\n}\r\n\r\nvec3 diffuseColor( vec3 wo, vec3 wi, SurfaceRec surf ) {\r\n\r\n\t// TODO: scale by 1 - F here\r\n\t// note on division by PI\r\n\t// https://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/\r\n\tfloat metalFactor = ( 1.0 - surf.metalness ) * wi.z / ( PI * PI );\r\n\tfloat transmissionFactor = 1.0 - surf.transmission;\r\n\treturn surf.color * metalFactor * transmissionFactor;\r\n\r\n}\r\n\r\n// specular\r\nfloat specularPDF( vec3 wo, vec3 wi, SurfaceRec surf ) {\r\n\r\n\t// See equation (17) in http://jcgt.org/published/0003/02/03/\r\n\tfloat filteredRoughness = surf.filteredRoughness;\r\n\tvec3 halfVector = getHalfVector( wi, wo );\r\n\treturn ggxPDF( wi, halfVector, filteredRoughness ) / ( 4.0 * dot( wi, halfVector ) );\r\n\r\n}\r\n\r\nvec3 specularDirection( vec3 wo, SurfaceRec surf ) {\r\n\r\n\t// sample ggx vndf distribution which gives a new normal\r\n\tfloat filteredRoughness = surf.filteredRoughness;\r\n\tvec3 halfVector = ggxDirection(\r\n\t\two,\r\n\t\tfilteredRoughness,\r\n\t\tfilteredRoughness,\r\n\t\trand(),\r\n\t\trand()\r\n\t);\r\n\r\n\t// apply to new ray by reflecting off the new normal\r\n\treturn - reflect( wo, halfVector );\r\n\r\n}\r\n\r\nvec3 specularColor( vec3 wo, vec3 wi, SurfaceRec surf ) {\r\n\r\n\t// if roughness is set to 0 then D === NaN which results in black pixels\r\n\tfloat metalness = surf.metalness;\r\n\tfloat ior = surf.ior;\r\n\tbool frontFace = surf.frontFace;\r\n\tfloat filteredRoughness = surf.filteredRoughness;\r\n\r\n\tvec3 halfVector = getHalfVector( wo, wi );\r\n\tfloat iorRatio = frontFace ? 1.0 / ior : ior;\r\n\tfloat G = ggxShadowMaskG2( wi, wo, filteredRoughness );\r\n\tfloat D = ggxDistribution( halfVector, filteredRoughness );\r\n\r\n\tfloat F = schlickFresnelFromIor( dot( wi, halfVector ), iorRatio );\r\n\tfloat cosTheta = min( wo.z, 1.0 );\r\n\tfloat sinTheta = sqrt( 1.0 - cosTheta * cosTheta );\r\n\tbool cannotRefract = iorRatio * sinTheta > 1.0;\r\n\tif ( cannotRefract ) {\r\n\r\n\t\tF = 1.0;\r\n\r\n\t}\r\n\r\n\tvec3 color = mix( vec3( 1.0 ), surf.color, metalness );\r\n\tcolor = mix( color, vec3( 1.0 ), F );\r\n\tcolor *= G * D / ( 4.0 * abs( wi.z * wo.z ) );\r\n\tcolor *= mix( F, 1.0, metalness );\r\n\tcolor *= wi.z; // scale the light by the direction the light is coming in from\r\n\r\n\treturn color;\r\n\r\n}\r\n\r\n/*\r\n// transmission\r\nfunction transmissionPDF( wo, wi, material, surf ) {\r\n\r\n\t// See section 4.2 in https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf\r\n\r\n\tconst { roughness, ior } = material;\r\n\tconst { frontFace } = hit;\r\n\tconst ratio = frontFace ? ior : 1 / ior;\r\n\tconst minRoughness = Math.max( roughness, MIN_ROUGHNESS );\r\n\r\n\thalfVector.set( 0, 0, 0 ).addScaledVector( wi, ratio ).addScaledVector( wo, 1.0 ).normalize().multiplyScalar( - 1 );\r\n\r\n\tconst denom = Math.pow( ratio * halfVector.dot( wi ) + 1.0 * halfVector.dot( wo ), 2.0 );\r\n\treturn ggxPDF( wo, halfVector, minRoughness ) / denom;\r\n\r\n}\r\n\r\nfunction transmissionDirection( wo, hit, material, lightDirection ) {\r\n\r\n\tconst { roughness, ior } = material;\r\n\tconst { frontFace } = hit;\r\n\tconst ratio = frontFace ? 1 / ior : ior;\r\n\tconst minRoughness = Math.max( roughness, MIN_ROUGHNESS );\r\n\r\n\t// sample ggx vndf distribution which gives a new normal\r\n\tggxDirection(\r\n\t\two,\r\n\t\tminRoughness,\r\n\t\tminRoughness,\r\n\t\tMath.random(),\r\n\t\tMath.random(),\r\n\t\thalfVector,\r\n\t);\r\n\r\n\t// apply to new ray by reflecting off the new normal\r\n\ttempDir.copy( wo ).multiplyScalar( - 1 );\r\n\trefract( tempDir, halfVector, ratio, lightDirection );\r\n\r\n}\r\n\r\nfunction transmissionColor( wo, wi, material, hit, colorTarget ) {\r\n\r\n\tconst { metalness, transmission } = material;\r\n\tcolorTarget\r\n\t\t.copy( material.color )\r\n\t\t.multiplyScalar( ( 1.0 - metalness ) * wo.z )\r\n\t\t.multiplyScalar( transmission );\r\n\r\n}\r\n*/\r\n\r\n// TODO: This is just using a basic cosine-weighted specular distribution with an\r\n// incorrect PDF value at the moment. Update it to correctly use a GGX distribution\r\nfloat transmissionPDF( vec3 wo, vec3 wi, SurfaceRec surf ) {\r\n\r\n\tfloat ior = surf.ior;\r\n\tbool frontFace = surf.frontFace;\r\n\r\n\tfloat ratio = frontFace ? 1.0 / ior : ior;\r\n\tfloat cosTheta = min( wo.z, 1.0 );\r\n\tfloat sinTheta = sqrt( 1.0 - cosTheta * cosTheta );\r\n\tfloat reflectance = schlickFresnelFromIor( cosTheta, ratio );\r\n\tbool cannotRefract = ratio * sinTheta > 1.0;\r\n\tif ( cannotRefract ) {\r\n\r\n\t\treturn 0.0;\r\n\r\n\t}\r\n\r\n\treturn 1.0 / ( 1.0 - reflectance );\r\n\r\n}\r\n\r\nvec3 transmissionDirection( vec3 wo, SurfaceRec surf ) {\r\n\r\n\tfloat roughness = surf.roughness;\r\n\tfloat ior = surf.ior;\r\n\tbool frontFace = surf.frontFace;\r\n\tfloat ratio = frontFace ? 1.0 / ior : ior;\r\n\r\n\tvec3 lightDirection = refract( - wo, vec3( 0.0, 0.0, 1.0 ), ratio );\r\n\tlightDirection += randDirection() * roughness;\r\n\treturn normalize( lightDirection );\r\n\r\n}\r\n\r\nvec3 transmissionColor( vec3 wo, vec3 wi, SurfaceRec surf ) {\r\n\r\n\tfloat metalness = surf.metalness;\r\n\tfloat transmission = surf.transmission;\r\n\r\n\tvec3 color = surf.color;\r\n\tcolor *= ( 1.0 - metalness );\r\n\tcolor *= transmission;\r\n\r\n\treturn color;\r\n\r\n}\r\n\r\nfloat bsdfPdf( vec3 wo, vec3 wi, SurfaceRec surf ) {\r\n\r\n\tfloat ior = surf.ior;\r\n\tfloat metalness = surf.metalness;\r\n\tfloat transmission = surf.transmission;\r\n\tbool frontFace = surf.frontFace;\r\n\r\n\tfloat ratio = frontFace ? 1.0 / ior : ior;\r\n\tfloat cosTheta = min( wo.z, 1.0 );\r\n\tfloat sinTheta = sqrt( 1.0 - cosTheta * cosTheta );\r\n\tfloat reflectance = schlickFresnelFromIor( cosTheta, ratio );\r\n\tbool cannotRefract = ratio * sinTheta > 1.0;\r\n\tif ( cannotRefract ) {\r\n\r\n\t\treflectance = 1.0;\r\n\r\n\t}\r\n\r\n\tfloat spdf = 0.0;\r\n\tfloat dpdf = 0.0;\r\n\tfloat tpdf = 0.0;\r\n\r\n\tif ( wi.z < 0.0 ) {\r\n\r\n\t\ttpdf = transmissionPDF( wo, wi, surf );\r\n\r\n\t} else {\r\n\r\n\t\tspdf = specularPDF( wo, wi, surf );\r\n\t\tdpdf = diffusePDF( wo, wi, surf );\r\n\r\n\t}\r\n\r\n\tfloat transSpecularProb = mix( reflectance, 1.0, metalness );\r\n\tfloat diffSpecularProb = 0.5 + 0.5 * metalness;\r\n\tfloat pdf =\r\n\t\tspdf * transmission * transSpecularProb\r\n\t\t+ tpdf * transmission * ( 1.0 - transSpecularProb )\r\n\t\t+ spdf * ( 1.0 - transmission ) * diffSpecularProb\r\n\t\t+ dpdf * ( 1.0 - transmission ) * ( 1.0 - diffSpecularProb );\r\n\r\n\treturn pdf;\r\n\r\n}\r\n\r\nvec3 bsdfColor( vec3 wo, vec3 wi, SurfaceRec surf ) {\r\n\r\n\tvec3 color = vec3( 0.0 );\r\n\tif ( wi.z < 0.0 ) {\r\n\r\n\t\tcolor = transmissionColor( wo, wi, surf );\r\n\r\n\t} else {\r\n\r\n\t\tcolor = diffuseColor( wo, wi, surf );\r\n\t\tcolor *= 1.0 - surf.transmission;\r\n\r\n\t\tcolor += specularColor( wo, wi, surf );\r\n\r\n\t}\r\n\r\n\treturn color;\r\n\r\n}\r\n\r\nSampleRec bsdfSample( vec3 wo, SurfaceRec surf ) {\r\n\r\n\tfloat ior = surf.ior;\r\n\tfloat metalness = surf.metalness;\r\n\tfloat transmission = surf.transmission;\r\n\tbool frontFace = surf.frontFace;\r\n\r\n\tfloat ratio = frontFace ? 1.0 / ior : ior;\r\n\tfloat cosTheta = min( wo.z, 1.0 );\r\n\tfloat sinTheta = sqrt( 1.0 - cosTheta * cosTheta );\r\n\tfloat reflectance = schlickFresnelFromIor( cosTheta, ratio );\r\n\tbool cannotRefract = ratio * sinTheta > 1.0;\r\n\tif ( cannotRefract ) {\r\n\r\n\t\treflectance = 1.0;\r\n\r\n\t}\r\n\r\n\tSampleRec result;\r\n\tif ( rand() < transmission ) {\r\n\r\n\t\tfloat specularProb = mix( reflectance, 1.0, metalness );\r\n\t\tif ( rand() < specularProb ) {\r\n\r\n\t\t\tresult.direction = specularDirection( wo, surf );\r\n\r\n\t\t} else {\r\n\r\n\t\t\tresult.direction = transmissionDirection( wo, surf );\r\n\r\n\t\t}\r\n\r\n\t} else {\r\n\r\n\t\tfloat specularProb = 0.5 + 0.5 * metalness;\r\n\t\tif ( rand() < specularProb ) {\r\n\r\n\t\t\tresult.direction = specularDirection( wo, surf );\r\n\r\n\t\t} else {\r\n\r\n\t\t\tresult.direction = diffuseDirection( wo, surf );\r\n\r\n\t\t}\r\n\r\n\t}\r\n\r\n\tresult.pdf = bsdfPdf( wo, result.direction, surf );\r\n\tresult.color = bsdfColor( wo, result.direction, surf );\r\n\treturn result;\r\n\r\n}\r\n`;\r\n","export const shaderUtils = /* glsl */`\r\n\r\n\t// https://google.github.io/filament/Filament.md.html#materialsystem/diffusebrdf\r\n\tfloat schlickFresnel( float cosine, float f0 ) {\r\n\r\n\t\treturn f0 + ( 1.0 - f0 ) * pow( 1.0 - cosine, 5.0 );\r\n\r\n\t}\r\n\r\n\t// https://raytracing.github.io/books/RayTracingInOneWeekend.html#dielectrics/schlickapproximation\r\n\tfloat schlickFresnelFromIor( float cosine, float iorRatio ) {\r\n\r\n\t\t// Schlick approximation\r\n\t\tfloat r_0 = pow( ( 1.0 - iorRatio ) / ( 1.0 + iorRatio ), 2.0 );\r\n\t\treturn schlickFresnel( cosine, r_0 );\r\n\r\n\t}\r\n\r\n\t// forms a basis with the normal vector as Z\r\n\tmat3 getBasisFromNormal( vec3 normal ) {\r\n\r\n\t\tvec3 other;\r\n\t\tif ( abs( normal.x ) > 0.5 ) {\r\n\r\n\t\t\tother = vec3( 0.0, 1.0, 0.0 );\r\n\r\n\t\t} else {\r\n\r\n\t\t\tother = vec3( 1.0, 0.0, 0.0 );\r\n\r\n\t\t}\r\n\r\n\t\tvec3 ortho = normalize( cross( normal, other ) );\r\n\t\tvec3 ortho2 = normalize( cross( normal, ortho ) );\r\n\t\treturn mat3( ortho2, ortho, normal );\r\n\r\n\t}\r\n\r\n\tvec3 getHalfVector( vec3 a, vec3 b ) {\r\n\r\n\t\treturn normalize( a + b );\r\n\r\n\t}\r\n\r\n\t// The discrepancy between interpolated surface normal and geometry normal can cause issues when a ray\r\n\t// is cast that is on the top side of the geometry normal plane but below the surface normal plane. If\r\n\t// we find a ray like that we ignore it to avoid artifacts.\r\n\t// This function returns if the direction is on the same side of both planes.\r\n\tbool isDirectionValid( vec3 direction, vec3 surfaceNormal, vec3 geometryNormal ) {\r\n\r\n\t\tbool aboveSurfaceNormal = dot( direction, surfaceNormal ) > 0.0;\r\n\t\tbool aboveGeometryNormal = dot( direction, geometryNormal ) > 0.0;\r\n\t\treturn aboveSurfaceNormal == aboveGeometryNormal;\r\n\r\n\t}\r\n\r\n\tvec3 getHemisphereSample( vec3 n, vec2 uv ) {\r\n\r\n\t\t// https://www.rorydriscoll.com/2009/01/07/better-sampling/\r\n\t\t// https://graphics.pixar.com/library/OrthonormalB/paper.pdf\r\n\t\tfloat sign = n.z == 0.0 ? 1.0 : sign( n.z );\r\n\t\tfloat a = - 1.0 / ( sign + n.z );\r\n\t\tfloat b = n.x * n.y * a;\r\n\t\tvec3 b1 = vec3( 1.0 + sign * n.x * n.x * a, sign * b, - sign * n.x );\r\n\t\tvec3 b2 = vec3( b, sign + n.y * n.y * a, - n.y );\r\n\r\n\t\tfloat r = sqrt( uv.x );\r\n\t\tfloat theta = 2.0 * PI * uv.y;\r\n\t\tfloat x = r * cos( theta );\r\n\t\tfloat y = r * sin( theta );\r\n\t\treturn x * b1 + y * b2 + sqrt( 1.0 - uv.x ) * n;\r\n\r\n\t}\r\n\r\n\t// https://www.shadertoy.com/view/wltcRS\r\n\tuvec4 s0;\r\n\r\n\tvoid rng_initialize(vec2 p, int frame) {\r\n\r\n\t\t// white noise seed\r\n\t\ts0 = uvec4( p, uint( frame ), uint( p.x ) + uint( p.y ) );\r\n\r\n\t}\r\n\r\n\t// https://www.pcg-random.org/\r\n\tvoid pcg4d( inout uvec4 v ) {\r\n\r\n\t\tv = v * 1664525u + 1013904223u;\r\n\t\tv.x += v.y * v.w;\r\n\t\tv.y += v.z * v.x;\r\n\t\tv.z += v.x * v.y;\r\n\t\tv.w += v.y * v.z;\r\n\t\tv = v ^ ( v >> 16u );\r\n\t\tv.x += v.y*v.w;\r\n\t\tv.y += v.z*v.x;\r\n\t\tv.z += v.x*v.y;\r\n\t\tv.w += v.y*v.z;\r\n\r\n\t}\r\n\r\n\tfloat rand() {\r\n\r\n\t\tpcg4d(s0);\r\n\t\treturn float( s0.x ) / float( 0xffffffffu );\r\n\r\n\t}\r\n\r\n\tvec2 rand2() {\r\n\r\n\t\tpcg4d( s0 );\r\n\t\treturn vec2( s0.xy ) / float(0xffffffffu);\r\n\r\n\t}\r\n\r\n\tvec3 rand3() {\r\n\r\n\t\tpcg4d(s0);\r\n\t\treturn vec3( s0.xyz ) / float( 0xffffffffu );\r\n\r\n\t}\r\n\r\n\tvec4 rand4() {\r\n\r\n\t\tpcg4d(s0);\r\n\t\treturn vec4(s0)/float(0xffffffffu);\r\n\r\n\t}\r\n\r\n\t// https://github.com/mrdoob/three.js/blob/dev/src/math/Vector3.js#L724\r\n\tvec3 randDirection() {\r\n\r\n\t\tvec2 r = rand2();\r\n\t\tfloat u = ( r.x - 0.5 ) * 2.0;\r\n\t\tfloat t = r.y * PI * 2.0;\r\n\t\tfloat f = sqrt( 1.0 - u * u );\r\n\r\n\t\treturn vec3( f * cos( t ), f * sin( t ), u );\r\n\r\n\t}\r\n`;\r\n","import { Matrix4, Matrix3, Color } from 'three';\r\nimport { MaterialBase } from './MaterialBase.js';\r\nimport {\r\n\tMeshBVHUniformStruct, FloatVertexAttributeTexture, UIntVertexAttributeTexture,\r\n\tshaderStructs, shaderIntersectFunction,\r\n} from 'three-mesh-bvh';\r\nimport { shaderMaterialStructs } from '../shader/shaderStructs.js';\r\nimport { MaterialStructArrayUniform } from '../uniforms/MaterialStructArrayUniform.js';\r\nimport { RenderTarget2DArray } from '../uniforms/RenderTarget2DArray.js';\r\nimport { shaderMaterialSampling } from '../shader/shaderMaterialSampling.js';\r\nimport { shaderUtils } from '../shader/shaderUtils.js';\r\n\r\nexport class PhysicalPathTracingMaterial extends MaterialBase {\r\n\r\n\t// three.js relies on this field to add env map functions and defines\r\n\tget envMap() {\r\n\r\n\t\treturn this.environmentMap;\r\n\r\n\t}\r\n\r\n\tconstructor( parameters ) {\r\n\r\n\t\tsuper( {\r\n\r\n\t\t\ttransparent: true,\r\n\t\t\tdepthWrite: false,\r\n\r\n\t\t\tdefines: {\r\n\t\t\t\tBOUNCES: 3,\r\n\t\t\t\tTRANSPARENT_TRAVERSALS: 5,\r\n\t\t\t\tMATERIAL_LENGTH: 0,\r\n\t\t\t\tGRADIENT_BG: 0,\r\n\t\t\t},\r\n\r\n\t\t\tuniforms: {\r\n\t\t\t\tbvh: { value: new MeshBVHUniformStruct() },\r\n\t\t\t\tnormalAttribute: { value: new FloatVertexAttributeTexture() },\r\n\t\t\t\ttangentAttribute: { value: new FloatVertexAttributeTexture() },\r\n\t\t\t\tuvAttribute: { value: new FloatVertexAttributeTexture() },\r\n\t\t\t\tmaterialIndexAttribute: { value: new UIntVertexAttributeTexture() },\r\n\t\t\t\tmaterials: { value: new MaterialStructArrayUniform() },\r\n\t\t\t\ttextures: { value: new RenderTarget2DArray().texture },\r\n\t\t\t\tcameraWorldMatrix: { value: new Matrix4() },\r\n\t\t\t\tinvProjectionMatrix: { value: new Matrix4() },\r\n\t\t\t\tenvironmentBlur: { value: 0.2 },\r\n\t\t\t\tenvironmentIntensity: { value: 2.0 },\r\n\t\t\t\tenvironmentMap: { value: null },\r\n\t\t\t\tenvironmentRotation: { value: new Matrix3() },\r\n\t\t\t\tseed: { value: 0 },\r\n\t\t\t\topacity: { value: 1 },\r\n\t\t\t\tfilterGlossyFactor: { value: 0.0 },\r\n\r\n\t\t\t\tgradientTop: { value: new Color( 0xbfd8ff ) },\r\n\t\t\t\tgradientBottom: { value: new Color( 0xffffff ) },\r\n\r\n\t\t\t\tbgGradientTop: { value: new Color( 0x111111 ) },\r\n\t\t\t\tbgGradientBottom: { value: new Color( 0x000000 ) },\r\n\t\t\t},\r\n\r\n\t\t\tvertexShader: /* glsl */`\r\n\r\n\t\t\t\tvarying vec2 vUv;\r\n\t\t\t\tvoid main() {\r\n\r\n\t\t\t\t\tvec4 mvPosition = vec4( position, 1.0 );\r\n\t\t\t\t\tmvPosition = modelViewMatrix * mvPosition;\r\n\t\t\t\t\tgl_Position = projectionMatrix * mvPosition;\r\n\r\n\t\t\t\t\tvUv = uv;\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t`,\r\n\r\n\t\t\tfragmentShader: /* glsl */`\r\n\t\t\t\t#define RAY_OFFSET 1e-5\r\n\r\n\t\t\t\tprecision highp isampler2D;\r\n\t\t\t\tprecision highp usampler2D;\r\n\t\t\t\tprecision highp sampler2DArray;\r\n\t\t\t\tvec4 envMapTexelToLinear( vec4 a ) { return a; }\r\n\t\t\t\t#include <common>\r\n\t\t\t\t#include <cube_uv_reflection_fragment>\r\n\r\n\t\t\t\t${ shaderStructs }\r\n\t\t\t\t${ shaderIntersectFunction }\r\n\t\t\t\t${ shaderMaterialStructs }\r\n\r\n\t\t\t\t${ shaderUtils }\r\n\t\t\t\t${ shaderMaterialSampling }\r\n\r\n\t\t\t\t#ifdef USE_ENVMAP\r\n\r\n\t\t\t\tuniform float environmentBlur;\r\n\t\t\t\tuniform sampler2D environmentMap;\r\n\t\t\t\tuniform mat3 environmentRotation;\r\n\r\n\t\t\t\t#else\r\n\r\n\t\t\t\tuniform vec3 gradientTop;\r\n\t\t\t\tuniform vec3 gradientBottom;\r\n\r\n\t\t\t\t#endif\r\n\r\n\t\t\t\t#if GRADIENT_BG\r\n\r\n\t\t\t\tuniform vec3 bgGradientTop;\r\n\t\t\t\tuniform vec3 bgGradientBottom;\r\n\r\n\t\t\t\t#endif\r\n\r\n\t\t\t\tuniform mat4 cameraWorldMatrix;\r\n\t\t\t\tuniform mat4 invProjectionMatrix;\r\n\t\t\t\tuniform sampler2D normalAttribute;\r\n\t\t\t\tuniform sampler2D tangentAttribute;\r\n\t\t\t\tuniform sampler2D uvAttribute;\r\n\t\t\t\tuniform usampler2D materialIndexAttribute;\r\n\t\t\t\tuniform BVH bvh;\r\n\t\t\t\tuniform float environmentIntensity;\r\n\t\t\t\tuniform float filterGlossyFactor;\r\n\t\t\t\tuniform int seed;\r\n\t\t\t\tuniform float opacity;\r\n\t\t\t\tuniform Material materials[ MATERIAL_LENGTH ];\r\n\t\t\t\tuniform sampler2DArray textures;\r\n\t\t\t\tvarying vec2 vUv;\r\n\r\n\t\t\t\tvoid main() {\r\n\r\n\t\t\t\t\trng_initialize( gl_FragCoord.xy, seed );\r\n\r\n\t\t\t\t\t// get [-1, 1] normalized device coordinates\r\n\t\t\t\t\tvec2 ndc = 2.0 * vUv - vec2( 1.0 );\r\n\t\t\t\t\tvec3 rayOrigin, rayDirection;\r\n\t\t\t\t\tndcToCameraRay( ndc, cameraWorldMatrix, invProjectionMatrix, rayOrigin, rayDirection );\r\n\r\n\t\t\t\t\t// Lambertian render\r\n\t\t\t\t\tgl_FragColor = vec4( 0.0 );\r\n\r\n\t\t\t\t\tvec3 throughputColor = vec3( 1.0 );\r\n\r\n\t\t\t\t\t// hit results\r\n\t\t\t\t\tuvec4 faceIndices = uvec4( 0u );\r\n\t\t\t\t\tvec3 faceNormal = vec3( 0.0, 0.0, 1.0 );\r\n\t\t\t\t\tvec3 barycoord = vec3( 0.0 );\r\n\t\t\t\t\tfloat side = 1.0;\r\n\t\t\t\t\tfloat dist = 0.0;\r\n\t\t\t\t\tfloat accumulatedRoughness = 0.0;\r\n\t\t\t\t\tint i;\r\n\t\t\t\t\tint transparentTraversals = TRANSPARENT_TRAVERSALS;\r\n\t\t\t\t\tfor ( i = 0; i < BOUNCES; i ++ ) {\r\n\r\n\t\t\t\t\t\tif ( ! bvhIntersectFirstHit( bvh, rayOrigin, rayDirection, faceIndices, faceNormal, barycoord, side, dist ) ) {\r\n\r\n\t\t\t\t\t\t\t#if GRADIENT_BG\r\n\r\n\t\t\t\t\t\t\tif ( i == 0 ) {\r\n\r\n\t\t\t\t\t\t\t\trayDirection = normalize( rayDirection + randDirection() * 0.05 );\r\n\t\t\t\t\t\t\t\tfloat value = ( rayDirection.y + 1.0 ) / 2.0;\r\n\r\n\t\t\t\t\t\t\t\tvalue = pow( value, 2.0 );\r\n\r\n\t\t\t\t\t\t\t\tgl_FragColor = vec4( mix( bgGradientBottom, bgGradientTop, value ), 1.0 );\r\n\t\t\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\t#endif\r\n\r\n\t\t\t\t\t\t\t#ifdef USE_ENVMAP\r\n\r\n vec3 skyColor = textureCubeUV( environmentMap, environmentRotation * rayDirection, environmentBlur ).rgb;\r\n\r\n\t\t\t\t\t\t\t#else\r\n\r\n\t\t\t\t\t\t\trayDirection = normalize( rayDirection );\r\n\t\t\t\t\t\t\tfloat value = ( rayDirection.y + 1.0 ) / 2.0;\r\n\t\t\t\t\t\t\tvec3 skyColor = mix( gradientBottom, gradientTop, value );\r\n\r\n\t\t\t\t\t\t\t#endif\r\n\r\n\t\t\t\t\t\t\tgl_FragColor += vec4( skyColor * throughputColor * environmentIntensity, 1.0 );\r\n\r\n\t\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tuint materialIndex = uTexelFetch1D( materialIndexAttribute, faceIndices.x ).r;\r\n\t\t\t\t\t\tMaterial material = materials[ materialIndex ];\r\n\r\n\t\t\t\t\t\tvec2 uv = textureSampleBarycoord( uvAttribute, barycoord, faceIndices.xyz ).xy;\r\n\r\n\t\t\t\t\t\t// albedo\r\n\t\t\t\t\t\tvec4 albedo = vec4( material.color, material.opacity );\r\n\t\t\t\t\t\tif ( material.map != - 1 ) {\r\n\r\n\t\t\t\t\t\t\talbedo *= texture2D( textures, vec3( uv, material.map ) );\r\n\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// possibly skip this sample if it's transparent or alpha test is enabled\r\n\t\t\t\t\t\t// alpha test is disabled when it === 0\r\n\t\t\t\t\t\tfloat alphaTest = material.alphaTest;\r\n\t\t\t\t\t\tbool useAlphaTest = alphaTest != 0.0;\r\n\t\t\t\t\t\tif (\r\n\t\t\t\t\t\t\tuseAlphaTest && albedo.a < alphaTest\r\n\t\t\t\t\t\t\t|| ! useAlphaTest && albedo.a < rand()\r\n\t\t\t\t\t\t) {\r\n\r\n\t\t\t\t\t\t\tvec3 point = rayOrigin + rayDirection * dist;\r\n\t\t\t\t\t\t\trayOrigin += rayDirection * dist - faceNormal * RAY_OFFSET;\r\n\r\n\t\t\t\t\t\t\t// only allow a limited number of transparency discards otherwise we could\r\n\t\t\t\t\t\t\t// crash the context with too long a loop.\r\n\t\t\t\t\t\t\ti -= sign( transparentTraversals );\r\n\t\t\t\t\t\t\ttransparentTraversals -= sign( transparentTraversals );\r\n\t\t\t\t\t\t\tcontinue;\r\n\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// fetch the interpolated smooth normal\r\n\t\t\t\t\t\tvec3 normal = normalize( textureSampleBarycoord(\r\n\t\t\t\t\t\t\tnormalAttribute,\r\n\t\t\t\t\t\t\tbarycoord,\r\n\t\t\t\t\t\t\tfaceIndices.xyz\r\n\t\t\t\t\t\t).xyz );\r\n\r\n\t\t\t\t\t\t// roughness\r\n\t\t\t\t\t\tfloat roughness = material.roughness;\r\n\t\t\t\t\t\tif ( material.roughnessMap != - 1 ) {\r\n\r\n\t\t\t\t\t\t\troughness *= texture2D( textures, vec3( uv, material.roughnessMap ) ).g;\r\n\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// metalness\r\n\t\t\t\t\t\tfloat metalness = material.metalness;\r\n\t\t\t\t\t\tif ( material.metalnessMap != - 1 ) {\r\n\r\n\t\t\t\t\t\t\tmetalness *= texture2D( textures, vec3( uv, material.metalnessMap ) ).b;\r\n\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// emission\r\n\t\t\t\t\t\tvec3 emission = material.emissiveIntensity * material.emissive;\r\n\t\t\t\t\t\tif ( material.emissiveMap != - 1 ) {\r\n\r\n\t\t\t\t\t\t\temission *= texture2D( textures, vec3( uv, material.emissiveMap ) ).xyz;\r\n\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// transmission\r\n\t\t\t\t\t\tfloat transmission = material.transmission;\r\n\t\t\t\t\t\tif ( material.transmissionMap != - 1 ) {\r\n\r\n\t\t\t\t\t\t\ttransmission *= texture2D( textures, vec3( uv, material.transmissionMap ) ).r;\r\n\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// normal\r\n\t\t\t\t\t\tif ( material.normalMap != - 1 ) {\r\n\r\n\t\t\t\t\t\t\tvec4 tangentSample = textureSampleBarycoord(\r\n\t\t\t\t\t\t\t\ttangentAttribute,\r\n\t\t\t\t\t\t\t\tbarycoord,\r\n\t\t\t\t\t\t\t\tfaceIndices.xyz\r\n\t\t\t\t\t\t\t);\r\n\r\n\t\t\t\t\t\t\t// some provided tangents can be malformed (0, 0, 0) causing the normal to be degenerate\r\n\t\t\t\t\t\t\t// resulting in NaNs and slow path tracing.\r\n\t\t\t\t\t\t\tif ( length( tangentSample.xyz ) > 0.0 ) {\r\n\r\n\t\t\t\t\t\t\t\tvec3 tangent = normalize( tangentSample.xyz );\r\n\t\t\t\t\t\t\t\tvec3 bitangent = normalize( cross( normal, tangent ) * tangentSample.w );\r\n\t\t\t\t\t\t\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\r\n\r\n\t\t\t\t\t\t\t\tvec3 texNormal = texture2D( textures, vec3( uv, material.normalMap ) ).xyz * 2.0 - 1.0;\r\n\t\t\t\t\t\t\t\ttexNormal.xy *= material.normalScale;\r\n\t\t\t\t\t\t\t\tnormal = vTBN * texNormal;\r\n\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tnormal *= side;\r\n\r\n\t\t\t\t\t\tSurfaceRec surfaceRec;\r\n\t\t\t\t\t\tsurfaceRec.normal = normal;\r\n\t\t\t\t\t\tsurfaceRec.faceNormal = faceNormal;\r\n\t\t\t\t\t\tsurfaceRec.frontFace = side == 1.0;\r\n\t\t\t\t\t\tsurfaceRec.transmission = transmission;\r\n\t\t\t\t\t\tsurfaceRec.ior = material.ior;\r\n\t\t\t\t\t\tsurfaceRec.emission = emission;\r\n\t\t\t\t\t\tsurfaceRec.metalness = metalness;\r\n\t\t\t\t\t\tsurfaceRec.color = albedo.rgb;\r\n\t\t\t\t\t\tsurfaceRec.roughness = roughness;\r\n\r\n\t\t\t\t\t\t// Compute the filtered roughness value to use during specular reflection computations. A minimum\r\n\t\t\t\t\t\t// value of 1e-6 is needed because the GGX functions do not work with a roughness value of 0 and\r\n\t\t\t\t\t\t// the accumulated roughness value is scaled by a user setting and a \"magic value\" of 5.0.\r\n\t\t\t\t\t\t// If we're exiting something transmissive then scale the factor down significantly so we can retain\r\n\t\t\t\t\t\t// sharp internal reflections\r\n\t\t\t\t\t\tsurfaceRec.filteredRoughness = clamp(\r\n\t\t\t\t\t\t\tmax( surfaceRec.roughness, accumulatedRoughness * filterGlossyFactor * 5.0 ),\r\n\t\t\t\t\t\t\t1e-3,\r\n\t\t\t\t\t\t\t1.0\r\n\t\t\t\t\t\t);\r\n\r\n\t\t\t\t\t\tmat3 normalBasis = getBasisFromNormal( surfaceRec.normal );\r\n\t\t\t\t\t\tmat3 invBasis = inverse( normalBasis );\r\n\r\n\t\t\t\t\t\tvec3 outgoing = - normalize( invBasis * rayDirection );\r\n\t\t\t\t\t\tSampleRec sampleRec = bsdfSample( outgoing, surfaceRec );\r\n\r\n\t\t\t\t\t\t// adjust the hit point by the surface normal by a factor of some offset and the\r\n\t\t\t\t\t\t// maximum component-wise value of the current point to accommodate floating point\r\n\t\t\t\t\t\t// error as values increase.\r\n\t\t\t\t\t\tvec3 point = rayOrigin + rayDirection * dist;\r\n\t\t\t\t\t\tvec3 absPoint = abs( point );\r\n\t\t\t\t\t\tfloat maxPoint = max( absPoint.x, max( absPoint.y, absPoint.z ) );\r\n\t\t\t\t\t\trayDirection = normalize( normalBasis * sampleRec.direction );\r\n\r\n\t\t\t\t\t\tbool isBelowSurface = dot( rayDirection, faceNormal ) < 0.0;\r\n\t\t\t\t\t\trayOrigin = point + faceNormal * ( maxPoint + 1.0 ) * ( isBelowSurface ? - RAY_OFFSET : RAY_OFFSET );\r\n\r\n\t\t\t\t\t\t// accumulate a roughness value to offset diffuse, specular, diffuse rays that have high contribution\r\n\t\t\t\t\t\t// to a single pixel resulting in fireflies\r\n\t\t\t\t\t\tif ( ! isBelowSurface ) {\r\n\r\n\t\t\t\t\t\t\t// determine if this is a rough normal or not by checking how far off straight up it is\r\n\t\t\t\t\t\t\tvec3 halfVector = normalize( outgoing + sampleRec.direction );\r\n\t\t\t\t\t\t\taccumulatedRoughness += sin( acos( halfVector.z ) );\r\n\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// accumulate color\r\n\t\t\t\t\t\tgl_FragColor.rgb += ( emission * throughputColor );\r\n\r\n\t\t\t\t\t\t// skip the sample if our PDF or ray is impossible\r\n\t\t\t\t\t\tif ( sampleRec.pdf <= 0.0 || ! isDirectionValid( rayDirection, normal, faceNormal) ) {\r\n\r\n\t\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tthroughputColor *= sampleRec.color / sampleRec.pdf;\r\n\r\n\t\t\t\t\t\t// discard the sample if there are any NaNs\r\n\t\t\t\t\t\tif ( any( isnan( throughputColor ) ) || any( isinf( throughputColor ) ) ) {\r\n\r\n\t\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tgl_FragColor.a = opacity;\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t`\r\n\r\n\t\t} );\r\n\r\n\t\tthis.setValues( parameters );\r\n\r\n\t}\r\n\r\n}\r\n","// core\r\nexport * from './core/PathTracingRenderer.js';\r\nexport * from './core/PathTracingSceneGenerator.js';\r\nexport * from './core/MaterialReducer.js';\r\n\r\n// uniforms\r\nexport * from './uniforms/MaterialStructArrayUniform.js';\r\nexport * from './uniforms/MaterialStructUniform.js';\r\nexport * from './uniforms/RenderTarget2DArray.js';\r\n\r\n// utils\r\nexport * from './utils/GeometryPreparationUtils.js';\r\n\r\n// materials\r\nexport * from './materials/MaterialBase.js';\r\nexport * from './materials/PhysicalPathTracingMaterial.js';\r\n\r\n// shaders\r\nexport * from './shader/shaderMaterialSampling.js';\r\nexport * from './shader/shaderUtils.js';\r\nexport * from './shader/shaderStructs.js';\r\n"],"names":[],"mappings":"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AAS,GAAG;AACtC;AACA,EAAE,KAAK,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,GAAG;AAC/C;AACA,GAAG,KAAK,IAAI,IAAI,IAAI,CAAC,OAAO,GAAG;AAC/B;AACA,IAAI,OAAO,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;AAChC,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;AAC5B;AACA,IAAI;AACJ;AACA,GAAG,MAAM;AACT;AACA,GAAG,KAAK,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,KAAK,GAAG;AACzC;AACA,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;AACjC,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;AAC5B;AACA,IAAI;AACJ;AACA,GAAG;AACH;AACA,EAAE;AACF;AACA;;ACvDY,MAAC,qBAAqB,cAAc,CAAC;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7BO,MAAM,kBAAkB,aAAa,CAAC;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;ACxGW,MAAC,sBAAsB,aAAa,CAAC;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG,kBAAkB,EAAE;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5UY,MAAC,WAAW,aAAa,CAAC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/HO,MAAM,2BAA2B,SAAS,YAAY,CAAC;AAC9D;AACA;AACA,CAAC,IAAI,MAAM,GAAG;AACd;AACA,EAAE,OAAO,IAAI,CAAC,cAAc,CAAC;AAC7B;AACA,EAAE;AACF;AACA,CAAC,WAAW,EAAE,UAAU,GAAG;AAC3B;AACA,EAAE,KAAK,EAAE;AACT;AACA,GAAG,WAAW,EAAE,IAAI;AACpB,GAAG,UAAU,EAAE,KAAK;AACpB;AACA,GAAG,OAAO,EAAE;AACZ,IAAI,OAAO,EAAE,CAAC;AACd,IAAI,sBAAsB,EAAE,CAAC;AAC7B,IAAI,eAAe,EAAE,CAAC;AACtB,IAAI,WAAW,EAAE,CAAC;AAClB,IAAI;AACJ;AACA,GAAG,QAAQ,EAAE;AACb,IAAI,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,oBAAoB,EAAE,EAAE;AAC9C,IAAI,eAAe,EAAE,EAAE,KAAK,EAAE,IAAI,2BAA2B,EAAE,EAAE;AACjE,IAAI,gBAAgB,EAAE,EAAE,KAAK,EAAE,IAAI,2BAA2B,EAAE,EAAE;AAClE,IAAI,WAAW,EAAE,EAAE,KAAK,EAAE,IAAI,2BAA2B,EAAE,EAAE;AAC7D,IAAI,sBAAsB,EAAE,EAAE,KAAK,EAAE,IAAI,0BAA0B,EAAE,EAAE;AACvE,IAAI,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,0BAA0B,EAAE,EAAE;AAC1D,IAAI,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,mBAAmB,EAAE,CAAC,OAAO,EAAE;AAC1D,IAAI,iBAAiB,EAAE,EAAE,KAAK,EAAE,IAAI,OAAO,EAAE,EAAE;AAC/C,IAAI,mBAAmB,EAAE,EAAE,KAAK,EAAE,IAAI,OAAO,EAAE,EAAE;AACjD,IAAI,eAAe,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;AACnC,IAAI,oBAAoB,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;AACxC,IAAI,cAAc,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;AACnC,IAAI,mBAAmB,EAAE,EAAE,KAAK,EAAE,IAAI,OAAO,EAAE,EAAE;AACjD,IAAI,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE;AACtB,IAAI,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE;AACzB,IAAI,kBAAkB,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;AACtC;AACA,IAAI,WAAW,EAAE,EAAE,KAAK,EAAE,IAAI,KAAK,EAAE,QAAQ,EAAE,EAAE;AACjD,IAAI,cAAc,EAAE,EAAE,KAAK,EAAE,IAAI,KAAK,EAAE,QAAQ,EAAE,EAAE;AACpD;AACA,IAAI,aAAa,EAAE,EAAE,KAAK,EAAE,IAAI,KAAK,EAAE,QAAQ,EAAE,EAAE;AACnD,IAAI,gBAAgB,EAAE,EAAE,KAAK,EAAE,IAAI,KAAK,EAAE,QAAQ,EAAE,EAAE;AACtD,IAAI;AACJ;AACA,GAAG,YAAY,YAAY,CAAC;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG,CAAC;AACJ;AACA,GAAG,cAAc,YAAY,CAAC;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,GAAG,aAAa,EAAE;AACtB,IAAI,GAAG,uBAAuB,EAAE;AAChC,IAAI,GAAG,qBAAqB,EAAE;AAC9B;AACA,IAAI,GAAG,WAAW,EAAE;AACpB,IAAI,GAAG,sBAAsB,EAAE;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG,CAAC;AACJ;AACA,GAAG,EAAE,CAAC;AACN;AACA,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,CAAC;AAC/B;AACA,EAAE;AACF;AACA;;ACjXA;;;;"}