📄 PMREMNode.js
¶
📊 Analysis Summary¶
Metric | Count |
---|---|
🔧 Functions | 9 |
🧱 Classes | 1 |
📦 Imports | 10 |
📊 Variables & Constants | 14 |
📚 Table of Contents¶
🛠️ File Location:¶
📂 src/nodes/pmrem/PMREMNode.js
📦 Imports¶
Name | Source |
---|---|
TempNode |
../core/TempNode.js |
texture |
../accessors/TextureNode.js |
textureCubeUV |
./PMREMUtils.js |
uniform |
../core/UniformNode.js |
NodeUpdateType |
../core/constants.js |
nodeProxy |
../tsl/TSLBase.js |
vec3 |
../tsl/TSLBase.js |
Texture |
../../textures/Texture.js |
PMREMGenerator |
../../renderers/common/extras/PMREMGenerator.js |
materialEnvRotation |
../accessors/MaterialProperties.js |
Variables & Constants¶
Name | Type | Kind | Value | Exported |
---|---|---|---|---|
_cache |
WeakMap<WeakKey, any> |
let/var | new WeakMap() |
✗ |
maxMip |
number |
let/var | Math.log2( imageHeight ) - 2 |
✗ |
texelHeight |
number |
let/var | 1.0 / imageHeight |
✗ |
texelWidth |
number |
let/var | 1.0 / ( 3 * Math.max( Math.pow( 2, maxMip ), 7 * 16 ) ) |
✗ |
pmremVersion |
number |
let/var | cacheTexture !== undefined ? cacheTexture.pmremVersion : - 1 |
✗ |
image |
any |
let/var | texture.image |
✗ |
defaultTexture |
Texture |
let/var | new Texture() |
✗ |
pmrem |
Texture |
let/var | this._pmrem |
✗ |
pmremVersion |
number |
let/var | pmrem ? pmrem.pmremVersion : - 1 |
✗ |
texture |
Texture |
let/var | this._value |
✗ |
uvNode |
any |
let/var | this.uvNode |
✗ |
levelNode |
any |
let/var | this.levelNode |
✗ |
count |
number |
let/var | 0 |
✗ |
length |
6 |
let/var | 6 |
✗ |
Functions¶
_generateCubeUVSize(imageHeight: number): { texelWidth: number; texelHeight: number; maxMip: number; }
¶
JSDoc:
/**
* Generates the cubeUV size based on the given image height.
*
* @private
* @param {number} imageHeight - The image height.
* @return {{texelWidth: number,texelHeight: number, maxMip: number}} The result object.
*/
Parameters:
imageHeight
number
Returns: { texelWidth: number; texelHeight: number; maxMip: number; }
Calls:
Math.log2
Math.max
Math.pow
Code
_getPMREMFromTexture(texture: Texture, renderer: Renderer, generator: PMREMGenerator): Texture
¶
JSDoc:
/**
* Generates a PMREM from the given texture.
*
* @private
* @param {Texture} texture - The texture to create the PMREM for.
* @param {Renderer} renderer - The renderer.
* @param {PMREMGenerator} generator - The PMREM generator.
* @return {?Texture} The PMREM.
*/
Parameters:
texture
Texture
renderer
Renderer
generator
PMREMGenerator
Returns: Texture
Calls:
_getCache
cache.get
isCubeMapReady
generator.fromCubemap
isEquirectangularMapReady
generator.fromEquirectangular
cache.set
Code
function _getPMREMFromTexture( texture, renderer, generator ) {
const cache = _getCache( renderer );
let cacheTexture = cache.get( texture );
const pmremVersion = cacheTexture !== undefined ? cacheTexture.pmremVersion : - 1;
if ( pmremVersion !== texture.pmremVersion ) {
const image = texture.image;
if ( texture.isCubeTexture ) {
if ( isCubeMapReady( image ) ) {
cacheTexture = generator.fromCubemap( texture, cacheTexture );
} else {
return null;
}
} else {
if ( isEquirectangularMapReady( image ) ) {
cacheTexture = generator.fromEquirectangular( texture, cacheTexture );
} else {
return null;
}
}
cacheTexture.pmremVersion = texture.pmremVersion;
cache.set( texture, cacheTexture );
}
return cacheTexture.texture;
}
_getCache(renderer: Renderer): WeakMap<Texture, Texture>
¶
JSDoc:
/**
* Returns a cache that stores generated PMREMs for the respective textures.
* A cache must be maintained per renderer since PMREMs are render target textures
* which can't be shared across render contexts.
*
* @private
* @param {Renderer} renderer - The renderer.
* @return {WeakMap<Texture, Texture>} The PMREM cache.
*/
Parameters:
renderer
Renderer
Returns: WeakMap<Texture, Texture>
Calls:
_cache.get
_cache.set
Code
PMREMNode.updateFromTexture(texture: Texture): void
¶
JSDoc:
/**
* Uses the given PMREM texture to update internal values.
*
* @param {Texture} texture - The PMREM texture.
*/
Parameters:
texture
Texture
Returns: void
Calls:
_generateCubeUVSize
Code
PMREMNode.updateBefore(frame: any): void
¶
Parameters:
frame
any
Returns: void
Calls:
_getPMREMFromTexture
this.updateFromTexture
Code
updateBefore( frame ) {
let pmrem = this._pmrem;
const pmremVersion = pmrem ? pmrem.pmremVersion : - 1;
const texture = this._value;
if ( pmremVersion !== texture.pmremVersion ) {
if ( texture.isPMREMTexture === true ) {
pmrem = texture;
} else {
pmrem = _getPMREMFromTexture( texture, frame.renderer, this._generator );
}
if ( pmrem !== null ) {
this._pmrem = pmrem;
this.updateFromTexture( pmrem );
}
}
}
PMREMNode.setup(builder: any): void
¶
Parameters:
builder
any
Returns: void
Calls:
this.updateBefore
builder.context.getUV
materialEnvRotation.mul
vec3 (from ../tsl/TSLBase.js)
uvNode.y.negate
builder.context.getTextureLevel
textureCubeUV (from ./PMREMUtils.js)
Internal Comments:
Code
setup( builder ) {
if ( this._generator === null ) {
this._generator = new PMREMGenerator( builder.renderer );
}
this.updateBefore( builder );
//
let uvNode = this.uvNode;
if ( uvNode === null && builder.context.getUV ) {
uvNode = builder.context.getUV( this );
}
//
uvNode = materialEnvRotation.mul( vec3( uvNode.x, uvNode.y.negate(), uvNode.z ) );
//
let levelNode = this.levelNode;
if ( levelNode === null && builder.context.getTextureLevel ) {
levelNode = builder.context.getTextureLevel( this );
}
//
return textureCubeUV( this._texture, uvNode, levelNode, this._width, this._height, this._maxMip );
}
PMREMNode.dispose(): void
¶
Returns: void
Calls:
super.dispose
this._generator.dispose
isCubeMapReady(image: any[]): boolean
¶
JSDoc:
/**
* Returns `true` if the given cube map image has been fully loaded.
*
* @private
* @param {?Array<(Image|Object)>} [image] - The cube map image.
* @return {boolean} Whether the given cube map is ready or not.
*/
Parameters:
image
any[]
Returns: boolean
Code
isEquirectangularMapReady(image: any): boolean
¶
JSDoc:
/**
* Returns `true` if the given equirectangular image has been fully loaded.
*
* @private
* @param {(Image|Object)} image - The equirectangular image.
* @return {boolean} Whether the given cube map is ready or not.
*/
Parameters:
image
any
Returns: boolean
Code
Classes¶
PMREMNode
¶
Class Code
class PMREMNode extends TempNode {
static get type() {
return 'PMREMNode';
}
/**
* Constructs a new function overloading node.
*
* @param {Texture} value - The input texture.
* @param {Node<vec2>} [uvNode=null] - The uv node.
* @param {Node<float>} [levelNode=null] - The level node.
*/
constructor( value, uvNode = null, levelNode = null ) {
super( 'vec3' );
/**
* Reference to the input texture.
*
* @private
* @type {Texture}
*/
this._value = value;
/**
* Reference to the generated PMREM.
*
* @private
* @type {Texture | null}
* @default null
*/
this._pmrem = null;
/**
* The uv node.
*
* @type {Node<vec2>}
*/
this.uvNode = uvNode;
/**
* The level node.
*
* @type {Node<float>}
*/
this.levelNode = levelNode;
/**
* Reference to a PMREM generator.
*
* @private
* @type {?PMREMGenerator}
* @default null
*/
this._generator = null;
const defaultTexture = new Texture();
defaultTexture.isRenderTargetTexture = true;
/**
* The texture node holding the generated PMREM.
*
* @private
* @type {TextureNode}
*/
this._texture = texture( defaultTexture );
/**
* A uniform representing the PMREM's width.
*
* @private
* @type {UniformNode<float>}
*/
this._width = uniform( 0 );
/**
* A uniform representing the PMREM's height.
*
* @private
* @type {UniformNode<float>}
*/
this._height = uniform( 0 );
/**
* A uniform representing the PMREM's max Mip.
*
* @private
* @type {UniformNode<float>}
*/
this._maxMip = uniform( 0 );
/**
* The `updateBeforeType` is set to `NodeUpdateType.RENDER`.
*
* @type {string}
* @default 'render'
*/
this.updateBeforeType = NodeUpdateType.RENDER;
}
set value( value ) {
this._value = value;
this._pmrem = null;
}
/**
* The node's texture value.
*
* @type {Texture}
*/
get value() {
return this._value;
}
/**
* Uses the given PMREM texture to update internal values.
*
* @param {Texture} texture - The PMREM texture.
*/
updateFromTexture( texture ) {
const cubeUVSize = _generateCubeUVSize( texture.image.height );
this._texture.value = texture;
this._width.value = cubeUVSize.texelWidth;
this._height.value = cubeUVSize.texelHeight;
this._maxMip.value = cubeUVSize.maxMip;
}
updateBefore( frame ) {
let pmrem = this._pmrem;
const pmremVersion = pmrem ? pmrem.pmremVersion : - 1;
const texture = this._value;
if ( pmremVersion !== texture.pmremVersion ) {
if ( texture.isPMREMTexture === true ) {
pmrem = texture;
} else {
pmrem = _getPMREMFromTexture( texture, frame.renderer, this._generator );
}
if ( pmrem !== null ) {
this._pmrem = pmrem;
this.updateFromTexture( pmrem );
}
}
}
setup( builder ) {
if ( this._generator === null ) {
this._generator = new PMREMGenerator( builder.renderer );
}
this.updateBefore( builder );
//
let uvNode = this.uvNode;
if ( uvNode === null && builder.context.getUV ) {
uvNode = builder.context.getUV( this );
}
//
uvNode = materialEnvRotation.mul( vec3( uvNode.x, uvNode.y.negate(), uvNode.z ) );
//
let levelNode = this.levelNode;
if ( levelNode === null && builder.context.getTextureLevel ) {
levelNode = builder.context.getTextureLevel( this );
}
//
return textureCubeUV( this._texture, uvNode, levelNode, this._width, this._height, this._maxMip );
}
dispose() {
super.dispose();
if ( this._generator !== null ) this._generator.dispose();
}
}
Methods¶
updateFromTexture(texture: Texture): void
¶
Code
updateBefore(frame: any): void
¶
Code
updateBefore( frame ) {
let pmrem = this._pmrem;
const pmremVersion = pmrem ? pmrem.pmremVersion : - 1;
const texture = this._value;
if ( pmremVersion !== texture.pmremVersion ) {
if ( texture.isPMREMTexture === true ) {
pmrem = texture;
} else {
pmrem = _getPMREMFromTexture( texture, frame.renderer, this._generator );
}
if ( pmrem !== null ) {
this._pmrem = pmrem;
this.updateFromTexture( pmrem );
}
}
}
setup(builder: any): void
¶
Code
setup( builder ) {
if ( this._generator === null ) {
this._generator = new PMREMGenerator( builder.renderer );
}
this.updateBefore( builder );
//
let uvNode = this.uvNode;
if ( uvNode === null && builder.context.getUV ) {
uvNode = builder.context.getUV( this );
}
//
uvNode = materialEnvRotation.mul( vec3( uvNode.x, uvNode.y.negate(), uvNode.z ) );
//
let levelNode = this.levelNode;
if ( levelNode === null && builder.context.getTextureLevel ) {
levelNode = builder.context.getTextureLevel( this );
}
//
return textureCubeUV( this._texture, uvNode, levelNode, this._width, this._height, this._maxMip );
}