From b8c03ae2fc20ba395dcdb0c0cabb245a9e70bb79 Mon Sep 17 00:00:00 2001 From: sunag Date: Fri, 20 Jun 2025 15:28:49 -0300 Subject: [PATCH 1/4] TSL: Introduce `textureBicubicLevel()` (#31288) * fix texture uv reference * add `textureBicubicLevel` * cleanup * cleanup --- src/Three.TSL.js | 1 + src/nodes/accessors/TextureBicubic.js | 24 +++++++++++++++++--- src/nodes/display/PassNode.js | 11 ++++++++- src/nodes/functions/PhysicalLightingModel.js | 4 ++-- src/nodes/utils/ReflectorNode.js | 15 ++++++++---- 5 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/Three.TSL.js b/src/Three.TSL.js index 1660a2a4bdb53b..d83b8ce83671b9 100644 --- a/src/Three.TSL.js +++ b/src/Three.TSL.js @@ -477,6 +477,7 @@ export const texture = TSL.texture; export const texture3D = TSL.texture3D; export const textureBarrier = TSL.textureBarrier; export const textureBicubic = TSL.textureBicubic; +export const textureBicubicLevel = TSL.textureBicubicLevel; export const textureCubeUV = TSL.textureCubeUV; export const textureLoad = TSL.textureLoad; export const textureSize = TSL.textureSize; diff --git a/src/nodes/accessors/TextureBicubic.js b/src/nodes/accessors/TextureBicubic.js index 89db08a756fd85..a71a121752ca63 100644 --- a/src/nodes/accessors/TextureBicubic.js +++ b/src/nodes/accessors/TextureBicubic.js @@ -1,6 +1,7 @@ import { add, mul, div } from '../math/OperatorNode.js'; import { floor, ceil, fract, pow } from '../math/MathNode.js'; -import { Fn, float, vec2, vec4, int } from '../tsl/TSLBase.js'; +import { Fn, vec2, vec4, int } from '../tsl/TSLBase.js'; +import { maxMipLevel } from '../utils/MaxMipLevelNode.js'; // Mipped Bicubic Texture Filtering by N8 // https://www.shadertoy.com/view/Dl2SDW @@ -57,10 +58,10 @@ const bicubic = ( textureNode, texelSize, lod ) => { * @tsl * @function * @param {TextureNode} textureNode - The texture node that should be filtered. - * @param {Node} [lodNode=float(3)] - Defines the LOD to sample from. + * @param {Node} lodNode - Defines the LOD to sample from. * @return {Node} The filtered texture sample. */ -export const textureBicubic = /*@__PURE__*/ Fn( ( [ textureNode, lodNode = float( 3 ) ] ) => { +export const textureBicubicLevel = /*@__PURE__*/ Fn( ( [ textureNode, lodNode ] ) => { const fLodSize = vec2( textureNode.size( int( lodNode ) ) ); const cLodSize = vec2( textureNode.size( int( lodNode.add( 1.0 ) ) ) ); @@ -72,3 +73,20 @@ export const textureBicubic = /*@__PURE__*/ Fn( ( [ textureNode, lodNode = float return fract( lodNode ).mix( fSample, cSample ); } ); + +/** + * Applies mipped bicubic texture filtering to the given texture node. + * + * @tsl + * @function + * @param {TextureNode} textureNode - The texture node that should be filtered. + * @param {Node} [strength] - Defines the strength of the bicubic filtering. + * @return {Node} The filtered texture sample. + */ +export const textureBicubic = /*@__PURE__*/ Fn( ( [ textureNode, strength ] ) => { + + const lod = strength.mul( maxMipLevel( textureNode ) ); + + return textureBicubicLevel( textureNode, lod ); + +} ); diff --git a/src/nodes/display/PassNode.js b/src/nodes/display/PassNode.js index 6024ebaa75faa6..1a347cb892da0b 100644 --- a/src/nodes/display/PassNode.js +++ b/src/nodes/display/PassNode.js @@ -126,7 +126,16 @@ class PassMultipleTextureNode extends PassTextureNode { clone() { - return new this.constructor( this.passNode, this.textureName, this.previousTexture ); + const newNode = new this.constructor( this.passNode, this.textureName, this.previousTexture ); + newNode.uvNode = this.uvNode; + newNode.levelNode = this.levelNode; + newNode.biasNode = this.biasNode; + newNode.sampler = this.sampler; + newNode.depthNode = this.depthNode; + newNode.compareNode = this.compareNode; + newNode.gradNode = this.gradNode; + + return newNode; } diff --git a/src/nodes/functions/PhysicalLightingModel.js b/src/nodes/functions/PhysicalLightingModel.js index 40ec1ca3ef10b0..cd071c69fe13a7 100644 --- a/src/nodes/functions/PhysicalLightingModel.js +++ b/src/nodes/functions/PhysicalLightingModel.js @@ -18,7 +18,7 @@ import { cameraPosition, cameraProjectionMatrix, cameraViewMatrix } from '../acc import { modelWorldMatrix } from '../accessors/ModelNode.js'; import { screenSize } from '../display/ScreenNode.js'; import { viewportMipTexture } from '../display/ViewportTextureNode.js'; -import { textureBicubic } from '../accessors/TextureBicubic.js'; +import { textureBicubicLevel } from '../accessors/TextureBicubic.js'; import { Loop } from '../utils/LoopNode.js'; import { BackSide } from '../../constants.js'; @@ -80,7 +80,7 @@ const getTransmissionSample = /*@__PURE__*/ Fn( ( [ fragCoord, roughness, ior ], const lod = log2( screenSize.x ).mul( applyIorToRoughness( roughness, ior ) ); - return textureBicubic( transmissionSample, lod ); + return textureBicubicLevel( transmissionSample, lod ); } ); diff --git a/src/nodes/utils/ReflectorNode.js b/src/nodes/utils/ReflectorNode.js index f1cfa7b61870d8..15cf9776aed07a 100644 --- a/src/nodes/utils/ReflectorNode.js +++ b/src/nodes/utils/ReflectorNode.js @@ -154,10 +154,17 @@ class ReflectorNode extends TextureNode { clone() { - const texture = new this.constructor( this.reflectorNode ); - texture._reflectorBaseNode = this._reflectorBaseNode; - - return texture; + const newNode = new this.constructor( this.reflectorNode ); + newNode.uvNode = this.uvNode; + newNode.levelNode = this.levelNode; + newNode.biasNode = this.biasNode; + newNode.sampler = this.sampler; + newNode.depthNode = this.depthNode; + newNode.compareNode = this.compareNode; + newNode.gradNode = this.gradNode; + newNode._reflectorBaseNode = this._reflectorBaseNode; + + return newNode; } From 5f6ec606484116b762c72c223dd0c98380c919c4 Mon Sep 17 00:00:00 2001 From: sunag Date: Fri, 20 Jun 2025 15:39:19 -0300 Subject: [PATCH 2/4] TSL: Introduce `sample()` (#31287) * introduce ``sample` * optimize example using packing --- examples/webgpu_postprocessing_ssr.html | 25 +++++++- src/Three.TSL.js | 1 + src/nodes/TSL.js | 1 + src/nodes/utils/SampleNode.js | 81 +++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 src/nodes/utils/SampleNode.js diff --git a/examples/webgpu_postprocessing_ssr.html b/examples/webgpu_postprocessing_ssr.html index 5ca97dfa6c2006..9ef04730b6642d 100644 --- a/examples/webgpu_postprocessing_ssr.html +++ b/examples/webgpu_postprocessing_ssr.html @@ -11,11 +11,13 @@ +
three.js webgpu - postprocessing - screen space reflections
Steampunk Camera by dylanheyes is licensed under Creative Commons Attribution.
+ - - - - - diff --git a/examples/webgl_water_flowmap.html b/examples/webgl_water_flowmap.html deleted file mode 100644 index bdaa55b2226e35..00000000000000 --- a/examples/webgl_water_flowmap.html +++ /dev/null @@ -1,139 +0,0 @@ - - - - Codestin Search App - - - - - - -
-
- three.js - water flow map -
- - - - - - - diff --git a/examples/webgpu_water.html b/examples/webgpu_water.html index e7f4b72fa0dc2a..4dcfa05b17d373 100644 --- a/examples/webgpu_water.html +++ b/examples/webgpu_water.html @@ -10,7 +10,9 @@
- three.js - water + three.js - water
+ The Night Pool by + syntheticplants is licensed under Creative Commons Attribution.