|
|
@@ -3732,7 +3732,13 @@ const ConvertType = function ( type, cacheMap = null ) {
|
|
|
|
|
|
return ( ...params ) => {
|
|
|
|
|
|
- if ( params.length === 0 || ( ! [ 'bool', 'float', 'int', 'uint' ].includes( type ) && params.every( param => typeof param !== 'object' ) ) ) {
|
|
|
+ if ( params.length === 0 || ( ! [ 'bool', 'float', 'int', 'uint' ].includes( type ) && params.every( param => {
|
|
|
+
|
|
|
+ const paramType = typeof param;
|
|
|
+
|
|
|
+ return paramType !== 'object' && paramType !== 'function';
|
|
|
+
|
|
|
+ } ) ) ) {
|
|
|
|
|
|
params = [ getValueFromType( type, ...params ) ];
|
|
|
|
|
|
@@ -3785,37 +3791,90 @@ const nodeProxyIntent = ( NodeClass, scope = null, factor = null, settings = {}
|
|
|
|
|
|
let fnId = 0;
|
|
|
|
|
|
-const Fn = ( jsFunc, layout = null ) => {
|
|
|
+class FnNode extends Node {
|
|
|
|
|
|
- let nodeType = null;
|
|
|
+ constructor( jsFunc, layout = null ) {
|
|
|
|
|
|
- if ( layout !== null ) {
|
|
|
+ super();
|
|
|
|
|
|
- if ( typeof layout === 'object' ) {
|
|
|
+ let nodeType = null;
|
|
|
|
|
|
- nodeType = layout.return;
|
|
|
+ if ( layout !== null ) {
|
|
|
|
|
|
- } else {
|
|
|
+ if ( typeof layout === 'object' ) {
|
|
|
|
|
|
- if ( typeof layout === 'string' ) {
|
|
|
-
|
|
|
- nodeType = layout;
|
|
|
+ nodeType = layout.return;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- console.error( 'THREE.TSL: Invalid layout type.' );
|
|
|
+ if ( typeof layout === 'string' ) {
|
|
|
+
|
|
|
+ nodeType = layout;
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ console.error( 'THREE.TSL: Invalid layout type.' );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ layout = null;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ this.shaderNode = new ShaderNode( jsFunc, nodeType );
|
|
|
+
|
|
|
+ if ( layout !== null ) {
|
|
|
+
|
|
|
+ this.setLayout( layout );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ this.isFn = true;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ setLayout( layout ) {
|
|
|
+
|
|
|
+ const nodeType = this.shaderNode.nodeType;
|
|
|
+
|
|
|
+ if ( typeof layout.inputs !== 'object' ) {
|
|
|
+
|
|
|
+ const fullLayout = {
|
|
|
+ name: 'fn' + fnId ++,
|
|
|
+ type: nodeType,
|
|
|
+ inputs: []
|
|
|
+ };
|
|
|
+
|
|
|
+ for ( const name in layout ) {
|
|
|
+
|
|
|
+ if ( name === 'return' ) continue;
|
|
|
+
|
|
|
+ fullLayout.inputs.push( {
|
|
|
+ name: name,
|
|
|
+ type: layout[ name ]
|
|
|
+ } );
|
|
|
|
|
|
}
|
|
|
|
|
|
- layout = null;
|
|
|
+ layout = fullLayout;
|
|
|
|
|
|
}
|
|
|
|
|
|
+ this.shaderNode.setLayout( layout );
|
|
|
+
|
|
|
+ return this;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
- const shaderNode = new ShaderNode( jsFunc, nodeType );
|
|
|
+ getNodeType( builder ) {
|
|
|
+
|
|
|
+ return this.shaderNode.getNodeType( builder ) || 'float';
|
|
|
|
|
|
- const fn = ( ...params ) => {
|
|
|
+ }
|
|
|
+
|
|
|
+ call( ...params ) {
|
|
|
|
|
|
let inputs;
|
|
|
|
|
|
@@ -3833,71 +3892,62 @@ const Fn = ( jsFunc, layout = null ) => {
|
|
|
|
|
|
}
|
|
|
|
|
|
- const fnCall = shaderNode.call( inputs );
|
|
|
+ const fnCall = this.shaderNode.call( inputs );
|
|
|
|
|
|
- if ( nodeType === 'void' ) fnCall.toStack();
|
|
|
+ if ( this.shaderNode.nodeType === 'void' ) fnCall.toStack();
|
|
|
|
|
|
return fnCall.toVarIntent();
|
|
|
|
|
|
- };
|
|
|
+ }
|
|
|
|
|
|
- fn.shaderNode = shaderNode;
|
|
|
- fn.id = shaderNode.id;
|
|
|
+ once( subBuilds = null ) {
|
|
|
|
|
|
- fn.isFn = true;
|
|
|
+ this.shaderNode.once = true;
|
|
|
+ this.shaderNode.subBuilds = subBuilds;
|
|
|
|
|
|
- fn.getNodeType = ( ...params ) => shaderNode.getNodeType( ...params );
|
|
|
- fn.getCacheKey = ( ...params ) => shaderNode.getCacheKey( ...params );
|
|
|
+ return this;
|
|
|
|
|
|
- fn.setLayout = ( layout ) => {
|
|
|
+ }
|
|
|
|
|
|
- shaderNode.setLayout( layout );
|
|
|
+ generate( builder ) {
|
|
|
|
|
|
- return fn;
|
|
|
+ const type = this.getNodeType( builder );
|
|
|
|
|
|
- };
|
|
|
+ console.warn( 'THREE.TSL: "Fn()" was declared but not invoked. Try calling it like "Fn()( ...params )".' );
|
|
|
|
|
|
- fn.once = ( subBuilds = null ) => {
|
|
|
+ return builder.generateConst( type );
|
|
|
|
|
|
- shaderNode.once = true;
|
|
|
- shaderNode.subBuilds = subBuilds;
|
|
|
+ }
|
|
|
|
|
|
- return fn;
|
|
|
+}
|
|
|
|
|
|
- };
|
|
|
+function Fn( jsFunc, layout = null ) {
|
|
|
|
|
|
- if ( layout !== null ) {
|
|
|
+ const instance = new FnNode( jsFunc, layout );
|
|
|
|
|
|
- if ( typeof layout.inputs !== 'object' ) {
|
|
|
+ return new Proxy( () => {}, {
|
|
|
|
|
|
- const fullLayout = {
|
|
|
- name: 'fn' + fnId ++,
|
|
|
- type: nodeType,
|
|
|
- inputs: []
|
|
|
- };
|
|
|
+ apply( target, thisArg, params ) {
|
|
|
|
|
|
- for ( const name in layout ) {
|
|
|
+ return instance.call( ...params );
|
|
|
|
|
|
- if ( name === 'return' ) continue;
|
|
|
+ },
|
|
|
|
|
|
- fullLayout.inputs.push( {
|
|
|
- name: name,
|
|
|
- type: layout[ name ]
|
|
|
- } );
|
|
|
+ get( target, prop, receiver ) {
|
|
|
|
|
|
- }
|
|
|
+ return Reflect.get( instance, prop, receiver );
|
|
|
|
|
|
- layout = fullLayout;
|
|
|
+ },
|
|
|
|
|
|
- }
|
|
|
+ set( target, prop, value, receiver ) {
|
|
|
|
|
|
- fn.setLayout( layout );
|
|
|
+ return Reflect.set( instance, prop, value, receiver );
|
|
|
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- return fn;
|
|
|
+ } );
|
|
|
|
|
|
-};
|
|
|
+}
|
|
|
|
|
|
//
|
|
|
|
|
|
@@ -7813,26 +7863,6 @@ addMethodChaining( 'toVar', Var );
|
|
|
addMethodChaining( 'toConst', Const );
|
|
|
addMethodChaining( 'toVarIntent', VarIntent );
|
|
|
|
|
|
-// Deprecated
|
|
|
-
|
|
|
-/**
|
|
|
- * @tsl
|
|
|
- * @function
|
|
|
- * @deprecated since r170. Use `Var( node )` or `node.toVar()` instead.
|
|
|
- *
|
|
|
- * @param {any} node
|
|
|
- * @returns {VarNode}
|
|
|
- */
|
|
|
-const temp = ( node ) => { // @deprecated, r170
|
|
|
-
|
|
|
- console.warn( 'TSL: "temp( node )" is deprecated. Use "Var( node )" or "node.toVar()" instead.' );
|
|
|
-
|
|
|
- return createVar( node );
|
|
|
-
|
|
|
-};
|
|
|
-
|
|
|
-addMethodChaining( 'temp', temp );
|
|
|
-
|
|
|
/**
|
|
|
* This node is used to build a sub-build in the node system.
|
|
|
*
|
|
|
@@ -31995,53 +32025,6 @@ const deltaTime = /*@__PURE__*/ uniform( 0 ).setGroup( renderGroup ).onRenderUpd
|
|
|
*/
|
|
|
const frameId = /*@__PURE__*/ uniform( 0, 'uint' ).setGroup( renderGroup ).onRenderUpdate( ( frame ) => frame.frameId );
|
|
|
|
|
|
-// Deprecated
|
|
|
-
|
|
|
-/**
|
|
|
- * @tsl
|
|
|
- * @function
|
|
|
- * @deprecated since r170. Use {@link time} instead.
|
|
|
- *
|
|
|
- * @param {number} [timeScale=1] - The time scale.
|
|
|
- * @returns {UniformNode<float>}
|
|
|
- */
|
|
|
-const timerLocal = ( timeScale = 1 ) => { // @deprecated, r170
|
|
|
-
|
|
|
- console.warn( 'TSL: timerLocal() is deprecated. Use "time" instead.' );
|
|
|
- return time.mul( timeScale );
|
|
|
-
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * @tsl
|
|
|
- * @function
|
|
|
- * @deprecated since r170. Use {@link time} instead.
|
|
|
- *
|
|
|
- * @param {number} [timeScale=1] - The time scale.
|
|
|
- * @returns {UniformNode<float>}
|
|
|
- */
|
|
|
-const timerGlobal = ( timeScale = 1 ) => { // @deprecated, r170
|
|
|
-
|
|
|
- console.warn( 'TSL: timerGlobal() is deprecated. Use "time" instead.' );
|
|
|
- return time.mul( timeScale );
|
|
|
-
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * @tsl
|
|
|
- * @function
|
|
|
- * @deprecated since r170. Use {@link deltaTime} instead.
|
|
|
- *
|
|
|
- * @param {number} [timeScale=1] - The time scale.
|
|
|
- * @returns {UniformNode<float>}
|
|
|
- */
|
|
|
-const timerDelta = ( timeScale = 1 ) => { // @deprecated, r170
|
|
|
-
|
|
|
- console.warn( 'TSL: timerDelta() is deprecated. Use "deltaTime" instead.' );
|
|
|
- return deltaTime.mul( timeScale );
|
|
|
-
|
|
|
-};
|
|
|
-
|
|
|
/**
|
|
|
* Generates a sine wave oscillation based on a timer.
|
|
|
*
|
|
|
@@ -32396,6 +32379,7 @@ class ReflectorNode extends TextureNode {
|
|
|
* @param {boolean} [parameters.generateMipmaps=false] - Whether mipmaps should be generated or not.
|
|
|
* @param {boolean} [parameters.bounces=true] - Whether reflectors can render other reflector nodes or not.
|
|
|
* @param {boolean} [parameters.depth=false] - Whether depth data should be generated or not.
|
|
|
+ * @param {number} [parameters.samples] - Anti-Aliasing samples of the internal render-target.
|
|
|
* @param {TextureNode} [parameters.defaultTexture] - The default texture node.
|
|
|
* @param {ReflectorBaseNode} [parameters.reflector] - The reflector base node.
|
|
|
*/
|
|
|
@@ -32539,6 +32523,7 @@ class ReflectorBaseNode extends Node {
|
|
|
* @param {boolean} [parameters.generateMipmaps=false] - Whether mipmaps should be generated or not.
|
|
|
* @param {boolean} [parameters.bounces=true] - Whether reflectors can render other reflector nodes or not.
|
|
|
* @param {boolean} [parameters.depth=false] - Whether depth data should be generated or not.
|
|
|
+ * @param {number} [parameters.samples] - Anti-Aliasing samples of the internal render-target.
|
|
|
*/
|
|
|
constructor( textureNode, parameters = {} ) {
|
|
|
|
|
|
@@ -32549,7 +32534,8 @@ class ReflectorBaseNode extends Node {
|
|
|
resolution = 1,
|
|
|
generateMipmaps = false,
|
|
|
bounces = true,
|
|
|
- depth = false
|
|
|
+ depth = false,
|
|
|
+ samples = 0
|
|
|
} = parameters;
|
|
|
|
|
|
/**
|
|
|
@@ -32599,6 +32585,14 @@ class ReflectorBaseNode extends Node {
|
|
|
*/
|
|
|
this.depth = depth;
|
|
|
|
|
|
+ /**
|
|
|
+ * The number of anti-aliasing samples for the render-target
|
|
|
+ *
|
|
|
+ * @type {number}
|
|
|
+ * @default {0}
|
|
|
+ */
|
|
|
+ this.samples = samples;
|
|
|
+
|
|
|
/**
|
|
|
* The `updateBeforeType` is set to `NodeUpdateType.RENDER` when {@link ReflectorBaseNode#bounces}
|
|
|
* is `true`. Otherwise it's `NodeUpdateType.FRAME`.
|
|
|
@@ -32719,7 +32713,7 @@ class ReflectorBaseNode extends Node {
|
|
|
|
|
|
if ( renderTarget === undefined ) {
|
|
|
|
|
|
- renderTarget = new RenderTarget( 0, 0, { type: HalfFloatType } );
|
|
|
+ renderTarget = new RenderTarget( 0, 0, { type: HalfFloatType, samples: this.samples } );
|
|
|
|
|
|
if ( this.generateMipmaps === true ) {
|
|
|
|
|
|
@@ -32901,6 +32895,7 @@ class ReflectorBaseNode extends Node {
|
|
|
* @param {boolean} [parameters.generateMipmaps=false] - Whether mipmaps should be generated or not.
|
|
|
* @param {boolean} [parameters.bounces=true] - Whether reflectors can render other reflector nodes or not.
|
|
|
* @param {boolean} [parameters.depth=false] - Whether depth data should be generated or not.
|
|
|
+ * @param {number} [parameters.samples] - Anti-Aliasing samples of the internal render-target.
|
|
|
* @param {TextureNode} [parameters.defaultTexture] - The default texture node.
|
|
|
* @param {ReflectorBaseNode} [parameters.reflector] - The reflector base node.
|
|
|
* @returns {ReflectorNode}
|
|
|
@@ -43355,7 +43350,6 @@ var TSL = /*#__PURE__*/Object.freeze({
|
|
|
tangentLocal: tangentLocal,
|
|
|
tangentView: tangentView,
|
|
|
tangentWorld: tangentWorld,
|
|
|
- temp: temp,
|
|
|
texture: texture,
|
|
|
texture3D: texture3D,
|
|
|
textureBarrier: textureBarrier,
|
|
|
@@ -43367,9 +43361,6 @@ var TSL = /*#__PURE__*/Object.freeze({
|
|
|
textureStore: textureStore,
|
|
|
thickness: thickness,
|
|
|
time: time,
|
|
|
- timerDelta: timerDelta,
|
|
|
- timerGlobal: timerGlobal,
|
|
|
- timerLocal: timerLocal,
|
|
|
toneMapping: toneMapping,
|
|
|
toneMappingExposure: toneMappingExposure,
|
|
|
toonOutlinePass: toonOutlinePass,
|
|
|
@@ -65806,6 +65797,7 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
msaaTextureDescriptorGPU.label = msaaTextureDescriptorGPU.label + '-msaa';
|
|
|
msaaTextureDescriptorGPU.sampleCount = samples;
|
|
|
+ msaaTextureDescriptorGPU.mipLevelCount = 1; // See https://www.w3.org/TR/webgpu/#texture-creation
|
|
|
|
|
|
textureData.msaaTexture = backend.device.createTexture( msaaTextureDescriptorGPU );
|
|
|
|