Skip to content

Commit 6a5d6de

Browse files
authoredSep 26, 2023
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()
1 parent 9fe5ed2 commit 6a5d6de

File tree

5 files changed

+219
-179
lines changed

5 files changed

+219
-179
lines changed
 

‎examples/jsm/nodes/utils/TimerNode.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,6 @@ export default TimerNode;
8989
export const timerLocal = ( timeScale, value = 0 ) => nodeObject( new TimerNode( TimerNode.LOCAL, timeScale, value ) );
9090
export const timerGlobal = ( timeScale, value = 0 ) => nodeObject( new TimerNode( TimerNode.GLOBAL, timeScale, value ) );
9191
export const timerDelta = ( timeScale, value = 0 ) => nodeObject( new TimerNode( TimerNode.DELTA, timeScale, value ) );
92-
export const frameId = nodeImmutable( TimerNode, TimerNode.FRAME );
92+
export const frameId = nodeImmutable( TimerNode, TimerNode.FRAME ).uint();
9393

9494
addNodeClass( TimerNode );

‎examples/jsm/renderers/common/Renderer.js

+11-10
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ class Renderer {
4646
this.depth = true;
4747
this.stencil = true;
4848

49+
this.info = new Info();
50+
4951
// internals
5052

5153
this._pixelRatio = 1;
@@ -56,7 +58,6 @@ class Renderer {
5658
this._scissor = new Vector4( 0, 0, this._width, this._height );
5759
this._scissorTest = false;
5860

59-
this._info = null;
6061
this._properties = null;
6162
this._attributes = null;
6263
this._geometries = null;
@@ -131,15 +132,14 @@ class Renderer {
131132

132133
}
133134

134-
this._info = new Info();
135135
this._nodes = new Nodes( this, backend );
136136
this._attributes = new Attributes( backend );
137137
this._background = new Background( this, this._nodes );
138-
this._geometries = new Geometries( this._attributes, this._info );
139-
this._textures = new Textures( backend, this._info );
138+
this._geometries = new Geometries( this._attributes, this.info );
139+
this._textures = new Textures( backend, this.info );
140140
this._pipelines = new Pipelines( backend, this._nodes );
141-
this._bindings = new Bindings( backend, this._nodes, this._textures, this._attributes, this._pipelines, this._info );
142-
this._objects = new RenderObjects( this, this._nodes, this._geometries, this._pipelines, this._bindings, this._info );
141+
this._bindings = new Bindings( backend, this._nodes, this._textures, this._attributes, this._pipelines, this.info );
142+
this._objects = new RenderObjects( this, this._nodes, this._geometries, this._pipelines, this._bindings, this.info );
143143
this._renderLists = new RenderLists();
144144
this._renderContexts = new RenderContexts();
145145

@@ -214,9 +214,9 @@ class Renderer {
214214

215215
if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
216216

217-
if ( this._info.autoReset === true ) this._info.reset();
217+
if ( this.info.autoReset === true ) this.info.reset();
218218

219-
this._info.render.frame ++;
219+
this.info.render.frame ++;
220220

221221
//
222222

@@ -612,12 +612,13 @@ class Renderer {
612612

613613
dispose() {
614614

615+
this.info.dispose();
616+
615617
this._objects.dispose();
616618
this._properties.dispose();
617619
this._pipelines.dispose();
618620
this._nodes.dispose();
619621
this._bindings.dispose();
620-
this._info.dispose();
621622
this._renderLists.dispose();
622623
this._renderContexts.dispose();
623624
this._textures.dispose();
@@ -921,7 +922,7 @@ class Renderer {
921922

922923
//
923924

924-
this.backend.draw( renderObject, this._info );
925+
this.backend.draw( renderObject, this.info );
925926

926927
}
927928

‎examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { getVectorLength, getStrideLength } from '../../common/BufferUtils.js';
1111

1212
import { NodeBuilder, CodeNode, NodeMaterial } from '../../../nodes/Nodes.js';
1313

14+
import { getFormat } from '../utils/WebGPUTextureUtils.js';
15+
1416
import WGSLNodeParser from './WGSLNodeParser.js';
1517

1618
const gpuShaderStageLib = {
@@ -659,8 +661,9 @@ class WGSLNodeBuilder extends NodeBuilder {
659661

660662
} else if ( uniform.node.isStoreTextureNode === true ) {
661663

662-
// @TODO: Add support for other formats
663-
textureType = 'texture_storage_2d<rgba8unorm, write>';
664+
const format = getFormat( texture );
665+
666+
textureType = 'texture_storage_2d<' + format + ', write>';
664667

665668
} else {
666669

‎examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js

+152-152
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ class WebGPUTextureUtils {
106106
const { width, height, depth, levels } = options;
107107

108108
const dimension = this._getDimension( texture );
109-
const format = texture.internalFormat || this._getFormat( texture );
109+
const format = texture.internalFormat || getFormat( texture, this.device );
110110

111111
const sampleCount = options.sampleCount !== undefined ? options.sampleCount : 1;
112112
const primarySampleCount = texture.isRenderTargetTexture ? 1 : sampleCount;
@@ -649,237 +649,237 @@ class WebGPUTextureUtils {
649649

650650
}
651651

652-
_getFormat( texture ) {
652+
}
653653

654-
const format = texture.format;
655-
const type = texture.type;
656-
const colorSpace = texture.colorSpace;
654+
export function getFormat( texture, device = null ) {
657655

658-
let formatGPU;
656+
const format = texture.format;
657+
const type = texture.type;
658+
const colorSpace = texture.colorSpace;
659659

660-
if ( /*texture.isRenderTargetTexture === true ||*/ texture.isFramebufferTexture === true ) {
660+
let formatGPU;
661661

662-
formatGPU = GPUTextureFormat.BGRA8Unorm;
662+
if ( /*texture.isRenderTargetTexture === true ||*/ texture.isFramebufferTexture === true ) {
663663

664-
} else if ( texture.isCompressedTexture === true ) {
664+
formatGPU = GPUTextureFormat.BGRA8Unorm;
665665

666-
switch ( format ) {
666+
} else if ( texture.isCompressedTexture === true ) {
667667

668-
case RGBA_S3TC_DXT1_Format:
669-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC1RGBAUnormSRGB : GPUTextureFormat.BC1RGBAUnorm;
670-
break;
668+
switch ( format ) {
671669

672-
case RGBA_S3TC_DXT3_Format:
673-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC2RGBAUnormSRGB : GPUTextureFormat.BC2RGBAUnorm;
674-
break;
670+
case RGBA_S3TC_DXT1_Format:
671+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC1RGBAUnormSRGB : GPUTextureFormat.BC1RGBAUnorm;
672+
break;
675673

676-
case RGBA_S3TC_DXT5_Format:
677-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC3RGBAUnormSRGB : GPUTextureFormat.BC3RGBAUnorm;
678-
break;
674+
case RGBA_S3TC_DXT3_Format:
675+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC2RGBAUnormSRGB : GPUTextureFormat.BC2RGBAUnorm;
676+
break;
679677

680-
case RGB_ETC2_Format:
681-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ETC2RGB8UnormSRGB : GPUTextureFormat.ETC2RGB8Unorm;
682-
break;
678+
case RGBA_S3TC_DXT5_Format:
679+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC3RGBAUnormSRGB : GPUTextureFormat.BC3RGBAUnorm;
680+
break;
683681

684-
case RGBA_ETC2_EAC_Format:
685-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ETC2RGBA8UnormSRGB : GPUTextureFormat.ETC2RGBA8Unorm;
686-
break;
682+
case RGB_ETC2_Format:
683+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ETC2RGB8UnormSRGB : GPUTextureFormat.ETC2RGB8Unorm;
684+
break;
687685

688-
case RGBA_ASTC_4x4_Format:
689-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC4x4UnormSRGB : GPUTextureFormat.ASTC4x4Unorm;
690-
break;
686+
case RGBA_ETC2_EAC_Format:
687+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ETC2RGBA8UnormSRGB : GPUTextureFormat.ETC2RGBA8Unorm;
688+
break;
691689

692-
case RGBA_ASTC_5x4_Format:
693-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC5x4UnormSRGB : GPUTextureFormat.ASTC5x4Unorm;
694-
break;
690+
case RGBA_ASTC_4x4_Format:
691+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC4x4UnormSRGB : GPUTextureFormat.ASTC4x4Unorm;
692+
break;
695693

696-
case RGBA_ASTC_5x5_Format:
697-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC5x5UnormSRGB : GPUTextureFormat.ASTC5x5Unorm;
698-
break;
694+
case RGBA_ASTC_5x4_Format:
695+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC5x4UnormSRGB : GPUTextureFormat.ASTC5x4Unorm;
696+
break;
699697

700-
case RGBA_ASTC_6x5_Format:
701-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC6x5UnormSRGB : GPUTextureFormat.ASTC6x5Unorm;
702-
break;
698+
case RGBA_ASTC_5x5_Format:
699+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC5x5UnormSRGB : GPUTextureFormat.ASTC5x5Unorm;
700+
break;
703701

704-
case RGBA_ASTC_6x6_Format:
705-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC6x6UnormSRGB : GPUTextureFormat.ASTC6x6Unorm;
706-
break;
702+
case RGBA_ASTC_6x5_Format:
703+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC6x5UnormSRGB : GPUTextureFormat.ASTC6x5Unorm;
704+
break;
707705

708-
case RGBA_ASTC_8x5_Format:
709-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x5UnormSRGB : GPUTextureFormat.ASTC8x5Unorm;
710-
break;
706+
case RGBA_ASTC_6x6_Format:
707+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC6x6UnormSRGB : GPUTextureFormat.ASTC6x6Unorm;
708+
break;
711709

712-
case RGBA_ASTC_8x6_Format:
713-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x6UnormSRGB : GPUTextureFormat.ASTC8x6Unorm;
714-
break;
710+
case RGBA_ASTC_8x5_Format:
711+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x5UnormSRGB : GPUTextureFormat.ASTC8x5Unorm;
712+
break;
715713

716-
case RGBA_ASTC_8x8_Format:
717-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x8UnormSRGB : GPUTextureFormat.ASTC8x8Unorm;
718-
break;
714+
case RGBA_ASTC_8x6_Format:
715+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x6UnormSRGB : GPUTextureFormat.ASTC8x6Unorm;
716+
break;
719717

720-
case RGBA_ASTC_10x5_Format:
721-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x5UnormSRGB : GPUTextureFormat.ASTC10x5Unorm;
722-
break;
718+
case RGBA_ASTC_8x8_Format:
719+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x8UnormSRGB : GPUTextureFormat.ASTC8x8Unorm;
720+
break;
723721

724-
case RGBA_ASTC_10x6_Format:
725-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x6UnormSRGB : GPUTextureFormat.ASTC10x6Unorm;
726-
break;
722+
case RGBA_ASTC_10x5_Format:
723+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x5UnormSRGB : GPUTextureFormat.ASTC10x5Unorm;
724+
break;
727725

728-
case RGBA_ASTC_10x8_Format:
729-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x8UnormSRGB : GPUTextureFormat.ASTC10x8Unorm;
730-
break;
726+
case RGBA_ASTC_10x6_Format:
727+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x6UnormSRGB : GPUTextureFormat.ASTC10x6Unorm;
728+
break;
731729

732-
case RGBA_ASTC_10x10_Format:
733-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x10UnormSRGB : GPUTextureFormat.ASTC10x10Unorm;
734-
break;
730+
case RGBA_ASTC_10x8_Format:
731+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x8UnormSRGB : GPUTextureFormat.ASTC10x8Unorm;
732+
break;
735733

736-
case RGBA_ASTC_12x10_Format:
737-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC12x10UnormSRGB : GPUTextureFormat.ASTC12x10Unorm;
738-
break;
734+
case RGBA_ASTC_10x10_Format:
735+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x10UnormSRGB : GPUTextureFormat.ASTC10x10Unorm;
736+
break;
739737

740-
case RGBA_ASTC_12x12_Format:
741-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC12x12UnormSRGB : GPUTextureFormat.ASTC12x12Unorm;
742-
break;
738+
case RGBA_ASTC_12x10_Format:
739+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC12x10UnormSRGB : GPUTextureFormat.ASTC12x10Unorm;
740+
break;
743741

744-
default:
745-
console.error( 'WebGPURenderer: Unsupported texture format.', format );
742+
case RGBA_ASTC_12x12_Format:
743+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC12x12UnormSRGB : GPUTextureFormat.ASTC12x12Unorm;
744+
break;
746745

747-
}
746+
default:
747+
console.error( 'WebGPURenderer: Unsupported texture format.', format );
748748

749-
} else {
749+
}
750750

751-
switch ( format ) {
751+
} else {
752752

753-
case RGBAFormat:
753+
switch ( format ) {
754754

755-
switch ( type ) {
755+
case RGBAFormat:
756756

757-
case UnsignedByteType:
758-
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.RGBA8UnormSRGB : GPUTextureFormat.RGBA8Unorm;
759-
break;
757+
switch ( type ) {
760758

761-
case HalfFloatType:
762-
formatGPU = GPUTextureFormat.RGBA16Float;
763-
break;
759+
case UnsignedByteType:
760+
formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.RGBA8UnormSRGB : GPUTextureFormat.RGBA8Unorm;
761+
break;
764762

765-
case FloatType:
766-
formatGPU = GPUTextureFormat.RGBA32Float;
767-
break;
763+
case HalfFloatType:
764+
formatGPU = GPUTextureFormat.RGBA16Float;
765+
break;
768766

769-
default:
770-
console.error( 'WebGPURenderer: Unsupported texture type with RGBAFormat.', type );
767+
case FloatType:
768+
formatGPU = GPUTextureFormat.RGBA32Float;
769+
break;
771770

772-
}
771+
default:
772+
console.error( 'WebGPURenderer: Unsupported texture type with RGBAFormat.', type );
773773

774-
break;
774+
}
775775

776-
case RedFormat:
776+
break;
777777

778-
switch ( type ) {
778+
case RedFormat:
779779

780-
case UnsignedByteType:
781-
formatGPU = GPUTextureFormat.R8Unorm;
782-
break;
780+
switch ( type ) {
783781

784-
case HalfFloatType:
785-
formatGPU = GPUTextureFormat.R16Float;
786-
break;
782+
case UnsignedByteType:
783+
formatGPU = GPUTextureFormat.R8Unorm;
784+
break;
787785

788-
case FloatType:
789-
formatGPU = GPUTextureFormat.R32Float;
790-
break;
786+
case HalfFloatType:
787+
formatGPU = GPUTextureFormat.R16Float;
788+
break;
791789

792-
default:
793-
console.error( 'WebGPURenderer: Unsupported texture type with RedFormat.', type );
790+
case FloatType:
791+
formatGPU = GPUTextureFormat.R32Float;
792+
break;
794793

795-
}
794+
default:
795+
console.error( 'WebGPURenderer: Unsupported texture type with RedFormat.', type );
796796

797-
break;
797+
}
798798

799-
case RGFormat:
799+
break;
800800

801-
switch ( type ) {
801+
case RGFormat:
802802

803-
case UnsignedByteType:
804-
formatGPU = GPUTextureFormat.RG8Unorm;
805-
break;
803+
switch ( type ) {
806804

807-
case HalfFloatType:
808-
formatGPU = GPUTextureFormat.RG16Float;
809-
break;
805+
case UnsignedByteType:
806+
formatGPU = GPUTextureFormat.RG8Unorm;
807+
break;
810808

811-
case FloatType:
812-
formatGPU = GPUTextureFormat.RG32Float;
813-
break;
809+
case HalfFloatType:
810+
formatGPU = GPUTextureFormat.RG16Float;
811+
break;
814812

815-
default:
816-
console.error( 'WebGPURenderer: Unsupported texture type with RGFormat.', type );
813+
case FloatType:
814+
formatGPU = GPUTextureFormat.RG32Float;
815+
break;
817816

818-
}
817+
default:
818+
console.error( 'WebGPURenderer: Unsupported texture type with RGFormat.', type );
819819

820-
break;
820+
}
821821

822-
case DepthFormat:
822+
break;
823823

824-
switch ( type ) {
824+
case DepthFormat:
825825

826-
case UnsignedShortType:
827-
formatGPU = GPUTextureFormat.Depth16Unorm;
828-
break;
826+
switch ( type ) {
829827

830-
case UnsignedIntType:
831-
formatGPU = GPUTextureFormat.Depth24Plus;
832-
break;
828+
case UnsignedShortType:
829+
formatGPU = GPUTextureFormat.Depth16Unorm;
830+
break;
833831

834-
case FloatType:
835-
formatGPU = GPUTextureFormat.Depth32Float;
836-
break;
832+
case UnsignedIntType:
833+
formatGPU = GPUTextureFormat.Depth24Plus;
834+
break;
837835

838-
default:
839-
console.error( 'WebGPURenderer: Unsupported texture type with DepthFormat.', type );
836+
case FloatType:
837+
formatGPU = GPUTextureFormat.Depth32Float;
838+
break;
840839

841-
}
840+
default:
841+
console.error( 'WebGPURenderer: Unsupported texture type with DepthFormat.', type );
842842

843-
break;
843+
}
844844

845-
case DepthStencilFormat:
845+
break;
846846

847-
switch ( type ) {
847+
case DepthStencilFormat:
848848

849-
case UnsignedInt248Type:
850-
formatGPU = GPUTextureFormat.Depth24PlusStencil8;
851-
break;
849+
switch ( type ) {
852850

853-
case FloatType:
851+
case UnsignedInt248Type:
852+
formatGPU = GPUTextureFormat.Depth24PlusStencil8;
853+
break;
854854

855-
if ( this.device.features.has( GPUFeatureName.Depth32FloatStencil8 ) === false ) {
855+
case FloatType:
856856

857-
console.error( 'WebGPURenderer: Depth textures with DepthStencilFormat + FloatType can only be used with the "depth32float-stencil8" GPU feature.' );
857+
if ( device && device.features.has( GPUFeatureName.Depth32FloatStencil8 ) === false ) {
858858

859-
}
859+
console.error( 'WebGPURenderer: Depth textures with DepthStencilFormat + FloatType can only be used with the "depth32float-stencil8" GPU feature.' );
860860

861-
formatGPU = GPUTextureFormat.Depth32FloatStencil8;
861+
}
862862

863-
break;
863+
formatGPU = GPUTextureFormat.Depth32FloatStencil8;
864864

865-
default:
866-
console.error( 'WebGPURenderer: Unsupported texture type with DepthStencilFormat.', type );
865+
break;
867866

868-
}
867+
default:
868+
console.error( 'WebGPURenderer: Unsupported texture type with DepthStencilFormat.', type );
869869

870-
break;
870+
}
871871

872-
default:
873-
console.error( 'WebGPURenderer: Unsupported texture format.', format );
872+
break;
874873

875-
}
874+
default:
875+
console.error( 'WebGPURenderer: Unsupported texture format.', format );
876876

877877
}
878878

879-
return formatGPU;
880-
881879
}
882880

881+
return formatGPU;
882+
883883
}
884884

885885
export default WebGPUTextureUtils;

‎examples/webgpu_compute_texture_pingpong.html

+50-14
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,18 @@
2525
<script type="module">
2626

2727
import * as THREE from 'three';
28-
import { texture, textureStore, wgslFn, code, instanceIndex } from 'three/nodes';
28+
import { texture, textureStore, wgslFn, code, instanceIndex, uniform } from 'three/nodes';
2929

3030
import WebGPU from 'three/addons/capabilities/WebGPU.js';
3131
import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
3232
import StorageTexture from 'three/addons/renderers/common/StorageTexture.js';
3333

3434
let camera, scene, renderer;
35-
let computeToPing, computeToPong;
35+
let computeInitNode, computeToPing, computeToPong;
3636
let pingTexture, pongTexture;
3737
let material;
3838
let phase = true;
39+
let seed = uniform( new THREE.Vector2() );
3940

4041
init();
4142
render();
@@ -58,11 +59,21 @@
5859

5960
// texture
6061

62+
const hdr = true;
6163
const width = 512, height = 512;
6264

6365
pingTexture = new StorageTexture( width, height );
6466
pongTexture = new StorageTexture( width, height );
6567

68+
if ( hdr ) {
69+
70+
pingTexture.type = THREE.HalfFloatType;
71+
pongTexture.type = THREE.HalfFloatType;
72+
73+
}
74+
75+
const wgslFormat = hdr ? 'rgba16float' : 'rgba8unorm';
76+
6677
// compute init
6778

6879
const rand2 = code( `
@@ -71,18 +82,18 @@
7182
return fract( sin( dot( n, vec2f( 12.9898, 4.1414 ) ) ) * 43758.5453 );
7283
7384
}
74-
` );
7585
76-
const computeInitWGSL = wgslFn( `
77-
fn computeInitWGSL( writeTex: texture_storage_2d<rgba8unorm, write>, index: u32 ) -> void {
86+
fn blur( image : texture_2d<f32>, uv : vec2i ) -> vec4f {
7887
79-
let posX = index % ${ width };
80-
let posY = index / ${ width };
81-
let indexUV = vec2u( posX, posY );
82-
let uv = getUV( posX, posY );
88+
var color = vec4f( 0.0 );
8389
84-
textureStore( writeTex, indexUV, vec4f( vec3f( rand2( uv ) ), 1 ) );
90+
color += textureLoad( image, uv + vec2i( - 1, 1 ), 0 );
91+
color += textureLoad( image, uv + vec2i( - 1, - 1 ), 0 );
92+
color += textureLoad( image, uv + vec2i( 0, 0 ), 0 );
93+
color += textureLoad( image, uv + vec2i( 1, - 1 ), 0 );
94+
color += textureLoad( image, uv + vec2i( 1, 1 ), 0 );
8595
96+
return color / 5.0;
8697
}
8798
8899
fn getUV( posX: u32, posY: u32 ) -> vec2f {
@@ -91,27 +102,42 @@
91102
92103
return uv;
93104
105+
}
106+
` );
107+
108+
const computeInitWGSL = wgslFn( `
109+
fn computeInitWGSL( writeTex: texture_storage_2d<${ wgslFormat }, write>, index: u32, seed: vec2f ) -> void {
110+
111+
let posX = index % ${ width };
112+
let posY = index / ${ width };
113+
let indexUV = vec2u( posX, posY );
114+
let uv = getUV( posX, posY );
115+
116+
textureStore( writeTex, indexUV, vec4f( vec3f( rand2( uv + seed ) ), 1 ) );
117+
94118
}
95119
`, [ rand2 ] );
96120

97-
const computeInitNode = computeInitWGSL( { writeTex: textureStore( pingTexture ), index: instanceIndex } ).compute( width * height );
121+
computeInitNode = computeInitWGSL( { writeTex: textureStore( pingTexture ), index: instanceIndex, seed } ).compute( width * height );
98122

99123
// compute loop
100124

101125
const computePingPongWGSL = wgslFn( `
102-
fn computePingPongWGSL( readTex: texture_2d<f32>, writeTex: texture_storage_2d<rgba8unorm, write>, index: u32 ) -> void {
126+
fn computePingPongWGSL( readTex: texture_2d<f32>, writeTex: texture_storage_2d<${ wgslFormat }, write>, index: u32 ) -> void {
103127
104128
let posX = index % ${ width };
105129
let posY = index / ${ width };
106-
let indexUV = vec2u( posX, posY );
130+
let indexUV = vec2i( i32( posX ), i32( posY ) );
107131
108-
let color = vec3f( rand2( textureLoad( readTex, indexUV, 0 ).xy ) );
132+
let color = blur( readTex, indexUV ).rgb;
109133
110134
textureStore( writeTex, indexUV, vec4f( color, 1 ) );
111135
112136
}
113137
`, [ rand2 ] );
114138

139+
//
140+
115141
computeToPong = computePingPongWGSL( { readTex: texture( pingTexture ), writeTex: textureStore( pongTexture ), index: instanceIndex } ).compute( width * height );
116142
computeToPing = computePingPongWGSL( { readTex: texture( pongTexture ), writeTex: textureStore( pingTexture ), index: instanceIndex } ).compute( width * height );
117143

@@ -155,6 +181,16 @@
155181

156182
function render() {
157183

184+
// reset every 50 frames
185+
186+
if ( renderer.info.render.frame % 50 === 0 ) {
187+
188+
seed.value.set( Math.random(), Math.random() );
189+
190+
renderer.compute( computeInitNode );
191+
192+
}
193+
158194
// compute step
159195

160196
renderer.compute( phase ? computeToPong : computeToPing );

0 commit comments

Comments
 (0)
Please sign in to comment.