Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebGPURenderer: Int/Uint Support to StorageBufferNode in WebGLBackend #28606

Merged
merged 5 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 69 additions & 13 deletions examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import NodeUniformsGroup from '../../common/nodes/NodeUniformsGroup.js';

import { NodeSampledTexture, NodeSampledCubeTexture, NodeSampledTexture3D } from '../../common/nodes/NodeSampledTexture.js';

import { RedFormat, RGFormat, IntType, DataTexture, RGBFormat, RGBAFormat, FloatType } from 'three';
import { ByteType, ShortType, RGBAIntegerFormat, RGBIntegerFormat, RedIntegerFormat, RGIntegerFormat, UnsignedByteType, UnsignedIntType, UnsignedShortType, RedFormat, RGFormat, IntType, DataTexture, RGBFormat, RGBAFormat, FloatType } from 'three';

const glslMethods = {
[ MathNode.ATAN2 ]: 'atan',
Expand All @@ -27,8 +27,21 @@ const supports = {
const defaultPrecisions = `
precision highp float;
precision highp int;
precision highp sampler2D;
precision highp sampler3D;
precision mediump sampler2DArray;
precision highp samplerCube;
precision highp sampler2DArray;

precision highp usampler2D;
precision highp usampler3D;
precision highp usamplerCube;
precision highp usampler2DArray;

precision highp isampler2D;
precision highp isampler3D;
precision highp isamplerCube;
precision highp isampler2DArray;

precision lowp sampler2DShadow;
`;

Expand Down Expand Up @@ -101,35 +114,50 @@ ${ flowData.code }
const numElements = attribute.count * attribute.itemSize;

const { itemSize } = attribute;
let format = RedFormat;

const isInteger = attribute.array.constructor.name.toLowerCase().includes( 'int' );

let format = isInteger ? RedIntegerFormat : RedFormat;


if ( itemSize === 2 ) {

format = RGFormat;
format = isInteger ? RGIntegerFormat : RGFormat;

} else if ( itemSize === 3 ) {

format = RGBFormat;
format = isInteger ? RGBIntegerFormat : RGBFormat;

} else if ( itemSize === 4 ) {

format = RGBAFormat;
format = isInteger ? RGBAIntegerFormat : RGBAFormat;

}

const typeMap = {
Float32Array: FloatType,
Uint8Array: UnsignedByteType,
Uint16Array: UnsignedShortType,
Uint32Array: UnsignedIntType,
Int8Array: ByteType,
Int16Array: ShortType,
Int32Array: IntType,
Uint8ClampedArray: UnsignedByteType,
};

const width = Math.pow( 2, Math.ceil( Math.log2( Math.sqrt( numElements / itemSize ) ) ) );
let height = Math.ceil( ( numElements / itemSize ) / width );
if ( width * height * itemSize < numElements ) height ++; // Ensure enough space

const newSize = width * height * itemSize;

const newArray = new Float32Array( newSize );
const newArray = new originalArray.constructor( newSize );

newArray.set( originalArray, 0 );

attribute.array = newArray;

const pboTexture = new DataTexture( attribute.array, width, height, format, FloatType );
const pboTexture = new DataTexture( attribute.array, width, height, format, typeMap[ attribute.array.constructor.name ] || FloatType );
pboTexture.needsUpdate = true;
pboTexture.isPBOTexture = true;

Expand Down Expand Up @@ -205,7 +233,20 @@ ${ flowData.code }

//

this.addLineFlowCode( `${ propertyName } = ${ snippet + channel }` );
const typePrefix = attribute.array.constructor.name.toLowerCase().charAt( 0 );

let prefix = 'vec4';
if ( typePrefix === 'u' ) {

prefix = 'uvec4';

} else if ( typePrefix === 'i' ) {

prefix = 'ivec4';

}

this.addLineFlowCode( `${ propertyName } = ${prefix}(${ snippet })${channel}` );

elementNodeData.propertyName = propertyName;

Expand Down Expand Up @@ -303,21 +344,36 @@ ${ flowData.code }
let snippet = null;
let group = false;


if ( uniform.type === 'texture' ) {

const texture = uniform.node.value;

let typePrefix = '';

if ( texture.isPBOTexture === true ) {

const prefix = texture.source.data.data.constructor.name.toLowerCase().charAt( 0 );

if ( prefix === 'u' || prefix === 'i' ) {

typePrefix = prefix;

}

}

if ( texture.compareFunction ) {

snippet = `sampler2DShadow ${ uniform.name };`;

} else if ( texture.isDataArrayTexture === true ) {

snippet = `sampler2DArray ${ uniform.name };`;
snippet = `${typePrefix}sampler2DArray ${ uniform.name };`;

} else {

snippet = `sampler2D ${ uniform.name };`;
snippet = `${typePrefix}sampler2D ${ uniform.name };`;

}

Expand Down Expand Up @@ -492,7 +548,7 @@ ${ flowData.code }

if ( shaderStage === 'compute' ) varying.needsInterpolation = true;
const type = varying.type;
const flat = type === 'int' || type === 'uint' ? 'flat ' : '';
const flat = type.includes( 'int' ) || type.includes( 'uv' ) || type.includes( 'iv' ) ? 'flat ' : '';

snippet += `${flat}${varying.needsInterpolation ? 'out' : '/*out*/'} ${type} ${varying.name};\n`;

Expand All @@ -505,7 +561,7 @@ ${ flowData.code }
if ( varying.needsInterpolation ) {

const type = varying.type;
const flat = type === 'int' || type === 'uint' ? 'flat ' : '';
const flat = type.includes( 'int' ) || type.includes( 'uv' ) || type.includes( 'iv' ) ? 'flat ' : '';

snippet += `${flat}in ${type} ${varying.name};\n`;

Expand Down
32 changes: 32 additions & 0 deletions examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,16 @@ class WebGLTextureUtils {
if ( glType === gl.SHORT ) internalFormat = gl.RG16I;
if ( glType === gl.INT ) internalFormat = gl.RG32I;

}

if ( glFormat === gl.RG_INTEGER ) {

if ( glType === gl.UNSIGNED_BYTE ) internalFormat = gl.RG8UI;
if ( glType === gl.UNSIGNED_SHORT ) internalFormat = gl.RG16UI;
if ( glType === gl.UNSIGNED_INT ) internalFormat = gl.RG32UI;
if ( glType === gl.BYTE ) internalFormat = gl.RG8I;
if ( glType === gl.SHORT ) internalFormat = gl.RG16I;
if ( glType === gl.INT ) internalFormat = gl.RG32I;

}

Expand All @@ -168,6 +178,17 @@ class WebGLTextureUtils {

}

if ( glFormat === gl.RGB_INTEGER ) {

if ( glType === gl.UNSIGNED_BYTE ) internalFormat = gl.RGB8UI;
if ( glType === gl.UNSIGNED_SHORT ) internalFormat = gl.RGB16UI;
if ( glType === gl.UNSIGNED_INT ) internalFormat = gl.RGB32UI;
if ( glType === gl.BYTE ) internalFormat = gl.RGB8I;
if ( glType === gl.SHORT ) internalFormat = gl.RGB16I;
if ( glType === gl.INT ) internalFormat = gl.RGB32I;

}

if ( glFormat === gl.RGBA ) {

if ( glType === gl.FLOAT ) internalFormat = gl.RGBA32F;
Expand All @@ -184,6 +205,17 @@ class WebGLTextureUtils {

}

if ( glFormat === gl.RGBA_INTEGER ) {

if ( glType === gl.UNSIGNED_BYTE ) internalFormat = gl.RGBA8UI;
if ( glType === gl.UNSIGNED_SHORT ) internalFormat = gl.RGBA16UI;
if ( glType === gl.UNSIGNED_INT ) internalFormat = gl.RGBA32UI;
if ( glType === gl.BYTE ) internalFormat = gl.RGBA8I;
if ( glType === gl.SHORT ) internalFormat = gl.RGBA16I;
if ( glType === gl.INT ) internalFormat = gl.RGBA32I;

}

if ( glFormat === gl.DEPTH_COMPONENT ) {

if ( glType === gl.UNSIGNED_INT ) internalFormat = gl.DEPTH24_STENCIL8;
Expand Down
1 change: 1 addition & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export const RedFormat = 1028;
export const RedIntegerFormat = 1029;
export const RGFormat = 1030;
export const RGIntegerFormat = 1031;
export const RGBIntegerFormat = 1032;
export const RGBAIntegerFormat = 1033;

export const RGB_S3TC_DXT1_Format = 33776;
Expand Down