@takram/three-geospatial 0.5.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +2 -0
  3. package/build/index.cjs +1 -1
  4. package/build/index.cjs.map +1 -1
  5. package/build/index.js +318 -312
  6. package/build/index.js.map +1 -1
  7. package/build/r3f.cjs.map +1 -1
  8. package/build/r3f.js.map +1 -1
  9. package/build/shaders.cjs.map +1 -1
  10. package/build/shaders.js.map +1 -1
  11. package/build/shared.cjs.map +1 -1
  12. package/build/shared.js.map +1 -1
  13. package/build/shared2.cjs.map +1 -1
  14. package/build/shared2.js.map +1 -1
  15. package/build/shared3.cjs.map +1 -1
  16. package/build/shared3.js.map +1 -1
  17. package/build/webgpu.cjs +1 -1
  18. package/build/webgpu.cjs.map +1 -1
  19. package/build/webgpu.js +445 -463
  20. package/build/webgpu.js.map +1 -1
  21. package/package.json +2 -2
  22. package/src/decorators.ts +30 -10
  23. package/src/r3f/EastNorthUpFrame.tsx +2 -1
  24. package/src/r3f/EllipsoidMesh.tsx +4 -2
  25. package/src/webgpu/DownsampleThresholdNode.ts +3 -4
  26. package/src/webgpu/DualMipmapFilterNode.ts +1 -1
  27. package/src/webgpu/FnLayout.ts +5 -5
  28. package/src/webgpu/GaussianBlurNode.ts +3 -3
  29. package/src/webgpu/HighpVelocityNode.ts +8 -4
  30. package/src/webgpu/KawaseBlurNode.ts +3 -3
  31. package/src/webgpu/LensFlareNode.ts +10 -19
  32. package/src/webgpu/LensGlareNode.ts +8 -11
  33. package/src/webgpu/MipmapBlurNode.ts +7 -7
  34. package/src/webgpu/MipmapSurfaceBlurNode.ts +5 -6
  35. package/src/webgpu/OutputTexture3DNode.ts +1 -5
  36. package/src/webgpu/OutputTextureNode.ts +1 -4
  37. package/src/webgpu/RTTextureNode.ts +6 -8
  38. package/src/webgpu/TemporalAntialiasNode.ts +20 -23
  39. package/src/webgpu/accessors.ts +8 -10
  40. package/src/webgpu/generators.ts +7 -9
  41. package/src/webgpu/math.ts +13 -13
  42. package/src/webgpu/node.ts +3 -6
  43. package/src/webgpu/sampling.ts +3 -51
  44. package/src/webgpu/transformations.ts +30 -35
  45. package/src/webgpu/utils.ts +9 -9
  46. package/types/decorators.d.ts +2 -2
  47. package/types/webgpu/DownsampleThresholdNode.d.ts +4 -4
  48. package/types/webgpu/DualMipmapFilterNode.d.ts +2 -2
  49. package/types/webgpu/FnLayout.d.ts +3 -3
  50. package/types/webgpu/GaussianBlurNode.d.ts +2 -2
  51. package/types/webgpu/HighpVelocityNode.d.ts +2 -3
  52. package/types/webgpu/KawaseBlurNode.d.ts +2 -2
  53. package/types/webgpu/LensFlareNode.d.ts +4 -4
  54. package/types/webgpu/LensGhostNode.d.ts +1 -1
  55. package/types/webgpu/LensGlareNode.d.ts +5 -5
  56. package/types/webgpu/LensHaloNode.d.ts +2 -2
  57. package/types/webgpu/MipmapBlurNode.d.ts +4 -4
  58. package/types/webgpu/MipmapSurfaceBlurNode.d.ts +3 -3
  59. package/types/webgpu/OutputTexture3DNode.d.ts +1 -2
  60. package/types/webgpu/OutputTextureNode.d.ts +1 -2
  61. package/types/webgpu/RTTextureNode.d.ts +2 -3
  62. package/types/webgpu/SeparableFilterNode.d.ts +2 -2
  63. package/types/webgpu/SingleFilterNode.d.ts +1 -1
  64. package/types/webgpu/TemporalAntialiasNode.d.ts +6 -6
  65. package/types/webgpu/accessors.d.ts +8 -8
  66. package/types/webgpu/generators.d.ts +4 -4
  67. package/types/webgpu/node.d.ts +4 -5
  68. package/types/webgpu/sampling.d.ts +0 -1
  69. package/types/webgpu/transformations.d.ts +8 -8
  70. package/types/webgpu/utils.d.ts +1 -2
@@ -16,7 +16,6 @@ import {
16
16
  instancedArray,
17
17
  instanceIndex,
18
18
  mat3,
19
- nodeObject,
20
19
  positionGeometry,
21
20
  Return,
22
21
  storage,
@@ -40,7 +39,7 @@ import {
40
39
  import invariant from 'tiny-invariant'
41
40
 
42
41
  import { FilterNode } from './FilterNode'
43
- import type { Node, NodeObject } from './node'
42
+ import type { Node } from './node'
44
43
  import { convertToTexture } from './RTTextureNode'
45
44
 
46
45
  const { resetRendererState, restoreRendererState } = RendererUtils
@@ -187,7 +186,7 @@ export class LensGlareNode extends FilterNode {
187
186
  this.rendererState = resetRendererState(renderer, this.rendererState)
188
187
 
189
188
  renderer.setRenderTarget(renderTarget)
190
- void renderer.render(this.mesh, this.camera)
189
+ renderer.render(this.mesh, this.camera)
191
190
 
192
191
  restoreRendererState(renderer, this.rendererState)
193
192
  }
@@ -258,7 +257,7 @@ export class LensGlareNode extends FilterNode {
258
257
 
259
258
  this.material.colorNode = this.wireframe
260
259
  ? vec4(1)
261
- : nodeObject(spikeNode).mul(instance.get('color').mul(intensity))
260
+ : spikeNode.mul(instance.get('color').mul(intensity))
262
261
 
263
262
  this.material.vertexNode = Fn(() => {
264
263
  const sin = instance.get('sin')
@@ -308,11 +307,9 @@ export class LensGlareNode extends FilterNode {
308
307
  }
309
308
  }
310
309
 
311
- export const lensGlare = (inputNode: Node | null): NodeObject<LensGlareNode> =>
312
- nodeObject(
313
- new LensGlareNode(
314
- inputNode != null
315
- ? convertToTexture(inputNode, 'LensGlareNode.Input')
316
- : null
317
- )
310
+ export const lensGlare = (inputNode: Node | null): LensGlareNode =>
311
+ new LensGlareNode(
312
+ inputNode != null
313
+ ? convertToTexture(inputNode, 'LensGlareNode.Input')
314
+ : null
318
315
  )
@@ -1,4 +1,4 @@
1
- import { add, nodeObject, uv, vec2, vec4 } from 'three/tsl'
1
+ import { add, uv, vec2, vec4 } from 'three/tsl'
2
2
  import type {
3
3
  NodeBuilder,
4
4
  TextureNode,
@@ -8,12 +8,12 @@ import type {
8
8
  import invariant from 'tiny-invariant'
9
9
 
10
10
  import { DualMipmapFilterNode } from './DualMipmapFilterNode'
11
- import type { Node, NodeObject } from './node'
11
+ import type { Node } from './node'
12
12
 
13
13
  export const mipmapBlurDownsample = (
14
14
  inputNode: TextureNode,
15
- texelSize: NodeObject<'vec2'> | NodeObject<UniformNode<Vector2>>
16
- ): NodeObject<'vec4'> => {
15
+ texelSize: Node<'vec2'> | UniformNode<Vector2>
16
+ ): Node<'vec4'> => {
17
17
  const center = uv()
18
18
  const offset1 = vec4(1, 1, -1, -1).mul(texelSize.xyxy).add(center.xyxy)
19
19
  const offset2 = vec4(2, 2, -2, -2).mul(texelSize.xyxy).add(center.xyxy)
@@ -55,8 +55,8 @@ export const mipmapBlurDownsample = (
55
55
 
56
56
  export const mipmapBlurUpsample = (
57
57
  inputNode: TextureNode,
58
- texelSize: NodeObject<'vec2'> | NodeObject<UniformNode<Vector2>>
59
- ): NodeObject<'vec4'> => {
58
+ texelSize: Node<'vec2'> | UniformNode<Vector2>
59
+ ): Node<'vec4'> => {
60
60
  const center = uv()
61
61
  const offset = vec4(1, 1, -1, -1).mul(texelSize.xyxy).add(center.xyxy)
62
62
  const uv1 = vec2(center.x, offset.y).toVertexStage() // 0, 1
@@ -110,4 +110,4 @@ export class MipmapBlurNode extends DualMipmapFilterNode {
110
110
 
111
111
  export const mipmapBlur = (
112
112
  ...args: ConstructorParameters<typeof MipmapBlurNode>
113
- ): NodeObject<MipmapBlurNode> => nodeObject(new MipmapBlurNode(...args))
113
+ ): MipmapBlurNode => new MipmapBlurNode(...args)
@@ -1,11 +1,11 @@
1
- import { add, Fn, mix, nodeObject, uniform, uv, vec2, vec4 } from 'three/tsl'
1
+ import { add, Fn, mix, uniform, uv, vec2, vec4 } from 'three/tsl'
2
2
  import type { NodeBuilder, TextureNode } from 'three/webgpu'
3
3
  import invariant from 'tiny-invariant'
4
4
 
5
5
  import { DualMipmapFilterNode } from './DualMipmapFilterNode'
6
- import type { Node, NodeObject } from './node'
6
+ import type { Node } from './node'
7
7
 
8
- const clampToBorder = (uv: NodeObject<'vec2'>): NodeObject<'float'> => {
8
+ const clampToBorder = (uv: Node<'vec2'>): Node<'float'> => {
9
9
  return uv.greaterThanEqual(0).all().and(uv.lessThanEqual(1).all()).toFloat()
10
10
  }
11
11
 
@@ -53,7 +53,7 @@ export class MipmapSurfaceBlurNode extends DualMipmapFilterNode {
53
53
 
54
54
  const output = inputNode.sample(center).mul(outerWeight)
55
55
 
56
- let weight: NodeObject
56
+ let weight: Node
57
57
  weight = vec4(
58
58
  clampToBorder(uv01),
59
59
  clampToBorder(uv02),
@@ -136,5 +136,4 @@ export class MipmapSurfaceBlurNode extends DualMipmapFilterNode {
136
136
 
137
137
  export const mipmapSurfaceBlur = (
138
138
  ...args: ConstructorParameters<typeof MipmapSurfaceBlurNode>
139
- ): NodeObject<MipmapSurfaceBlurNode> =>
140
- nodeObject(new MipmapSurfaceBlurNode(...args))
139
+ ): MipmapSurfaceBlurNode => new MipmapSurfaceBlurNode(...args)
@@ -1,9 +1,6 @@
1
1
  import type { Texture } from 'three'
2
- import { nodeObject } from 'three/tsl'
3
2
  import { Texture3DNode, type Node, type NodeBuilder } from 'three/webgpu'
4
3
 
5
- import type { NodeObject } from './node'
6
-
7
4
  export class OutputTexture3DNode extends Texture3DNode {
8
5
  static override get type(): string {
9
6
  return 'OutputTexture3DNode'
@@ -30,5 +27,4 @@ export class OutputTexture3DNode extends Texture3DNode {
30
27
 
31
28
  export const outputTexture3D = (
32
29
  ...args: ConstructorParameters<typeof OutputTexture3DNode>
33
- ): NodeObject<OutputTexture3DNode> =>
34
- nodeObject(new OutputTexture3DNode(...args))
30
+ ): OutputTexture3DNode => new OutputTexture3DNode(...args)
@@ -1,9 +1,6 @@
1
1
  import type { Texture } from 'three'
2
- import { nodeObject } from 'three/tsl'
3
2
  import { TextureNode, type Node, type NodeBuilder } from 'three/webgpu'
4
3
 
5
- import type { NodeObject } from './node'
6
-
7
4
  export class OutputTextureNode extends TextureNode {
8
5
  static override get type(): string {
9
6
  return 'OutputTextureNode'
@@ -30,4 +27,4 @@ export class OutputTextureNode extends TextureNode {
30
27
 
31
28
  export const outputTexture = (
32
29
  ...args: ConstructorParameters<typeof OutputTextureNode>
33
- ): NodeObject<OutputTextureNode> => nodeObject(new OutputTextureNode(...args))
30
+ ): OutputTextureNode => new OutputTextureNode(...args)
@@ -1,4 +1,4 @@
1
- import { nodeObject, uv } from 'three/tsl'
1
+ import { uv } from 'three/tsl'
2
2
  import {
3
3
  HalfFloatType,
4
4
  LinearFilter,
@@ -15,8 +15,6 @@ import {
15
15
  type NodeFrame
16
16
  } from 'three/webgpu'
17
17
 
18
- import type { NodeObject } from './node'
19
-
20
18
  const { resetRendererState, restoreRendererState } = RendererUtils
21
19
 
22
20
  function createRenderTarget(): RenderTarget {
@@ -50,7 +48,7 @@ export class RTTextureNode extends TextureNode {
50
48
 
51
49
  constructor(node: Node, uvNode?: Node) {
52
50
  const renderTarget = createRenderTarget()
53
- super(renderTarget.texture, uvNode != null ? nodeObject(uvNode) : uv())
51
+ super(renderTarget.texture, uvNode ?? uv())
54
52
  this.node = node
55
53
  this.renderTarget = renderTarget
56
54
  this.updateBeforeType = NodeUpdateType.FRAME
@@ -84,7 +82,7 @@ export class RTTextureNode extends TextureNode {
84
82
  const { material } = this
85
83
  // I don't fully understand why, but updates on "node" doesn't propagate
86
84
  // unless giving the builder context.
87
- material.fragmentNode = nodeObject(this.node).context(builder.getContext())
85
+ material.fragmentNode = this.node.context(builder.getContext())
88
86
  material.needsUpdate = true
89
87
  return super.setup(builder)
90
88
  }
@@ -107,7 +105,7 @@ export class RTTextureNode extends TextureNode {
107
105
 
108
106
  export const rtTexture = (
109
107
  ...args: ConstructorParameters<typeof RTTextureNode>
110
- ): NodeObject<RTTextureNode> => nodeObject(new RTTextureNode(...args))
108
+ ): RTTextureNode => new RTTextureNode(...args)
111
109
 
112
110
  export const convertToTexture = (
113
111
  node: Node & {
@@ -116,7 +114,7 @@ export const convertToTexture = (
116
114
  getTextureNode?: () => TextureNode
117
115
  },
118
116
  name?: string
119
- ): NodeObject<TextureNode> => {
117
+ ): TextureNode => {
120
118
  let textureNode: TextureNode
121
119
  if (node.isTextureNode === true || node.isSampleNode === true) {
122
120
  textureNode = node as TextureNode
@@ -128,5 +126,5 @@ export const convertToTexture = (
128
126
  textureNode.value.name = name
129
127
  }
130
128
  }
131
- return nodeObject(textureNode)
129
+ return textureNode
132
130
  }
@@ -17,7 +17,6 @@ import {
17
17
  ivec2,
18
18
  max,
19
19
  mix,
20
- nodeObject,
21
20
  screenCoordinate,
22
21
  screenSize,
23
22
  screenUV,
@@ -26,6 +25,7 @@ import {
26
25
  step,
27
26
  struct,
28
27
  texture,
28
+ textureSize,
29
29
  uniform,
30
30
  vec3,
31
31
  vec4
@@ -46,10 +46,9 @@ import { cameraFar, cameraNear } from './accessors'
46
46
  import { FnLayout } from './FnLayout'
47
47
  import { FnVar } from './FnVar'
48
48
  import { haltonOffsets } from './internals'
49
- import type { Node, NodeObject } from './node'
49
+ import type { Node } from './node'
50
50
  import { outputTexture } from './OutputTextureNode'
51
51
  import { convertToTexture } from './RTTextureNode'
52
- import { textureBicubic } from './sampling'
53
52
  import { logarithmicToPerspectiveDepth } from './transformations'
54
53
  import { isWebGPU } from './utils'
55
54
 
@@ -127,11 +126,11 @@ const varianceOffsets = [
127
126
  const varianceClipping = /*#__PURE__*/ FnVar(
128
127
  (
129
128
  inputNode: TextureNode,
130
- coord: NodeObject<'ivec2'>,
131
- current: NodeObject<'vec4'>,
132
- history: NodeObject<'vec4'>,
133
- gamma: NodeObject<'float'>
134
- ): NodeObject<'vec4'> => {
129
+ coord: Node<'ivec2'>,
130
+ current: Node<'vec4'>,
131
+ history: Node<'vec4'>,
132
+ gamma: Node<'float'>
133
+ ): Node<'vec4'> => {
135
134
  const moment1 = current.toVar()
136
135
  const moment2 = current.pow2().toVar()
137
136
 
@@ -169,7 +168,7 @@ const closestDepthStruct = /*#__PURE__*/ struct({
169
168
  })
170
169
 
171
170
  const getClosestDepth = /*#__PURE__*/ FnVar(
172
- (depthNode: TextureNode, inputCoord: NodeObject<'ivec2'>) => {
171
+ (depthNode: TextureNode, inputCoord: Node<'ivec2'>) => {
173
172
  const depth = float(1)
174
173
  const coord = ivec2(0)
175
174
  for (const offset of neighborOffsets) {
@@ -321,9 +320,9 @@ export class TemporalAntialiasNode extends TempNode {
321
320
  // Bind and clear the history render target to make sure it's initialized
322
321
  // after the resize which triggers a dispose().
323
322
  renderer.setRenderTarget(this.resolveRT)
324
- void renderer.clear()
323
+ renderer.clear()
325
324
  renderer.setRenderTarget(this.historyRT)
326
- void renderer.clear()
325
+ renderer.clear()
327
326
 
328
327
  // Copy the current input to the history with scaling.
329
328
  renderer.setRenderTarget(this.historyRT)
@@ -419,10 +418,10 @@ export class TemporalAntialiasNode extends TempNode {
419
418
  }
420
419
 
421
420
  private setupResolveNode({ renderer }: NodeBuilder): Node {
422
- const getPreviousDepth = (uv: NodeObject<'vec2'>): NodeObject<'float'> => {
421
+ const getPreviousDepth = (uv: Node<'vec2'>): Node<'float'> => {
423
422
  const { previousDepthNode: depthNode } = this
424
423
  const depth = depthNode
425
- .load(ivec2(uv.mul(depthNode.size(0)).sub(0.5)))
424
+ .load(ivec2(uv.mul(textureSize(depthNode)).sub(0.5)))
426
425
  .toVar()
427
426
  return renderer.logarithmicDepthBuffer
428
427
  ? logarithmicToPerspectiveDepth(
@@ -482,7 +481,7 @@ export class TemporalAntialiasNode extends TempNode {
482
481
 
483
482
  const outputColor = vec4(0).toVar()
484
483
  If(uvWeight.mul(depthWeight).mul(confidence).greaterThan(0), () => {
485
- const historyColor = textureBicubic(this.historyNode, prevUV)
484
+ const historyColor = texture(this.historyNode, prevUV)
486
485
  const clippedColor = varianceClipping(
487
486
  this.inputNode,
488
487
  coord,
@@ -559,13 +558,11 @@ export const temporalAntialias =
559
558
  depthNode: TextureNode,
560
559
  velocityNode: TextureNode,
561
560
  camera: Camera
562
- ): NodeObject<TemporalAntialiasNode> =>
563
- nodeObject(
564
- new TemporalAntialiasNode(
565
- velocityNodeImmutable,
566
- convertToTexture(inputNode, 'TemporalAntialiasNode.Input'),
567
- depthNode,
568
- velocityNode,
569
- camera
570
- )
561
+ ): TemporalAntialiasNode =>
562
+ new TemporalAntialiasNode(
563
+ velocityNodeImmutable,
564
+ convertToTexture(inputNode, 'TemporalAntialiasNode.Input'),
565
+ depthNode,
566
+ velocityNode,
567
+ camera
571
568
  )
@@ -2,7 +2,7 @@ import { Vector3, type Camera } from 'three'
2
2
  import { reference, uniform } from 'three/tsl'
3
3
  import type { UniformNode } from 'three/webgpu'
4
4
 
5
- import type { NodeObject } from './node'
5
+ import type { Node } from './node'
6
6
 
7
7
  let caches: WeakMap<{}, Record<string, {}>> | undefined
8
8
 
@@ -23,31 +23,29 @@ function getCache<T extends {}, U extends {}>(
23
23
  return (cache[name] ??= callback()) as U
24
24
  }
25
25
 
26
- export const projectionMatrix = (camera: Camera): NodeObject<'mat4'> =>
26
+ export const projectionMatrix = (camera: Camera): Node<'mat4'> =>
27
27
  getCache(camera, 'projectionMatrix', () =>
28
28
  reference('projectionMatrix', 'mat4', camera).setName('projectionMatrix')
29
29
  )
30
30
 
31
- export const viewMatrix = (camera: Camera): NodeObject<'mat4'> =>
31
+ export const viewMatrix = (camera: Camera): Node<'mat4'> =>
32
32
  getCache(camera, 'viewMatrix', () =>
33
33
  reference('matrixWorldInverse', 'mat4', camera).setName('viewMatrix')
34
34
  )
35
35
 
36
- export const inverseProjectionMatrix = (camera: Camera): NodeObject<'mat4'> =>
36
+ export const inverseProjectionMatrix = (camera: Camera): Node<'mat4'> =>
37
37
  getCache(camera, 'inverseProjectionMatrix', () =>
38
38
  reference('projectionMatrixInverse', 'mat4', camera).setName(
39
39
  'inverseProjectionMatrix'
40
40
  )
41
41
  )
42
42
 
43
- export const inverseViewMatrix = (camera: Camera): NodeObject<'mat4'> =>
43
+ export const inverseViewMatrix = (camera: Camera): Node<'mat4'> =>
44
44
  getCache(camera, 'inverseViewMatrix', () =>
45
45
  reference('matrixWorld', 'mat4', camera).setName('inverseViewMatrix')
46
46
  )
47
47
 
48
- export const cameraPositionWorld = (
49
- camera: Camera
50
- ): NodeObject<UniformNode<Vector3>> =>
48
+ export const cameraPositionWorld = (camera: Camera): UniformNode<Vector3> =>
51
49
  getCache(camera, 'cameraPositionWorld', () =>
52
50
  uniform(new Vector3())
53
51
  .setName('cameraPositionWorld')
@@ -56,12 +54,12 @@ export const cameraPositionWorld = (
56
54
  })
57
55
  )
58
56
 
59
- export const cameraNear = (camera: Camera): NodeObject<'float'> =>
57
+ export const cameraNear = (camera: Camera): Node<'float'> =>
60
58
  getCache(camera, 'cameraNear', () =>
61
59
  reference('near', 'float', camera).setName('cameraNear')
62
60
  )
63
61
 
64
- export const cameraFar = (camera: Camera): NodeObject<'float'> =>
62
+ export const cameraFar = (camera: Camera): Node<'float'> =>
65
63
  getCache(camera, 'cameraFar', () =>
66
64
  reference('far', 'float', camera).setName('cameraFar')
67
65
  )
@@ -10,27 +10,25 @@ import {
10
10
  vec3
11
11
  } from 'three/tsl'
12
12
 
13
- import type { NodeObject } from './node'
13
+ import type { Node } from './node'
14
14
 
15
15
  // Reference: https://advances.realtimerendering.com/s2014/index.html
16
- export const interleavedGradientNoise = (
17
- seed: NodeObject<'vec2'>
18
- ): NodeObject<'float'> => {
16
+ export const interleavedGradientNoise = (seed: Node<'vec2'>): Node<'float'> => {
19
17
  return seed.dot(vec2(0.06711056, 0.00583715)).fract().mul(52.9829189).fract()
20
18
  }
21
19
 
22
20
  // Reference (sixth from the bottom): https://www.shadertoy.com/view/MslGR8
23
- export const dithering: NodeObject<'vec3'> = /*#__PURE__*/ Fn(() => {
21
+ export const dithering: Node<'vec3'> = /*#__PURE__*/ Fn(() => {
24
22
  const seed = vec2(screenCoordinate.xy).add(time.fract().mul(1337))
25
23
  const noise = interleavedGradientNoise(seed)
26
24
  return vec3(noise, noise.oneMinus(), noise).sub(0.5).div(255)
27
25
  }).once()()
28
26
 
29
27
  export const equirectGrid = (
30
- direction: NodeObject<'vec3'>,
31
- lineWidth: NodeObject<'float'>,
32
- count: NodeObject<'vec2'> = vec2(90, 45)
33
- ): NodeObject<'float'> => {
28
+ direction: Node<'vec3'>,
29
+ lineWidth: Node<'float'>,
30
+ count: Node<'vec2'> = vec2(90, 45)
31
+ ): Node<'float'> => {
34
32
  const uv = equirectUV(direction)
35
33
  const deltaUV = fwidth(uv)
36
34
  const width = lineWidth.mul(deltaUV).mul(0.5)
@@ -1,16 +1,16 @@
1
1
  import { dot, If, sqrt, struct, vec2, vec4 } from 'three/tsl'
2
2
 
3
3
  import { FnVar } from './FnVar'
4
- import type { NodeObject } from './node'
4
+ import type { Node } from './node'
5
5
 
6
6
  // Reference: https://iquilezles.org/articles/intersectors/
7
7
 
8
8
  export const raySphereIntersection = /*#__PURE__*/ FnVar(
9
9
  (
10
- rayOrigin: NodeObject<'vec3'>,
11
- rayDirection: NodeObject<'vec3'>,
12
- center: NodeObject<'vec3'>,
13
- radius: NodeObject<'float'>
10
+ rayOrigin: Node<'vec3'>,
11
+ rayDirection: Node<'vec3'>,
12
+ center: Node<'vec3'>,
13
+ radius: Node<'float'>
14
14
  ) => {
15
15
  const a = rayOrigin.sub(center)
16
16
  const b = dot(rayDirection, a)
@@ -34,10 +34,10 @@ export const raySpheresIntersectionsStruct = /*#__PURE__*/ struct(
34
34
  // Derive ray-sphere intersections with multiple radii at once:
35
35
  export const raySpheresIntersections = /*#__PURE__*/ FnVar(
36
36
  (
37
- rayOrigin: NodeObject<'vec3'>,
38
- rayDirection: NodeObject<'vec3'>,
39
- center: NodeObject<'vec3'>,
40
- radii: NodeObject // Scalar or vector
37
+ rayOrigin: Node<'vec3'>,
38
+ rayDirection: Node<'vec3'>,
39
+ center: Node<'vec3'>,
40
+ radii: Node // Scalar or vector
41
41
  ) => {
42
42
  const a = rayOrigin.sub(center)
43
43
  const b = dot(rayDirection, a)
@@ -57,10 +57,10 @@ export const raySpheresIntersections = /*#__PURE__*/ FnVar(
57
57
 
58
58
  export const rayEllipsoidIntersection = /*#__PURE__*/ FnVar(
59
59
  (
60
- rayOrigin: NodeObject<'vec3'>,
61
- rayDirection: NodeObject<'vec3'>,
62
- radii: NodeObject<'vec3'>
63
- ): NodeObject<'vec2'> => {
60
+ rayOrigin: Node<'vec3'>,
61
+ rayDirection: Node<'vec3'>,
62
+ radii: Node<'vec3'>
63
+ ): Node<'vec2'> => {
64
64
  const ro = rayOrigin.div(radii)
65
65
  const rd = rayDirection.div(radii)
66
66
  const a = rd.dot(rd)
@@ -27,10 +27,9 @@ import {
27
27
  uvec4,
28
28
  vec2,
29
29
  vec3,
30
- vec4,
31
- type ShaderNodeObject
30
+ vec4
32
31
  } from 'three/tsl'
33
- import type { Node as N } from 'three/webgpu'
32
+ import { Node as N } from 'three/webgpu'
34
33
 
35
34
  // prettier-ignore
36
35
  const nodes = {
@@ -91,9 +90,7 @@ export type Node<
91
90
  T extends NodeType = NodeType
92
91
  > = N
93
92
 
94
- export type NodeObject<T extends NodeType | N = N> = ShaderNodeObject<
95
- T extends NodeType ? Node<T> : T
96
- >
93
+ export const Node = N
97
94
 
98
95
  export function node<T extends NodeType>(type: T): (typeof nodes)[T] {
99
96
  return nodes[type]
@@ -1,61 +1,13 @@
1
- import { add, nodeObject, sub, textureSize, vec2, vec4 } from 'three/tsl'
1
+ import { add, sub, textureSize, vec2 } from 'three/tsl'
2
2
  import type { TextureNode } from 'three/webgpu'
3
3
 
4
4
  import { FnVar } from './FnVar'
5
- import type { NodeObject } from './node'
6
-
7
- // 5-taps version of bicubic sampling.
8
- // Reference: https://www.shadertoy.com/view/MtVGWz
9
- export const textureBicubic = /*#__PURE__*/ FnVar(
10
- (
11
- textureNode: TextureNode,
12
- uv: NodeObject<'vec2'>,
13
- sharpness: number | NodeObject<'float'> = 0.4
14
- ): NodeObject<'vec4'> => {
15
- const size = vec2(textureSize(textureNode))
16
- const texelSize = size.reciprocal()
17
- const position = size.mul(uv)
18
- const centerPosition = position.sub(0.5).floor().add(0.5)
19
-
20
- const f = position.sub(centerPosition)
21
- const f2 = f.mul(f)
22
- const f3 = f.mul(f2)
23
-
24
- // w0 = -c * f3 + 2*c * f2 - c*f
25
- // w1 = (2 - c) * f3 - (3 - c) * f2 + 1
26
- // w2 = -(2 - c) * f3 + (3 - 2*c) * f2 + c*f
27
- // w3 = c * f3 - c * f2
28
- const c = nodeObject(sharpness)
29
- const cf = c.mul(f)
30
- const w0 = c.negate().mul(f3).add(c.mul(2).mul(f2).sub(cf))
31
- const w1 = sub(2, c).mul(f3).sub(sub(3, c).mul(f2)).add(1)
32
- const w2 = sub(2, c)
33
- .negate()
34
- .mul(f3)
35
- .add(sub(3, c.mul(2)).mul(f2))
36
- .add(cf)
37
- const w3 = c.mul(f3).sub(c.mul(f2))
38
-
39
- const w12 = w1.add(w2)
40
- const tc12 = texelSize.mul(centerPosition.add(w2.div(w12)))
41
- const centerColor = textureNode.sample(tc12).rgb
42
- const tc0 = texelSize.mul(centerPosition.sub(1))
43
- const tc3 = texelSize.mul(centerPosition.add(2))
44
-
45
- return add(
46
- vec4(textureNode.sample(vec2(tc12.x, tc0.y)).rgb, 1).mul(w12.x.mul(w0.y)),
47
- vec4(textureNode.sample(vec2(tc0.x, tc12.y)).rgb, 1).mul(w0.x.mul(w12.y)),
48
- vec4(centerColor, 1).mul(w12.x.mul(w12.y)),
49
- vec4(textureNode.sample(vec2(tc3.x, tc12.y)).rgb, 1).mul(w3.x.mul(w12.y)),
50
- vec4(textureNode.sample(vec2(tc12.x, tc3.y)).rgb, 1).mul(w12.x.mul(w3.y))
51
- )
52
- }
53
- )
5
+ import type { Node } from './node'
54
6
 
55
7
  // 9-taps version of Catmull-Rom sampling.
56
8
  // Reference: https://gist.github.com/TheRealMJP/c83b8c0f46b63f3a88a5986f4fa982b1
57
9
  export const textureCatmullRom = /*#__PURE__*/ FnVar(
58
- (textureNode: TextureNode, uv: NodeObject<'vec2'>): NodeObject<'vec4'> => {
10
+ (textureNode: TextureNode, uv: Node<'vec2'>): Node<'vec4'> => {
59
11
  const size = vec2(textureSize(textureNode))
60
12
  const texelSize = size.reciprocal()
61
13
  const position = uv.mul(size)