diff --git a/examples-testing/changes.patch b/examples-testing/changes.patch index f8662fad2..1127e9eca 100644 --- a/examples-testing/changes.patch +++ b/examples-testing/changes.patch @@ -15964,6 +15964,52 @@ index 7a493c71..74e8e0d9 100644 const thicknessControls = new ThicknessControls(); +diff --git a/examples-testing/examples/webgpu_materials_texture_manualmipmap.ts b/examples-testing/examples/webgpu_materials_texture_manualmipmap.ts +index 09037272..2456b295 100644 +--- a/examples-testing/examples/webgpu_materials_texture_manualmipmap.ts ++++ b/examples-testing/examples/webgpu_materials_texture_manualmipmap.ts +@@ -3,9 +3,9 @@ import * as THREE from 'three/webgpu'; + const SCREEN_WIDTH = window.innerWidth; + const SCREEN_HEIGHT = window.innerHeight; + +-let container; ++let container: HTMLDivElement; + +-let camera, scene1, scene2, renderer; ++let camera: THREE.PerspectiveCamera, scene1: THREE.Scene, scene2: THREE.Scene, renderer: THREE.WebGPURenderer; + + let mouseX = 0, + mouseY = 0; +@@ -90,7 +90,7 @@ async function init() { + addPainting(scene1, mesh1); + addPainting(scene2, mesh2); + +- function addPainting(zscene, zmesh) { ++ function addPainting(zscene: THREE.Scene, zmesh: THREE.Mesh) { + const image = texturePainting1.image; + + zmesh.scale.x = image.width / 100; +@@ -131,9 +131,9 @@ async function init() { + document.addEventListener('mousemove', onDocumentMouseMove); + } + +-function mipmap(size, color) { ++function mipmap(size: number, color: string) { + const imageCanvas = document.createElement('canvas'); +- const context = imageCanvas.getContext('2d'); ++ const context = imageCanvas.getContext('2d')!; + + imageCanvas.width = imageCanvas.height = size; + +@@ -146,7 +146,7 @@ function mipmap(size, color) { + return imageCanvas; + } + +-function onDocumentMouseMove(event) { ++function onDocumentMouseMove(event: MouseEvent) { + mouseX = event.clientX - windowHalfX; + mouseY = event.clientY - windowHalfY; + } diff --git a/examples-testing/examples/webgpu_materials_toon.ts b/examples-testing/examples/webgpu_materials_toon.ts index b94318de..5f5dfef0 100644 --- a/examples-testing/examples/webgpu_materials_toon.ts diff --git a/examples-testing/index.js b/examples-testing/index.js index 8398ad321..072972d8f 100644 --- a/examples-testing/index.js +++ b/examples-testing/index.js @@ -53,6 +53,7 @@ const exceptionList = [ 'webgpu_compute_particles_fluid', 'webgpu_compute_particles_rain', 'webgpu_compute_particles_snow', + 'webgpu_compute_reduce', 'webgpu_compute_water', 'webgpu_depth_texture', 'webgpu_equirectangular', diff --git a/src-testing/changes.patch b/src-testing/changes.patch index 99cc3ef2b..e86dd5f3d 100644 --- a/src-testing/changes.patch +++ b/src-testing/changes.patch @@ -5998,7 +5998,7 @@ index d12ad583..ef6e14ec 100644 } diff --git a/src-testing/src/renderers/common/RenderObject.ts b/src-testing/src/renderers/common/RenderObject.ts -index cbb1dffb..6c363a1b 100644 +index 579aa58c..fb8b7f7f 100644 --- a/src-testing/src/renderers/common/RenderObject.ts +++ b/src-testing/src/renderers/common/RenderObject.ts @@ -1,8 +1,27 @@ @@ -6174,7 +6174,7 @@ index cbb1dffb..6c363a1b 100644 const attributesId = {}; -@@ -779,7 +843,7 @@ class RenderObject { +@@ -789,7 +853,7 @@ class RenderObject { this.material.removeEventListener('dispose', this.onMaterialDispose); this.geometry.removeEventListener('dispose', this.onGeometryDispose); @@ -7698,7 +7698,7 @@ index 4b7c259d..96cda7ef 100644 /** diff --git a/src-testing/src/renderers/common/Textures.ts b/src-testing/src/renderers/common/Textures.ts -index 5b929721..d3827d5c 100644 +index 6615956d..ffc1fa3e 100644 --- a/src-testing/src/renderers/common/Textures.ts +++ b/src-testing/src/renderers/common/Textures.ts @@ -11,8 +11,46 @@ import { @@ -7817,7 +7817,7 @@ index 5b929721..d3827d5c 100644 } /** -@@ -343,10 +388,10 @@ class Textures extends DataMap { +@@ -343,13 +388,13 @@ class Textures extends DataMap { * @param {number} height - The texture's height. * @return {number} The number of mipmap levels. */ @@ -7825,23 +7825,28 @@ index 5b929721..d3827d5c 100644 + getMipLevels(texture: Texture, width: number, height: number) { let mipLevelCount; -- if (texture.isCompressedTexture) { -+ if ((texture as CompressedTexture).isCompressedTexture) { - if (texture.mipmaps) { - mipLevelCount = texture.mipmaps.length; - } else { -@@ -365,8 +410,8 @@ class Textures extends DataMap { +- if (texture.mipmaps.length > 0) { +- mipLevelCount = texture.mipmaps.length; ++ if (texture.mipmaps!.length > 0) { ++ mipLevelCount = texture.mipmaps!.length; + } else { +- if (texture.isCompressedTexture === true) { ++ if ((texture as CompressedTexture).isCompressedTexture === true) { + // it is not possible to compute mipmaps for compressed textures. So + // when no mipmaps are defined in "texture.mipmaps", force a texture + // level of 1 +@@ -369,8 +414,8 @@ class Textures extends DataMap { * @param {Texture} texture - The texture. * @return {boolean} Whether mipmaps are required or not. */ - needsMipmaps(texture) { -- return texture.isCompressedTexture === true || texture.generateMipmaps; +- return texture.generateMipmaps === true || texture.mipmaps.length > 0; + needsMipmaps(texture: Texture) { -+ return (texture as CompressedTexture).isCompressedTexture === true || texture.generateMipmaps; ++ return texture.generateMipmaps === true || texture.mipmaps!.length > 0; } /** -@@ -375,7 +420,7 @@ class Textures extends DataMap { +@@ -379,7 +424,7 @@ class Textures extends DataMap { * * @param {Texture} texture - The texture to destroy. */ diff --git a/three.js b/three.js index 8fd936dd4..63b49831e 160000 --- a/three.js +++ b/three.js @@ -1 +1 @@ -Subproject commit 8fd936dd4ca0179ac8b207fbd7ed23773e34475f +Subproject commit 63b49831e0be50779f9bbeccd24f4f93f7fa7c24 diff --git a/types/three/src/Three.TSL.d.ts b/types/three/src/Three.TSL.d.ts index c4c5a7e30..37e23517d 100644 --- a/types/three/src/Three.TSL.d.ts +++ b/types/three/src/Three.TSL.d.ts @@ -505,9 +505,30 @@ export const storageTexture: typeof TSL.storageTexture; export const string: typeof TSL.string; export const struct: typeof TSL.struct; export const sub: typeof TSL.sub; +export const subgroupAdd: typeof TSL.subgroupAdd; +export const subgroupAll: typeof TSL.subgroupAll; +export const subgroupAnd: typeof TSL.subgroupAnd; +export const subgroupAny: typeof TSL.subgroupAny; +export const subgroupBallot: typeof TSL.subgroupBallot; +export const subgroupBroadcast: typeof TSL.subgroupBroadcast; +export const subgroupBroadcastFirst: typeof TSL.subgroupBroadcastFirst; export const subBuild: typeof TSL.subBuild; +export const subgroupElect: typeof TSL.subgroupElect; +export const subgroupExclusiveAdd: typeof TSL.subgroupExclusiveAdd; +export const subgroupExclusiveMul: typeof TSL.subgroupExclusiveMul; +export const subgroupInclusiveAdd: typeof TSL.subgroupInclusiveAdd; +export const subgroupInclusiveMul: typeof TSL.subgroupInclusiveMul; export const subgroupIndex: typeof TSL.subgroupIndex; +export const subgroupMax: typeof TSL.subgroupMax; +export const subgroupMin: typeof TSL.subgroupMin; +export const subgroupMul: typeof TSL.subgroupMul; +export const subgroupOr: typeof TSL.subgroupOr; +export const subgroupShuffle: typeof TSL.subgroupShuffle; +export const subgroupShuffleDown: typeof TSL.subgroupShuffleDown; +export const subgroupShuffleUp: typeof TSL.subgroupShuffleUp; +export const subgroupShuffleXor: typeof TSL.subgroupShuffleXor; export const subgroupSize: typeof TSL.subgroupSize; +export const subgroupXor: typeof TSL.subgroupXor; export const tan: typeof TSL.tan; export const tangentGeometry: typeof TSL.tangentGeometry; export const tangentLocal: typeof TSL.tangentLocal; diff --git a/types/three/src/nodes/TSL.d.ts b/types/three/src/nodes/TSL.d.ts index adfc665ab..220d9481a 100644 --- a/types/three/src/nodes/TSL.d.ts +++ b/types/three/src/nodes/TSL.d.ts @@ -128,6 +128,7 @@ export * from "./gpgpu/AtomicFunctionNode.js"; export * from "./gpgpu/BarrierNode.js"; export * from "./gpgpu/ComputeBuiltinNode.js"; export * from "./gpgpu/ComputeNode.js"; +export * from "./gpgpu/SubgroupFunctionNode.js"; export * from "./gpgpu/WorkgroupInfoNode.js"; // lighting diff --git a/types/three/src/nodes/gpgpu/SubgroupFunctionNode.d.ts b/types/three/src/nodes/gpgpu/SubgroupFunctionNode.d.ts new file mode 100644 index 000000000..e32de328a --- /dev/null +++ b/types/three/src/nodes/gpgpu/SubgroupFunctionNode.d.ts @@ -0,0 +1,100 @@ +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export type SubgroupFunctionNodeMethod0 = typeof SubgroupFunctionNode.SUBGROUP_ELECT; + +export type SubgroupFunctionNodeMethod1 = + | typeof SubgroupFunctionNode.SUBGROUP_BALLOT + | typeof SubgroupFunctionNode.SUBGROUP_ADD + | typeof SubgroupFunctionNode.SUBGROUP_INCLUSIVE_ADD + | typeof SubgroupFunctionNode.SUBGROUP_EXCLUSIVE_AND + | typeof SubgroupFunctionNode.SUBGROUP_MUL + | typeof SubgroupFunctionNode.SUBGROUP_INCLUSIVE_MUL + | typeof SubgroupFunctionNode.SUBGROUP_EXCLUSIVE_MUL + | typeof SubgroupFunctionNode.SUBGROUP_AND + | typeof SubgroupFunctionNode.SUBGROUP_OR + | typeof SubgroupFunctionNode.SUBGROUP_XOR + | typeof SubgroupFunctionNode.SUBGROUP_MIN + | typeof SubgroupFunctionNode.SUBGROUP_MAX + | typeof SubgroupFunctionNode.SUBGROUP_ALL + | typeof SubgroupFunctionNode.SUBGROUP_ANY + | typeof SubgroupFunctionNode.SUBGROUP_BROADCAST_FIRST + | typeof SubgroupFunctionNode.QUAD_SWAP_X + | typeof SubgroupFunctionNode.QUAD_SWAP_Y + | typeof SubgroupFunctionNode.QUAD_SWAP_DIAGONAL; + +export type SubgroupFunctionNodeMethod2 = + | typeof SubgroupFunctionNode.SUBGROUP_BROADCAST + | typeof SubgroupFunctionNode.SUBGROUP_SHUFFLE + | typeof SubgroupFunctionNode.SUBGROUP_SHUFFLE_XOR + | typeof SubgroupFunctionNode.SUBGROUP_SHUFFLE_UP + | typeof SubgroupFunctionNode.SUBGROUP_SHUFFLE_DOWN + | typeof SubgroupFunctionNode.QUAD_BROADCAST; + +declare class SubgroupFunctionNode extends TempNode { + constructor(method: SubgroupFunctionNodeMethod0); + constructor(method: SubgroupFunctionNodeMethod1, aNode: Node); + constructor(method: SubgroupFunctionNodeMethod2, aNode: Node, bNode: Node); + + // 0 inputs + static SUBGROUP_ELECT: "subgroupElect"; + + // 1 input + static SUBGROUP_BALLOT: "subgroupBallot"; + static SUBGROUP_ADD: "subgroupAdd"; + static SUBGROUP_INCLUSIVE_ADD: "subgroupInclusiveAdd"; + static SUBGROUP_EXCLUSIVE_AND: "subgroupExclusiveAdd"; + static SUBGROUP_MUL: "subgroupMul"; + static SUBGROUP_INCLUSIVE_MUL: "subgroupInclusiveMul"; + static SUBGROUP_EXCLUSIVE_MUL: "subgroupExclusiveMul"; + static SUBGROUP_AND: "subgroupAnd"; + static SUBGROUP_OR: "subgroupOr"; + static SUBGROUP_XOR: "subgroupXor"; + static SUBGROUP_MIN: "subgroupMin"; + static SUBGROUP_MAX: "subgroupMax"; + static SUBGROUP_ALL: "subgroupAll"; + static SUBGROUP_ANY: "subgroupAny"; + static SUBGROUP_BROADCAST_FIRST: "subgroupBroadcastFirst"; + static QUAD_SWAP_X: "quadSwapX"; + static QUAD_SWAP_Y: "quadSwapY"; + static QUAD_SWAP_DIAGONAL: "quadSwapDiagonal"; + + // 2 inputs + static SUBGROUP_BROADCAST: "subgroupBroadcast"; + static SUBGROUP_SHUFFLE: "subgroupShuffle"; + static SUBGROUP_SHUFFLE_XOR: "subgroupShuffleXor"; + static SUBGROUP_SHUFFLE_UP: "subgroupShuffleUp"; + static SUBGROUP_SHUFFLE_DOWN: "subgroupShuffleDown"; + static QUAD_BROADCAST: "quadBroadcast"; +} + +export default SubgroupFunctionNode; + +export const subgroupElect: () => ShaderNodeObject; + +export const subgroupBallot: (pred: Node) => ShaderNodeObject; +export const subgroupAdd: (e: Node) => ShaderNodeObject; +export const subgroupInclusiveAdd: (e: Node) => ShaderNodeObject; +export const subgroupExclusiveAdd: (e: Node) => ShaderNodeObject; +export const subgroupMul: (e: Node) => ShaderNodeObject; +export const subgroupInclusiveMul: (e: Node) => ShaderNodeObject; +export const subgroupExclusiveMul: (e: Node) => ShaderNodeObject; +export const subgroupAnd: (e: Node) => ShaderNodeObject; +export const subgroupOr: (e: Node) => ShaderNodeObject; +export const subgroupXor: (e: Node) => ShaderNodeObject; +export const subgroupMin: (e: Node) => ShaderNodeObject; +export const subgroupMax: (e: Node) => ShaderNodeObject; +export const subgroupAll: () => ShaderNodeObject; +export const subgroupAny: () => ShaderNodeObject; +export const subgroupBroadcastFirst: (e: Node, id: Node) => ShaderNodeObject; +export const quadSwapX: (e: Node) => ShaderNodeObject; +export const quadSwapY: (e: Node) => ShaderNodeObject; +export const quadSwapDiagonal: (e: Node) => ShaderNodeObject; + +export const subgroupBroadcast: (e: Node, id: Node) => ShaderNodeObject; +export const subgroupShuffle: (v: Node, id: Node) => ShaderNodeObject; +export const subgroupShuffleXor: (v: Node, mask: Node) => ShaderNodeObject; +export const subgroupShuffleUp: (v: Node, delta: Node) => ShaderNodeObject; +export const subgroupShuffleDown: (v: Node, delta: Node) => ShaderNodeObject; +export const quadBroadcast: (e: Node) => ShaderNodeObject; diff --git a/types/three/src/renderers/common/Textures.d.ts b/types/three/src/renderers/common/Textures.d.ts index d8a91f4ad..ac4ac7f93 100644 --- a/types/three/src/renderers/common/Textures.d.ts +++ b/types/three/src/renderers/common/Textures.d.ts @@ -110,7 +110,7 @@ declare class Textures extends DataMap<{ */ getMipLevels(texture: Texture, width: number, height: number): number; /** - * Returns `true` if the given texture requires mipmaps. + * Returns `true` if the given texture makes use of mipmapping. * * @param {Texture} texture - The texture. * @return {boolean} Whether mipmaps are required or not. diff --git a/types/three/src/textures/CompressedTexture.d.ts b/types/three/src/textures/CompressedTexture.d.ts index 33ec5b17d..8112f90ee 100644 --- a/types/three/src/textures/CompressedTexture.d.ts +++ b/types/three/src/textures/CompressedTexture.d.ts @@ -39,9 +39,9 @@ export class CompressedTexture extends Texture { * @param colorSpace See {@link Texture.colorSpace .colorSpace}. Default {@link NoColorSpace} */ constructor( - mipmaps?: CompressedTextureMipmap[], - width?: number, - height?: number, + mipmaps: CompressedTextureMipmap[], + width: number, + height: number, format?: CompressedPixelFormat, type?: TextureDataType, mapping?: Mapping, @@ -71,7 +71,7 @@ export class CompressedTexture extends Texture { * The mipmaps array should contain objects with data, width and height. The mipmaps should be of the correct * format and type. */ - mipmaps: CompressedTextureMipmap[] | undefined; + mipmaps: CompressedTextureMipmap[]; /** * @override diff --git a/types/three/src/textures/Texture.d.ts b/types/three/src/textures/Texture.d.ts index 8c82c4694..a9e9ba2de 100644 --- a/types/three/src/textures/Texture.d.ts +++ b/types/three/src/textures/Texture.d.ts @@ -207,7 +207,7 @@ export class Texture extends EventDispatcher<{ dispose: {} }> { * Array of user-specified mipmaps * @defaultValue `[]` */ - mipmaps: CompressedTextureMipmap[] | CubeTexture[] | HTMLCanvasElement[] | undefined; + mipmaps: CompressedTextureMipmap[] | CubeTexture[] | HTMLCanvasElement[]; /** * How the image is applied to the object.