123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- 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;
|