three
Advanced tools
Comparing version 0.135.0 to 0.136.0
@@ -148,3 +148,2 @@ ( function () { | ||
angle = math.acos( angle ); // skip if changing angle is too small to prevent vibration of bone | ||
// Refer to http://www20.atpages.jp/katwat/three.js_r58/examples/mytest37/mmd.three.js | ||
@@ -151,0 +150,0 @@ if ( angle < 1e-5 ) continue; |
@@ -1089,3 +1089,2 @@ ( function () { | ||
// this parameter is from http://www20.atpages.jp/katwat/three.js_r58/examples/mytest37/mmd.three.js | ||
constraint.setParam( 2, 0.475, i ); | ||
@@ -1225,5 +1224,4 @@ | ||
} // copy from http://www20.atpages.jp/katwat/three.js_r58/examples/mytest37/mytest37.js?ver=20160815 | ||
} | ||
function createCapsuleGeometry( radius, cylinderHeight, segmentsRadius, segmentsHeight ) { | ||
@@ -1230,0 +1228,0 @@ |
@@ -535,2 +535,19 @@ ( function () { | ||
reset() { | ||
if ( ! this.enabled ) return; | ||
if ( this.dragging ) { | ||
this.object.position.copy( this._positionStart ); | ||
this.object.quaternion.copy( this._quaternionStart ); | ||
this.object.scale.copy( this._scaleStart ); | ||
this.dispatchEvent( _changeEvent ); | ||
this.dispatchEvent( _objectChangeEvent ); | ||
this.pointStart.copy( this.pointEnd ); | ||
} | ||
} | ||
getRaycaster() { | ||
@@ -636,3 +653,9 @@ | ||
if ( ! this.enabled ) return; | ||
this.domElement.setPointerCapture( event.pointerId ); | ||
if ( ! document.pointerLockElement ) { | ||
this.domElement.setPointerCapture( event.pointerId ); | ||
} | ||
this.domElement.addEventListener( 'pointermove', this._onPointerMove ); | ||
@@ -639,0 +662,0 @@ this.pointerHover( this._getPointer( event ) ); |
@@ -8,5 +8,3 @@ ( function () { | ||
* http://mathworld.wolfram.com/HeartCurve.html | ||
* http://mathdl.maa.org/images/upload_library/23/stemkoski/knots/page6.html | ||
* http://en.wikipedia.org/wiki/Viviani%27s_curve | ||
* http://mathdl.maa.org/images/upload_library/23/stemkoski/knots/page4.html | ||
* http://www.mi.sanu.ac.rs/vismath/taylorapril2011/Taylor.pdf | ||
@@ -13,0 +11,0 @@ * https://prideout.net/blog/old/blog/index.html@p=44.html |
( function () { | ||
/** | ||
* Ascii generation is based on http://www.nihilogic.dk/labs/jsascii/ | ||
* Maybe more about this later with a blog post at http://lab4games.net/zz85/blog | ||
* Ascii generation is based on https://github.com/hassadee/jsascii/blob/master/jsascii.js | ||
* | ||
@@ -53,10 +52,4 @@ * 16 April 2012 - @blurspline | ||
this.domElement = domElement; // Throw in ascii library from http://www.nihilogic.dk/labs/jsascii/jsascii.js | ||
this.domElement = domElement; // Throw in ascii library from https://github.com/hassadee/jsascii/blob/master/jsascii.js (MIT License) | ||
/* | ||
* jsAscii 0.1 | ||
* Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/ | ||
* MIT License [http://www.nihilogic.dk/licenses/mit-license.txt] | ||
*/ | ||
function initAsciiSize() { | ||
@@ -63,0 +56,0 @@ |
@@ -2037,3 +2037,3 @@ ( function () { | ||
* | ||
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness | ||
* Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness | ||
*/ | ||
@@ -2040,0 +2040,0 @@ |
@@ -45,3 +45,2 @@ ( function () { | ||
* Created for the Udacity course "Interactive Rendering", http://bit.ly/ericity | ||
* Lesson: https://www.udacity.com/course/viewer#!/c-cs291/l-68866048/m-106482448 | ||
* YouTube video on teapot history: https://www.youtube.com/watch?v=DxMfblPzFNc | ||
@@ -48,0 +47,0 @@ * |
@@ -218,2 +218,4 @@ ( function () { | ||
_center.applyMatrix4( object.matrixWorld ); | ||
if ( frustum.containsPoint( _center ) ) { | ||
@@ -220,0 +222,0 @@ |
@@ -15,10 +15,12 @@ ( function () { | ||
this.isDown = false; | ||
this.renderer.domElement.addEventListener( 'pointerdown', function ( event ) { | ||
this.onPointerDown = function ( event ) { | ||
this.isDown = true; | ||
this.onSelectStart( event ); | ||
}.bind( this ) ); | ||
this.renderer.domElement.addEventListener( 'pointermove', function ( event ) { | ||
}.bind( this ); | ||
this.onPointerMove = function ( event ) { | ||
if ( this.isDown ) { | ||
@@ -30,12 +32,25 @@ | ||
}.bind( this ) ); | ||
this.renderer.domElement.addEventListener( 'pointerup', function ( event ) { | ||
}.bind( this ); | ||
this.onPointerUp = function () { | ||
this.isDown = false; | ||
this.onSelectOver( event ); | ||
this.onSelectOver(); | ||
}.bind( this ) ); | ||
}.bind( this ); | ||
this.renderer.domElement.addEventListener( 'pointerdown', this.onPointerDown ); | ||
this.renderer.domElement.addEventListener( 'pointermove', this.onPointerMove ); | ||
this.renderer.domElement.addEventListener( 'pointerup', this.onPointerUp ); | ||
} | ||
dispose() { | ||
this.renderer.domElement.removeEventListener( 'pointerdown', this.onPointerDown ); | ||
this.renderer.domElement.removeEventListener( 'pointermove', this.onPointerMove ); | ||
this.renderer.domElement.removeEventListener( 'pointerup', this.onPointerUp ); | ||
} | ||
onSelectStart( event ) { | ||
@@ -42,0 +57,0 @@ |
@@ -7,4 +7,2 @@ ( function () { | ||
* | ||
* More information about the AMF format: http://amf.wikispaces.com | ||
* | ||
* Usage: | ||
@@ -11,0 +9,0 @@ * const loader = new AMFLoader(); |
@@ -109,36 +109,3 @@ ( function () { | ||
const logBase = Math.pow( 2.7182818, 2.2 ); | ||
var tmpDataView = new DataView( new ArrayBuffer( 8 ) ); | ||
function frexp( value ) { | ||
if ( value === 0 ) return [ value, 0 ]; | ||
tmpDataView.setFloat64( 0, value ); | ||
var bits = tmpDataView.getUint32( 0 ) >>> 20 & 0x7FF; | ||
if ( bits === 0 ) { | ||
// denormal | ||
tmpDataView.setFloat64( 0, value * Math.pow( 2, 64 ) ); // exp + 64 | ||
bits = ( tmpDataView.getUint32( 0 ) >>> 20 & 0x7FF ) - 64; | ||
} | ||
var exponent = bits - 1022; | ||
var mantissa = ldexp( value, - exponent ); | ||
return [ mantissa, exponent ]; | ||
} | ||
function ldexp( mantissa, exponent ) { | ||
var steps = Math.min( 3, Math.ceil( Math.abs( exponent ) / 1023 ) ); | ||
var result = mantissa; | ||
for ( var i = 0; i < steps; i ++ ) result *= Math.pow( 2, Math.floor( ( exponent + i ) / steps ) ); | ||
return result; | ||
} | ||
function reverseLutFromBitmap( bitmap, lut ) { | ||
@@ -1211,4 +1178,3 @@ | ||
}; | ||
var tmpBufSize = info.width * scanlineBlockSize * ( EXRHeader.channels.length * info.type ); | ||
var outBuffer = new Uint16Array( tmpBufSize ); | ||
var outBuffer = new Uint16Array( info.width * info.scanlineBlockSize * ( info.channels * info.type ) ); | ||
var bitmap = new Uint8Array( BITMAP_SIZE ); // Setup channel info | ||
@@ -1370,3 +1336,3 @@ | ||
}; | ||
var outBuffer = new Uint8Array( info.width * info.lines * ( EXRHeader.channels.length * info.type * INT16_SIZE ) ); // Read compression header information | ||
var outBuffer = new Uint8Array( info.width * info.lines * ( info.channels * info.type * INT16_SIZE ) ); // Read compression header information | ||
@@ -1598,10 +1564,2 @@ var dwaHeader = { | ||
function parseUlong( dataView, offset ) { | ||
var uLong = dataView.getUint32( 0, true ); | ||
offset.value = offset.value + ULONG_SIZE; | ||
return uLong; | ||
} | ||
function parseRational( dataView, offset ) { | ||
@@ -1864,40 +1822,45 @@ | ||
var bufferDataView = new DataView( buffer ); | ||
var uInt8Array = new Uint8Array( buffer ); | ||
var EXRHeader = {}; | ||
bufferDataView.getUint32( 0, true ); // magic | ||
function parseHeader( dataView, buffer, offset ) { | ||
bufferDataView.getUint8( 4, true ); // versionByteZero | ||
const EXRHeader = {}; | ||
if ( dataView.getUint32( 0, true ) != 20000630 ) // magic | ||
throw 'THREE.EXRLoader: provided file doesn\'t appear to be in OpenEXR format.'; | ||
EXRHeader.version = dataView.getUint8( 4, true ); | ||
const spec = dataView.getUint8( 5, true ); // fullMask | ||
bufferDataView.getUint8( 5, true ); // fullMask | ||
// start of header | ||
EXRHeader.spec = { | ||
singleTile: !! ( spec & 1 ), | ||
longName: !! ( spec & 2 ), | ||
deepFormat: !! ( spec & 4 ), | ||
multiPart: !! ( spec & 8 ) | ||
}; // start of header | ||
var offset = { | ||
value: 8 | ||
}; // start at 8, after magic stuff | ||
offset.value = 8; // start at 8 - after pre-amble | ||
var keepReading = true; | ||
var keepReading = true; | ||
while ( keepReading ) { | ||
while ( keepReading ) { | ||
var attributeName = parseNullTerminatedString( buffer, offset ); | ||
var attributeName = parseNullTerminatedString( buffer, offset ); | ||
if ( attributeName == 0 ) { | ||
if ( attributeName == 0 ) { | ||
keepReading = false; | ||
keepReading = false; | ||
} else { | ||
} else { | ||
var attributeType = parseNullTerminatedString( buffer, offset ); | ||
var attributeSize = parseUint32( bufferDataView, offset ); | ||
var attributeValue = parseValue( bufferDataView, buffer, offset, attributeType, attributeSize ); | ||
var attributeType = parseNullTerminatedString( buffer, offset ); | ||
var attributeSize = parseUint32( dataView, offset ); | ||
var attributeValue = parseValue( dataView, buffer, offset, attributeType, attributeSize ); | ||
if ( attributeValue === undefined ) { | ||
if ( attributeValue === undefined ) { | ||
console.warn( `EXRLoader.parse: skipped unknown header attribute type \'${attributeType}\'.` ); | ||
console.warn( `EXRLoader.parse: skipped unknown header attribute type \'${attributeType}\'.` ); | ||
} else { | ||
} else { | ||
EXRHeader[ attributeName ] = attributeValue; | ||
EXRHeader[ attributeName ] = attributeValue; | ||
} | ||
} | ||
@@ -1907,237 +1870,215 @@ | ||
} // offsets | ||
if ( spec != 0 ) { | ||
console.error( 'EXRHeader:', EXRHeader ); | ||
throw 'THREE.EXRLoader: provided file is currently unsupported.'; | ||
var dataWindowHeight = EXRHeader.dataWindow.yMax + 1; | ||
var uncompress; | ||
var scanlineBlockSize; | ||
} | ||
switch ( EXRHeader.compression ) { | ||
return EXRHeader; | ||
case 'NO_COMPRESSION': | ||
scanlineBlockSize = 1; | ||
uncompress = uncompressRAW; | ||
break; | ||
case 'RLE_COMPRESSION': | ||
scanlineBlockSize = 1; | ||
uncompress = uncompressRLE; | ||
break; | ||
case 'ZIPS_COMPRESSION': | ||
scanlineBlockSize = 1; | ||
uncompress = uncompressZIP; | ||
break; | ||
case 'ZIP_COMPRESSION': | ||
scanlineBlockSize = 16; | ||
uncompress = uncompressZIP; | ||
break; | ||
case 'PIZ_COMPRESSION': | ||
scanlineBlockSize = 32; | ||
uncompress = uncompressPIZ; | ||
break; | ||
case 'PXR24_COMPRESSION': | ||
scanlineBlockSize = 16; | ||
uncompress = uncompressPXR; | ||
break; | ||
case 'DWAA_COMPRESSION': | ||
scanlineBlockSize = 32; | ||
uncompress = uncompressDWA; | ||
break; | ||
case 'DWAB_COMPRESSION': | ||
scanlineBlockSize = 256; | ||
uncompress = uncompressDWA; | ||
break; | ||
default: | ||
throw 'EXRLoader.parse: ' + EXRHeader.compression + ' is unsupported'; | ||
} | ||
var size_t; | ||
var getValue; // mixed pixelType not supported | ||
function setupDecoder( EXRHeader, dataView, uInt8Array, offset, outputType ) { | ||
var pixelType = EXRHeader.channels[ 0 ].pixelType; | ||
const EXRDecoder = { | ||
size: 0, | ||
viewer: dataView, | ||
array: uInt8Array, | ||
offset: offset, | ||
width: EXRHeader.dataWindow.xMax - EXRHeader.dataWindow.xMin + 1, | ||
height: EXRHeader.dataWindow.yMax - EXRHeader.dataWindow.yMin + 1, | ||
channels: EXRHeader.channels.length, | ||
bytesPerLine: null, | ||
lines: null, | ||
inputSize: null, | ||
type: EXRHeader.channels[ 0 ].pixelType, | ||
uncompress: null, | ||
getter: null, | ||
format: null, | ||
encoding: null | ||
}; | ||
if ( pixelType === 1 ) { | ||
switch ( EXRHeader.compression ) { | ||
// half | ||
switch ( this.type ) { | ||
case 'NO_COMPRESSION': | ||
EXRDecoder.lines = 1; | ||
EXRDecoder.uncompress = uncompressRAW; | ||
break; | ||
case THREE.UnsignedByteType: | ||
case THREE.FloatType: | ||
getValue = parseFloat16; | ||
size_t = INT16_SIZE; | ||
case 'RLE_COMPRESSION': | ||
EXRDecoder.lines = 1; | ||
EXRDecoder.uncompress = uncompressRLE; | ||
break; | ||
case THREE.HalfFloatType: | ||
getValue = parseUint16; | ||
size_t = INT16_SIZE; | ||
case 'ZIPS_COMPRESSION': | ||
EXRDecoder.lines = 1; | ||
EXRDecoder.uncompress = uncompressZIP; | ||
break; | ||
} | ||
case 'ZIP_COMPRESSION': | ||
EXRDecoder.lines = 16; | ||
EXRDecoder.uncompress = uncompressZIP; | ||
break; | ||
} else if ( pixelType === 2 ) { | ||
case 'PIZ_COMPRESSION': | ||
EXRDecoder.lines = 32; | ||
EXRDecoder.uncompress = uncompressPIZ; | ||
break; | ||
// float | ||
switch ( this.type ) { | ||
case 'PXR24_COMPRESSION': | ||
EXRDecoder.lines = 16; | ||
EXRDecoder.uncompress = uncompressPXR; | ||
break; | ||
case THREE.UnsignedByteType: | ||
case THREE.FloatType: | ||
getValue = parseFloat32; | ||
size_t = FLOAT32_SIZE; | ||
case 'DWAA_COMPRESSION': | ||
EXRDecoder.lines = 32; | ||
EXRDecoder.uncompress = uncompressDWA; | ||
break; | ||
case THREE.HalfFloatType: | ||
getValue = decodeFloat32; | ||
size_t = FLOAT32_SIZE; | ||
case 'DWAB_COMPRESSION': | ||
EXRDecoder.lines = 256; | ||
EXRDecoder.uncompress = uncompressDWA; | ||
break; | ||
default: | ||
throw 'EXRLoader.parse: ' + EXRHeader.compression + ' is unsupported'; | ||
} | ||
} else { | ||
EXRDecoder.scanlineBlockSize = EXRDecoder.lines; | ||
throw 'EXRLoader.parse: unsupported pixelType ' + pixelType + ' for ' + EXRHeader.compression + '.'; | ||
if ( EXRDecoder.type == 1 ) { | ||
} | ||
// half | ||
switch ( outputType ) { | ||
var numBlocks = dataWindowHeight / scanlineBlockSize; | ||
case THREE.FloatType: | ||
EXRDecoder.getter = parseFloat16; | ||
EXRDecoder.inputSize = INT16_SIZE; | ||
break; | ||
for ( var i = 0; i < numBlocks; i ++ ) { | ||
case THREE.HalfFloatType: | ||
EXRDecoder.getter = parseUint16; | ||
EXRDecoder.inputSize = INT16_SIZE; | ||
break; | ||
parseUlong( bufferDataView, offset ); // scanlineOffset | ||
} | ||
} // we should be passed the scanline offset table, start reading pixel data | ||
} else if ( EXRDecoder.type == 2 ) { | ||
// float | ||
switch ( outputType ) { | ||
var width = EXRHeader.dataWindow.xMax - EXRHeader.dataWindow.xMin + 1; | ||
var height = EXRHeader.dataWindow.yMax - EXRHeader.dataWindow.yMin + 1; // Firefox only supports RGBA (half) float textures | ||
// var numChannels = EXRHeader.channels.length; | ||
case THREE.FloatType: | ||
EXRDecoder.getter = parseFloat32; | ||
EXRDecoder.inputSize = FLOAT32_SIZE; | ||
break; | ||
var numChannels = 4; | ||
var size = width * height * numChannels; // Fill initially with 1s for the alpha value if the texture is not RGBA, RGB values will be overwritten | ||
case THREE.HalfFloatType: | ||
EXRDecoder.getter = decodeFloat32; | ||
EXRDecoder.inputSize = FLOAT32_SIZE; | ||
switch ( this.type ) { | ||
} | ||
case THREE.UnsignedByteType: | ||
case THREE.FloatType: | ||
var byteArray = new Float32Array( size ); | ||
} else { | ||
if ( EXRHeader.channels.length < numChannels ) { | ||
throw 'EXRLoader.parse: unsupported pixelType ' + EXRDecoder.type + ' for ' + EXRHeader.compression + '.'; | ||
byteArray.fill( 1, 0, size ); | ||
} | ||
} | ||
EXRDecoder.blockCount = ( EXRHeader.dataWindow.yMax + 1 ) / EXRDecoder.scanlineBlockSize; | ||
break; | ||
for ( var i = 0; i < EXRDecoder.blockCount; i ++ ) parseInt64( dataView, offset ); // scanlineOffset | ||
// we should be passed the scanline offset table, ready to start reading pixel data. | ||
// RGB images will be converted to RGBA format, preventing software emulation in select devices. | ||
case THREE.HalfFloatType: | ||
var byteArray = new Uint16Array( size ); | ||
if ( EXRHeader.channels.length < numChannels ) { | ||
EXRDecoder.outputChannels = EXRDecoder.channels == 3 ? 4 : EXRDecoder.channels; | ||
const size = EXRDecoder.width * EXRDecoder.height * EXRDecoder.outputChannels; | ||
byteArray.fill( 0x3C00, 0, size ); // Uint16Array holds half float data, 0x3C00 is 1 | ||
switch ( outputType ) { | ||
} | ||
case THREE.FloatType: | ||
EXRDecoder.byteArray = new Float32Array( size ); // Fill initially with 1s for the alpha value if the texture is not RGBA, RGB values will be overwritten | ||
break; | ||
if ( EXRDecoder.channels < EXRDecoder.outputChannels ) EXRDecoder.byteArray.fill( 1, 0, size ); | ||
break; | ||
default: | ||
console.error( 'THREE.EXRLoader: unsupported type: ', this.type ); | ||
break; | ||
case THREE.HalfFloatType: | ||
EXRDecoder.byteArray = new Uint16Array( size ); | ||
if ( EXRDecoder.channels < EXRDecoder.outputChannels ) EXRDecoder.byteArray.fill( 0x3C00, 0, size ); // Uint16Array holds half float data, 0x3C00 is 1 | ||
} | ||
break; | ||
var channelOffsets = { | ||
R: 0, | ||
G: 1, | ||
B: 2, | ||
A: 3 | ||
}; | ||
var compressionInfo = { | ||
size: 0, | ||
width: width, | ||
lines: scanlineBlockSize, | ||
offset: offset, | ||
array: uInt8Array, | ||
viewer: bufferDataView, | ||
type: pixelType, | ||
channels: EXRHeader.channels.length | ||
}; | ||
var line; | ||
var size; | ||
var viewer; | ||
var tmpOffset = { | ||
value: 0 | ||
}; | ||
default: | ||
console.error( 'THREE.EXRLoader: unsupported type: ', outputType ); | ||
break; | ||
for ( var scanlineBlockIdx = 0; scanlineBlockIdx < height / scanlineBlockSize; scanlineBlockIdx ++ ) { | ||
} | ||
line = parseUint32( bufferDataView, offset ); // line_no | ||
EXRDecoder.bytesPerLine = EXRDecoder.width * EXRDecoder.inputSize * EXRDecoder.channels; | ||
size = parseUint32( bufferDataView, offset ); // data_len | ||
if ( EXRDecoder.outputChannels == 4 ) { | ||
compressionInfo.lines = line + scanlineBlockSize > height ? height - line : scanlineBlockSize; | ||
compressionInfo.offset = offset; | ||
compressionInfo.size = size; | ||
viewer = uncompress( compressionInfo ); | ||
offset.value += size; | ||
EXRDecoder.format = THREE.RGBAFormat; | ||
EXRDecoder.encoding = THREE.LinearEncoding; | ||
for ( var line_y = 0; line_y < scanlineBlockSize; line_y ++ ) { | ||
} else { | ||
var true_y = line_y + scanlineBlockIdx * scanlineBlockSize; | ||
if ( true_y >= height ) break; | ||
EXRDecoder.format = THREE.RedFormat; | ||
EXRDecoder.encoding = THREE.LinearEncoding; | ||
for ( var channelID = 0; channelID < EXRHeader.channels.length; channelID ++ ) { | ||
} | ||
var cOff = channelOffsets[ EXRHeader.channels[ channelID ].name ]; | ||
return EXRDecoder; | ||
for ( var x = 0; x < width; x ++ ) { | ||
} // start parsing file [START] | ||
var idx = line_y * ( EXRHeader.channels.length * width ) + channelID * width + x; | ||
tmpOffset.value = idx * size_t; | ||
var val = getValue( viewer, tmpOffset ); | ||
byteArray[ ( height - 1 - true_y ) * ( width * numChannels ) + x * numChannels + cOff ] = val; | ||
} | ||
const bufferDataView = new DataView( buffer ); | ||
const uInt8Array = new Uint8Array( buffer ); | ||
const offset = { | ||
value: 0 | ||
}; // get header information and validate format. | ||
} | ||
const EXRHeader = parseHeader( bufferDataView, buffer, offset ); // get input compression information and prepare decoding. | ||
} | ||
const EXRDecoder = setupDecoder( EXRHeader, bufferDataView, uInt8Array, offset, this.type ); | ||
const tmpOffset = { | ||
value: 0 | ||
}; | ||
const channelOffsets = { | ||
R: 0, | ||
G: 1, | ||
B: 2, | ||
A: 3, | ||
Y: 0 | ||
}; | ||
} | ||
for ( let scanlineBlockIdx = 0; scanlineBlockIdx < EXRDecoder.height / EXRDecoder.scanlineBlockSize; scanlineBlockIdx ++ ) { | ||
if ( this.type === THREE.UnsignedByteType ) { | ||
const line = parseUint32( bufferDataView, offset ); // line_no | ||
let v, i; | ||
const size = byteArray.length; | ||
const RGBEArray = new Uint8Array( size ); | ||
EXRDecoder.size = parseUint32( bufferDataView, offset ); // data_len | ||
for ( let h = 0; h < height; ++ h ) { | ||
EXRDecoder.lines = line + EXRDecoder.scanlineBlockSize > EXRDecoder.height ? EXRDecoder.height - line : EXRDecoder.scanlineBlockSize; | ||
const isCompressed = EXRDecoder.size < EXRDecoder.lines * EXRDecoder.bytesPerLine; | ||
const viewer = isCompressed ? EXRDecoder.uncompress( EXRDecoder ) : uncompressRAW( EXRDecoder ); | ||
offset.value += EXRDecoder.size; | ||
for ( let w = 0; w < width; ++ w ) { | ||
for ( let line_y = 0; line_y < EXRDecoder.scanlineBlockSize; line_y ++ ) { | ||
i = h * width * 4 + w * 4; | ||
const red = byteArray[ i ]; | ||
const green = byteArray[ i + 1 ]; | ||
const blue = byteArray[ i + 2 ]; | ||
v = red > green ? red : green; | ||
v = blue > v ? blue : v; | ||
const true_y = line_y + scanlineBlockIdx * EXRDecoder.scanlineBlockSize; | ||
if ( true_y >= EXRDecoder.height ) break; | ||
if ( v < 1e-32 ) { | ||
for ( let channelID = 0; channelID < EXRDecoder.channels; channelID ++ ) { | ||
RGBEArray[ i ] = RGBEArray[ i + 1 ] = RGBEArray[ i + 2 ] = RGBEArray[ i + 3 ] = 0; | ||
const cOff = channelOffsets[ EXRHeader.channels[ channelID ].name ]; | ||
} else { | ||
for ( let x = 0; x < EXRDecoder.width; x ++ ) { | ||
const res = frexp( v ); | ||
v = res[ 0 ] * 256 / v; | ||
RGBEArray[ i ] = red * v; | ||
RGBEArray[ i + 1 ] = green * v; | ||
RGBEArray[ i + 2 ] = blue * v; | ||
RGBEArray[ i + 3 ] = res[ 1 ] + 128; | ||
tmpOffset.value = ( line_y * ( EXRDecoder.channels * EXRDecoder.width ) + channelID * EXRDecoder.width + x ) * EXRDecoder.inputSize; | ||
const outIndex = ( EXRDecoder.height - 1 - true_y ) * ( EXRDecoder.width * EXRDecoder.outputChannels ) + x * EXRDecoder.outputChannels + cOff; | ||
EXRDecoder.byteArray[ outIndex ] = EXRDecoder.getter( viewer, tmpOffset ); | ||
@@ -2150,13 +2091,11 @@ } | ||
byteArray = RGBEArray; | ||
} | ||
const format = this.type === THREE.UnsignedByteType ? THREE.RGBEFormat : numChannels === 4 ? THREE.RGBAFormat : THREE.RGBFormat; | ||
return { | ||
header: EXRHeader, | ||
width: width, | ||
height: height, | ||
data: byteArray, | ||
format: format, | ||
width: EXRDecoder.width, | ||
height: EXRDecoder.height, | ||
data: EXRDecoder.byteArray, | ||
format: EXRDecoder.format, | ||
encoding: EXRDecoder.encoding, | ||
type: this.type | ||
@@ -2178,23 +2117,7 @@ }; | ||
switch ( texture.type ) { | ||
case THREE.UnsignedByteType: | ||
texture.encoding = THREE.RGBEEncoding; | ||
texture.minFilter = THREE.NearestFilter; | ||
texture.magFilter = THREE.NearestFilter; | ||
texture.generateMipmaps = false; | ||
texture.flipY = false; | ||
break; | ||
case THREE.FloatType: | ||
case THREE.HalfFloatType: | ||
texture.encoding = THREE.LinearEncoding; | ||
texture.minFilter = THREE.LinearFilter; | ||
texture.magFilter = THREE.LinearFilter; | ||
texture.generateMipmaps = false; | ||
texture.flipY = false; | ||
break; | ||
} | ||
texture.encoding = texData.encoding; | ||
texture.minFilter = THREE.LinearFilter; | ||
texture.magFilter = THREE.LinearFilter; | ||
texture.generateMipmaps = false; | ||
texture.flipY = false; | ||
if ( onLoad ) onLoad( texture, texData ); | ||
@@ -2201,0 +2124,0 @@ |
@@ -31,10 +31,2 @@ ( function () { | ||
case THREE.UnsignedByteType: | ||
texture.encoding = THREE.RGBEEncoding; | ||
texture.format = THREE.RGBAFormat; | ||
texture.minFilter = THREE.NearestFilter; | ||
texture.magFilter = THREE.NearestFilter; | ||
texture.generateMipmaps = false; | ||
break; | ||
case THREE.FloatType: | ||
@@ -41,0 +33,0 @@ texture.encoding = THREE.LinearEncoding; |
@@ -66,2 +66,10 @@ ( function () { | ||
}; | ||
if ( renderer.capabilities.isWebGL2 ) { | ||
// https://github.com/mrdoob/three.js/pull/22928 | ||
this.workerConfig.etc1Supported = false; | ||
} | ||
return this; | ||
@@ -491,4 +499,4 @@ | ||
basisFormat: [ BasisFormat.ETC1S, BasisFormat.UASTC_4x4 ], | ||
transcoderFormat: [ TranscoderFormat.ETC1, TranscoderFormat.ETC1 ], | ||
engineFormat: [ EngineFormat.RGB_ETC1_Format, EngineFormat.RGB_ETC1_Format ], | ||
transcoderFormat: [ TranscoderFormat.ETC1 ], | ||
engineFormat: [ EngineFormat.RGB_ETC1_Format ], | ||
priorityETC1S: 2, | ||
@@ -528,2 +536,3 @@ priorityUASTC: 4, | ||
if ( ! opt.basisFormat.includes( basisFormat ) ) continue; | ||
if ( hasAlpha && opt.transcoderFormat.length < 2 ) continue; | ||
if ( opt.needsPowerOfTwo && ! ( isPowerOfTwo( width ) && isPowerOfTwo( height ) ) ) continue; | ||
@@ -530,0 +539,0 @@ transcoderFormat = opt.transcoderFormat[ hasAlpha ? 1 : 0 ]; |
@@ -7,3 +7,3 @@ ( function () { | ||
* | ||
* ported from https://github.com/BabylonJS/Babylon.js/blob/master/src/Tools/babylon.khronosTextureContainer.ts | ||
* ported from https://github.com/BabylonJS/Babylon.js/blob/master/src/Misc/khronosTextureContainer.ts | ||
*/ | ||
@@ -10,0 +10,0 @@ |
@@ -919,7 +919,9 @@ ( function () { | ||
matrix: new THREE.Matrix4(), | ||
type: 'Model', | ||
groupObject: null, | ||
// If false, it is a root material scope previous to parse | ||
isFromParse: true, | ||
faces: null, | ||
lineSegments: null, | ||
conditionalSegments: null, | ||
faces: [], | ||
lineSegments: [], | ||
conditionalSegments: [], | ||
totalFaces: 0, | ||
@@ -1139,17 +1141,7 @@ // If true, this object is the start of a construction step | ||
case FINISH_TYPE_PEARLESCENT: | ||
// Try to imitate pearlescency by setting the specular to the complementary of the color, and low shininess | ||
const specular = new THREE.Color( colour ); | ||
const hsl = specular.getHSL( { | ||
h: 0, | ||
s: 0, | ||
l: 0 | ||
} ); | ||
hsl.h = ( hsl.h + 0.5 ) % 1; | ||
hsl.l = Math.min( 1, hsl.l + ( 1 - hsl.l ) * 0.7 ); | ||
specular.setHSL( hsl.h, hsl.s, hsl.l ); | ||
material = new THREE.MeshPhongMaterial( { | ||
// Try to imitate pearlescency by making the surface glossy | ||
material = new THREE.MeshStandardMaterial( { | ||
color: colour, | ||
specular: specular, | ||
shininess: 10, | ||
reflectivity: 0.3 | ||
roughness: 0.3, | ||
metalness: 0.25 | ||
} ); | ||
@@ -1380,17 +1372,5 @@ break; | ||
type = lp.getToken(); | ||
currentParseScope.faces = []; | ||
currentParseScope.lineSegments = []; | ||
currentParseScope.conditionalSegments = []; | ||
currentParseScope.type = type; | ||
const isRoot = ! parentParseScope.isFromParse; | ||
if ( isRoot || scope.separateObjects && ! isPrimitiveType( type ) ) { | ||
currentParseScope.groupObject = new THREE.Group(); | ||
currentParseScope.groupObject.userData.startingConstructionStep = currentParseScope.startingConstructionStep; | ||
} // If the scale of the object is negated then the triangle winding order | ||
currentParseScope.type = type; // If the scale of the object is negated then the triangle winding order | ||
// needs to be flipped. | ||
if ( currentParseScope.matrix.determinant() < 0 && ( scope.separateObjects && isPrimitiveType( type ) || ! scope.separateObjects ) ) { | ||
@@ -1715,3 +1695,11 @@ | ||
currentParseScope.subobjectIndex = 0; | ||
const isRoot = ! parentParseScope.isFromParse; | ||
if ( isRoot || scope.separateObjects && ! isPrimitiveType( type ) ) { | ||
currentParseScope.groupObject = new THREE.Group(); | ||
currentParseScope.groupObject.userData.startingConstructionStep = currentParseScope.startingConstructionStep; | ||
} | ||
} | ||
@@ -1744,2 +1732,9 @@ | ||
// fail gracefully if an object could not be loaded | ||
if ( subobjectParseScope === null ) { | ||
return; | ||
} | ||
const parentParseScope = subobjectParseScope.parentScope; // Smooth the normals if this is a part or if this is a case where the subpart | ||
@@ -1927,2 +1922,3 @@ // is added directly into the parent model (meaning it will never get smoothed by | ||
console.warn( 'LDrawLoader: Subobject "' + subobject.fileName + '" could not be found.' ); | ||
return null; | ||
@@ -1929,0 +1925,0 @@ } ); |
@@ -105,2 +105,3 @@ ( function () { | ||
texture.generateMipmaps = false; | ||
texture.needsUpdate = true; | ||
const texture3D = new THREE.DataTexture3D(); | ||
@@ -119,2 +120,3 @@ texture3D.image.data = data; | ||
texture3D.generateMipmaps = false; | ||
texture3D.needsUpdate = true; | ||
return { | ||
@@ -121,0 +123,0 @@ size, |
@@ -111,2 +111,3 @@ ( function () { | ||
texture.generateMipmaps = false; | ||
texture.needsUpdate = true; | ||
const texture3D = new THREE.DataTexture3D(); | ||
@@ -125,2 +126,3 @@ texture3D.image.data = data; | ||
texture3D.generateMipmaps = false; | ||
texture3D.needsUpdate = true; | ||
return { | ||
@@ -127,0 +129,0 @@ title, |
@@ -290,3 +290,2 @@ ( function () { | ||
* We don't need to request external toon image files. | ||
* This idea is from http://www20.atpages.jp/katwat/three.js_r58/examples/mytest37/mmd.three.js | ||
*/ | ||
@@ -293,0 +292,0 @@ |
@@ -210,3 +210,6 @@ ( function () { | ||
//if no space direction is set, let's use the identity | ||
headerObject.vectors = [ new THREE.Vector3( 1, 0, 0 ), new THREE.Vector3( 0, 1, 0 ), new THREE.Vector3( 0, 0, 1 ) ]; //apply spacing if defined | ||
headerObject.vectors = []; | ||
headerObject.vectors.push( [ 1, 0, 0 ] ); | ||
headerObject.vectors.push( [ 0, 1, 0 ] ); | ||
headerObject.vectors.push( [ 0, 0, 1 ] ); //apply spacing if defined | ||
@@ -219,4 +222,8 @@ if ( headerObject.spacings ) { | ||
headerObject.vectors[ i ].multiplyScalar( headerObject.spacings[ i ] ); | ||
for ( let j = 0; j <= 2; j ++ ) { | ||
headerObject.vectors[ i ][ j ] *= headerObject.spacings[ i ]; | ||
} | ||
} | ||
@@ -223,0 +230,0 @@ |
@@ -586,4 +586,2 @@ ( function () { | ||
* http://paulbourke.net/dataformats/obj/ | ||
* or | ||
* http://www.cs.utah.edu/~boulos/cs3505/obj_spec.pdf | ||
* | ||
@@ -590,0 +588,0 @@ * From chapter "Grouping" Syntax explanation "s group_number": |
@@ -82,3 +82,3 @@ ( function () { | ||
const patternHeader = /ply([\s\S]*)end_header\r?\n/; | ||
const patternHeader = /^ply([\s\S]*)end_header\r?\n/; | ||
let headerText = ''; | ||
@@ -85,0 +85,0 @@ let headerLength = 0; |
@@ -377,9 +377,2 @@ ( function () { | ||
case THREE.UnsignedByteType: | ||
data = image_rgba_data; | ||
format = THREE.RGBEFormat; // handled as THREE.RGBAFormat in shaders | ||
type = THREE.UnsignedByteType; | ||
break; | ||
case THREE.FloatType: | ||
@@ -453,10 +446,2 @@ numElements = image_rgba_data.length / 4; | ||
case THREE.UnsignedByteType: | ||
texture.encoding = THREE.RGBEEncoding; | ||
texture.minFilter = THREE.NearestFilter; | ||
texture.magFilter = THREE.NearestFilter; | ||
texture.generateMipmaps = false; | ||
texture.flipY = true; | ||
break; | ||
case THREE.FloatType: | ||
@@ -463,0 +448,0 @@ texture.encoding = THREE.LinearEncoding; |
@@ -5,2 +5,24 @@ ( function () { | ||
constructor( manager ) { | ||
super( manager ); | ||
this.type = THREE.HalfFloatType; | ||
this.maxRange = 7; // more information about this property at https://iwasbeingirony.blogspot.com/2010/06/difference-between-rgbm-and-rgbd.html | ||
} | ||
setDataType( value ) { | ||
this.type = value; | ||
return this; | ||
} | ||
setMaxRange( value ) { | ||
this.maxRange = value; | ||
return this; | ||
} | ||
loadCubemap( urls, onLoad, onProgress, onError ) { | ||
@@ -36,3 +58,3 @@ | ||
texture.encoding = THREE.RGBM7Encoding; | ||
texture.type = this.type; | ||
texture.format = THREE.RGBAFormat; | ||
@@ -49,10 +71,38 @@ texture.minFilter = THREE.LinearFilter; | ||
const rgba = UPNG.toRGBA8( img )[ 0 ]; | ||
const data = new Uint8Array( rgba ); | ||
const size = img.width * img.height * 4; | ||
const output = this.type === THREE.HalfFloatType ? new Uint16Array( size ) : new Float32Array( size ); // decode RGBM | ||
for ( let i = 0; i < data.length; i += 4 ) { | ||
const r = data[ i + 0 ] / 255; | ||
const g = data[ i + 1 ] / 255; | ||
const b = data[ i + 2 ] / 255; | ||
const a = data[ i + 3 ] / 255; | ||
if ( this.type === THREE.HalfFloatType ) { | ||
output[ i + 0 ] = THREE.DataUtils.toHalfFloat( Math.min( r * a * this.maxRange, 65504 ) ); | ||
output[ i + 1 ] = THREE.DataUtils.toHalfFloat( Math.min( g * a * this.maxRange, 65504 ) ); | ||
output[ i + 2 ] = THREE.DataUtils.toHalfFloat( Math.min( b * a * this.maxRange, 65504 ) ); | ||
output[ i + 3 ] = THREE.DataUtils.toHalfFloat( 1 ); | ||
} else { | ||
output[ i + 0 ] = r * a * this.maxRange; | ||
output[ i + 1 ] = g * a * this.maxRange; | ||
output[ i + 2 ] = b * a * this.maxRange; | ||
output[ i + 3 ] = 1; | ||
} | ||
} | ||
return { | ||
width: img.width, | ||
height: img.height, | ||
data: new Uint8Array( rgba ), | ||
data: output, | ||
format: THREE.RGBAFormat, | ||
type: THREE.UnsignedByteType, | ||
flipY: true, | ||
encoding: THREE.RGBM7Encoding | ||
type: this.type, | ||
flipY: true | ||
}; | ||
@@ -59,0 +109,0 @@ |
@@ -239,2 +239,3 @@ ( function () { | ||
this.unpackAlignment = 1; | ||
this.needsUpdate = true; | ||
@@ -241,0 +242,0 @@ } |
( function () { | ||
// http://mrl.nyu.edu/~perlin/noise/ | ||
// https://cs.nyu.edu/~perlin/noise/ | ||
const _p = [ 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180 ]; | ||
@@ -5,0 +5,0 @@ |
@@ -313,3 +313,5 @@ ( function () { | ||
const data = new Float32Array( sizeX * sizeY * 4 ); | ||
return new THREE.DataTexture( data, sizeX, sizeY, THREE.RGBAFormat, THREE.FloatType ); | ||
const texture = new THREE.DataTexture( data, sizeX, sizeY, THREE.RGBAFormat, THREE.FloatType ); | ||
texture.needsUpdate = true; | ||
return texture; | ||
@@ -316,0 +318,0 @@ }; |
@@ -18,12 +18,4 @@ ( function () { | ||
const tempMap = new THREE.DataTexture( new Uint8Array( 16 * 16 * 3 ), 16, 16, THREE.RGBFormat ); | ||
tempMap.minFilter = THREE.NearestFilter; | ||
tempMap.magFilter = THREE.NearestFilter; | ||
tempMap.wrapS = THREE.ClampToEdgeWrapping; | ||
tempMap.wrapT = THREE.ClampToEdgeWrapping; | ||
const occlusionMap = new THREE.DataTexture( new Uint8Array( 16 * 16 * 3 ), 16, 16, THREE.RGBFormat ); | ||
occlusionMap.minFilter = THREE.NearestFilter; | ||
occlusionMap.magFilter = THREE.NearestFilter; | ||
occlusionMap.wrapS = THREE.ClampToEdgeWrapping; | ||
occlusionMap.wrapT = THREE.ClampToEdgeWrapping; // material | ||
const tempMap = new THREE.FramebufferTexture( 16, 16, THREE.RGBFormat ); | ||
const occlusionMap = new THREE.FramebufferTexture( 16, 16, THREE.RGBFormat ); // material | ||
@@ -30,0 +22,0 @@ const geometry = Lensflare.Geometry; |
@@ -138,2 +138,9 @@ ( function () { | ||
this.dispose = function () { | ||
renderTarget.dispose(); | ||
scope.material.dispose(); | ||
}; | ||
} | ||
@@ -140,0 +147,0 @@ |
@@ -192,2 +192,9 @@ ( function () { | ||
this.dispose = function () { | ||
renderTarget.dispose(); | ||
scope.material.dispose(); | ||
}; | ||
} | ||
@@ -194,0 +201,0 @@ |
@@ -9,3 +9,3 @@ ( function () { | ||
* First implemented by Simon Wallner | ||
* http://www.simonwallner.at/projects/atmospheric-scattering | ||
* http://simonwallner.at/project/atmospheric-scattering/ | ||
* | ||
@@ -12,0 +12,0 @@ * Improved by Martin Upitis |
@@ -5,4 +5,4 @@ ( function () { | ||
* Work based on : | ||
* http://slayvin.net : Flat mirror for three.js | ||
* http://www.adelphi.edu/~stemkoski : An implementation of water shader based on the flat mirror | ||
* https://github.com/Slayvin: Flat mirror for three.js | ||
* https://home.adelphi.edu/~stemkoski/ : An implementation of water shader based on the flat mirror | ||
* http://29a.ch/ && http://29a.ch/slides/2012/webglwater/ : Water shader explanations in WebGL | ||
@@ -9,0 +9,0 @@ */ |
@@ -5,4 +5,4 @@ ( function () { | ||
* References: | ||
* http://www.valvesoftware.com/publications/2010/siggraph2010_vlachos_waterflow.pdf | ||
* http://graphicsrunner.blogspot.de/2010/08/water-using-flow-maps.html | ||
* https://alex.vlachos.com/graphics/Vlachos-SIGGRAPH10-WaterFlow.pdf | ||
* http://graphicsrunner.blogspot.de/2010/08/water-using-flow-maps.html | ||
* | ||
@@ -27,3 +27,2 @@ */ | ||
const shader = options.shader || Water.WaterShader; | ||
const encoding = options.encoding !== undefined ? options.encoding : THREE.LinearEncoding; | ||
const textureLoader = new THREE.TextureLoader(); | ||
@@ -56,4 +55,3 @@ const flowMap = options.flowMap || undefined; | ||
textureHeight: textureHeight, | ||
clipBias: clipBias, | ||
encoding: encoding | ||
clipBias: clipBias | ||
} ); | ||
@@ -63,4 +61,3 @@ const refractor = new THREE.Refractor( geometry, { | ||
textureHeight: textureHeight, | ||
clipBias: clipBias, | ||
encoding: encoding | ||
clipBias: clipBias | ||
} ); | ||
@@ -67,0 +64,0 @@ reflector.matrixAutoUpdate = false; |
@@ -96,3 +96,5 @@ ( function () { | ||
return new THREE.DataTexture( data_arr, dt_size, dt_size, THREE.RGBFormat, THREE.FloatType ); | ||
const texture = new THREE.DataTexture( data_arr, dt_size, dt_size, THREE.RGBFormat, THREE.FloatType ); | ||
texture.needsUpdate = true; | ||
return texture; | ||
@@ -99,0 +101,0 @@ } |
@@ -319,2 +319,3 @@ ( function () { | ||
this.noiseTexture.wrapT = THREE.RepeatWrapping; | ||
this.noiseTexture.needsUpdate = true; | ||
@@ -321,0 +322,0 @@ } |
@@ -6,3 +6,2 @@ ( function () { | ||
* ported from o3d sample to WebGL / GLSL | ||
* http://o3d.googlecode.com/svn/trunk/samples/convolution.html | ||
*/ | ||
@@ -9,0 +8,0 @@ |
@@ -7,3 +7,3 @@ ( function () { | ||
* - ported from HLSL to WebGL / GLSL | ||
* http://www.truevision3d.com/forums/showcase/staticnoise_colorblackwhite_scanline_shaders-t18698.0.html | ||
* https://web.archive.org/web/20210226214859/http://www.truevision3d.com/forums/showcase/staticnoise_colorblackwhite_scanline_shaders-t18698.0.html | ||
* | ||
@@ -10,0 +10,0 @@ * Screen Space Static Postprocessor |
@@ -5,3 +5,3 @@ ( function () { | ||
* NVIDIA FXAA by Timothy Lottes | ||
* http://timothylottes.blogspot.com/2011/06/fxaa3-source-released.html | ||
* https://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf | ||
* - WebGL port by @supereggbert | ||
@@ -8,0 +8,0 @@ * http://www.glge.org/demos/fxaa/ |
@@ -37,3 +37,3 @@ ( function () { | ||
gl_FragColor = LinearTosRGB( tex ); // optional: LinearToGamma( tex, float( GAMMA_FACTOR ) ); | ||
gl_FragColor = LinearTosRGB( tex ); | ||
@@ -40,0 +40,0 @@ }` |
@@ -5,4 +5,3 @@ ( function () { | ||
* Two pass Gaussian blur filter (horizontal and vertical blur shaders) | ||
* - described in http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/ | ||
* and used in http://www.cake23.de/traveling-wavefronts-lit-up.html | ||
* - see http://www.cake23.de/traveling-wavefronts-lit-up.html | ||
* | ||
@@ -9,0 +8,0 @@ * - 9 samples per pass |
@@ -218,3 +218,3 @@ ( function () { | ||
#ifdef PERSPECTIVE_CAMERA | ||
// https://www.comp.nus.edu.sg/~lowkl/publications/lowk_persp_interp_techrep.pdf | ||
// https://comp.nus.edu.sg/~lowkl/publications/lowk_persp_interp_techrep.pdf | ||
float recipVPZ=1./viewPosition.z; | ||
@@ -221,0 +221,0 @@ float viewRefractRayZ=1./(recipVPZ+s*(1./d1viewPosition.z-recipVPZ)); |
@@ -200,3 +200,3 @@ ( function () { | ||
#ifdef PERSPECTIVE_CAMERA | ||
// https://www.comp.nus.edu.sg/~lowkl/publications/lowk_persp_interp_techrep.pdf | ||
// https://comp.nus.edu.sg/~lowkl/publications/lowk_persp_interp_techrep.pdf | ||
float recipVPZ=1./viewPosition.z; | ||
@@ -203,0 +203,0 @@ float viewReflectRayZ=1./(recipVPZ+s*(1./d1viewPosition.z-recipVPZ)); |
@@ -5,4 +5,3 @@ ( function () { | ||
* Two pass Gaussian blur filter (horizontal and vertical blur shaders) | ||
* - described in http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/ | ||
* and used in http://www.cake23.de/traveling-wavefronts-lit-up.html | ||
* - see http://www.cake23.de/traveling-wavefronts-lit-up.html | ||
* | ||
@@ -9,0 +8,0 @@ * - 9 samples per pass |
@@ -44,3 +44,3 @@ ( function () { | ||
* Based on work by: | ||
* @link http://www.openprocessing.org/visuals/?visualID=15599 | ||
* @link https://openprocessing.org/user/5654 | ||
* | ||
@@ -47,0 +47,0 @@ * @param center Center of Hilbert curve. |
@@ -58,30 +58,19 @@ ( function () { | ||
if ( width !== roughnessMap.image.width || height !== roughnessMap.image.height ) { | ||
const newRoughnessTexture = new THREE.FramebufferTexture( width, height, roughnessMap.format ); | ||
newRoughnessTexture.wrapS = roughnessMap.wrapS; | ||
newRoughnessTexture.wrapT = roughnessMap.wrapT; | ||
newRoughnessTexture.minFilter = roughnessMap.minFilter; | ||
newRoughnessTexture.magFilter = roughnessMap.magFilter; | ||
material.roughnessMap = newRoughnessTexture; | ||
if ( material.metalnessMap == roughnessMap ) material.metalnessMap = material.roughnessMap; | ||
if ( material.aoMap == roughnessMap ) material.aoMap = material.roughnessMap; // Copy UV transform parameters | ||
const params = { | ||
wrapS: roughnessMap.wrapS, | ||
wrapT: roughnessMap.wrapT, | ||
magFilter: roughnessMap.magFilter, | ||
minFilter: roughnessMap.minFilter, | ||
depthBuffer: false | ||
}; | ||
const newRoughnessTarget = new THREE.WebGLRenderTarget( width, height, params ); | ||
newRoughnessTarget.texture.generateMipmaps = true; // Setting the render target causes the memory to be allocated. | ||
material.roughnessMap.offset.copy( roughnessMap.offset ); | ||
material.roughnessMap.repeat.copy( roughnessMap.repeat ); | ||
material.roughnessMap.center.copy( roughnessMap.center ); | ||
material.roughnessMap.rotation = roughnessMap.rotation; | ||
material.roughnessMap.image = roughnessMap.image; // required for USDZExporter, see #22741 | ||
_renderer.setRenderTarget( newRoughnessTarget ); | ||
material.roughnessMap = newRoughnessTarget.texture; | ||
if ( material.metalnessMap == roughnessMap ) material.metalnessMap = material.roughnessMap; | ||
if ( material.aoMap == roughnessMap ) material.aoMap = material.roughnessMap; // Copy UV transform parameters | ||
material.roughnessMap.offset.copy( roughnessMap.offset ); | ||
material.roughnessMap.repeat.copy( roughnessMap.repeat ); | ||
material.roughnessMap.center.copy( roughnessMap.center ); | ||
material.roughnessMap.rotation = roughnessMap.rotation; | ||
material.roughnessMap.image = roughnessMap.image; | ||
material.roughnessMap.matrixAutoUpdate = roughnessMap.matrixAutoUpdate; | ||
material.roughnessMap.matrix.copy( roughnessMap.matrix ); | ||
} | ||
material.roughnessMap.matrixAutoUpdate = roughnessMap.matrixAutoUpdate; | ||
material.roughnessMap.matrix.copy( roughnessMap.matrix ); | ||
_mipmapMaterial.uniforms.roughnessMap.value = roughnessMap; | ||
@@ -114,3 +103,3 @@ _mipmapMaterial.uniforms.normalMap.value = normalMap; | ||
if ( roughnessMap !== material.roughnessMap ) roughnessMap.dispose(); | ||
roughnessMap.dispose(); | ||
@@ -117,0 +106,0 @@ _renderer.setRenderTarget( oldTarget ); |
@@ -152,3 +152,2 @@ import { | ||
// skip if changing angle is too small to prevent vibration of bone | ||
// Refer to http://www20.atpages.jp/katwat/three.js_r58/examples/mytest37/mmd.three.js | ||
if ( angle < 1e-5 ) continue; | ||
@@ -155,0 +154,0 @@ |
@@ -1206,3 +1206,2 @@ import { | ||
// this parameter is from http://www20.atpages.jp/katwat/three.js_r58/examples/mytest37/mmd.three.js | ||
constraint.setParam( 2, 0.475, i ); | ||
@@ -1372,3 +1371,2 @@ | ||
// copy from http://www20.atpages.jp/katwat/three.js_r58/examples/mytest37/mytest37.js?ver=20160815 | ||
function createCapsuleGeometry( radius, cylinderHeight, segmentsRadius, segmentsHeight ) { | ||
@@ -1375,0 +1373,0 @@ |
@@ -567,2 +567,21 @@ import { | ||
reset() { | ||
if ( ! this.enabled ) return; | ||
if ( this.dragging ) { | ||
this.object.position.copy( this._positionStart ); | ||
this.object.quaternion.copy( this._quaternionStart ); | ||
this.object.scale.copy( this._scaleStart ); | ||
this.dispatchEvent( _changeEvent ); | ||
this.dispatchEvent( _objectChangeEvent ); | ||
this.pointStart.copy( this.pointEnd ); | ||
} | ||
} | ||
getRaycaster() { | ||
@@ -673,4 +692,8 @@ | ||
this.domElement.setPointerCapture( event.pointerId ); | ||
if ( ! document.pointerLockElement ) { | ||
this.domElement.setPointerCapture( event.pointerId ); | ||
} | ||
this.domElement.addEventListener( 'pointermove', this._onPointerMove ); | ||
@@ -677,0 +700,0 @@ |
@@ -11,5 +11,3 @@ import { | ||
* http://mathworld.wolfram.com/HeartCurve.html | ||
* http://mathdl.maa.org/images/upload_library/23/stemkoski/knots/page6.html | ||
* http://en.wikipedia.org/wiki/Viviani%27s_curve | ||
* http://mathdl.maa.org/images/upload_library/23/stemkoski/knots/page4.html | ||
* http://www.mi.sanu.ac.rs/vismath/taylorapril2011/Taylor.pdf | ||
@@ -16,0 +14,0 @@ * https://prideout.net/blog/old/blog/index.html@p=44.html |
/** | ||
* Ascii generation is based on http://www.nihilogic.dk/labs/jsascii/ | ||
* Maybe more about this later with a blog post at http://lab4games.net/zz85/blog | ||
* Ascii generation is based on https://github.com/hassadee/jsascii/blob/master/jsascii.js | ||
* | ||
@@ -60,10 +59,4 @@ * 16 April 2012 - @blurspline | ||
// Throw in ascii library from http://www.nihilogic.dk/labs/jsascii/jsascii.js | ||
// Throw in ascii library from https://github.com/hassadee/jsascii/blob/master/jsascii.js (MIT License) | ||
/* | ||
* jsAscii 0.1 | ||
* Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/ | ||
* MIT License [http://www.nihilogic.dk/licenses/mit-license.txt] | ||
*/ | ||
function initAsciiSize() { | ||
@@ -70,0 +63,0 @@ |
@@ -2202,3 +2202,3 @@ import { | ||
* | ||
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness | ||
* Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness | ||
*/ | ||
@@ -2205,0 +2205,0 @@ class GLTFMaterialsPBRSpecularGlossiness { |
@@ -51,3 +51,2 @@ import { | ||
* Created for the Udacity course "Interactive Rendering", http://bit.ly/ericity | ||
* Lesson: https://www.udacity.com/course/viewer#!/c-cs291/l-68866048/m-106482448 | ||
* YouTube video on teapot history: https://www.youtube.com/watch?v=DxMfblPzFNc | ||
@@ -54,0 +53,0 @@ * |
@@ -185,2 +185,3 @@ import { | ||
_matrix.decompose( _center, _quaternion, _scale ); | ||
_center.applyMatrix4( object.matrixWorld ); | ||
@@ -187,0 +188,0 @@ if ( frustum.containsPoint( _center ) ) { |
@@ -21,3 +21,3 @@ import { | ||
this.renderer.domElement.addEventListener( 'pointerdown', function ( event ) { | ||
this.onPointerDown = function ( event ) { | ||
@@ -27,5 +27,5 @@ this.isDown = true; | ||
}.bind( this ) ); | ||
}.bind( this ); | ||
this.renderer.domElement.addEventListener( 'pointermove', function ( event ) { | ||
this.onPointerMove = function ( event ) { | ||
@@ -38,13 +38,25 @@ if ( this.isDown ) { | ||
}.bind( this ) ); | ||
}.bind( this ); | ||
this.renderer.domElement.addEventListener( 'pointerup', function ( event ) { | ||
this.onPointerUp = function ( ) { | ||
this.isDown = false; | ||
this.onSelectOver( event ); | ||
this.onSelectOver(); | ||
}.bind( this ) ); | ||
}.bind( this ); | ||
this.renderer.domElement.addEventListener( 'pointerdown', this.onPointerDown ); | ||
this.renderer.domElement.addEventListener( 'pointermove', this.onPointerMove ); | ||
this.renderer.domElement.addEventListener( 'pointerup', this.onPointerUp ); | ||
} | ||
dispose() { | ||
this.renderer.domElement.removeEventListener( 'pointerdown', this.onPointerDown ); | ||
this.renderer.domElement.removeEventListener( 'pointermove', this.onPointerMove ); | ||
this.renderer.domElement.removeEventListener( 'pointerup', this.onPointerUp ); | ||
} | ||
onSelectStart( event ) { | ||
@@ -51,0 +63,0 @@ |
@@ -18,4 +18,2 @@ import { | ||
* | ||
* More information about the AMF format: http://amf.wikispaces.com | ||
* | ||
* Usage: | ||
@@ -22,0 +20,0 @@ * const loader = new AMFLoader(); |
@@ -8,8 +8,4 @@ import { | ||
LinearFilter, | ||
NearestFilter, | ||
RGBAFormat, | ||
RGBEEncoding, | ||
RGBEFormat, | ||
RGBFormat, | ||
UnsignedByteType | ||
RedFormat, | ||
RGBAFormat | ||
} from 'three'; | ||
@@ -136,37 +132,2 @@ import * as fflate from '../libs/fflate.module.js'; | ||
var tmpDataView = new DataView( new ArrayBuffer( 8 ) ); | ||
function frexp( value ) { | ||
if ( value === 0 ) return [ value, 0 ]; | ||
tmpDataView.setFloat64( 0, value ); | ||
var bits = ( tmpDataView.getUint32( 0 ) >>> 20 ) & 0x7FF; | ||
if ( bits === 0 ) { // denormal | ||
tmpDataView.setFloat64( 0, value * Math.pow( 2, 64 ) ); // exp + 64 | ||
bits = ( ( tmpDataView.getUint32( 0 ) >>> 20 ) & 0x7FF ) - 64; | ||
} | ||
var exponent = bits - 1022; | ||
var mantissa = ldexp( value, - exponent ); | ||
return [ mantissa, exponent ]; | ||
} | ||
function ldexp( mantissa, exponent ) { | ||
var steps = Math.min( 3, Math.ceil( Math.abs( exponent ) / 1023 ) ); | ||
var result = mantissa; | ||
for ( var i = 0; i < steps; i ++ ) | ||
result *= Math.pow( 2, Math.floor( ( exponent + i ) / steps ) ); | ||
return result; | ||
} | ||
function reverseLutFromBitmap( bitmap, lut ) { | ||
@@ -1317,4 +1278,3 @@ | ||
var tmpBufSize = info.width * scanlineBlockSize * ( EXRHeader.channels.length * info.type ); | ||
var outBuffer = new Uint16Array( tmpBufSize ); | ||
var outBuffer = new Uint16Array( info.width * info.scanlineBlockSize * ( info.channels * info.type ) ); | ||
var bitmap = new Uint8Array( BITMAP_SIZE ); | ||
@@ -1339,2 +1299,3 @@ | ||
// Read range compression data | ||
var minNonZero = parseUint16( inDataView, inOffset ); | ||
@@ -1496,3 +1457,3 @@ var maxNonZero = parseUint16( inDataView, inOffset ); | ||
var inOffset = { value: info.offset.value }; | ||
var outBuffer = new Uint8Array( info.width * info.lines * ( EXRHeader.channels.length * info.type * INT16_SIZE ) ); | ||
var outBuffer = new Uint8Array( info.width * info.lines * ( info.channels * info.type * INT16_SIZE ) ); | ||
@@ -1745,12 +1706,2 @@ // Read compression header information | ||
function parseUlong( dataView, offset ) { | ||
var uLong = dataView.getUint32( 0, true ); | ||
offset.value = offset.value + ULONG_SIZE; | ||
return uLong; | ||
} | ||
function parseRational( dataView, offset ) { | ||
@@ -2046,308 +1997,268 @@ | ||
var bufferDataView = new DataView( buffer ); | ||
var uInt8Array = new Uint8Array( buffer ); | ||
function parseHeader( dataView, buffer, offset ) { | ||
var EXRHeader = {}; | ||
const EXRHeader = {}; | ||
bufferDataView.getUint32( 0, true ); // magic | ||
bufferDataView.getUint8( 4, true ); // versionByteZero | ||
bufferDataView.getUint8( 5, true ); // fullMask | ||
if ( dataView.getUint32( 0, true ) != 20000630 ) // magic | ||
throw 'THREE.EXRLoader: provided file doesn\'t appear to be in OpenEXR format.'; | ||
// start of header | ||
EXRHeader.version = dataView.getUint8( 4, true ); | ||
var offset = { value: 8 }; // start at 8, after magic stuff | ||
const spec = dataView.getUint8( 5, true ); // fullMask | ||
var keepReading = true; | ||
EXRHeader.spec = { | ||
singleTile: !! ( spec & 1 ), | ||
longName: !! ( spec & 2 ), | ||
deepFormat: !! ( spec & 4 ), | ||
multiPart: !! ( spec & 8 ), | ||
}; | ||
while ( keepReading ) { | ||
// start of header | ||
var attributeName = parseNullTerminatedString( buffer, offset ); | ||
offset.value = 8; // start at 8 - after pre-amble | ||
if ( attributeName == 0 ) { | ||
var keepReading = true; | ||
keepReading = false; | ||
while ( keepReading ) { | ||
} else { | ||
var attributeName = parseNullTerminatedString( buffer, offset ); | ||
var attributeType = parseNullTerminatedString( buffer, offset ); | ||
var attributeSize = parseUint32( bufferDataView, offset ); | ||
var attributeValue = parseValue( bufferDataView, buffer, offset, attributeType, attributeSize ); | ||
if ( attributeName == 0 ) { | ||
if ( attributeValue === undefined ) { | ||
keepReading = false; | ||
console.warn( `EXRLoader.parse: skipped unknown header attribute type \'${ attributeType }\'.` ); | ||
} else { | ||
EXRHeader[ attributeName ] = attributeValue; | ||
var attributeType = parseNullTerminatedString( buffer, offset ); | ||
var attributeSize = parseUint32( dataView, offset ); | ||
var attributeValue = parseValue( dataView, buffer, offset, attributeType, attributeSize ); | ||
} | ||
if ( attributeValue === undefined ) { | ||
} | ||
console.warn( `EXRLoader.parse: skipped unknown header attribute type \'${attributeType}\'.` ); | ||
} | ||
} else { | ||
// offsets | ||
var dataWindowHeight = EXRHeader.dataWindow.yMax + 1; | ||
EXRHeader[ attributeName ] = attributeValue; | ||
var uncompress; | ||
var scanlineBlockSize; | ||
} | ||
switch ( EXRHeader.compression ) { | ||
} | ||
case 'NO_COMPRESSION': | ||
} | ||
scanlineBlockSize = 1; | ||
uncompress = uncompressRAW; | ||
break; | ||
if ( spec != 0 ) { | ||
case 'RLE_COMPRESSION': | ||
console.error( 'EXRHeader:', EXRHeader ); | ||
throw 'THREE.EXRLoader: provided file is currently unsupported.'; | ||
scanlineBlockSize = 1; | ||
uncompress = uncompressRLE; | ||
break; | ||
} | ||
case 'ZIPS_COMPRESSION': | ||
return EXRHeader; | ||
scanlineBlockSize = 1; | ||
uncompress = uncompressZIP; | ||
break; | ||
case 'ZIP_COMPRESSION': | ||
scanlineBlockSize = 16; | ||
uncompress = uncompressZIP; | ||
break; | ||
case 'PIZ_COMPRESSION': | ||
scanlineBlockSize = 32; | ||
uncompress = uncompressPIZ; | ||
break; | ||
case 'PXR24_COMPRESSION': | ||
scanlineBlockSize = 16; | ||
uncompress = uncompressPXR; | ||
break; | ||
case 'DWAA_COMPRESSION': | ||
scanlineBlockSize = 32; | ||
uncompress = uncompressDWA; | ||
break; | ||
case 'DWAB_COMPRESSION': | ||
scanlineBlockSize = 256; | ||
uncompress = uncompressDWA; | ||
break; | ||
default: | ||
throw 'EXRLoader.parse: ' + EXRHeader.compression + ' is unsupported'; | ||
} | ||
var size_t; | ||
var getValue; | ||
function setupDecoder( EXRHeader, dataView, uInt8Array, offset, outputType ) { | ||
// mixed pixelType not supported | ||
var pixelType = EXRHeader.channels[ 0 ].pixelType; | ||
const EXRDecoder = { | ||
size: 0, | ||
viewer: dataView, | ||
array: uInt8Array, | ||
offset: offset, | ||
width: EXRHeader.dataWindow.xMax - EXRHeader.dataWindow.xMin + 1, | ||
height: EXRHeader.dataWindow.yMax - EXRHeader.dataWindow.yMin + 1, | ||
channels: EXRHeader.channels.length, | ||
bytesPerLine: null, | ||
lines: null, | ||
inputSize: null, | ||
type: EXRHeader.channels[ 0 ].pixelType, | ||
uncompress: null, | ||
getter: null, | ||
format: null, | ||
encoding: null, | ||
}; | ||
if ( pixelType === 1 ) { // half | ||
switch ( EXRHeader.compression ) { | ||
switch ( this.type ) { | ||
case 'NO_COMPRESSION': | ||
EXRDecoder.lines = 1; | ||
EXRDecoder.uncompress = uncompressRAW; | ||
break; | ||
case UnsignedByteType: | ||
case FloatType: | ||
case 'RLE_COMPRESSION': | ||
EXRDecoder.lines = 1; | ||
EXRDecoder.uncompress = uncompressRLE; | ||
break; | ||
getValue = parseFloat16; | ||
size_t = INT16_SIZE; | ||
case 'ZIPS_COMPRESSION': | ||
EXRDecoder.lines = 1; | ||
EXRDecoder.uncompress = uncompressZIP; | ||
break; | ||
case HalfFloatType: | ||
case 'ZIP_COMPRESSION': | ||
EXRDecoder.lines = 16; | ||
EXRDecoder.uncompress = uncompressZIP; | ||
break; | ||
getValue = parseUint16; | ||
size_t = INT16_SIZE; | ||
case 'PIZ_COMPRESSION': | ||
EXRDecoder.lines = 32; | ||
EXRDecoder.uncompress = uncompressPIZ; | ||
break; | ||
} | ||
case 'PXR24_COMPRESSION': | ||
EXRDecoder.lines = 16; | ||
EXRDecoder.uncompress = uncompressPXR; | ||
break; | ||
} else if ( pixelType === 2 ) { // float | ||
case 'DWAA_COMPRESSION': | ||
EXRDecoder.lines = 32; | ||
EXRDecoder.uncompress = uncompressDWA; | ||
break; | ||
switch ( this.type ) { | ||
case UnsignedByteType: | ||
case FloatType: | ||
getValue = parseFloat32; | ||
size_t = FLOAT32_SIZE; | ||
case 'DWAB_COMPRESSION': | ||
EXRDecoder.lines = 256; | ||
EXRDecoder.uncompress = uncompressDWA; | ||
break; | ||
case HalfFloatType: | ||
default: | ||
throw 'EXRLoader.parse: ' + EXRHeader.compression + ' is unsupported'; | ||
getValue = decodeFloat32; | ||
size_t = FLOAT32_SIZE; | ||
} | ||
} else { | ||
EXRDecoder.scanlineBlockSize = EXRDecoder.lines; | ||
throw 'EXRLoader.parse: unsupported pixelType ' + pixelType + ' for ' + EXRHeader.compression + '.'; | ||
if ( EXRDecoder.type == 1 ) { | ||
} | ||
// half | ||
switch ( outputType ) { | ||
var numBlocks = dataWindowHeight / scanlineBlockSize; | ||
case FloatType: | ||
EXRDecoder.getter = parseFloat16; | ||
EXRDecoder.inputSize = INT16_SIZE; | ||
break; | ||
for ( var i = 0; i < numBlocks; i ++ ) { | ||
case HalfFloatType: | ||
EXRDecoder.getter = parseUint16; | ||
EXRDecoder.inputSize = INT16_SIZE; | ||
break; | ||
parseUlong( bufferDataView, offset ); // scanlineOffset | ||
} | ||
// we should be passed the scanline offset table, start reading pixel data | ||
var width = EXRHeader.dataWindow.xMax - EXRHeader.dataWindow.xMin + 1; | ||
var height = EXRHeader.dataWindow.yMax - EXRHeader.dataWindow.yMin + 1; | ||
// Firefox only supports RGBA (half) float textures | ||
// var numChannels = EXRHeader.channels.length; | ||
var numChannels = 4; | ||
var size = width * height * numChannels; | ||
// Fill initially with 1s for the alpha value if the texture is not RGBA, RGB values will be overwritten | ||
switch ( this.type ) { | ||
case UnsignedByteType: | ||
case FloatType: | ||
var byteArray = new Float32Array( size ); | ||
if ( EXRHeader.channels.length < numChannels ) { | ||
byteArray.fill( 1, 0, size ); | ||
} | ||
break; | ||
} else if ( EXRDecoder.type == 2 ) { | ||
case HalfFloatType: | ||
// float | ||
switch ( outputType ) { | ||
var byteArray = new Uint16Array( size ); | ||
case FloatType: | ||
EXRDecoder.getter = parseFloat32; | ||
EXRDecoder.inputSize = FLOAT32_SIZE; | ||
break; | ||
if ( EXRHeader.channels.length < numChannels ) { | ||
case HalfFloatType: | ||
EXRDecoder.getter = decodeFloat32; | ||
EXRDecoder.inputSize = FLOAT32_SIZE; | ||
byteArray.fill( 0x3C00, 0, size ); // Uint16Array holds half float data, 0x3C00 is 1 | ||
} | ||
break; | ||
} else { | ||
default: | ||
throw 'EXRLoader.parse: unsupported pixelType ' + EXRDecoder.type + ' for ' + EXRHeader.compression + '.'; | ||
console.error( 'THREE.EXRLoader: unsupported type: ', this.type ); | ||
break; | ||
} | ||
} | ||
EXRDecoder.blockCount = ( EXRHeader.dataWindow.yMax + 1 ) / EXRDecoder.scanlineBlockSize; | ||
var channelOffsets = { | ||
R: 0, | ||
G: 1, | ||
B: 2, | ||
A: 3 | ||
}; | ||
for ( var i = 0; i < EXRDecoder.blockCount; i ++ ) | ||
parseInt64( dataView, offset ); // scanlineOffset | ||
var compressionInfo = { | ||
// we should be passed the scanline offset table, ready to start reading pixel data. | ||
size: 0, | ||
width: width, | ||
lines: scanlineBlockSize, | ||
// RGB images will be converted to RGBA format, preventing software emulation in select devices. | ||
EXRDecoder.outputChannels = ( ( EXRDecoder.channels == 3 ) ? 4 : EXRDecoder.channels ); | ||
const size = EXRDecoder.width * EXRDecoder.height * EXRDecoder.outputChannels; | ||
offset: offset, | ||
array: uInt8Array, | ||
viewer: bufferDataView, | ||
switch ( outputType ) { | ||
type: pixelType, | ||
channels: EXRHeader.channels.length, | ||
case FloatType: | ||
EXRDecoder.byteArray = new Float32Array( size ); | ||
}; | ||
// Fill initially with 1s for the alpha value if the texture is not RGBA, RGB values will be overwritten | ||
if ( EXRDecoder.channels < EXRDecoder.outputChannels ) | ||
EXRDecoder.byteArray.fill( 1, 0, size ); | ||
var line; | ||
var size; | ||
var viewer; | ||
var tmpOffset = { value: 0 }; | ||
break; | ||
for ( var scanlineBlockIdx = 0; scanlineBlockIdx < height / scanlineBlockSize; scanlineBlockIdx ++ ) { | ||
case HalfFloatType: | ||
EXRDecoder.byteArray = new Uint16Array( size ); | ||
line = parseUint32( bufferDataView, offset ); // line_no | ||
size = parseUint32( bufferDataView, offset ); // data_len | ||
if ( EXRDecoder.channels < EXRDecoder.outputChannels ) | ||
EXRDecoder.byteArray.fill( 0x3C00, 0, size ); // Uint16Array holds half float data, 0x3C00 is 1 | ||
compressionInfo.lines = ( line + scanlineBlockSize > height ) ? height - line : scanlineBlockSize; | ||
compressionInfo.offset = offset; | ||
compressionInfo.size = size; | ||
break; | ||
viewer = uncompress( compressionInfo ); | ||
default: | ||
console.error( 'THREE.EXRLoader: unsupported type: ', outputType ); | ||
break; | ||
offset.value += size; | ||
} | ||
for ( var line_y = 0; line_y < scanlineBlockSize; line_y ++ ) { | ||
EXRDecoder.bytesPerLine = EXRDecoder.width * EXRDecoder.inputSize * EXRDecoder.channels; | ||
var true_y = line_y + ( scanlineBlockIdx * scanlineBlockSize ); | ||
if ( EXRDecoder.outputChannels == 4 ) { | ||
if ( true_y >= height ) break; | ||
EXRDecoder.format = RGBAFormat; | ||
EXRDecoder.encoding = LinearEncoding; | ||
for ( var channelID = 0; channelID < EXRHeader.channels.length; channelID ++ ) { | ||
} else { | ||
var cOff = channelOffsets[ EXRHeader.channels[ channelID ].name ]; | ||
EXRDecoder.format = RedFormat; | ||
EXRDecoder.encoding = LinearEncoding; | ||
for ( var x = 0; x < width; x ++ ) { | ||
} | ||
var idx = ( line_y * ( EXRHeader.channels.length * width ) ) + ( channelID * width ) + x; | ||
tmpOffset.value = idx * size_t; | ||
return EXRDecoder; | ||
var val = getValue( viewer, tmpOffset ); | ||
} | ||
byteArray[ ( ( ( height - 1 - true_y ) * ( width * numChannels ) ) + ( x * numChannels ) ) + cOff ] = val; | ||
// start parsing file [START] | ||
} | ||
const bufferDataView = new DataView( buffer ); | ||
const uInt8Array = new Uint8Array( buffer ); | ||
const offset = { value: 0 }; | ||
} | ||
// get header information and validate format. | ||
const EXRHeader = parseHeader( bufferDataView, buffer, offset ); | ||
} | ||
// get input compression information and prepare decoding. | ||
const EXRDecoder = setupDecoder( EXRHeader, bufferDataView, uInt8Array, offset, this.type ); | ||
} | ||
const tmpOffset = { value: 0 }; | ||
const channelOffsets = { R: 0, G: 1, B: 2, A: 3, Y: 0 }; | ||
if ( this.type === UnsignedByteType ) { | ||
for ( let scanlineBlockIdx = 0; scanlineBlockIdx < EXRDecoder.height / EXRDecoder.scanlineBlockSize; scanlineBlockIdx ++ ) { | ||
let v, i; | ||
const size = byteArray.length; | ||
const RGBEArray = new Uint8Array( size ); | ||
const line = parseUint32( bufferDataView, offset ); // line_no | ||
EXRDecoder.size = parseUint32( bufferDataView, offset ); // data_len | ||
EXRDecoder.lines = ( ( line + EXRDecoder.scanlineBlockSize > EXRDecoder.height ) ? ( EXRDecoder.height - line ) : EXRDecoder.scanlineBlockSize ); | ||
for ( let h = 0; h < height; ++ h ) { | ||
const isCompressed = EXRDecoder.size < EXRDecoder.lines * EXRDecoder.bytesPerLine; | ||
const viewer = isCompressed ? EXRDecoder.uncompress( EXRDecoder ) : uncompressRAW( EXRDecoder ); | ||
for ( let w = 0; w < width; ++ w ) { | ||
offset.value += EXRDecoder.size; | ||
i = h * width * 4 + w * 4; | ||
for ( let line_y = 0; line_y < EXRDecoder.scanlineBlockSize; line_y ++ ) { | ||
const red = byteArray[ i ]; | ||
const green = byteArray[ i + 1 ]; | ||
const blue = byteArray[ i + 2 ]; | ||
const true_y = line_y + scanlineBlockIdx * EXRDecoder.scanlineBlockSize; | ||
if ( true_y >= EXRDecoder.height ) break; | ||
v = ( red > green ) ? red : green; | ||
v = ( blue > v ) ? blue : v; | ||
for ( let channelID = 0; channelID < EXRDecoder.channels; channelID ++ ) { | ||
if ( v < 1e-32 ) { | ||
const cOff = channelOffsets[ EXRHeader.channels[ channelID ].name ]; | ||
RGBEArray[ i ] = RGBEArray[ i + 1 ] = RGBEArray[ i + 2 ] = RGBEArray[ i + 3 ] = 0; | ||
for ( let x = 0; x < EXRDecoder.width; x ++ ) { | ||
} else { | ||
tmpOffset.value = ( line_y * ( EXRDecoder.channels * EXRDecoder.width ) + channelID * EXRDecoder.width + x ) * EXRDecoder.inputSize; | ||
const outIndex = ( EXRDecoder.height - 1 - true_y ) * ( EXRDecoder.width * EXRDecoder.outputChannels ) + x * EXRDecoder.outputChannels + cOff; | ||
EXRDecoder.byteArray[ outIndex ] = EXRDecoder.getter( viewer, tmpOffset ); | ||
const res = frexp( v ); | ||
v = res[ 0 ] * 256 / v; | ||
RGBEArray[ i ] = red * v; | ||
RGBEArray[ i + 1 ] = green * v; | ||
RGBEArray[ i + 2 ] = blue * v; | ||
RGBEArray[ i + 3 ] = res[ 1 ] + 128; | ||
} | ||
@@ -2359,15 +2270,12 @@ | ||
byteArray = RGBEArray; | ||
} | ||
const format = ( this.type === UnsignedByteType ) ? RGBEFormat : ( numChannels === 4 ) ? RGBAFormat : RGBFormat; | ||
return { | ||
header: EXRHeader, | ||
width: width, | ||
height: height, | ||
data: byteArray, | ||
format: format, | ||
type: this.type | ||
width: EXRDecoder.width, | ||
height: EXRDecoder.height, | ||
data: EXRDecoder.byteArray, | ||
format: EXRDecoder.format, | ||
encoding: EXRDecoder.encoding, | ||
type: this.type, | ||
}; | ||
@@ -2388,25 +2296,8 @@ | ||
switch ( texture.type ) { | ||
texture.encoding = texData.encoding; | ||
texture.minFilter = LinearFilter; | ||
texture.magFilter = LinearFilter; | ||
texture.generateMipmaps = false; | ||
texture.flipY = false; | ||
case UnsignedByteType: | ||
texture.encoding = RGBEEncoding; | ||
texture.minFilter = NearestFilter; | ||
texture.magFilter = NearestFilter; | ||
texture.generateMipmaps = false; | ||
texture.flipY = false; | ||
break; | ||
case FloatType: | ||
case HalfFloatType: | ||
texture.encoding = LinearEncoding; | ||
texture.minFilter = LinearFilter; | ||
texture.magFilter = LinearFilter; | ||
texture.generateMipmaps = false; | ||
texture.flipY = false; | ||
break; | ||
} | ||
if ( onLoad ) onLoad( texture, texData ); | ||
@@ -2413,0 +2304,0 @@ |
@@ -10,7 +10,3 @@ import { | ||
Loader, | ||
NearestFilter, | ||
RGBAFormat, | ||
RGBEEncoding, | ||
RGBFormat, | ||
UnsignedByteType | ||
RGBFormat | ||
} from 'three'; | ||
@@ -51,11 +47,2 @@ import { RGBELoader } from '../loaders/RGBELoader.js'; | ||
case UnsignedByteType: | ||
texture.encoding = RGBEEncoding; | ||
texture.format = RGBAFormat; | ||
texture.minFilter = NearestFilter; | ||
texture.magFilter = NearestFilter; | ||
texture.generateMipmaps = false; | ||
break; | ||
case FloatType: | ||
@@ -62,0 +49,0 @@ |
@@ -97,2 +97,10 @@ /** | ||
if ( renderer.capabilities.isWebGL2 ) { | ||
// https://github.com/mrdoob/three.js/pull/22928 | ||
this.workerConfig.etc1Supported = false; | ||
} | ||
return this; | ||
@@ -173,3 +181,3 @@ | ||
_activeLoaders++; | ||
_activeLoaders ++; | ||
@@ -270,3 +278,3 @@ } | ||
_activeLoaders--; | ||
_activeLoaders --; | ||
@@ -525,4 +533,4 @@ return this; | ||
basisFormat: [ BasisFormat.ETC1S, BasisFormat.UASTC_4x4 ], | ||
transcoderFormat: [ TranscoderFormat.ETC1, TranscoderFormat.ETC1 ], | ||
engineFormat: [ EngineFormat.RGB_ETC1_Format, EngineFormat.RGB_ETC1_Format ], | ||
transcoderFormat: [ TranscoderFormat.ETC1 ], | ||
engineFormat: [ EngineFormat.RGB_ETC1_Format ], | ||
priorityETC1S: 2, | ||
@@ -567,2 +575,3 @@ priorityUASTC: 4, | ||
if ( ! opt.basisFormat.includes( basisFormat ) ) continue; | ||
if ( hasAlpha && opt.transcoderFormat.length < 2 ) continue; | ||
if ( opt.needsPowerOfTwo && ! ( isPowerOfTwo( width ) && isPowerOfTwo( height ) ) ) continue; | ||
@@ -569,0 +578,0 @@ |
@@ -9,3 +9,3 @@ import { | ||
* | ||
* ported from https://github.com/BabylonJS/Babylon.js/blob/master/src/Tools/babylon.khronosTextureContainer.ts | ||
* ported from https://github.com/BabylonJS/Babylon.js/blob/master/src/Misc/khronosTextureContainer.ts | ||
*/ | ||
@@ -12,0 +12,0 @@ |
@@ -12,3 +12,2 @@ import { | ||
Mesh, | ||
MeshPhongMaterial, | ||
MeshStandardMaterial, | ||
@@ -971,2 +970,4 @@ ShaderMaterial, | ||
matrix: new Matrix4(), | ||
type: 'Model', | ||
groupObject: null, | ||
@@ -976,5 +977,5 @@ // If false, it is a root material scope previous to parse | ||
faces: null, | ||
lineSegments: null, | ||
conditionalSegments: null, | ||
faces: [], | ||
lineSegments: [], | ||
conditionalSegments: [], | ||
totalFaces: 0, | ||
@@ -1206,10 +1207,4 @@ | ||
// Try to imitate pearlescency by setting the specular to the complementary of the color, and low shininess | ||
const specular = new Color( colour ); | ||
const hsl = specular.getHSL( { h: 0, s: 0, l: 0 } ); | ||
hsl.h = ( hsl.h + 0.5 ) % 1; | ||
hsl.l = Math.min( 1, hsl.l + ( 1 - hsl.l ) * 0.7 ); | ||
specular.setHSL( hsl.h, hsl.s, hsl.l ); | ||
material = new MeshPhongMaterial( { color: colour, specular: specular, shininess: 10, reflectivity: 0.3 } ); | ||
// Try to imitate pearlescency by making the surface glossy | ||
material = new MeshStandardMaterial( { color: colour, roughness: 0.3, metalness: 0.25 } ); | ||
break; | ||
@@ -1450,16 +1445,4 @@ | ||
currentParseScope.faces = []; | ||
currentParseScope.lineSegments = []; | ||
currentParseScope.conditionalSegments = []; | ||
currentParseScope.type = type; | ||
const isRoot = ! parentParseScope.isFromParse; | ||
if ( isRoot || scope.separateObjects && ! isPrimitiveType( type ) ) { | ||
currentParseScope.groupObject = new Group(); | ||
currentParseScope.groupObject.userData.startingConstructionStep = currentParseScope.startingConstructionStep; | ||
} | ||
// If the scale of the object is negated then the triangle winding order | ||
@@ -1834,2 +1817,10 @@ // needs to be flipped. | ||
const isRoot = ! parentParseScope.isFromParse; | ||
if ( isRoot || scope.separateObjects && ! isPrimitiveType( type ) ) { | ||
currentParseScope.groupObject = new Group(); | ||
currentParseScope.groupObject.userData.startingConstructionStep = currentParseScope.startingConstructionStep; | ||
} | ||
} | ||
@@ -1865,2 +1856,9 @@ | ||
// fail gracefully if an object could not be loaded | ||
if ( subobjectParseScope === null ) { | ||
return; | ||
} | ||
const parentParseScope = subobjectParseScope.parentScope; | ||
@@ -2055,2 +2053,3 @@ | ||
console.warn( 'LDrawLoader: Subobject "' + subobject.fileName + '" could not be found.' ); | ||
return null; | ||
@@ -2057,0 +2056,0 @@ } ); |
@@ -121,2 +121,3 @@ // http://download.autodesk.com/us/systemdocs/help/2011/lustre/index.html?url=./files/WSc4e151a45a3b785a24c3d9a411df9298473-7ffd.htm,topicNumber=d0e9492 | ||
texture.generateMipmaps = false; | ||
texture.needsUpdate = true; | ||
@@ -136,2 +137,3 @@ const texture3D = new DataTexture3D(); | ||
texture3D.generateMipmaps = false; | ||
texture3D.needsUpdate = true; | ||
@@ -138,0 +140,0 @@ return { |
@@ -127,2 +127,3 @@ // https://wwwimages2.adobe.com/content/dam/acom/en/products/speedgrade/cc/pdfs/cube-lut-specification-1.0.pdf | ||
texture.generateMipmaps = false; | ||
texture.needsUpdate = true; | ||
@@ -142,2 +143,3 @@ const texture3D = new DataTexture3D(); | ||
texture3D.generateMipmaps = false; | ||
texture3D.needsUpdate = true; | ||
@@ -144,0 +146,0 @@ return { |
@@ -360,3 +360,2 @@ import { | ||
* We don't need to request external toon image files. | ||
* This idea is from http://www20.atpages.jp/katwat/three.js_r58/examples/mytest37/mmd.three.js | ||
*/ | ||
@@ -363,0 +362,0 @@ const DEFAULT_TOON_TEXTURES = [ |
@@ -211,3 +211,7 @@ import { | ||
//if no space direction is set, let's use the identity | ||
headerObject.vectors = [ new Vector3( 1, 0, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ) ]; | ||
headerObject.vectors = [ ]; | ||
headerObject.vectors.push( [ 1, 0, 0 ] ); | ||
headerObject.vectors.push( [ 0, 1, 0 ] ); | ||
headerObject.vectors.push( [ 0, 0, 1 ] ); | ||
//apply spacing if defined | ||
@@ -220,4 +224,8 @@ if ( headerObject.spacings ) { | ||
headerObject.vectors[ i ].multiplyScalar( headerObject.spacings[ i ] ); | ||
for ( let j = 0; j <= 2; j ++ ) { | ||
headerObject.vectors[ i ][ j ] *= headerObject.spacings[ i ]; | ||
} | ||
} | ||
@@ -224,0 +232,0 @@ |
@@ -687,4 +687,2 @@ import { | ||
* http://paulbourke.net/dataformats/obj/ | ||
* or | ||
* http://www.cs.utah.edu/~boulos/cs3505/obj_spec.pdf | ||
* | ||
@@ -691,0 +689,0 @@ * From chapter "Grouping" Syntax explanation "s group_number": |
@@ -91,3 +91,3 @@ import { | ||
const patternHeader = /ply([\s\S]*)end_header\r?\n/; | ||
const patternHeader = /^ply([\s\S]*)end_header\r?\n/; | ||
let headerText = ''; | ||
@@ -94,0 +94,0 @@ let headerLength = 0; |
@@ -8,7 +8,3 @@ import { | ||
LinearFilter, | ||
NearestFilter, | ||
RGBEEncoding, | ||
RGBEFormat, | ||
RGBFormat, | ||
UnsignedByteType | ||
} from 'three'; | ||
@@ -382,9 +378,2 @@ | ||
case UnsignedByteType: | ||
data = image_rgba_data; | ||
format = RGBEFormat; // handled as THREE.RGBAFormat in shaders | ||
type = UnsignedByteType; | ||
break; | ||
case FloatType: | ||
@@ -460,11 +449,2 @@ | ||
case UnsignedByteType: | ||
texture.encoding = RGBEEncoding; | ||
texture.minFilter = NearestFilter; | ||
texture.magFilter = NearestFilter; | ||
texture.generateMipmaps = false; | ||
texture.flipY = true; | ||
break; | ||
case FloatType: | ||
@@ -471,0 +451,0 @@ |
import { | ||
DataTextureLoader, | ||
UnsignedByteType, | ||
RGBAFormat, | ||
LinearFilter, | ||
CubeTexture, | ||
RGBM7Encoding | ||
HalfFloatType, | ||
DataUtils | ||
} from 'three'; | ||
@@ -12,2 +12,25 @@ | ||
constructor( manager ) { | ||
super( manager ); | ||
this.type = HalfFloatType; | ||
this.maxRange = 7; // more information about this property at https://iwasbeingirony.blogspot.com/2010/06/difference-between-rgbm-and-rgbd.html | ||
} | ||
setDataType( value ) { | ||
this.type = value; | ||
return this; | ||
} | ||
setMaxRange( value ) { | ||
this.maxRange = value; | ||
return this; | ||
} | ||
loadCubemap( urls, onLoad, onProgress, onError ) { | ||
@@ -47,3 +70,3 @@ | ||
texture.encoding = RGBM7Encoding; | ||
texture.type = this.type; | ||
texture.format = RGBAFormat; | ||
@@ -62,10 +85,41 @@ texture.minFilter = LinearFilter; | ||
const data = new Uint8Array( rgba ); | ||
const size = img.width * img.height * 4; | ||
const output = ( this.type === HalfFloatType ) ? new Uint16Array( size ) : new Float32Array( size ); | ||
// decode RGBM | ||
for ( let i = 0; i < data.length; i += 4 ) { | ||
const r = data[ i + 0 ] / 255; | ||
const g = data[ i + 1 ] / 255; | ||
const b = data[ i + 2 ] / 255; | ||
const a = data[ i + 3 ] / 255; | ||
if ( this.type === HalfFloatType ) { | ||
output[ i + 0 ] = DataUtils.toHalfFloat( Math.min( r * a * this.maxRange, 65504 ) ); | ||
output[ i + 1 ] = DataUtils.toHalfFloat( Math.min( g * a * this.maxRange, 65504 ) ); | ||
output[ i + 2 ] = DataUtils.toHalfFloat( Math.min( b * a * this.maxRange, 65504 ) ); | ||
output[ i + 3 ] = DataUtils.toHalfFloat( 1 ); | ||
} else { | ||
output[ i + 0 ] = r * a * this.maxRange; | ||
output[ i + 1 ] = g * a * this.maxRange; | ||
output[ i + 2 ] = b * a * this.maxRange; | ||
output[ i + 3 ] = 1; | ||
} | ||
} | ||
return { | ||
width: img.width, | ||
height: img.height, | ||
data: new Uint8Array( rgba ), | ||
data: output, | ||
format: RGBAFormat, | ||
type: UnsignedByteType, | ||
flipY: true, | ||
encoding: RGBM7Encoding | ||
type: this.type, | ||
flipY: true | ||
}; | ||
@@ -72,0 +126,0 @@ |
@@ -143,3 +143,3 @@ import { | ||
this.debugMessage( 'Unknown main chunk: ' + next.hexId); | ||
this.debugMessage( 'Unknown main chunk: ' + next.hexId ); | ||
@@ -222,3 +222,5 @@ } | ||
this.meshes.push( mesh ); | ||
} else { | ||
this.debugMessage( 'Unknown named object chunk: ' + next.hexId ); | ||
@@ -244,3 +246,3 @@ | ||
let next = chunk.readChunk(); | ||
let material = new MeshPhongMaterial(); | ||
const material = new MeshPhongMaterial(); | ||
@@ -491,3 +493,3 @@ while ( next ) { | ||
while ( !chunk.endOfChunk ) { | ||
while ( ! chunk.endOfChunk ) { | ||
@@ -703,2 +705,3 @@ const subchunk = chunk.readChunk( ); | ||
} | ||
} | ||
@@ -709,2 +712,3 @@ | ||
class Chunk { | ||
/** | ||
@@ -718,3 +722,4 @@ * Create a new chunk | ||
*/ | ||
constructor(data, position, debugMessage) { | ||
constructor( data, position, debugMessage ) { | ||
this.data = data; | ||
@@ -727,4 +732,6 @@ // the offset to the begin of this chunk | ||
if (this.debugMessage instanceof Function) { | ||
this.debugMessage = function() {}; | ||
if ( this.debugMessage instanceof Function ) { | ||
this.debugMessage = function () {}; | ||
} | ||
@@ -736,5 +743,8 @@ | ||
if (this.end > data.byteLength) { | ||
if ( this.end > data.byteLength ) { | ||
this.debugMessage( 'Bad chunk size for chunk at ' + position ); | ||
} | ||
} | ||
@@ -748,10 +758,13 @@ | ||
*/ | ||
readChunk () { | ||
readChunk() { | ||
if ( this.endOfChunk ) { | ||
return null; | ||
} | ||
try { | ||
let next = new Chunk( this.data, this.position, this.debugMessage ); | ||
const next = new Chunk( this.data, this.position, this.debugMessage ); | ||
this.position += next.size; | ||
@@ -761,2 +774,3 @@ return next; | ||
} catch ( e ) { | ||
this.debugMessage( 'Unable to read chunk at ' + this.position ); | ||
@@ -776,7 +790,11 @@ return null; | ||
get hexId() { | ||
return this.id.toString( 16 ); | ||
} | ||
get endOfChunk() { | ||
return this.position >= this.end; | ||
} | ||
@@ -888,7 +906,10 @@ | ||
while ( c ) { | ||
s += String.fromCharCode( c ); | ||
c = this.readByte(); | ||
} | ||
return s; | ||
} | ||
@@ -895,0 +916,0 @@ |
@@ -299,2 +299,3 @@ import { | ||
this.unpackAlignment = 1; | ||
this.needsUpdate = true; | ||
@@ -301,0 +302,0 @@ } |
@@ -1,2 +0,2 @@ | ||
// http://mrl.nyu.edu/~perlin/noise/ | ||
// https://cs.nyu.edu/~perlin/noise/ | ||
@@ -3,0 +3,0 @@ const _p = [ 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, |
@@ -348,3 +348,5 @@ import { | ||
const data = new Float32Array( sizeX * sizeY * 4 ); | ||
return new DataTexture( data, sizeX, sizeY, RGBAFormat, FloatType ); | ||
const texture = new DataTexture( data, sizeX, sizeY, RGBAFormat, FloatType ); | ||
texture.needsUpdate = true; | ||
return texture; | ||
@@ -351,0 +353,0 @@ }; |
@@ -1,1 +0,1 @@ | ||
{"objects":{"52":{"x":1873,"y":248,"width":"300px","elements":[53,55,56,57,58],"id":52,"type":"StandardMaterialEditor"},"53":{"style":"blue","title":"Standard Material","id":53,"type":"TitleElement"},"55":{"inputLength":3,"links":[103],"label":"Color","id":55,"type":"LabelElement"},"56":{"inputLength":1,"label":"Opacity","id":56,"type":"LabelElement"},"57":{"inputLength":1,"label":"Metalness","id":57,"type":"LabelElement"},"58":{"inputLength":1,"links":[177],"label":"Roughness","id":58,"type":"LabelElement"},"64":{"x":506,"y":328,"width":"200px","elements":[65,67,68],"id":64,"type":"DotEditor"},"65":{"outputLength":1,"title":"Dot Product","id":65,"type":"TitleElement"},"67":{"inputLength":3,"links":[85],"label":"A","id":67,"type":"LabelElement"},"68":{"inputLength":3,"links":[73],"label":"B","id":68,"type":"LabelElement"},"72":{"x":33,"y":453,"width":"300px","elements":[73,78],"id":72,"type":"Vector3Editor"},"73":{"outputLength":3,"title":"Vector 3","icon":"ti ti-box-multiple-3","id":73,"type":"TitleElement"},"75":{"value":0,"id":75,"type":"NumberInput"},"76":{"value":0,"id":76,"type":"NumberInput"},"77":{"value":1.54,"id":77,"type":"NumberInput"},"78":{"inputs":[75,76,77],"label":"Values","id":78,"type":"LabelElement"},"84":{"x":75,"y":278,"width":"250px","elements":[85,88],"id":84,"type":"NormalEditor"},"85":{"outputLength":3,"style":"red","title":"Normal","id":85,"type":"TitleElement"},"87":{"options":[{"name":"Local","value":"local"},{"name":"World","value":"world"},{"name":"View","value":"view"}],"value":"view","id":87,"type":"SelectInput"},"88":{"inputs":[87],"label":"Scope","id":88,"type":"LabelElement"},"92":{"x":846,"y":353,"width":"300px","elements":[93,97,96],"id":92,"type":"InvertEditor"},"93":{"outputLength":1,"title":"Invert / Negate","id":93,"type":"TitleElement"},"95":{"options":[{"name":"Invert ( 1 - Source )","value":"invert"},{"name":"Negate ( - Source )","value":"negate"}],"value":"invert","id":95,"type":"SelectInput"},"96":{"inputLength":1,"links":[65],"label":"Source","id":96,"type":"LabelElement"},"97":{"inputs":[95],"label":"Method","id":97,"type":"LabelElement"},"102":{"x":1459,"y":146,"width":"300px","elements":[103,105,106,107],"id":102,"type":"BlendEditor"},"103":{"outputLength":3,"title":"Blend","id":103,"type":"TitleElement"},"105":{"inputLength":3,"links":[113],"label":"Base","id":105,"type":"LabelElement"},"106":{"inputLength":3,"links":[133],"label":"Blend","id":106,"type":"LabelElement"},"107":{"inputLength":1,"links":[161],"label":"Opacity","id":107,"type":"LabelElement"},"112":{"x":846,"y":17,"width":"300px","elements":[113,120,121,122],"id":112,"type":"ColorEditor"},"113":{"outputLength":1,"title":"Color","icon":"ti ti-palette","id":113,"type":"TitleElement"},"115":{"value":5058,"id":115,"type":"ColorInput"},"116":{"value":"#13C200","id":116,"type":"StringInput"},"117":{"min":0,"max":1,"step":0.01,"value":0,"id":117,"type":"NumberInput"},"118":{"min":0,"max":1,"step":0.01,"value":0.075,"id":118,"type":"NumberInput"},"119":{"min":0,"max":1,"step":0.01,"value":0.761,"id":119,"type":"NumberInput"},"120":{"inputs":[115],"label":"Value","id":120,"type":"LabelElement"},"121":{"inputs":[116],"label":"Hex","id":121,"type":"LabelElement"},"122":{"inputs":[117,118,119],"label":"RGB","id":122,"type":"LabelElement"},"132":{"x":844,"y":189,"width":"300px","elements":[133,140,141,142],"id":132,"type":"ColorEditor"},"133":{"outputLength":1,"title":"Color","icon":"ti ti-palette","id":133,"type":"TitleElement"},"135":{"value":16711680,"id":135,"type":"ColorInput"},"136":{"value":"#FF0000","id":136,"type":"StringInput"},"137":{"min":0,"max":1,"step":0.01,"value":1,"id":137,"type":"NumberInput"},"138":{"min":0,"max":1,"step":0.01,"value":0,"id":138,"type":"NumberInput"},"139":{"min":0,"max":1,"step":0.01,"value":0,"id":139,"type":"NumberInput"},"140":{"inputs":[135],"label":"Value","id":140,"type":"LabelElement"},"141":{"inputs":[136],"label":"Hex","id":141,"type":"LabelElement"},"142":{"inputs":[137,138,139],"label":"RGB","id":142,"type":"LabelElement"},"160":{"x":1241,"y":361,"width":"200px","elements":[161,163,164],"id":160,"type":"PowerEditor"},"161":{"outputLength":1,"title":"Power","id":161,"type":"TitleElement"},"163":{"inputLength":1,"links":[93],"label":"A","id":163,"type":"LabelElement"},"164":{"inputLength":1,"links":[169],"label":"B","id":164,"type":"LabelElement"},"168":{"x":852,"y":503,"width":"250px","elements":[169,172],"id":168,"type":"FloatEditor"},"169":{"outputLength":1,"title":"Float","icon":"ti ti-box-multiple-1","id":169,"type":"TitleElement"},"171":{"value":1.32,"id":171,"type":"NumberInput"},"172":{"inputs":[171],"label":"Value","id":172,"type":"LabelElement"},"176":{"x":1482,"y":449,"width":"300px","elements":[177,187,183,184,185],"id":176,"type":"SliderEditor"},"177":{"outputLength":1,"title":"Slider","icon":"ti ti-adjustments-horizontal","id":177,"type":"TitleElement"},"179":{"min":0,"max":1,"value":1,"id":179,"type":"SliderInput"},"181":{"value":0,"id":181,"type":"NumberInput"},"182":{"value":1,"id":182,"type":"NumberInput"},"183":{"inputs":[181],"label":"Min.","id":183,"type":"LabelElement"},"184":{"inputs":[182],"label":"Max.","id":184,"type":"LabelElement"},"185":{"inputs":[186],"id":185,"type":"Element"},"186":{"value":"More","id":186,"type":"ButtonInput"},"187":{"inputs":[179],"label":"Value","id":187,"type":"LabelElement"}},"nodes":[52,64,72,84,92,102,112,132,160,168,176],"id":0,"type":"Canvas"} | ||
{"objects":{"52":{"x":1873,"y":248,"width":"300px","elements":[53,55,56,57,58],"id":52,"type":"StandardMaterialEditor"},"53":{"style":"blue","title":"Standard Material","id":53,"type":"TitleElement"},"55":{"inputLength":3,"links":[103],"label":"Color","id":55,"type":"LabelElement"},"56":{"inputLength":1,"label":"Opacity","id":56,"type":"LabelElement"},"57":{"inputLength":1,"label":"Metalness","id":57,"type":"LabelElement"},"58":{"inputLength":1,"links":[177],"label":"Roughness","id":58,"type":"LabelElement"},"64":{"x":506,"y":328,"width":"200px","elements":[65,67,68],"id":64,"type":"DotEditor"},"65":{"outputLength":1,"title":"Dot Product","id":65,"type":"TitleElement"},"67":{"inputLength":3,"links":[85],"label":"A","id":67,"type":"LabelElement"},"68":{"inputLength":3,"links":[73],"label":"B","id":68,"type":"LabelElement"},"72":{"x":33,"y":453,"width":"300px","elements":[73,78],"id":72,"type":"Vector3Editor"},"73":{"outputLength":3,"title":"Vector 3","icon":"ti ti-box-multiple-3","id":73,"type":"TitleElement"},"75":{"value":0,"id":75,"type":"NumberInput"},"76":{"value":0,"id":76,"type":"NumberInput"},"77":{"value":1.0,"id":77,"type":"NumberInput"},"78":{"inputs":[75,76,77],"label":"Values","id":78,"type":"LabelElement"},"84":{"x":75,"y":278,"width":"250px","elements":[85,88],"id":84,"type":"NormalEditor"},"85":{"outputLength":3,"style":"red","title":"Normal","id":85,"type":"TitleElement"},"87":{"options":[{"name":"Local","value":"local"},{"name":"World","value":"world"},{"name":"View","value":"view"}],"value":"view","id":87,"type":"SelectInput"},"88":{"inputs":[87],"label":"Scope","id":88,"type":"LabelElement"},"92":{"x":846,"y":353,"width":"300px","elements":[93,97,96],"id":92,"type":"InvertEditor"},"93":{"outputLength":1,"title":"Invert / Negate","id":93,"type":"TitleElement"},"95":{"options":[{"name":"Invert ( 1 - Source )","value":"invert"},{"name":"Negate ( - Source )","value":"negate"}],"value":"invert","id":95,"type":"SelectInput"},"96":{"inputLength":1,"links":[65],"label":"Source","id":96,"type":"LabelElement"},"97":{"inputs":[95],"label":"Method","id":97,"type":"LabelElement"},"102":{"x":1459,"y":146,"width":"300px","elements":[103,105,106,107],"id":102,"type":"BlendEditor"},"103":{"outputLength":3,"title":"Blend","id":103,"type":"TitleElement"},"105":{"inputLength":3,"links":[113],"label":"Base","id":105,"type":"LabelElement"},"106":{"inputLength":3,"links":[133],"label":"Blend","id":106,"type":"LabelElement"},"107":{"inputLength":1,"links":[161],"label":"Opacity","id":107,"type":"LabelElement"},"112":{"x":846,"y":17,"width":"300px","elements":[113,120,121,122],"id":112,"type":"ColorEditor"},"113":{"outputLength":1,"title":"Color","icon":"ti ti-palette","id":113,"type":"TitleElement"},"115":{"value":5058,"id":115,"type":"ColorInput"},"116":{"value":"#13C200","id":116,"type":"StringInput"},"117":{"min":0,"max":1,"step":0.01,"value":0,"id":117,"type":"NumberInput"},"118":{"min":0,"max":1,"step":0.01,"value":0.075,"id":118,"type":"NumberInput"},"119":{"min":0,"max":1,"step":0.01,"value":0.761,"id":119,"type":"NumberInput"},"120":{"inputs":[115],"label":"Value","id":120,"type":"LabelElement"},"121":{"inputs":[116],"label":"Hex","id":121,"type":"LabelElement"},"122":{"inputs":[117,118,119],"label":"RGB","id":122,"type":"LabelElement"},"132":{"x":844,"y":189,"width":"300px","elements":[133,140,141,142],"id":132,"type":"ColorEditor"},"133":{"outputLength":1,"title":"Color","icon":"ti ti-palette","id":133,"type":"TitleElement"},"135":{"value":16711680,"id":135,"type":"ColorInput"},"136":{"value":"#FF0000","id":136,"type":"StringInput"},"137":{"min":0,"max":1,"step":0.01,"value":1,"id":137,"type":"NumberInput"},"138":{"min":0,"max":1,"step":0.01,"value":0,"id":138,"type":"NumberInput"},"139":{"min":0,"max":1,"step":0.01,"value":0,"id":139,"type":"NumberInput"},"140":{"inputs":[135],"label":"Value","id":140,"type":"LabelElement"},"141":{"inputs":[136],"label":"Hex","id":141,"type":"LabelElement"},"142":{"inputs":[137,138,139],"label":"RGB","id":142,"type":"LabelElement"},"160":{"x":1241,"y":361,"width":"200px","elements":[161,163,164],"id":160,"type":"PowerEditor"},"161":{"outputLength":1,"title":"Power","id":161,"type":"TitleElement"},"163":{"inputLength":1,"links":[93],"label":"A","id":163,"type":"LabelElement"},"164":{"inputLength":1,"links":[169],"label":"B","id":164,"type":"LabelElement"},"168":{"x":852,"y":503,"width":"250px","elements":[169,172],"id":168,"type":"FloatEditor"},"169":{"outputLength":1,"title":"Float","icon":"ti ti-box-multiple-1","id":169,"type":"TitleElement"},"171":{"value":1.32,"id":171,"type":"NumberInput"},"172":{"inputs":[171],"label":"Value","id":172,"type":"LabelElement"},"176":{"x":1482,"y":449,"width":"300px","elements":[177,187,183,184,185],"id":176,"type":"SliderEditor"},"177":{"outputLength":1,"title":"Slider","icon":"ti ti-adjustments-horizontal","id":177,"type":"TitleElement"},"179":{"min":0,"max":1,"value":1,"id":179,"type":"SliderInput"},"181":{"value":0,"id":181,"type":"NumberInput"},"182":{"value":1,"id":182,"type":"NumberInput"},"183":{"inputs":[181],"label":"Min.","id":183,"type":"LabelElement"},"184":{"inputs":[182],"label":"Max.","id":184,"type":"LabelElement"},"185":{"inputs":[186],"id":185,"type":"Element"},"186":{"value":"More","id":186,"type":"ButtonInput"},"187":{"inputs":[179],"label":"Value","id":187,"type":"LabelElement"}},"nodes":[52,64,72,84,92,102,112,132,160,168,176],"id":0,"type":"Canvas"} |
@@ -1,8 +0,5 @@ | ||
import { ObjectNode, LabelElement } from '../../libs/flow.module.js'; | ||
import { MeshStandardNodeMaterial, ColorNode, FloatNode } from '../../renderers/nodes/Nodes.js'; | ||
import { ObjectNode, ColorInput, SliderInput, LabelElement } from '../../libs/flow.module.js'; | ||
import { MeshStandardNodeMaterial } from '../../renderers/nodes/Nodes.js'; | ||
import * as THREE from 'three'; | ||
const NULL_COLOR = new ColorNode(); | ||
const NULL_FLOAT = new FloatNode(); | ||
export class StandardMaterialEditor extends ObjectNode { | ||
@@ -25,2 +22,28 @@ | ||
color.add( new ColorInput( material.color.getHex() ).onChange( ( input ) => { | ||
material.color.setHex( input.getValue() ); | ||
} ) ); | ||
opacity.add( new SliderInput( material.opacity, 0, 1 ).onChange( ( input ) => { | ||
material.opacity = input.getValue(); | ||
this.updateTransparent(); | ||
} ) ); | ||
metalness.add( new SliderInput( material.metalness, 0, 1 ).onChange( ( input ) => { | ||
material.metalness = input.getValue(); | ||
} ) ); | ||
roughness.add( new SliderInput( material.roughness, 0, 1 ).onChange( ( input ) => { | ||
material.roughness = input.getValue(); | ||
} ) ); | ||
color.onConnect( () => this.update(), true ); | ||
@@ -51,12 +74,18 @@ opacity.onConnect( () => this.update(), true ); | ||
material.colorNode = color.linkedExtra || NULL_COLOR; | ||
color.setEnabledInputs( ! color.linkedExtra ); | ||
opacity.setEnabledInputs( ! opacity.linkedExtra ); | ||
roughness.setEnabledInputs( ! roughness.linkedExtra ); | ||
metalness.setEnabledInputs( ! metalness.linkedExtra ); | ||
material.colorNode = color.linkedExtra; | ||
material.opacityNode = opacity.linkedExtra || null; | ||
material.transparent = opacity.linkedExtra ? true : false; | ||
material.metalnessNode = metalness.linkedExtra || NULL_FLOAT; | ||
material.roughnessNode = roughness.linkedExtra || NULL_FLOAT; | ||
material.metalnessNode = metalness.linkedExtra; | ||
material.roughnessNode = roughness.linkedExtra; | ||
material.dispose(); | ||
this.updateTransparent(); | ||
// TODO: Fix on NodeMaterial System | ||
@@ -71,2 +100,12 @@ material.customProgramCacheKey = () => { | ||
updateTransparent() { | ||
const { material, opacity } = this; | ||
material.transparent = opacity.linkedExtra || material.opacity < 1 ? true : false; | ||
opacity.setIcon( material.transparent ? 'ti ti-layers-intersect' : 'ti ti-layers-subtract' ); | ||
} | ||
} |
@@ -23,26 +23,27 @@ import { Canvas, CircleMenu, ButtonInput, ContextMenu, Loader } from '../libs/flow.module.js'; | ||
import { CheckerEditor } from './procedural/CheckerEditor.js'; | ||
import { EventDispatcher } from 'three'; | ||
export const ClassLib = { | ||
'StandardMaterialEditor': StandardMaterialEditor, | ||
'OperatorEditor': OperatorEditor, | ||
'NormalizeEditor': NormalizeEditor, | ||
'InvertEditor': InvertEditor, | ||
'LimiterEditor': LimiterEditor, | ||
'DotEditor': DotEditor, | ||
'PowerEditor': PowerEditor, | ||
'TrigonometryEditor': TrigonometryEditor, | ||
'FloatEditor': FloatEditor, | ||
'Vector2Editor': Vector2Editor, | ||
'Vector3Editor': Vector3Editor, | ||
'Vector4Editor': Vector4Editor, | ||
'SliderEditor': SliderEditor, | ||
'ColorEditor': ColorEditor, | ||
'BlendEditor': BlendEditor, | ||
'UVEditor': UVEditor, | ||
'PositionEditor': PositionEditor, | ||
'NormalEditor': NormalEditor, | ||
'TimerEditor': TimerEditor, | ||
'OscillatorEditor': OscillatorEditor, | ||
'CheckerEditor': CheckerEditor | ||
StandardMaterialEditor, | ||
OperatorEditor, | ||
NormalizeEditor, | ||
InvertEditor, | ||
LimiterEditor, | ||
DotEditor, | ||
PowerEditor, | ||
TrigonometryEditor, | ||
FloatEditor, | ||
Vector2Editor, | ||
Vector3Editor, | ||
Vector4Editor, | ||
SliderEditor, | ||
ColorEditor, | ||
BlendEditor, | ||
UVEditor, | ||
PositionEditor, | ||
NormalEditor, | ||
TimerEditor, | ||
OscillatorEditor, | ||
CheckerEditor | ||
}; | ||
@@ -262,3 +263,3 @@ | ||
let isContext = false; | ||
let contextPosition = {}; | ||
const contextPosition = {}; | ||
@@ -265,0 +266,0 @@ const add = ( node ) => { |
@@ -36,3 +36,3 @@ import { ObjectNode, SelectInput, LabelElement } from '../../libs/flow.module.js'; | ||
} ); | ||
this.add( new LabelElement( 'Method' ).add( methodInput ) ) | ||
@@ -39,0 +39,0 @@ .add( timeElement ); |
@@ -7,3 +7,3 @@ import { | ||
LinearEncoding, | ||
GammaEncoding | ||
sRGBEncoding | ||
} from 'three'; | ||
@@ -955,3 +955,3 @@ | ||
encoding = GammaEncoding; | ||
encoding = sRGBEncoding; | ||
@@ -958,0 +958,0 @@ } |
@@ -35,2 +35,3 @@ import { | ||
builder.define( 'CLEARCOAT' ); | ||
builder.define( 'USE_CLEARCOAT' ); | ||
@@ -37,0 +38,0 @@ } |
@@ -21,2 +21,10 @@ import { TempNode } from '../core/TempNode.js'; | ||
// variable | ||
case MathNode.ARCTAN: | ||
return this.b ? 2 : 1; | ||
// 3 | ||
case MathNode.MIX: | ||
@@ -30,2 +38,4 @@ case MathNode.CLAMP: | ||
// 2 | ||
case MathNode.MIN: | ||
@@ -43,2 +53,4 @@ case MathNode.MAX: | ||
// 1 | ||
default: | ||
@@ -45,0 +57,0 @@ |
@@ -93,3 +93,3 @@ import { TempNode } from '../core/TempNode.js'; | ||
// Bump Mapping Unparametrized Surfaces on the GPU by Morten S. Mikkelsen | ||
// http://api.unrealengine.com/attachments/Engine/Rendering/LightingAndShadows/BumpMappingWithoutTangentSpace/mm_sfgrad_bump.pdf | ||
// https://mmikk.github.io/papers3d/mm_sfgrad_bump.pdf | ||
@@ -96,0 +96,0 @@ // Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2) |
@@ -29,15 +29,11 @@ import { TempNode } from '../core/TempNode.js'; | ||
this.colorSpaceTL = this.colorSpaceTL || new ColorSpaceNode( new ExpressionNode( '', 'v4' ) ); | ||
this.colorSpaceTL.fromDecoding( builder.getTextureEncodingFromMap( this.value.value ) ); | ||
this.colorSpaceTL.input.parse( bilinearCubeUV.build( builder ) + '.tl' ); | ||
this.colorSpaceTR = this.colorSpaceTR || new ColorSpaceNode( new ExpressionNode( '', 'v4' ) ); | ||
this.colorSpaceTR.fromDecoding( builder.getTextureEncodingFromMap( this.value.value ) ); | ||
this.colorSpaceTR.input.parse( bilinearCubeUV.build( builder ) + '.tr' ); | ||
this.colorSpaceBL = this.colorSpaceBL || new ColorSpaceNode( new ExpressionNode( '', 'v4' ) ); | ||
this.colorSpaceBL.fromDecoding( builder.getTextureEncodingFromMap( this.value.value ) ); | ||
this.colorSpaceBL.input.parse( bilinearCubeUV.build( builder ) + '.bl' ); | ||
this.colorSpaceBR = this.colorSpaceBR || new ColorSpaceNode( new ExpressionNode( '', 'v4' ) ); | ||
this.colorSpaceBR.fromDecoding( builder.getTextureEncodingFromMap( this.value.value ) ); | ||
this.colorSpaceBR.input.parse( bilinearCubeUV.build( builder ) + '.br' ); | ||
@@ -234,2 +230,3 @@ | ||
}`, [ TextureCubeUVData, getFace, getUV, cubeUV_maxMipLevel, cubeUV_minMipLevel, cubeUV_maxTileSize, cubeUV_minTileSize ] ); | ||
bilinearCubeUV.useKeywords = false; | ||
@@ -236,0 +233,0 @@ |
import { | ||
GammaEncoding, | ||
LinearEncoding, | ||
RGBEEncoding, | ||
RGBM7Encoding, | ||
RGBM16Encoding, | ||
RGBDEncoding, | ||
sRGBEncoding | ||
@@ -12,5 +7,3 @@ } from 'three'; | ||
import { TempNode } from '../core/TempNode.js'; | ||
import { FloatNode } from '../inputs/FloatNode.js'; | ||
import { FunctionNode } from '../core/FunctionNode.js'; | ||
import { ExpressionNode } from '../core/ExpressionNode.js'; | ||
@@ -109,4 +102,2 @@ class ColorSpaceNode extends TempNode { | ||
// For a discussion of what this is, please read this: http://lousodrome.net/blog/light/2013/05/26/gamma-correct-and-hdr-rendering-in-a-32-bits-buffer/ | ||
const LinearToLinear = new FunctionNode( /* glsl */` | ||
@@ -120,18 +111,2 @@ vec4 LinearToLinear( in vec4 value ) { | ||
const GammaToLinear = new FunctionNode( /* glsl */` | ||
vec4 GammaToLinear( in vec4 value, in float gammaFactor ) { | ||
return vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w ); | ||
}` | ||
); | ||
const LinearToGamma = new FunctionNode( /* glsl */` | ||
vec4 LinearToGamma( in vec4 value, in float gammaFactor ) { | ||
return vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w ); | ||
}` | ||
); | ||
const sRGBToLinear = new FunctionNode( /* glsl */` | ||
@@ -153,74 +128,6 @@ vec4 sRGBToLinear( in vec4 value ) { | ||
const RGBEToLinear = new FunctionNode( /* glsl */` | ||
vec4 RGBEToLinear( in vec4 value ) { | ||
return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 ); | ||
}` | ||
); | ||
const LinearToRGBE = new FunctionNode( /* glsl */` | ||
vec4 LinearToRGBE( in vec4 value ) { | ||
float maxComponent = max( max( value.r, value.g ), value.b ); | ||
float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 ); | ||
return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 ); | ||
}` | ||
); | ||
// reference: http://iwasbeingirony.blogspot.ca/2010/06/difference-between-rgbm-and-rgbd.html | ||
const RGBMToLinear = new FunctionNode( /* glsl */` | ||
vec3 RGBMToLinear( in vec4 value, in float maxRange ) { | ||
return vec4( value.xyz * value.w * maxRange, 1.0 ); | ||
}` | ||
); | ||
const LinearToRGBM = new FunctionNode( /* glsl */` | ||
vec3 LinearToRGBM( in vec4 value, in float maxRange ) { | ||
float maxRGB = max( value.x, max( value.g, value.b ) ); | ||
float M = clamp( maxRGB / maxRange, 0.0, 1.0 ); | ||
M = ceil( M * 255.0 ) / 255.0; | ||
return vec4( value.rgb / ( M * maxRange ), M ); | ||
}` | ||
); | ||
// reference: http://iwasbeingirony.blogspot.ca/2010/06/difference-between-rgbm-and-rgbd.html | ||
const RGBDToLinear = new FunctionNode( /* glsl */` | ||
vec3 RGBDToLinear( in vec4 value, in float maxRange ) { | ||
return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 ); | ||
}` | ||
); | ||
const LinearToRGBD = new FunctionNode( /* glsl */` | ||
vec3 LinearToRGBD( in vec4 value, in float maxRange ) { | ||
float maxRGB = max( value.x, max( value.g, value.b ) ); | ||
float D = max( maxRange / maxRGB, 1.0 ); | ||
D = clamp( floor( D ) / 255.0, 0.0, 1.0 ); | ||
return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D ); | ||
}` | ||
); | ||
return { | ||
LinearToLinear: LinearToLinear, | ||
GammaToLinear: GammaToLinear, | ||
LinearToGamma: LinearToGamma, | ||
sRGBToLinear: sRGBToLinear, | ||
LinearTosRGB: LinearTosRGB, | ||
RGBEToLinear: RGBEToLinear, | ||
LinearToRGBE: LinearToRGBE, | ||
RGBMToLinear: RGBMToLinear, | ||
LinearToRGBM: LinearToRGBM, | ||
RGBDToLinear: RGBDToLinear, | ||
LinearToRGBD: LinearToRGBD | ||
LinearTosRGB: LinearTosRGB | ||
}; | ||
@@ -232,17 +139,5 @@ | ||
ColorSpaceNode.GAMMA_TO_LINEAR = 'GammaToLinear'; | ||
ColorSpaceNode.LINEAR_TO_GAMMA = 'LinearToGamma'; | ||
ColorSpaceNode.SRGB_TO_LINEAR = 'sRGBToLinear'; | ||
ColorSpaceNode.LINEAR_TO_SRGB = 'LinearTosRGB'; | ||
ColorSpaceNode.RGBE_TO_LINEAR = 'RGBEToLinear'; | ||
ColorSpaceNode.LINEAR_TO_RGBE = 'LinearToRGBE'; | ||
ColorSpaceNode.RGBM_TO_LINEAR = 'RGBMToLinear'; | ||
ColorSpaceNode.LINEAR_TO_RGBM = 'LinearToRGBM'; | ||
ColorSpaceNode.RGBD_TO_LINEAR = 'RGBDToLinear'; | ||
ColorSpaceNode.LINEAR_TO_RGBD = 'LinearToRGBD'; | ||
ColorSpaceNode.getEncodingComponents = function ( encoding ) { | ||
@@ -256,12 +151,2 @@ | ||
return [ 'sRGB' ]; | ||
case RGBEEncoding: | ||
return [ 'RGBE' ]; | ||
case RGBM7Encoding: | ||
return [ 'RGBM', new FloatNode( 7.0 ).setReadonly( true ) ]; | ||
case RGBM16Encoding: | ||
return [ 'RGBM', new FloatNode( 16.0 ).setReadonly( true ) ]; | ||
case RGBDEncoding: | ||
return [ 'RGBD', new FloatNode( 256.0 ).setReadonly( true ) ]; | ||
case GammaEncoding: | ||
return [ 'Gamma', new ExpressionNode( 'float( GAMMA_FACTOR )', 'f' ) ]; | ||
@@ -268,0 +153,0 @@ } |
@@ -5,5 +5,4 @@ import { | ||
BufferGeometry, | ||
ClampToEdgeWrapping, | ||
Color, | ||
DataTexture, | ||
FramebufferTexture, | ||
InterleavedBuffer, | ||
@@ -13,3 +12,2 @@ InterleavedBufferAttribute, | ||
MeshBasicMaterial, | ||
NearestFilter, | ||
RGBFormat, | ||
@@ -39,14 +37,5 @@ RawShaderMaterial, | ||
const tempMap = new DataTexture( new Uint8Array( 16 * 16 * 3 ), 16, 16, RGBFormat ); | ||
tempMap.minFilter = NearestFilter; | ||
tempMap.magFilter = NearestFilter; | ||
tempMap.wrapS = ClampToEdgeWrapping; | ||
tempMap.wrapT = ClampToEdgeWrapping; | ||
const tempMap = new FramebufferTexture( 16, 16, RGBFormat ); | ||
const occlusionMap = new FramebufferTexture( 16, 16, RGBFormat ); | ||
const occlusionMap = new DataTexture( new Uint8Array( 16 * 16 * 3 ), 16, 16, RGBFormat ); | ||
occlusionMap.minFilter = NearestFilter; | ||
occlusionMap.magFilter = NearestFilter; | ||
occlusionMap.wrapS = ClampToEdgeWrapping; | ||
occlusionMap.wrapT = ClampToEdgeWrapping; | ||
// material | ||
@@ -53,0 +42,0 @@ |
@@ -196,2 +196,9 @@ import { | ||
this.dispose = function () { | ||
renderTarget.dispose(); | ||
scope.material.dispose(); | ||
}; | ||
} | ||
@@ -198,0 +205,0 @@ |
@@ -265,2 +265,9 @@ import { | ||
this.dispose = function () { | ||
renderTarget.dispose(); | ||
scope.material.dispose(); | ||
}; | ||
} | ||
@@ -267,0 +274,0 @@ |
@@ -16,3 +16,3 @@ import { | ||
* First implemented by Simon Wallner | ||
* http://www.simonwallner.at/projects/atmospheric-scattering | ||
* http://simonwallner.at/project/atmospheric-scattering/ | ||
* | ||
@@ -19,0 +19,0 @@ * Improved by Martin Upitis |
@@ -21,4 +21,4 @@ import { | ||
* Work based on : | ||
* http://slayvin.net : Flat mirror for three.js | ||
* http://www.adelphi.edu/~stemkoski : An implementation of water shader based on the flat mirror | ||
* https://github.com/Slayvin: Flat mirror for three.js | ||
* https://home.adelphi.edu/~stemkoski/ : An implementation of water shader based on the flat mirror | ||
* http://29a.ch/ && http://29a.ch/slides/2012/webglwater/ : Water shader explanations in WebGL | ||
@@ -25,0 +25,0 @@ */ |
import { | ||
Clock, | ||
Color, | ||
LinearEncoding, | ||
Matrix4, | ||
@@ -20,4 +19,4 @@ Mesh, | ||
* References: | ||
* http://www.valvesoftware.com/publications/2010/siggraph2010_vlachos_waterflow.pdf | ||
* http://graphicsrunner.blogspot.de/2010/08/water-using-flow-maps.html | ||
* https://alex.vlachos.com/graphics/Vlachos-SIGGRAPH10-WaterFlow.pdf | ||
* http://graphicsrunner.blogspot.de/2010/08/water-using-flow-maps.html | ||
* | ||
@@ -45,3 +44,2 @@ */ | ||
const shader = options.shader || Water.WaterShader; | ||
const encoding = options.encoding !== undefined ? options.encoding : LinearEncoding; | ||
@@ -78,4 +76,3 @@ const textureLoader = new TextureLoader(); | ||
textureHeight: textureHeight, | ||
clipBias: clipBias, | ||
encoding: encoding | ||
clipBias: clipBias | ||
} ); | ||
@@ -86,4 +83,3 @@ | ||
textureHeight: textureHeight, | ||
clipBias: clipBias, | ||
encoding: encoding | ||
clipBias: clipBias | ||
} ); | ||
@@ -90,0 +86,0 @@ |
@@ -109,3 +109,5 @@ import { | ||
return new DataTexture( data_arr, dt_size, dt_size, RGBFormat, FloatType ); | ||
const texture = new DataTexture( data_arr, dt_size, dt_size, RGBFormat, FloatType ); | ||
texture.needsUpdate = true; | ||
return texture; | ||
@@ -112,0 +114,0 @@ } |
@@ -81,3 +81,3 @@ import { | ||
this.depthRenderTarget = this.normalRenderTarget.clone(); | ||
let depthTexture; | ||
@@ -84,0 +84,0 @@ |
@@ -416,2 +416,3 @@ import { | ||
this.noiseTexture.wrapT = RepeatWrapping; | ||
this.noiseTexture.needsUpdate = true; | ||
@@ -418,0 +419,0 @@ } |
@@ -29,3 +29,3 @@ import Node from './Node.js'; | ||
getInputType( builder ) { | ||
getInputType( /* builder */ ) { | ||
@@ -32,0 +32,0 @@ return this.inputType; |
@@ -627,3 +627,3 @@ import NodeUniform from './NodeUniform.js'; | ||
return `// Three.js r${ REVISION } • NodeMaterial System\n`; | ||
return `// Three.js r${ REVISION } - NodeMaterial System\n`; | ||
@@ -630,0 +630,0 @@ } |
import TempNode from '../core/Node.js'; | ||
import { ShaderNode, vec3, pow, mul, add, mix, join, lessThanEqual } from '../ShaderNode.js'; | ||
import { ShaderNode, | ||
vec3, | ||
pow, mul, add, sub, mix, join, | ||
lessThanEqual } from '../ShaderNode.js'; | ||
import { LinearEncoding, | ||
sRGBEncoding/*, RGBEEncoding, RGBM7Encoding, RGBM16Encoding, | ||
RGBDEncoding, GammaEncoding*/ } from 'three'; | ||
import { LinearEncoding, sRGBEncoding } from 'three'; | ||
@@ -30,8 +31,25 @@ export const LinearToLinear = new ShaderNode( ( inputs ) => { | ||
export const LinearTosRGB = new ShaderNode( ( inputs ) => { | ||
const { value } = inputs; | ||
const rgb = value.rgb; | ||
const a = sub( mul( pow( value.rgb, vec3( 0.41666 ) ), 1.055 ), vec3( 0.055 ) ); | ||
const b = mul( rgb, 12.92 ); | ||
const factor = vec3( lessThanEqual( rgb, vec3( 0.0031308 ) ) ); | ||
const rgbResult = mix( a, b, factor ); | ||
return join( rgbResult.r, rgbResult.g, rgbResult.b, value.a ); | ||
} ); | ||
const EncodingLib = { | ||
LinearToLinear, | ||
sRGBToLinear | ||
sRGBToLinear, | ||
LinearTosRGB | ||
}; | ||
function getEncodingComponents ( encoding ) { | ||
function getEncodingComponents( encoding ) { | ||
@@ -44,14 +62,3 @@ switch ( encoding ) { | ||
return [ 'sRGB' ]; | ||
/* | ||
case RGBEEncoding: | ||
return [ 'RGBE' ]; | ||
case RGBM7Encoding: | ||
return [ 'RGBM', new FloatNode( 7.0 ).setConst( true ) ]; | ||
case RGBM16Encoding: | ||
return [ 'RGBM', new FloatNode( 16.0 ).setConst( true ) ]; | ||
case RGBDEncoding: | ||
return [ 'RGBD', new FloatNode( 256.0 ).setConst( true ) ]; | ||
case GammaEncoding: | ||
return [ 'Gamma', new CodeNode( 'float( GAMMA_FACTOR )' ) ]; | ||
*/ | ||
} | ||
@@ -67,15 +74,3 @@ | ||
static LINEAR_TO_SRGB = 'LinearTosRGB'; | ||
/* | ||
static GAMMA_TO_LINEAR = 'GammaToLinear'; | ||
static LINEAR_TO_GAMMA = 'LinearToGamma'; | ||
static RGBE_TO_LINEAR = 'RGBEToLinear'; | ||
static LINEAR_TO_RGBE = 'LinearToRGBE'; | ||
static RGBM_TO_LINEAR = 'RGBMToLinear'; | ||
static LINEAR_TO_RGBM = 'LinearToRGBM'; | ||
static RGBD_TO_LINEAR = 'RGBDToLinear'; | ||
static LINEAR_TO_RGBD = 'LinearToRGBD'; | ||
*/ | ||
constructor( method, node ) { | ||
@@ -123,3 +118,3 @@ | ||
const encodingFunctionNode = EncodingLib[ method ]; | ||
const encodingFunctionNode = EncodingLib[ method ]; | ||
const factor = this.factor; | ||
@@ -126,0 +121,0 @@ |
@@ -78,3 +78,3 @@ import { ShaderNode, | ||
// GGX Distribution, Schlick Fresnel, GGX_SmithCorrelated Visibility | ||
export const BRDF_Specular_GGX = new ShaderNode( ( inputs ) => { | ||
export const BRDF_GGX = new ShaderNode( ( inputs ) => { | ||
@@ -113,3 +113,3 @@ const { lightDirection, f0, f90, roughness } = inputs; | ||
addTo( directSpecular, mul( irradiance, BRDF_Specular_GGX( { lightDirection, f0: specularColor, f90: 1, roughness } ) ) ); | ||
addTo( directSpecular, mul( irradiance, BRDF_GGX( { lightDirection, f0: specularColor, f90: 1, roughness } ) ) ); | ||
@@ -116,0 +116,0 @@ } ); |
@@ -24,3 +24,3 @@ import InputNode from '../core/InputNode.js'; | ||
throw new Error( `TextureNode: Need a three.js texture.` ); | ||
throw new Error( 'TextureNode: Need a three.js texture.' ); | ||
@@ -27,0 +27,0 @@ } |
@@ -130,4 +130,6 @@ import TempNode from '../core/TempNode.js'; | ||
if ( builder.renderer.isWebGLRenderer === true && ( method === MathNode.DFDX || method === MathNode.DFDY ) && output === 'vec3' ) { | ||
const isWebGL = builder.renderer.isWebGLRenderer === true; | ||
if ( isWebGL && ( method === MathNode.DFDX || method === MathNode.DFDY ) && output === 'vec3' ) { | ||
// Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988 | ||
@@ -189,7 +191,7 @@ | ||
params.push( | ||
b.build( builder, builder.getTypeLength( a.getNodeType( builder ) ) === 1 ? 'float' : inputType ), | ||
a.build( builder, builder.getTypeLength( a.getNodeType( builder ) ) === 1 ? 'float' : inputType ), | ||
b.build( builder, inputType ) | ||
); | ||
} else if ( method === MathNode.MIN || method === MathNode.MAX || method === MathNode.MOD ) { | ||
} else if ( ( isWebGL && ( method === MathNode.MIN || method === MathNode.MAX ) ) || method === MathNode.MOD ) { | ||
@@ -196,0 +198,0 @@ params.push( |
@@ -152,7 +152,7 @@ import TempNode from '../core/TempNode.js'; | ||
return `greaterThan( ${a}, ${b} )`; | ||
return `${ builder.getMethod( 'greaterThan' ) }( ${a}, ${b} )`; | ||
} else if ( op === '<=' && outputLength > 1 ) { | ||
return `lessThanEqual( ${a}, ${b} )`; | ||
return `${ builder.getMethod( 'lessThanEqual' ) }( ${a}, ${b} )`; | ||
@@ -159,0 +159,0 @@ } else { |
@@ -154,2 +154,3 @@ // core | ||
ArrayElementNode, | ||
ConvertNode, | ||
JoinNode, | ||
@@ -156,0 +157,0 @@ SplitNode, |
@@ -212,5 +212,5 @@ // core | ||
if ( params[0]?.isNode === true ) { | ||
if ( params[ 0 ]?.isNode === true ) { | ||
return ShaderNodeObject( new ConvertNode( params[0], 'vec2' ) ); | ||
return ShaderNodeObject( new ConvertNode( params[ 0 ], 'vec2' ) ); | ||
@@ -235,5 +235,5 @@ } else { | ||
if ( params[0]?.isNode === true ) { | ||
if ( params[ 0 ]?.isNode === true ) { | ||
return ShaderNodeObject( new ConvertNode( params[0], 'vec3' ) ); | ||
return ShaderNodeObject( new ConvertNode( params[ 0 ], 'vec3' ) ); | ||
@@ -258,5 +258,5 @@ } else { | ||
if ( params[0]?.isNode === true ) { | ||
if ( params[ 0 ]?.isNode === true ) { | ||
return ShaderNodeObject( new ConvertNode( params[0], 'vec4' ) ); | ||
return ShaderNodeObject( new ConvertNode( params[ 0 ], 'vec4' ) ); | ||
@@ -299,2 +299,3 @@ } else { | ||
export const normalGeometry = new NormalNode( NormalNode.GEOMETRY ); | ||
export const normalLocal = new NormalNode( NormalNode.LOCAL ); | ||
@@ -301,0 +302,0 @@ export const normalWorld = new NormalNode( NormalNode.WORLD ); |
@@ -6,3 +6,3 @@ import FloatNode from '../inputs/FloatNode.js'; | ||
static LOCAL = 'local'; | ||
static LOCAL = 'local'; | ||
static GLOBAL = 'global'; | ||
@@ -9,0 +9,0 @@ static DELTA = 'delta'; |
@@ -119,11 +119,11 @@ import NodeBuilder from '../../nodes/core/NodeBuilder.js'; | ||
if ( material.sizeNode && material.sizeNode.isNode ) { | ||
if ( material.positionNode && material.positionNode.isNode ) { | ||
this.addSlot( 'vertex', new SlotNode( material.sizeNode, 'SIZE', 'float' ) ); | ||
this.addSlot( 'vertex', new SlotNode( material.positionNode, 'POSITION', 'vec3' ) ); | ||
} | ||
if ( material.positionNode && material.positionNode.isNode ) { | ||
if ( material.sizeNode && material.sizeNode.isNode ) { | ||
this.addSlot( 'vertex', new SlotNode( material.positionNode, 'POSITION', 'vec3' ) ); | ||
this.addSlot( 'vertex', new SlotNode( material.sizeNode, 'SIZE', 'float' ) ); | ||
@@ -220,3 +220,3 @@ } | ||
getVarys( shaderStage ) { | ||
getVarys( /* shaderStage */ ) { | ||
@@ -290,3 +290,3 @@ let snippet = ''; | ||
getTextureEncodingFromMap( map ) { | ||
/* | ||
const isWebGL2 = this.renderer.capabilities.isWebGL2; | ||
@@ -299,3 +299,3 @@ | ||
} | ||
*/ | ||
return super.getTextureEncodingFromMap( map ); | ||
@@ -383,4 +383,4 @@ | ||
const colorSlot = this.getSlot( 'fragment', 'COLOR' ); | ||
const opacityNode = this.getSlot( 'fragment', 'OPACITY' ); | ||
const normalSlot = this.getSlot( 'fragment', 'NORMAL' ); | ||
const opacityNode = this.getSlot( 'fragment', 'OPACITY' ); | ||
const emissiveNode = this.getSlot( 'fragment', 'EMISSIVE' ); | ||
@@ -405,8 +405,8 @@ const roughnessNode = this.getSlot( 'fragment', 'ROUGHNESS' ); | ||
if ( normalSlot !== undefined ) { | ||
if ( opacityNode !== undefined ) { | ||
this.addCodeAfterInclude( | ||
'fragment', | ||
'normal_fragment_begin', | ||
`${normalSlot.code}\n\tnormal = ${normalSlot.result};` | ||
'alphatest_fragment', | ||
`${opacityNode.code}\n\tdiffuseColor.a = ${opacityNode.result};` | ||
); | ||
@@ -416,8 +416,8 @@ | ||
if ( opacityNode !== undefined ) { | ||
if ( normalSlot !== undefined ) { | ||
this.addCodeAfterInclude( | ||
'fragment', | ||
'alphamap_fragment', | ||
`${opacityNode.code}\n\tdiffuseColor.a = ${opacityNode.result};` | ||
'normal_fragment_begin', | ||
`${normalSlot.code}\n\tnormal = ${normalSlot.result};` | ||
); | ||
@@ -424,0 +424,0 @@ |
@@ -0,1 +1,3 @@ | ||
import { LinearEncoding } from 'three'; | ||
import WebGPUNodeUniformsGroup from './WebGPUNodeUniformsGroup.js'; | ||
@@ -22,5 +24,8 @@ import { | ||
import SkinningNode from '../../nodes/accessors/SkinningNode.js'; | ||
import ColorSpaceNode from '../../nodes/display/ColorSpaceNode.js'; | ||
import LightContextNode from '../../nodes/lights/LightContextNode.js'; | ||
import OperatorNode from '../../nodes/math/OperatorNode.js'; | ||
import WGSLNodeParser from '../../nodes/parsers/WGSLNodeParser.js'; | ||
import { vec4 } from '../../nodes/ShaderNode.js'; | ||
import { getRoughness } from '../../nodes/functions/PhysicalMaterialFunctions.js'; | ||
@@ -34,2 +39,3 @@ const wgslTypeLib = { | ||
uvec4: 'vec4<u32>', | ||
bvec3: 'vec3<bool>', | ||
mat3: 'mat3x3<f32>', | ||
@@ -45,2 +51,9 @@ mat4: 'mat4x4<f32>' | ||
const wgslPolyfill = { | ||
lessThanEqual: new CodeNode( ` | ||
fn lessThanEqual( a : vec3<f32>, b : vec3<f32> ) -> vec3<bool> { | ||
return vec3<bool>( a.x <= b.x, a.y <= b.y, a.z <= b.z ); | ||
} | ||
` ), | ||
mod: new CodeNode( ` | ||
@@ -141,4 +154,6 @@ fn mod( x : f32, y : f32 ) -> f32 { | ||
colorNode = this.addFlow( 'fragment', new VarNode( colorNode, 'DiffuseColor', 'vec4' ) ); | ||
colorNode = this.addFlow( 'fragment', new VarNode( colorNode, 'Color', 'vec4' ) ); | ||
this.addFlow( 'fragment', new VarNode( colorNode, 'DiffuseColor', 'vec4' ) ); | ||
// OPACITY | ||
@@ -218,2 +233,4 @@ | ||
roughnessNode = getRoughness( { roughness: roughnessNode } ); | ||
this.addFlow( 'fragment', new VarNode( roughnessNode, 'Roughness', 'float' ) ); | ||
@@ -223,3 +240,3 @@ | ||
this.addFlow( 'fragment', new VarNode( new ExpressionNode( 'mix( vec3<f32>( 0.04 ), DiffuseColor.rgb, Metalness )', 'vec3' ), 'SpecularColor', 'color' ) ); | ||
this.addFlow( 'fragment', new VarNode( new ExpressionNode( 'mix( vec3<f32>( 0.04 ), Color.rgb, Metalness )', 'vec3' ), 'SpecularColor', 'color' ) ); | ||
@@ -258,2 +275,11 @@ // NORMAL_VIEW | ||
const outputEncoding = this.renderer.outputEncoding; | ||
if ( outputEncoding !== LinearEncoding ) { | ||
outputNode = new ColorSpaceNode( ColorSpaceNode.LINEAR_TO_LINEAR, vec4( outputNode ) ); | ||
outputNode.fromEncoding( outputEncoding ); | ||
} | ||
this.addFlow( 'fragment', new VarNode( outputNode, 'Output', 'vec4' ) ); | ||
@@ -277,3 +303,3 @@ | ||
getTexture( textureProperty, uvSnippet, biasSnippet = null, shaderStage = this.shaderStage ) { | ||
getTexture( textureProperty, uvSnippet, biasSnippet, shaderStage = this.shaderStage ) { | ||
@@ -768,3 +794,3 @@ if ( shaderStage === 'fragment' ) { | ||
return `[[ block ]] | ||
return ` | ||
struct ${name} { | ||
@@ -771,0 +797,0 @@ \n${vars} |
@@ -52,2 +52,8 @@ class WebGPUBindings { | ||
remove( object ) { | ||
this.uniformsData.delete( object ); | ||
} | ||
getForCompute( param ) { | ||
@@ -112,8 +118,3 @@ | ||
this.device.queue.writeBuffer( | ||
bufferGPU, | ||
0, | ||
buffer, | ||
0 | ||
); | ||
this.device.queue.writeBuffer( bufferGPU, 0, buffer, 0 ); | ||
@@ -120,0 +121,0 @@ } |
@@ -186,5 +186,5 @@ import { GPUIndexFormat, GPUTextureFormat, GPUStoreOp } from './constants.js'; | ||
this._nodes = new WebGPUNodes( this ); | ||
this._renderPipelines = new WebGPURenderPipelines( this, this._properties, device, parameters.sampleCount, this._nodes ); | ||
this._computePipelines = new WebGPUComputePipelines( device ); | ||
this._bindings = new WebGPUBindings( device, this._info, this._properties, this._textures, this._renderPipelines, this._computePipelines, this._attributes, this._nodes ); | ||
this._renderPipelines = new WebGPURenderPipelines( this, device, parameters.sampleCount, this._nodes ); | ||
this._bindings = this._renderPipelines.bindings = new WebGPUBindings( device, this._info, this._properties, this._textures, this._renderPipelines, this._computePipelines, this._attributes, this._nodes ); | ||
this._renderLists = new WebGPURenderLists(); | ||
@@ -191,0 +191,0 @@ this._background = new WebGPUBackground( this ); |
@@ -709,3 +709,3 @@ import { GPUPrimitiveTopology, GPUIndexFormat, GPUCompareFunction, GPUFrontFace, GPUCullMode, GPUVertexFormat, GPUBlendFactor, GPUBlendOperation, BlendColorFactor, OneMinusBlendColorFactor, GPUColorWriteFlags, GPUStencilOperation, GPUInputStepMode } from './constants.js'; | ||
for ( let slot = 0; slot < nodeAttributes.length; slot++ ) { | ||
for ( let slot = 0; slot < nodeAttributes.length; slot ++ ) { | ||
@@ -712,0 +712,0 @@ const nodeAttribute = nodeAttributes[ slot ]; |
@@ -6,9 +6,9 @@ import WebGPURenderPipeline from './WebGPURenderPipeline.js'; | ||
constructor( renderer, properties, device, sampleCount, nodes ) { | ||
constructor( renderer, device, sampleCount, nodes, bindings = null ) { | ||
this.renderer = renderer; | ||
this.properties = properties; | ||
this.device = device; | ||
this.sampleCount = sampleCount; | ||
this.nodes = nodes; | ||
this.bindings = bindings; | ||
@@ -28,6 +28,3 @@ this.pipelines = []; | ||
const device = this.device; | ||
const properties = this.properties; | ||
const material = object.material; | ||
const materialProperties = properties.get( material ); | ||
@@ -40,2 +37,10 @@ const cache = this._getCache( object ); | ||
// release previous cache | ||
if ( cache.currentPipeline !== undefined ) { | ||
this._releaseObject( object ); | ||
} | ||
// get shader | ||
@@ -70,34 +75,12 @@ | ||
// keep track of all pipelines which are used by a material | ||
// keep track of all used times | ||
let materialPipelines = materialProperties.pipelines; | ||
currentPipeline.usedTimes ++; | ||
stageVertex.usedTimes ++; | ||
stageFragment.usedTimes ++; | ||
if ( materialPipelines === undefined ) { | ||
// events | ||
materialPipelines = new Set(); | ||
materialProperties.pipelines = materialPipelines; | ||
material.addEventListener( 'dispose', cache.dispose ); | ||
} | ||
if ( materialPipelines.has( currentPipeline ) === false ) { | ||
materialPipelines.add( currentPipeline ); | ||
currentPipeline.usedTimes ++; | ||
stageVertex.usedTimes ++; | ||
stageFragment.usedTimes ++; | ||
} | ||
// dispose | ||
if ( materialProperties.disposeCallback === undefined ) { | ||
const disposeCallback = onMaterialDispose.bind( this ); | ||
materialProperties.disposeCallback = disposeCallback; | ||
material.addEventListener( 'dispose', disposeCallback ); | ||
} | ||
} else { | ||
@@ -189,3 +172,16 @@ | ||
cache = {}; | ||
cache = { | ||
dispose: () => { | ||
this._releaseObject( object ); | ||
this.objectCache.delete( object ); | ||
object.material.removeEventListener( 'dispose', cache.dispose ); | ||
} | ||
}; | ||
this.objectCache.set( object, cache ); | ||
@@ -199,2 +195,14 @@ | ||
_releaseObject( object ) { | ||
const cache = this.objectCache.get( object ); | ||
this._releasePipeline( cache.currentPipeline ); | ||
delete cache.currentPipeline; | ||
this.nodes.remove( object ); | ||
this.bindings.remove( object ); | ||
} | ||
_releasePipeline( pipeline ) { | ||
@@ -291,29 +299,2 @@ | ||
function onMaterialDispose( event ) { | ||
const properties = this.properties; | ||
const material = event.target; | ||
const materialProperties = properties.get( material ); | ||
material.removeEventListener( 'dispose', materialProperties.disposeCallback ); | ||
properties.remove( material ); | ||
// remove references to pipelines | ||
const pipelines = materialProperties.pipelines; | ||
if ( pipelines !== undefined ) { | ||
for ( const pipeline of pipelines ) { | ||
this._releasePipeline( pipeline ); | ||
} | ||
} | ||
} | ||
export default WebGPURenderPipelines; |
@@ -32,3 +32,2 @@ // Copyright 2020 Brandon Jones | ||
const mipmapVertexSource = ` | ||
[[ block ]] | ||
struct VarysStruct { | ||
@@ -35,0 +34,0 @@ |
@@ -8,3 +8,2 @@ import { | ||
* ported from o3d sample to WebGL / GLSL | ||
* http://o3d.googlecode.com/svn/trunk/samples/convolution.html | ||
*/ | ||
@@ -11,0 +10,0 @@ |
@@ -5,3 +5,3 @@ /** | ||
* - ported from HLSL to WebGL / GLSL | ||
* http://www.truevision3d.com/forums/showcase/staticnoise_colorblackwhite_scanline_shaders-t18698.0.html | ||
* https://web.archive.org/web/20210226214859/http://www.truevision3d.com/forums/showcase/staticnoise_colorblackwhite_scanline_shaders-t18698.0.html | ||
* | ||
@@ -8,0 +8,0 @@ * Screen Space Static Postprocessor |
@@ -7,3 +7,3 @@ import { | ||
* NVIDIA FXAA by Timothy Lottes | ||
* http://timothylottes.blogspot.com/2011/06/fxaa3-source-released.html | ||
* https://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf | ||
* - WebGL port by @supereggbert | ||
@@ -10,0 +10,0 @@ * http://www.glge.org/demos/fxaa/ |
@@ -35,3 +35,3 @@ /** | ||
gl_FragColor = LinearTosRGB( tex ); // optional: LinearToGamma( tex, float( GAMMA_FACTOR ) ); | ||
gl_FragColor = LinearTosRGB( tex ); | ||
@@ -38,0 +38,0 @@ }` |
/** | ||
* Two pass Gaussian blur filter (horizontal and vertical blur shaders) | ||
* - described in http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/ | ||
* and used in http://www.cake23.de/traveling-wavefronts-lit-up.html | ||
* - see http://www.cake23.de/traveling-wavefronts-lit-up.html | ||
* | ||
@@ -6,0 +5,0 @@ * - 9 samples per pass |
@@ -193,3 +193,3 @@ import { | ||
#ifdef PERSPECTIVE_CAMERA | ||
// https://www.comp.nus.edu.sg/~lowkl/publications/lowk_persp_interp_techrep.pdf | ||
// https://comp.nus.edu.sg/~lowkl/publications/lowk_persp_interp_techrep.pdf | ||
float recipVPZ=1./viewPosition.z; | ||
@@ -196,0 +196,0 @@ float viewRefractRayZ=1./(recipVPZ+s*(1./d1viewPosition.z-recipVPZ)); |
@@ -178,3 +178,3 @@ import { | ||
#ifdef PERSPECTIVE_CAMERA | ||
// https://www.comp.nus.edu.sg/~lowkl/publications/lowk_persp_interp_techrep.pdf | ||
// https://comp.nus.edu.sg/~lowkl/publications/lowk_persp_interp_techrep.pdf | ||
float recipVPZ=1./viewPosition.z; | ||
@@ -181,0 +181,0 @@ float viewReflectRayZ=1./(recipVPZ+s*(1./d1viewPosition.z-recipVPZ)); |
/** | ||
* Two pass Gaussian blur filter (horizontal and vertical blur shaders) | ||
* - described in http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/ | ||
* and used in http://www.cake23.de/traveling-wavefronts-lit-up.html | ||
* - see http://www.cake23.de/traveling-wavefronts-lit-up.html | ||
* | ||
@@ -6,0 +5,0 @@ * - 9 samples per pass |
@@ -62,3 +62,3 @@ import { | ||
* Based on work by: | ||
* @link http://www.openprocessing.org/visuals/?visualID=15599 | ||
* @link https://openprocessing.org/user/5654 | ||
* | ||
@@ -65,0 +65,0 @@ * @param center Center of Hilbert curve. |
@@ -17,3 +17,4 @@ /** | ||
Vector2, | ||
WebGLRenderTarget | ||
WebGLRenderTarget, | ||
FramebufferTexture | ||
} from 'three'; | ||
@@ -72,39 +73,25 @@ | ||
if ( width !== roughnessMap.image.width || height !== roughnessMap.image.height ) { | ||
const newRoughnessTexture = new FramebufferTexture( width, height, roughnessMap.format ); | ||
newRoughnessTexture.wrapS = roughnessMap.wrapS; | ||
newRoughnessTexture.wrapT = roughnessMap.wrapT; | ||
newRoughnessTexture.minFilter = roughnessMap.minFilter; | ||
newRoughnessTexture.magFilter = roughnessMap.magFilter; | ||
const params = { | ||
wrapS: roughnessMap.wrapS, | ||
wrapT: roughnessMap.wrapT, | ||
magFilter: roughnessMap.magFilter, | ||
minFilter: roughnessMap.minFilter, | ||
depthBuffer: false | ||
}; | ||
material.roughnessMap = newRoughnessTexture; | ||
const newRoughnessTarget = new WebGLRenderTarget( width, height, params ); | ||
if ( material.metalnessMap == roughnessMap ) material.metalnessMap = material.roughnessMap; | ||
newRoughnessTarget.texture.generateMipmaps = true; | ||
if ( material.aoMap == roughnessMap ) material.aoMap = material.roughnessMap; | ||
// Setting the render target causes the memory to be allocated. | ||
// Copy UV transform parameters | ||
_renderer.setRenderTarget( newRoughnessTarget ); | ||
material.roughnessMap.offset.copy( roughnessMap.offset ); | ||
material.roughnessMap.repeat.copy( roughnessMap.repeat ); | ||
material.roughnessMap.center.copy( roughnessMap.center ); | ||
material.roughnessMap.rotation = roughnessMap.rotation; | ||
material.roughnessMap.image = roughnessMap.image; // required for USDZExporter, see #22741 | ||
material.roughnessMap = newRoughnessTarget.texture; | ||
material.roughnessMap.matrixAutoUpdate = roughnessMap.matrixAutoUpdate; | ||
material.roughnessMap.matrix.copy( roughnessMap.matrix ); | ||
if ( material.metalnessMap == roughnessMap ) material.metalnessMap = material.roughnessMap; | ||
if ( material.aoMap == roughnessMap ) material.aoMap = material.roughnessMap; | ||
// Copy UV transform parameters | ||
material.roughnessMap.offset.copy( roughnessMap.offset ); | ||
material.roughnessMap.repeat.copy( roughnessMap.repeat ); | ||
material.roughnessMap.center.copy( roughnessMap.center ); | ||
material.roughnessMap.rotation = roughnessMap.rotation; | ||
material.roughnessMap.image = roughnessMap.image; | ||
material.roughnessMap.matrixAutoUpdate = roughnessMap.matrixAutoUpdate; | ||
material.roughnessMap.matrix.copy( roughnessMap.matrix ); | ||
} | ||
_mipmapMaterial.uniforms.roughnessMap.value = roughnessMap; | ||
@@ -142,3 +129,3 @@ | ||
if ( roughnessMap !== material.roughnessMap ) roughnessMap.dispose(); | ||
roughnessMap.dispose(); | ||
@@ -145,0 +132,0 @@ _renderer.setRenderTarget( oldTarget ); |
@@ -7,3 +7,3 @@ /** | ||
constructor ( pool = 4 ) { | ||
constructor( pool = 4 ) { | ||
@@ -18,5 +18,5 @@ this.pool = pool; | ||
_initWorker ( workerId ) { | ||
_initWorker( workerId ) { | ||
if ( !this.workers[ workerId ] ) { | ||
if ( ! this.workers[ workerId ] ) { | ||
@@ -31,8 +31,8 @@ const worker = this.workerCreator(); | ||
_getIdleWorker () { | ||
_getIdleWorker() { | ||
for ( let i = 0 ; i < this.pool ; i ++ ) | ||
for ( let i = 0; i < this.pool; i ++ ) | ||
if ( ! ( this.workerStatus & ( 1 << i ) ) ) return i; | ||
return -1; | ||
return - 1; | ||
@@ -60,3 +60,3 @@ } | ||
setWorkerCreator ( workerCreator ) { | ||
setWorkerCreator( workerCreator ) { | ||
@@ -67,3 +67,3 @@ this.workerCreator = workerCreator; | ||
setWorkerLimit ( pool ) { | ||
setWorkerLimit( pool ) { | ||
@@ -74,3 +74,3 @@ this.pool = pool; | ||
postMessage ( msg, transfer ) { | ||
postMessage( msg, transfer ) { | ||
@@ -81,3 +81,3 @@ return new Promise( ( resolve ) => { | ||
if ( workerId !== -1 ) { | ||
if ( workerId !== - 1 ) { | ||
@@ -99,3 +99,3 @@ this._initWorker( workerId ); | ||
dispose () { | ||
dispose() { | ||
@@ -102,0 +102,0 @@ this.workers.forEach( ( worker ) => worker.terminate() ); |
{ | ||
"name": "three", | ||
"version": "0.135.0", | ||
"version": "0.136.0", | ||
"description": "JavaScript 3D library", | ||
@@ -42,10 +42,16 @@ "main": "build/three.js", | ||
"globals": { | ||
"potpack": true, | ||
"fflate": true, | ||
"ZSTDDecoder": true, | ||
"bodymovin": true, | ||
"OIMO": true, | ||
"Stats": true, | ||
"XRWebGLBinding": true, | ||
"XRWebGLLayer": true | ||
"__THREE_DEVTOOLS__": "readonly", | ||
"WebGL2ComputeRenderingContext": "readonly", | ||
"potpack": "readonly", | ||
"fflate": "readonly", | ||
"bodymovin": "readonly", | ||
"OIMO": "readonly", | ||
"Stats": "readonly", | ||
"XRWebGLBinding": "readonly", | ||
"XRWebGLLayer": "readonly", | ||
"GPUShaderStage": "readonly", | ||
"GPUBufferUsage": "readonly", | ||
"GPUTextureUsage": "readonly" | ||
}, | ||
@@ -52,0 +58,0 @@ "rules": { |
@@ -1,2 +0,2 @@ | ||
export const REVISION = '135'; | ||
export const REVISION = '136'; | ||
export const MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 }; | ||
@@ -94,3 +94,2 @@ export const TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 }; | ||
export const LuminanceAlphaFormat = 1025; | ||
export const RGBEFormat = RGBAFormat; | ||
export const DepthFormat = 1026; | ||
@@ -161,7 +160,2 @@ export const DepthStencilFormat = 1027; | ||
export const sRGBEncoding = 3001; | ||
export const GammaEncoding = 3007; | ||
export const RGBEEncoding = 3002; | ||
export const RGBM7Encoding = 3004; | ||
export const RGBM16Encoding = 3005; | ||
export const RGBDEncoding = 3006; | ||
export const BasicDepthPacking = 3200; | ||
@@ -168,0 +162,0 @@ export const RGBADepthPacking = 3201; |
@@ -503,3 +503,3 @@ import { Quaternion } from '../math/Quaternion.js'; | ||
raycast() {} | ||
raycast( /* raycaster, intersects */ ) {} | ||
@@ -506,0 +506,0 @@ traverse( callback ) { |
/** | ||
* Bezier Curves formulas obtained from | ||
* http://en.wikipedia.org/wiki/Bézier_curve | ||
* https://en.wikipedia.org/wiki/B%C3%A9zier_curve | ||
*/ | ||
@@ -5,0 +5,0 @@ |
@@ -5,14 +5,10 @@ import { | ||
CubeUVReflectionMapping, | ||
GammaEncoding, | ||
LinearEncoding, | ||
LinearFilter, | ||
NoToneMapping, | ||
NearestFilter, | ||
NoBlending, | ||
RGBDEncoding, | ||
RGBEEncoding, | ||
RGBEFormat, | ||
RGBM16Encoding, | ||
RGBM7Encoding, | ||
RGBAFormat, | ||
UnsignedByteType, | ||
sRGBEncoding | ||
sRGBEncoding, | ||
HalfFloatType | ||
} from '../constants.js'; | ||
@@ -52,8 +48,3 @@ | ||
[ LinearEncoding ]: 0, | ||
[ sRGBEncoding ]: 1, | ||
[ RGBEEncoding ]: 2, | ||
[ RGBM7Encoding ]: 3, | ||
[ RGBM16Encoding ]: 4, | ||
[ RGBDEncoding ]: 5, | ||
[ GammaEncoding ]: 6 | ||
[ sRGBEncoding ]: 1 | ||
}; | ||
@@ -142,3 +133,3 @@ | ||
* Generates a PMREM from an equirectangular texture, which can be either LDR | ||
* (RGBFormat) or HDR (RGBEFormat). The ideal input image size is 1k (1024 x 512), | ||
* or HDR. The ideal input image size is 1k (1024 x 512), | ||
* as this matches best with the 256 x 256 cubemap output. | ||
@@ -154,3 +145,3 @@ */ | ||
* Generates a PMREM from an cubemap texture, which can be either LDR | ||
* (RGBFormat) or HDR (RGBEFormat). The ideal input cube size is 256 x 256, | ||
* or HDR. The ideal input cube size is 256 x 256, | ||
* as this matches best with the 256 x 256 cubemap output. | ||
@@ -240,8 +231,8 @@ */ | ||
const params = { | ||
magFilter: NearestFilter, | ||
minFilter: NearestFilter, | ||
magFilter: LinearFilter, | ||
minFilter: LinearFilter, | ||
generateMipmaps: false, | ||
type: UnsignedByteType, | ||
format: RGBEFormat, | ||
encoding: _isLDR( texture ) ? texture.encoding : RGBEEncoding, | ||
type: HalfFloatType, | ||
format: RGBAFormat, | ||
encoding: LinearEncoding, | ||
depthBuffer: false | ||
@@ -274,3 +265,2 @@ }; | ||
const originalAutoClear = renderer.autoClear; | ||
const outputEncoding = renderer.outputEncoding; | ||
const toneMapping = renderer.toneMapping; | ||
@@ -280,3 +270,2 @@ renderer.getClearColor( _clearColor ); | ||
renderer.toneMapping = NoToneMapping; | ||
renderer.outputEncoding = LinearEncoding; | ||
renderer.autoClear = false; | ||
@@ -351,3 +340,2 @@ | ||
renderer.toneMapping = toneMapping; | ||
renderer.outputEncoding = outputEncoding; | ||
renderer.autoClear = originalAutoClear; | ||
@@ -360,3 +348,3 @@ scene.background = background; | ||
/* if ( this._renderer.capabilities.isWebGL2 === true && texture.format === RGBAFormat && texture.type === UnsignedByteType && texture.encoding === sRGBEncoding ) { | ||
if ( this._renderer.capabilities.isWebGL2 === true && texture.format === RGBAFormat && texture.type === UnsignedByteType && texture.encoding === sRGBEncoding ) { | ||
@@ -369,6 +357,4 @@ uniform.value = ENCODINGS[ LinearEncoding ]; | ||
} */ | ||
} | ||
uniform.value = ENCODINGS[ texture.encoding ]; | ||
} | ||
@@ -414,3 +400,2 @@ | ||
this._setEncoding( uniforms[ 'inputEncoding' ], texture ); | ||
this._setEncoding( uniforms[ 'outputEncoding' ], cubeUVRenderTarget.texture ); | ||
@@ -547,5 +532,2 @@ _setViewport( cubeUVRenderTarget, 0, 0, 3 * SIZE_MAX, 2 * SIZE_MAX ); | ||
this._setEncoding( blurUniforms[ 'inputEncoding' ], targetIn.texture ); | ||
this._setEncoding( blurUniforms[ 'outputEncoding' ], targetIn.texture ); | ||
const outputSize = _sizeLods[ lodOut ]; | ||
@@ -563,10 +545,2 @@ const x = 3 * Math.max( 0, SIZE_MAX - 2 * outputSize ); | ||
function _isLDR( texture ) { | ||
if ( texture === undefined || texture.type !== UnsignedByteType ) return false; | ||
return texture.encoding === LinearEncoding || texture.encoding === sRGBEncoding || texture.encoding === GammaEncoding; | ||
} | ||
function _createPlanes() { | ||
@@ -684,5 +658,3 @@ | ||
'mipInt': { value: 0 }, | ||
'poleAxis': { value: poleAxis }, | ||
'inputEncoding': { value: ENCODINGS[ LinearEncoding ] }, | ||
'outputEncoding': { value: ENCODINGS[ LinearEncoding ] } | ||
'poleAxis': { value: poleAxis } | ||
}, | ||
@@ -753,4 +725,2 @@ | ||
gl_FragColor = linearToOutputTexel( gl_FragColor ); | ||
} | ||
@@ -779,4 +749,3 @@ `, | ||
'texelSize': { value: texelSize }, | ||
'inputEncoding': { value: ENCODINGS[ LinearEncoding ] }, | ||
'outputEncoding': { value: ENCODINGS[ LinearEncoding ] } | ||
'inputEncoding': { value: ENCODINGS[ LinearEncoding ] } | ||
}, | ||
@@ -821,4 +790,2 @@ | ||
gl_FragColor = linearToOutputTexel( gl_FragColor ); | ||
} | ||
@@ -845,4 +812,3 @@ `, | ||
'envMap': { value: null }, | ||
'inputEncoding': { value: ENCODINGS[ LinearEncoding ] }, | ||
'outputEncoding': { value: ENCODINGS[ LinearEncoding ] } | ||
'inputEncoding': { value: ENCODINGS[ LinearEncoding ] } | ||
}, | ||
@@ -865,5 +831,3 @@ | ||
gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 ); | ||
gl_FragColor.rgb = envMapTexelToLinear( textureCube( envMap, vec3( - vOutputDirection.x, vOutputDirection.yz ) ) ).rgb; | ||
gl_FragColor = linearToOutputTexel( gl_FragColor ); | ||
gl_FragColor = envMapTexelToLinear( textureCube( envMap, vec3( - vOutputDirection.x, vOutputDirection.yz ) ) ); | ||
@@ -951,3 +915,2 @@ } | ||
uniform int inputEncoding; | ||
uniform int outputEncoding; | ||
@@ -962,26 +925,6 @@ #include <encodings_pars_fragment> | ||
} else if ( inputEncoding == 1 ) { | ||
} else { | ||
return sRGBToLinear( value ); | ||
} else if ( inputEncoding == 2 ) { | ||
return RGBEToLinear( value ); | ||
} else if ( inputEncoding == 3 ) { | ||
return RGBMToLinear( value, 7.0 ); | ||
} else if ( inputEncoding == 4 ) { | ||
return RGBMToLinear( value, 16.0 ); | ||
} else if ( inputEncoding == 5 ) { | ||
return RGBDToLinear( value, 256.0 ); | ||
} else { | ||
return GammaToLinear( value, 2.2 ); | ||
} | ||
@@ -991,36 +934,2 @@ | ||
vec4 linearToOutputTexel( vec4 value ) { | ||
if ( outputEncoding == 0 ) { | ||
return value; | ||
} else if ( outputEncoding == 1 ) { | ||
return LinearTosRGB( value ); | ||
} else if ( outputEncoding == 2 ) { | ||
return LinearToRGBE( value ); | ||
} else if ( outputEncoding == 3 ) { | ||
return LinearToRGBM( value, 7.0 ); | ||
} else if ( outputEncoding == 4 ) { | ||
return LinearToRGBM( value, 16.0 ); | ||
} else if ( outputEncoding == 5 ) { | ||
return LinearToRGBD( value, 256.0 ); | ||
} else { | ||
return LinearToGamma( value, 2.2 ); | ||
} | ||
} | ||
vec4 envMapTexelToLinear( vec4 color ) { | ||
@@ -1027,0 +936,0 @@ |
@@ -33,2 +33,4 @@ import { Float32BufferAttribute } from '../core/BufferAttribute.js'; | ||
const uvs = []; | ||
const initNormals = []; | ||
const normals = []; | ||
@@ -40,5 +42,64 @@ // helper variables | ||
const uv = new Vector2(); | ||
const normal = new Vector3(); | ||
const curNormal = new Vector3(); | ||
const prevNormal = new Vector3(); | ||
let dx = 0; | ||
let dy = 0; | ||
// generate vertices and uvs | ||
// pre-compute normals for initial "meridian" | ||
for ( let j = 0; j <= ( points.length - 1 ); j ++ ) { | ||
switch ( j ) { | ||
case 0: // special handling for 1st vertex on path | ||
dx = points[ j + 1 ].x - points[ j ].x; | ||
dy = points[ j + 1 ].y - points[ j ].y; | ||
normal.x = dy * 1.0; | ||
normal.y = - dx; | ||
normal.z = dy * 0.0; | ||
prevNormal.copy( normal ); | ||
normal.normalize(); | ||
initNormals.push( normal.x, normal.y, normal.z ); | ||
break; | ||
case ( points.length - 1 ): // special handling for last Vertex on path | ||
initNormals.push( prevNormal.x, prevNormal.y, prevNormal.z ); | ||
break; | ||
default: // default handling for all vertices in between | ||
dx = points[ j + 1 ].x - points[ j ].x; | ||
dy = points[ j + 1 ].y - points[ j ].y; | ||
normal.x = dy * 1.0; | ||
normal.y = - dx; | ||
normal.z = dy * 0.0; | ||
curNormal.copy( normal ); | ||
normal.x += prevNormal.x; | ||
normal.y += prevNormal.y; | ||
normal.z += prevNormal.z; | ||
normal.normalize(); | ||
initNormals.push( normal.x, normal.y, normal.z ); | ||
prevNormal.copy( curNormal ); | ||
} | ||
} | ||
// generate vertices, uvs and normals | ||
for ( let i = 0; i <= segments; i ++ ) { | ||
@@ -68,3 +129,10 @@ | ||
// normal | ||
const x = initNormals[ 3 * j + 0 ] * sin; | ||
const y = initNormals[ 3 * j + 1 ]; | ||
const z = initNormals[ 3 * j + 0 ] * cos; | ||
normals.push( x, y, z ); | ||
} | ||
@@ -101,49 +169,4 @@ | ||
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); | ||
this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); | ||
// generate normals | ||
this.computeVertexNormals(); | ||
// if the geometry is closed, we need to average the normals along the seam. | ||
// because the corresponding vertices are identical (but still have different UVs). | ||
if ( phiLength === Math.PI * 2 ) { | ||
const normals = this.attributes.normal.array; | ||
const n1 = new Vector3(); | ||
const n2 = new Vector3(); | ||
const n = new Vector3(); | ||
// this is the buffer offset for the last line of vertices | ||
const base = segments * points.length * 3; | ||
for ( let i = 0, j = 0; i < points.length; i ++, j += 3 ) { | ||
// select the normal of the vertex in the first line | ||
n1.x = normals[ j + 0 ]; | ||
n1.y = normals[ j + 1 ]; | ||
n1.z = normals[ j + 2 ]; | ||
// select the normal of the vertex in the last line | ||
n2.x = normals[ base + j + 0 ]; | ||
n2.y = normals[ base + j + 1 ]; | ||
n2.z = normals[ base + j + 2 ]; | ||
// average normals | ||
n.addVectors( n1, n2 ).normalize(); | ||
// assign the new values to both normals | ||
normals[ j + 0 ] = normals[ base + j + 0 ] = n.x; | ||
normals[ j + 1 ] = normals[ base + j + 1 ] = n.y; | ||
normals[ j + 2 ] = normals[ base + j + 2 ] = n.z; | ||
} | ||
} | ||
} | ||
@@ -150,0 +173,0 @@ |
@@ -16,3 +16,3 @@ import { Camera } from '../cameras/Camera.js'; | ||
* - based on frustum visualization in lightgl.js shadowmap example | ||
* http://evanw.github.com/lightgl.js/tests/shadowmap.html | ||
* https://github.com/evanw/lightgl.js/blob/master/tests/shadowmap.html | ||
*/ | ||
@@ -19,0 +19,0 @@ |
@@ -87,2 +87,8 @@ import { Cache } from './Cache.js'; | ||
if ( typeof ReadableStream === 'undefined' || response.body.getReader === undefined ) { | ||
return response; | ||
} | ||
const callbacks = loading[ url ]; | ||
@@ -96,3 +102,3 @@ const reader = response.body.getReader(); | ||
// periodically read data into the new stream tracking while download progress | ||
return new ReadableStream( { | ||
const stream = new ReadableStream( { | ||
start( controller ) { | ||
@@ -135,2 +141,4 @@ | ||
return new Response( stream ); | ||
} else { | ||
@@ -143,6 +151,4 @@ | ||
} ) | ||
.then( stream => { | ||
.then( response => { | ||
const response = new Response( stream ); | ||
switch ( this.responseType ) { | ||
@@ -195,4 +201,2 @@ | ||
this.manager.itemEnd( url ); | ||
} ) | ||
@@ -204,2 +208,11 @@ .catch( err => { | ||
const callbacks = loading[ url ]; | ||
if ( callbacks === undefined ) { | ||
// When onLoad was called and url was deleted in `loading` | ||
this.manager.itemError( url ); | ||
throw err; | ||
} | ||
delete loading[ url ]; | ||
@@ -215,2 +228,6 @@ | ||
this.manager.itemError( url ); | ||
} ) | ||
.finally( () => { | ||
this.manager.itemEnd( url ); | ||
@@ -217,0 +234,0 @@ |
@@ -301,40 +301,2 @@ import * as MathUtils from './MathUtils.js'; | ||
copyGammaToLinear( color, gammaFactor = 2.0 ) { | ||
this.r = Math.pow( color.r, gammaFactor ); | ||
this.g = Math.pow( color.g, gammaFactor ); | ||
this.b = Math.pow( color.b, gammaFactor ); | ||
return this; | ||
} | ||
copyLinearToGamma( color, gammaFactor = 2.0 ) { | ||
const safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0; | ||
this.r = Math.pow( color.r, safeInverse ); | ||
this.g = Math.pow( color.g, safeInverse ); | ||
this.b = Math.pow( color.b, safeInverse ); | ||
return this; | ||
} | ||
convertGammaToLinear( gammaFactor ) { | ||
this.copyGammaToLinear( this, gammaFactor ); | ||
return this; | ||
} | ||
convertLinearToGamma( gammaFactor ) { | ||
this.copyLinearToGamma( this, gammaFactor ); | ||
return this; | ||
} | ||
copySRGBToLinear( color ) { | ||
@@ -341,0 +303,0 @@ |
@@ -103,3 +103,3 @@ import { Vector3 } from './Vector3.js'; | ||
// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h | ||
// from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteDistRaySegment.h | ||
// It returns the min distance between the ray and the segment | ||
@@ -403,3 +403,3 @@ // defined by v0 and v1 | ||
// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h | ||
// from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h | ||
@@ -406,0 +406,0 @@ _edge1.subVectors( b, a ); |
@@ -196,4 +196,13 @@ import { Box3 } from './Box3.js'; | ||
_toFarthestPoint.subVectors( sphere.center, this.center ).normalize().multiplyScalar( sphere.radius ); | ||
if ( this.center.equals( sphere.center ) === true ) { | ||
_toFarthestPoint.set( 0, 0, 1 ).multiplyScalar( sphere.radius ); | ||
} else { | ||
_toFarthestPoint.subVectors( sphere.center, this.center ).normalize().multiplyScalar( sphere.radius ); | ||
} | ||
this.expandByPoint( _v1.copy( sphere.center ).add( _toFarthestPoint ) ); | ||
@@ -200,0 +209,0 @@ this.expandByPoint( _v1.copy( sphere.center ).sub( _toFarthestPoint ) ); |
@@ -181,2 +181,3 @@ import { | ||
const boneTexture = new DataTexture( boneMatrices, size, size, RGBAFormat, FloatType ); | ||
boneTexture.needsUpdate = true; | ||
@@ -183,0 +184,0 @@ this.boneMatrices = boneMatrices; |
@@ -8,3 +8,3 @@ export default /* glsl */` | ||
// Bump Mapping Unparametrized Surfaces on the GPU by Morten S. Mikkelsen | ||
// http://api.unrealengine.com/attachments/Engine/Rendering/LightingAndShadows/BumpMappingWithoutTangentSpace/mm_sfgrad_bump.pdf | ||
// https://mmikk.github.io/papers3d/mm_sfgrad_bump.pdf | ||
@@ -11,0 +11,0 @@ // Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2) |
@@ -92,8 +92,4 @@ export default /* glsl */` | ||
vec2 uv = getUV( direction, face ) * ( faceSize - 1.0 ); | ||
vec2 uv = getUV( direction, face ) * ( faceSize - 1.0 ) + 0.5; | ||
vec2 f = fract( uv ); | ||
uv += 0.5 - f; | ||
if ( face > 2.0 ) { | ||
@@ -121,22 +117,4 @@ | ||
vec3 tl = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb; | ||
return texture2D( envMap, uv ).rgb; | ||
uv.x += texelSize; | ||
vec3 tr = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb; | ||
uv.y += texelSize; | ||
vec3 br = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb; | ||
uv.x -= texelSize; | ||
vec3 bl = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb; | ||
vec3 tm = mix( tl, tr, f.x ); | ||
vec3 bm = mix( bl, br, f.x ); | ||
return mix( tm, bm, f.y ); | ||
} | ||
@@ -143,0 +121,0 @@ |
export default /* glsl */` | ||
// For a discussion of what this is, please read this: http://lousodrome.net/blog/light/2013/05/26/gamma-correct-and-hdr-rendering-in-a-32-bits-buffer/ | ||
@@ -8,10 +7,2 @@ vec4 LinearToLinear( in vec4 value ) { | ||
vec4 GammaToLinear( in vec4 value, in float gammaFactor ) { | ||
return vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a ); | ||
} | ||
vec4 LinearToGamma( in vec4 value, in float gammaFactor ) { | ||
return vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a ); | ||
} | ||
vec4 sRGBToLinear( in vec4 value ) { | ||
@@ -25,40 +16,2 @@ return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a ); | ||
vec4 RGBEToLinear( in vec4 value ) { | ||
return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 ); | ||
} | ||
vec4 LinearToRGBE( in vec4 value ) { | ||
float maxComponent = max( max( value.r, value.g ), value.b ); | ||
float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 ); | ||
return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 ); | ||
// return vec4( value.brg, ( 3.0 + 128.0 ) / 256.0 ); | ||
} | ||
// reference: http://iwasbeingirony.blogspot.ca/2010/06/difference-between-rgbm-and-rgbd.html | ||
vec4 RGBMToLinear( in vec4 value, in float maxRange ) { | ||
return vec4( value.rgb * value.a * maxRange, 1.0 ); | ||
} | ||
vec4 LinearToRGBM( in vec4 value, in float maxRange ) { | ||
float maxRGB = max( value.r, max( value.g, value.b ) ); | ||
float M = clamp( maxRGB / maxRange, 0.0, 1.0 ); | ||
M = ceil( M * 255.0 ) / 255.0; | ||
return vec4( value.rgb / ( M * maxRange ), M ); | ||
} | ||
// reference: http://iwasbeingirony.blogspot.ca/2010/06/difference-between-rgbm-and-rgbd.html | ||
vec4 RGBDToLinear( in vec4 value, in float maxRange ) { | ||
return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 ); | ||
} | ||
vec4 LinearToRGBD( in vec4 value, in float maxRange ) { | ||
float maxRGB = max( value.r, max( value.g, value.b ) ); | ||
float D = max( maxRange / maxRGB, 1.0 ); | ||
// NOTE: The implementation with min causes the shader to not compile on | ||
// a common Alcatel A502DL in Chrome 78/Android 8.1. Some research suggests | ||
// that the chipset is Mediatek MT6739 w/ IMG PowerVR GE8100 GPU. | ||
// D = min( floor( D ) / 255.0, 1.0 ); | ||
D = clamp( floor( D ) / 255.0, 0.0, 1.0 ); | ||
return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D ); | ||
} | ||
`; |
@@ -17,3 +17,3 @@ export default /* glsl */` | ||
return texture2D( gradientMap, coord ).rgb; | ||
return vec3( texture2D( gradientMap, coord ).r ); | ||
@@ -20,0 +20,0 @@ #else |
@@ -25,3 +25,23 @@ export default /* glsl */` | ||
vec3 clearcoatSpecular = vec3( 0.0 ); | ||
vec3 sheenSpecular = vec3( 0.0 ); | ||
// This is a curve-fit approxmation to the "Charlie sheen" BRDF integrated over the hemisphere from | ||
// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF". The analysis can be found | ||
// in the Sheen section of https://drive.google.com/file/d/1T0D1VSyR4AllqIJTQAraEIzjlb5h4FKH/view?usp=sharing | ||
float IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness) { | ||
float dotNV = saturate( dot( normal, viewDir ) ); | ||
float r2 = roughness * roughness; | ||
float a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95; | ||
float b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72; | ||
float DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) ); | ||
return saturate( DG * RECIPROCAL_PI ); | ||
} | ||
// Analytical approximation of the DFG LUT, one half of the | ||
@@ -137,3 +157,3 @@ // split-sum approximation used in indirect specular lighting. | ||
reflectedLight.directSpecular += irradiance * BRDF_Sheen( directLight.direction, geometry.viewDir, geometry.normal, material.sheenColor, material.sheenRoughness ); | ||
sheenSpecular += irradiance * BRDF_Sheen( directLight.direction, geometry.viewDir, geometry.normal, material.sheenColor, material.sheenRoughness ); | ||
@@ -162,2 +182,8 @@ #endif | ||
#ifdef USE_SHEEN | ||
sheenSpecular += irradiance * material.sheenColor * IBLSheenBRDF( geometry.normal, geometry.viewDir, material.sheenRoughness ); | ||
#endif | ||
// Both indirect specular and indirect diffuse light accumulate here | ||
@@ -164,0 +190,0 @@ |
@@ -16,3 +16,3 @@ export default /* glsl */` | ||
// source: https://www.cs.utah.edu/~reinhard/cdrom/ | ||
// source: https://www.cs.utah.edu/docs/techreports/2002/pdf/UUCS-02-001.pdf | ||
vec3 ReinhardToneMapping( vec3 color ) { | ||
@@ -19,0 +19,0 @@ |
@@ -178,2 +178,12 @@ export const vertex = /* glsl */` | ||
#ifdef USE_SHEEN | ||
// Sheen energy compensation approximation calculation can be found at the end of | ||
// https://drive.google.com/file/d/1T0D1VSyR4AllqIJTQAraEIzjlb5h4FKH/view?usp=sharing | ||
float sheenEnergyComp = 1.0 - 0.157 * max3( material.sheenColor ); | ||
outgoingLight = outgoingLight * sheenEnergyComp + sheenSpecular; | ||
#endif | ||
#ifdef USE_CLEARCOAT | ||
@@ -180,0 +190,0 @@ |
@@ -55,6 +55,4 @@ function WebGLCapabilities( gl, extensions, parameters ) { | ||
/* eslint-disable no-undef */ | ||
const isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext ) || | ||
( typeof WebGL2ComputeRenderingContext !== 'undefined' && gl instanceof WebGL2ComputeRenderingContext ); | ||
/* eslint-enable no-undef */ | ||
@@ -61,0 +59,0 @@ let precision = parameters.precision !== undefined ? parameters.precision : 'highp'; |
@@ -87,2 +87,3 @@ import { FloatType, RGBAFormat } from '../../constants.js'; | ||
texture.type = FloatType; | ||
texture.needsUpdate = true; | ||
@@ -89,0 +90,0 @@ // fill buffer |
import { WebGLUniforms } from './WebGLUniforms.js'; | ||
import { WebGLShader } from './WebGLShader.js'; | ||
import { ShaderChunk } from '../shaders/ShaderChunk.js'; | ||
import { RGBFormat, NoToneMapping, AddOperation, MixOperation, MultiplyOperation, CubeRefractionMapping, CubeUVRefractionMapping, CubeUVReflectionMapping, CubeReflectionMapping, PCFSoftShadowMap, PCFShadowMap, VSMShadowMap, ACESFilmicToneMapping, CineonToneMapping, CustomToneMapping, ReinhardToneMapping, LinearToneMapping, GammaEncoding, RGBDEncoding, RGBM16Encoding, RGBM7Encoding, RGBEEncoding, sRGBEncoding, LinearEncoding, GLSL3 } from '../../constants.js'; | ||
import { RGBFormat, NoToneMapping, AddOperation, MixOperation, MultiplyOperation, CubeRefractionMapping, CubeUVRefractionMapping, CubeUVReflectionMapping, CubeReflectionMapping, PCFSoftShadowMap, PCFShadowMap, VSMShadowMap, ACESFilmicToneMapping, CineonToneMapping, CustomToneMapping, ReinhardToneMapping, LinearToneMapping, sRGBEncoding, LinearEncoding, GLSL3 } from '../../constants.js'; | ||
@@ -30,12 +30,2 @@ let programIdCount = 0; | ||
return [ 'sRGB', '( value )' ]; | ||
case RGBEEncoding: | ||
return [ 'RGBE', '( value )' ]; | ||
case RGBM7Encoding: | ||
return [ 'RGBM', '( value, 7.0 )' ]; | ||
case RGBM16Encoding: | ||
return [ 'RGBM', '( value, 16.0 )' ]; | ||
case RGBDEncoding: | ||
return [ 'RGBD', '( value, 256.0 )' ]; | ||
case GammaEncoding: | ||
return [ 'Gamma', '( value, float( GAMMA_FACTOR ) )' ]; | ||
default: | ||
@@ -401,5 +391,2 @@ console.warn( 'THREE.WebGLProgram: Unsupported encoding:', encoding ); | ||
const gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0; | ||
const customExtensions = parameters.isWebGL2 ? '' : generateExtensions( parameters ); | ||
@@ -456,4 +443,2 @@ | ||
'#define GAMMA_FACTOR ' + gammaFactorDefine, | ||
'#define MAX_BONES ' + parameters.maxBones, | ||
@@ -607,4 +592,2 @@ ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', | ||
'#define GAMMA_FACTOR ' + gammaFactorDefine, | ||
( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', | ||
@@ -729,3 +712,3 @@ ( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '', | ||
'#define varying in', | ||
( parameters.glslVersion === GLSL3 ) ? '' : 'out highp vec4 pc_fragColor;', | ||
( parameters.glslVersion === GLSL3 ) ? '' : 'layout(location = 0) out highp vec4 pc_fragColor;', | ||
( parameters.glslVersion === GLSL3 ) ? '' : '#define gl_FragColor pc_fragColor', | ||
@@ -732,0 +715,0 @@ '#define gl_FragDepthEXT gl_FragDepth', |
@@ -1,9 +0,12 @@ | ||
import { BackSide, DoubleSide, CubeUVRefractionMapping, CubeUVReflectionMapping, LinearEncoding, ObjectSpaceNormalMap, TangentSpaceNormalMap, NoToneMapping } from '../../constants.js'; | ||
import { BackSide, DoubleSide, CubeUVRefractionMapping, CubeUVReflectionMapping, LinearEncoding, sRGBEncoding, ObjectSpaceNormalMap, TangentSpaceNormalMap, NoToneMapping, RGBAFormat, UnsignedByteType } from '../../constants.js'; | ||
import { Layers } from '../../core/Layers.js'; | ||
import { WebGLProgram } from './WebGLProgram.js'; | ||
import { WebGLShaderCache } from './WebGLShaderCache.js'; | ||
import { ShaderLib } from '../shaders/ShaderLib.js'; | ||
import { UniformsUtils } from '../shaders/UniformsUtils.js'; | ||
import { hashString } from '../../utils.js'; | ||
function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping ) { | ||
const _programLayers = new Layers(); | ||
const _customShaders = new WebGLShaderCache(); | ||
const programs = []; | ||
@@ -16,3 +19,2 @@ | ||
const vertexTextures = capabilities.vertexTextures; | ||
let precision = capabilities.precision; | ||
@@ -38,21 +40,2 @@ | ||
const parameterNames = [ | ||
'precision', 'isWebGL2', 'supportsVertexTextures', 'outputEncoding', 'instancing', 'instancingColor', | ||
'map', 'mapEncoding', 'matcap', 'matcapEncoding', 'envMap', 'envMapMode', 'envMapEncoding', 'envMapCubeUV', | ||
'lightMap', 'lightMapEncoding', 'aoMap', 'emissiveMap', 'emissiveMapEncoding', 'bumpMap', 'normalMap', | ||
'objectSpaceNormalMap', 'tangentSpaceNormalMap', | ||
'clearcoat', 'clearcoatMap', 'clearcoatRoughnessMap', 'clearcoatNormalMap', | ||
'displacementMap', 'specularMap', , 'roughnessMap', 'metalnessMap', 'gradientMap', | ||
'alphaMap', 'alphaTest', 'combine', 'vertexColors', 'vertexAlphas', 'vertexTangents', 'vertexUvs', 'uvsVertexOnly', 'fog', 'useFog', 'fogExp2', | ||
'flatShading', 'sizeAttenuation', 'logarithmicDepthBuffer', 'skinning', | ||
'maxBones', 'useVertexTexture', 'morphTargets', 'morphNormals', 'morphTargetsCount', 'premultipliedAlpha', | ||
'numDirLights', 'numPointLights', 'numSpotLights', 'numHemiLights', 'numRectAreaLights', | ||
'numDirLightShadows', 'numPointLightShadows', 'numSpotLightShadows', | ||
'shadowMapEnabled', 'shadowMapType', 'toneMapping', 'physicallyCorrectLights', | ||
'doubleSided', 'flipSided', 'numClippingPlanes', 'numClipIntersection', 'depthPacking', 'dithering', 'format', | ||
'specularIntensityMap', 'specularColorMap', 'specularColorMapEncoding', | ||
'transmission', 'transmissionMap', 'thicknessMap', | ||
'sheen', 'sheenColorMap', 'sheenColorMapEncoding', 'sheenRoughnessMap' | ||
]; | ||
function getMaxBones( object ) { | ||
@@ -113,7 +96,7 @@ | ||
/* if ( isWebGL2 && map && map.isTexture && map.format === RGBAFormat && map.type === UnsignedByteType && map.encoding === sRGBEncoding ) { | ||
if ( isWebGL2 && map && map.isTexture && map.format === RGBAFormat && map.type === UnsignedByteType && map.encoding === sRGBEncoding ) { | ||
encoding = LinearEncoding; // disable inline decode for sRGB textures in WebGL 2 | ||
} */ | ||
} | ||
@@ -151,2 +134,3 @@ return encoding; | ||
let vertexShader, fragmentShader; | ||
let customVertexShaderID, customFragmentShaderID; | ||
@@ -165,2 +149,7 @@ if ( shaderID ) { | ||
_customShaders.update( material ); | ||
customVertexShaderID = _customShaders.getVertexShaderID( material ); | ||
customFragmentShaderID = _customShaders.getFragmentShaderID( material ); | ||
} | ||
@@ -184,2 +173,5 @@ | ||
customVertexShaderID: customVertexShaderID, | ||
customFragmentShaderID: customFragmentShaderID, | ||
isRawShaderMaterial: material.isRawShaderMaterial === true, | ||
@@ -245,3 +237,3 @@ glslVersion: material.glslVersion, | ||
vertexAlphas: material.vertexColors === true && !! object.geometry && !! object.geometry.attributes.color && object.geometry.attributes.color.itemSize === 4, | ||
vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatMap || !! material.clearcoatRoughnessMap || !! material.clearcoatNormalMap || !! material.displacementMap || !! material.transmissionMap || !! material.thicknessMap || !! material.specularIntensityMap || !! material.specularColorMap || !! material.sheenColorMap || material.sheenRoughnessMap, | ||
vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatMap || !! material.clearcoatRoughnessMap || !! material.clearcoatNormalMap || !! material.displacementMap || !! material.transmissionMap || !! material.thicknessMap || !! material.specularIntensityMap || !! material.specularColorMap || !! material.sheenColorMap || !! material.sheenRoughnessMap, | ||
uvsVertexOnly: ! ( !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatNormalMap || material.transmission > 0 || !! material.transmissionMap || !! material.thicknessMap || !! material.specularIntensityMap || !! material.specularColorMap || material.sheen > 0 || !! material.sheenColorMap || !! material.sheenRoughnessMap ) && !! material.displacementMap, | ||
@@ -324,4 +316,4 @@ | ||
array.push( hashString( parameters.fragmentShader ) ); | ||
array.push( hashString( parameters.vertexShader ) ); | ||
array.push( parameters.customVertexShaderID ); | ||
array.push( parameters.customFragmentShaderID ); | ||
@@ -343,10 +335,5 @@ } | ||
for ( let i = 0; i < parameterNames.length; i ++ ) { | ||
array.push( parameters[ parameterNames[ i ] ] ); | ||
} | ||
getProgramCacheKeyParameters( array, parameters ); | ||
getProgramCacheKeyBooleans( array, parameters ); | ||
array.push( renderer.outputEncoding ); | ||
array.push( renderer.gammaFactor ); | ||
@@ -361,2 +348,157 @@ } | ||
function getProgramCacheKeyParameters( array, parameters ) { | ||
array.push( parameters.precision ); | ||
array.push( parameters.outputEncoding ); | ||
array.push( parameters.mapEncoding ); | ||
array.push( parameters.matcapEncoding ); | ||
array.push( parameters.envMapMode ); | ||
array.push( parameters.envMapEncoding ); | ||
array.push( parameters.lightMapEncoding ); | ||
array.push( parameters.emissiveMapEncoding ); | ||
array.push( parameters.combine ); | ||
array.push( parameters.vertexUvs ); | ||
array.push( parameters.fogExp2 ); | ||
array.push( parameters.sizeAttenuation ); | ||
array.push( parameters.maxBones ); | ||
array.push( parameters.morphTargetsCount ); | ||
array.push( parameters.numDirLights ); | ||
array.push( parameters.numPointLights ); | ||
array.push( parameters.numSpotLights ); | ||
array.push( parameters.numHemiLights ); | ||
array.push( parameters.numRectAreaLights ); | ||
array.push( parameters.numDirLightShadows ); | ||
array.push( parameters.numPointLightShadows ); | ||
array.push( parameters.numSpotLightShadows ); | ||
array.push( parameters.shadowMapType ); | ||
array.push( parameters.toneMapping ); | ||
array.push( parameters.numClippingPlanes ); | ||
array.push( parameters.numClipIntersection ); | ||
array.push( parameters.format ); | ||
array.push( parameters.specularColorMapEncoding ); | ||
array.push( parameters.sheenColorMapEncoding ); | ||
} | ||
function getProgramCacheKeyBooleans( array, parameters ) { | ||
_programLayers.disableAll(); | ||
if ( parameters.isWebGL2 ) | ||
_programLayers.enable( 0 ); | ||
if ( parameters.supportsVertexTextures ) | ||
_programLayers.enable( 1 ); | ||
if ( parameters.instancing ) | ||
_programLayers.enable( 2 ); | ||
if ( parameters.instancingColor ) | ||
_programLayers.enable( 3 ); | ||
if ( parameters.map ) | ||
_programLayers.enable( 4 ); | ||
if ( parameters.matcap ) | ||
_programLayers.enable( 5 ); | ||
if ( parameters.envMap ) | ||
_programLayers.enable( 6 ); | ||
if ( parameters.envMapCubeUV ) | ||
_programLayers.enable( 7 ); | ||
if ( parameters.lightMap ) | ||
_programLayers.enable( 8 ); | ||
if ( parameters.aoMap ) | ||
_programLayers.enable( 9 ); | ||
if ( parameters.emissiveMap ) | ||
_programLayers.enable( 10 ); | ||
if ( parameters.bumpMap ) | ||
_programLayers.enable( 11 ); | ||
if ( parameters.normalMap ) | ||
_programLayers.enable( 12 ); | ||
if ( parameters.objectSpaceNormalMap ) | ||
_programLayers.enable( 13 ); | ||
if ( parameters.tangentSpaceNormalMap ) | ||
_programLayers.enable( 14 ); | ||
if ( parameters.clearcoat ) | ||
_programLayers.enable( 15 ); | ||
if ( parameters.clearcoatMap ) | ||
_programLayers.enable( 16 ); | ||
if ( parameters.clearcoatRoughnessMap ) | ||
_programLayers.enable( 17 ); | ||
if ( parameters.clearcoatNormalMap ) | ||
_programLayers.enable( 18 ); | ||
if ( parameters.displacementMap ) | ||
_programLayers.enable( 19 ); | ||
if ( parameters.specularMap ) | ||
_programLayers.enable( 20 ); | ||
if ( parameters.roughnessMap ) | ||
_programLayers.enable( 21 ); | ||
if ( parameters.metalnessMap ) | ||
_programLayers.enable( 22 ); | ||
if ( parameters.gradientMap ) | ||
_programLayers.enable( 23 ); | ||
if ( parameters.alphaMap ) | ||
_programLayers.enable( 24 ); | ||
if ( parameters.alphaTest ) | ||
_programLayers.enable( 25 ); | ||
if ( parameters.vertexColors ) | ||
_programLayers.enable( 26 ); | ||
if ( parameters.vertexAlphas ) | ||
_programLayers.enable( 27 ); | ||
if ( parameters.vertexUvs ) | ||
_programLayers.enable( 28 ); | ||
if ( parameters.vertexTangents ) | ||
_programLayers.enable( 29 ); | ||
if ( parameters.uvsVertexOnly ) | ||
_programLayers.enable( 30 ); | ||
if ( parameters.fog ) | ||
_programLayers.enable( 31 ); | ||
array.push( _programLayers.mask ); | ||
_programLayers.disableAll(); | ||
if ( parameters.useFog ) | ||
_programLayers.enable( 0 ); | ||
if ( parameters.flatShading ) | ||
_programLayers.enable( 1 ); | ||
if ( parameters.logarithmicDepthBuffer ) | ||
_programLayers.enable( 2 ); | ||
if ( parameters.skinning ) | ||
_programLayers.enable( 3 ); | ||
if ( parameters.useVertexTexture ) | ||
_programLayers.enable( 4 ); | ||
if ( parameters.morphTargets ) | ||
_programLayers.enable( 5 ); | ||
if ( parameters.morphNormals ) | ||
_programLayers.enable( 6 ); | ||
if ( parameters.premultipliedAlpha ) | ||
_programLayers.enable( 7 ); | ||
if ( parameters.shadowMapEnabled ) | ||
_programLayers.enable( 8 ); | ||
if ( parameters.physicallyCorrectLights ) | ||
_programLayers.enable( 9 ); | ||
if ( parameters.doubleSided ) | ||
_programLayers.enable( 10 ); | ||
if ( parameters.flipSided ) | ||
_programLayers.enable( 11 ); | ||
if ( parameters.depthPacking ) | ||
_programLayers.enable( 12 ); | ||
if ( parameters.dithering ) | ||
_programLayers.enable( 13 ); | ||
if ( parameters.specularIntensityMap ) | ||
_programLayers.enable( 14 ); | ||
if ( parameters.specularColorMap ) | ||
_programLayers.enable( 15 ); | ||
if ( parameters.transmission ) | ||
_programLayers.enable( 16 ); | ||
if ( parameters.transmissionMap ) | ||
_programLayers.enable( 17 ); | ||
if ( parameters.thicknessMap ) | ||
_programLayers.enable( 18 ); | ||
if ( parameters.sheen ) | ||
_programLayers.enable( 19 ); | ||
if ( parameters.sheenColorMap ) | ||
_programLayers.enable( 20 ); | ||
if ( parameters.sheenRoughnessMap ) | ||
_programLayers.enable( 21 ); | ||
array.push( _programLayers.mask ); | ||
} | ||
function getUniforms( material ) { | ||
@@ -429,2 +571,14 @@ | ||
function releaseShaderCache( material ) { | ||
_customShaders.remove( material ); | ||
} | ||
function dispose() { | ||
_customShaders.dispose(); | ||
} | ||
return { | ||
@@ -436,4 +590,6 @@ getParameters: getParameters, | ||
releaseProgram: releaseProgram, | ||
releaseShaderCache: releaseShaderCache, | ||
// Exposed for resource monitoring & error feedback via renderer.info: | ||
programs: programs | ||
programs: programs, | ||
dispose: dispose | ||
}; | ||
@@ -440,0 +596,0 @@ |
@@ -11,6 +11,2 @@ function painterSortStable( a, b ) { | ||
} else if ( a.program !== b.program ) { | ||
return a.program.id - b.program.id; | ||
} else if ( a.material.id !== b.material.id ) { | ||
@@ -55,3 +51,3 @@ | ||
function WebGLRenderList( properties ) { | ||
function WebGLRenderList() { | ||
@@ -65,4 +61,2 @@ const renderItems = []; | ||
const defaultProgram = { id: - 1 }; | ||
function init() { | ||
@@ -81,3 +75,2 @@ | ||
let renderItem = renderItems[ renderItemsIndex ]; | ||
const materialProperties = properties.get( material ); | ||
@@ -91,3 +84,2 @@ if ( renderItem === undefined ) { | ||
material: material, | ||
program: materialProperties.program || defaultProgram, | ||
groupOrder: groupOrder, | ||
@@ -107,3 +99,2 @@ renderOrder: object.renderOrder, | ||
renderItem.material = material; | ||
renderItem.program = materialProperties.program || defaultProgram; | ||
renderItem.groupOrder = groupOrder; | ||
@@ -184,3 +175,2 @@ renderItem.renderOrder = object.renderOrder; | ||
renderItem.material = null; | ||
renderItem.program = null; | ||
renderItem.group = null; | ||
@@ -208,3 +198,3 @@ | ||
function WebGLRenderLists( properties ) { | ||
function WebGLRenderLists() { | ||
@@ -219,3 +209,3 @@ let lists = new WeakMap(); | ||
list = new WebGLRenderList( properties ); | ||
list = new WebGLRenderList(); | ||
lists.set( scene, [ list ] ); | ||
@@ -227,3 +217,3 @@ | ||
list = new WebGLRenderList( properties ); | ||
list = new WebGLRenderList(); | ||
lists.get( scene ).push( list ); | ||
@@ -230,0 +220,0 @@ |
@@ -881,2 +881,30 @@ import { NotEqualDepth, GreaterDepth, GreaterEqualDepth, EqualDepth, LessEqualDepth, LessDepth, AlwaysDepth, NeverDepth, CullFaceFront, CullFaceBack, CullFaceNone, DoubleSide, BackSide, CustomBlending, MultiplyBlending, SubtractiveBlending, AdditiveBlending, NoBlending, NormalBlending, AddEquation, SubtractEquation, ReverseSubtractEquation, MinEquation, MaxEquation, ZeroFactor, OneFactor, SrcColorFactor, SrcAlphaFactor, SrcAlphaSaturateFactor, DstColorFactor, DstAlphaFactor, OneMinusSrcColorFactor, OneMinusSrcAlphaFactor, OneMinusDstColorFactor, OneMinusDstAlphaFactor } from '../../constants.js'; | ||
function texSubImage3D() { | ||
try { | ||
gl.texSubImage3D.apply( gl, arguments ); | ||
} catch ( error ) { | ||
console.error( 'THREE.WebGLState:', error ); | ||
} | ||
} | ||
function compressedTexSubImage2D() { | ||
try { | ||
gl.compressedTexSubImage2D.apply( gl, arguments ); | ||
} catch ( error ) { | ||
console.error( 'THREE.WebGLState:', error ); | ||
} | ||
} | ||
function texStorage2D() { | ||
@@ -896,2 +924,16 @@ | ||
function texStorage3D() { | ||
try { | ||
gl.texStorage3D.apply( gl, arguments ); | ||
} catch ( error ) { | ||
console.error( 'THREE.WebGLState:', error ); | ||
} | ||
} | ||
function texImage2D() { | ||
@@ -1074,3 +1116,6 @@ | ||
texStorage2D: texStorage2D, | ||
texStorage3D: texStorage3D, | ||
texSubImage2D: texSubImage2D, | ||
texSubImage3D: texSubImage3D, | ||
compressedTexSubImage2D: compressedTexSubImage2D, | ||
@@ -1077,0 +1122,0 @@ scissor: scissor, |
@@ -1,2 +0,2 @@ | ||
import { LinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, NearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, RGBFormat, RGBAFormat, DepthFormat, DepthStencilFormat, UnsignedShortType, UnsignedIntType, UnsignedInt248Type, FloatType, HalfFloatType, MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping } from '../../constants.js'; | ||
import { LinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, NearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, RGBFormat, RGBAFormat, DepthFormat, DepthStencilFormat, UnsignedShortType, UnsignedIntType, UnsignedInt248Type, FloatType, HalfFloatType, MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, sRGBEncoding } from '../../constants.js'; | ||
import * as MathUtils from '../../math/MathUtils.js'; | ||
@@ -133,3 +133,3 @@ import { createElementNS } from '../../utils.js'; | ||
function getInternalFormat( internalFormatName, glFormat, glType/*, encoding*/ ) { | ||
function getInternalFormat( internalFormatName, glFormat, glType, encoding ) { | ||
@@ -168,6 +168,4 @@ if ( isWebGL2 === false ) return glFormat; | ||
if ( glType === _gl.HALF_FLOAT ) internalFormat = _gl.RGBA16F; | ||
//if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = ( encoding === sRGBEncoding ) ? _gl.SRGB8_ALPHA8 : _gl.RGBA8; | ||
if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = _gl.RGBA8; | ||
if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = ( encoding === sRGBEncoding ) ? _gl.SRGB8_ALPHA8 : _gl.RGBA8; | ||
} | ||
@@ -188,9 +186,7 @@ | ||
if ( textureNeedsGenerateMipmaps( texture, supportsMips ) === true ) { | ||
if ( textureNeedsGenerateMipmaps( texture, supportsMips ) === true || ( texture.isFramebufferTexture && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) ) { | ||
// generated mipmaps via gl.generateMipmap() | ||
return Math.log2( Math.max( image.width, image.height ) ) + 1; | ||
} else if ( texture.mipmaps.length > 0 ) { | ||
} else if ( texture.mipmaps !== undefined && texture.mipmaps.length > 0 ) { | ||
@@ -201,2 +197,6 @@ // user-defined mipmaps | ||
} else if ( texture.isCompressedTexture && Array.isArray( texture.image ) ) { | ||
return image.mipmaps.length; | ||
} else { | ||
@@ -570,2 +570,6 @@ | ||
const useTexStorage = ( isWebGL2 && texture.isVideoTexture !== true ); | ||
const allocateMemory = ( textureProperties.__version === undefined ); | ||
const levels = getMipLevels( texture, image, supportsMips ); | ||
if ( texture.isDepthTexture ) { | ||
@@ -647,4 +651,12 @@ | ||
state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null ); | ||
if ( useTexStorage && allocateMemory ) { | ||
state.texStorage2D( _gl.TEXTURE_2D, 1, glInternalFormat, image.width, image.height ); | ||
} else { | ||
state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null ); | ||
} | ||
} else if ( texture.isDataTexture ) { | ||
@@ -658,7 +670,22 @@ | ||
if ( useTexStorage && allocateMemory ) { | ||
state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height ); | ||
} | ||
for ( let i = 0, il = mipmaps.length; i < il; i ++ ) { | ||
mipmap = mipmaps[ i ]; | ||
state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); | ||
if ( useTexStorage ) { | ||
state.texSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data ); | ||
} else { | ||
state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); | ||
} | ||
} | ||
@@ -670,4 +697,18 @@ | ||
state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data ); | ||
if ( useTexStorage ) { | ||
if ( allocateMemory ) { | ||
state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height ); | ||
} | ||
state.texSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, image.width, image.height, glFormat, glType, image.data ); | ||
} else { | ||
state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data ); | ||
} | ||
} | ||
@@ -677,2 +718,8 @@ | ||
if ( useTexStorage && allocateMemory ) { | ||
state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height ); | ||
} | ||
for ( let i = 0, il = mipmaps.length; i < il; i ++ ) { | ||
@@ -686,4 +733,12 @@ | ||
state.compressedTexImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); | ||
if ( useTexStorage ) { | ||
state.compressedTexSubImage2D( _gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data ); | ||
} else { | ||
state.compressedTexImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); | ||
} | ||
} else { | ||
@@ -697,4 +752,12 @@ | ||
state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); | ||
if ( useTexStorage ) { | ||
state.texSubImage2D( _gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data ); | ||
} else { | ||
state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); | ||
} | ||
} | ||
@@ -706,8 +769,48 @@ | ||
state.texImage3D( _gl.TEXTURE_2D_ARRAY, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data ); | ||
if ( useTexStorage ) { | ||
if ( allocateMemory ) { | ||
state.texStorage3D( _gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, image.width, image.height, image.depth ); | ||
} | ||
state.texSubImage3D( _gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data ); | ||
} else { | ||
state.texImage3D( _gl.TEXTURE_2D_ARRAY, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data ); | ||
} | ||
} else if ( texture.isDataTexture3D ) { | ||
state.texImage3D( _gl.TEXTURE_3D, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data ); | ||
if ( useTexStorage ) { | ||
if ( allocateMemory ) { | ||
state.texStorage3D( _gl.TEXTURE_3D, levels, glInternalFormat, image.width, image.height, image.depth ); | ||
} | ||
state.texSubImage3D( _gl.TEXTURE_3D, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data ); | ||
} else { | ||
state.texImage3D( _gl.TEXTURE_3D, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data ); | ||
} | ||
} else if ( texture.isFramebufferTexture ) { | ||
if ( useTexStorage && allocateMemory ) { | ||
state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height ); | ||
} else { | ||
state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null ); | ||
} | ||
} else { | ||
@@ -721,6 +824,2 @@ | ||
const levels = getMipLevels( texture, image, supportsMips ); | ||
const useTexStorage = ( isWebGL2 && texture.isVideoTexture !== true ); | ||
const allocateMemory = ( textureProperties.__version === undefined ); | ||
if ( mipmaps.length > 0 && supportsMips ) { | ||
@@ -825,2 +924,6 @@ | ||
const useTexStorage = ( isWebGL2 && texture.isVideoTexture !== true ); | ||
const allocateMemory = ( textureProperties.__version === undefined ); | ||
let levels = getMipLevels( texture, image, supportsMips ); | ||
setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, supportsMips ); | ||
@@ -832,2 +935,8 @@ | ||
if ( useTexStorage && allocateMemory ) { | ||
state.texStorage2D( _gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, image.width, image.height ); | ||
} | ||
for ( let i = 0; i < 6; i ++ ) { | ||
@@ -845,4 +954,12 @@ | ||
state.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); | ||
if ( useTexStorage ) { | ||
state.compressedTexSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data ); | ||
} else { | ||
state.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); | ||
} | ||
} else { | ||
@@ -856,4 +973,12 @@ | ||
state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); | ||
if ( useTexStorage ) { | ||
state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data ); | ||
} else { | ||
state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); | ||
} | ||
} | ||
@@ -869,2 +994,14 @@ | ||
if ( useTexStorage && allocateMemory ) { | ||
// TODO: Uniformly handle mipmap definitions | ||
// Normal textures and compressed cube textures define base level + mips with their mipmap array | ||
// Uncompressed cube textures use their mipmap array only for mips (no base level) | ||
if ( mipmaps.length > 0 ) levels ++; | ||
state.texStorage2D( _gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, cubeImage[ 0 ].width, cubeImage[ 0 ].height ); | ||
} | ||
for ( let i = 0; i < 6; i ++ ) { | ||
@@ -874,4 +1011,12 @@ | ||
state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data ); | ||
if ( useTexStorage ) { | ||
state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, cubeImage[ i ].width, cubeImage[ i ].height, glFormat, glType, cubeImage[ i ].data ); | ||
} else { | ||
state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data ); | ||
} | ||
for ( let j = 0; j < mipmaps.length; j ++ ) { | ||
@@ -882,4 +1027,12 @@ | ||
state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data ); | ||
if ( useTexStorage ) { | ||
state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, mipmapImage.width, mipmapImage.height, glFormat, glType, mipmapImage.data ); | ||
} else { | ||
state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data ); | ||
} | ||
} | ||
@@ -889,4 +1042,12 @@ | ||
state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[ i ] ); | ||
if ( useTexStorage ) { | ||
state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, glFormat, glType, cubeImage[ i ] ); | ||
} else { | ||
state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[ i ] ); | ||
} | ||
for ( let j = 0; j < mipmaps.length; j ++ ) { | ||
@@ -896,4 +1057,12 @@ | ||
state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[ i ] ); | ||
if ( useTexStorage ) { | ||
state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, glFormat, glType, mipmap.image[ i ] ); | ||
} else { | ||
state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[ i ] ); | ||
} | ||
} | ||
@@ -900,0 +1069,0 @@ |
@@ -113,3 +113,2 @@ import { | ||
this.gammaFactor = 2.0; // for backwards compatibility | ||
this.outputEncoding = LinearEncoding; | ||
@@ -309,3 +308,3 @@ | ||
materials = new WebGLMaterials( properties ); | ||
renderLists = new WebGLRenderLists( properties ); | ||
renderLists = new WebGLRenderLists(); | ||
renderStates = new WebGLRenderStates( extensions, capabilities ); | ||
@@ -578,2 +577,3 @@ background = new WebGLBackground( _this, cubemaps, state, objects, _premultipliedAlpha ); | ||
bindingStates.dispose(); | ||
programCache.dispose(); | ||
@@ -663,2 +663,8 @@ xr.dispose(); | ||
if ( material.isShaderMaterial ) { | ||
programCache.releaseShaderCache( material ); | ||
} | ||
} | ||
@@ -1410,2 +1416,3 @@ | ||
materialProperties.vertexTangents = parameters.vertexTangents; | ||
materialProperties.toneMapping = parameters.toneMapping; | ||
@@ -1429,2 +1436,3 @@ } | ||
const morphTargetsCount = !! geometry.morphAttributes.position ? geometry.morphAttributes.position.length : 0; | ||
const toneMapping = material.toneMapped ? _this.toneMapping : NoToneMapping; | ||
@@ -1511,2 +1519,6 @@ const materialProperties = properties.get( material ); | ||
} else if ( materialProperties.toneMapping !== toneMapping ) { | ||
needsProgramChange = true; | ||
} else if ( capabilities.isWebGL2 === true && materialProperties.morphTargetsCount !== morphTargetsCount ) { | ||
@@ -2048,2 +2060,9 @@ | ||
if ( texture.isFramebufferTexture !== true ) { | ||
console.error( 'THREE.WebGLRenderer: copyFramebufferToTexture() can only be used with FramebufferTexture.' ); | ||
return; | ||
} | ||
const levelScale = Math.pow( 2, - level ); | ||
@@ -2053,17 +2072,5 @@ const width = Math.floor( texture.image.width * levelScale ); | ||
let glFormat = utils.convert( texture.format ); | ||
if ( capabilities.isWebGL2 ) { | ||
// Workaround for https://bugs.chromium.org/p/chromium/issues/detail?id=1120100 | ||
// Not needed in Chrome 93+ | ||
if ( glFormat === _gl.RGB ) glFormat = _gl.RGB8; | ||
if ( glFormat === _gl.RGBA ) glFormat = _gl.RGBA8; | ||
} | ||
textures.setTexture2D( texture, 0 ); | ||
_gl.copyTexImage2D( _gl.TEXTURE_2D, level, glFormat, position.x, position.y, width, height, 0 ); | ||
_gl.copyTexSubImage2D( _gl.TEXTURE_2D, level, 0, 0, position.x, position.y, width, height ); | ||
@@ -2218,3 +2225,3 @@ state.unbindTexture(); | ||
__THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); // eslint-disable-line no-undef | ||
__THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); | ||
@@ -2221,0 +2228,0 @@ } |
@@ -260,3 +260,8 @@ import { ArrayCamera } from '../../cameras/ArrayCamera.js'; | ||
glBaseLayer.framebufferWidth, | ||
glBaseLayer.framebufferHeight | ||
glBaseLayer.framebufferHeight, | ||
{ | ||
format: RGBAFormat, | ||
type: UnsignedByteType, | ||
encoding: renderer.outputEncoding | ||
} | ||
); | ||
@@ -273,3 +278,3 @@ | ||
glDepthFormat = attributes.stencil ? gl.DEPTH24_STENCIL8 : gl.DEPTH_COMPONENT16; | ||
glDepthFormat = attributes.stencil ? gl.DEPTH24_STENCIL8 : gl.DEPTH_COMPONENT24; | ||
depthFormat = attributes.stencil ? DepthStencilFormat : DepthFormat; | ||
@@ -304,2 +309,3 @@ depthType = attributes.stencil ? UnsignedInt248Type : UnsignedShortType; | ||
useRenderToTexture: hasMultisampledRenderToTexture, | ||
encoding: renderer.outputEncoding | ||
} ); | ||
@@ -318,2 +324,3 @@ | ||
ignoreDepth: glProjLayer.ignoreDepthValues, | ||
encoding: renderer.outputEncoding | ||
} ); | ||
@@ -326,3 +333,3 @@ | ||
// Set foveation to maximum. | ||
this.setFoveation( 0 ); | ||
this.setFoveation( 1.0 ); | ||
@@ -329,0 +336,0 @@ referenceSpace = await session.requestReferenceSpace( referenceSpaceType ); |
@@ -21,3 +21,3 @@ import { Object3D } from '../core/Object3D.js'; | ||
__THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); // eslint-disable-line no-undef | ||
__THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); | ||
@@ -24,0 +24,0 @@ } |
@@ -19,4 +19,2 @@ import { Texture } from './Texture.js'; | ||
this.needsUpdate = true; | ||
} | ||
@@ -23,0 +21,0 @@ |
@@ -21,4 +21,2 @@ import { Texture } from './Texture.js'; | ||
this.needsUpdate = true; | ||
} | ||
@@ -25,0 +23,0 @@ |
@@ -29,4 +29,2 @@ import { Texture } from './Texture.js'; | ||
this.needsUpdate = true; | ||
} | ||
@@ -33,0 +31,0 @@ |
@@ -29,2 +29,3 @@ import { REVISION } from './constants.js'; | ||
export { VideoTexture } from './textures/VideoTexture.js'; | ||
export { FramebufferTexture } from './textures/FramebufferTexture.js'; | ||
export { DataTexture } from './textures/DataTexture.js'; | ||
@@ -158,7 +159,5 @@ export { DataTexture2DArray } from './textures/DataTexture2DArray.js'; | ||
/* eslint-disable no-undef */ | ||
__THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'register', { detail: { | ||
revision: REVISION, | ||
} } ) ); | ||
/* eslint-enable no-undef */ | ||
@@ -165,0 +164,0 @@ } |
@@ -1600,3 +1600,15 @@ import { Audio } from './audio/Audio.js'; | ||
}, | ||
gammaFactor: { | ||
get: function () { | ||
console.warn( 'THREE.WebGLRenderer: .gammaFactor has been removed.' ); | ||
return 2; | ||
}, | ||
set: function () { | ||
console.warn( 'THREE.WebGLRenderer: .gammaFactor has been removed.' ); | ||
} | ||
} | ||
} ); | ||
@@ -1603,0 +1615,0 @@ |
@@ -57,38 +57,2 @@ function arrayMin( array ) { | ||
/** | ||
* cyrb53 hash for string from: https://stackoverflow.com/a/52171480 | ||
* | ||
* Public Domain, @bryc - https://stackoverflow.com/users/815680/bryc | ||
* | ||
* It is roughly similar to the well-known MurmurHash/xxHash algorithms. It uses a combination | ||
* of multiplication and Xorshift to generate the hash, but not as thorough. As a result it's | ||
* faster than either would be in JavaScript and significantly simpler to implement. Keep in | ||
* mind this is not a secure algorithm, if privacy/security is a concern, this is not for you. | ||
* | ||
* @param {string} str | ||
* @param {number} seed, default 0 | ||
* @returns number | ||
*/ | ||
function hashString( str, seed = 0 ) { | ||
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed; | ||
for ( let i = 0, ch; i < str.length; i ++ ) { | ||
ch = str.charCodeAt( i ); | ||
h1 = Math.imul( h1 ^ ch, 2654435761 ); | ||
h2 = Math.imul( h2 ^ ch, 1597334677 ); | ||
} | ||
h1 = Math.imul( h1 ^ ( h1 >>> 16 ), 2246822507 ) ^ Math.imul( h2 ^ ( h2 >>> 13 ), 3266489909 ); | ||
h2 = Math.imul( h2 ^ ( h2 >>> 16 ), 2246822507 ) ^ Math.imul( h1 ^ ( h1 >>> 13 ), 3266489909 ); | ||
return 4294967296 * ( 2097151 & h2 ) + ( h1 >>> 0 ); | ||
} | ||
export { arrayMin, arrayMax, getTypedArray, createElementNS, hashString }; | ||
export { arrayMin, arrayMax, getTypedArray, createElementNS }; |
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 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 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
31591319
1169
384775