import * as THREE from 'three' ; import { scanAtlasTexels } from './atlas' ; import { Workbench } from './workbench' ; import { withLightProbe } from './lightProbe' ; const MAX_PASSES = 2 ; const offDirX = [ 1 , 1 , 0 , - 1 , - 1 , - 1 , 0 , 1 ] ; const offDirY = [ 0 , 1 , 1 , 1 , 0 , - 1 , - 1 , - 1 ] ; function storeLightMapValue ( atlasData , atlasWidth , totalTexelCount , texelIndex , rgba , passOutputData ) { const mainOffTexelBase = texelIndex * 4 ; rgba . w = 1 ; rgba . toArray ( passOutputData , mainOffTexelBase ) ; const texelX = texelIndex % atlasWidth ; const texelRowStart = texelIndex - texelX ; for ( let offDir = 0 ; offDir < 8 ; offDir += 1 ) { const offX = offDirX [ offDir ] ; const offY = offDirY [ offDir ] ; const offRowX = ( atlasWidth + texelX + offX ) % atlasWidth ; const offRowStart = ( totalTexelCount + texelRowStart + offY * atlasWidth ) % totalTexelCount ; const offTexelBase = ( offRowStart + offRowX ) * 4 ; const offTexelFaceEnc = atlasData [ offTexelBase + 2 ] ; const isStrongNeighbour = offX === 0 || offY === 0 ; const isUnfilled = passOutputData [ offTexelBase + 3 ] === 0 ; if ( offTexelFaceEnc === 0 && ( isStrongNeighbour || isUnfilled ) ) { rgba . toArray ( passOutputData , offTexelBase ) ; } } } export async function runBakingPasses ( workbench , requestWork ) { await withLightProbe ( workbench . aoMode , workbench . aoDistance , workbench . settings , async ( renderLightProbeBatch ) => { const { atlasMap , irradiance , irradianceData } = workbench ; const { width : atlasWidth , height : atlasHeight } = atlasMap ; const totalTexelCount = atlasWidth * atlasHeight ; const passOutputData = new Float32Array ( 4 * totalTexelCount ) ; for ( let passCount = 0 ; passCount < MAX_PASSES ; passCount += 1 ) { passOutputData . fill ( 0 ) ; let texelsDone = false ; const texelIterator = scanAtlasTexels ( atlasMap , ( ) => { texelsDone = true ; } ) ; while ( ! texelsDone ) { const gl = await requestWork ( ) ; for ( const { texelIndex , rgba } of renderLightProbeBatch ( gl , workbench . lightScene , texelIterator ) ) { storeLightMapValue ( atlasMap . data , atlasWidth , totalTexelCount , texelIndex , rgba , passOutputData ) ; } } irradianceData . set ( passOutputData ) ; irradiance . needsUpdate = true ; } } ) ; }