最新代码
This commit is contained in:
193
public/sdk/three/jsm/nodes/pmrem/PMREMNode.js
Normal file
193
public/sdk/three/jsm/nodes/pmrem/PMREMNode.js
Normal file
@ -0,0 +1,193 @@
|
||||
import TempNode from '../core/TempNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { texture } from '../accessors/TextureNode.js';
|
||||
import { textureCubeUV } from './PMREMUtils.js';
|
||||
import { uniform } from '../core/UniformNode.js';
|
||||
import { NodeUpdateType } from '../core/constants.js';
|
||||
import { nodeProxy, vec3 } from '../shadernode/ShaderNode.js';
|
||||
import { WebGLCoordinateSystem } from 'three';
|
||||
|
||||
let _generator = null;
|
||||
|
||||
const _cache = new WeakMap();
|
||||
|
||||
function _generateCubeUVSize( imageHeight ) {
|
||||
|
||||
const maxMip = Math.log2( imageHeight ) - 2;
|
||||
|
||||
const texelHeight = 1.0 / imageHeight;
|
||||
|
||||
const texelWidth = 1.0 / ( 3 * Math.max( Math.pow( 2, maxMip ), 7 * 16 ) );
|
||||
|
||||
return { texelWidth, texelHeight, maxMip };
|
||||
|
||||
}
|
||||
|
||||
function _getPMREMFromTexture( texture ) {
|
||||
|
||||
let cacheTexture = _cache.get( texture );
|
||||
|
||||
const pmremVersion = cacheTexture !== undefined ? cacheTexture.pmremVersion : - 1;
|
||||
|
||||
if ( pmremVersion !== texture.pmremVersion ) {
|
||||
|
||||
if ( texture.isCubeTexture ) {
|
||||
|
||||
if ( texture.source.data.some( ( texture ) => texture === undefined ) ) {
|
||||
|
||||
throw new Error( 'PMREMNode: Undefined texture in CubeTexture. Use onLoad callback or async loader' );
|
||||
|
||||
}
|
||||
|
||||
cacheTexture = _generator.fromCubemap( texture, cacheTexture );
|
||||
|
||||
} else {
|
||||
|
||||
if ( texture.image === undefined ) {
|
||||
|
||||
throw new Error( 'PMREMNode: Undefined image in Texture. Use onLoad callback or async loader' );
|
||||
|
||||
}
|
||||
|
||||
cacheTexture = _generator.fromEquirectangular( texture, cacheTexture );
|
||||
|
||||
}
|
||||
|
||||
cacheTexture.pmremVersion = texture.pmremVersion;
|
||||
|
||||
_cache.set( texture, cacheTexture );
|
||||
|
||||
}
|
||||
|
||||
return cacheTexture.texture;
|
||||
|
||||
}
|
||||
|
||||
class PMREMNode extends TempNode {
|
||||
|
||||
constructor( value, uvNode = null, levelNode = null ) {
|
||||
|
||||
super( 'vec3' );
|
||||
|
||||
this._value = value;
|
||||
this._pmrem = null;
|
||||
|
||||
this.uvNode = uvNode;
|
||||
this.levelNode = levelNode;
|
||||
|
||||
this._generator = null;
|
||||
this._texture = texture( null );
|
||||
this._width = uniform( 0 );
|
||||
this._height = uniform( 0 );
|
||||
this._maxMip = uniform( 0 );
|
||||
|
||||
this.updateBeforeType = NodeUpdateType.RENDER;
|
||||
|
||||
}
|
||||
|
||||
set value( value ) {
|
||||
|
||||
this._value = value;
|
||||
this._pmrem = null;
|
||||
|
||||
}
|
||||
|
||||
get value() {
|
||||
|
||||
return this._value;
|
||||
|
||||
}
|
||||
|
||||
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() {
|
||||
|
||||
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 );
|
||||
|
||||
}
|
||||
|
||||
this._pmrem = pmrem;
|
||||
|
||||
this.updateFromTexture( pmrem );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
if ( _generator === null ) {
|
||||
|
||||
_generator = builder.createPMREMGenerator();
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
this.updateBefore( builder );
|
||||
|
||||
//
|
||||
|
||||
let uvNode = this.uvNode;
|
||||
|
||||
if ( uvNode === null && builder.context.getUV ) {
|
||||
|
||||
uvNode = builder.context.getUV( this );
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
const texture = this.value;
|
||||
|
||||
if ( builder.renderer.coordinateSystem === WebGLCoordinateSystem && texture.isPMREMTexture !== true && texture.isRenderTargetTexture === true ) {
|
||||
|
||||
uvNode = vec3( uvNode.x.negate(), uvNode.yz );
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
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 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const pmremTexture = nodeProxy( PMREMNode );
|
||||
|
||||
addNodeClass( 'PMREMNode', PMREMNode );
|
||||
|
||||
export default PMREMNode;
|
Reference in New Issue
Block a user