Socket
Socket
Sign inDemoInstall

three

Package Overview
Dependencies
0
Maintainers
2
Versions
283
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.156.1 to 0.157.0

examples/jsm/nodes/materials/Line2NodeMaterial.js

17

examples/jsm/capabilities/WebGL.js

@@ -33,2 +33,19 @@ class WebGL {

static isColorSpaceAvailable( colorSpace ) {
try {
const canvas = document.createElement( 'canvas' );
const ctx = window.WebGL2RenderingContext && canvas.getContext( 'webgl2' );
ctx.drawingBufferColorSpace = colorSpace;
return ctx.drawingBufferColorSpace === colorSpace; // deepscan-disable-line SAME_OPERAND_VALUE
} catch ( e ) {
return false;
}
}
static getWebGLErrorMessage() {

@@ -35,0 +52,0 @@

5

examples/jsm/controls/DragControls.js

@@ -102,3 +102,3 @@ import {

_raycaster.setFromCamera( _pointer, _camera );
_raycaster.intersectObjects( _objects, true, _intersections );
_raycaster.intersectObjects( _objects, scope.recursive, _intersections );

@@ -155,3 +155,3 @@ if ( _intersections.length > 0 ) {

_raycaster.setFromCamera( _pointer, _camera );
_raycaster.intersectObjects( _objects, true, _intersections );
_raycaster.intersectObjects( _objects, scope.recursive, _intersections );

@@ -210,2 +210,3 @@ if ( _intersections.length > 0 ) {

this.enabled = true;
this.recursive = true;
this.transformGroup = false;

@@ -212,0 +213,0 @@

46

examples/jsm/csm/CSMShader.js

@@ -5,11 +5,11 @@ import { ShaderChunk } from 'three';

lights_fragment_begin: /* glsl */`
GeometricContext geometry;
vec3 geometryPosition = - vViewPosition;
vec3 geometryNormal = normal;
vec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );
geometry.position = - vViewPosition;
geometry.normal = normal;
geometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );
vec3 geometryClearcoatNormal;
#ifdef USE_CLEARCOAT
geometry.clearcoatNormal = clearcoatNormal;
geometryClearcoatNormal = clearcoatNormal;

@@ -19,3 +19,3 @@ #endif

#ifdef USE_IRIDESCENCE
float dotNVi = saturate( dot( normal, geometry.viewDir ) );
float dotNVi = saturate( dot( normal, geometryViewDir ) );
if ( material.iridescenceThickness == 0.0 ) {

@@ -47,3 +47,3 @@ material.iridescence = 0.0;

getPointLightInfo( pointLight, geometry, directLight );
getPointLightInfo( pointLight, geometryPosition, directLight );

@@ -55,3 +55,3 @@ #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )

RE_Direct( directLight, geometry, material, reflectedLight );
RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );

@@ -79,3 +79,3 @@ }

getSpotLightInfo( spotLight, geometry, directLight );
getSpotLightInfo( spotLight, geometryPosition, directLight );

@@ -104,3 +104,3 @@ // spot lights are ordered [shadows with maps, shadows without maps, maps without shadows, none]

RE_Direct( directLight, geometry, material, reflectedLight );
RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );

@@ -132,3 +132,3 @@ }

directionalLight = directionalLights[ i ];
getDirectionalLightInfo( directionalLight, geometry, directLight );
getDirectionalLightInfo( directionalLight, directLight );

@@ -157,3 +157,3 @@ #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )

ReflectedLight prevLight = reflectedLight;
RE_Direct( directLight, geometry, material, reflectedLight );
RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );

@@ -179,3 +179,3 @@ bool shouldBlend = UNROLLED_LOOP_INDEX != CSM_CASCADES - 1 || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 && linearDepth < cascadeCenter;

directionalLight = directionalLights[ i ];
getDirectionalLightInfo( directionalLight, geometry, directLight );
getDirectionalLightInfo( directionalLight, directLight );

@@ -187,3 +187,3 @@ #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )

if(linearDepth >= CSM_cascades[UNROLLED_LOOP_INDEX].x && (linearDepth < CSM_cascades[UNROLLED_LOOP_INDEX].y || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1)) RE_Direct( directLight, geometry, material, reflectedLight );
if(linearDepth >= CSM_cascades[UNROLLED_LOOP_INDEX].x && (linearDepth < CSM_cascades[UNROLLED_LOOP_INDEX].y || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1)) RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );

@@ -205,5 +205,5 @@ #endif

getDirectionalLightInfo( directionalLight, geometry, directLight );
getDirectionalLightInfo( directionalLight, directLight );
RE_Direct( directLight, geometry, material, reflectedLight );
RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );

@@ -230,3 +230,3 @@ }

getDirectionalLightInfo( directionalLight, geometry, directLight );
getDirectionalLightInfo( directionalLight, directLight );

@@ -238,3 +238,3 @@ #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )

RE_Direct( directLight, geometry, material, reflectedLight );
RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );

@@ -254,3 +254,3 @@ }

rectAreaLight = rectAreaLights[ i ];
RE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );
RE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );

@@ -268,4 +268,8 @@ }

irradiance += getLightProbeIrradiance( lightProbe, geometry.normal );
#if defined( USE_LIGHT_PROBES )
irradiance += getLightProbeIrradiance( lightProbe, geometryNormal );
#endif
#if ( NUM_HEMI_LIGHTS > 0 )

@@ -276,3 +280,3 @@

irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal );
irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal );

@@ -279,0 +283,0 @@ }

@@ -24,33 +24,52 @@ /**

parse( renderer, renderTarget, options ) {
parse( arg1, arg2, arg3 ) {
if ( ! supported( renderer, renderTarget ) ) return undefined;
if ( ! arg1 || ! ( arg1.isWebGLRenderer || arg1.isDataTexture ) ) {
const info = buildInfo( renderTarget, options ),
dataBuffer = getPixelData( renderer, renderTarget, info ),
rawContentBuffer = reorganizeDataBuffer( dataBuffer, info ),
chunks = compressData( rawContentBuffer, info );
throw Error( 'EXRExporter.parse: Unsupported first parameter, expected instance of WebGLRenderer or DataTexture.' );
return fillData( chunks, info );
} else if ( arg1.isWebGLRenderer ) {
}
const renderer = arg1, renderTarget = arg2, options = arg3;
}
supportedRTT( renderTarget );
function supported( renderer, renderTarget ) {
const info = buildInfoRTT( renderTarget, options ),
dataBuffer = getPixelData( renderer, renderTarget, info ),
rawContentBuffer = reorganizeDataBuffer( dataBuffer, info ),
chunks = compressData( rawContentBuffer, info );
if ( ! renderer || ! renderer.isWebGLRenderer ) {
return fillData( chunks, info );
console.error( 'EXRExporter.parse: Unsupported first parameter, expected instance of WebGLRenderer.' );
} else if ( arg1.isDataTexture ) {
return false;
const texture = arg1, options = arg2;
supportedDT( texture );
const info = buildInfoDT( texture, options ),
dataBuffer = texture.image.data,
rawContentBuffer = reorganizeDataBuffer( dataBuffer, info ),
chunks = compressData( rawContentBuffer, info );
return fillData( chunks, info );
}
}
}
function supportedRTT( renderTarget ) {
if ( ! renderTarget || ! renderTarget.isWebGLRenderTarget ) {
console.error( 'EXRExporter.parse: Unsupported second parameter, expected instance of WebGLRenderTarget.' );
throw Error( 'EXRExporter.parse: Unsupported second parameter, expected instance of WebGLRenderTarget.' );
return false;
}
if ( renderTarget.isWebGLCubeRenderTarget || renderTarget.isWebGL3DRenderTarget || renderTarget.isWebGLArrayRenderTarget ) {
throw Error( 'EXRExporter.parse: Unsupported render target type, expected instance of WebGLRenderTarget.' );
}

@@ -60,6 +79,4 @@

console.error( 'EXRExporter.parse: Unsupported WebGLRenderTarget texture type.' );
throw Error( 'EXRExporter.parse: Unsupported WebGLRenderTarget texture type.' );
return false;
}

@@ -69,14 +86,43 @@

console.error( 'EXRExporter.parse: Unsupported WebGLRenderTarget texture format, expected RGBAFormat.' );
throw Error( 'EXRExporter.parse: Unsupported WebGLRenderTarget texture format, expected RGBAFormat.' );
return false;
}
}
function supportedDT( texture ) {
if ( texture.type !== FloatType && texture.type !== HalfFloatType ) {
throw Error( 'EXRExporter.parse: Unsupported DataTexture texture type.' );
}
if ( texture.format !== RGBAFormat ) {
return true;
throw Error( 'EXRExporter.parse: Unsupported DataTexture texture format, expected RGBAFormat.' );
}
if ( ! texture.image.data ) {
throw Error( 'EXRExporter.parse: Invalid DataTexture image data.' );
}
if ( texture.type === FloatType && texture.image.data.constructor.name !== 'Float32Array' ) {
throw Error( 'EXRExporter.parse: DataTexture image data doesn\'t match type, expected \'Float32Array\'.' );
}
if ( texture.type === HalfFloatType && texture.image.data.constructor.name !== 'Uint16Array' ) {
throw Error( 'EXRExporter.parse: DataTexture image data doesn\'t match type, expected \'Uint16Array\'.' );
}
}
function buildInfo( renderTarget, options = {} ) {
function buildInfoRTT( renderTarget, options = {} ) {

@@ -93,3 +139,2 @@ const compressionSizes = {

FORMAT = renderTarget.texture.format,
COLOR_SPACE = renderTarget.texture.colorSpace,
COMPRESSION = ( options.compression !== undefined ) ? options.compression : ZIP_COMPRESSION,

@@ -106,3 +151,2 @@ EXPORTER_TYPE = ( options.type !== undefined ) ? options.type : HalfFloatType,

format: FORMAT,
colorSpace: COLOR_SPACE,
compression: COMPRESSION,

@@ -119,2 +163,36 @@ blockLines: COMPRESSION_SIZE,

function buildInfoDT( texture, options = {} ) {
const compressionSizes = {
0: 1,
2: 1,
3: 16
};
const WIDTH = texture.image.width,
HEIGHT = texture.image.height,
TYPE = texture.type,
FORMAT = texture.format,
COMPRESSION = ( options.compression !== undefined ) ? options.compression : ZIP_COMPRESSION,
EXPORTER_TYPE = ( options.type !== undefined ) ? options.type : HalfFloatType,
OUT_TYPE = ( EXPORTER_TYPE === FloatType ) ? 2 : 1,
COMPRESSION_SIZE = compressionSizes[ COMPRESSION ],
NUM_CHANNELS = 4;
return {
width: WIDTH,
height: HEIGHT,
type: TYPE,
format: FORMAT,
compression: COMPRESSION,
blockLines: COMPRESSION_SIZE,
dataType: OUT_TYPE,
dataSize: 2 * OUT_TYPE,
numBlocks: Math.ceil( HEIGHT / COMPRESSION_SIZE ),
numInputChannels: 4,
numOutputChannels: NUM_CHANNELS,
};
}
function getPixelData( renderer, rtt, info ) {

@@ -121,0 +199,0 @@

@@ -8,3 +8,5 @@ import {

SRGBColorSpace,
NoColorSpace
NoColorSpace,
HalfFloatType,
DataUtils
} from 'three';

@@ -144,6 +146,22 @@

const dataType = cubeRenderTarget.texture.type;
for ( let faceIndex = 0; faceIndex < 6; faceIndex ++ ) {
const imageWidth = cubeRenderTarget.width; // assumed to be square
const data = new Uint8Array( imageWidth * imageWidth * 4 );
let data;
if ( dataType === HalfFloatType ) {
data = new Uint16Array( imageWidth * imageWidth * 4 );
} else {
// assuming UnsignedByteType
data = new Uint8Array( imageWidth * imageWidth * 4 );
}
renderer.readRenderTargetPixels( cubeRenderTarget, 0, 0, imageWidth, imageWidth, data, faceIndex );

@@ -155,4 +173,20 @@

let r, g, b;
if ( dataType === HalfFloatType ) {
r = DataUtils.fromHalfFloat( data[ i ] );
g = DataUtils.fromHalfFloat( data[ i + 1 ] );
b = DataUtils.fromHalfFloat( data[ i + 2 ] );
} else {
r = data[ i ] / 255;
g = data[ i + 1 ] / 255;
b = data[ i + 2 ] / 255;
}
// pixel color
color.setRGB( data[ i ] / 255, data[ i + 1 ] / 255, data[ i + 2 ] / 255 );
color.setRGB( r, g, b );

@@ -159,0 +193,0 @@ // convert to linear color space

@@ -456,244 +456,178 @@ /**

Object.defineProperties( this, {
this.setValues( parameters );
color: {
}
enumerable: true,
get color() {
get: function () {
return this.uniforms.diffuse.value;
return this.uniforms.diffuse.value;
}
},
set color( value ) {
set: function ( value ) {
this.uniforms.diffuse.value = value;
this.uniforms.diffuse.value = value;
}
}
get worldUnits() {
},
return 'WORLD_UNITS' in this.defines;
worldUnits: {
}
enumerable: true,
set worldUnits( value ) {
get: function () {
if ( value === true ) {
return 'WORLD_UNITS' in this.defines;
this.defines.WORLD_UNITS = '';
},
} else {
set: function ( value ) {
delete this.defines.WORLD_UNITS;
if ( value === true ) {
}
this.defines.WORLD_UNITS = '';
}
} else {
get linewidth() {
delete this.defines.WORLD_UNITS;
return this.uniforms.linewidth.value;
}
}
}
set linewidth( value ) {
},
if ( ! this.uniforms.linewidth ) return;
this.uniforms.linewidth.value = value;
linewidth: {
}
enumerable: true,
get dashed() {
get: function () {
return 'USE_DASH' in this.defines;
return this.uniforms.linewidth.value;
}
},
set dashed( value ) {
set: function ( value ) {
if ( ( value === true ) !== this.dashed ) {
this.uniforms.linewidth.value = value;
this.needsUpdate = true;
}
}
},
if ( value === true ) {
dashed: {
this.defines.USE_DASH = '';
enumerable: true,
} else {
get: function () {
delete this.defines.USE_DASH;
return Boolean( 'USE_DASH' in this.defines );
}
},
}
set( value ) {
get dashScale() {
if ( Boolean( value ) !== Boolean( 'USE_DASH' in this.defines ) ) {
return this.uniforms.dashScale.value;
this.needsUpdate = true;
}
}
set dashScale( value ) {
if ( value === true ) {
this.uniforms.dashScale.value = value;
this.defines.USE_DASH = '';
}
} else {
get dashSize() {
delete this.defines.USE_DASH;
return this.uniforms.dashSize.value;
}
}
}
set dashSize( value ) {
},
this.uniforms.dashSize.value = value;
dashScale: {
}
enumerable: true,
get dashOffset() {
get: function () {
return this.uniforms.dashOffset.value;
return this.uniforms.dashScale.value;
}
},
set dashOffset( value ) {
set: function ( value ) {
this.uniforms.dashOffset.value = value;
this.uniforms.dashScale.value = value;
}
}
get gapSize() {
},
return this.uniforms.gapSize.value;
dashSize: {
}
enumerable: true,
set gapSize( value ) {
get: function () {
this.uniforms.gapSize.value = value;
return this.uniforms.dashSize.value;
}
},
get opacity() {
set: function ( value ) {
return this.uniforms.opacity.value;
this.uniforms.dashSize.value = value;
}
}
set opacity( value ) {
},
if ( ! this.uniforms ) return;
this.uniforms.opacity.value = value;
dashOffset: {
}
enumerable: true,
get resolution() {
get: function () {
return this.uniforms.resolution.value;
return this.uniforms.dashOffset.value;
}
},
set resolution( value ) {
set: function ( value ) {
this.uniforms.resolution.value.copy( value );
this.uniforms.dashOffset.value = value;
}
}
get alphaToCoverage() {
},
return 'USE_ALPHA_TO_COVERAGE' in this.defines;
gapSize: {
}
enumerable: true,
set alphaToCoverage( value ) {
get: function () {
if ( ! this.defines ) return;
return this.uniforms.gapSize.value;
if ( ( value === true ) !== this.alphaToCoverage ) {
},
this.needsUpdate = true;
set: function ( value ) {
}
this.uniforms.gapSize.value = value;
if ( value === true ) {
}
this.defines.USE_ALPHA_TO_COVERAGE = '';
this.extensions.derivatives = true;
},
} else {
opacity: {
delete this.defines.USE_ALPHA_TO_COVERAGE;
this.extensions.derivatives = false;
enumerable: true,
}
get: function () {
return this.uniforms.opacity.value;
},
set: function ( value ) {
this.uniforms.opacity.value = value;
}
},
resolution: {
enumerable: true,
get: function () {
return this.uniforms.resolution.value;
},
set: function ( value ) {
this.uniforms.resolution.value.copy( value );
}
},
alphaToCoverage: {
enumerable: true,
get: function () {
return Boolean( 'USE_ALPHA_TO_COVERAGE' in this.defines );
},
set: function ( value ) {
if ( Boolean( value ) !== Boolean( 'USE_ALPHA_TO_COVERAGE' in this.defines ) ) {
this.needsUpdate = true;
}
if ( value === true ) {
this.defines.USE_ALPHA_TO_COVERAGE = '';
this.extensions.derivatives = true;
} else {
delete this.defines.USE_ALPHA_TO_COVERAGE;
this.extensions.derivatives = false;
}
}
}
} );
this.setValues( parameters );
}

@@ -700,0 +634,0 @@

@@ -7,2 +7,3 @@ import {

MeshStandardMaterial,
MeshPhysicalMaterial,
Mesh,

@@ -29,2 +30,4 @@ Color,

import { EXRLoader } from '../loaders/EXRLoader.js';
const _taskCache = new WeakMap();

@@ -222,3 +225,3 @@

_createMaterial( material ) {
_createMaterial( material, renderEnvironment ) {

@@ -236,24 +239,48 @@ if ( material === undefined ) {

const _diffuseColor = material.diffuseColor;
//console.log(material)
const diffusecolor = new Color( _diffuseColor.r / 255.0, _diffuseColor.g / 255.0, _diffuseColor.b / 255.0 );
let mat = new MeshPhysicalMaterial( {
if ( _diffuseColor.r === 0 && _diffuseColor.g === 0 && _diffuseColor.b === 0 ) {
color: new Color( material.diffuseColor.r / 255.0, material.diffuseColor.g / 255.0, material.diffuseColor.b / 255.0 ),
emissive: new Color( material.emissionColor.r, material.emissionColor.g, material.emissionColor.b ),
flatShading: material.disableLighting,
ior: material.indexOfRefraction,
name: material.name,
reflectivity: material.reflectivity,
opacity: 1.0 - material.transparency,
side: DoubleSide,
specularColor: material.specularColor,
transparent: material.transparency > 0 ? true : false
diffusecolor.r = 1;
diffusecolor.g = 1;
diffusecolor.b = 1;
} );
mat.userData.id = material.id;
if ( material.pbrSupported ) {
const pbr = material.pbr;
mat.anisotropy = pbr.anisotropy;
mat.anisotropyRotation = pbr.anisotropicRotation;
mat.color = new Color( pbr.baseColor.r, pbr.baseColor.g, pbr.baseColor.b );
mat.clearCoat = pbr.clearCoat;
mat.clearCoatRoughness = pbr.clearCoatRoughness;
mat.metalness = pbr.metallic;
mat.transmission = 1 - pbr.opacity;
mat.roughness = pbr.roughness;
mat.sheen = pbr.sheen;
mat.specularIntensity = pbr.specular;
mat.thickness = pbr.subsurface;
}
// console.log( material );
if ( material.pbrSupported && material.pbr.opacity === 0 && material.transparency === 1 ) {
const mat = new MeshStandardMaterial( {
color: diffusecolor,
name: material.name,
side: DoubleSide,
transparent: material.transparency > 0 ? true : false,
opacity: 1.0 - material.transparency
} );
//some compromises
mat.opacity = 0.2;
mat.transmission = 1.00;
}
const textureLoader = new TextureLoader();

@@ -269,4 +296,12 @@

//console.log(texture.type )
switch ( texture.type ) {
case 'Bump':
mat.bumpMap = map;
break;
case 'Diffuse':

@@ -278,8 +313,14 @@

case 'Bump':
case 'Emap':
mat.bumpMap = map;
mat.envMap = map;
break;
case 'Opacity':
mat.transmissionMap = map;
break;
case 'Transparency':

@@ -292,8 +333,96 @@

case 'Emap':
case 'PBR_Alpha':
mat.envMap = map;
mat.alphaMap = map;
mat.transparent = true;
break;
case 'PBR_AmbientOcclusion':
mat.aoMap = map;
break;
case 'PBR_Anisotropic':
mat.anisotropyMap = map;
break;
case 'PBR_BaseColor':
mat.map = map;
break;
case 'PBR_Clearcoat':
mat.clearcoatMap = map;
break;
case 'PBR_ClearcoatBump':
mat.clearcoatNormalMap = map;
break;
case 'PBR_ClearcoatRoughness':
mat.clearcoatRoughnessMap = map;
break;
case 'PBR_Displacement':
mat.displacementMap = map;
break;
case 'PBR_Emission':
mat.emissiveMap = map;
break;
case 'PBR_Metallic':
mat.metalnessMap = map;
break;
case 'PBR_Roughness':
mat.roughnessMap = map;
break;
case 'PBR_Sheen':
mat.sheenColorMap = map;
break;
case 'PBR_Specular':
mat.specularColorMap = map;
break;
case 'PBR_Subsurface':
mat.thicknessMap = map;
break;
default:
this.warnings.push( {
message: `THREE.3DMLoader: No conversion exists for 3dm ${texture.type}.`,
type: 'no conversion'
} );
break;
}

@@ -303,4 +432,9 @@

map.wrapT = texture.wrapV === 0 ? RepeatWrapping : ClampToEdgeWrapping;
map.repeat.set( texture.repeat[ 0 ], texture.repeat[ 1 ] );
if ( texture.repeat ) {
map.repeat.set( texture.repeat[ 0 ], texture.repeat[ 1 ] );
}
}

@@ -310,2 +444,13 @@

if ( renderEnvironment ) {
new EXRLoader().load( renderEnvironment.image, function ( texture ) {
texture.mapping = THREE.EquirectangularReflectionMapping;
mat.envMap = texture;
} );
}
return mat;

@@ -317,4 +462,2 @@

// console.log(data);
const object = new Object3D();

@@ -328,4 +471,6 @@ const instanceDefinitionObjects = [];

object.userData[ 'settings' ] = data.settings;
object.userData.settings[ 'renderSettings' ] = data.renderSettings;
object.userData[ 'objectType' ] = 'File3dm';
object.userData[ 'materials' ] = null;
object.name = this.url;

@@ -357,18 +502,52 @@

let _object;
let matId;
if ( attributes.materialIndex >= 0 ) {
switch( attributes.materialSource.name ) {
case 'ObjectMaterialSource_MaterialFromLayer':
//check layer index
if ( attributes.layerIndex >= 0 ) {
const rMaterial = materials[ attributes.materialIndex ];
let material = this._createMaterial( rMaterial );
material = this._compareMaterials( material );
_object = this._createObject( obj, material );
matId = data.layers[ attributes.layerIndex ].renderMaterialIndex;
} else {
matId = null;
}
break;
case 'ObjectMaterialSource_MaterialFromObject':
if ( attributes.materialIndex >= 0 ) {
matId = attributes.materialIndex;
} else {
matId = null;
}
break;
}
let material;
if ( matId >= 0 ) {
const rMaterial = materials[ matId ];
material = this._createMaterial( rMaterial, data.renderEnvironment );
} else {
const material = this._createMaterial();
_object = this._createObject( obj, material );
material = this._createMaterial();
}
material = this._compareMaterials( material );
const _object = this._createObject( obj, material );
if ( _object === undefined ) {

@@ -455,2 +634,3 @@

object.userData[ 'materials' ] = this.materials;
object.name = '';
return object;

@@ -658,3 +838,3 @@

case 'LightStyle_WorldLinear':
// not conversion exists, warning has already been printed to the console
// no conversion exists, warning has already been printed to the console
break;

@@ -838,3 +1018,2 @@

// console.log(message)
libraryConfig = message.libraryConfig;

@@ -920,3 +1099,3 @@ const wasmBinary = libraryConfig.wasmBinary;

for ( let i = 0; i < doc.instanceDefinitions().count(); i ++ ) {
for ( let i = 0; i < doc.instanceDefinitions().count; i ++ ) {

@@ -965,6 +1144,5 @@ const idef = doc.instanceDefinitions().get( i );

for ( let i = 0; i < doc.materials().count(); i ++ ) {
for ( let i = 0; i < doc.materials().count; i ++ ) {
const _material = doc.materials().get( i );
const _pbrMaterial = _material.physicallyBased();

@@ -975,42 +1153,11 @@ let material = extractProperties( _material );

for ( let j = 0; j < textureTypes.length; j ++ ) {
textures.push( ...extractTextures( _material, textureTypes, doc ) );
const _texture = _material.getTexture( textureTypes[ j ] );
if ( _texture ) {
material.pbrSupported = _material.physicallyBased().supported;
let textureType = textureTypes[ j ].constructor.name;
textureType = textureType.substring( 12, textureType.length );
const texture = { type: textureType };
if ( material.pbrSupported ) {
const image = doc.getEmbeddedFileAsBase64( _texture.fileName );
textures.push( ...extractTextures( _material, pbrTextureTypes, doc ) );
material.pbr = extractProperties( _material.physicallyBased() );
texture.wrapU = _texture.wrapU;
texture.wrapV = _texture.wrapV;
texture.wrapW = _texture.wrapW;
const uvw = _texture.uvwTransform.toFloatArray( true );
texture.repeat = [ uvw[ 0 ], uvw[ 5 ] ];
if ( image ) {
texture.image = 'data:image/png;base64,' + image;
} else {
self.postMessage( { type: 'warning', id: taskID, data: {
message: `THREE.3DMLoader: Image for ${textureType} texture not embedded in file.`,
type: 'missing resource'
}
} );
texture.image = null;
}
textures.push( texture );
_texture.delete();
}
}

@@ -1020,31 +1167,5 @@

if ( _pbrMaterial.supported ) {
for ( let j = 0; j < pbrTextureTypes.length; j ++ ) {
const _texture = _material.getTexture( pbrTextureTypes[ j ] );
if ( _texture ) {
const image = doc.getEmbeddedFileAsBase64( _texture.fileName );
let textureType = pbrTextureTypes[ j ].constructor.name;
textureType = textureType.substring( 12, textureType.length );
const texture = { type: textureType, image: 'data:image/png;base64,' + image };
textures.push( texture );
_texture.delete();
}
}
const pbMaterialProperties = extractProperties( _material.physicallyBased() );
material = Object.assign( pbMaterialProperties, material );
}
materials.push( material );
_material.delete();
_pbrMaterial.delete();

@@ -1055,3 +1176,3 @@ }

for ( let i = 0; i < doc.layers().count(); i ++ ) {
for ( let i = 0; i < doc.layers().count; i ++ ) {

@@ -1069,3 +1190,3 @@ const _layer = doc.layers().get( i );

for ( let i = 0; i < doc.views().count(); i ++ ) {
for ( let i = 0; i < doc.views().count; i ++ ) {

@@ -1083,3 +1204,3 @@ const _view = doc.views().get( i );

for ( let i = 0; i < doc.namedViews().count(); i ++ ) {
for ( let i = 0; i < doc.namedViews().count; i ++ ) {

@@ -1097,3 +1218,3 @@ const _namedView = doc.namedViews().get( i );

for ( let i = 0; i < doc.groups().count(); i ++ ) {
for ( let i = 0; i < doc.groups().count; i ++ ) {

@@ -1124,5 +1245,5 @@ const _group = doc.groups().get( i );

// Note: doc.strings().documentUserTextCount() counts any doc.strings defined in a section
//console.log( `Document User Text Count: ${doc.strings().documentUserTextCount()}` );
// console.log( `Document User Text Count: ${doc.strings().documentUserTextCount()}` );
const strings_count = doc.strings().count();
const strings_count = doc.strings().count;

@@ -1135,8 +1256,145 @@ for ( let i = 0; i < strings_count; i ++ ) {

// Handle Render Environments for Material Environment
// get the id of the active render environment skylight, which we'll use for environment texture
const reflectionId = doc.settings().renderSettings().renderEnvironments.reflectionId
const rc = doc.renderContent()
let renderEnvironment = null
for( let i = 0; i < rc.count; i++ ) {
const content = rc.get(i)
switch( content.kind ) {
case 'environment':
const id = content.id
// there could be multiple render environments in a 3dm file
if ( id !== reflectionId ) break;
const renderTexture = content.findChild( 'texture' )
const fileName = renderTexture.fileName
for ( let j = 0; j < doc.embeddedFiles().count; j ++ ) {
const _fileName = doc.embeddedFiles().get( j ).fileName
if ( fileName === _fileName ) {
const background = doc.getEmbeddedFileAsBase64( fileName )
const backgroundImage = 'data:image/png;base64,' + background
renderEnvironment = { type: 'renderEnvironment', image: backgroundImage, name: fileName };
}
}
break;
}
}
// Handle Render Settings
const renderSettings = {
ambientLight: doc.settings().renderSettings().ambientLight,
backgroundColorTop: doc.settings().renderSettings().backgroundColorTop,
backgroundColorBottom: doc.settings().renderSettings().backgroundColorBottom,
useHiddenLights: doc.settings().renderSettings().useHiddenLights,
depthCue: doc.settings().renderSettings().depthCue,
flatShade: doc.settings().renderSettings().flatShade,
renderBackFaces: doc.settings().renderSettings().renderBackFaces,
renderPoints: doc.settings().renderSettings().renderPoints,
renderCurves: doc.settings().renderSettings().renderCurves,
renderIsoParams: doc.settings().renderSettings().renderIsoParams,
renderMeshEdges: doc.settings().renderSettings().renderMeshEdges,
renderAnnotations: doc.settings().renderSettings().renderAnnotations,
useViewportSize: doc.settings().renderSettings().useViewportSize,
scaleBackgroundToFit: doc.settings().renderSettings().scaleBackgroundToFit,
transparentBackground: doc.settings().renderSettings().transparentBackground,
imageDpi: doc.settings().renderSettings().imageDpi,
shadowMapLevel: doc.settings().renderSettings().shadowMapLevel,
namedView: doc.settings().renderSettings().namedView,
snapShot: doc.settings().renderSettings().snapShot,
specificViewport: doc.settings().renderSettings().specificViewport,
groundPlane: extractProperties( doc.settings().renderSettings().groundPlane ),
safeFrame: extractProperties( doc.settings().renderSettings().safeFrame ),
dithering: extractProperties( doc.settings().renderSettings().dithering ),
skylight: extractProperties( doc.settings().renderSettings().skylight ),
linearWorkflow: extractProperties( doc.settings().renderSettings().linearWorkflow ),
renderChannels: extractProperties( doc.settings().renderSettings().renderChannels ),
sun: extractProperties( doc.settings().renderSettings().sun ),
renderEnvironments: extractProperties( doc.settings().renderSettings().renderEnvironments ),
postEffects: extractProperties( doc.settings().renderSettings().postEffects ),
}
doc.delete();
return { objects, materials, layers, views, namedViews, groups, strings, settings };
return { objects, materials, layers, views, namedViews, groups, strings, settings, renderSettings, renderEnvironment };
}
function extractTextures( m, tTypes, d ) {
const textures = []
for ( let i = 0; i < tTypes.length; i ++ ) {
const _texture = m.getTexture( tTypes[ i ] );
if ( _texture ) {
let textureType = tTypes[ i ].constructor.name;
textureType = textureType.substring( 12, textureType.length );
const texture = extractTextureData( _texture, textureType, d );
textures.push( texture );
_texture.delete();
}
}
return textures;
}
function extractTextureData( t, tType, d ) {
const texture = { type: tType };
const image = d.getEmbeddedFileAsBase64( t.fileName );
texture.wrapU = t.wrapU;
texture.wrapV = t.wrapV;
texture.wrapW = t.wrapW;
const uvw = t.uvwTransform.toFloatArray( true );
texture.repeat = [ uvw[ 0 ], uvw[ 5 ] ];
if ( image ) {
texture.image = 'data:image/png;base64,' + image;
} else {
self.postMessage( { type: 'warning', id: taskID, data: {
message: `THREE.3DMLoader: Image for ${tType} texture not embedded in file.`,
type: 'missing resource'
}
} );
texture.image = null;
}
return texture;
}
function extractObjectData( object, doc ) {

@@ -1351,2 +1609,14 @@

if ( _attributes.decals().count > 0 ) {
self.postMessage( { type: 'warning', id: taskID, data: {
message: `THREE.3DMLoader: No conversion exists for the decals associated with this object.`,
type: 'no conversion',
guid: _attributes.id
}
} );
}
attributes.drawColor = _attributes.drawColor( doc );

@@ -1387,2 +1657,6 @@

} else if ( typeof value === 'object' && value !== null ) {
result[ property ] = extractProperties( value );
} else {

@@ -1389,0 +1663,0 @@

@@ -1523,3 +1523,3 @@ import {

group.add( createObject( info.faces, 3, false, info.totalFaces ) );
group.add( createObject( this.loader, info.faces, 3, false, info.totalFaces ) );

@@ -1530,3 +1530,3 @@ }

group.add( createObject( info.lineSegments, 2 ) );
group.add( createObject( this.loader, info.lineSegments, 2 ) );

@@ -1537,3 +1537,3 @@ }

group.add( createObject( info.conditionalSegments, 2, true ) );
group.add( createObject( this.loader, info.conditionalSegments, 2, true ) );

@@ -1646,3 +1646,3 @@ }

function createObject( elements, elementSize, isConditionalSegments = false, totalElements = null ) {
function createObject( loader, elements, elementSize, isConditionalSegments = false, totalElements = null ) {

@@ -1766,7 +1766,9 @@ // Creates a LineSegments (elementSize = 2) or a Mesh (elementSize = 3 )

materials.push( material.userData.edgeMaterial.userData.conditionalEdgeMaterial );
const edgeMaterial = loader.edgeMaterialCache.get( material );
materials.push( loader.conditionalEdgeMaterialCache.get( edgeMaterial ) );
} else {
materials.push( material.userData.edgeMaterial );
materials.push( loader.edgeMaterialCache.get( material ) );

@@ -1894,2 +1896,4 @@ }

this.materialLibrary = {};
this.edgeMaterialCache = new WeakMap();
this.conditionalEdgeMaterialCache = new WeakMap();

@@ -1915,4 +1919,4 @@ // This also allows to handle the embedded text files ("0 FILE" lines)

this.missingConditionalEdgeColorMaterial = new LDrawConditionalLineMaterial( { name: Loader.DEFAULT_MATERIAL_NAME, fog: true, color: 0xFF00FF } );
this.missingColorMaterial.userData.edgeMaterial = this.missingEdgeColorMaterial;
this.missingEdgeColorMaterial.userData.conditionalEdgeMaterial = this.missingConditionalEdgeColorMaterial;
this.edgeMaterialCache.set( this.missingColorMaterial, this.missingEdgeColorMaterial );
this.conditionalEdgeMaterialCache.set( this.missingEdgeColorMaterial, this.missingConditionalEdgeColorMaterial );

@@ -2136,7 +2140,7 @@ }

material = material.userData.edgeMaterial;
material = loader.edgeMaterialCache.get( material );
if ( c.isConditionalLine ) {
material = material.userData.conditionalEdgeMaterial;
material = loader.conditionalEdgeMaterialCache.get( material );

@@ -2162,3 +2166,3 @@ }

const mat = this.getMaterial( MAIN_EDGE_COLOUR_CODE );
return mat ? mat.userData.edgeMaterial : null;
return mat ? this.edgeMaterialCache.get( mat ) : null;

@@ -2248,3 +2252,3 @@ }

// Get the edge material for this triangle material
edgeMaterial = edgeMaterial.userData.edgeMaterial;
edgeMaterial = this.edgeMaterialCache.get( edgeMaterial );

@@ -2393,3 +2397,3 @@ }

// This is the material used for conditional edges
edgeMaterial.userData.conditionalEdgeMaterial = new LDrawConditionalLineMaterial( {
const conditionalEdgeMaterial = new LDrawConditionalLineMaterial( {

@@ -2403,5 +2407,7 @@ fog: true,

} );
edgeMaterial.userData.conditionalEdgeMaterial.userData.code = code;
edgeMaterial.userData.conditionalEdgeMaterial.name = name + ' - Conditional Edge';
conditionalEdgeMaterial.userData.code = code;
conditionalEdgeMaterial.name = name + ' - Conditional Edge';
this.conditionalEdgeMaterialCache.set( edgeMaterial, conditionalEdgeMaterial );
}

@@ -2412,3 +2418,3 @@

material.userData.edgeMaterial = edgeMaterial;
this.edgeMaterialCache.set( material, edgeMaterial );

@@ -2415,0 +2421,0 @@ this.addMaterial( material );

@@ -398,3 +398,3 @@ import {

throw new Error( 'THREE.RGBELoader: unsupported type: ', this.type );
throw new Error( 'THREE.RGBELoader: Unsupported type: ' + this.type );
break;

@@ -401,0 +401,0 @@

@@ -7,5 +7,6 @@ import {

Group,
NoColorSpace,
Loader,
Mesh,
MeshStandardMaterial,
MeshPhysicalMaterial,
MirroredRepeatWrapping,

@@ -16,2 +17,3 @@ RepeatWrapping,

Object3D,
Vector2
} from 'three';

@@ -183,4 +185,11 @@

if ( filename.endsWith( 'usd' ) ) {
if ( filename.endsWith( 'usd' ) || filename.endsWith( 'usda' ) ) {
if ( isCrateFile( zip[ filename ] ) ) {
console.warn( 'THREE.USDZLoader: Crate files (.usdc or binary .usd) are not supported.' );
continue;
}
const text = fflate.strFromU8( zip[ filename ] );

@@ -197,10 +206,40 @@ data[ filename ] = parser.parse( text );

function isCrateFile( buffer ) {
// Check if this a crate file. First 7 bytes of a crate file are "PXR-USDC".
const fileHeader = buffer.slice( 0, 7 );
const crateHeader = new Uint8Array( [ 0x50, 0x58, 0x52, 0x2D, 0x55, 0x53, 0x44, 0x43 ] );
// If this is not a crate file, we assume it is a plain USDA file.
return fileHeader.every( ( value, index ) => value === crateHeader[ index ] );
}
function findUSD( zip ) {
for ( const filename in zip ) {
if ( zip.length < 1 ) return undefined;
if ( filename.endsWith( 'usda' ) ) {
const firstFileName = Object.keys( zip )[ 0 ];
let isCrate = false;
return zip[ filename ];
// As per the USD specification, the first entry in the zip archive is used as the main file ("UsdStage").
// ASCII files can end in either .usda or .usd.
// See https://openusd.org/release/spec_usdz.html#layout
if ( firstFileName.endsWith( 'usda' ) ) return zip[ firstFileName ];
if ( firstFileName.endsWith( 'usdc' ) ) {
isCrate = true;
} else if ( firstFileName.endsWith( 'usd' ) ) {
// If this is not a crate file, we assume it is a plain USDA file.
if ( ! isCrateFile( zip[ firstFileName ] ) ) {
return zip[ firstFileName ];
} else {
isCrate = true;
}

@@ -210,2 +249,10 @@

if ( isCrate ) {
console.warn( 'THREE.USDZLoader: Crate files (.usdc or binary .usd) are not supported.' );
}
return undefined;
}

@@ -260,5 +307,7 @@

if ( ! data ) return undefined;
if ( id !== undefined ) {
const def = `def "${id}"`;
const def = `def Mesh "${id}"`;

@@ -289,5 +338,5 @@ if ( def in data ) {

if ( 'float2[] primvars:st' in data ) {
if ( 'texCoord2f[] primvars:st' in data ) {
object[ 'float2[] primvars:st' ] = data[ 'float2[] primvars:st' ];
object[ 'texCoord2f[] primvars:st' ] = data[ 'texCoord2f[] primvars:st' ];

@@ -330,3 +379,3 @@ }

const indices = JSON.parse( data[ 'int[] faceVertexIndices' ] );
geometry.setIndex( new BufferAttribute( new Uint16Array( indices ), 1 ) );
geometry.setIndex( indices );

@@ -452,5 +501,29 @@ }

function setTextureParams( map, data_value ) {
// rotation, scale and translation
if ( data_value[ 'float inputs:rotation' ] ) {
map.rotation = parseFloat( data_value[ 'float inputs:rotation' ] );
}
if ( data_value[ 'float2 inputs:scale' ] ) {
map.repeat = new Vector2().fromArray( JSON.parse( '[' + data_value[ 'float2 inputs:scale' ].replace( /[()]*/g, '' ) + ']' ) );
}
if ( data_value[ 'float2 inputs:translation' ] ) {
map.offset = new Vector2().fromArray( JSON.parse( '[' + data_value[ 'float2 inputs:translation' ].replace( /[()]*/g, '' ) + ']' ) );
}
}
function buildMaterial( data ) {
const material = new MeshStandardMaterial();
const material = new MeshPhysicalMaterial();

@@ -471,2 +544,8 @@ if ( data !== undefined ) {

if ( 'def Shader "Transform2d_diffuse"' in data ) {
setTextureParams( material.map, data[ 'def Shader "Transform2d_diffuse"' ] );
}
} else if ( 'color3f inputs:diffuseColor' in surface ) {

@@ -479,2 +558,24 @@

if ( 'color3f inputs:emissiveColor.connect' in surface ) {
const path = surface[ 'color3f inputs:emissiveColor.connect' ];
const sampler = findTexture( root, /(\w+).output/.exec( path )[ 1 ] );
material.emissiveMap = buildTexture( sampler );
material.emissiveMap.colorSpace = SRGBColorSpace;
material.emissive.set( 0xffffff );
if ( 'def Shader "Transform2d_emissive"' in data ) {
setTextureParams( material.emissiveMap, data[ 'def Shader "Transform2d_emissive"' ] );
}
} else if ( 'color3f inputs:emissiveColor' in surface ) {
const color = surface[ 'color3f inputs:emissiveColor' ].replace( /[()]*/g, '' );
material.emissive.fromArray( JSON.parse( '[' + color + ']' ) );
}
if ( 'normal3f inputs:normal.connect' in surface ) {

@@ -486,7 +587,29 @@

material.normalMap = buildTexture( sampler );
material.normalMap.colorSpace = NoColorSpace;
if ( 'def Shader "Transform2d_normal"' in data ) {
setTextureParams( material.normalMap, data[ 'def Shader "Transform2d_normal"' ] );
}
}
if ( 'float inputs:roughness' in surface ) {
if ( 'float inputs:roughness.connect' in surface ) {
const path = surface[ 'float inputs:roughness.connect' ];
const sampler = findTexture( root, /(\w+).output/.exec( path )[ 1 ] );
material.roughness = 1.0;
material.roughnessMap = buildTexture( sampler );
material.roughnessMap.colorSpace = NoColorSpace;
if ( 'def Shader "Transform2d_roughness"' in data ) {
setTextureParams( material.roughnessMap, data[ 'def Shader "Transform2d_roughness"' ] );
}
} else if ( 'float inputs:roughness' in surface ) {
material.roughness = parseFloat( surface[ 'float inputs:roughness' ] );

@@ -496,4 +619,19 @@

if ( 'float inputs:metallic' in surface ) {
if ( 'float inputs:metallic.connect' in surface ) {
const path = surface[ 'float inputs:metallic.connect' ];
const sampler = findTexture( root, /(\w+).output/.exec( path )[ 1 ] );
material.metalness = 1.0;
material.metalnessMap = buildTexture( sampler );
material.metalnessMap.colorSpace = NoColorSpace;
if ( 'def Shader "Transform2d_metallic"' in data ) {
setTextureParams( material.metalnessMap, data[ 'def Shader "Transform2d_metallic"' ] );
}
} else if ( 'float inputs:metallic' in surface ) {
material.metalness = parseFloat( surface[ 'float inputs:metallic' ] );

@@ -503,2 +641,66 @@

if ( 'float inputs:clearcoat.connect' in surface ) {
const path = surface[ 'float inputs:clearcoat.connect' ];
const sampler = findTexture( root, /(\w+).output/.exec( path )[ 1 ] );
material.clearcoat = 1.0;
material.clearcoatMap = buildTexture( sampler );
material.clearcoatMap.colorSpace = NoColorSpace;
if ( 'def Shader "Transform2d_clearcoat"' in data ) {
setTextureParams( material.clearcoatMap, data[ 'def Shader "Transform2d_clearcoat"' ] );
}
} else if ( 'float inputs:clearcoat' in surface ) {
material.clearcoat = parseFloat( surface[ 'float inputs:clearcoat' ] );
}
if ( 'float inputs:clearcoatRoughness.connect' in surface ) {
const path = surface[ 'float inputs:clearcoatRoughness.connect' ];
const sampler = findTexture( root, /(\w+).output/.exec( path )[ 1 ] );
material.clearcoatRoughness = 1.0;
material.clearcoatRoughnessMap = buildTexture( sampler );
material.clearcoatRoughnessMap.colorSpace = NoColorSpace;
if ( 'def Shader "Transform2d_clearcoatRoughness"' in data ) {
setTextureParams( material.clearcoatRoughnessMap, data[ 'def Shader "Transform2d_clearcoatRoughness"' ] );
}
} else if ( 'float inputs:clearcoatRoughness' in surface ) {
material.clearcoatRoughness = parseFloat( surface[ 'float inputs:clearcoatRoughness' ] );
}
if ( 'float inputs:ior' in surface ) {
material.ior = parseFloat( surface[ 'float inputs:ior' ] );
}
if ( 'float inputs:occlusion.connect' in surface ) {
const path = surface[ 'float inputs:occlusion.connect' ];
const sampler = findTexture( root, /(\w+).output/.exec( path )[ 1 ] );
material.aoMap = buildTexture( sampler );
material.aoMap.colorSpace = NoColorSpace;
if ( 'def Shader "Transform2d_occlusion"' in data ) {
setTextureParams( material.aoMap, data[ 'def Shader "Transform2d_occlusion"' ] );
}
}
}

@@ -520,2 +722,3 @@

material.normalMap = buildTexture( sampler );
material.normalMap.colorSpace = NoColorSpace;

@@ -522,0 +725,0 @@ }

@@ -77,11 +77,7 @@ /**

GeometricContext geometry;
geometry.position = mvPosition.xyz;
geometry.normal = normalize( transformedNormal );
geometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz );
vec3 geometryPosition = mvPosition.xyz;
vec3 geometryNormal = normalize( transformedNormal );
vec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz );
GeometricContext backGeometry;
backGeometry.position = geometry.position;
backGeometry.normal = -geometry.normal;
backGeometry.viewDir = geometry.viewDir;
vec3 backGeometryNormal = - geometryNormal;

@@ -101,4 +97,8 @@ vLightFront = vec3( 0.0 );

vIndirectFront += getLightProbeIrradiance( lightProbe, geometry.normal );
#if defined( USE_LIGHT_PROBES )
vIndirectFront += getLightProbeIrradiance( lightProbe, geometryNormal );
#endif
#ifdef DOUBLE_SIDED

@@ -108,4 +108,8 @@

vIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry.normal );
#if defined( USE_LIGHT_PROBES )
vIndirectBack += getLightProbeIrradiance( lightProbe, backGeometryNormal );
#endif
#endif

@@ -118,5 +122,5 @@

getPointLightInfo( pointLights[ i ], geometry, directLight );
getPointLightInfo( pointLights[ i ], geometryPosition, directLight );
dotNL = dot( geometry.normal, directLight.direction );
dotNL = dot( geometryNormal, directLight.direction );
directLightColor_Diffuse = directLight.color;

@@ -142,5 +146,5 @@

getSpotLightInfo( spotLights[ i ], geometry, directLight );
getSpotLightInfo( spotLights[ i ], geometryPosition, directLight );
dotNL = dot( geometry.normal, directLight.direction );
dotNL = dot( geometryNormal, directLight.direction );
directLightColor_Diffuse = directLight.color;

@@ -165,5 +169,5 @@

getDirectionalLightInfo( directionalLights[ i ], geometry, directLight );
getDirectionalLightInfo( directionalLights[ i ], directLight );
dotNL = dot( geometry.normal, directLight.direction );
dotNL = dot( geometryNormal, directLight.direction );
directLightColor_Diffuse = directLight.color;

@@ -189,7 +193,7 @@

vIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal );
vIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal );
#ifdef DOUBLE_SIDED
vIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry.normal );
vIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometryNormal );

@@ -196,0 +200,0 @@ #endif

@@ -89,2 +89,2 @@ import Node, { addNodeClass } from '../core/Node.js';

addNodeClass( BitangentNode );
addNodeClass( 'BitangentNode', BitangentNode );

@@ -46,3 +46,3 @@ import InputNode from '../core/InputNode.js';

construct( builder ) {
setup( builder ) {

@@ -126,2 +126,2 @@ if ( this.attribute !== null ) return;

addNodeClass( BufferAttributeNode );
addNodeClass( 'BufferAttributeNode', BufferAttributeNode );

@@ -30,2 +30,2 @@ import UniformNode from '../core/UniformNode.js';

addNodeClass( BufferNode );
addNodeClass( 'BufferNode', BufferNode );

@@ -98,2 +98,2 @@ import Object3DNode from './Object3DNode.js';

addNodeClass( CameraNode );
addNodeClass( 'CameraNode', CameraNode );

@@ -100,3 +100,3 @@ import TextureNode from './TextureNode.js';

snippet = colorSpaceToLinear( expression( snippet, nodeType ), this.value.colorSpace ).construct( builder ).build( builder, nodeType );
snippet = colorSpaceToLinear( expression( snippet, nodeType ), this.value.colorSpace ).setup( builder ).build( builder, nodeType );

@@ -119,2 +119,2 @@ }

addNodeClass( CubeTextureNode );
addNodeClass( 'CubeTextureNode', CubeTextureNode );

@@ -32,3 +32,3 @@ import MaterialNode from './MaterialNode.js';

construct( builder ) {
setup( builder ) {

@@ -44,6 +44,7 @@ const material = builder.material;

node = normalMap( this.getTexture( builder, 'normalMap' ), materialReference( 'normalScale', 'vec2' ) );
node = normalMap( this.getTexture( 'normalMap' ), materialReference( 'normalScale', 'vec2' ) );
} else if ( material.bumpMap ) {
// @TODO: Replace material.bumpMap to this.getTexture( 'bumpMap' )
node = bumpMap( material.bumpMap, materialReference( 'bumpScale', 'float' ) );

@@ -59,7 +60,7 @@

node = material.clearcoatNormalMap ? normalMap( this.getTexture( builder, 'clearcoatNormalMap' ), materialReference( 'clearcoatNormalScale', 'vec2' ) ) : normalView;
node = material.clearcoatNormalMap ? normalMap( this.getTexture( 'clearcoatNormalMap' ), materialReference( 'clearcoatNormalScale', 'vec2' ) ) : normalView;
}
return node || super.construct( builder );
return node || super.setup( builder );

@@ -78,2 +79,2 @@ }

addNodeClass( ExtendedMaterialNode );
addNodeClass( 'ExtendedMaterialNode', ExtendedMaterialNode );

@@ -20,3 +20,3 @@ import Node, { addNodeClass } from '../core/Node.js';

construct( builder ) {
setup( builder ) {

@@ -72,2 +72,2 @@ let instanceMatrixNode = this.instanceMatrixNode;

addNodeClass( InstanceNode );
addNodeClass( 'InstanceNode', InstanceNode );

@@ -7,14 +7,8 @@ import MaterialNode from './MaterialNode.js';

constructor( scope ) {
setup( /*builder*/ ) {
super( scope );
return this.getFloat( this.scope );
}
construct( builder ) {
return this.getFloat( builder, this.scope );
}
}

@@ -25,2 +19,4 @@

LineMaterialNode.GAP_SIZE = 'gapSize';
LineMaterialNode.LINEWIDTH = 'linewidth';
LineMaterialNode.DASH_OFFSET = 'dashOffset';

@@ -30,5 +26,7 @@ export default LineMaterialNode;

export const materialLineScale = nodeImmutable( LineMaterialNode, LineMaterialNode.SCALE );
export const materialLineDashOffset = nodeImmutable( LineMaterialNode, LineMaterialNode.DASH_OFFSET );
export const materialLineDashSize = nodeImmutable( LineMaterialNode, LineMaterialNode.DASH_SIZE );
export const materialLineGapSize = nodeImmutable( LineMaterialNode, LineMaterialNode.GAP_SIZE );
export const materialLineWidth = nodeImmutable( LineMaterialNode, LineMaterialNode.LINEWIDTH );
addNodeClass( LineMaterialNode );
addNodeClass( 'LineMaterialNode', LineMaterialNode );

@@ -6,3 +6,3 @@ import Node, { addNodeClass } from '../core/Node.js';

const cache = new WeakMap();
const _propertyCache = new Map();

@@ -19,18 +19,6 @@ class MaterialNode extends Node {

getCache( builder, property, type ) {
getCache( property, type ) {
const material = builder.context.material;
let node = _propertyCache.get( property );
let cacheMaterial = cache.get( material );
if ( cacheMaterial === undefined ) {
cacheMaterial = {};
cache.set( material, cacheMaterial );
}
let node = cacheMaterial[ property ];
if ( node === undefined ) {

@@ -40,3 +28,3 @@

cacheMaterial[ property ] = node;
_propertyCache.set( property, node );

@@ -49,21 +37,21 @@ }

getFloat( builder, property ) {
getFloat( property ) {
return this.getCache( builder, property, 'float' );
return this.getCache( property, 'float' );
}
getColor( builder, property ) {
getColor( property ) {
return this.getCache( builder, property, 'color' );
return this.getCache( property, 'color' );
}
getTexture( builder, property ) {
getTexture( property ) {
return this.getCache( builder, property, 'texture' );
return this.getCache( property, 'texture' );
}
construct( builder ) {
setup( builder ) {

@@ -77,15 +65,15 @@ const material = builder.context.material;

node = this.getFloat( builder, scope );
node = this.getFloat( scope );
} else if ( scope === MaterialNode.SPECULAR_COLOR ) {
node = this.getColor( builder, 'specular' );
node = this.getColor( 'specular' );
} else if ( scope === MaterialNode.COLOR ) {
const colorNode = this.getColor( builder, 'color' );
const colorNode = this.getColor( 'color' );
if ( material.map && material.map.isTexture === true ) {
node = colorNode.mul( this.getTexture( builder, 'map' ) );
node = colorNode.mul( this.getTexture( 'map' ) );

@@ -100,7 +88,7 @@ } else {

const opacityNode = this.getFloat( builder, 'opacity' );
const opacityNode = this.getFloat( 'opacity' );
if ( material.alphaMap && material.alphaMap.isTexture === true ) {
node = opacityNode.mul( this.getTexture( builder, 'alphaMap' ) );
node = opacityNode.mul( this.getTexture( 'alphaMap' ) );

@@ -117,3 +105,3 @@ } else {

node = this.getTexture( builder, 'specularMap' ).r;
node = this.getTexture( 'specularMap' ).r;

@@ -128,7 +116,7 @@ } else {

const roughnessNode = this.getFloat( builder, 'roughness' );
const roughnessNode = this.getFloat( 'roughness' );
if ( material.roughnessMap && material.roughnessMap.isTexture === true ) {
node = roughnessNode.mul( this.getTexture( builder, 'roughnessMap' ).g );
node = roughnessNode.mul( this.getTexture( 'roughnessMap' ).g );

@@ -143,7 +131,7 @@ } else {

const metalnessNode = this.getFloat( builder, 'metalness' );
const metalnessNode = this.getFloat( 'metalness' );
if ( material.metalnessMap && material.metalnessMap.isTexture === true ) {
node = metalnessNode.mul( this.getTexture( builder, 'metalnessMap' ).b );
node = metalnessNode.mul( this.getTexture( 'metalnessMap' ).b );

@@ -158,7 +146,7 @@ } else {

const emissiveNode = this.getColor( builder, 'emissive' );
const emissiveNode = this.getColor( 'emissive' );
if ( material.emissiveMap && material.emissiveMap.isTexture === true ) {
node = emissiveNode.mul( this.getTexture( builder, 'emissiveMap' ) );
node = emissiveNode.mul( this.getTexture( 'emissiveMap' ) );

@@ -173,7 +161,7 @@ } else {

const clearcoatNode = this.getFloat( builder, 'clearcoat' );
const clearcoatNode = this.getFloat( 'clearcoat' );
if ( material.clearcoatMap && material.clearcoatMap.isTexture === true ) {
node = clearcoatNode.mul( this.getTexture( builder, 'clearcoatMap' ).r );
node = clearcoatNode.mul( this.getTexture( 'clearcoatMap' ).r );

@@ -188,7 +176,7 @@ } else {

const clearcoatRoughnessNode = this.getFloat( builder, 'clearcoatRoughness' );
const clearcoatRoughnessNode = this.getFloat( 'clearcoatRoughness' );
if ( material.clearcoatRoughnessMap && material.clearcoatRoughnessMap.isTexture === true ) {
node = clearcoatRoughnessNode.mul( this.getTexture( builder, 'clearcoatRoughnessMap' ).r );
node = clearcoatRoughnessNode.mul( this.getTexture( 'clearcoatRoughnessMap' ).r );

@@ -203,7 +191,7 @@ } else {

const sheenNode = this.getColor( builder, 'sheenColor' ).mul( this.getFloat( builder, 'sheen' ) ); // Move this mul() to CPU
const sheenNode = this.getColor( 'sheenColor' ).mul( this.getFloat( 'sheen' ) ); // Move this mul() to CPU
if ( material.sheenColorMap && material.sheenColorMap.isTexture === true ) {
node = sheenNode.mul( this.getTexture( builder, 'sheenColorMap' ).rgb );
node = sheenNode.mul( this.getTexture( 'sheenColorMap' ).rgb );

@@ -218,7 +206,7 @@ } else {

const sheenRoughnessNode = this.getFloat( builder, 'sheenRoughness' );
const sheenRoughnessNode = this.getFloat( 'sheenRoughness' );
if ( material.sheenRoughnessMap && material.sheenRoughnessMap.isTexture === true ) {
node = sheenRoughnessNode.mul( this.getTexture( builder, 'sheenRoughnessMap' ).a );
node = sheenRoughnessNode.mul( this.getTexture( 'sheenRoughnessMap' ).a );

@@ -241,3 +229,3 @@ } else {

node = iridescenceThicknessMaximum.sub( iridescenceThicknessMinimum ).mul( this.getTexture( builder, 'iridescenceThicknessMap' ).g ).add( iridescenceThicknessMinimum );
node = iridescenceThicknessMaximum.sub( iridescenceThicknessMinimum ).mul( this.getTexture( 'iridescenceThicknessMap' ).g ).add( iridescenceThicknessMinimum );

@@ -304,2 +292,2 @@ } else {

addNodeClass( MaterialNode );
addNodeClass( 'MaterialNode', MaterialNode );

@@ -18,18 +18,18 @@ import ReferenceNode from './ReferenceNode.js';

construct( builder ) {
updateReference( frame ) {
const material = this.material !== null ? this.material : builder.material;
this.reference = this.material !== null ? this.material : frame.material;
this.node.value = material[ this.property ];
return this.reference;
return super.construct( builder );
}
update( frame ) {
setup( builder ) {
this.object = this.material !== null ? this.material : frame.material;
const material = this.material !== null ? this.material : builder.material;
super.update( frame );
this.node.value = material[ this.property ];
return super.setup( builder );
}

@@ -43,2 +43,2 @@

addNodeClass( MaterialReferenceNode );
addNodeClass( 'MaterialReferenceNode', MaterialReferenceNode );

@@ -34,2 +34,2 @@ import Object3DNode from './Object3DNode.js';

addNodeClass( ModelNode );
addNodeClass( 'ModelNode', ModelNode );

@@ -1,2 +0,3 @@

import Node, { addNodeClass } from '../core/Node.js';
import { addNodeClass } from '../core/Node.js';
import TempNode from '../core/TempNode.js';
import { cameraProjectionMatrix } from './CameraNode.js';

@@ -7,3 +8,3 @@ import { modelViewMatrix } from './ModelNode.js';

class ModelViewProjectionNode extends Node {
class ModelViewProjectionNode extends TempNode {

@@ -18,3 +19,3 @@ constructor( positionNode = positionLocal ) {

construct() {
setup() {

@@ -31,2 +32,2 @@ return cameraProjectionMatrix.mul( modelViewMatrix ).mul( this.positionNode );

addNodeClass( ModelViewProjectionNode );
addNodeClass( 'ModelViewProjectionNode', ModelViewProjectionNode );

@@ -22,3 +22,3 @@ import Node, { addNodeClass } from '../core/Node.js';

constructAttribute( builder, name, assignNode = positionLocal ) {
setupAttribute( builder, name, assignNode = positionLocal ) {

@@ -43,5 +43,5 @@ const mesh = this.mesh;

construct( builder ) {
setup( builder ) {
this.constructAttribute( builder, 'position' );
this.setupAttribute( builder, 'position' );

@@ -72,2 +72,2 @@ }

addNodeClass( MorphNode );
addNodeClass( 'MorphNode', MorphNode );

@@ -96,2 +96,2 @@ import Node, { addNodeClass } from '../core/Node.js';

addNodeClass( NormalNode );
addNodeClass( 'NormalNode', NormalNode );

@@ -150,2 +150,2 @@ import Node, { addNodeClass } from '../core/Node.js';

addNodeClass( Object3DNode );
addNodeClass( 'Object3DNode', Object3DNode );

@@ -26,2 +26,2 @@ import Node, { addNodeClass } from '../core/Node.js';

addNodeClass( PointUVNode );
addNodeClass( 'PointUVNode', PointUVNode );

@@ -104,2 +104,2 @@ import Node, { addNodeClass } from '../core/Node.js';

addNodeClass( PositionNode );
addNodeClass( 'PositionNode', PositionNode );

@@ -18,2 +18,3 @@ import Node, { addNodeClass } from '../core/Node.js';

this.object = object;
this.reference = null;

@@ -28,2 +29,10 @@ this.node = null;

updateReference( frame ) {
this.reference = this.object !== null ? this.object : frame.object;
return this.reference;
}
setNodeType( uniformType ) {

@@ -53,12 +62,9 @@

update( frame ) {
update( /*frame*/ ) {
const object = this.object !== null ? this.object : frame.object;
const property = this.property;
this.node.value = this.reference[ this.property ];
this.node.value = object[ property ];
}
construct( /*builder*/ ) {
setup( /*builder*/ ) {

@@ -75,2 +81,2 @@ return this.node;

addNodeClass( ReferenceNode );
addNodeClass( 'ReferenceNode', ReferenceNode );

@@ -21,3 +21,3 @@ import Node, { addNodeClass } from '../core/Node.js';

construct() {
setup() {

@@ -36,2 +36,2 @@ const reflectView = positionViewDirection.negate().reflect( transformedNormalView );

addNodeClass( ReflectVectorNode );
addNodeClass( 'ReflectVectorNode', ReflectVectorNode );

@@ -17,3 +17,3 @@ import Node from '../core/Node.js';

construct( builder ) {
setup( builder ) {

@@ -53,2 +53,2 @@ const scope = this.scope;

addNodeClass( SceneNode );
addNodeClass( 'SceneNode', SceneNode );

@@ -33,3 +33,3 @@ import Node, { addNodeClass } from '../core/Node.js';

construct( builder ) {
setup( builder ) {

@@ -94,2 +94,2 @@ const { skinIndexNode, skinWeightNode, bindMatrixNode, bindMatrixInverseNode, boneMatricesNode } = this;

addNodeClass( SkinningNode );
addNodeClass( 'SkinningNode', SkinningNode );

@@ -27,2 +27,2 @@ import BufferNode from './BufferNode.js';

addNodeClass( StorageBufferNode );
addNodeClass( 'StorageBufferNode', StorageBufferNode );

@@ -103,2 +103,2 @@ import Node, { addNodeClass } from '../core/Node.js';

addNodeClass( TangentNode );
addNodeClass( 'TangentNode', TangentNode );

@@ -80,3 +80,3 @@ import TempNode from '../core/TempNode.js';

construct() {
setup() {

@@ -95,2 +95,2 @@ return textureBicubicMethod( this.textureNode, this.blurNode );

addNodeClass( TextureBicubicNode );
addNodeClass( 'TextureBicubicNode', TextureBicubicNode );

@@ -56,4 +56,10 @@ import UniformNode, { uniform } from '../core/UniformNode.js';

getTextureMatrix( uvNode ) {
updateReference( /*frame*/ ) {
return this.value;
}
getTransformedUV( uvNode ) {
const texture = this.value;

@@ -74,3 +80,3 @@

construct( builder ) {
setup( builder ) {

@@ -91,5 +97,5 @@ const properties = builder.getNodeProperties( this );

if ( this.updateMatrix ) {
if ( this.updateMatrix === true ) {
uvNode = this.getTextureMatrix( uvNode );
uvNode = this.getTransformedUV( uvNode );

@@ -187,3 +193,3 @@ }

snippet = colorSpaceToLinear( expression( snippet, nodeType ), this.value.colorSpace ).construct( builder ).build( builder, nodeType );
snippet = colorSpaceToLinear( expression( snippet, nodeType ), this.value.colorSpace ).setup( builder ).build( builder, nodeType );

@@ -279,2 +285,2 @@ }

addNodeClass( TextureNode );
addNodeClass( 'TextureNode', TextureNode );

@@ -23,3 +23,3 @@ import Node from '../core/Node.js';

return builder.format( `textureDimensions( ${textureProperty}, ${levelNode} )`, this.getNodeType( builder ), output );
return builder.format( `${builder.getMethod( 'textureDimensions' )}( ${textureProperty}, ${levelNode} )`, this.getNodeType( builder ), output );

@@ -36,2 +36,2 @@ }

addNodeClass( TextureSizeNode );
addNodeClass( 'TextureSizeNode', TextureSizeNode );

@@ -29,2 +29,2 @@ import { addNodeClass } from '../core/Node.js';

addNodeClass( TextureStoreNode );
addNodeClass( 'TextureStoreNode', TextureStoreNode );

@@ -17,3 +17,3 @@ import ReferenceNode from './ReferenceNode.js';

this.object = this.userData !== null ? this.userData : frame.object.userData;
this.reference = this.userData !== null ? this.userData : frame.object.userData;

@@ -30,2 +30,2 @@ super.update( frame );

addNodeClass( UserDataNode );
addNodeClass( 'UserDataNode', UserDataNode );

@@ -47,2 +47,2 @@ import { addNodeClass } from '../core/Node.js';

addNodeClass( UVNode );
addNodeClass( 'UVNode', UVNode );

@@ -78,2 +78,2 @@ import Node, { addNodeClass } from '../core/Node.js';

addNodeClass( CodeNode );
addNodeClass( 'CodeNode', CodeNode );

@@ -37,2 +37,2 @@ import Node, { addNodeClass } from '../core/Node.js';

addNodeClass( ExpressionNode );
addNodeClass( 'ExpressionNode', ExpressionNode );

@@ -96,2 +96,2 @@ import TempNode from '../core/TempNode.js';

addNodeClass( FunctionCallNode );
addNodeClass( 'FunctionCallNode', FunctionCallNode );

@@ -102,14 +102,25 @@ import CodeNode from './CodeNode.js';

const nativeFn = ( code, includes, language = '' ) => {
const nativeFn = ( code, includes = [], language = '' ) => {
let functionNode = null;
for ( let i = 0; i < includes.length; i ++ ) {
return ( ...params ) => {
const include = includes[ i ];
if ( functionNode === null ) functionNode = nodeObject( new FunctionNode( code, includes, language ) );
// TSL Function: glslFn, wgslFn
return functionNode.call( ...params );
if ( typeof include === 'function' ) {
};
includes[ i ] = include.functionNode;
}
}
const functionNode = nodeObject( new FunctionNode( code, includes, language ) );
const fn = ( ...params ) => functionNode.call( ...params );
fn.functionNode = functionNode;
return fn;
};

@@ -128,2 +139,2 @@

addNodeClass( FunctionNode );
addNodeClass( 'FunctionNode', FunctionNode );

@@ -434,3 +434,3 @@ import Node, { addNodeClass } from '../core/Node.js';

construct() {
setup() {

@@ -489,2 +489,2 @@ return this.getDefaultOutputNode();

addNodeClass( ScriptableNode );
addNodeClass( 'ScriptableNode', ScriptableNode );

@@ -95,3 +95,3 @@ import Node, { addNodeClass } from '../core/Node.js';

construct() {
setup() {

@@ -168,2 +168,2 @@ return this.value && this.value.isNode ? this.value : float();

addNodeClass( ScriptableValueNode );
addNodeClass( 'ScriptableValueNode', ScriptableValueNode );

@@ -26,2 +26,2 @@ import UniformNode from './UniformNode.js';

addNodeClass( ArrayUniformNode );
addNodeClass( 'ArrayUniformNode', ArrayUniformNode );

@@ -102,2 +102,2 @@ import Node, { addNodeClass } from './Node.js';

addNodeClass( AttributeNode );
addNodeClass( 'AttributeNode', AttributeNode );

@@ -45,2 +45,2 @@ import Node, { addNodeClass } from './Node.js';

addNodeClass( BypassNode );
addNodeClass( 'BypassNode', BypassNode );

@@ -46,2 +46,2 @@ import Node, { addNodeClass } from './Node.js';

addNodeClass( CacheNode );
addNodeClass( 'CacheNode', CacheNode );

@@ -25,4 +25,4 @@ export const NodeShaderStage = {

export const defaultShaderStages = [ 'fragment', 'vertex' ];
export const defaultBuildStages = [ 'construct', 'analyze', 'generate' ];
export const defaultBuildStages = [ 'setup', 'analyze', 'generate' ];
export const shaderStages = [ ...defaultShaderStages, 'compute' ];
export const vectorComponents = [ 'x', 'y', 'z', 'w' ];

@@ -32,2 +32,2 @@ import InputNode from './InputNode.js';

addNodeClass( ConstNode );
addNodeClass( 'ConstNode', ConstNode );

@@ -23,3 +23,3 @@ import Node, { addNodeClass } from './Node.js';

construct( builder ) {
setup( builder ) {

@@ -62,2 +62,2 @@ const previousContext = builder.getContext();

addNodeClass( ContextNode );
addNodeClass( 'ContextNode', ContextNode );

@@ -66,2 +66,2 @@ import Node, { addNodeClass } from './Node.js';

addNodeClass( IndexNode );
addNodeClass( 'IndexNode', IndexNode );

@@ -83,2 +83,2 @@ import Node, { addNodeClass } from './Node.js';

addNodeClass( InputNode );
addNodeClass( 'InputNode', InputNode );

@@ -31,3 +31,3 @@ import { EventDispatcher } from 'three';

return this.constructor.name;
return this.constructor.type;

@@ -44,2 +44,8 @@ }

updateReference() {
return this;
}
isGlobal( /*builder*/ ) {

@@ -124,3 +130,3 @@

getReference( builder ) {
getShared( builder ) {

@@ -134,3 +140,3 @@ const hash = this.getHash( builder );

construct( builder ) {
setup( builder ) {

@@ -150,2 +156,10 @@ const nodeProperties = builder.getNodeProperties( this );

construct( builder ) { // @deprecated, r157
console.warn( 'THREE.Node: construct() is deprecated. Use setup() instead.' );
return this.setup( builder );
}
analyze( builder ) {

@@ -202,3 +216,3 @@

const refNode = this.getReference( builder );
const refNode = this.getShared( builder );

@@ -215,3 +229,3 @@ if ( this !== refNode ) {

/* Build stages expected results:
- "construct" -> Node
- "setup" -> Node
- "analyze" -> null

@@ -224,3 +238,3 @@ - "generate" -> String

if ( buildStage === 'construct' ) {
if ( buildStage === 'setup' ) {

@@ -231,8 +245,8 @@ const properties = builder.getNodeProperties( this );

const stackNodesBeforeConstruct = builder.stack.nodes.length;
const stackNodesBeforeSetup = builder.stack.nodes.length;
properties.initialized = true;
properties.outputNode = this.construct( builder );
properties.outputNode = this.setup( builder );
if ( properties.outputNode !== null && builder.stack.nodes.length !== stackNodesBeforeConstruct ) {
if ( properties.outputNode !== null && builder.stack.nodes.length !== stackNodesBeforeSetup ) {

@@ -460,8 +474,9 @@ properties.outputNode = builder.stack;

export function addNodeClass( nodeClass ) {
export function addNodeClass( type, nodeClass ) {
if ( typeof nodeClass !== 'function' || ! nodeClass.name ) throw new Error( `Node class ${ nodeClass.name } is not a class` );
if ( NodeClasses.has( nodeClass.name ) ) throw new Error( `Redefinition of node class ${ nodeClass.name }` );
if ( typeof nodeClass !== 'function' || ! type ) throw new Error( `Node class ${ type } is not a class` );
if ( NodeClasses.has( type ) ) throw new Error( `Redefinition of node class ${ type }` );
NodeClasses.set( nodeClass.name, nodeClass );
NodeClasses.set( type, nodeClass );
nodeClass.type = type;

@@ -468,0 +483,0 @@ }

@@ -53,6 +53,6 @@ import NodeUniform from './NodeUniform.js';

constructor( object, renderer, parser, scene = null ) {
constructor( object, renderer, parser, scene = null, material = null ) {
this.object = object;
this.material = ( object && object.material ) || null;
this.material = material || ( object && object.material ) || null;
this.geometry = ( object && object.geometry ) || null;

@@ -128,16 +128,2 @@ this.renderer = renderer;

createBindings() {
const bindingsArray = [];
for ( const binding of this.getBindings() ) {
bindingsArray.push( binding.clone() );
}
return bindingsArray;
}
getBindings() {

@@ -964,3 +950,3 @@

// construct() -> stage 1: create possible new nodes and returns an output reference node
// setup() -> stage 1: create possible new nodes and returns an output reference node
// analyze() -> stage 2: analyze nodes to possible optimization and validation

@@ -967,0 +953,0 @@ // generate() -> stage 3: generate shader

@@ -15,6 +15,4 @@ import { NodeUpdateType } from './constants.js';

this.frameMap = new WeakMap();
this.frameBeforeMap = new WeakMap();
this.renderMap = new WeakMap();
this.renderBeforeMap = new WeakMap();
this.updateMap = new WeakMap();
this.updateBeforeMap = new WeakMap();

@@ -29,11 +27,33 @@ this.renderer = null;

_getMaps( referenceMap, nodeRef ) {
let maps = referenceMap.get( nodeRef );
if ( maps === undefined ) {
maps = {
renderMap: new WeakMap(),
frameMap: new WeakMap()
};
referenceMap.set( nodeRef, maps );
}
return maps;
}
updateBeforeNode( node ) {
const updateType = node.getUpdateBeforeType();
const reference = node.updateReference( this );
const { frameMap, renderMap } = this._getMaps( this.updateBeforeMap, reference );
if ( updateType === NodeUpdateType.FRAME ) {
if ( this.frameBeforeMap.get( node ) !== this.frameId ) {
if ( frameMap.get( node ) !== this.frameId ) {
this.frameBeforeMap.set( node, this.frameId );
frameMap.set( node, this.frameId );

@@ -46,6 +66,6 @@ node.updateBefore( this );

if ( this.renderBeforeMap.get( node ) !== this.renderId || this.frameBeforeMap.get( node ) !== this.frameId ) {
if ( renderMap.get( node ) !== this.renderId || frameMap.get( node ) !== this.frameId ) {
this.renderBeforeMap.set( node, this.renderId );
this.frameBeforeMap.set( node, this.frameId );
renderMap.set( node, this.renderId );
frameMap.set( node, this.frameId );

@@ -67,8 +87,11 @@ node.updateBefore( this );

const updateType = node.getUpdateType();
const reference = node.updateReference( this );
const { frameMap, renderMap } = this._getMaps( this.updateMap, reference );
if ( updateType === NodeUpdateType.FRAME ) {
if ( this.frameMap.get( node ) !== this.frameId ) {
if ( frameMap.get( node ) !== this.frameId ) {
this.frameMap.set( node, this.frameId );
frameMap.set( node, this.frameId );

@@ -81,6 +104,6 @@ node.update( this );

if ( this.renderMap.get( node ) !== this.renderId || this.frameMap.get( node ) !== this.frameId ) {
if ( renderMap.get( node ) !== this.renderId || frameMap.get( node ) !== this.frameId ) {
this.renderMap.set( node, this.renderId );
this.frameMap.set( node, this.frameId );
renderMap.set( node, this.renderId );
frameMap.set( node, this.frameId );

@@ -87,0 +110,0 @@ node.update( this );

@@ -16,5 +16,5 @@ import Node, { addNodeClass } from './Node.js';

construct( builder ) {
setup( builder ) {
super.construct( builder );
super.setup( builder );

@@ -37,2 +37,4 @@ const members = this.members;

const nodeVar = builder.getVarFromNode( this, this.nodeType );
nodeVar.isOutputStructVar = true;
const propertyName = builder.getPropertyName( nodeVar );

@@ -42,2 +44,4 @@

const structPrefix = propertyName !== '' ? propertyName + '.' : '';
for ( let i = 0; i < members.length; i++ ) {

@@ -47,3 +51,3 @@

builder.addLineFlowCode( `${propertyName}.m${i} = ${snippet}` );
builder.addLineFlowCode( `${structPrefix}m${i} = ${snippet}` );

@@ -62,2 +66,2 @@ }

addNodeClass( OutputStructNode );
addNodeClass( 'OutputStructNode', OutputStructNode );

@@ -60,5 +60,5 @@ import Node, { addNodeClass } from './Node.js';

export const output = nodeImmutable( PropertyNode, 'vec4', 'Output' );
export const dashSize = nodeImmutable( PropertyNode, 'float', 'dashScale' );
export const gapSize= nodeImmutable( PropertyNode, 'float', 'gapSize' );
export const dashSize = nodeImmutable( PropertyNode, 'float', 'dashSize' );
export const gapSize = nodeImmutable( PropertyNode, 'float', 'gapSize' );
addNodeClass( PropertyNode );
addNodeClass( 'PropertyNode', PropertyNode );

@@ -99,2 +99,2 @@ import Node, { addNodeClass } from './Node.js';

addNodeClass( StackNode );
addNodeClass( 'StackNode', StackNode );

@@ -24,2 +24,2 @@ import Node, { addNodeClass } from './Node.js';

addNodeClass( StructTypeNode );
addNodeClass( 'StructTypeNode', StructTypeNode );

@@ -58,2 +58,2 @@ import Node, { addNodeClass } from './Node.js';

addNodeClass( TempNode );
addNodeClass( 'TempNode', TempNode );

@@ -42,2 +42,4 @@ import InputNode from './InputNode.js';

if ( builder.context.label !== undefined ) delete builder.context.label;
return builder.format( propertyName, type, output );

@@ -62,2 +64,2 @@

addNodeClass( UniformNode );
addNodeClass( 'UniformNode', UniformNode );

@@ -87,2 +87,2 @@ import Node, { addNodeClass } from './Node.js';

addNodeClass( VarNode );
addNodeClass( 'VarNode', VarNode );

@@ -69,2 +69,2 @@ import Node, { addNodeClass } from './Node.js';

addNodeClass( VaryingNode );
addNodeClass( 'VaryingNode', VaryingNode );

@@ -51,3 +51,3 @@ import TempNode from '../core/TempNode.js';

construct() {
setup() {

@@ -100,2 +100,2 @@ const { blendMode, baseNode, blendNode } = this;

addNodeClass( BlendModeNode );
addNodeClass( 'BlendModeNode', BlendModeNode );

@@ -58,3 +58,3 @@ import TempNode from '../core/TempNode.js';

construct() {
setup() {

@@ -78,2 +78,2 @@ const bumpScale = this.scaleNode !== null ? this.scaleNode : 1;

addNodeClass( BumpMapNode );
addNodeClass( 'BumpMapNode', BumpMapNode );

@@ -51,3 +51,3 @@ import TempNode from '../core/TempNode.js';

construct() {
setup() {

@@ -101,2 +101,2 @@ const { method, colorNode, adjustmentNode } = this;

addNodeClass( ColorAdjustmentNode );
addNodeClass( 'ColorAdjustmentNode', ColorAdjustmentNode );

@@ -73,3 +73,3 @@ import TempNode from '../core/TempNode.js';

construct() {
setup() {

@@ -109,2 +109,2 @@ const { method, node } = this;

addNodeClass( ColorSpaceNode );
addNodeClass( 'ColorSpaceNode', ColorSpaceNode );

@@ -27,2 +27,2 @@ import Node, { addNodeClass } from '../core/Node.js';

addNodeClass( FrontFacingNode );
addNodeClass( 'FrontFacingNode', FrontFacingNode );

@@ -55,3 +55,3 @@ import TempNode from '../core/TempNode.js';

construct( builder ) {
setup( builder ) {

@@ -107,2 +107,2 @@ const { normalMapType, scaleNode } = this;

addNodeClass( NormalMapNode );
addNodeClass( 'NormalMapNode', NormalMapNode );

@@ -16,3 +16,3 @@ import TempNode from '../core/TempNode.js';

construct() {
setup() {

@@ -33,2 +33,2 @@ const { sourceNode, stepsNode } = this;

addNodeClass( PosterizeNode );
addNodeClass( 'PosterizeNode', PosterizeNode );

@@ -107,3 +107,3 @@ import TempNode from '../core/TempNode.js';

construct( builder ) {
setup( builder ) {

@@ -142,2 +142,2 @@ const colorNode = this.colorNode || builder.context.color;

addNodeClass( ToneMappingNode );
addNodeClass( 'ToneMappingNode', ToneMappingNode );

@@ -20,3 +20,3 @@ import Node, { addNodeClass } from '../core/Node.js';

construct( /*builder*/ ) {
setup( /*builder*/ ) {

@@ -70,2 +70,2 @@ const { scope } = this;

addNodeClass( ViewportDepthNode );
addNodeClass( 'ViewportDepthNode', ViewportDepthNode );

@@ -34,2 +34,2 @@ import ViewportTextureNode from './ViewportTextureNode.js';

addNodeClass( ViewportDepthTextureNode );
addNodeClass( 'ViewportDepthTextureNode', ViewportDepthTextureNode );

@@ -58,3 +58,3 @@ import Node, { addNodeClass } from '../core/Node.js';

construct( builder ) {
setup( builder ) {

@@ -130,2 +130,2 @@ const scope = this.scope;

addNodeClass( ViewportNode );
addNodeClass( 'ViewportNode', ViewportNode );

@@ -31,2 +31,2 @@ import ViewportTextureNode from './ViewportTextureNode.js';

addNodeClass( ViewportSharedTextureNode );
addNodeClass( 'ViewportSharedTextureNode', ViewportSharedTextureNode );

@@ -75,2 +75,2 @@ import TextureNode from '../accessors/TextureNode.js';

addNodeClass( ViewportTextureNode );
addNodeClass( 'ViewportTextureNode', ViewportTextureNode );

@@ -18,3 +18,3 @@ import FogNode from './FogNode.js';

construct() {
setup() {

@@ -36,2 +36,2 @@ const depthNode = positionView.z.negate();

addNodeClass( FogExp2Node );
addNodeClass( 'FogExp2Node', FogExp2Node );

@@ -23,3 +23,3 @@ import Node, { addNodeClass } from '../core/Node.js';

construct() {
setup() {

@@ -38,2 +38,2 @@ return this.factorNode;

addNodeClass( FogNode );
addNodeClass( 'FogNode', FogNode );

@@ -20,3 +20,3 @@ import FogNode from './FogNode.js';

construct() {
setup() {

@@ -35,2 +35,2 @@ return smoothstep( this.nearNode, this.farNode, positionView.z.negate() );

addNodeClass( FogRangeNode );
addNodeClass( 'FogRangeNode', FogRangeNode );

@@ -39,3 +39,3 @@ import Node, { addNodeClass } from '../core/Node.js';

construct( builder ) {
setup( builder ) {

@@ -105,2 +105,2 @@ const object = builder.object;

addNodeClass( RangeNode );
addNodeClass( 'RangeNode', RangeNode );

@@ -85,2 +85,2 @@ import Node, { addNodeClass } from '../core/Node.js';

addNodeClass( ComputeNode );
addNodeClass( 'ComputeNode', ComputeNode );

@@ -15,3 +15,3 @@ import AnalyticLightNode from './AnalyticLightNode.js';

construct( { context } ) {
setup( { context } ) {

@@ -26,4 +26,4 @@ context.irradiance.addAssign( this.colorNode );

addNodeClass( 'AmbientLightNode', AmbientLightNode );
addLightNode( AmbientLight, AmbientLightNode );
addNodeClass( AmbientLightNode );

@@ -40,3 +40,3 @@ import LightingNode from './LightingNode.js';

constructShadow( builder ) {
setupShadow( builder ) {

@@ -140,5 +140,5 @@ let shadowNode = this.shadowNode;

construct( builder ) {
setup( builder ) {
if ( this.light.castShadow ) this.constructShadow( builder );
if ( this.light.castShadow ) this.setupShadow( builder );

@@ -186,2 +186,2 @@ }

addNodeClass( AnalyticLightNode );
addNodeClass( 'AnalyticLightNode', AnalyticLightNode );

@@ -14,3 +14,3 @@ import LightingNode from './LightingNode.js';

construct( builder ) {
setup( builder ) {

@@ -28,2 +28,2 @@ const aoIntensity = 1;

addNodeClass( AONode );
addNodeClass( 'AONode', AONode );

@@ -16,5 +16,5 @@ import AnalyticLightNode from './AnalyticLightNode.js';

construct( builder ) {
setup( builder ) {
super.construct( builder );
super.setup( builder );

@@ -39,4 +39,4 @@ const lightingModel = builder.context.lightingModel;

addNodeClass( 'DirectionalLightNode', DirectionalLightNode );
addLightNode( DirectionalLight, DirectionalLightNode );
addNodeClass( DirectionalLightNode );

@@ -27,3 +27,3 @@ import LightingNode from './LightingNode.js';

construct( builder ) {
setup( builder ) {

@@ -192,2 +192,2 @@ let envNode = this.envNode;

addNodeClass( EnvironmentNode );
addNodeClass( 'EnvironmentNode', EnvironmentNode );

@@ -36,3 +36,3 @@ import AnalyticLightNode from './AnalyticLightNode.js';

construct( builder ) {
setup( builder ) {

@@ -54,4 +54,4 @@ const { colorNode, groundColorNode, lightDirectionNode } = this;

addNodeClass( 'HemisphereLightNode', HemisphereLightNode );
addLightNode( HemisphereLight, HemisphereLightNode );
addNodeClass( HemisphereLightNode );

@@ -37,4 +37,4 @@ import SpotLightNode from './SpotLightNode.js';

addNodeClass( 'IESSpotLightNode', IESSpotLightNode );
addLightNode( IESSpotLight, IESSpotLightNode );
addNodeClass( IESSpotLightNode );

@@ -25,3 +25,3 @@ import ContextNode from '../core/ContextNode.js';

construct( builder ) {
setup( builder ) {

@@ -80,3 +80,3 @@ const { lightingModel, backdropNode, backdropAlphaNode } = this;

return super.construct( builder );
return super.setup( builder );

@@ -104,2 +104,2 @@ }

addNodeClass( LightingContextNode );
addNodeClass( 'LightingContextNode', LightingContextNode );

@@ -21,2 +21,2 @@ import Node, { addNodeClass } from '../core/Node.js';

addNodeClass( LightingNode );
addNodeClass( 'LightingNode', LightingNode );

@@ -17,3 +17,3 @@ import Node, { addNodeClass } from '../core/Node.js';

construct() {
setup() {

@@ -58,2 +58,2 @@ const { scope, light } = this;

addNodeClass( LightNode );
addNodeClass( 'LightNode', LightNode );

@@ -31,3 +31,3 @@ import Node from '../core/Node.js';

construct( builder ) {
setup( builder ) {

@@ -123,5 +123,5 @@ const lightNodes = this.lightNodes;

if ( LightNodes.has( lightClass ) ) throw new Error( `Redefinition of light node ${ lightNodeClass.name }` );
if ( typeof lightClass !== 'function' || ! lightClass.name ) throw new Error( `Light ${ lightClass.name } is not a class` );
if ( typeof lightNodeClass !== 'function' || ! lightNodeClass.name ) throw new Error( `Light node ${ lightNodeClass.name } is not a class` );
if ( LightNodes.has( lightClass ) ) throw new Error( `Redefinition of light node ${ lightNodeClass.type }` );
if ( typeof lightClass !== 'function' ) throw new Error( `Light ${ lightClass.name } is not a class` );
if ( typeof lightNodeClass !== 'function' || ! lightNodeClass.type ) throw new Error( `Light node ${ lightNodeClass.type } is not a class` );

@@ -128,0 +128,0 @@ LightNodes.set( lightClass, lightNodeClass );

@@ -33,3 +33,3 @@ import AnalyticLightNode from './AnalyticLightNode.js';

construct( builder ) {
setup( builder ) {

@@ -67,4 +67,4 @@ const { colorNode, cutoffDistanceNode, decayExponentNode, light } = this;

addNodeClass( 'PointLightNode', PointLightNode );
addLightNode( PointLight, PointLightNode );
addNodeClass( PointLightNode );

@@ -49,5 +49,5 @@ import AnalyticLightNode from './AnalyticLightNode.js';

construct( builder ) {
setup( builder ) {
super.construct( builder );
super.setup( builder );

@@ -88,4 +88,4 @@ const lightingModel = builder.context.lightingModel;

addNodeClass( 'SpotLightNode', SpotLightNode );
addLightNode( SpotLight, SpotLightNode );
addNodeClass( SpotLightNode );

@@ -28,2 +28,2 @@ import NodeMaterial, { addNodeMaterial } from './NodeMaterial.js';

addNodeMaterial( LineBasicNodeMaterial );
addNodeMaterial( 'LineBasicNodeMaterial', LineBasicNodeMaterial );

@@ -33,3 +33,3 @@ import NodeMaterial, { addNodeMaterial } from './NodeMaterial.js';

constructVariants( { stack } ) {
setupVariants( { stack } ) {

@@ -55,2 +55,2 @@ const offsetNode = this.offsetNode;

addNodeMaterial( LineDashedNodeMaterial );
addNodeMaterial( 'LineDashedNodeMaterial', LineDashedNodeMaterial );

@@ -6,2 +6,3 @@ // @TODO: We can simplify "export { default as SomeNode, other, exports } from '...'" to just "export * from '...'" if we will use only named exports

export { default as LineDashedNodeMaterial } from './LineDashedNodeMaterial.js';
export { default as Line2NodeMaterial } from './Line2NodeMaterial.js';
export { default as MeshNormalNodeMaterial } from './MeshNormalNodeMaterial.js';

@@ -8,0 +9,0 @@ export { default as MeshBasicNodeMaterial } from './MeshBasicNodeMaterial.js';

@@ -27,2 +27,2 @@ import NodeMaterial, { addNodeMaterial } from './NodeMaterial.js';

addNodeMaterial( MeshBasicNodeMaterial );
addNodeMaterial( 'MeshBasicNodeMaterial', MeshBasicNodeMaterial );

@@ -24,3 +24,3 @@ import NodeMaterial, { addNodeMaterial } from './NodeMaterial.js';

constructLightingModel( /*builder*/ ) {
setupLightingModel( /*builder*/ ) {

@@ -35,2 +35,2 @@ return new PhongLightingModel( false ); // ( specular ) -> force lambert

addNodeMaterial( MeshLambertNodeMaterial );
addNodeMaterial( 'MeshLambertNodeMaterial', MeshLambertNodeMaterial );

@@ -28,3 +28,3 @@ import NodeMaterial, { addNodeMaterial } from './NodeMaterial.js';

constructDiffuseColor( { stack } ) {
setupDiffuseColor( { stack } ) {

@@ -41,2 +41,2 @@ const opacityNode = this.opacityNode ? float( this.opacityNode ) : materialOpacity;

addNodeMaterial( MeshNormalNodeMaterial );
addNodeMaterial( 'MeshNormalNodeMaterial', MeshNormalNodeMaterial );

@@ -30,3 +30,3 @@ import NodeMaterial, { addNodeMaterial } from './NodeMaterial.js';

constructLightingModel( /*builder*/ ) {
setupLightingModel( /*builder*/ ) {

@@ -37,3 +37,3 @@ return new PhongLightingModel();

constructVariants( { stack } ) {
setupVariants( { stack } ) {

@@ -67,2 +67,2 @@ // SHININESS

addNodeMaterial( MeshPhongNodeMaterial );
addNodeMaterial( 'MeshPhongNodeMaterial', MeshPhongNodeMaterial );

@@ -47,3 +47,3 @@ import { addNodeMaterial } from './NodeMaterial.js';

constructLightingModel( /*builder*/ ) {
setupLightingModel( /*builder*/ ) {

@@ -54,5 +54,5 @@ return new PhysicalLightingModel(); // @TODO: Optimize shader using parameters.

constructVariants( builder ) {
setupVariants( builder ) {
super.constructVariants( builder );
super.setupVariants( builder );

@@ -89,5 +89,5 @@ const { stack } = builder;

constructNormal( builder ) {
setupNormal( builder ) {
super.constructNormal( builder );
super.setupNormal( builder );

@@ -131,2 +131,2 @@ // CLEARCOAT NORMAL

addNodeMaterial( MeshPhysicalNodeMaterial );
addNodeMaterial( 'MeshPhysicalNodeMaterial', MeshPhysicalNodeMaterial );

@@ -32,3 +32,3 @@ import NodeMaterial, { addNodeMaterial } from './NodeMaterial.js';

constructLightingModel( /*builder*/ ) {
setupLightingModel( /*builder*/ ) {

@@ -39,3 +39,3 @@ return new PhysicalLightingModel( false, false ); // ( clearcoat, sheen ) -> standard

constructVariants( { stack } ) {
setupVariants( { stack } ) {

@@ -82,2 +82,2 @@ // METALNESS

addNodeMaterial( MeshStandardNodeMaterial );
addNodeMaterial( 'MeshStandardNodeMaterial', MeshStandardNodeMaterial );

@@ -32,3 +32,3 @@ import { Material, ShaderMaterial, NoColorSpace, LinearSRGBColorSpace } from 'three';

this.type = this.constructor.name;
this.type = this.constructor.type;

@@ -69,7 +69,7 @@ this.forceSinglePass = false;

this.construct( builder );
this.setup( builder );
}
construct( builder ) {
setup( builder ) {

@@ -80,3 +80,3 @@ // < VERTEX STAGE >

builder.stack.outputNode = this.constructPosition( builder );
builder.stack.outputNode = this.setupPosition( builder );

@@ -93,10 +93,10 @@ builder.addFlow( 'vertex', builder.removeStack() );

if ( this.normals === true ) this.constructNormal( builder );
if ( this.normals === true ) this.setupNormal( builder );
this.constructDiffuseColor( builder );
this.constructVariants( builder );
this.setupDiffuseColor( builder );
this.setupVariants( builder );
const outgoingLightNode = this.constructLighting( builder );
const outgoingLightNode = this.setupLighting( builder );
outputNode = this.constructOutput( builder, vec4( outgoingLightNode, diffuseColor.a ) );
outputNode = this.setupOutput( builder, vec4( outgoingLightNode, diffuseColor.a ) );

@@ -113,3 +113,3 @@ // OUTPUT NODE

outputNode = this.constructOutput( builder, this.outputNode || vec4( 0, 0, 0, 1 ) );
outputNode = this.setupOutput( builder, this.outputNode || vec4( 0, 0, 0, 1 ) );

@@ -124,3 +124,3 @@ }

constructPosition( builder ) {
setupPosition( builder ) {

@@ -162,3 +162,3 @@ const object = builder.object;

constructDiffuseColor( { stack, geometry } ) {
setupDiffuseColor( { stack, geometry } ) {

@@ -196,3 +196,3 @@ let colorNode = this.colorNode ? vec4( this.colorNode ) : materialColor;

constructVariants( /*builder*/ ) {
setupVariants( /*builder*/ ) {

@@ -203,3 +203,3 @@ // Interface function.

constructNormal( { stack } ) {
setupNormal( { stack } ) {

@@ -211,3 +211,3 @@ // NORMAL VIEW

const fdx = dFdx( positionView );
const fdy = dFdy( positionView.negate() ); // use -positionView ?
const fdy = dFdy( positionView );
const normalNode = fdx.cross( fdy ).normalize();

@@ -249,3 +249,3 @@

constructLights( builder ) {
setupLights( builder ) {

@@ -282,3 +282,3 @@ const envNode = this.getEnvNode( builder );

constructLightingModel( /*builder*/ ) {
setupLightingModel( /*builder*/ ) {

@@ -289,3 +289,3 @@ // Interface function.

constructLighting( builder ) {
setupLighting( builder ) {

@@ -299,3 +299,3 @@ const { material } = builder;

const lightsNode = lights ? this.constructLights( builder ) : null;
const lightsNode = lights ? this.setupLights( builder ) : null;

@@ -306,3 +306,3 @@ let outgoingLightNode = diffuseColor.rgb;

const lightingModelNode = this.constructLightingModel( builder );
const lightingModelNode = this.setupLightingModel( builder );

@@ -329,3 +329,3 @@ outgoingLightNode = lightingContext( lightsNode, lightingModelNode, backdropNode, backdropAlphaNode );

constructOutput( builder, outputNode ) {
setupOutput( builder, outputNode ) {

@@ -540,8 +540,9 @@ const renderer = builder.renderer;

export function addNodeMaterial( nodeMaterial ) {
export function addNodeMaterial( type, nodeMaterial ) {
if ( typeof nodeMaterial !== 'function' || ! nodeMaterial.name ) throw new Error( `Node material ${ nodeMaterial.name } is not a class` );
if ( NodeMaterials.has( nodeMaterial.name ) ) throw new Error( `Redefinition of node material ${ nodeMaterial.name }` );
if ( typeof nodeMaterial !== 'function' || ! type ) throw new Error( `Node material ${ type } is not a class` );
if ( NodeMaterials.has( type ) ) throw new Error( `Redefinition of node material ${ type }` );
NodeMaterials.set( nodeMaterial.name, nodeMaterial );
NodeMaterials.set( type, nodeMaterial );
nodeMaterial.type = type;

@@ -562,2 +563,2 @@ }

addNodeMaterial( NodeMaterial );
addNodeMaterial( 'NodeMaterial', NodeMaterial );

@@ -49,2 +49,2 @@ import NodeMaterial, { addNodeMaterial } from './NodeMaterial.js';

addNodeMaterial( PointsNodeMaterial );
addNodeMaterial( 'PointsNodeMaterial', PointsNodeMaterial );

@@ -41,3 +41,3 @@ import NodeMaterial, { addNodeMaterial } from './NodeMaterial.js';

constructPosition( { object, context } ) {
setupPosition( { object, context } ) {

@@ -104,2 +104,2 @@ // < VERTEX STAGE >

addNodeMaterial( SpriteNodeMaterial );
addNodeMaterial( 'SpriteNodeMaterial', SpriteNodeMaterial );

@@ -86,2 +86,2 @@ import Node, { addNodeClass } from '../core/Node.js';

addNodeClass( CondNode );
addNodeClass( 'CondNode', CondNode );
import Node, { addNodeClass } from '../core/Node.js';
import { add, mul, bitXor, shiftRight } from './OperatorNode.js';
import { addNodeElement, nodeProxy, uint } from '../shadernode/ShaderNode.js';
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';

@@ -15,11 +14,11 @@ class HashNode extends Node {

construct( /*builder*/ ) {
setup( /*builder*/ ) {
const seed = this.seedNode;
// Taken from https://www.shadertoy.com/view/XlGcRh, originally from pcg-random.org
const state = add( mul( uint( seed ), 747796405 ), 2891336453 );
const word = mul( bitXor( shiftRight( state, add( shiftRight( state, 28 ), 4 ) ), state ), 277803737 );
const uintResult = bitXor( shiftRight( word, 22 ), word );
const state = this.seedNode.uint().mul( 747796405 ).add( 2891336453 );
const word = state.shiftRight( state.shiftRight( 28 ).add( 4 ) ).bitXor( state ).mul( 277803737 );
const result = word.shiftRight( 22 ).bitXor( word );
return mul( 1 / 2 ** 32, uintResult ); // Convert to range [0, 1)
return result.float().mul( 1 / 2 ** 32 ); // Convert to range [0, 1)

@@ -36,2 +35,2 @@ }

addNodeClass( HashNode );
addNodeClass( 'HashNode', HashNode );

@@ -105,3 +105,3 @@ import TempNode from '../core/TempNode.js';

return builder.format( '-' + a.build( builder, inputType ), type, output );
return builder.format( '( - ' + a.build( builder, inputType ) + ' )', type, output );

@@ -360,2 +360,2 @@ } else if ( method === MathNode.ONE_MINUS ) {

addNodeClass( MathNode );
addNodeClass( 'MathNode', MathNode );

@@ -269,2 +269,2 @@ import TempNode from '../core/TempNode.js';

addNodeClass( OperatorNode );
addNodeClass( 'OperatorNode', OperatorNode );

@@ -57,2 +57,3 @@ // @TODO: We can simplify "export { default as SomeNode, other, exports } from '...'" to just "export * from '...'" if we will use only named exports

export { default as RotateUVNode, rotateUV } from './utils/RotateUVNode.js';
export { default as SetNode } from './utils/SetNode.js';
export { default as SpecularMIPLevelNode, specularMIPLevel } from './utils/SpecularMIPLevelNode.js';

@@ -75,2 +76,3 @@ export { default as SplitNode } from './utils/SplitNode.js';

export { default as InstanceNode, instance } from './accessors/InstanceNode.js';
export { default as LineMaterialNode, materialLineDashSize, materialLineDashOffset, materialLineGapSize, materialLineScale, materialLineWidth } from './accessors/LineMaterialNode.js';
export { default as MaterialNode, materialAlphaTest, materialColor, materialShininess, materialEmissive, materialOpacity, materialSpecularColor, materialReflectivity, materialRoughness, materialMetalness, materialRotation, materialSheen, materialSheenRoughness } from './accessors/MaterialNode.js';

@@ -99,2 +101,3 @@ export { default as MaterialReferenceNode, materialReference } from './accessors/MaterialReferenceNode.js';

export { default as BlendModeNode, burn, dodge, overlay, screen } from './display/BlendModeNode.js';
export { default as BumpMapNode, bumpMap } from './display/BumpMapNode.js';
export { default as ColorAdjustmentNode, saturation, vibrance, hue, lumaCoeffs, luminance } from './display/ColorAdjustmentNode.js';

@@ -106,3 +109,3 @@ export { default as ColorSpaceNode, linearToColorSpace, colorSpaceToLinear, linearTosRGB, sRGBToLinear } from './display/ColorSpaceNode.js';

export { default as ToneMappingNode, toneMapping } from './display/ToneMappingNode.js';
export { default as ViewportNode, viewportCoordinate, viewportResolution, viewportTopLeft, viewportBottomLeft, viewportTopRight, viewportBottomRight } from './display/ViewportNode.js';
export { default as ViewportNode, viewport, viewportCoordinate, viewportResolution, viewportTopLeft, viewportBottomLeft, viewportTopRight, viewportBottomRight } from './display/ViewportNode.js';
export { default as ViewportTextureNode, viewportTexture, viewportMipTexture } from './display/ViewportTextureNode.js';

@@ -170,2 +173,3 @@ export { default as ViewportSharedTextureNode, viewportSharedTexture } from './display/ViewportSharedTextureNode.js';

export { default as F_Schlick } from './functions/BSDF/F_Schlick.js';
export { default as Schlick_to_F0 } from './functions/BSDF/Schlick_to_F0.js';
export { default as V_GGX_SmithCorrelated } from './functions/BSDF/V_GGX_SmithCorrelated.js';

@@ -172,0 +176,0 @@

@@ -28,5 +28,5 @@ import TempNode from '../core/TempNode.js';

generate( builder ) {
setup() {
return checkerShaderNode( { uv: this.uvNode } ).build( builder );
return checkerShaderNode( { uv: this.uvNode } );

@@ -43,2 +43,2 @@ }

addNodeClass( CheckerNode );
addNodeClass( 'CheckerNode', CheckerNode );

@@ -6,2 +6,3 @@ import Node, { addNodeClass } from '../core/Node.js';

import SplitNode from '../utils/SplitNode.js';
import SetNode from '../utils/SetNode.js';
import ConstNode from '../core/ConstNode.js';

@@ -21,5 +22,7 @@ import { getValueFromType, getValueType } from '../core/NodeUtils.js';

const parseSwizzle = ( props ) => props.replace( /r|s/g, 'x' ).replace( /g|t/g, 'y' ).replace( /b|p/g, 'z' ).replace( /a|q/g, 'w' );
const shaderNodeHandler = {
construct( NodeClosure, params ) {
setup( NodeClosure, params ) {

@@ -56,16 +59,28 @@ const inputs = params.shift();

prop = prop
.replace( /r|s/g, 'x' )
.replace( /g|t/g, 'y' )
.replace( /b|p/g, 'z' )
.replace( /a|q/g, 'w' );
prop = parseSwizzle( prop );
return nodeObject( new SplitNode( node, prop ) );
} else if ( prop === 'width' || prop === 'height' ) {
} else if ( /^set[XYZWRGBASTPQ]{1,4}$/.test( prop ) === true ) {
// set properties ( swizzle )
prop = parseSwizzle( prop.slice( 3 ).toLowerCase() );
// sort to xyzw sequence
prop = prop.split( '' ).sort().join( '' );
return ( value ) => nodeObject( new SetNode( node, prop, value ) );
} else if ( prop === 'width' || prop === 'height' || prop === 'depth' ) {
// accessing property
return nodeObject( new SplitNode( node, prop === 'width' ? 'x' : 'y' ) );
if ( prop === 'width' ) prop = 'x';
else if ( prop === 'height' ) prop = 'y';
else if ( prop === 'depth' ) prop = 'z';
return nodeObject( new SplitNode( node, prop ) );
} else if ( /^\d+$/.test( prop ) === true ) {

@@ -187,33 +202,37 @@

class ShaderNodeInternal extends Node {
class ShaderCallNodeInternal extends Node {
constructor( jsFunc ) {
constructor( shaderNode, inputNodes ) {
super();
this._jsFunc = jsFunc;
this.shaderNode = shaderNode;
this.inputNodes = inputNodes;
}
call( inputs, stack, builder ) {
getNodeType( builder ) {
inputs = nodeObjects( inputs );
const { outputNode } = builder.getNodeProperties( this );
return nodeObject( this._jsFunc( inputs, stack, builder ) );
return outputNode ? outputNode.getNodeType( builder ) : super.getNodeType( builder );
}
getNodeType( builder ) {
call( builder ) {
const { outputNode } = builder.getNodeProperties( this );
const { shaderNode, inputNodes } = this;
return outputNode ? outputNode.getNodeType( builder ) : super.getNodeType( builder );
const jsFunc = shaderNode.jsFunc;
const outputNode = inputNodes !== null ? jsFunc( nodeObjects( inputNodes ), builder.stack, builder ) : jsFunc( builder.stack, builder );
return nodeObject( outputNode );
}
construct( builder ) {
setup( builder ) {
builder.addStack();
builder.stack.outputNode = nodeObject( this._jsFunc( builder.stack, builder ) );
builder.stack.outputNode = this.call( builder );

@@ -224,4 +243,44 @@ return builder.removeStack();

generate( builder, output ) {
const { outputNode } = builder.getNodeProperties( this );
if ( outputNode === null ) {
// TSL: It's recommended to use `tslFn` in setup() pass.
return this.call( builder ).build( builder, output );
}
return super.generate( builder, output );
}
}
class ShaderNodeInternal extends Node {
constructor( jsFunc ) {
super();
this.jsFunc = jsFunc;
}
call( inputs = null ) {
return nodeObject( new ShaderCallNodeInternal( this, inputs ) );
}
setup() {
return this.call();
}
}
const bools = [ false, true ];

@@ -342,15 +401,9 @@ const uints = [ 0, 1, 2, 3 ];

let shaderNode = null;
const shaderNode = new ShaderNode( jsFunc );
return ( ...params ) => {
return ( inputs ) => shaderNode.call( inputs );
if ( shaderNode === null ) shaderNode = new ShaderNode( jsFunc );
return shaderNode.call( ...params );
};
};
addNodeClass( ShaderNode );
addNodeClass( 'ShaderNode', ShaderNode );

@@ -357,0 +410,0 @@ // types

@@ -33,2 +33,2 @@ import Node, { addNodeClass } from '../core/Node.js';

addNodeClass( ArrayElementNode );
addNodeClass( 'ArrayElementNode', ArrayElementNode );

@@ -65,2 +65,2 @@ import Node, { addNodeClass } from '../core/Node.js';

addNodeClass( ConvertNode );
addNodeClass( 'ConvertNode', ConvertNode );

@@ -26,2 +26,2 @@ import CondNode from '../math/CondNode.js';

addNodeClass( DiscardNode );
addNodeClass( 'DiscardNode', DiscardNode );

@@ -16,3 +16,3 @@ import TempNode from '../core/TempNode.js';

construct() {
setup() {

@@ -34,2 +34,2 @@ const dir = this.dirNode;

addNodeClass( EquirectUVNode );
addNodeClass( 'EquirectUVNode', EquirectUVNode );

@@ -51,2 +51,2 @@ import { addNodeClass } from '../core/Node.js';

addNodeClass( JoinNode );
addNodeClass( 'JoinNode', JoinNode );
import Node, { addNodeClass } from '../core/Node.js';
import { expression } from '../code/ExpressionNode.js';
import { bypass } from '../core/BypassNode.js';
import { context as contextNode } from '../core/ContextNode.js';
import { context } from '../core/ContextNode.js';
import { addNodeElement, nodeObject, nodeArray } from '../shadernode/ShaderNode.js';

@@ -56,5 +56,5 @@

construct( builder ) {
setup( builder ) {
// construct properties
// setup properties

@@ -69,3 +69,3 @@ this.getProperties( builder );

const context = { tempWrite: false };
const contextData = { tempWrite: false };

@@ -75,4 +75,2 @@ const params = this.params;

const returnsSnippet = properties.returnsNode ? properties.returnsNode.build( builder ) : '';
for ( let i = 0, l = params.length - 1; i < l; i ++ ) {

@@ -88,3 +86,3 @@

start = '0';
end = param.generate( builder, 'int' );
end = param.build( builder, 'int' );
direction = 'forward';

@@ -99,6 +97,6 @@

if ( typeof start === 'number' ) start = start.toString();
else if ( start && start.isNode ) start = start.generate( builder, 'int' );
else if ( start && start.isNode ) start = start.build( builder, 'int' );
if ( typeof end === 'number' ) end = end.toString();
else if ( end && end.isNode ) end = end.generate( builder, 'int' );
else if ( end && end.isNode ) end = end.build( builder, 'int' );

@@ -167,4 +165,6 @@ if ( start !== undefined && end === undefined ) {

const stackSnippet = contextNode( stackNode, context ).build( builder, 'void' );
const stackSnippet = context( stackNode, contextData ).build( builder, 'void' );
const returnsSnippet = properties.returnsNode ? properties.returnsNode.build( builder ) : '';
builder.removeFlowTab().addFlowCode( '\n' + builder.tab + stackSnippet );

@@ -192,2 +192,2 @@

addNodeClass( LoopNode );
addNodeClass( 'LoopNode', LoopNode );

@@ -15,3 +15,3 @@ import TempNode from '../core/TempNode.js';

construct() {
setup() {

@@ -31,2 +31,2 @@ const x = vec3( positionViewDirection.z, 0, positionViewDirection.x.negate() ).normalize();

addNodeClass( MatcapUVNode );
addNodeClass( 'MatcapUVNode', MatcapUVNode );

@@ -46,2 +46,2 @@ import UniformNode from '../core/UniformNode.js';

addNodeClass( MaxMipLevelNode );
addNodeClass( 'MaxMipLevelNode', MaxMipLevelNode );

@@ -22,3 +22,3 @@ import Node, { addNodeClass } from '../core/Node.js';

construct() {
setup() {

@@ -82,2 +82,2 @@ const method = this.method;

addNodeClass( OscNode );
addNodeClass( 'OscNode', OscNode );

@@ -22,3 +22,3 @@ import TempNode from '../core/TempNode.js';

construct() {
setup() {

@@ -56,2 +56,2 @@ const { scope, node } = this;

addNodeClass( PackingNode );
addNodeClass( 'PackingNode', PackingNode );

@@ -20,3 +20,3 @@ import Node, { addNodeClass } from '../core/Node.js';

construct() {
setup() {

@@ -43,2 +43,2 @@ const { node, inLowNode, inHighNode, outLowNode, outHighNode, doClamp } = this;

addNodeClass( RemapNode );
addNodeClass( 'RemapNode', RemapNode );

@@ -17,3 +17,3 @@ import TempNode from '../core/TempNode.js';

construct() {
setup() {

@@ -44,2 +44,2 @@ const { uvNode, rotationNode, centerNode } = this;

addNodeClass( RotateUVNode );
addNodeClass( 'RotateUVNode', RotateUVNode );

@@ -16,3 +16,3 @@ import Node, { addNodeClass } from '../core/Node.js';

construct() {
setup() {

@@ -38,2 +38,2 @@ const { textureNode, roughnessNode } = this;

addNodeClass( SpecularMIPLevelNode );
addNodeClass( 'SpecularMIPLevelNode', SpecularMIPLevelNode );

@@ -104,2 +104,2 @@ import Node, { addNodeClass } from '../core/Node.js';

addNodeClass( SplitNode );
addNodeClass( 'SplitNode', SplitNode );

@@ -17,3 +17,3 @@ import Node, { addNodeClass } from '../core/Node.js';

construct() {
setup() {

@@ -42,2 +42,2 @@ const { frameNode, uvNode, countNode } = this;

addNodeClass( SpriteSheetUVNode );
addNodeClass( 'SpriteSheetUVNode', SpriteSheetUVNode );

@@ -92,4 +92,4 @@ import UniformNode from '../core/UniformNode.js';

export const timerDelta = ( timeScale, value = 0 ) => nodeObject( new TimerNode( TimerNode.DELTA, timeScale, value ) );
export const frameId = nodeImmutable( TimerNode, TimerNode.FRAME );
export const frameId = nodeImmutable( TimerNode, TimerNode.FRAME ).uint();
addNodeClass( TimerNode );
addNodeClass( 'TimerNode', TimerNode );

@@ -25,3 +25,3 @@ import Node, { addNodeClass } from '../core/Node.js';

construct() {
setup() {

@@ -63,2 +63,2 @@ const { textureXNode, textureYNode, textureZNode, scaleNode, positionNode, normalNode } = this;

addNodeClass( TriplanarTexturesNode );
addNodeClass( 'TriplanarTexturesNode', TriplanarTexturesNode );

@@ -141,4 +141,2 @@ import {

const vec3 cameraPos = vec3( 0.0, 0.0, 0.0 );
// constants for atmospheric scattering

@@ -173,3 +171,3 @@ const float pi = 3.141592653589793238462643383279502884197169;

vec3 direction = normalize( vWorldPosition - cameraPos );
vec3 direction = normalize( vWorldPosition - cameraPosition );

@@ -176,0 +174,0 @@ // optical length

import {
ColorManagement,
RawShaderMaterial,

@@ -8,3 +9,3 @@ UniformsUtils,

ACESFilmicToneMapping,
SRGBColorSpace
SRGBTransfer
} from 'three';

@@ -55,3 +56,3 @@ import { Pass, FullScreenQuad } from './Pass.js';

if ( this._outputColorSpace == SRGBColorSpace ) this.material.defines.SRGB_COLOR_SPACE = '';
if ( ColorManagement.getTransfer( this._outputColorSpace ) === SRGBTransfer ) this.material.defines.SRGB_TRANSFER = '';

@@ -58,0 +59,0 @@ if ( this._toneMapping === LinearToneMapping ) this.material.defines.LINEAR_TONE_MAPPING = '';

import DataMap from './DataMap.js';
import { Color, Mesh, SphereGeometry, BackSide } from 'three';
import { vec4, context, normalWorld, backgroundBlurriness, backgroundIntensity, NodeMaterial, modelViewProjection } from '../../nodes/Nodes.js';
import { context, normalWorld, backgroundBlurriness, backgroundIntensity, NodeMaterial, modelViewProjection } from '../../nodes/Nodes.js';

@@ -63,3 +63,3 @@ let _clearAlpha;

let viewProj = modelViewProjection();
viewProj = vec4( viewProj.x, viewProj.y, viewProj.w, viewProj.w );
viewProj = viewProj.setZ( viewProj.w );

@@ -66,0 +66,0 @@ const nodeMaterial = new NodeMaterial();

@@ -51,5 +51,5 @@ import DataMap from './DataMap.js';

const nodeBuilder = this.nodes.getForCompute( computeNode );
const nodeBuilderState = this.nodes.getForCompute( computeNode );
const bindings = nodeBuilder.getBindings();
const bindings = nodeBuilderState.bindings;

@@ -86,6 +86,4 @@ data.bindings = bindings;

const store = binding.store === true;
this.textures.updateTexture( binding.texture );
this.textures.updateTexture( binding.texture, { store } );
} else if ( binding.isStorageBuffer ) {

@@ -92,0 +90,0 @@

import DataMap from '../DataMap.js';
import ChainMap from '../ChainMap.js';
import NodeBuilderState from './NodeBuilderState.js';
import { NoToneMapping, EquirectangularReflectionMapping, EquirectangularRefractionMapping } from 'three';

@@ -15,12 +15,10 @@ import { NodeFrame, cubeTexture, texture, rangeFog, densityFog, reference, toneMapping, equirectUV, viewportBottomLeft, normalWorld } from '../../../nodes/Nodes.js';

this.nodeFrame = new NodeFrame();
this.cache = new ChainMap();
this.nodeBuilderCache = new Map();
}
getForRenderChainKey( renderObject ) {
getForRenderCacheKey( renderObject ) {
const { object, material, lightsNode, context } = renderObject;
return renderObject.initialCacheKey;
return [ object.geometry, material, lightsNode, context ];
}

@@ -32,16 +30,17 @@

let nodeBuilder = renderObjectData.nodeBuilder;
let nodeBuilderState = renderObjectData.nodeBuilderState;
if ( nodeBuilder === undefined ) {
if ( nodeBuilderState === undefined ) {
const { cache } = this;
const { nodeBuilderCache } = this;
const chainKey = this.getForRenderChainKey( renderObject );
const cacheKey = this.getForRenderCacheKey( renderObject );
nodeBuilder = cache.get( chainKey );
nodeBuilderState = nodeBuilderCache.get( cacheKey );
if ( nodeBuilder === undefined ) {
if ( nodeBuilderState === undefined ) {
nodeBuilder = this.backend.createNodeBuilder( renderObject.object, this.renderer, renderObject.scene );
const nodeBuilder = this.backend.createNodeBuilder( renderObject.object, this.renderer, renderObject.scene );
nodeBuilder.material = renderObject.material;
nodeBuilder.context.material = renderObject.material;
nodeBuilder.lightsNode = renderObject.lightsNode;

@@ -53,11 +52,15 @@ nodeBuilder.environmentNode = this.getEnvironmentNode( renderObject.scene );

cache.set( chainKey, nodeBuilder );
nodeBuilderState = this._createNodeBuilderState( nodeBuilder );
nodeBuilderCache.set( cacheKey, nodeBuilderState );
}
renderObjectData.nodeBuilder = nodeBuilder;
nodeBuilderState.usedTimes ++;
renderObjectData.nodeBuilderState = nodeBuilderState;
}
return nodeBuilder;
return nodeBuilderState;

@@ -70,4 +73,11 @@ }

this.cache.delete( this.getForRenderChainKey( object ) );
const nodeBuilderState = this.get( object ).nodeBuilderState;
nodeBuilderState.usedTimes --;
if ( nodeBuilderState.usedTimes === 0 ) {
this.nodeBuilderCache.delete( this.getForRenderCacheKey( object ) );
}
}

@@ -83,17 +93,33 @@

let nodeBuilder = computeData.nodeBuilder;
let nodeBuilderState = computeData.nodeBuilderState;
if ( nodeBuilder === undefined ) {
if ( nodeBuilderState === undefined ) {
nodeBuilder = this.backend.createNodeBuilder( computeNode, this.renderer );
const nodeBuilder = this.backend.createNodeBuilder( computeNode, this.renderer );
nodeBuilder.build();
computeData.nodeBuilder = nodeBuilder;
nodeBuilderState = this._createNodeBuilderState( nodeBuilder );
computeData.nodeBuilderState = nodeBuilder;
}
return nodeBuilder;
return nodeBuilderState;
}
_createNodeBuilderState( nodeBuilder ) {
return new NodeBuilderState(
nodeBuilder.vertexShader,
nodeBuilder.fragmentShader,
nodeBuilder.computeShader,
nodeBuilder.getAttributesArray(),
nodeBuilder.getBindings(),
nodeBuilder.updateNodes,
nodeBuilder.updateBeforeNodes
);
}
getEnvironmentNode( scene ) {

@@ -334,3 +360,3 @@

const nodeFrame = this.getNodeFrame( renderObject );
const nodeBuilder = renderObject.getNodeBuilder();
const nodeBuilder = renderObject.getNodeBuilderState();

@@ -350,3 +376,3 @@ for ( const node of nodeBuilder.updateBeforeNodes ) {

const nodeFrame = this.getNodeFrame( renderObject );
const nodeBuilder = renderObject.getNodeBuilder();
const nodeBuilder = renderObject.getNodeBuilderState();

@@ -366,2 +392,3 @@ for ( const node of nodeBuilder.updateNodes ) {

this.nodeFrame = new NodeFrame();
this.nodeBuilderCache = new Map();

@@ -368,0 +395,0 @@ }

@@ -1,2 +0,2 @@

import { SampledTexture, SampledCubeTexture } from '../SampledTexture.js';
import { SampledTexture } from '../SampledTexture.js';

@@ -13,24 +13,34 @@ class NodeSampledTexture extends SampledTexture {

getTexture() {
get needsBindingsUpdate() {
return this.textureNode.value;
return this.textureNode.value !== this.texture || super.needsBindingsUpdate;
}
}
update() {
class NodeSampledCubeTexture extends SampledCubeTexture {
const { textureNode } = this;
constructor( name, textureNode ) {
if ( this.texture !== textureNode.value ) {
super( name, textureNode ? textureNode.value : null );
this.texture = textureNode.value;
this.textureNode = textureNode;
return true;
}
return super.update();
}
getTexture() {
}
return this.textureNode.value;
class NodeSampledCubeTexture extends NodeSampledTexture {
constructor( name, textureNode ) {
super( name, textureNode );
this.isSampledCubeTexture = true;
}

@@ -37,0 +47,0 @@

@@ -13,10 +13,4 @@ import Sampler from '../Sampler.js';

getTexture() {
return this.textureNode.value;
}
}
export default NodeSampler;

@@ -112,7 +112,7 @@ import DataMap from './DataMap.js';

const nodeBuilder = this.nodes.getForRender( renderObject );
const nodeBuilderState = renderObject.getNodeBuilderState();
// programmable stages
let stageVertex = this.programs.vertex.get( nodeBuilder.vertexShader );
let stageVertex = this.programs.vertex.get( nodeBuilderState.vertexShader );

@@ -123,4 +123,4 @@ if ( stageVertex === undefined ) {

stageVertex = new ProgrammableStage( nodeBuilder.vertexShader, 'vertex' );
this.programs.vertex.set( nodeBuilder.vertexShader, stageVertex );
stageVertex = new ProgrammableStage( nodeBuilderState.vertexShader, 'vertex' );
this.programs.vertex.set( nodeBuilderState.vertexShader, stageVertex );

@@ -131,3 +131,3 @@ backend.createProgram( stageVertex );

let stageFragment = this.programs.fragment.get( nodeBuilder.fragmentShader );
let stageFragment = this.programs.fragment.get( nodeBuilderState.fragmentShader );

@@ -138,4 +138,4 @@ if ( stageFragment === undefined ) {

stageFragment = new ProgrammableStage( nodeBuilder.fragmentShader, 'fragment' );
this.programs.fragment.set( nodeBuilder.fragmentShader, stageFragment );
stageFragment = new ProgrammableStage( nodeBuilderState.fragmentShader, 'fragment' );
this.programs.fragment.set( nodeBuilderState.fragmentShader, stageFragment );

@@ -142,0 +142,0 @@ backend.createProgram( stageFragment );

@@ -34,2 +34,5 @@ import { Vector4 } from 'three';

this.width = 0;
this.height = 0;
}

@@ -36,0 +39,0 @@

@@ -49,2 +49,4 @@ import Animation from './Animation.js';

this.info = new Info();
// internals

@@ -60,3 +62,2 @@

this._info = null;
this._properties = null;

@@ -88,3 +89,4 @@ this._attributes = null;

this._renderTarget = null;
this._currentActiveCubeFace = 0;
this._activeCubeFace = 0;
this._activeMipmapLevel = 0;

@@ -136,11 +138,10 @@ this._initialized = false;

this._info = new Info();
this._nodes = new Nodes( this, backend );
this._attributes = new Attributes( backend );
this._background = new Background( this, this._nodes );
this._geometries = new Geometries( this._attributes, this._info );
this._textures = new Textures( backend, this._info );
this._geometries = new Geometries( this._attributes, this.info );
this._textures = new Textures( backend, this.info );
this._pipelines = new Pipelines( backend, this._nodes );
this._bindings = new Bindings( backend, this._nodes, this._textures, this._attributes, this._pipelines, this._info );
this._objects = new RenderObjects( this, this._nodes, this._geometries, this._pipelines, this._bindings, this._info );
this._bindings = new Bindings( backend, this._nodes, this._textures, this._attributes, this._pipelines, this.info );
this._objects = new RenderObjects( this, this._nodes, this._geometries, this._pipelines, this._bindings, this.info );
this._renderLists = new RenderLists();

@@ -194,2 +195,3 @@ this._renderContexts = new RenderContexts();

const activeCubeFace = this._activeCubeFace;
const activeMipmapLevel = this._activeMipmapLevel;

@@ -220,5 +222,5 @@ this._currentRenderContext = renderContext;

if ( this._info.autoReset === true ) this._info.reset();
if ( this.info.autoReset === true ) this.info.reset();
this._info.render.frame ++;
this.info.render.frame ++;

@@ -247,2 +249,4 @@ //

renderContext.viewportValue.copy( viewport ).multiplyScalar( pixelRatio ).floor();
renderContext.viewportValue.width >>= activeMipmapLevel;
renderContext.viewportValue.height >>= activeMipmapLevel;
renderContext.viewportValue.minDepth = minDepth;

@@ -254,2 +258,4 @@ renderContext.viewportValue.maxDepth = maxDepth;

renderContext.scissor = this._scissorTest && renderContext.scissorValue.equals( _screen ) === false;
renderContext.scissorValue.width >>= activeMipmapLevel;
renderContext.scissorValue.height >>= activeMipmapLevel;

@@ -285,3 +291,3 @@ renderContext.depth = this.depth;

this._textures.updateRenderTarget( renderTarget );
this._textures.updateRenderTarget( renderTarget, activeMipmapLevel );

@@ -292,2 +298,4 @@ const renderTargetData = this._textures.get( renderTarget );

renderContext.depthTexture = renderTargetData.depthTexture;
renderContext.width = renderTargetData.width;
renderContext.height = renderTargetData.height;

@@ -298,6 +306,11 @@ } else {

renderContext.depthTexture = null;
renderContext.width = this.domElement.width;
renderContext.height = this.domElement.height;
}
renderContext.width >>= activeMipmapLevel;
renderContext.height >>= activeMipmapLevel;
renderContext.activeCubeFace = activeCubeFace;
renderContext.activeMipmapLevel = activeMipmapLevel;
renderContext.occlusionQueryCount = renderList.occlusionQueryCount;

@@ -343,2 +356,14 @@

getActiveCubeFace() {
return this._activeCubeFace;
}
getActiveMipmapLevel() {
return this._activeMipmapLevel;
}
setAnimationLoop( callback ) {

@@ -602,2 +627,4 @@

this.info.dispose();
this._objects.dispose();

@@ -608,3 +635,2 @@ this._properties.dispose();

this._bindings.dispose();
this._info.dispose();
this._renderLists.dispose();

@@ -619,6 +645,7 @@ this._renderContexts.dispose();

setRenderTarget( renderTarget, activeCubeFace = 0 ) {
setRenderTarget( renderTarget, activeCubeFace = 0, activeMipmapLevel = 0 ) {
this._renderTarget = renderTarget;
this._activeCubeFace = activeCubeFace;
this._activeMipmapLevel = activeMipmapLevel;

@@ -913,3 +940,3 @@ }

this.backend.draw( renderObject, this._info );
this.backend.draw( renderObject, this.info );

@@ -916,0 +943,0 @@ }

@@ -21,2 +21,3 @@ let id = 0;

this.geometry = object.geometry;
this.version = material.version;

@@ -27,6 +28,6 @@ this.attributes = null;

this._nodeBuilder = null;
this.initialCacheKey = this.getCacheKey();
this._nodeBuilderState = null;
this._bindings = null;
this._materialVersion = - 1;
this._materialCacheKey = '';

@@ -47,5 +48,5 @@ this.onDispose = null;

getNodeBuilder() {
getNodeBuilderState() {
return this._nodeBuilder || ( this._nodeBuilder = this._nodes.getForRender( this ) );
return this._nodeBuilderState || ( this._nodeBuilderState = this._nodes.getForRender( this ) );

@@ -56,3 +57,3 @@ }

return this._bindings || ( this._bindings = this.getNodeBuilder().createBindings() );
return this._bindings || ( this._bindings = this.getNodeBuilderState().createBindings() );

@@ -77,3 +78,3 @@ }

const nodeAttributes = this.getNodeBuilder().getAttributesArray();
const nodeAttributes = this.getNodeBuilderState().nodeAttributes;
const geometry = this.geometry;

@@ -110,22 +111,45 @@

getCacheKey() {
getMaterialCacheKey() {
const { material, scene, lightsNode } = this;
const material = this.material;
if ( material.version !== this._materialVersion ) {
let cacheKey = material.customProgramCacheKey();
this._materialVersion = material.version;
this._materialCacheKey = material.customProgramCacheKey();
for ( const property in material ) {
if ( /^(is[A-Z])|^(visible|version|uuid|name|opacity|userData)$/.test( property ) ) continue;
let value = material[ property ];
if ( value !== null ) {
const type = typeof value;
if ( type === 'number' ) value = value !== 0 ? '1' : '0'; // Convert to on/off, important for clearcoat, transmission, etc
else if ( type === 'object' ) value = '{}';
}
cacheKey += /*property + ':' +*/ value + ',';
}
const cacheKey = [];
return cacheKey;
cacheKey.push( 'material:' + this._materialCacheKey );
cacheKey.push( 'nodes:' + this._nodes.getCacheKey( scene, lightsNode ) );
}
return '{' + cacheKey.join( ',' ) + '}';
getNodesCacheKey() {
// Environment Nodes Cache Key
return this._nodes.getCacheKey( this.scene, this.lightsNode );
}
getCacheKey() {
return `{material:${ this.getMaterialCacheKey() },nodes:${ this.getNodesCacheKey()}`;
}
dispose() {

@@ -132,0 +156,0 @@

@@ -1,2 +0,1 @@

import DataMap from './DataMap.js';
import ChainMap from './ChainMap.js';

@@ -17,3 +16,2 @@ import RenderObject from './RenderObject.js';

this.chainMaps = {};
this.dataMap = new DataMap();

@@ -37,11 +35,14 @@ }

const data = this.dataMap.get( renderObject );
const cacheKey = renderObject.getCacheKey();
if ( renderObject.version !== material.version ) {
if ( data.cacheKey !== cacheKey ) {
renderObject.version = material.version;
renderObject.dispose();
if ( renderObject.initialCacheKey !== renderObject.getCacheKey() ) {
renderObject = this.get( object, material, scene, camera, lightsNode, renderContext, passId );
renderObject.dispose();
renderObject = this.get( object, material, scene, camera, lightsNode, renderContext, passId );
}
}

@@ -64,3 +65,2 @@

this.chainMaps = {};
this.dataMap = new DataMap();

@@ -72,13 +72,7 @@ }

const chainMap = this.getChainMap( passId );
const dataMap = this.dataMap;
const renderObject = new RenderObject( nodes, geometries, renderer, object, material, scene, camera, lightsNode, renderContext );
const data = dataMap.get( renderObject );
data.cacheKey = renderObject.getCacheKey();
renderObject.onDispose = () => {
dataMap.delete( renderObject );
this.pipelines.delete( renderObject );

@@ -85,0 +79,0 @@ this.bindings.delete( renderObject );

@@ -31,6 +31,8 @@ import Binding from './Binding.js';

if ( this.version !== this.texture.version ) {
const { texture, version } = this;
this.version = this.texture.version;
if ( version !== texture.version ) {
this.version = texture.version;
return true;

@@ -37,0 +39,0 @@

@@ -18,6 +18,8 @@ import DataMap from './DataMap.js';

updateRenderTarget( renderTarget ) {
updateRenderTarget( renderTarget, activeMipmapLevel = 0 ) {
const renderTargetData = this.get( renderTarget );
const sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples;
const depthTextureMips = renderTargetData.depthTextureMips || ( renderTargetData.depthTextureMips = {} );

@@ -40,3 +42,6 @@ let texture, textures;

let depthTexture = renderTarget.depthTexture || renderTargetData.depthTexture;
const mipWidth = size.width >> activeMipmapLevel;
const mipHeight = size.height >> activeMipmapLevel;
let depthTexture = renderTarget.depthTexture || depthTextureMips[ activeMipmapLevel ];
let textureNeedsUpdate = false;

@@ -49,5 +54,7 @@

depthTexture.type = UnsignedInt248Type;
depthTexture.image.width = size.width;
depthTexture.image.height = size.height;
depthTexture.image.width = mipWidth;
depthTexture.image.height = mipHeight;
depthTextureMips[ activeMipmapLevel ] = depthTexture;
}

@@ -60,4 +67,4 @@

depthTexture.image.width = size.width;
depthTexture.image.height = size.height;
depthTexture.image.width = mipWidth;
depthTexture.image.height = mipHeight;

@@ -160,6 +167,4 @@ }

if ( isRenderTarget || options.store === true ) {
if ( isRenderTarget || texture.isStorageTexture === true ) {
//if ( options.store === true ) options.levels = 1; /* no mipmaps? */
backend.createSampler( texture );

@@ -166,0 +171,0 @@ backend.createTexture( texture, options );

@@ -41,5 +41,5 @@ import { defaultShaderStages, NodeFrame, MathNode, GLSLNodeParser, NodeBuilder, normalView } from 'three/nodes';

constructor( object, renderer, shader ) {
constructor( object, renderer, shader, material = null ) {
super( object, renderer, new GLSLNodeParser() );
super( object, renderer, new GLSLNodeParser(), null, material );

@@ -224,3 +224,3 @@ this.shader = shader;

nodeType: 'vec3',
source: 'vec3 clearcoatNormal = geometryNormal;',
source: 'vec3 clearcoatNormal = nonPerturbedNormal;',
target: 'vec3 clearcoatNormal = %RESULT%;'

@@ -227,0 +227,0 @@ } ) );

@@ -11,6 +11,18 @@ import { WebGLNodeBuilder } from './WebGLNodeBuilder.js';

if ( object.material.isNodeMaterial === true ) {
if ( Array.isArray( object.material ) ) {
builders.set( this, new WebGLNodeBuilder( object, renderer, parameters ).build() );
for ( const material of object.material ) {
if ( material.isNodeMaterial === true ) {
builders.set( material, new WebGLNodeBuilder( object, renderer, parameters, material ).build() );
}
}
} else if ( object.material.isNodeMaterial === true ) {
builders.set( object.material, new WebGLNodeBuilder( object, renderer, parameters ).build() );
}

@@ -17,0 +29,0 @@

@@ -7,3 +7,4 @@ import { MathNode, GLSLNodeParser, NodeBuilder, NodeMaterial } from '../../../nodes/Nodes.js';

const glslMethods = {
[ MathNode.ATAN2 ]: 'atan'
[ MathNode.ATAN2 ]: 'atan',
textureDimensions: 'textureSize'
};

@@ -33,2 +34,10 @@

getPropertyName( node, shaderStage ) {
if ( node.isOutputStructVar ) return '';
return super.getPropertyName( node, shaderStage );
}
getTexture( texture, textureProperty, uvSnippet ) {

@@ -40,2 +49,6 @@

} else if ( texture.isDepthTexture ) {
return `texture( ${textureProperty}, ${uvSnippet} ).x`;
} else {

@@ -55,2 +68,16 @@

getTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, shaderStage = this.shaderStage ) {
if ( shaderStage === 'fragment' ) {
return `texture( ${textureProperty}, vec3( ${uvSnippet}, ${compareSnippet} ) )`;
} else {
console.error( `WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${ shaderStage } shader.` );
}
}
getVars( shaderStage ) {

@@ -64,2 +91,4 @@

if ( variable.isOutputStructVar ) continue;
snippets.push( `${ this.getVar( variable.type, variable.name ) };` );

@@ -87,4 +116,12 @@

snippet = `sampler2D ${uniform.name};`;
if ( uniform.node.value.compareFunction ) {
snippet = `sampler2DShadow ${uniform.name};`;
} else {
snippet = `sampler2D ${uniform.name};`;
}
} else if ( uniform.type === 'cubeTexture' ) {

@@ -164,2 +201,45 @@

getStructMembers( struct ) {
const snippets = [];
const members = struct.getMemberTypes();
for ( let i = 0; i < members.length; i ++ ) {
const member = members[ i ];
snippets.push( `layout( location = ${i} ) out ${ member} m${i};` );
}
return snippets.join( '\n' );
}
getStructs( shaderStage ) {
const snippets = [];
const structs = this.structs[ shaderStage ];
if ( structs.length === 0 ) {
return "layout( location = 0 ) out vec4 fragColor;\n";
}
for ( let index = 0, length = structs.length; index < length; index ++ ) {
const struct = structs[ index ];
let snippet = `\n`;
snippet += this.getStructMembers( struct );
snippet += '\n';
snippets.push( snippet );
}
return snippets.join( '\n\n' );
}
getVaryings( shaderStage ) {

@@ -276,2 +356,3 @@

precision highp int;
precision lowp sampler2DShadow;

@@ -287,3 +368,3 @@ // uniforms

layout( location = 0 ) out vec4 fragColor;
${shaderData.structs}

@@ -337,11 +418,15 @@ void main() {

flow += 'gl_Position = ';
flow += `${ flowSlotData.result };`;
} else if ( shaderStage === 'fragment' ) {
flow += 'fragColor = ';
if ( ! node.outputNode.isOutputStructNode ) {
flow += 'fragColor = ';
flow += `${ flowSlotData.result };`;
}
}
flow += `${ flowSlotData.result };`;
}

@@ -357,2 +442,3 @@

stageData.vars = this.getVars( shaderStage );
stageData.structs = this.getStructs( shaderStage );
stageData.codes = this.getCodes( shaderStage );

@@ -359,0 +445,0 @@ stageData.flow = flow;

@@ -143,2 +143,15 @@ import { LinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, NearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, RGBAFormat, DepthFormat, DepthStencilFormat, UnsignedShortType, UnsignedIntType, UnsignedInt248Type, FloatType, HalfFloatType, MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, UnsignedByteType, _SRGBAFormat, NoColorSpace, LinearSRGBColorSpace, SRGBColorSpace, NeverCompare, AlwaysCompare, LessCompare, LessEqualCompare, EqualCompare, GreaterEqualCompare, GreaterCompare, NotEqualCompare } from 'three';

if ( glFormat === gl.DEPTH_COMPONENT ) {
if ( glType === gl.UNSIGNED_INT ) internalFormat = gl.DEPTH_COMPONENT24;
if ( glType === gl.FLOAT ) internalFormat = gl.DEPTH_COMPONENT32F;
}
if ( glFormat === gl.DEPTH_STENCIL ) {
if ( glType === gl.UNSIGNED_INT_24_8 ) internalFormat = gl.DEPTH24_STENCIL8;
}
if ( internalFormat === gl.R16F || internalFormat === gl.R32F ||

@@ -145,0 +158,0 @@ internalFormat === gl.RG16F || internalFormat === gl.RG32F ||

@@ -57,2 +57,4 @@ import { WebGLCoordinateSystem } from 'three';

this._setFramebuffer( renderContext );
let clear = 0;

@@ -66,5 +68,23 @@

gl.clearColor( clearColor.x, clearColor.y, clearColor.z, clearColor.a );
gl.clear( clear );
if ( clear !== 0 ) {
if ( renderContext.textures === null ) {
gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearColor.a );
gl.clear( clear );
} else {
for ( let i = 0; i < renderContext.textures.length; i ++ ) {
gl.clearBufferfv( gl.COLOR, i, [ clearColor.r, clearColor.g, clearColor.b, clearColor.a ] );
}
gl.clearBufferfi( gl.DEPTH_STENCIL, 0, 1, 1 );
}
}
//

@@ -287,4 +307,9 @@

gl.bindTexture( glTextureType, textureGPU );
gl.texStorage2D( glTextureType, levels, glInternalFormat, width, height );
if ( ! texture.isVideoTexture ) {
gl.texStorage2D( glTextureType, levels, glInternalFormat, width, height );
}
this.set( texture, {

@@ -304,3 +329,3 @@ textureGPU,

const { width, height } = options;
const { textureGPU, glTextureType, glFormat, glType } = this.get( texture );
const { textureGPU, glTextureType, glFormat, glType, glInternalFormat } = this.get( texture );

@@ -313,5 +338,9 @@ const getImage = ( source ) => {

} else if ( source instanceof ImageBitmap || source instanceof OffscreenCanvas ) {
return source;
}
return source;
return source.data;

@@ -334,2 +363,9 @@ };

} else if ( texture.isVideoTexture ) {
texture.update();
gl.texImage2D( glTextureType, 0, glInternalFormat, glFormat, glType, options.image );
} else {

@@ -611,4 +647,63 @@

_setFramebuffer( renderContext ) {
const { gl } = this;
if ( renderContext.textures !== null ) {
const renderContextData = this.get( renderContext );
let fb = renderContextData.framebuffer;
if ( fb === undefined ) {
fb = gl.createFramebuffer();
gl.bindFramebuffer( gl.FRAMEBUFFER, fb );
const textures = renderContext.textures;
const drawBuffers = [];
for ( let i = 0; i < textures.length; i++ ) {
const texture = textures[ i ];
const { textureGPU } = this.get( texture );
const attachment = gl.COLOR_ATTACHMENT0 + i;
gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, textureGPU, 0 );
drawBuffers.push( attachment );
}
gl.drawBuffers( drawBuffers );
if ( renderContext.depthTexture !== null ) {
const { textureGPU } = this.get( renderContext.depthTexture );
gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, textureGPU, 0 );
}
renderContextData.framebuffer = fb;
} else {
gl.bindFramebuffer( gl.FRAMEBUFFER, fb );
}
} else {
gl.bindFramebuffer( gl.FRAMEBUFFER, null );
}
}
}
export default WebGLBackend;

@@ -14,2 +14,4 @@ import { NoColorSpace, FloatType } from 'three';

import { getFormat } from '../utils/WebGPUTextureUtils.js';
import WGSLNodeParser from './WGSLNodeParser.js';

@@ -62,3 +64,3 @@

dFdx: 'dpdx',
dFdy: 'dpdy',
dFdy: '- dpdy',
mod: 'threejs_mod',

@@ -664,5 +666,6 @@ lessThanEqual: 'threejs_lessThanEqual',

// @TODO: Add support for other formats
textureType = 'texture_storage_2d<rgba8unorm, write>';
const format = getFormat( texture );
textureType = 'texture_storage_2d<' + format + ', write>';
} else {

@@ -669,0 +672,0 @@

@@ -469,13 +469,13 @@ import { BlendColorFactor, OneMinusBlendColorFactor, } from '../../common/Constants.js';

case FrontSide:
descriptor.frontFace = GPUFrontFace.CW;
descriptor.cullMode = GPUCullMode.Front;
descriptor.frontFace = GPUFrontFace.CCW;
descriptor.cullMode = GPUCullMode.Back;
break;
case BackSide:
descriptor.frontFace = GPUFrontFace.CW;
descriptor.cullMode = GPUCullMode.Back;
descriptor.frontFace = GPUFrontFace.CCW;
descriptor.cullMode = GPUCullMode.Front;
break;
case DoubleSide:
descriptor.frontFace = GPUFrontFace.CW;
descriptor.frontFace = GPUFrontFace.CCW;
descriptor.cullMode = GPUCullMode.None;

@@ -482,0 +482,0 @@ break;

@@ -18,3 +18,3 @@ import {

import WebGPUTextureMipmapUtils from './WebGPUTextureMipmapUtils.js';
import WebGPUTexturePassUtils from './WebGPUTexturePassUtils.js';

@@ -32,2 +32,4 @@ const _compareToWebGPU = {

const _flipMap = [ 0, 1, 3, 2, 4, 5 ];
class WebGPUTextureUtils {

@@ -39,3 +41,3 @@

this.mipmapUtils = null;
this._passUtils = null;

@@ -110,3 +112,3 @@ this.defaultTexture = null;

const dimension = this._getDimension( texture );
const format = texture.internalFormat || this._getFormat( texture );
const format = texture.internalFormat || getFormat( texture, this.device );

@@ -118,3 +120,3 @@ const sampleCount = options.sampleCount !== undefined ? options.sampleCount : 1;

if ( options.store === true ) {
if ( texture.isStorageTexture === true ) {

@@ -245,3 +247,3 @@ usage |= GPUTextureUsage.STORAGE_BINDING;

this._copyBufferToTexture( options.image, textureData.texture, textureDescriptorGPU );
this._copyBufferToTexture( options.image, textureData.texture, textureDescriptorGPU, 0, false );

@@ -254,3 +256,3 @@ } else if ( texture.isCompressedTexture ) {

this._copyCubeMapToTexture( options.images, texture, textureData.texture, textureDescriptorGPU );
this._copyCubeMapToTexture( options.images, textureData.texture, textureDescriptorGPU, texture.flipY );

@@ -265,3 +267,3 @@ } else if ( texture.isVideoTexture ) {

this._copyImageToTexture( options.image, textureData.texture );
this._copyImageToTexture( options.image, textureData.texture, textureDescriptorGPU, 0, texture.flipY );

@@ -372,3 +374,3 @@ }

_copyCubeMapToTexture( images, texture, textureGPU, textureDescriptorGPU ) {
_copyCubeMapToTexture( images, textureGPU, textureDescriptorGPU, flipY ) {

@@ -379,9 +381,11 @@ for ( let i = 0; i < 6; i ++ ) {

const flipIndex = flipY === true ? _flipMap[ i ] : i;
if ( image.isDataTexture ) {
this._copyBufferToTexture( image.image, textureGPU, textureDescriptorGPU, i );
this._copyBufferToTexture( image.image, textureGPU, textureDescriptorGPU, flipIndex, flipY );
} else {
this._copyImageToTexture( image, textureGPU, i );
this._copyImageToTexture( image, textureGPU, textureDescriptorGPU, flipIndex, flipY );

@@ -394,3 +398,3 @@ }

_copyImageToTexture( image, textureGPU, originDepth = 0 ) {
_copyImageToTexture( image, textureGPU, textureDescriptorGPU, originDepth, flipY ) {

@@ -413,18 +417,38 @@ const device = this.backend.device;

if ( flipY === true ) {
this._flipY( textureGPU, textureDescriptorGPU, originDepth );
}
}
_generateMipmaps( textureGPU, textureDescriptorGPU, baseArrayLayer = 0 ) {
_getPassUtils() {
if ( this.mipmapUtils === null ) {
let passUtils = this._passUtils;
this.mipmapUtils = new WebGPUTextureMipmapUtils( this.backend.device );
if ( passUtils === null ) {
this._passUtils = passUtils = new WebGPUTexturePassUtils( this.backend.device );
}
this.mipmapUtils.generateMipmaps( textureGPU, textureDescriptorGPU, baseArrayLayer );
return passUtils;
}
_copyBufferToTexture( image, textureGPU, textureDescriptorGPU, originDepth = 0 ) {
_generateMipmaps( textureGPU, textureDescriptorGPU, baseArrayLayer = 0 ) {
this._getPassUtils().generateMipmaps( textureGPU, textureDescriptorGPU, baseArrayLayer );
}
_flipY( textureGPU, textureDescriptorGPU, originDepth = 0 ) {
this._getPassUtils().flipY( textureGPU, textureDescriptorGPU, originDepth );
}
_copyBufferToTexture( image, textureGPU, textureDescriptorGPU, originDepth, flipY ) {
// @TODO: Consider to use GPUCommandEncoder.copyBufferToTexture()

@@ -457,2 +481,8 @@ // @TODO: Consider to support valid buffer layouts with other formats like RGB

if ( flipY === true ) {
this._flipY( textureGPU, textureDescriptorGPU, originDepth );
}
}

@@ -635,235 +665,235 @@

_getFormat( texture ) {
}
const format = texture.format;
const type = texture.type;
const colorSpace = texture.colorSpace;
export function getFormat( texture, device = null ) {
let formatGPU;
const format = texture.format;
const type = texture.type;
const colorSpace = texture.colorSpace;
if ( /*texture.isRenderTargetTexture === true ||*/ texture.isFramebufferTexture === true ) {
let formatGPU;
formatGPU = GPUTextureFormat.BGRA8Unorm;
if ( /*texture.isRenderTargetTexture === true ||*/ texture.isFramebufferTexture === true ) {
} else if ( texture.isCompressedTexture === true ) {
formatGPU = GPUTextureFormat.BGRA8Unorm;
switch ( format ) {
} else if ( texture.isCompressedTexture === true ) {
case RGBA_S3TC_DXT1_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC1RGBAUnormSRGB : GPUTextureFormat.BC1RGBAUnorm;
break;
switch ( format ) {
case RGBA_S3TC_DXT3_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC2RGBAUnormSRGB : GPUTextureFormat.BC2RGBAUnorm;
break;
case RGBA_S3TC_DXT1_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC1RGBAUnormSRGB : GPUTextureFormat.BC1RGBAUnorm;
break;
case RGBA_S3TC_DXT5_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC3RGBAUnormSRGB : GPUTextureFormat.BC3RGBAUnorm;
break;
case RGBA_S3TC_DXT3_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC2RGBAUnormSRGB : GPUTextureFormat.BC2RGBAUnorm;
break;
case RGB_ETC2_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ETC2RGB8UnormSRGB : GPUTextureFormat.ETC2RGB8Unorm;
break;
case RGBA_S3TC_DXT5_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC3RGBAUnormSRGB : GPUTextureFormat.BC3RGBAUnorm;
break;
case RGBA_ETC2_EAC_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ETC2RGBA8UnormSRGB : GPUTextureFormat.ETC2RGBA8Unorm;
break;
case RGB_ETC2_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ETC2RGB8UnormSRGB : GPUTextureFormat.ETC2RGB8Unorm;
break;
case RGBA_ASTC_4x4_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC4x4UnormSRGB : GPUTextureFormat.ASTC4x4Unorm;
break;
case RGBA_ETC2_EAC_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ETC2RGBA8UnormSRGB : GPUTextureFormat.ETC2RGBA8Unorm;
break;
case RGBA_ASTC_5x4_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC5x4UnormSRGB : GPUTextureFormat.ASTC5x4Unorm;
break;
case RGBA_ASTC_4x4_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC4x4UnormSRGB : GPUTextureFormat.ASTC4x4Unorm;
break;
case RGBA_ASTC_5x5_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC5x5UnormSRGB : GPUTextureFormat.ASTC5x5Unorm;
break;
case RGBA_ASTC_5x4_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC5x4UnormSRGB : GPUTextureFormat.ASTC5x4Unorm;
break;
case RGBA_ASTC_6x5_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC6x5UnormSRGB : GPUTextureFormat.ASTC6x5Unorm;
break;
case RGBA_ASTC_5x5_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC5x5UnormSRGB : GPUTextureFormat.ASTC5x5Unorm;
break;
case RGBA_ASTC_6x6_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC6x6UnormSRGB : GPUTextureFormat.ASTC6x6Unorm;
break;
case RGBA_ASTC_6x5_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC6x5UnormSRGB : GPUTextureFormat.ASTC6x5Unorm;
break;
case RGBA_ASTC_8x5_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x5UnormSRGB : GPUTextureFormat.ASTC8x5Unorm;
break;
case RGBA_ASTC_6x6_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC6x6UnormSRGB : GPUTextureFormat.ASTC6x6Unorm;
break;
case RGBA_ASTC_8x6_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x6UnormSRGB : GPUTextureFormat.ASTC8x6Unorm;
break;
case RGBA_ASTC_8x5_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x5UnormSRGB : GPUTextureFormat.ASTC8x5Unorm;
break;
case RGBA_ASTC_8x8_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x8UnormSRGB : GPUTextureFormat.ASTC8x8Unorm;
break;
case RGBA_ASTC_8x6_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x6UnormSRGB : GPUTextureFormat.ASTC8x6Unorm;
break;
case RGBA_ASTC_10x5_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x5UnormSRGB : GPUTextureFormat.ASTC10x5Unorm;
break;
case RGBA_ASTC_8x8_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x8UnormSRGB : GPUTextureFormat.ASTC8x8Unorm;
break;
case RGBA_ASTC_10x6_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x6UnormSRGB : GPUTextureFormat.ASTC10x6Unorm;
break;
case RGBA_ASTC_10x5_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x5UnormSRGB : GPUTextureFormat.ASTC10x5Unorm;
break;
case RGBA_ASTC_10x8_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x8UnormSRGB : GPUTextureFormat.ASTC10x8Unorm;
break;
case RGBA_ASTC_10x6_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x6UnormSRGB : GPUTextureFormat.ASTC10x6Unorm;
break;
case RGBA_ASTC_10x10_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x10UnormSRGB : GPUTextureFormat.ASTC10x10Unorm;
break;
case RGBA_ASTC_10x8_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x8UnormSRGB : GPUTextureFormat.ASTC10x8Unorm;
break;
case RGBA_ASTC_12x10_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC12x10UnormSRGB : GPUTextureFormat.ASTC12x10Unorm;
break;
case RGBA_ASTC_10x10_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x10UnormSRGB : GPUTextureFormat.ASTC10x10Unorm;
break;
case RGBA_ASTC_12x12_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC12x12UnormSRGB : GPUTextureFormat.ASTC12x12Unorm;
break;
case RGBA_ASTC_12x10_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC12x10UnormSRGB : GPUTextureFormat.ASTC12x10Unorm;
break;
default:
console.error( 'WebGPURenderer: Unsupported texture format.', format );
case RGBA_ASTC_12x12_Format:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC12x12UnormSRGB : GPUTextureFormat.ASTC12x12Unorm;
break;
}
default:
console.error( 'WebGPURenderer: Unsupported texture format.', format );
} else {
}
switch ( format ) {
} else {
case RGBAFormat:
switch ( format ) {
switch ( type ) {
case RGBAFormat:
case UnsignedByteType:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.RGBA8UnormSRGB : GPUTextureFormat.RGBA8Unorm;
break;
switch ( type ) {
case HalfFloatType:
formatGPU = GPUTextureFormat.RGBA16Float;
break;
case UnsignedByteType:
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.RGBA8UnormSRGB : GPUTextureFormat.RGBA8Unorm;
break;
case FloatType:
formatGPU = GPUTextureFormat.RGBA32Float;
break;
case HalfFloatType:
formatGPU = GPUTextureFormat.RGBA16Float;
break;
default:
console.error( 'WebGPURenderer: Unsupported texture type with RGBAFormat.', type );
case FloatType:
formatGPU = GPUTextureFormat.RGBA32Float;
break;
}
default:
console.error( 'WebGPURenderer: Unsupported texture type with RGBAFormat.', type );
break;
}
case RedFormat:
break;
switch ( type ) {
case RedFormat:
case UnsignedByteType:
formatGPU = GPUTextureFormat.R8Unorm;
break;
switch ( type ) {
case HalfFloatType:
formatGPU = GPUTextureFormat.R16Float;
break;
case UnsignedByteType:
formatGPU = GPUTextureFormat.R8Unorm;
break;
case FloatType:
formatGPU = GPUTextureFormat.R32Float;
break;
case HalfFloatType:
formatGPU = GPUTextureFormat.R16Float;
break;
default:
console.error( 'WebGPURenderer: Unsupported texture type with RedFormat.', type );
case FloatType:
formatGPU = GPUTextureFormat.R32Float;
break;
}
default:
console.error( 'WebGPURenderer: Unsupported texture type with RedFormat.', type );
break;
}
case RGFormat:
break;
switch ( type ) {
case RGFormat:
case UnsignedByteType:
formatGPU = GPUTextureFormat.RG8Unorm;
break;
switch ( type ) {
case HalfFloatType:
formatGPU = GPUTextureFormat.RG16Float;
break;
case UnsignedByteType:
formatGPU = GPUTextureFormat.RG8Unorm;
break;
case FloatType:
formatGPU = GPUTextureFormat.RG32Float;
break;
case HalfFloatType:
formatGPU = GPUTextureFormat.RG16Float;
break;
default:
console.error( 'WebGPURenderer: Unsupported texture type with RGFormat.', type );
case FloatType:
formatGPU = GPUTextureFormat.RG32Float;
break;
}
default:
console.error( 'WebGPURenderer: Unsupported texture type with RGFormat.', type );
break;
}
case DepthFormat:
break;
switch ( type ) {
case DepthFormat:
case UnsignedShortType:
formatGPU = GPUTextureFormat.Depth16Unorm;
break;
switch ( type ) {
case UnsignedIntType:
formatGPU = GPUTextureFormat.Depth24Plus;
break;
case UnsignedShortType:
formatGPU = GPUTextureFormat.Depth16Unorm;
break;
case FloatType:
formatGPU = GPUTextureFormat.Depth32Float;
break;
case UnsignedIntType:
formatGPU = GPUTextureFormat.Depth24Plus;
break;
default:
console.error( 'WebGPURenderer: Unsupported texture type with DepthFormat.', type );
case FloatType:
formatGPU = GPUTextureFormat.Depth32Float;
break;
}
default:
console.error( 'WebGPURenderer: Unsupported texture type with DepthFormat.', type );
break;
}
case DepthStencilFormat:
break;
switch ( type ) {
case DepthStencilFormat:
case UnsignedInt248Type:
formatGPU = GPUTextureFormat.Depth24PlusStencil8;
break;
switch ( type ) {
case FloatType:
case UnsignedInt248Type:
formatGPU = GPUTextureFormat.Depth24PlusStencil8;
break;
if ( this.device.features.has( GPUFeatureName.Depth32FloatStencil8 ) === false ) {
case FloatType:
console.error( 'WebGPURenderer: Depth textures with DepthStencilFormat + FloatType can only be used with the "depth32float-stencil8" GPU feature.' );
if ( device && device.features.has( GPUFeatureName.Depth32FloatStencil8 ) === false ) {
}
console.error( 'WebGPURenderer: Depth textures with DepthStencilFormat + FloatType can only be used with the "depth32float-stencil8" GPU feature.' );
formatGPU = GPUTextureFormat.Depth32FloatStencil8;
}
break;
formatGPU = GPUTextureFormat.Depth32FloatStencil8;
default:
console.error( 'WebGPURenderer: Unsupported texture type with DepthStencilFormat.', type );
break;
}
default:
console.error( 'WebGPURenderer: Unsupported texture type with DepthStencilFormat.', type );
break;
}
default:
console.error( 'WebGPURenderer: Unsupported texture format.', format );
break;
}
default:
console.error( 'WebGPURenderer: Unsupported texture format.', format );
}
return formatGPU;
}
return formatGPU;
}
export default WebGPUTextureUtils;

@@ -194,3 +194,3 @@ /*// debugger tools

const textureView = textureData.texture.createView( {
baseMipLevel: 0,
baseMipLevel: renderContext.activeMipmapLevel,
mipLevelCount: 1,

@@ -354,3 +354,3 @@ baseArrayLayer: renderContext.activeCubeFace,

currentPass.setScissorRect( x, y, width, height );
currentPass.setScissorRect( x, renderContext.height - height - y, width, height );

@@ -472,3 +472,3 @@ }

occluded.add( currentOcclusionQueryObjects[ i ], true );
occluded.add( currentOcclusionQueryObjects[ i ] );

@@ -490,5 +490,5 @@ }

const { currentPass } = this.get( renderContext );
const { x, y, width, height, minDepth, maxDepth } = renderContext.viewportValue;
let { x, y, width, height, minDepth, maxDepth } = renderContext.viewportValue;
currentPass.setViewport( x, y, width, height, minDepth, maxDepth );
currentPass.setViewport( x, renderContext.height - height - y, width, height, minDepth, maxDepth );

@@ -495,0 +495,0 @@ }

@@ -37,3 +37,3 @@ /**

gl_FragColor = LinearTosRGB( tex );
gl_FragColor = sRGBTransferOETF( tex );

@@ -40,0 +40,0 @@ }`

@@ -30,13 +30,13 @@ /**

void RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {
void RE_Direct_BlinnPhong( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {
vec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;
vec3 irradiance = getGradientIrradiance( geometryNormal, directLight.direction ) * directLight.color;
reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );
reflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularShininess ) * material.specularStrength;
reflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometryViewDir, geometryNormal, material.specularColor, material.specularShininess ) * material.specularStrength;
}
void RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {
void RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {

@@ -43,0 +43,0 @@ reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );

@@ -68,5 +68,5 @@ import {

#ifdef SRGB_COLOR_SPACE
#ifdef SRGB_TRANSFER
gl_FragColor = LinearTosRGB( gl_FragColor );
gl_FragColor = sRGBTransferOETF( gl_FragColor );

@@ -73,0 +73,0 @@ #endif

@@ -60,6 +60,6 @@ import {

'void RE_Direct_Scattering(const in IncidentLight directLight, const in vec2 uv, const in GeometricContext geometry, inout ReflectedLight reflectedLight) {',
'void RE_Direct_Scattering(const in IncidentLight directLight, const in vec2 uv, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, inout ReflectedLight reflectedLight) {',
' vec3 thickness = thicknessColor * texture2D(thicknessMap, uv).r;',
' vec3 scatteringHalf = normalize(directLight.direction + (geometry.normal * thicknessDistortion));',
' float scatteringDot = pow(saturate(dot(geometry.viewDir, -scatteringHalf)), thicknessPower) * thicknessScale;',
' vec3 scatteringHalf = normalize(directLight.direction + (geometryNormal * thicknessDistortion));',
' float scatteringDot = pow(saturate(dot(geometryViewDir, -scatteringHalf)), thicknessPower) * thicknessScale;',
' vec3 scatteringIllu = (scatteringDot + thicknessAmbient) * thickness;',

@@ -73,8 +73,8 @@ ' reflectedLight.directDiffuse += scatteringIllu * thicknessAttenuation * directLight.color;',

ShaderChunk[ 'lights_fragment_begin' ],
'RE_Direct( directLight, geometry, material, reflectedLight );',
'RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );',
[
'RE_Direct( directLight, geometry, material, reflectedLight );',
'RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );',
'#if defined( SUBSURFACE ) && defined( USE_UV )',
' RE_Direct_Scattering(directLight, vUv, geometry, reflectedLight);',
' RE_Direct_Scattering(directLight, vUv, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, reflectedLight);',
'#endif',

@@ -81,0 +81,0 @@ ].join( '\n' )

@@ -558,3 +558,3 @@ import {

/**
* @param {Array<BufferGeometry>} geometry
* @param {BufferGeometry} geometry
* @return {number}

@@ -635,4 +635,6 @@ */

// convert the error tolerance to an amount of decimal places to truncate to
const decimalShift = Math.log10( 1 / tolerance );
const shiftMultiplier = Math.pow( 10, decimalShift );
const halfTolerance = tolerance * 0.5;
const exponent = Math.log10( 1 / tolerance );
const hashMultiplier = Math.pow( 10, exponent );
const hashAdditive = halfTolerance * hashMultiplier;
for ( let i = 0; i < vertexCount; i ++ ) {

@@ -653,3 +655,3 @@

// double tilde truncates the decimal value
hash += `${ ~ ~ ( attribute[ getters[ k ] ]( index ) * shiftMultiplier ) },`;
hash += `${ ~ ~ ( attribute[ getters[ k ] ]( index ) * hashMultiplier + hashAdditive ) },`;

@@ -656,0 +658,0 @@ }

{
"name": "three",
"version": "0.156.1",
"version": "0.157.0",
"description": "JavaScript 3D library",

@@ -5,0 +5,0 @@ "type": "module",

import { Quaternion } from '../math/Quaternion.js';
import { AdditiveAnimationBlendMode } from '../constants.js';
// same as Array.prototype.slice, but also works on typed arrays
function arraySlice( array, from, to ) {
if ( isTypedArray( array ) ) {
// in ios9 array.subarray(from, undefined) will return empty array
// but array.subarray(from) or array.subarray(from, len) is correct
return new array.constructor( array.subarray( from, to !== undefined ? to : array.length ) );
}
return array.slice( from, to );
}
// converts an array to a specific type

@@ -282,3 +267,3 @@ function convertArray( array, type, forceClone ) {

const endIndex = referenceValueSize - referenceOffset;
referenceValue = arraySlice( referenceTrack.values, startIndex, endIndex );
referenceValue = referenceTrack.values.slice( startIndex, endIndex );

@@ -290,3 +275,3 @@ } else if ( referenceTime >= referenceTrack.times[ lastIndex ] ) {

const endIndex = startIndex + referenceValueSize - referenceOffset;
referenceValue = arraySlice( referenceTrack.values, startIndex, endIndex );
referenceValue = referenceTrack.values.slice( startIndex, endIndex );

@@ -300,3 +285,3 @@ } else {

interpolant.evaluate( referenceTime );
referenceValue = arraySlice( interpolant.resultBuffer, startIndex, endIndex );
referenceValue = interpolant.resultBuffer.slice( startIndex, endIndex );

@@ -356,3 +341,2 @@ }

const AnimationUtils = {
arraySlice: arraySlice,
convertArray: convertArray,

@@ -368,3 +352,2 @@ isTypedArray: isTypedArray,

export {
arraySlice,
convertArray,

@@ -371,0 +354,0 @@ isTypedArray,

@@ -242,4 +242,4 @@ import {

const stride = this.getValueSize();
this.times = AnimationUtils.arraySlice( times, from, to );
this.values = AnimationUtils.arraySlice( this.values, from * stride, to * stride );
this.times = times.slice( from, to );
this.values = this.values.slice( from * stride, to * stride );

@@ -334,4 +334,4 @@ }

// times or values may be shared with other tracks, so overwriting is unsafe
const times = AnimationUtils.arraySlice( this.times ),
values = AnimationUtils.arraySlice( this.values ),
const times = this.times.slice(),
values = this.values.slice(),
stride = this.getValueSize(),

@@ -429,4 +429,4 @@

this.times = AnimationUtils.arraySlice( times, 0, writeIndex );
this.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );
this.times = times.slice( 0, writeIndex );
this.values = values.slice( 0, writeIndex * stride );

@@ -446,4 +446,4 @@ } else {

const times = AnimationUtils.arraySlice( this.times, 0 );
const values = AnimationUtils.arraySlice( this.values, 0 );
const times = this.times.slice();
const values = this.values.slice();

@@ -450,0 +450,0 @@ const TypedKeyframeTrack = this.constructor;

@@ -41,8 +41,4 @@ import { WebGLCoordinateSystem } from '../constants.js';

this.updateWorldMatrix( true, false );
return super.getWorldDirection( target ).negate();
const e = this.matrixWorld.elements;
return target.set( - e[ 8 ], - e[ 9 ], - e[ 10 ] ).normalize();
}

@@ -49,0 +45,0 @@

@@ -18,2 +18,3 @@ import { WebGLCoordinateSystem, WebGPUCoordinateSystem } from '../constants.js';

this.coordinateSystem = null;
this.activeMipmapLevel = 0;

@@ -116,3 +117,3 @@ const cameraPX = new PerspectiveCamera( fov, aspect, near, far );

const renderTarget = this.renderTarget;
const { renderTarget, activeMipmapLevel } = this;

@@ -130,2 +131,4 @@ if ( this.coordinateSystem !== renderer.coordinateSystem ) {

const currentRenderTarget = renderer.getRenderTarget();
const currentActiveCubeFace = renderer.getActiveCubeFace();
const currentActiveMipmapLevel = renderer.getActiveMipmapLevel();

@@ -140,23 +143,26 @@ const currentXrEnabled = renderer.xr.enabled;

renderer.setRenderTarget( renderTarget, 0 );
renderer.setRenderTarget( renderTarget, 0, activeMipmapLevel );
renderer.render( scene, cameraPX );
renderer.setRenderTarget( renderTarget, 1 );
renderer.setRenderTarget( renderTarget, 1, activeMipmapLevel );
renderer.render( scene, cameraNX );
renderer.setRenderTarget( renderTarget, 2 );
renderer.setRenderTarget( renderTarget, 2, activeMipmapLevel );
renderer.render( scene, cameraPY );
renderer.setRenderTarget( renderTarget, 3 );
renderer.setRenderTarget( renderTarget, 3, activeMipmapLevel );
renderer.render( scene, cameraNY );
renderer.setRenderTarget( renderTarget, 4 );
renderer.setRenderTarget( renderTarget, 4, activeMipmapLevel );
renderer.render( scene, cameraPZ );
// mipmaps are generated during the last call of render()
// at this point, all sides of the cube render target are defined
renderTarget.texture.generateMipmaps = generateMipmaps;
renderer.setRenderTarget( renderTarget, 5 );
renderer.setRenderTarget( renderTarget, 5, activeMipmapLevel );
renderer.render( scene, cameraNZ );
renderer.setRenderTarget( currentRenderTarget );
renderer.setRenderTarget( currentRenderTarget, currentActiveCubeFace, currentActiveMipmapLevel );

@@ -163,0 +169,0 @@ renderer.xr.enabled = currentXrEnabled;

@@ -1,2 +0,2 @@

export const REVISION = '156';
export const REVISION = '157';

@@ -161,2 +161,8 @@ export const MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 };

export const LinearTransfer = 'linear';
export const SRGBTransfer = 'srgb';
export const Rec709Primaries = 'rec709';
export const P3Primaries = 'p3';
export const ZeroStencilOp = 0;

@@ -163,0 +169,0 @@ export const KeepStencilOp = 7680;

@@ -40,2 +40,12 @@ import { EventDispatcher } from './EventDispatcher.js';

options = Object.assign( {
generateMipmaps: false,
internalFormat: null,
minFilter: LinearFilter,
depthBuffer: true,
stencilBuffer: false,
depthTexture: null,
samples: 0
}, options );
this.texture = new Texture( image, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.colorSpace );

@@ -45,12 +55,11 @@ this.texture.isRenderTargetTexture = true;

this.texture.flipY = false;
this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false;
this.texture.internalFormat = options.internalFormat !== undefined ? options.internalFormat : null;
this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter;
this.texture.generateMipmaps = options.generateMipmaps;
this.texture.internalFormat = options.internalFormat;
this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;
this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : false;
this.depthBuffer = options.depthBuffer;
this.stencilBuffer = options.stencilBuffer;
this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;
this.depthTexture = options.depthTexture;
this.samples = options.samples !== undefined ? options.samples : 0;
this.samples = options.samples;

@@ -57,0 +66,0 @@ }

@@ -36,6 +36,9 @@ import { Curve } from './Curve.js';

this.curves.push( new Curves[ 'LineCurve' ]( endPoint, startPoint ) );
const lineType = ( startPoint.isVector2 === true ) ? 'LineCurve' : 'LineCurve3';
this.curves.push( new Curves[ lineType ]( endPoint, startPoint ) );
}
return this;
}

@@ -42,0 +45,0 @@

@@ -145,3 +145,3 @@ import { Color } from '../math/Color.js';

if ( json.linewidth !== 1 ) material.linewidth = json.linewidth;
if ( json.linewidth !== undefined ) material.linewidth = json.linewidth;
if ( json.dashSize !== undefined ) material.dashSize = json.dashSize;

@@ -148,0 +148,0 @@ if ( json.gapSize !== undefined ) material.gapSize = json.gapSize;

@@ -788,2 +788,8 @@ import {

if ( data.fog.name !== '' ) {
object.fog.name = data.fog.name;
}
}

@@ -790,0 +796,0 @@

@@ -323,6 +323,6 @@ import { EventDispatcher } from '../core/EventDispatcher.js';

if ( this.side !== FrontSide ) data.side = this.side;
if ( this.vertexColors ) data.vertexColors = true;
if ( this.vertexColors === true ) data.vertexColors = true;
if ( this.opacity < 1 ) data.opacity = this.opacity;
if ( this.transparent === true ) data.transparent = this.transparent;
if ( this.transparent === true ) data.transparent = true;

@@ -358,8 +358,8 @@ data.depthFunc = this.depthFunc;

if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;
if ( this.alphaHash === true ) data.alphaHash = this.alphaHash;
if ( this.alphaToCoverage === true ) data.alphaToCoverage = this.alphaToCoverage;
if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;
if ( this.forceSinglePass === true ) data.forceSinglePass = this.forceSinglePass;
if ( this.alphaHash === true ) data.alphaHash = true;
if ( this.alphaToCoverage === true ) data.alphaToCoverage = true;
if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = true;
if ( this.forceSinglePass === true ) data.forceSinglePass = true;
if ( this.wireframe === true ) data.wireframe = this.wireframe;
if ( this.wireframe === true ) data.wireframe = true;
if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;

@@ -369,3 +369,3 @@ if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;

if ( this.flatShading === true ) data.flatShading = this.flatShading;
if ( this.flatShading === true ) data.flatShading = true;

@@ -372,0 +372,0 @@ if ( this.visible === false ) data.visible = false;

@@ -445,8 +445,4 @@ import { clamp, euclideanModulo, lerp } from './MathUtils.js';

_hslA.h += h; _hslA.s += s; _hslA.l += l;
return this.setHSL( _hslA.h + h, _hslA.s + s, _hslA.l + l );
this.setHSL( _hslA.h, _hslA.s, _hslA.l );
return this;
}

@@ -453,0 +449,0 @@

@@ -1,16 +0,4 @@

import { SRGBColorSpace, LinearSRGBColorSpace, DisplayP3ColorSpace, } from '../constants.js';
import { SRGBColorSpace, LinearSRGBColorSpace, DisplayP3ColorSpace, LinearDisplayP3ColorSpace, Rec709Primaries, P3Primaries, SRGBTransfer, LinearTransfer, NoColorSpace, } from '../constants.js';
import { Matrix3 } from './Matrix3.js';
export function SRGBToLinear( c ) {
return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 );
}
export function LinearToSRGB( c ) {
return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055;
}
/**

@@ -28,41 +16,46 @@ * Matrices converting P3 <-> Rec. 709 primaries, without gamut mapping

const LINEAR_SRGB_TO_LINEAR_DISPLAY_P3 = /*@__PURE__*/ new Matrix3().fromArray( [
0.8224621, 0.0331941, 0.0170827,
0.1775380, 0.9668058, 0.0723974,
- 0.0000001, 0.0000001, 0.9105199
] );
const LINEAR_SRGB_TO_LINEAR_DISPLAY_P3 = /*@__PURE__*/ new Matrix3().set(
0.8224621, 0.177538, 0.0,
0.0331941, 0.9668058, 0.0,
0.0170827, 0.0723974, 0.9105199,
);
const LINEAR_DISPLAY_P3_TO_LINEAR_SRGB = /*@__PURE__*/ new Matrix3().fromArray( [
1.2249401, - 0.0420569, - 0.0196376,
- 0.2249404, 1.0420571, - 0.0786361,
0.0000001, 0.0000000, 1.0982735
] );
const LINEAR_DISPLAY_P3_TO_LINEAR_SRGB = /*@__PURE__*/ new Matrix3().set(
1.2249401, - 0.2249404, 0.0,
- 0.0420569, 1.0420571, 0.0,
- 0.0196376, - 0.0786361, 1.0982735
);
function DisplayP3ToLinearSRGB( color ) {
// Display P3 uses the sRGB transfer functions
return color.convertSRGBToLinear().applyMatrix3( LINEAR_DISPLAY_P3_TO_LINEAR_SRGB );
}
function LinearSRGBToDisplayP3( color ) {
// Display P3 uses the sRGB transfer functions
return color.applyMatrix3( LINEAR_SRGB_TO_LINEAR_DISPLAY_P3 ).convertLinearToSRGB();
}
// Conversions from <source> to Linear-sRGB reference space.
const TO_LINEAR = {
[ LinearSRGBColorSpace ]: ( color ) => color,
[ SRGBColorSpace ]: ( color ) => color.convertSRGBToLinear(),
[ DisplayP3ColorSpace ]: DisplayP3ToLinearSRGB,
/**
* Defines supported color spaces by transfer function and primaries,
* and provides conversions to/from the Linear-sRGB reference space.
*/
const COLOR_SPACES = {
[ LinearSRGBColorSpace ]: {
transfer: LinearTransfer,
primaries: Rec709Primaries,
toReference: ( color ) => color,
fromReference: ( color ) => color,
},
[ SRGBColorSpace ]: {
transfer: SRGBTransfer,
primaries: Rec709Primaries,
toReference: ( color ) => color.convertSRGBToLinear(),
fromReference: ( color ) => color.convertLinearToSRGB(),
},
[ LinearDisplayP3ColorSpace ]: {
transfer: LinearTransfer,
primaries: P3Primaries,
toReference: ( color ) => color.applyMatrix3( LINEAR_DISPLAY_P3_TO_LINEAR_SRGB ),
fromReference: ( color ) => color.applyMatrix3( LINEAR_SRGB_TO_LINEAR_DISPLAY_P3 ),
},
[ DisplayP3ColorSpace ]: {
transfer: SRGBTransfer,
primaries: P3Primaries,
toReference: ( color ) => color.convertSRGBToLinear().applyMatrix3( LINEAR_DISPLAY_P3_TO_LINEAR_SRGB ),
fromReference: ( color ) => color.applyMatrix3( LINEAR_SRGB_TO_LINEAR_DISPLAY_P3 ).convertLinearToSRGB(),
},
};
// Conversions to <target> from Linear-sRGB reference space.
const FROM_LINEAR = {
[ LinearSRGBColorSpace ]: ( color ) => color,
[ SRGBColorSpace ]: ( color ) => color.convertLinearToSRGB(),
[ DisplayP3ColorSpace ]: LinearSRGBToDisplayP3,
};
const SUPPORTED_WORKING_COLOR_SPACES = new Set( [ LinearSRGBColorSpace, LinearDisplayP3ColorSpace ] );

@@ -73,2 +66,4 @@ export const ColorManagement = {

_workingColorSpace: LinearSRGBColorSpace,
get legacyMode() {

@@ -92,3 +87,3 @@

return LinearSRGBColorSpace;
return this._workingColorSpace;

@@ -99,4 +94,10 @@ },

console.warn( 'THREE.ColorManagement: .workingColorSpace is readonly.' );
if ( ! SUPPORTED_WORKING_COLOR_SPACES.has( colorSpace ) ) {
throw new Error( `Unsupported working color space, "${ colorSpace }".` );
}
this._workingColorSpace = colorSpace;
},

@@ -112,27 +113,48 @@

const sourceToLinear = TO_LINEAR[ sourceColorSpace ];
const targetFromLinear = FROM_LINEAR[ targetColorSpace ];
const sourceToReference = COLOR_SPACES[ sourceColorSpace ].toReference;
const targetFromReference = COLOR_SPACES[ targetColorSpace ].fromReference;
if ( sourceToLinear === undefined || targetFromLinear === undefined ) {
return targetFromReference( sourceToReference( color ) );
throw new Error( `Unsupported color space conversion, "${ sourceColorSpace }" to "${ targetColorSpace }".` );
},
}
fromWorkingColorSpace: function ( color, targetColorSpace ) {
return targetFromLinear( sourceToLinear( color ) );
return this.convert( color, this._workingColorSpace, targetColorSpace );
},
fromWorkingColorSpace: function ( color, targetColorSpace ) {
toWorkingColorSpace: function ( color, sourceColorSpace ) {
return this.convert( color, this.workingColorSpace, targetColorSpace );
return this.convert( color, sourceColorSpace, this._workingColorSpace );
},
toWorkingColorSpace: function ( color, sourceColorSpace ) {
getPrimaries: function ( colorSpace ) {
return this.convert( color, sourceColorSpace, this.workingColorSpace );
return COLOR_SPACES[ colorSpace ].primaries;
},
getTransfer: function ( colorSpace ) {
if ( colorSpace === NoColorSpace ) return LinearTransfer;
return COLOR_SPACES[ colorSpace ].transfer;
},
};
export function SRGBToLinear( c ) {
return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 );
}
export function LinearToSRGB( c ) {
return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055;
}

@@ -31,3 +31,3 @@ import { Vector2 } from '../math/Vector2.js';

constructor( material ) {
constructor( material = new SpriteMaterial() ) {

@@ -60,3 +60,3 @@ super();

this.geometry = _geometry;
this.material = ( material !== undefined ) ? material : new SpriteMaterial();
this.material = material;

@@ -63,0 +63,0 @@ this.center = new Vector2( 0.5, 0.5 );

@@ -11,3 +11,3 @@ export default /* glsl */`

float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );
float dotNV = saturate( dot( geometryNormal, geometryViewDir ) );

@@ -14,0 +14,0 @@ reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );

export default /* glsl */`
#ifdef USE_CLEARCOAT
vec3 clearcoatNormal = geometryNormal;
vec3 clearcoatNormal = nonPerturbedNormal;
#endif
`;
export default /* glsl */`
// http://www.russellcottrell.com/photo/matrixCalculator.htm
// Linear sRGB => XYZ => Linear Display P3
const mat3 LINEAR_SRGB_TO_LINEAR_DISPLAY_P3 = mat3(
vec3( 0.8224621, 0.177538, 0.0 ),
vec3( 0.0331941, 0.9668058, 0.0 ),
vec3( 0.0170827, 0.0723974, 0.9105199 )
);
// Linear Display P3 => XYZ => Linear sRGB
const mat3 LINEAR_DISPLAY_P3_TO_LINEAR_SRGB = mat3(
vec3( 1.2249401, - 0.2249404, 0.0 ),
vec3( - 0.0420569, 1.0420571, 0.0 ),
vec3( - 0.0196376, - 0.0786361, 1.0982735 )
);
vec4 LinearSRGBToLinearDisplayP3( in vec4 value ) {
return vec4( value.rgb * LINEAR_SRGB_TO_LINEAR_DISPLAY_P3, value.a );
}
vec4 LinearDisplayP3ToLinearSRGB( in vec4 value ) {
return vec4( value.rgb * LINEAR_DISPLAY_P3_TO_LINEAR_SRGB, value.a );
}
vec4 LinearTransferOETF( in vec4 value ) {
return value;
}
vec4 sRGBTransferOETF( in vec4 value ) {
return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );
}
// @deprecated, r156
vec4 LinearToLinear( in vec4 value ) {

@@ -7,6 +40,6 @@ return value;

// @deprecated, r156
vec4 LinearTosRGB( in vec4 value ) {
return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );
return sRGBTransferOETF( value );
}
`;

@@ -55,11 +55,2 @@ export default /* glsl */`

struct GeometricContext {
vec3 position;
vec3 normal;
vec3 viewDir;
#ifdef USE_CLEARCOAT
vec3 clearcoatNormal;
#endif
};
#ifdef USE_ALPHAHASH

@@ -66,0 +57,0 @@

@@ -16,11 +16,11 @@ export default /* glsl */`

GeometricContext geometry;
vec3 geometryPosition = - vViewPosition;
vec3 geometryNormal = normal;
vec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );
geometry.position = - vViewPosition;
geometry.normal = normal;
geometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );
vec3 geometryClearcoatNormal;
#ifdef USE_CLEARCOAT
geometry.clearcoatNormal = clearcoatNormal;
geometryClearcoatNormal = clearcoatNormal;

@@ -31,3 +31,3 @@ #endif

float dotNVi = saturate( dot( normal, geometry.viewDir ) );
float dotNVi = saturate( dot( normal, geometryViewDir ) );

@@ -69,3 +69,3 @@ if ( material.iridescenceThickness == 0.0 ) {

getPointLightInfo( pointLight, geometry, directLight );
getPointLightInfo( pointLight, geometryPosition, directLight );

@@ -77,3 +77,3 @@ #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )

RE_Direct( directLight, geometry, material, reflectedLight );
RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );

@@ -101,3 +101,3 @@ }

getSpotLightInfo( spotLight, geometry, directLight );
getSpotLightInfo( spotLight, geometryPosition, directLight );

@@ -127,3 +127,3 @@ // spot lights are ordered [shadows with maps, shadows without maps, maps without shadows, none]

RE_Direct( directLight, geometry, material, reflectedLight );
RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );

@@ -147,3 +147,3 @@ }

getDirectionalLightInfo( directionalLight, geometry, directLight );
getDirectionalLightInfo( directionalLight, directLight );

@@ -155,3 +155,3 @@ #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )

RE_Direct( directLight, geometry, material, reflectedLight );
RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );

@@ -171,3 +171,3 @@ }

rectAreaLight = rectAreaLights[ i ];
RE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );
RE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );

@@ -185,4 +185,8 @@ }

irradiance += getLightProbeIrradiance( lightProbe, geometry.normal );
#if defined( USE_LIGHT_PROBES )
irradiance += getLightProbeIrradiance( lightProbe, geometryNormal );
#endif
#if ( NUM_HEMI_LIGHTS > 0 )

@@ -193,3 +197,3 @@

irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal );
irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal );

@@ -196,0 +200,0 @@ }

export default /* glsl */`
#if defined( RE_IndirectDiffuse )
RE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );
RE_IndirectDiffuse( irradiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );

@@ -10,5 +10,5 @@ #endif

RE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );
RE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
#endif
`;

@@ -15,3 +15,3 @@ export default /* glsl */`

iblIrradiance += getIBLIrradiance( geometry.normal );
iblIrradiance += getIBLIrradiance( geometryNormal );

@@ -26,7 +26,7 @@ #endif

radiance += getIBLAnisotropyRadiance( geometry.viewDir, geometry.normal, material.roughness, material.anisotropyB, material.anisotropy );
radiance += getIBLAnisotropyRadiance( geometryViewDir, geometryNormal, material.roughness, material.anisotropyB, material.anisotropy );
#else
radiance += getIBLRadiance( geometry.viewDir, geometry.normal, material.roughness );
radiance += getIBLRadiance( geometryViewDir, geometryNormal, material.roughness );

@@ -37,3 +37,3 @@ #endif

clearcoatRadiance += getIBLRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness );
clearcoatRadiance += getIBLRadiance( geometryViewDir, geometryClearcoatNormal, material.clearcoatRoughness );

@@ -40,0 +40,0 @@ #endif

@@ -11,5 +11,5 @@ export default /* glsl */`

void RE_Direct_Lambert( const in IncidentLight directLight, const in GeometricContext geometry, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {
void RE_Direct_Lambert( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {
float dotNL = saturate( dot( geometry.normal, directLight.direction ) );
float dotNL = saturate( dot( geometryNormal, directLight.direction ) );
vec3 irradiance = dotNL * directLight.color;

@@ -21,3 +21,3 @@

void RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in GeometricContext geometry, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {
void RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {

@@ -24,0 +24,0 @@ reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );

export default /* glsl */`
uniform bool receiveShadow;
uniform vec3 ambientLightColor;
uniform vec3 lightProbe[ 9 ];
#if defined( USE_LIGHT_PROBES )
uniform vec3 lightProbe[ 9 ];
#endif
// get the irradiance (radiance convolved with cosine lobe) at the point 'normal' on the unit sphere

@@ -97,3 +102,3 @@ // source: https://graphics.stanford.edu/papers/envmap/envmap.pdf

void getDirectionalLightInfo( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight light ) {
void getDirectionalLightInfo( const in DirectionalLight directionalLight, out IncidentLight light ) {

@@ -121,5 +126,5 @@ light.color = directionalLight.color;

// light is an out parameter as having it as a return value caused compiler errors on some devices
void getPointLightInfo( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight light ) {
void getPointLightInfo( const in PointLight pointLight, const in vec3 geometryPosition, out IncidentLight light ) {
vec3 lVector = pointLight.position - geometry.position;
vec3 lVector = pointLight.position - geometryPosition;

@@ -154,5 +159,5 @@ light.direction = normalize( lVector );

// light is an out parameter as having it as a return value caused compiler errors on some devices
void getSpotLightInfo( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight light ) {
void getSpotLightInfo( const in SpotLight spotLight, const in vec3 geometryPosition, out IncidentLight light ) {
vec3 lVector = spotLight.position - geometry.position;
vec3 lVector = spotLight.position - geometryPosition;

@@ -159,0 +164,0 @@ light.direction = normalize( lVector );

@@ -13,5 +13,5 @@ export default /* glsl */`

void RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {
void RE_Direct_BlinnPhong( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {
float dotNL = saturate( dot( geometry.normal, directLight.direction ) );
float dotNL = saturate( dot( geometryNormal, directLight.direction ) );
vec3 irradiance = dotNL * directLight.color;

@@ -21,7 +21,7 @@

reflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularShininess ) * material.specularStrength;
reflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometryViewDir, geometryNormal, material.specularColor, material.specularShininess ) * material.specularStrength;
}
void RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {
void RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {

@@ -28,0 +28,0 @@ reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );

@@ -5,3 +5,3 @@ export default /* glsl */`

vec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );
vec3 dxy = max( abs( dFdx( nonPerturbedNormal ) ), abs( dFdy( nonPerturbedNormal ) ) );
float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );

@@ -8,0 +8,0 @@

@@ -436,7 +436,7 @@ export default /* glsl */`

void RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {
void RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {
vec3 normal = geometry.normal;
vec3 viewDir = geometry.viewDir;
vec3 position = geometry.position;
vec3 normal = geometryNormal;
vec3 viewDir = geometryViewDir;
vec3 position = geometryPosition;
vec3 lightPos = rectAreaLight.position;

@@ -477,5 +477,5 @@ vec3 halfWidth = rectAreaLight.halfWidth;

void RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {
void RE_Direct_Physical( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {
float dotNL = saturate( dot( geometry.normal, directLight.direction ) );
float dotNL = saturate( dot( geometryNormal, directLight.direction ) );

@@ -486,7 +486,7 @@ vec3 irradiance = dotNL * directLight.color;

float dotNLcc = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );
float dotNLcc = saturate( dot( geometryClearcoatNormal, directLight.direction ) );
vec3 ccIrradiance = dotNLcc * directLight.color;
clearcoatSpecular += ccIrradiance * BRDF_GGX_Clearcoat( directLight.direction, geometry.viewDir, geometry.clearcoatNormal, material );
clearcoatSpecular += ccIrradiance * BRDF_GGX_Clearcoat( directLight.direction, geometryViewDir, geometryClearcoatNormal, material );

@@ -497,7 +497,7 @@ #endif

sheenSpecular += irradiance * BRDF_Sheen( directLight.direction, geometry.viewDir, geometry.normal, material.sheenColor, material.sheenRoughness );
sheenSpecular += irradiance * BRDF_Sheen( directLight.direction, geometryViewDir, geometryNormal, material.sheenColor, material.sheenRoughness );
#endif
reflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.normal, material );
reflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometryViewDir, geometryNormal, material );

@@ -507,3 +507,3 @@ reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );

void RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {
void RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {

@@ -514,7 +514,7 @@ reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );

void RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {
void RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {
#ifdef USE_CLEARCOAT
clearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometry.clearcoatNormal, geometry.viewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );
clearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometryClearcoatNormal, geometryViewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );

@@ -525,3 +525,3 @@ #endif

sheenSpecular += irradiance * material.sheenColor * IBLSheenBRDF( geometry.normal, geometry.viewDir, material.sheenRoughness );
sheenSpecular += irradiance * material.sheenColor * IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );

@@ -538,7 +538,7 @@ #endif

computeMultiscatteringIridescence( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering );
computeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering );
#else
computeMultiscattering( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );
computeMultiscattering( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );

@@ -545,0 +545,0 @@ #endif

@@ -10,5 +10,5 @@ export default /* glsl */`

void RE_Direct_Toon( const in IncidentLight directLight, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {
void RE_Direct_Toon( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {
vec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;
vec3 irradiance = getGradientIrradiance( geometryNormal, directLight.direction ) * directLight.color;

@@ -19,3 +19,3 @@ reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );

void RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {
void RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {

@@ -22,0 +22,0 @@ reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );

@@ -74,4 +74,4 @@ export default /* glsl */`

vec3 geometryNormal = normal;
vec3 nonPerturbedNormal = normal;
`;

@@ -206,3 +206,3 @@ export const vertex = /* glsl */`

float dotNVcc = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );
float dotNVcc = saturate( dot( geometryClearcoatNormal, geometryViewDir ) );

@@ -209,0 +209,0 @@ vec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );

@@ -1,2 +0,2 @@

import { LinearSRGBColorSpace } from '../../constants.js';
import { ColorManagement } from '../../math/ColorManagement.js';

@@ -96,3 +96,3 @@ /**

return LinearSRGBColorSpace;
return ColorManagement.workingColorSpace;

@@ -99,0 +99,0 @@ }

@@ -1,2 +0,2 @@

import { BackSide, FrontSide, CubeUVReflectionMapping, SRGBColorSpace } from '../../constants.js';
import { BackSide, FrontSide, CubeUVReflectionMapping, SRGBTransfer } from '../../constants.js';
import { BoxGeometry } from '../../geometries/BoxGeometry.js';

@@ -6,2 +6,3 @@ import { PlaneGeometry } from '../../geometries/PlaneGeometry.js';

import { Color } from '../../math/Color.js';
import { ColorManagement } from '../../math/ColorManagement.js';
import { Mesh } from '../../objects/Mesh.js';

@@ -112,3 +113,3 @@ import { ShaderLib } from '../shaders/ShaderLib.js';

boxMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity;
boxMesh.material.toneMapped = ( background.colorSpace === SRGBColorSpace ) ? false : true;
boxMesh.material.toneMapped = ColorManagement.getTransfer( background.colorSpace ) !== SRGBTransfer;

@@ -169,3 +170,3 @@ if ( currentBackground !== background ||

planeMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity;
planeMesh.material.toneMapped = ( background.colorSpace === SRGBColorSpace ) ? false : true;
planeMesh.material.toneMapped = ColorManagement.getTransfer( background.colorSpace ) !== SRGBTransfer;

@@ -172,0 +173,0 @@ if ( background.matrixAutoUpdate === true ) {

@@ -173,3 +173,5 @@ import { Color } from '../../math/Color.js';

numSpotShadows: - 1,
numSpotMaps: - 1
numSpotMaps: - 1,
numLightProbes: - 1
},

@@ -196,3 +198,4 @@

hemi: [],
numSpotLightShadowsWithMaps: 0
numSpotLightShadowsWithMaps: 0,
numLightProbes: 0

@@ -225,2 +228,4 @@ };

let numLightProbes = 0;
// ordering : [shadow casting + map texturing, map texturing, shadow casting, none ]

@@ -256,2 +261,4 @@ lights.sort( shadowCastingAndTexturingLightsFirst );

numLightProbes ++;
} else if ( light.isDirectionalLight ) {

@@ -444,3 +451,4 @@

hash.numSpotShadows !== numSpotShadows ||
hash.numSpotMaps !== numSpotMaps ) {
hash.numSpotMaps !== numSpotMaps ||
hash.numLightProbes !== numLightProbes ) {

@@ -464,2 +472,3 @@ state.directional.length = directionalLength;

state.numSpotLightShadowsWithMaps = numSpotShadowsWithMaps;
state.numLightProbes = numLightProbes;

@@ -477,2 +486,4 @@ hash.directionalLength = directionalLength;

hash.numLightProbes = numLightProbes;
state.version = nextVersion ++;

@@ -479,0 +490,0 @@

import { WebGLUniforms } from './WebGLUniforms.js';
import { WebGLShader } from './WebGLShader.js';
import { ShaderChunk } from '../shaders/ShaderChunk.js';
import { NoToneMapping, AddOperation, MixOperation, MultiplyOperation, CubeRefractionMapping, CubeUVReflectionMapping, CubeReflectionMapping, PCFSoftShadowMap, PCFShadowMap, VSMShadowMap, ACESFilmicToneMapping, CineonToneMapping, CustomToneMapping, ReinhardToneMapping, LinearToneMapping, GLSL3, LinearSRGBColorSpace, SRGBColorSpace } from '../../constants.js';
import { NoToneMapping, AddOperation, MixOperation, MultiplyOperation, CubeRefractionMapping, CubeUVReflectionMapping, CubeReflectionMapping, PCFSoftShadowMap, PCFShadowMap, VSMShadowMap, ACESFilmicToneMapping, CineonToneMapping, CustomToneMapping, ReinhardToneMapping, LinearToneMapping, GLSL3, LinearSRGBColorSpace, SRGBColorSpace, LinearDisplayP3ColorSpace, DisplayP3ColorSpace, P3Primaries, Rec709Primaries } from '../../constants.js';
import { ColorManagement } from '../../math/ColorManagement.js';

@@ -29,11 +30,34 @@ let programIdCount = 0;

const workingPrimaries = ColorManagement.getPrimaries( ColorManagement.workingColorSpace );
const encodingPrimaries = ColorManagement.getPrimaries( colorSpace );
let gamutMapping;
if ( workingPrimaries === encodingPrimaries ) {
gamutMapping = '';
} else if ( workingPrimaries === P3Primaries && encodingPrimaries === Rec709Primaries ) {
gamutMapping = 'LinearDisplayP3ToLinearSRGB';
} else if ( workingPrimaries === Rec709Primaries && encodingPrimaries === P3Primaries ) {
gamutMapping = 'LinearSRGBToLinearDisplayP3';
}
switch ( colorSpace ) {
case LinearSRGBColorSpace:
return [ 'Linear', '( value )' ];
case LinearDisplayP3ColorSpace:
return [ gamutMapping, 'LinearTransferOETF' ];
case SRGBColorSpace:
return [ 'sRGB', '( value )' ];
case DisplayP3ColorSpace:
return [ gamutMapping, 'sRGBTransferOETF' ];
default:
console.warn( 'THREE.WebGLProgram: Unsupported color space:', colorSpace );
return [ 'Linear', '( value )' ];
return [ gamutMapping, 'LinearTransferOETF' ];

@@ -71,3 +95,3 @@ }

const components = getEncodingComponents( colorSpace );
return 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[ 0 ] + components[ 1 ] + '; }';
return `vec4 ${functionName}( vec4 value ) { return ${components[ 0 ]}( ${components[ 1 ]}( value ) ); }`;

@@ -499,2 +523,3 @@ }

parameters.anisotropy ? '#define USE_ANISOTROPY' : '',
parameters.anisotropyMap ? '#define USE_ANISOTROPYMAP' : '',

@@ -587,2 +612,4 @@

parameters.numLightProbes > 0 ? '#define USE_LIGHT_PROBES' : '',
parameters.useLegacyLights ? '#define LEGACY_LIGHTS' : '',

@@ -770,2 +797,4 @@

parameters.numLightProbes > 0 ? '#define USE_LIGHT_PROBES' : '',
parameters.useLegacyLights ? '#define LEGACY_LIGHTS' : '',

@@ -772,0 +801,0 @@

@@ -1,2 +0,2 @@

import { BackSide, DoubleSide, CubeUVReflectionMapping, ObjectSpaceNormalMap, TangentSpaceNormalMap, NoToneMapping, NormalBlending, LinearSRGBColorSpace, SRGBColorSpace } from '../../constants.js';
import { BackSide, DoubleSide, CubeUVReflectionMapping, ObjectSpaceNormalMap, TangentSpaceNormalMap, NoToneMapping, NormalBlending, LinearSRGBColorSpace, SRGBTransfer } from '../../constants.js';
import { Layers } from '../../core/Layers.js';

@@ -7,2 +7,3 @@ import { WebGLProgram } from './WebGLProgram.js';

import { UniformsUtils } from '../shaders/UniformsUtils.js';
import { ColorManagement } from '../../math/ColorManagement.js';

@@ -328,2 +329,4 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping ) {

numLightProbes: lights.numLightProbes,
numClippingPlanes: clipping.numPlanes,

@@ -340,3 +343,3 @@ numClipIntersection: clipping.numIntersection,

decodeVideoTexture: HAS_MAP && ( material.map.isVideoTexture === true ) && ( material.map.colorSpace === SRGBColorSpace ),
decodeVideoTexture: HAS_MAP && ( material.map.isVideoTexture === true ) && ( ColorManagement.getTransfer( material.map.colorSpace ) === SRGBTransfer ),

@@ -454,2 +457,3 @@ premultipliedAlpha: material.premultipliedAlpha,

array.push( parameters.numSpotLightShadowsWithMaps );
array.push( parameters.numLightProbes );
array.push( parameters.shadowMapType );

@@ -456,0 +460,0 @@ array.push( parameters.toneMapping );

@@ -1,5 +0,6 @@

import { LinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, NearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, RGBAFormat, DepthFormat, DepthStencilFormat, UnsignedShortType, UnsignedIntType, UnsignedInt248Type, FloatType, HalfFloatType, MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, UnsignedByteType, _SRGBAFormat, NoColorSpace, LinearSRGBColorSpace, SRGBColorSpace, NeverCompare, AlwaysCompare, LessCompare, LessEqualCompare, EqualCompare, GreaterEqualCompare, GreaterCompare, NotEqualCompare, DisplayP3ColorSpace } from '../../constants.js';
import { LinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, NearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, RGBAFormat, DepthFormat, DepthStencilFormat, UnsignedShortType, UnsignedIntType, UnsignedInt248Type, FloatType, HalfFloatType, MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, UnsignedByteType, _SRGBAFormat, NoColorSpace, LinearSRGBColorSpace, NeverCompare, AlwaysCompare, LessCompare, LessEqualCompare, EqualCompare, GreaterEqualCompare, GreaterCompare, NotEqualCompare, SRGBTransfer, LinearTransfer } from '../../constants.js';
import * as MathUtils from '../../math/MathUtils.js';
import { ImageUtils } from '../../extras/ImageUtils.js';
import { createElementNS } from '../../utils.js';
import { ColorManagement } from '../../math/ColorManagement.js';

@@ -181,5 +182,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) {

const transfer = forceLinearTransfer ? LinearTransfer : ColorManagement.getTransfer( colorSpace );
if ( glType === _gl.FLOAT ) internalFormat = _gl.RGBA32F;
if ( glType === _gl.HALF_FLOAT ) internalFormat = _gl.RGBA16F;
if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = ( colorSpace === SRGBColorSpace && forceLinearTransfer === false ) ? _gl.SRGB8_ALPHA8 : _gl.RGBA8;
if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = ( transfer === SRGBTransfer ) ? _gl.SRGB8_ALPHA8 : _gl.RGBA8;
if ( glType === _gl.UNSIGNED_SHORT_4_4_4_4 ) internalFormat = _gl.RGBA4;

@@ -739,6 +742,10 @@ if ( glType === _gl.UNSIGNED_SHORT_5_5_5_1 ) internalFormat = _gl.RGB5_A1;

const workingPrimaries = ColorManagement.getPrimaries( ColorManagement.workingColorSpace );
const texturePrimaries = texture.colorSpace === NoColorSpace ? null : ColorManagement.getPrimaries( texture.colorSpace );
const unpackConversion = texture.colorSpace === NoColorSpace || workingPrimaries === texturePrimaries ? _gl.NONE : _gl.BROWSER_DEFAULT_WEBGL;
_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
_gl.pixelStorei( _gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, _gl.NONE );
_gl.pixelStorei( _gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, unpackConversion );

@@ -1154,6 +1161,10 @@ const needsPowerOfTwo = textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( texture.image ) === false;

const workingPrimaries = ColorManagement.getPrimaries( ColorManagement.workingColorSpace );
const texturePrimaries = texture.colorSpace === NoColorSpace ? null : ColorManagement.getPrimaries( texture.colorSpace );
const unpackConversion = texture.colorSpace === NoColorSpace || workingPrimaries === texturePrimaries ? _gl.NONE : _gl.BROWSER_DEFAULT_WEBGL;
_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
_gl.pixelStorei( _gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, _gl.NONE );
_gl.pixelStorei( _gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, unpackConversion );

@@ -1398,3 +1409,3 @@ const isCompressed = ( texture.isCompressedTexture || texture.image[ 0 ].isCompressedTexture );

let glInternalFormat = _gl.DEPTH_COMPONENT16;
let glInternalFormat = ( isWebGL2 === true ) ? _gl.DEPTH_COMPONENT24 : _gl.DEPTH_COMPONENT16;

@@ -2040,3 +2051,3 @@ if ( isMultisample || useMultisampledRTT( renderTarget ) ) {

if ( colorSpace === SRGBColorSpace || colorSpace === DisplayP3ColorSpace ) {
if ( ColorManagement.getTransfer( colorSpace ) === SRGBTransfer ) {

@@ -2043,0 +2054,0 @@ if ( isWebGL2 === false ) {

@@ -1,6 +0,4 @@

import { RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_10x10_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT5_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT1_Format, RGB_S3TC_DXT1_Format, DepthFormat, DepthStencilFormat, LuminanceAlphaFormat, LuminanceFormat, RedFormat, RGBAFormat, AlphaFormat, RedIntegerFormat, RGFormat, RGIntegerFormat, RGBAIntegerFormat, HalfFloatType, FloatType, UnsignedIntType, IntType, UnsignedShortType, ShortType, ByteType, UnsignedInt248Type, UnsignedShort5551Type, UnsignedShort4444Type, UnsignedByteType, RGBA_BPTC_Format, RGB_BPTC_SIGNED_Format, RGB_BPTC_UNSIGNED_Format, _SRGBAFormat, RED_RGTC1_Format, SIGNED_RED_RGTC1_Format, RED_GREEN_RGTC2_Format, SIGNED_RED_GREEN_RGTC2_Format, SRGBColorSpace, NoColorSpace, DisplayP3ColorSpace } from '../../constants.js';
import { RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_10x10_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT5_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT1_Format, RGB_S3TC_DXT1_Format, DepthFormat, DepthStencilFormat, LuminanceAlphaFormat, LuminanceFormat, RedFormat, RGBAFormat, AlphaFormat, RedIntegerFormat, RGFormat, RGIntegerFormat, RGBAIntegerFormat, HalfFloatType, FloatType, UnsignedIntType, IntType, UnsignedShortType, ShortType, ByteType, UnsignedInt248Type, UnsignedShort5551Type, UnsignedShort4444Type, UnsignedByteType, RGBA_BPTC_Format, RGB_BPTC_SIGNED_Format, RGB_BPTC_UNSIGNED_Format, _SRGBAFormat, RED_RGTC1_Format, SIGNED_RED_RGTC1_Format, RED_GREEN_RGTC2_Format, SIGNED_RED_GREEN_RGTC2_Format, NoColorSpace, SRGBTransfer } from '../../constants.js';
import { ColorManagement } from '../../math/ColorManagement.js';
const LinearTransferFunction = 0;
const SRGBTransferFunction = 1;
function WebGLUtils( gl, extensions, capabilities ) {

@@ -14,3 +12,3 @@

const transferFunction = ( colorSpace === SRGBColorSpace || colorSpace === DisplayP3ColorSpace ) ? SRGBTransferFunction : LinearTransferFunction;
const transfer = ColorManagement.getTransfer( colorSpace );

@@ -83,3 +81,3 @@ if ( p === UnsignedByteType ) return gl.UNSIGNED_BYTE;

if ( transferFunction === SRGBTransferFunction ) {
if ( transfer === SRGBTransfer ) {

@@ -169,4 +167,4 @@ extension = extensions.get( 'WEBGL_compressed_texture_s3tc_srgb' );

if ( p === RGB_ETC2_Format ) return ( transferFunction === SRGBTransferFunction ) ? extension.COMPRESSED_SRGB8_ETC2 : extension.COMPRESSED_RGB8_ETC2;
if ( p === RGBA_ETC2_EAC_Format ) return ( transferFunction === SRGBTransferFunction ) ? extension.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : extension.COMPRESSED_RGBA8_ETC2_EAC;
if ( p === RGB_ETC2_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ETC2 : extension.COMPRESSED_RGB8_ETC2;
if ( p === RGBA_ETC2_EAC_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : extension.COMPRESSED_RGBA8_ETC2_EAC;

@@ -193,16 +191,16 @@ } else {

if ( p === RGBA_ASTC_4x4_Format ) return ( transferFunction === SRGBTransferFunction ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : extension.COMPRESSED_RGBA_ASTC_4x4_KHR;
if ( p === RGBA_ASTC_5x4_Format ) return ( transferFunction === SRGBTransferFunction ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : extension.COMPRESSED_RGBA_ASTC_5x4_KHR;
if ( p === RGBA_ASTC_5x5_Format ) return ( transferFunction === SRGBTransferFunction ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : extension.COMPRESSED_RGBA_ASTC_5x5_KHR;
if ( p === RGBA_ASTC_6x5_Format ) return ( transferFunction === SRGBTransferFunction ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : extension.COMPRESSED_RGBA_ASTC_6x5_KHR;
if ( p === RGBA_ASTC_6x6_Format ) return ( transferFunction === SRGBTransferFunction ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : extension.COMPRESSED_RGBA_ASTC_6x6_KHR;
if ( p === RGBA_ASTC_8x5_Format ) return ( transferFunction === SRGBTransferFunction ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : extension.COMPRESSED_RGBA_ASTC_8x5_KHR;
if ( p === RGBA_ASTC_8x6_Format ) return ( transferFunction === SRGBTransferFunction ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : extension.COMPRESSED_RGBA_ASTC_8x6_KHR;
if ( p === RGBA_ASTC_8x8_Format ) return ( transferFunction === SRGBTransferFunction ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : extension.COMPRESSED_RGBA_ASTC_8x8_KHR;
if ( p === RGBA_ASTC_10x5_Format ) return ( transferFunction === SRGBTransferFunction ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : extension.COMPRESSED_RGBA_ASTC_10x5_KHR;
if ( p === RGBA_ASTC_10x6_Format ) return ( transferFunction === SRGBTransferFunction ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : extension.COMPRESSED_RGBA_ASTC_10x6_KHR;
if ( p === RGBA_ASTC_10x8_Format ) return ( transferFunction === SRGBTransferFunction ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : extension.COMPRESSED_RGBA_ASTC_10x8_KHR;
if ( p === RGBA_ASTC_10x10_Format ) return ( transferFunction === SRGBTransferFunction ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : extension.COMPRESSED_RGBA_ASTC_10x10_KHR;
if ( p === RGBA_ASTC_12x10_Format ) return ( transferFunction === SRGBTransferFunction ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : extension.COMPRESSED_RGBA_ASTC_12x10_KHR;
if ( p === RGBA_ASTC_12x12_Format ) return ( transferFunction === SRGBTransferFunction ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : extension.COMPRESSED_RGBA_ASTC_12x12_KHR;
if ( p === RGBA_ASTC_4x4_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : extension.COMPRESSED_RGBA_ASTC_4x4_KHR;
if ( p === RGBA_ASTC_5x4_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : extension.COMPRESSED_RGBA_ASTC_5x4_KHR;
if ( p === RGBA_ASTC_5x5_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : extension.COMPRESSED_RGBA_ASTC_5x5_KHR;
if ( p === RGBA_ASTC_6x5_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : extension.COMPRESSED_RGBA_ASTC_6x5_KHR;
if ( p === RGBA_ASTC_6x6_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : extension.COMPRESSED_RGBA_ASTC_6x6_KHR;
if ( p === RGBA_ASTC_8x5_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : extension.COMPRESSED_RGBA_ASTC_8x5_KHR;
if ( p === RGBA_ASTC_8x6_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : extension.COMPRESSED_RGBA_ASTC_8x6_KHR;
if ( p === RGBA_ASTC_8x8_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : extension.COMPRESSED_RGBA_ASTC_8x8_KHR;
if ( p === RGBA_ASTC_10x5_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : extension.COMPRESSED_RGBA_ASTC_10x5_KHR;
if ( p === RGBA_ASTC_10x6_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : extension.COMPRESSED_RGBA_ASTC_10x6_KHR;
if ( p === RGBA_ASTC_10x8_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : extension.COMPRESSED_RGBA_ASTC_10x8_KHR;
if ( p === RGBA_ASTC_10x10_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : extension.COMPRESSED_RGBA_ASTC_10x10_KHR;
if ( p === RGBA_ASTC_12x10_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : extension.COMPRESSED_RGBA_ASTC_12x10_KHR;
if ( p === RGBA_ASTC_12x12_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : extension.COMPRESSED_RGBA_ASTC_12x12_KHR;

@@ -225,3 +223,3 @@ } else {

if ( p === RGBA_BPTC_Format ) return ( transferFunction === SRGBTransferFunction ) ? extension.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT : extension.COMPRESSED_RGBA_BPTC_UNORM_EXT;
if ( p === RGBA_BPTC_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT : extension.COMPRESSED_RGBA_BPTC_UNORM_EXT;
if ( p === RGB_BPTC_SIGNED_Format ) return extension.COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT;

@@ -228,0 +226,0 @@ if ( p === RGB_BPTC_UNSIGNED_Format ) return extension.COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT;

@@ -28,2 +28,3 @@ import { Color } from '../math/Color.js';

type: 'Fog',
name: this.name,
color: this.color.getHex(),

@@ -30,0 +31,0 @@ near: this.near,

@@ -26,2 +26,3 @@ import { Color } from '../math/Color.js';

type: 'FogExp2',
name: this.name,
color: this.color.getHex(),

@@ -28,0 +29,0 @@ density: this.density

import { ImageUtils } from '../extras/ImageUtils.js';
import * as MathUtils from '../math/MathUtils.js';
let sourceId = 0;
let _sourceId = 0;

@@ -12,3 +12,3 @@ class Source {

Object.defineProperty( this, 'id', { value: sourceId ++ } );
Object.defineProperty( this, 'id', { value: _sourceId ++ } );

@@ -15,0 +15,0 @@ this.uuid = MathUtils.generateUUID();

@@ -64,6 +64,4 @@ import { REVISION } from './constants.js';

export { HemisphereLight } from './lights/HemisphereLight.js';
export { HemisphereLightProbe } from './lights/HemisphereLightProbe.js';
export { DirectionalLight } from './lights/DirectionalLight.js';
export { AmbientLight } from './lights/AmbientLight.js';
export { AmbientLightProbe } from './lights/AmbientLightProbe.js';
export { Light } from './lights/Light.js';

@@ -70,0 +68,0 @@ export { LightProbe } from './lights/LightProbe.js';

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc