import { Vector3 } from 'babylonjs/Maths/math' ; import { Tools } from 'babylonjs/Misc/tools' ; import { TextureCube , PixelFormat , PixelType } from './texture' ; ignoreChildren export interface SphericalPolynomalCoefficients { x : Vector3 ; y : Vector3 ; z : Vector3 ; xx : Vector3 ; yy : Vector3 ; zz : Vector3 ; yz : Vector3 ; zx : Vector3 ; xy : Vector3 ; } /**
 * Wraps data and maps required for environments with physically based rendering
 */ export interface PBREnvironment { /**
     * Spherical Polynomial Coefficients representing an irradiance map
     */ irradiancePolynomialCoefficients : SphericalPolynomalCoefficients ; /**
     * Specular cubemap
     */ specularTexture ? : TextureCube ; /**
     * A scale factor applied to RGB values after reading from environment maps
     */ textureIntensityScale : number ; } /**
         * Environment map representations: layouts, projections and approximations
         */ export type MapType = 'irradiance_sh_coefficients_9' | 'cubemap_faces' ; /**
 * Image type used for environment map
 */ export type ImageType = 'png' ; /**
 * A generic field in JSON that report's its type
 */ export interface TypedObject < T > { type : T ; } /**
 * Describes a range of bytes starting at byte pos (inclusive) and finishing at byte pos + length - 1
 */ export interface ByteRange { pos : number ; length : number ; } /**
 * Complete Spectre Environment JSON Descriptor
 */ export interface EnvJsonDescriptor { radiance : TypedObject < MapType > ; irradiance : TypedObject < MapType > ; specular : TypedObject < MapType > ; } /**
 * Spherical harmonic coefficients to provide an irradiance map
 */ export interface IrradianceSHCoefficients9 extends TypedObject < MapType > { l00 : Array < number > ; l1_1 : Array < number > ; l10 : Array < number > ; l11 : Array < number > ; l2_2 : Array < number > ; l2_1 : Array < number > ; l20 : Array < number > ; l21 : Array < number > ; l22 : Array < number > ; } /**
 * A generic set of images, where the image content is specified by byte ranges in the mipmaps field
 */ export interface ImageSet < T > extends TypedObject < MapType > { imageType : ImageType ; width : number ; height : number ; mipmaps : Array < T > ; multiplier : number ; } /**
 * A set of cubemap faces
 */ export type CubemapFaces = ImageSet < Array < ByteRange > > ; /**
 * A single image containing an atlas of equirectangular-projection maps across all mip levels
 */ export type EquirectangularMipmapAtlas = ImageSet < ByteRange > ; /**
 * A static class proving methods to aid parsing Spectre environment files
 */ export class EnvironmentDeserializer { param arrayBuffer return public static Parse ( arrayBuffer ) { var environment = { irradiancePolynomialCoefficients : { x : new Vector3 ( 0 , 0 , 0 ) , y : new Vector3 ( 0 , 0 , 0 ) , z : new Vector3 ( 0 , 0 , 0 ) , xx : new Vector3 ( 0 , 0 , 0 ) , yy : new Vector3 ( 0 , 0 , 0 ) , zz : new Vector3 ( 0 , 0 , 0 ) , yz : new Vector3 ( 0 , 0 , 0 ) , zx : new Vector3 ( 0 , 0 , 0 ) , xy : new Vector3 ( 0 , 0 , 0 ) } , textureIntensityScale : 1.0 , } ; let littleEndian = false ; let magicBytes = [ 0x86 , 0x16 , 0x87 , 0x96 , 0xf6 , 0xd6 , 0x96 , 0x36 ] ; let dataView = new DataView ( arrayBuffer ) ; let pos = 0 ; for ( let i = 0 ; i < magicBytes . length ; i ++ ) { if ( dataView . getUint8 ( pos ++ ) !== magicBytes [ i ] ) { Tools . Error ( 'Not a Spectre environment map' ) ; } } let version = dataView . getUint16 ( pos , littleEndian ) ; pos += 2 ; if ( version !== 1 ) { Tools . Warn ( 'Unsupported Spectre environment map version "' + version + '"' ) ; } let descriptorString = '' ; let charCode = 0x00 ; while ( ( charCode = dataView . getUint8 ( pos ++ ) ) ) { descriptorString += String . fromCharCode ( charCode ) ; } let descriptor = JSON . parse ( descriptorString ) ; let payloadPos = pos ; switch ( descriptor . irradiance . type ) { case 'irradiance_sh_coefficients_9' : let harmonics = < IrradianceSHCoefficients9 > descriptor . irradiance ; EnvironmentDeserializer . _ConvertSHIrradianceToLambertianRadiance ( harmonics ) ; EnvironmentDeserializer . _ConvertSHToSP ( harmonics , environment . irradiancePolynomialCoefficients ) ; break ; default : Tools . Error ( 'Unhandled MapType descriptor.irradiance.type (' + descriptor . irradiance . type + ')' ) ; } switch ( descriptor . specular . type ) { case 'cubemap_faces' : var specularDescriptor = < CubemapFaces > descriptor . specular ; let specularTexture = environment . specularTexture = new TextureCube ( PixelFormat . RGBA , PixelType . UNSIGNED_BYTE ) ; environment . textureIntensityScale = specularDescriptor . multiplier != null ? specularDescriptor . multiplier : 1.0 ; let mipmaps = specularDescriptor . mipmaps ; let imageType = specularDescriptor . imageType ; for ( let l = 0 ; l < mipmaps . length ; l ++ ) { let faceRanges = mipmaps [ l ] ; specularTexture . source [ l ] = [ ] ; for ( let i = 0 ; i < 6 ; i ++ ) { let range = faceRanges [ i ] ; let bytes = new Uint8Array ( arrayBuffer , payloadPos + range . pos , range . length ) ; switch ( imageType ) { case 'png' : let image = new Image ( ) ; let src = URL . createObjectURL ( new Blob ( [ bytes ] , { type : 'image/png' } ) ) ; image . src = src ; specularTexture . source [ l ] [ i ] = image ; break ; default : Tools . Error ( 'Unhandled ImageType descriptor.specular.imageType (' + imageType + ')' ) ; } } } break ; default : Tools . Error ( 'Unhandled MapType descriptor.specular.type (' + descriptor . specular . type + ')' ) ; } return environment ; } param harmonics private static _ConvertSHIrradianceToLambertianRadiance ( harmonics ) { EnvironmentDeserializer . _ScaleSH ( harmonics , 1 / Math . PI ) ; } param harmonics param outPolynomialCoefficents private static _ConvertSHToSP ( harmonics , outPolynomialCoefficents ) { const rPi = 1 / Math . PI ; outPolynomialCoefficents . x . x = 1.02333 * harmonics . l11 [ 0 ] * rPi ; outPolynomialCoefficents . x . y = 1.02333 * harmonics . l11 [ 1 ] * rPi ; outPolynomialCoefficents . x . z = 1.02333 * harmonics . l11 [ 2 ] * rPi ; outPolynomialCoefficents . y . x = 1.02333 * harmonics . l1_1 [ 0 ] * rPi ; outPolynomialCoefficents . y . y = 1.02333 * harmonics . l1_1 [ 1 ] * rPi ; outPolynomialCoefficents . y . z = 1.02333 * harmonics . l1_1 [ 2 ] * rPi ; outPolynomialCoefficents . z . x = 1.02333 * harmonics . l10 [ 0 ] * rPi ; outPolynomialCoefficents . z . y = 1.02333 * harmonics . l10 [ 1 ] * rPi ; outPolynomialCoefficents . z . z = 1.02333 * harmonics . l10 [ 2 ] * rPi ; outPolynomialCoefficents . xx . x = ( 0.886277 * harmonics . l00 [ 0 ] - 0.247708 * harmonics . l20 [ 0 ] + 0.429043 * harmonics . l22 [ 0 ] ) * rPi ; outPolynomialCoefficents . xx . y = ( 0.886277 * harmonics . l00 [ 1 ] - 0.247708 * harmonics . l20 [ 1 ] + 0.429043 * harmonics . l22 [ 1 ] ) * rPi ; outPolynomialCoefficents . xx . z = ( 0.886277 * harmonics . l00 [ 2 ] - 0.247708 * harmonics . l20 [ 2 ] + 0.429043 * harmonics . l22 [ 2 ] ) * rPi ; outPolynomialCoefficents . yy . x = ( 0.886277 * harmonics . l00 [ 0 ] - 0.247708 * harmonics . l20 [ 0 ] - 0.429043 * harmonics . l22 [ 0 ] ) * rPi ; outPolynomialCoefficents . yy . y = ( 0.886277 * harmonics . l00 [ 1 ] - 0.247708 * harmonics . l20 [ 1 ] - 0.429043 * harmonics . l22 [ 1 ] ) * rPi ; outPolynomialCoefficents . yy . z = ( 0.886277 * harmonics . l00 [ 2 ] - 0.247708 * harmonics . l20 [ 2 ] - 0.429043 * harmonics . l22 [ 2 ] ) * rPi ; outPolynomialCoefficents . zz . x = ( 0.886277 * harmonics . l00 [ 0 ] + 0.495417 * harmonics . l20 [ 0 ] ) * rPi ; outPolynomialCoefficents . zz . y = ( 0.886277 * harmonics . l00 [ 1 ] + 0.495417 * harmonics . l20 [ 1 ] ) * rPi ; outPolynomialCoefficents . zz . z = ( 0.886277 * harmonics . l00 [ 2 ] + 0.495417 * harmonics . l20 [ 2 ] ) * rPi ; outPolynomialCoefficents . yz . x = 0.858086 * harmonics . l2_1 [ 0 ] * rPi ; outPolynomialCoefficents . yz . y = 0.858086 * harmonics . l2_1 [ 1 ] * rPi ; outPolynomialCoefficents . yz . z = 0.858086 * harmonics . l2_1 [ 2 ] * rPi ; outPolynomialCoefficents . zx . x = 0.858086 * harmonics . l21 [ 0 ] * rPi ; outPolynomialCoefficents . zx . y = 0.858086 * harmonics . l21 [ 1 ] * rPi ; outPolynomialCoefficents . zx . z = 0.858086 * harmonics . l21 [ 2 ] * rPi ; outPolynomialCoefficents . xy . x = 0.858086 * harmonics . l2_2 [ 0 ] * rPi ; outPolynomialCoefficents . xy . y = 0.858086 * harmonics . l2_2 [ 1 ] * rPi ; outPolynomialCoefficents . xy . z = 0.858086 * harmonics . l2_2 [ 2 ] * rPi ; } param harmonics param scaleFactor private static _ScaleSH ( harmonics , scaleFactor ) { harmonics . l00 [ 0 ] *= scaleFactor ; harmonics . l00 [ 1 ] *= scaleFactor ; harmonics . l00 [ 2 ] *= scaleFactor ; harmonics . l1_1 [ 0 ] *= scaleFactor ; harmonics . l1_1 [ 1 ] *= scaleFactor ; harmonics . l1_1 [ 2 ] *= scaleFactor ; harmonics . l10 [ 0 ] *= scaleFactor ; harmonics . l10 [ 1 ] *= scaleFactor ; harmonics . l10 [ 2 ] *= scaleFactor ; harmonics . l11 [ 0 ] *= scaleFactor ; harmonics . l11 [ 1 ] *= scaleFactor ; harmonics . l11 [ 2 ] *= scaleFactor ; harmonics . l2_2 [ 0 ] *= scaleFactor ; harmonics . l2_2 [ 1 ] *= scaleFactor ; harmonics . l2_2 [ 2 ] *= scaleFactor ; harmonics . l2_1 [ 0 ] *= scaleFactor ; harmonics . l2_1 [ 1 ] *= scaleFactor ; harmonics . l2_1 [ 2 ] *= scaleFactor ; harmonics . l20 [ 0 ] *= scaleFactor ; harmonics . l20 [ 1 ] *= scaleFactor ; harmonics . l20 [ 2 ] *= scaleFactor ; harmonics . l21 [ 0 ] *= scaleFactor ; harmonics . l21 [ 1 ] *= scaleFactor ; harmonics . l21 [ 2 ] *= scaleFactor ; harmonics . l22 [ 0 ] *= scaleFactor ; harmonics . l22 [ 1 ] *= scaleFactor ; harmonics . l22 [ 2 ] *= scaleFactor ; } }