Przeglądaj źródła

StorageTexture: Adds support for other formats. (#26842)

* TimeNode: Define `frameId` as integer

* Renderer: Set `info` as public

* StorageTexture: Adds support for other formats.

* Update example to `temporal blur`

* fix device in getFormat()
sunag 1 rok temu
rodzic
commit
6a5d6de348

+ 1 - 1
examples/jsm/nodes/utils/TimerNode.js

@@ -89,6 +89,6 @@ export default TimerNode;
 export const timerLocal = ( timeScale, value = 0 ) => nodeObject( new TimerNode( TimerNode.LOCAL, timeScale, value ) );
 export const timerLocal = ( timeScale, value = 0 ) => nodeObject( new TimerNode( TimerNode.LOCAL, timeScale, value ) );
 export const timerGlobal = ( timeScale, value = 0 ) => nodeObject( new TimerNode( TimerNode.GLOBAL, timeScale, value ) );
 export const timerGlobal = ( timeScale, value = 0 ) => nodeObject( new TimerNode( TimerNode.GLOBAL, timeScale, value ) );
 export const timerDelta = ( timeScale, value = 0 ) => nodeObject( new TimerNode( TimerNode.DELTA, timeScale, value ) );
 export const timerDelta = ( timeScale, value = 0 ) => nodeObject( new TimerNode( TimerNode.DELTA, timeScale, value ) );
-export const frameId = nodeImmutable( TimerNode, TimerNode.FRAME );
+export const frameId = nodeImmutable( TimerNode, TimerNode.FRAME ).uint();
 
 
 addNodeClass( TimerNode );
 addNodeClass( TimerNode );

+ 11 - 10
examples/jsm/renderers/common/Renderer.js

@@ -46,6 +46,8 @@ class Renderer {
 		this.depth = true;
 		this.depth = true;
 		this.stencil = true;
 		this.stencil = true;
 
 
+		this.info = new Info();
+
 		// internals
 		// internals
 
 
 		this._pixelRatio = 1;
 		this._pixelRatio = 1;
@@ -56,7 +58,6 @@ class Renderer {
 		this._scissor = new Vector4( 0, 0, this._width, this._height );
 		this._scissor = new Vector4( 0, 0, this._width, this._height );
 		this._scissorTest = false;
 		this._scissorTest = false;
 
 
-		this._info = null;
 		this._properties = null;
 		this._properties = null;
 		this._attributes = null;
 		this._attributes = null;
 		this._geometries = null;
 		this._geometries = null;
@@ -131,15 +132,14 @@ class Renderer {
 
 
 			}
 			}
 
 
-			this._info = new Info();
 			this._nodes = new Nodes( this, backend );
 			this._nodes = new Nodes( this, backend );
 			this._attributes = new Attributes( backend );
 			this._attributes = new Attributes( backend );
 			this._background = new Background( this, this._nodes );
 			this._background = new Background( this, this._nodes );
-			this._geometries = new Geometries( this._attributes, this._info );
-			this._textures = new Textures( backend, this._info );
+			this._geometries = new Geometries( this._attributes, this.info );
+			this._textures = new Textures( backend, this.info );
 			this._pipelines = new Pipelines( backend, this._nodes );
 			this._pipelines = new Pipelines( backend, this._nodes );
-			this._bindings = new Bindings( backend, this._nodes, this._textures, this._attributes, this._pipelines, this._info );
-			this._objects = new RenderObjects( this, this._nodes, this._geometries, this._pipelines, this._bindings, this._info );
+			this._bindings = new Bindings( backend, this._nodes, this._textures, this._attributes, this._pipelines, this.info );
+			this._objects = new RenderObjects( this, this._nodes, this._geometries, this._pipelines, this._bindings, this.info );
 			this._renderLists = new RenderLists();
 			this._renderLists = new RenderLists();
 			this._renderContexts = new RenderContexts();
 			this._renderContexts = new RenderContexts();
 
 
@@ -214,9 +214,9 @@ class Renderer {
 
 
 		if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
 		if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
 
 
-		if ( this._info.autoReset === true ) this._info.reset();
+		if ( this.info.autoReset === true ) this.info.reset();
 
 
-		this._info.render.frame ++;
+		this.info.render.frame ++;
 
 
 		//
 		//
 
 
@@ -612,12 +612,13 @@ class Renderer {
 
 
 	dispose() {
 	dispose() {
 
 
+		this.info.dispose();
+
 		this._objects.dispose();
 		this._objects.dispose();
 		this._properties.dispose();
 		this._properties.dispose();
 		this._pipelines.dispose();
 		this._pipelines.dispose();
 		this._nodes.dispose();
 		this._nodes.dispose();
 		this._bindings.dispose();
 		this._bindings.dispose();
-		this._info.dispose();
 		this._renderLists.dispose();
 		this._renderLists.dispose();
 		this._renderContexts.dispose();
 		this._renderContexts.dispose();
 		this._textures.dispose();
 		this._textures.dispose();
@@ -921,7 +922,7 @@ class Renderer {
 
 
 		//
 		//
 
 
-		this.backend.draw( renderObject, this._info );
+		this.backend.draw( renderObject, this.info );
 
 
 	}
 	}
 
 

+ 5 - 2
examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js

@@ -11,6 +11,8 @@ import { getVectorLength, getStrideLength } from '../../common/BufferUtils.js';
 
 
 import { NodeBuilder, CodeNode, NodeMaterial } from '../../../nodes/Nodes.js';
 import { NodeBuilder, CodeNode, NodeMaterial } from '../../../nodes/Nodes.js';
 
 
+import { getFormat } from '../utils/WebGPUTextureUtils.js';
+
 import WGSLNodeParser from './WGSLNodeParser.js';
 import WGSLNodeParser from './WGSLNodeParser.js';
 
 
 const gpuShaderStageLib = {
 const gpuShaderStageLib = {
@@ -659,8 +661,9 @@ class WGSLNodeBuilder extends NodeBuilder {
 
 
 				} else if ( uniform.node.isStoreTextureNode === true ) {
 				} else if ( uniform.node.isStoreTextureNode === true ) {
 
 
-					// @TODO: Add support for other formats
-					textureType = 'texture_storage_2d<rgba8unorm, write>';
+					const format = getFormat( texture );
+
+					textureType = 'texture_storage_2d<' + format + ', write>';
 
 
 				} else {
 				} else {
 
 

+ 152 - 152
examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js

@@ -106,7 +106,7 @@ class WebGPUTextureUtils {
 		const { width, height, depth, levels } = options;
 		const { width, height, depth, levels } = options;
 
 
 		const dimension = this._getDimension( texture );
 		const dimension = this._getDimension( texture );
-		const format = texture.internalFormat || this._getFormat( texture );
+		const format = texture.internalFormat || getFormat( texture, this.device );
 
 
 		const sampleCount = options.sampleCount !== undefined ? options.sampleCount : 1;
 		const sampleCount = options.sampleCount !== undefined ? options.sampleCount : 1;
 		const primarySampleCount = texture.isRenderTargetTexture ? 1 : sampleCount;
 		const primarySampleCount = texture.isRenderTargetTexture ? 1 : sampleCount;
@@ -649,237 +649,237 @@ class WebGPUTextureUtils {
 
 
 	}
 	}
 
 
-	_getFormat( texture ) {
+}
 
 
-		const format = texture.format;
-		const type = texture.type;
-		const colorSpace = texture.colorSpace;
+export function getFormat( texture, device = null ) {
 
 
-		let formatGPU;
+	const format = texture.format;
+	const type = texture.type;
+	const colorSpace = texture.colorSpace;
 
 
-		if ( /*texture.isRenderTargetTexture === true ||*/ texture.isFramebufferTexture === true ) {
+	let formatGPU;
 
 
-			formatGPU = GPUTextureFormat.BGRA8Unorm;
+	if ( /*texture.isRenderTargetTexture === true ||*/ texture.isFramebufferTexture === true ) {
 
 
-		} else if ( texture.isCompressedTexture === true ) {
+		formatGPU = GPUTextureFormat.BGRA8Unorm;
 
 
-			switch ( format ) {
+	} else if ( texture.isCompressedTexture === true ) {
 
 
-				case RGBA_S3TC_DXT1_Format:
-					formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC1RGBAUnormSRGB : GPUTextureFormat.BC1RGBAUnorm;
-					break;
+		switch ( format ) {
 
 
-				case RGBA_S3TC_DXT3_Format:
-					formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC2RGBAUnormSRGB : GPUTextureFormat.BC2RGBAUnorm;
-					break;
+			case RGBA_S3TC_DXT1_Format:
+				formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC1RGBAUnormSRGB : GPUTextureFormat.BC1RGBAUnorm;
+				break;
 
 
-				case RGBA_S3TC_DXT5_Format:
-					formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC3RGBAUnormSRGB : GPUTextureFormat.BC3RGBAUnorm;
-					break;
+			case RGBA_S3TC_DXT3_Format:
+				formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC2RGBAUnormSRGB : GPUTextureFormat.BC2RGBAUnorm;
+				break;
 
 
-				case RGB_ETC2_Format:
-					formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ETC2RGB8UnormSRGB : GPUTextureFormat.ETC2RGB8Unorm;
-					break;
+			case RGBA_S3TC_DXT5_Format:
+				formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC3RGBAUnormSRGB : GPUTextureFormat.BC3RGBAUnorm;
+				break;
 
 
-				case RGBA_ETC2_EAC_Format:
-					formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ETC2RGBA8UnormSRGB : GPUTextureFormat.ETC2RGBA8Unorm;
-					break;
+			case RGB_ETC2_Format:
+				formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ETC2RGB8UnormSRGB : GPUTextureFormat.ETC2RGB8Unorm;
+				break;
 
 
-				case RGBA_ASTC_4x4_Format:
-					formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC4x4UnormSRGB : GPUTextureFormat.ASTC4x4Unorm;
-					break;
+			case RGBA_ETC2_EAC_Format:
+				formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ETC2RGBA8UnormSRGB : GPUTextureFormat.ETC2RGBA8Unorm;
+				break;
 
 
-				case RGBA_ASTC_5x4_Format:
-					formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC5x4UnormSRGB : GPUTextureFormat.ASTC5x4Unorm;
-					break;
+			case RGBA_ASTC_4x4_Format:
+				formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC4x4UnormSRGB : GPUTextureFormat.ASTC4x4Unorm;
+				break;
 
 
-				case RGBA_ASTC_5x5_Format:
-					formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC5x5UnormSRGB : GPUTextureFormat.ASTC5x5Unorm;
-					break;
+			case RGBA_ASTC_5x4_Format:
+				formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC5x4UnormSRGB : GPUTextureFormat.ASTC5x4Unorm;
+				break;
 
 
-				case RGBA_ASTC_6x5_Format:
-					formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC6x5UnormSRGB : GPUTextureFormat.ASTC6x5Unorm;
-					break;
+			case RGBA_ASTC_5x5_Format:
+				formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC5x5UnormSRGB : GPUTextureFormat.ASTC5x5Unorm;
+				break;
 
 
-				case RGBA_ASTC_6x6_Format:
-					formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC6x6UnormSRGB : GPUTextureFormat.ASTC6x6Unorm;
-					break;
+			case RGBA_ASTC_6x5_Format:
+				formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC6x5UnormSRGB : GPUTextureFormat.ASTC6x5Unorm;
+				break;
 
 
-				case RGBA_ASTC_8x5_Format:
-					formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x5UnormSRGB : GPUTextureFormat.ASTC8x5Unorm;
-					break;
+			case RGBA_ASTC_6x6_Format:
+				formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC6x6UnormSRGB : GPUTextureFormat.ASTC6x6Unorm;
+				break;
 
 
-				case RGBA_ASTC_8x6_Format:
-					formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x6UnormSRGB : GPUTextureFormat.ASTC8x6Unorm;
-					break;
+			case RGBA_ASTC_8x5_Format:
+				formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x5UnormSRGB : GPUTextureFormat.ASTC8x5Unorm;
+				break;
 
 
-				case RGBA_ASTC_8x8_Format:
-					formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x8UnormSRGB : GPUTextureFormat.ASTC8x8Unorm;
-					break;
+			case RGBA_ASTC_8x6_Format:
+				formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x6UnormSRGB : GPUTextureFormat.ASTC8x6Unorm;
+				break;
 
 
-				case RGBA_ASTC_10x5_Format:
-					formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x5UnormSRGB : GPUTextureFormat.ASTC10x5Unorm;
-					break;
+			case RGBA_ASTC_8x8_Format:
+				formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x8UnormSRGB : GPUTextureFormat.ASTC8x8Unorm;
+				break;
 
 
-				case RGBA_ASTC_10x6_Format:
-					formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x6UnormSRGB : GPUTextureFormat.ASTC10x6Unorm;
-					break;
+			case RGBA_ASTC_10x5_Format:
+				formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x5UnormSRGB : GPUTextureFormat.ASTC10x5Unorm;
+				break;
 
 
-				case RGBA_ASTC_10x8_Format:
-					formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x8UnormSRGB : GPUTextureFormat.ASTC10x8Unorm;
-					break;
+			case RGBA_ASTC_10x6_Format:
+				formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x6UnormSRGB : GPUTextureFormat.ASTC10x6Unorm;
+				break;
 
 
-				case RGBA_ASTC_10x10_Format:
-					formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x10UnormSRGB : GPUTextureFormat.ASTC10x10Unorm;
-					break;
+			case RGBA_ASTC_10x8_Format:
+				formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x8UnormSRGB : GPUTextureFormat.ASTC10x8Unorm;
+				break;
 
 
-				case RGBA_ASTC_12x10_Format:
-					formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC12x10UnormSRGB : GPUTextureFormat.ASTC12x10Unorm;
-					break;
+			case RGBA_ASTC_10x10_Format:
+				formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x10UnormSRGB : GPUTextureFormat.ASTC10x10Unorm;
+				break;
 
 
-				case RGBA_ASTC_12x12_Format:
-					formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC12x12UnormSRGB : GPUTextureFormat.ASTC12x12Unorm;
-					break;
+			case RGBA_ASTC_12x10_Format:
+				formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC12x10UnormSRGB : GPUTextureFormat.ASTC12x10Unorm;
+				break;
 
 
-				default:
-					console.error( 'WebGPURenderer: Unsupported texture format.', format );
+			case RGBA_ASTC_12x12_Format:
+				formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC12x12UnormSRGB : GPUTextureFormat.ASTC12x12Unorm;
+				break;
 
 
-			}
+			default:
+				console.error( 'WebGPURenderer: Unsupported texture format.', format );
 
 
-		} else {
+		}
 
 
-			switch ( format ) {
+	} else {
 
 
-				case RGBAFormat:
+		switch ( format ) {
 
 
-					switch ( type ) {
+			case RGBAFormat:
 
 
-						case UnsignedByteType:
-							formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.RGBA8UnormSRGB : GPUTextureFormat.RGBA8Unorm;
-							break;
+				switch ( type ) {
 
 
-						case HalfFloatType:
-							formatGPU = GPUTextureFormat.RGBA16Float;
-							break;
+					case UnsignedByteType:
+						formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.RGBA8UnormSRGB : GPUTextureFormat.RGBA8Unorm;
+						break;
 
 
-						case FloatType:
-							formatGPU = GPUTextureFormat.RGBA32Float;
-							break;
+					case HalfFloatType:
+						formatGPU = GPUTextureFormat.RGBA16Float;
+						break;
 
 
-						default:
-							console.error( 'WebGPURenderer: Unsupported texture type with RGBAFormat.', type );
+					case FloatType:
+						formatGPU = GPUTextureFormat.RGBA32Float;
+						break;
 
 
-					}
+					default:
+						console.error( 'WebGPURenderer: Unsupported texture type with RGBAFormat.', type );
 
 
-					break;
+				}
 
 
-				case RedFormat:
+				break;
 
 
-					switch ( type ) {
+			case RedFormat:
 
 
-						case UnsignedByteType:
-							formatGPU = GPUTextureFormat.R8Unorm;
-							break;
+				switch ( type ) {
 
 
-						case HalfFloatType:
-							formatGPU = GPUTextureFormat.R16Float;
-							break;
+					case UnsignedByteType:
+						formatGPU = GPUTextureFormat.R8Unorm;
+						break;
 
 
-						case FloatType:
-							formatGPU = GPUTextureFormat.R32Float;
-							break;
+					case HalfFloatType:
+						formatGPU = GPUTextureFormat.R16Float;
+						break;
 
 
-						default:
-							console.error( 'WebGPURenderer: Unsupported texture type with RedFormat.', type );
+					case FloatType:
+						formatGPU = GPUTextureFormat.R32Float;
+						break;
 
 
-					}
+					default:
+						console.error( 'WebGPURenderer: Unsupported texture type with RedFormat.', type );
 
 
-					break;
+				}
 
 
-				case RGFormat:
+				break;
 
 
-					switch ( type ) {
+			case RGFormat:
 
 
-						case UnsignedByteType:
-							formatGPU = GPUTextureFormat.RG8Unorm;
-							break;
+				switch ( type ) {
 
 
-						case HalfFloatType:
-							formatGPU = GPUTextureFormat.RG16Float;
-							break;
+					case UnsignedByteType:
+						formatGPU = GPUTextureFormat.RG8Unorm;
+						break;
 
 
-						case FloatType:
-							formatGPU = GPUTextureFormat.RG32Float;
-							break;
+					case HalfFloatType:
+						formatGPU = GPUTextureFormat.RG16Float;
+						break;
 
 
-						default:
-							console.error( 'WebGPURenderer: Unsupported texture type with RGFormat.', type );
+					case FloatType:
+						formatGPU = GPUTextureFormat.RG32Float;
+						break;
 
 
-					}
+					default:
+						console.error( 'WebGPURenderer: Unsupported texture type with RGFormat.', type );
 
 
-					break;
+				}
 
 
-				case DepthFormat:
+				break;
 
 
-					switch ( type ) {
+			case DepthFormat:
 
 
-						case UnsignedShortType:
-							formatGPU = GPUTextureFormat.Depth16Unorm;
-							break;
+				switch ( type ) {
 
 
-						case UnsignedIntType:
-							formatGPU = GPUTextureFormat.Depth24Plus;
-							break;
+					case UnsignedShortType:
+						formatGPU = GPUTextureFormat.Depth16Unorm;
+						break;
 
 
-						case FloatType:
-							formatGPU = GPUTextureFormat.Depth32Float;
-							break;
+					case UnsignedIntType:
+						formatGPU = GPUTextureFormat.Depth24Plus;
+						break;
 
 
-						default:
-							console.error( 'WebGPURenderer: Unsupported texture type with DepthFormat.', type );
+					case FloatType:
+						formatGPU = GPUTextureFormat.Depth32Float;
+						break;
 
 
-					}
+					default:
+						console.error( 'WebGPURenderer: Unsupported texture type with DepthFormat.', type );
 
 
-					break;
+				}
 
 
-				case DepthStencilFormat:
+				break;
 
 
-					switch ( type ) {
+			case DepthStencilFormat:
 
 
-						case UnsignedInt248Type:
-							formatGPU = GPUTextureFormat.Depth24PlusStencil8;
-							break;
+				switch ( type ) {
 
 
-						case FloatType:
+					case UnsignedInt248Type:
+						formatGPU = GPUTextureFormat.Depth24PlusStencil8;
+						break;
 
 
-							if ( this.device.features.has( GPUFeatureName.Depth32FloatStencil8 ) === false ) {
+					case FloatType:
 
 
-								console.error( 'WebGPURenderer: Depth textures with DepthStencilFormat + FloatType can only be used with the "depth32float-stencil8" GPU feature.' );
+						if ( device && device.features.has( GPUFeatureName.Depth32FloatStencil8 ) === false ) {
 
 
-							}
+							console.error( 'WebGPURenderer: Depth textures with DepthStencilFormat + FloatType can only be used with the "depth32float-stencil8" GPU feature.' );
 
 
-							formatGPU = GPUTextureFormat.Depth32FloatStencil8;
+						}
 
 
-							break;
+						formatGPU = GPUTextureFormat.Depth32FloatStencil8;
 
 
-						default:
-							console.error( 'WebGPURenderer: Unsupported texture type with DepthStencilFormat.', type );
+						break;
 
 
-					}
+					default:
+						console.error( 'WebGPURenderer: Unsupported texture type with DepthStencilFormat.', type );
 
 
-					break;
+				}
 
 
-				default:
-					console.error( 'WebGPURenderer: Unsupported texture format.', format );
+				break;
 
 
-			}
+			default:
+				console.error( 'WebGPURenderer: Unsupported texture format.', format );
 
 
 		}
 		}
 
 
-		return formatGPU;
-
 	}
 	}
 
 
+	return formatGPU;
+
 }
 }
 
 
 export default WebGPUTextureUtils;
 export default WebGPUTextureUtils;

+ 50 - 14
examples/webgpu_compute_texture_pingpong.html

@@ -25,17 +25,18 @@
 		<script type="module">
 		<script type="module">
 
 
 			import * as THREE from 'three';
 			import * as THREE from 'three';
-			import { texture, textureStore, wgslFn, code, instanceIndex } from 'three/nodes';
+			import { texture, textureStore, wgslFn, code, instanceIndex, uniform } from 'three/nodes';
 
 
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
 			import StorageTexture from 'three/addons/renderers/common/StorageTexture.js';
 			import StorageTexture from 'three/addons/renderers/common/StorageTexture.js';
 
 
 			let camera, scene, renderer;
 			let camera, scene, renderer;
-			let computeToPing, computeToPong;
+			let computeInitNode, computeToPing, computeToPong;
 			let pingTexture, pongTexture;
 			let pingTexture, pongTexture;
 			let material;
 			let material;
 			let phase = true;
 			let phase = true;
+			let seed = uniform( new THREE.Vector2() );
 
 
 			init();
 			init();
 			render();
 			render();
@@ -58,11 +59,21 @@
 
 
 				// texture
 				// texture
 
 
+				const hdr = true;
 				const width = 512, height = 512;
 				const width = 512, height = 512;
 
 
 				pingTexture = new StorageTexture( width, height );
 				pingTexture = new StorageTexture( width, height );
 				pongTexture = new StorageTexture( width, height );
 				pongTexture = new StorageTexture( width, height );
 
 
+				if ( hdr ) {
+
+					pingTexture.type = THREE.HalfFloatType;
+					pongTexture.type = THREE.HalfFloatType;
+
+				}
+
+				const wgslFormat = hdr ? 'rgba16float' : 'rgba8unorm';
+
 				// compute init
 				// compute init
 
 
 				const rand2 = code( `
 				const rand2 = code( `
@@ -71,18 +82,18 @@
 						return fract( sin( dot( n, vec2f( 12.9898, 4.1414 ) ) ) * 43758.5453 );
 						return fract( sin( dot( n, vec2f( 12.9898, 4.1414 ) ) ) * 43758.5453 );
 
 
 					}
 					}
-				` );
 
 
-				const computeInitWGSL = wgslFn( `
-					fn computeInitWGSL( writeTex: texture_storage_2d<rgba8unorm, write>, index: u32 ) -> void {
+					fn blur( image : texture_2d<f32>, uv : vec2i ) -> vec4f {
 
 
-						let posX = index % ${ width };
-						let posY = index / ${ width };
-						let indexUV = vec2u( posX, posY );
-						let uv = getUV( posX, posY );
+						var color = vec4f( 0.0 );
 
 
-						textureStore( writeTex, indexUV, vec4f( vec3f( rand2( uv ) ), 1 ) );
+						color += textureLoad( image, uv + vec2i( - 1, 1 ), 0 );
+						color += textureLoad( image, uv + vec2i( - 1, - 1 ), 0 );
+						color += textureLoad( image, uv + vec2i( 0, 0 ), 0 );
+						color += textureLoad( image, uv + vec2i( 1, - 1 ), 0 );
+						color += textureLoad( image, uv + vec2i( 1, 1 ), 0 );
 
 
+						return color / 5.0; 
 					}
 					}
 
 
 					fn getUV( posX: u32, posY: u32 ) -> vec2f {
 					fn getUV( posX: u32, posY: u32 ) -> vec2f {
@@ -91,27 +102,42 @@
 
 
 						return uv;
 						return uv;
 
 
+					}
+				` );
+
+				const computeInitWGSL = wgslFn( `
+					fn computeInitWGSL( writeTex: texture_storage_2d<${ wgslFormat }, write>, index: u32, seed: vec2f ) -> void {
+
+						let posX = index % ${ width };
+						let posY = index / ${ width };
+						let indexUV = vec2u( posX, posY );
+						let uv = getUV( posX, posY );
+
+						textureStore( writeTex, indexUV, vec4f( vec3f( rand2( uv + seed ) ), 1 ) );
+
 					}
 					}
 				`, [ rand2 ] );
 				`, [ rand2 ] );
 
 
-				const computeInitNode = computeInitWGSL( { writeTex: textureStore( pingTexture ), index: instanceIndex } ).compute( width * height );
+				computeInitNode = computeInitWGSL( { writeTex: textureStore( pingTexture ), index: instanceIndex, seed } ).compute( width * height );
 
 
 				// compute loop
 				// compute loop
 
 
 				const computePingPongWGSL = wgslFn( `
 				const computePingPongWGSL = wgslFn( `
-					fn computePingPongWGSL( readTex: texture_2d<f32>, writeTex: texture_storage_2d<rgba8unorm, write>, index: u32 ) -> void {
+					fn computePingPongWGSL( readTex: texture_2d<f32>, writeTex: texture_storage_2d<${ wgslFormat }, write>, index: u32 ) -> void {
 
 
 						let posX = index % ${ width };
 						let posX = index % ${ width };
 						let posY = index / ${ width };
 						let posY = index / ${ width };
-						let indexUV = vec2u( posX, posY );
+						let indexUV = vec2i( i32( posX ), i32( posY ) );
 
 
-						let color = vec3f( rand2( textureLoad( readTex, indexUV, 0 ).xy ) );
+						let color = blur( readTex, indexUV ).rgb;
 
 
 						textureStore( writeTex, indexUV, vec4f( color, 1 ) );
 						textureStore( writeTex, indexUV, vec4f( color, 1 ) );
 
 
 					}
 					}
 				`, [ rand2 ] );
 				`, [ rand2 ] );
 
 
+				//
+
 				computeToPong = computePingPongWGSL( { readTex: texture( pingTexture ), writeTex: textureStore( pongTexture ), index: instanceIndex } ).compute( width * height );
 				computeToPong = computePingPongWGSL( { readTex: texture( pingTexture ), writeTex: textureStore( pongTexture ), index: instanceIndex } ).compute( width * height );
 				computeToPing = computePingPongWGSL( { readTex: texture( pongTexture ), writeTex: textureStore( pingTexture ), index: instanceIndex } ).compute( width * height );
 				computeToPing = computePingPongWGSL( { readTex: texture( pongTexture ), writeTex: textureStore( pingTexture ), index: instanceIndex } ).compute( width * height );
 
 
@@ -155,6 +181,16 @@
 
 
 			function render() {
 			function render() {
 
 
+				// reset every 50 frames
+
+				if ( renderer.info.render.frame % 50 === 0 ) {
+
+					seed.value.set( Math.random(), Math.random() );
+
+					renderer.compute( computeInitNode );
+
+				}
+
 				// compute step
 				// compute step
 
 
 				renderer.compute( phase ? computeToPong : computeToPing );
 				renderer.compute( phase ? computeToPong : computeToPing );