super-three 0.169.0 → 0.170.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 (195) hide show
  1. package/build/three.cjs +989 -1131
  2. package/build/three.module.js +990 -1128
  3. package/build/three.module.min.js +1 -1
  4. package/build/three.webgpu.js +8398 -9842
  5. package/build/three.webgpu.min.js +1 -1
  6. package/build/three.webgpu.nodes.js +8398 -9842
  7. package/build/three.webgpu.nodes.min.js +1 -1
  8. package/examples/jsm/Addons.js +3 -3
  9. package/examples/jsm/animation/MMDAnimationHelper.js +2 -0
  10. package/examples/jsm/animation/MMDPhysics.js +2 -0
  11. package/examples/jsm/controls/TransformControls.js +22 -6
  12. package/examples/jsm/csm/CSM.js +2 -2
  13. package/examples/jsm/csm/CSMFrustum.js +7 -4
  14. package/examples/jsm/csm/CSMHelper.js +2 -0
  15. package/examples/jsm/csm/CSMShadowNode.js +435 -0
  16. package/examples/jsm/curves/NURBSCurve.js +34 -3
  17. package/examples/jsm/exporters/GLTFExporter.js +138 -71
  18. package/examples/jsm/exporters/KTX2Exporter.js +35 -12
  19. package/examples/jsm/exporters/MMDExporter.js +6 -0
  20. package/examples/jsm/exporters/USDZExporter.js +21 -3
  21. package/examples/jsm/geometries/DecalGeometry.js +65 -20
  22. package/examples/jsm/geometries/InstancedPointsGeometry.js +2 -0
  23. package/examples/jsm/helpers/TextureHelperGPU.js +175 -0
  24. package/examples/jsm/interactive/HTMLMesh.js +1 -0
  25. package/examples/jsm/lighting/TiledLighting.js +18 -0
  26. package/examples/jsm/lights/RectAreaLightTexturesLib.js +1 -1
  27. package/examples/jsm/lines/LineMaterial.js +7 -2
  28. package/examples/jsm/lines/LineSegmentsGeometry.js +2 -0
  29. package/examples/jsm/lines/webgpu/LineSegments2.js +0 -15
  30. package/examples/jsm/lines/webgpu/Wireframe.js +56 -0
  31. package/examples/jsm/loaders/3DMLoader.js +1 -0
  32. package/examples/jsm/loaders/3MFLoader.js +91 -0
  33. package/examples/jsm/loaders/FBXLoader.js +12 -2
  34. package/examples/jsm/loaders/GLTFLoader.js +2 -0
  35. package/examples/jsm/loaders/KTX2Loader.js +140 -49
  36. package/examples/jsm/loaders/LDrawLoader.js +22 -136
  37. package/examples/jsm/loaders/LottieLoader.js +1 -0
  38. package/examples/jsm/loaders/MMDLoader.js +9 -2
  39. package/examples/jsm/materials/LDrawConditionalLineMaterial.js +143 -0
  40. package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +114 -0
  41. package/examples/jsm/materials/MeshGouraudMaterial.js +6 -2
  42. package/examples/jsm/math/ColorSpaces.js +76 -0
  43. package/examples/jsm/misc/ProgressiveLightMap.js +52 -40
  44. package/examples/jsm/misc/ProgressiveLightMapGPU.js +293 -0
  45. package/examples/jsm/misc/VolumeSlice.js +1 -0
  46. package/examples/jsm/objects/WaterMesh.js +8 -8
  47. package/examples/jsm/postprocessing/AfterimagePass.js +14 -3
  48. package/examples/jsm/postprocessing/SSRPass.js +6 -0
  49. package/examples/jsm/renderers/CSS2DRenderer.js +6 -3
  50. package/examples/jsm/renderers/CSS3DRenderer.js +7 -4
  51. package/examples/jsm/shaders/FXAAShader.js +225 -224
  52. package/examples/jsm/transpiler/ShaderToyDecoder.js +1 -1
  53. package/{src/nodes → examples/jsm/tsl}/display/AfterImageNode.js +17 -20
  54. package/{src/nodes → examples/jsm/tsl}/display/AnaglyphPassNode.js +2 -6
  55. package/{src/nodes → examples/jsm/tsl}/display/AnamorphicNode.js +12 -18
  56. package/{src/nodes → examples/jsm/tsl}/display/BleachBypass.js +1 -3
  57. package/{src/nodes → examples/jsm/tsl}/display/BloomNode.js +11 -40
  58. package/{src/nodes → examples/jsm/tsl}/display/DenoiseNode.js +18 -41
  59. package/{src/nodes → examples/jsm/tsl}/display/DepthOfFieldNode.js +2 -8
  60. package/{src/nodes → examples/jsm/tsl}/display/DotScreenNode.js +2 -9
  61. package/examples/jsm/tsl/display/FXAANode.js +316 -0
  62. package/{src/nodes → examples/jsm/tsl}/display/FilmNode.js +2 -6
  63. package/{src/nodes → examples/jsm/tsl}/display/GTAONode.js +30 -70
  64. package/{src/nodes → examples/jsm/tsl}/display/GaussianBlurNode.js +74 -36
  65. package/examples/jsm/tsl/display/LensflareNode.js +161 -0
  66. package/{src/nodes → examples/jsm/tsl}/display/Lut3DNode.js +1 -4
  67. package/{src/nodes → examples/jsm/tsl}/display/MotionBlur.js +2 -3
  68. package/examples/jsm/tsl/display/OutlineNode.js +434 -0
  69. package/{src/nodes → examples/jsm/tsl}/display/ParallaxBarrierPassNode.js +1 -5
  70. package/{src/nodes → examples/jsm/tsl}/display/PixelationPassNode.js +3 -15
  71. package/{src/nodes → examples/jsm/tsl}/display/RGBShiftNode.js +1 -6
  72. package/examples/jsm/tsl/display/SMAANode.js +620 -0
  73. package/{src/nodes → examples/jsm/tsl}/display/SSAAPassNode.js +10 -25
  74. package/examples/jsm/tsl/display/SSRNode.js +343 -0
  75. package/{src/nodes → examples/jsm/tsl}/display/Sepia.js +1 -2
  76. package/{src/nodes → examples/jsm/tsl}/display/SobelOperatorNode.js +3 -11
  77. package/{src/nodes → examples/jsm/tsl}/display/StereoCompositePassNode.js +9 -11
  78. package/{src/nodes → examples/jsm/tsl}/display/StereoPassNode.js +10 -11
  79. package/examples/jsm/tsl/display/TRAAPassNode.js +355 -0
  80. package/{src/nodes → examples/jsm/tsl}/display/TransitionNode.js +1 -6
  81. package/examples/jsm/tsl/display/hashBlur.js +24 -0
  82. package/examples/jsm/tsl/lighting/TiledLightsNode.js +392 -0
  83. package/examples/jsm/utils/{TextureUtilsGPU.js → WebGPUTextureUtils.js} +2 -1
  84. package/examples/jsm/webxr/OculusHandPointerModel.js +21 -21
  85. package/examples/jsm/webxr/Text2D.js +6 -6
  86. package/package.json +2 -2
  87. package/src/Three.WebGPU.Nodes.js +4 -0
  88. package/src/Three.WebGPU.js +4 -0
  89. package/src/constants.js +1 -6
  90. package/src/core/BufferGeometry.js +44 -6
  91. package/src/geometries/CylinderGeometry.js +2 -2
  92. package/src/materials/LineBasicMaterial.js +6 -2
  93. package/src/materials/LineDashedMaterial.js +6 -2
  94. package/src/materials/Material.js +14 -1
  95. package/src/materials/MeshBasicMaterial.js +6 -2
  96. package/src/materials/MeshDepthMaterial.js +6 -2
  97. package/src/materials/MeshDistanceMaterial.js +6 -2
  98. package/src/materials/MeshLambertMaterial.js +6 -2
  99. package/src/materials/MeshMatcapMaterial.js +6 -2
  100. package/src/materials/MeshNormalMaterial.js +6 -2
  101. package/src/materials/MeshPhongMaterial.js +6 -2
  102. package/src/materials/MeshPhysicalMaterial.js +6 -2
  103. package/src/materials/MeshStandardMaterial.js +6 -2
  104. package/src/materials/MeshToonMaterial.js +6 -2
  105. package/src/materials/PointsMaterial.js +6 -2
  106. package/src/materials/RawShaderMaterial.js +6 -2
  107. package/src/materials/ShaderMaterial.js +6 -2
  108. package/src/materials/ShadowMaterial.js +6 -2
  109. package/src/materials/SpriteMaterial.js +6 -2
  110. package/src/materials/nodes/NodeMaterial.js +31 -9
  111. package/src/materials/nodes/SpriteNodeMaterial.js +11 -2
  112. package/src/materials/nodes/manager/NodeMaterialObserver.js +111 -2
  113. package/src/math/ColorManagement.js +118 -85
  114. package/src/math/Vector4.js +11 -0
  115. package/src/nodes/Nodes.js +1 -21
  116. package/src/nodes/TSL.js +6 -24
  117. package/src/nodes/accessors/Camera.js +0 -1
  118. package/src/nodes/accessors/SceneNode.js +35 -1
  119. package/src/nodes/accessors/StorageBufferNode.js +32 -10
  120. package/src/nodes/accessors/VelocityNode.js +13 -3
  121. package/src/nodes/code/FunctionCallNode.js +16 -5
  122. package/src/nodes/code/ScriptableNode.js +4 -4
  123. package/src/nodes/core/Node.js +1 -0
  124. package/src/nodes/core/NodeBuilder.js +29 -5
  125. package/src/nodes/core/VarNode.js +15 -3
  126. package/src/nodes/display/ColorAdjustment.js +53 -4
  127. package/src/nodes/display/ColorSpaceFunctions.js +5 -5
  128. package/src/nodes/display/ColorSpaceNode.js +27 -39
  129. package/src/nodes/display/PassNode.js +6 -4
  130. package/src/nodes/display/ToneMappingNode.js +1 -1
  131. package/src/nodes/display/ViewportDepthNode.js +33 -1
  132. package/src/nodes/functions/PhysicalLightingModel.js +21 -15
  133. package/src/nodes/functions/material/getAlphaHashThreshold.js +64 -0
  134. package/src/nodes/functions/material/getGeometryRoughness.js +8 -2
  135. package/src/nodes/functions/material/getParallaxCorrectNormal.js +22 -0
  136. package/src/nodes/gpgpu/ComputeNode.js +9 -1
  137. package/src/nodes/lighting/AnalyticLightNode.js +12 -416
  138. package/src/nodes/lighting/LightsNode.js +24 -12
  139. package/src/nodes/lighting/PointLightNode.js +36 -26
  140. package/src/nodes/lighting/RectAreaLightNode.js +3 -0
  141. package/src/nodes/lighting/ShadowNode.js +484 -0
  142. package/src/nodes/utils/LoopNode.js +2 -2
  143. package/src/nodes/utils/Oscillators.js +6 -0
  144. package/src/nodes/utils/PostProcessingUtils.js +89 -0
  145. package/src/nodes/utils/ReflectorNode.js +101 -15
  146. package/src/nodes/utils/Timer.js +29 -0
  147. package/src/objects/BatchedMesh.js +458 -241
  148. package/src/renderers/WebGLRenderer.js +121 -126
  149. package/src/renderers/common/Attributes.js +4 -0
  150. package/src/renderers/common/Backend.js +2 -0
  151. package/src/renderers/common/Background.js +14 -4
  152. package/src/renderers/common/Bindings.js +3 -2
  153. package/src/renderers/common/Constants.js +2 -1
  154. package/src/renderers/common/Geometries.js +20 -0
  155. package/src/renderers/common/IndirectStorageBufferAttribute.js +15 -0
  156. package/src/renderers/common/Lighting.js +45 -0
  157. package/src/renderers/common/PostProcessingUtils.js +86 -0
  158. package/src/renderers/common/RenderList.js +39 -11
  159. package/src/renderers/common/RenderLists.js +4 -2
  160. package/src/renderers/common/RenderObject.js +18 -1
  161. package/src/renderers/common/Renderer.js +165 -26
  162. package/src/renderers/common/Textures.js +30 -14
  163. package/src/renderers/common/nodes/NodeLibrary.js +1 -14
  164. package/src/renderers/common/nodes/Nodes.js +2 -2
  165. package/src/renderers/shaders/ShaderChunk/colorspace_pars_fragment.glsl.js +4 -24
  166. package/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl.js +8 -0
  167. package/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js +2 -2
  168. package/src/renderers/webgl/WebGLBufferRenderer.js +2 -6
  169. package/src/renderers/webgl/WebGLCapabilities.js +0 -7
  170. package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +2 -6
  171. package/src/renderers/webgl/WebGLProgram.js +24 -28
  172. package/src/renderers/webgl/WebGLPrograms.js +5 -2
  173. package/src/renderers/webgl/WebGLState.js +37 -1
  174. package/src/renderers/webgl/WebGLTextures.js +29 -12
  175. package/src/renderers/webgl-fallback/WebGLBackend.js +98 -31
  176. package/src/renderers/webgl-fallback/WebGLBufferRenderer.js +2 -7
  177. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +33 -8
  178. package/src/renderers/webgpu/WebGPUBackend.js +105 -25
  179. package/src/renderers/webgpu/WebGPURenderer.Nodes.js +1 -1
  180. package/src/renderers/webgpu/WebGPURenderer.js +1 -1
  181. package/src/renderers/webgpu/nodes/BasicNodeLibrary.js +0 -8
  182. package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +0 -8
  183. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +10 -20
  184. package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +12 -4
  185. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +29 -9
  186. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +24 -6
  187. package/src/renderers/webgpu/utils/WebGPUUtils.js +0 -1
  188. package/src/renderers/webxr/WebXRManager.js +4 -4
  189. package/examples/jsm/cameras/CinematicCamera.js +0 -208
  190. package/src/nodes/display/FXAANode.js +0 -332
  191. package/src/nodes/utils/OscNode.js +0 -85
  192. package/src/nodes/utils/TimerNode.js +0 -97
  193. package/src/renderers/webvr/WebVRManager.js +0 -495
  194. package/src/renderers/webvr/WebVRUtils.js +0 -66
  195. /package/examples/jsm/utils/{TextureUtils.js → WebGLTextureUtils.js} +0 -0
@@ -1,28 +1,11 @@
1
- import TempNode from '../core/TempNode.js';
2
- import { texture } from '../accessors/TextureNode.js';
3
- import { textureSize } from '../accessors/TextureSizeNode.js';
4
- import { uv } from '../accessors/UV.js';
5
- import { nodeObject, Fn, mat3, vec2, vec3, vec4, float, int, If } from '../tsl/TSLBase.js';
6
- import { NodeUpdateType } from '../core/constants.js';
7
- import { uniform } from '../core/UniformNode.js';
8
- import { DataTexture } from '../../textures/DataTexture.js';
9
- import { Vector2 } from '../../math/Vector2.js';
10
- import { Vector3 } from '../../math/Vector3.js';
11
- import { PI, cos, sin, pow, clamp, abs, max, mix, sqrt, acos, dot, normalize, cross } from '../math/MathNode.js';
12
- import { div, mul, add, sub } from '../math/OperatorNode.js';
13
- import { Loop } from '../utils/LoopNode.js';
14
- import { passTexture } from './PassNode.js';
15
- import { RepeatWrapping } from '../../constants.js';
16
- import QuadMesh from '../../renderers/common/QuadMesh.js';
17
- import NodeMaterial from '../../materials/nodes/NodeMaterial.js';
18
-
19
- import { RenderTarget } from '../../core/RenderTarget.js';
20
- import { Color } from '../../math/Color.js';
1
+ import { DataTexture, RenderTarget, RepeatWrapping, Vector2, Vector3, PostProcessingUtils } from 'three';
2
+ import { getNormalFromDepth, getScreenPosition, getViewPosition, QuadMesh, TempNode, nodeObject, Fn, float, NodeUpdateType, uv, uniform, Loop, vec2, vec3, vec4, int, dot, max, pow, abs, If, textureSize, sin, cos, PI, texture, passTexture, mat3, add, normalize, mul, cross, div, mix, sqrt, sub, acos, clamp, NodeMaterial } from 'three/tsl';
21
3
 
22
4
  const _quadMesh = /*@__PURE__*/ new QuadMesh();
23
- const _currentClearColor = /*@__PURE__*/ new Color();
24
5
  const _size = /*@__PURE__*/ new Vector2();
25
6
 
7
+ let _rendererState;
8
+
26
9
  class GTAONode extends TempNode {
27
10
 
28
11
  static get type() {
@@ -51,7 +34,7 @@ class GTAONode extends TempNode {
51
34
 
52
35
  this.SAMPLES = uniform( 16 );
53
36
 
54
- this._aoRenderTarget = new RenderTarget();
37
+ this._aoRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false } );
55
38
  this._aoRenderTarget.texture.name = 'GTAONode.AO';
56
39
 
57
40
  this._material = null;
@@ -78,20 +61,17 @@ class GTAONode extends TempNode {
78
61
 
79
62
  const { renderer } = frame;
80
63
 
81
- const size = renderer.getDrawingBufferSize( _size );
82
-
83
- const currentRenderTarget = renderer.getRenderTarget();
84
- const currentMRT = renderer.getMRT();
85
- renderer.getClearColor( _currentClearColor );
86
- const currentClearAlpha = renderer.getClearAlpha();
64
+ _rendererState = PostProcessingUtils.resetRendererState( renderer, _rendererState );
87
65
 
88
- _quadMesh.material = this._material;
66
+ //
89
67
 
68
+ const size = renderer.getDrawingBufferSize( _size );
90
69
  this.setSize( size.width, size.height );
91
70
 
71
+ _quadMesh.material = this._material;
72
+
92
73
  // clear
93
74
 
94
- renderer.setMRT( null );
95
75
  renderer.setClearColor( 0xffffff, 1 );
96
76
 
97
77
  // ao
@@ -101,9 +81,7 @@ class GTAONode extends TempNode {
101
81
 
102
82
  // restore
103
83
 
104
- renderer.setRenderTarget( currentRenderTarget );
105
- renderer.setMRT( currentMRT );
106
- renderer.setClearColor( _currentClearColor, currentClearAlpha );
84
+ PostProcessingUtils.restoreRendererState( renderer, _rendererState );
107
85
 
108
86
  }
109
87
 
@@ -113,36 +91,16 @@ class GTAONode extends TempNode {
113
91
 
114
92
  const sampleDepth = ( uv ) => this.depthNode.uv( uv ).x;
115
93
  const sampleNoise = ( uv ) => this.noiseNode.uv( uv );
116
-
117
- const getSceneUvAndDepth = Fn( ( [ sampleViewPos ] )=> {
118
-
119
- const sampleClipPos = this.cameraProjectionMatrix.mul( vec4( sampleViewPos, 1.0 ) );
120
- let sampleUv = sampleClipPos.xy.div( sampleClipPos.w ).mul( 0.5 ).add( 0.5 ).toVar();
121
- sampleUv = vec2( sampleUv.x, sampleUv.y.oneMinus() );
122
- const sampleSceneDepth = sampleDepth( sampleUv );
123
- return vec3( sampleUv, sampleSceneDepth );
124
-
125
- } );
126
-
127
- const getViewPosition = Fn( ( [ screenPosition, depth ] ) => {
128
-
129
- screenPosition = vec2( screenPosition.x, screenPosition.y.oneMinus() ).mul( 2.0 ).sub( 1.0 );
130
-
131
- const clipSpacePosition = vec4( vec3( screenPosition, depth ), 1.0 );
132
- const viewSpacePosition = vec4( this.cameraProjectionMatrixInverse.mul( clipSpacePosition ) );
133
-
134
- return viewSpacePosition.xyz.div( viewSpacePosition.w );
135
-
136
- } );
94
+ const sampleNormal = ( uv ) => ( this.normalNode !== null ) ? this.normalNode.uv( uv ).rgb.normalize() : getNormalFromDepth( uv, this.depthNode.value, this.cameraProjectionMatrixInverse );
137
95
 
138
96
  const ao = Fn( () => {
139
97
 
140
- const depth = sampleDepth( uvNode );
98
+ const depth = sampleDepth( uvNode ).toVar();
141
99
 
142
100
  depth.greaterThanEqual( 1.0 ).discard();
143
101
 
144
- const viewPosition = getViewPosition( uvNode, depth );
145
- const viewNormal = this.normalNode.rgb.normalize();
102
+ const viewPosition = getViewPosition( uvNode, depth, this.cameraProjectionMatrixInverse ).toVar();
103
+ const viewNormal = sampleNormal( uvNode ).toVar();
146
104
 
147
105
  const radiusToUse = this.radius;
148
106
 
@@ -155,23 +113,23 @@ class GTAONode extends TempNode {
155
113
  const bitangent = vec3( tangent.y.mul( - 1.0 ), tangent.x, 0.0 );
156
114
  const kernelMatrix = mat3( tangent, bitangent, vec3( 0.0, 0.0, 1.0 ) );
157
115
 
158
- const DIRECTIONS = this.SAMPLES.lessThan( 30 ).select( 3, 5 );
159
- const STEPS = add( this.SAMPLES, DIRECTIONS.sub( 1 ) ).div( DIRECTIONS );
116
+ const DIRECTIONS = this.SAMPLES.lessThan( 30 ).select( 3, 5 ).toVar();
117
+ const STEPS = add( this.SAMPLES, DIRECTIONS.sub( 1 ) ).div( DIRECTIONS ).toVar();
160
118
 
161
119
  const ao = float( 0 ).toVar();
162
120
 
163
121
  Loop( { start: int( 0 ), end: DIRECTIONS, type: 'int', condition: '<' }, ( { i } ) => {
164
122
 
165
- const angle = float( i ).div( float( DIRECTIONS ) ).mul( PI );
123
+ const angle = float( i ).div( float( DIRECTIONS ) ).mul( PI ).toVar();
166
124
  const sampleDir = vec4( cos( angle ), sin( angle ), 0., add( 0.5, mul( 0.5, noiseTexel.w ) ) );
167
125
  sampleDir.xyz = normalize( kernelMatrix.mul( sampleDir.xyz ) );
168
126
 
169
- const viewDir = normalize( viewPosition.xyz.negate() );
170
- const sliceBitangent = normalize( cross( sampleDir.xyz, viewDir ) );
127
+ const viewDir = normalize( viewPosition.xyz.negate() ).toVar();
128
+ const sliceBitangent = normalize( cross( sampleDir.xyz, viewDir ) ).toVar();
171
129
  const sliceTangent = cross( sliceBitangent, viewDir );
172
130
  const normalInSlice = normalize( viewNormal.sub( sliceBitangent.mul( dot( viewNormal, sliceBitangent ) ) ) );
173
131
 
174
- const tangentToNormalInSlice = cross( normalInSlice, sliceBitangent );
132
+ const tangentToNormalInSlice = cross( normalInSlice, sliceBitangent ).toVar();
175
133
  const cosHorizons = vec2( dot( viewDir, tangentToNormalInSlice ), dot( viewDir, tangentToNormalInSlice.negate() ) ).toVar();
176
134
 
177
135
  Loop( { end: STEPS, type: 'int', name: 'j', condition: '<' }, ( { j } ) => {
@@ -180,9 +138,10 @@ class GTAONode extends TempNode {
180
138
 
181
139
  // x
182
140
 
183
- const sampleSceneUvDepthX = getSceneUvAndDepth( viewPosition.add( sampleViewOffset ) );
184
- const sampleSceneViewPositionX = getViewPosition( sampleSceneUvDepthX.xy, sampleSceneUvDepthX.z );
185
- const viewDeltaX = sampleSceneViewPositionX.sub( viewPosition );
141
+ const sampleScreenPositionX = getScreenPosition( viewPosition.add( sampleViewOffset ), this.cameraProjectionMatrix ).toVar();
142
+ const sampleDepthX = sampleDepth( sampleScreenPositionX ).toVar();
143
+ const sampleSceneViewPositionX = getViewPosition( sampleScreenPositionX, sampleDepthX, this.cameraProjectionMatrixInverse ).toVar();
144
+ const viewDeltaX = sampleSceneViewPositionX.sub( viewPosition ).toVar();
186
145
 
187
146
  If( abs( viewDeltaX.z ).lessThan( this.thickness ), () => {
188
147
 
@@ -193,9 +152,10 @@ class GTAONode extends TempNode {
193
152
 
194
153
  // y
195
154
 
196
- const sampleSceneUvDepthY = getSceneUvAndDepth( viewPosition.sub( sampleViewOffset ) );
197
- const sampleSceneViewPositionY = getViewPosition( sampleSceneUvDepthY.xy, sampleSceneUvDepthY.z );
198
- const viewDeltaY = sampleSceneViewPositionY.sub( viewPosition );
155
+ const sampleScreenPositionY = getScreenPosition( viewPosition.sub( sampleViewOffset ), this.cameraProjectionMatrix ).toVar();
156
+ const sampleDepthY = sampleDepth( sampleScreenPositionY ).toVar();
157
+ const sampleSceneViewPositionY = getViewPosition( sampleScreenPositionY, sampleDepthY, this.cameraProjectionMatrixInverse ).toVar();
158
+ const viewDeltaY = sampleSceneViewPositionY.sub( viewPosition ).toVar();
199
159
 
200
160
  If( abs( viewDeltaY.z ).lessThan( this.thickness ), () => {
201
161
 
@@ -206,7 +166,7 @@ class GTAONode extends TempNode {
206
166
 
207
167
  } );
208
168
 
209
- const sinHorizons = sqrt( sub( 1.0, cosHorizons.mul( cosHorizons ) ) );
169
+ const sinHorizons = sqrt( sub( 1.0, cosHorizons.mul( cosHorizons ) ) ).toVar();
210
170
  const nx = dot( normalInSlice, sliceTangent );
211
171
  const ny = dot( normalInSlice, viewDir );
212
172
  const nxb = mul( 0.5, acos( cosHorizons.y ).sub( acos( cosHorizons.x ) ).add( sinHorizons.x.mul( cosHorizons.x ).sub( sinHorizons.y.mul( cosHorizons.y ) ) ) );
@@ -1,16 +1,5 @@
1
- import TempNode from '../core/TempNode.js';
2
- import { nodeObject, Fn, float, vec2, vec4 } from '../tsl/TSLBase.js';
3
- import { NodeUpdateType } from '../core/constants.js';
4
- import { mul } from '../math/OperatorNode.js';
5
- import { uv } from '../accessors/UV.js';
6
- import { passTexture } from './PassNode.js';
7
- import { uniform } from '../core/UniformNode.js';
8
- import { convertToTexture } from '../utils/RTTNode.js';
9
- import QuadMesh from '../../renderers/common/QuadMesh.js';
10
-
11
- import { Vector2 } from '../../math/Vector2.js';
12
- import { RenderTarget } from '../../core/RenderTarget.js';
13
- import NodeMaterial from '../../materials/nodes/NodeMaterial.js';
1
+ import { RenderTarget, Vector2, PostProcessingUtils } from 'three';
2
+ import { TempNode, nodeObject, Fn, If, float, NodeUpdateType, uv, uniform, convertToTexture, vec2, vec4, QuadMesh, passTexture, mul, NodeMaterial } from 'three/tsl';
14
3
 
15
4
  // WebGPU: The use of a single QuadMesh for both gaussian blur passes results in a single RenderObject with a SampledTexture binding that
16
5
  // alternates between source textures and triggers creation of new BindGroups and BindGroupLayouts every frame.
@@ -18,6 +7,34 @@ import NodeMaterial from '../../materials/nodes/NodeMaterial.js';
18
7
  const _quadMesh1 = /*@__PURE__*/ new QuadMesh();
19
8
  const _quadMesh2 = /*@__PURE__*/ new QuadMesh();
20
9
 
10
+ let _rendererState;
11
+
12
+ const premult = /*@__PURE__*/ Fn( ( [ color ] ) => {
13
+
14
+ return vec4( color.rgb.mul( color.a ), color.a );
15
+
16
+ } ).setLayout( {
17
+ name: 'premult',
18
+ type: 'vec4',
19
+ inputs: [
20
+ { name: 'color', type: 'vec4' }
21
+ ]
22
+ } );
23
+
24
+ const unpremult = /*@__PURE__*/ Fn( ( [ color ] ) => {
25
+
26
+ If( color.a.equal( 0.0 ), () => vec4( 0.0 ) );
27
+
28
+ return vec4( color.rgb.div( color.a ), color.a );
29
+
30
+ } ).setLayout( {
31
+ name: 'unpremult',
32
+ type: 'vec4',
33
+ inputs: [
34
+ { name: 'color', type: 'vec4' }
35
+ ]
36
+ } );
37
+
21
38
  class GaussianBlurNode extends TempNode {
22
39
 
23
40
  static get type() {
@@ -37,17 +54,34 @@ class GaussianBlurNode extends TempNode {
37
54
  this._invSize = uniform( new Vector2() );
38
55
  this._passDirection = uniform( new Vector2() );
39
56
 
40
- this._horizontalRT = new RenderTarget();
57
+ this._horizontalRT = new RenderTarget( 1, 1, { depthBuffer: false } );
41
58
  this._horizontalRT.texture.name = 'GaussianBlurNode.horizontal';
42
- this._verticalRT = new RenderTarget();
59
+ this._verticalRT = new RenderTarget( 1, 1, { depthBuffer: false } );
43
60
  this._verticalRT.texture.name = 'GaussianBlurNode.vertical';
44
61
 
45
62
  this._textureNode = passTexture( this, this._verticalRT.texture );
63
+ this._textureNode.uvNode = textureNode.uvNode;
46
64
 
47
- this.updateBeforeType = NodeUpdateType.RENDER;
65
+ this.updateBeforeType = NodeUpdateType.FRAME;
48
66
 
49
67
  this.resolution = new Vector2( 1, 1 );
50
68
 
69
+ this.premultipliedAlpha = false;
70
+
71
+ }
72
+
73
+ setPremultipliedAlpha( value ) {
74
+
75
+ this.premultipliedAlpha = value;
76
+
77
+ return this;
78
+
79
+ }
80
+
81
+ getPremultipliedAlpha() {
82
+
83
+ return this.premultipliedAlpha;
84
+
51
85
  }
52
86
 
53
87
  setSize( width, height ) {
@@ -65,12 +99,13 @@ class GaussianBlurNode extends TempNode {
65
99
 
66
100
  const { renderer } = frame;
67
101
 
102
+ _rendererState = PostProcessingUtils.resetRendererState( renderer, _rendererState );
103
+
104
+ //
105
+
68
106
  const textureNode = this.textureNode;
69
107
  const map = textureNode.value;
70
108
 
71
- const currentRenderTarget = renderer.getRenderTarget();
72
- const currentMRT = renderer.getMRT();
73
-
74
109
  const currentTexture = textureNode.value;
75
110
 
76
111
  _quadMesh1.material = this._material;
@@ -83,10 +118,6 @@ class GaussianBlurNode extends TempNode {
83
118
  this._horizontalRT.texture.type = textureType;
84
119
  this._verticalRT.texture.type = textureType;
85
120
 
86
- // clear
87
-
88
- renderer.setMRT( null );
89
-
90
121
  // horizontal
91
122
 
92
123
  renderer.setRenderTarget( this._horizontalRT );
@@ -106,10 +137,10 @@ class GaussianBlurNode extends TempNode {
106
137
 
107
138
  // restore
108
139
 
109
- renderer.setRenderTarget( currentRenderTarget );
110
- renderer.setMRT( currentMRT );
111
140
  textureNode.value = currentTexture;
112
141
 
142
+ PostProcessingUtils.restoreRendererState( renderer, _rendererState );
143
+
113
144
  }
114
145
 
115
146
  getTextureNode() {
@@ -122,20 +153,26 @@ class GaussianBlurNode extends TempNode {
122
153
 
123
154
  const textureNode = this.textureNode;
124
155
 
125
- if ( textureNode.isTextureNode !== true ) {
156
+ //
126
157
 
127
- console.error( 'GaussianBlurNode requires a TextureNode.' );
158
+ const uvNode = textureNode.uvNode || uv();
159
+ const directionNode = vec2( this.directionNode || 1 );
128
160
 
129
- return vec4();
161
+ let sampleTexture, output;
130
162
 
131
- }
163
+ if ( this.premultipliedAlpha ) {
132
164
 
133
- //
165
+ // https://lisyarus.github.io/blog/posts/blur-coefficients-generator.html
134
166
 
135
- const uvNode = textureNode.uvNode || uv();
136
- const directionNode = vec2( this.directionNode || 1 );
167
+ sampleTexture = ( uv ) => premult( textureNode.uv( uv ) );
168
+ output = ( color ) => unpremult( color );
169
+
170
+ } else {
137
171
 
138
- const sampleTexture = ( uv ) => textureNode.uv( uv );
172
+ sampleTexture = ( uv ) => textureNode.uv( uv );
173
+ output = ( color ) => color;
174
+
175
+ }
139
176
 
140
177
  const blur = Fn( () => {
141
178
 
@@ -155,15 +192,15 @@ class GaussianBlurNode extends TempNode {
155
192
 
156
193
  const uvOffset = vec2( direction.mul( invSize.mul( x ) ) ).toVar();
157
194
 
158
- const sample1 = vec4( sampleTexture( uvNode.add( uvOffset ) ) );
159
- const sample2 = vec4( sampleTexture( uvNode.sub( uvOffset ) ) );
195
+ const sample1 = sampleTexture( uvNode.add( uvOffset ) );
196
+ const sample2 = sampleTexture( uvNode.sub( uvOffset ) );
160
197
 
161
198
  diffuseSum.addAssign( sample1.add( sample2 ).mul( w ) );
162
199
  weightSum.addAssign( mul( 2.0, w ) );
163
200
 
164
201
  }
165
202
 
166
- return diffuseSum.div( weightSum );
203
+ return output( diffuseSum.div( weightSum ) );
167
204
 
168
205
  } );
169
206
 
@@ -211,3 +248,4 @@ class GaussianBlurNode extends TempNode {
211
248
  export default GaussianBlurNode;
212
249
 
213
250
  export const gaussianBlur = ( node, directionNode, sigma ) => nodeObject( new GaussianBlurNode( convertToTexture( node ), directionNode, sigma ) );
251
+ export const premultipliedGaussianBlur = ( node, directionNode, sigma ) => nodeObject( new GaussianBlurNode( convertToTexture( node ), directionNode, sigma ).setPremultipliedAlpha( true ) );
@@ -0,0 +1,161 @@
1
+ import { RenderTarget, Vector2 } from 'three';
2
+ import { convertToTexture, TempNode, nodeObject, Fn, NodeUpdateType, QuadMesh, PostProcessingUtils, NodeMaterial, passTexture, uv, vec2, vec3, vec4, max, float, sub, int, Loop, fract, pow, distance } from 'three/tsl';
3
+
4
+ const _quadMesh = /*@__PURE__*/ new QuadMesh();
5
+ const _size = /*@__PURE__*/ new Vector2();
6
+ let _rendererState;
7
+
8
+ /**
9
+ * References:
10
+ * https://john-chapman-graphics.blogspot.com/2013/02/pseudo-lens-flare.html
11
+ * https://john-chapman.github.io/2017/11/05/pseudo-lens-flare.html
12
+ */
13
+ class LensflareNode extends TempNode {
14
+
15
+ static get type() {
16
+
17
+ return 'LensflareNode';
18
+
19
+ }
20
+
21
+ constructor( textureNode, params = {} ) {
22
+
23
+ super();
24
+
25
+ this.textureNode = textureNode;
26
+
27
+ const {
28
+ ghostTint = vec3( 1, 1, 1 ),
29
+ threshold = float( 0.5 ),
30
+ ghostSamples = float( 4 ),
31
+ ghostSpacing = float( 0.25 ),
32
+ ghostAttenuationFactor = float( 25 ),
33
+ downSampleRatio = 4
34
+ } = params;
35
+
36
+ this.ghostTintNode = nodeObject( ghostTint );
37
+ this.thresholdNode = nodeObject( threshold );
38
+ this.ghostSamplesNode = nodeObject( ghostSamples );
39
+ this.ghostSpacingNode = nodeObject( ghostSpacing );
40
+ this.ghostAttenuationFactorNode = nodeObject( ghostAttenuationFactor );
41
+ this.downSampleRatio = downSampleRatio;
42
+
43
+ this.updateBeforeType = NodeUpdateType.FRAME;
44
+
45
+ // render targets
46
+
47
+ this._renderTarget = new RenderTarget( 1, 1, { depthBuffer: false } );
48
+ this._renderTarget.texture.name = 'LensflareNode';
49
+
50
+ // materials
51
+
52
+ this._material = new NodeMaterial();
53
+ this._material.name = 'LensflareNode';
54
+
55
+ //
56
+
57
+ this._textureNode = passTexture( this, this._renderTarget.texture );
58
+
59
+ }
60
+
61
+ getTextureNode() {
62
+
63
+ return this._textureNode;
64
+
65
+ }
66
+
67
+ setSize( width, height ) {
68
+
69
+ const resx = Math.round( width / this.downSampleRatio );
70
+ const resy = Math.round( height / this.downSampleRatio );
71
+
72
+ this._renderTarget.setSize( resx, resy );
73
+
74
+ }
75
+
76
+ updateBefore( frame ) {
77
+
78
+ const { renderer } = frame;
79
+
80
+ const size = renderer.getDrawingBufferSize( _size );
81
+ this.setSize( size.width, size.height );
82
+
83
+ _rendererState = PostProcessingUtils.resetRendererState( renderer, _rendererState );
84
+
85
+ _quadMesh.material = this._material;
86
+
87
+ // clear
88
+
89
+ renderer.setMRT( null );
90
+
91
+ // lensflare
92
+
93
+ renderer.setRenderTarget( this._renderTarget );
94
+ _quadMesh.render( renderer );
95
+
96
+ // restore
97
+
98
+ PostProcessingUtils.restoreRendererState( renderer, _rendererState );
99
+
100
+ }
101
+
102
+ setup( builder ) {
103
+
104
+ const lensflare = Fn( () => {
105
+
106
+ // flip uvs so lens flare pivot around the image center
107
+
108
+ const texCoord = uv().oneMinus().toVar();
109
+
110
+ // ghosts are positioned along this vector
111
+
112
+ const ghostVec = sub( vec2( 0.5 ), texCoord ).mul( this.ghostSpacingNode ).toVar();
113
+
114
+ // sample ghosts
115
+
116
+ const result = vec4().toVar();
117
+
118
+ Loop( { start: int( 0 ), end: int( this.ghostSamplesNode ), type: 'int', condition: '<' }, ( { i } ) => {
119
+
120
+ // use fract() to ensure that the texture coordinates wrap around
121
+
122
+ const sampleUv = fract( texCoord.add( ghostVec.mul( float( i ) ) ) ).toVar();
123
+
124
+ // reduce contributions from samples at the screen edge
125
+
126
+ const d = distance( sampleUv, vec2( 0.5 ) );
127
+ const weight = pow( d.oneMinus(), this.ghostAttenuationFactorNode );
128
+
129
+ // accumulate
130
+
131
+ let sample = this.textureNode.uv( sampleUv ).rgb;
132
+
133
+ sample = max( sample.sub( this.thresholdNode ), vec3( 0 ) ).mul( this.ghostTintNode );
134
+
135
+ result.addAssign( sample.mul( weight ) );
136
+
137
+ } );
138
+
139
+ return result;
140
+
141
+ } );
142
+
143
+ this._material.fragmentNode = lensflare().context( builder.getSharedContext() );
144
+ this._material.needsUpdate = true;
145
+
146
+ return this._textureNode;
147
+
148
+ }
149
+
150
+ dispose() {
151
+
152
+ this._renderTarget.dispose();
153
+ this._material.dispose();
154
+
155
+ }
156
+
157
+ }
158
+
159
+ export default LensflareNode;
160
+
161
+ export const lensflare = ( inputNode, params ) => nodeObject( new LensflareNode( convertToTexture( inputNode ), params ) );
@@ -1,7 +1,4 @@
1
- import TempNode from '../core/TempNode.js';
2
- import { Fn, nodeObject, vec3, vec4, float } from '../tsl/TSLBase.js';
3
- import { uniform } from '../core/UniformNode.js';
4
- import { mix } from '../math/MathNode.js';
1
+ import { TempNode, nodeObject, Fn, float, uniform, vec3, vec4, mix } from 'three/tsl';
5
2
 
6
3
  class Lut3DNode extends TempNode {
7
4
 
@@ -1,6 +1,5 @@
1
- import { float, int, Fn } from '../tsl/TSLBase.js';
2
- import { Loop } from '../utils/LoopNode.js';
3
- import { uv } from '../accessors/UV.js';
1
+
2
+ import { Fn, float, uv, Loop, int } from 'three/tsl';
4
3
 
5
4
  export const motionBlur = /*@__PURE__*/ Fn( ( [ inputNode, velocity, numSamples = int( 16 ) ] ) => {
6
5