Skip to content

Commit

Permalink
WebGPURenderer: Improve support int/uint textures (#27932)
Browse files Browse the repository at this point in the history
  • Loading branch information
sunag committed Mar 18, 2024
1 parent b0a6ea1 commit e6ec298
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 36 deletions.
21 changes: 7 additions & 14 deletions examples/jsm/nodes/core/NodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
ColorNodeUniform, Matrix3NodeUniform, Matrix4NodeUniform
} from '../../renderers/common/nodes/NodeUniform.js';

import { REVISION, RenderTarget, NoColorSpace, Color, Vector2, Vector3, Vector4, Float16BufferAttribute } from 'three';
import { REVISION, RenderTarget, Color, Vector2, Vector3, Vector4, IntType, UnsignedIntType, Float16BufferAttribute } from 'three';

import { stack } from './StackNode.js';
import { getCurrentStack, setCurrentStack } from '../shadernode/ShaderNode.js';
Expand Down Expand Up @@ -484,25 +484,18 @@ class NodeBuilder {

}

getTextureColorSpaceFromMap( map ) {
getComponentTypeFromTexture( texture ) {

let colorSpace;
const type = texture.type;

if ( map && map.isTexture ) {
if ( texture.isDataTexture ) {

colorSpace = map.colorSpace;

} else if ( map && map.isWebGLRenderTarget ) {

colorSpace = map.texture.colorSpace;

} else {

colorSpace = NoColorSpace;
if ( type === IntType ) return 'int';
if ( type === UnsignedIntType ) return 'uint';

}

return colorSpace;
return 'float';

}

Expand Down
8 changes: 5 additions & 3 deletions examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ class WGSLNodeBuilder extends NodeBuilder {

isUnfilterable( texture ) {

return texture.isDataTexture === true && texture.type === FloatType;
return this.getComponentTypeFromTexture( texture ) !== 'float' || ( texture.isDataTexture === true && texture.type === FloatType );

}

Expand Down Expand Up @@ -759,11 +759,13 @@ ${ flowData.code }

const format = getFormat( texture );

textureType = 'texture_storage_2d<' + format + ', write>';
textureType = `texture_storage_2d<${ format }, write>`;

} else {

textureType = 'texture_2d<f32>';
const componentPrefix = this.getComponentTypeFromTexture( texture ).charAt( 0 );

textureType = `texture_2d<${ componentPrefix }32>`;

}

Expand Down
22 changes: 18 additions & 4 deletions examples/jsm/renderers/webgpu/utils/WebGPUBindingUtils.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
GPUTextureAspect, GPUTextureViewDimension, GPUBufferBindingType, GPUTextureSampleType
} from './WebGPUConstants.js';
import { FloatType } from 'three';
import { FloatType, IntType, UnsignedIntType } from 'three';

class WebGPUBindingUtils {

Expand Down Expand Up @@ -73,11 +73,25 @@ class WebGPUBindingUtils {

texture.sampleType = GPUTextureSampleType.Depth;

} else if ( binding.texture.isDataTexture && binding.texture.type === FloatType ) {
} else if ( binding.texture.isDataTexture ) {

// @TODO: Add support for this soon: backend.hasFeature( 'float32-filterable' )
const type = binding.texture.type;

texture.sampleType = GPUTextureSampleType.UnfilterableFloat;
if ( type === IntType ) {

texture.sampleType = GPUTextureSampleType.SInt;

} else if ( type === UnsignedIntType ) {

texture.sampleType = GPUTextureSampleType.UInt;

} else if ( type === FloatType ) {

// @TODO: Add support for this soon: backend.hasFeature( 'float32-filterable' )

texture.sampleType = GPUTextureSampleType.UnfilterableFloat;

}

}

Expand Down
89 changes: 74 additions & 15 deletions examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
RGBAFormat, RedFormat, RGFormat, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, UnsignedByteType, FloatType, HalfFloatType, SRGBColorSpace, DepthFormat, DepthStencilFormat,
RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_ASTC_10x5_Format,
RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_10x10_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, UnsignedIntType, UnsignedShortType, UnsignedInt248Type,
NeverCompare, AlwaysCompare, LessCompare, LessEqualCompare, EqualCompare, GreaterEqualCompare, GreaterCompare, NotEqualCompare
NeverCompare, AlwaysCompare, LessCompare, LessEqualCompare, EqualCompare, GreaterEqualCompare, GreaterCompare, NotEqualCompare, IntType, RedIntegerFormat, RGIntegerFormat, RGBAIntegerFormat
} from 'three';

import { CubeReflectionMapping, CubeRefractionMapping, EquirectangularReflectionMapping, EquirectangularRefractionMapping, DepthTexture } from 'three';
Expand Down Expand Up @@ -38,8 +38,8 @@ class WebGPUTextureUtils {

this._passUtils = null;

this.defaultTexture = null;
this.defaultCubeTexture = null;
this.defaultTexture = {};
this.defaultCubeTexture = {};

this.colorBuffer = null;

Expand Down Expand Up @@ -79,13 +79,15 @@ class WebGPUTextureUtils {

let textureGPU;

const format = getFormat( texture );

if ( texture.isCubeTexture ) {

textureGPU = this._getDefaultCubeTextureGPU();
textureGPU = this._getDefaultCubeTextureGPU( format );

} else {

textureGPU = this._getDefaultTextureGPU();
textureGPU = this._getDefaultTextureGPU( format );

}

Expand All @@ -111,7 +113,7 @@ class WebGPUTextureUtils {
const { width, height, depth, levels } = options;

const dimension = this._getDimension( texture );
const format = texture.internalFormat || getFormat( texture, backend.device );
const format = texture.internalFormat || options.format || getFormat( texture, backend.device );

let sampleCount = options.sampleCount !== undefined ? options.sampleCount : 1;

Expand Down Expand Up @@ -422,39 +424,39 @@ class WebGPUTextureUtils {

}

_getDefaultTextureGPU() {
_getDefaultTextureGPU( format ) {

let defaultTexture = this.defaultTexture;
let defaultTexture = this.defaultTexture[ format ];

if ( defaultTexture === null ) {
if ( defaultTexture === undefined ) {

const texture = new Texture();
texture.minFilter = NearestFilter;
texture.magFilter = NearestFilter;

this.createTexture( texture, { width: 1, height: 1 } );
this.createTexture( texture, { width: 1, height: 1, format } );

this.defaultTexture = defaultTexture = texture;
this.defaultTexture[ format ] = defaultTexture = texture;

}

return this.backend.get( defaultTexture ).texture;

}

_getDefaultCubeTextureGPU() {
_getDefaultCubeTextureGPU( format ) {

let defaultCubeTexture = this.defaultTexture;
let defaultCubeTexture = this.defaultTexture[ format ];

if ( defaultCubeTexture === null ) {
if ( defaultCubeTexture === undefined ) {

const texture = new CubeTexture();
texture.minFilter = NearestFilter;
texture.magFilter = NearestFilter;

this.createTexture( texture, { width: 1, height: 1, depth: 6 } );

this.defaultCubeTexture = defaultCubeTexture = texture;
this.defaultCubeTexture[ format ] = defaultCubeTexture = texture;

}

Expand Down Expand Up @@ -1026,6 +1028,63 @@ export function getFormat( texture, device = null ) {

break;

case RedIntegerFormat:

switch ( type ) {

case IntType:
formatGPU = GPUTextureFormat.R32Sint;
break;

case UnsignedIntType:
formatGPU = GPUTextureFormat.R32Uint;
break;

default:
console.error( 'WebGPURenderer: Unsupported texture type with RedIntegerFormat.', type );

}

break;

case RGIntegerFormat:

switch ( type ) {

case IntType:
formatGPU = GPUTextureFormat.RG32Sint;
break;

case UnsignedIntType:
formatGPU = GPUTextureFormat.RG32Uint;
break;

default:
console.error( 'WebGPURenderer: Unsupported texture type with RGIntegerFormat.', type );

}

break;

case RGBAIntegerFormat:

switch ( type ) {

case IntType:
formatGPU = GPUTextureFormat.RGBA32Sint;
break;

case UnsignedIntType:
formatGPU = GPUTextureFormat.RGBA32Uint;
break;

default:
console.error( 'WebGPURenderer: Unsupported texture type with RGBAIntegerFormat.', type );

}

break;

default:
console.error( 'WebGPURenderer: Unsupported texture format.', format );

Expand Down

0 comments on commit e6ec298

Please sign in to comment.