diff --git a/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js b/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js index aa60d4b484c852..8a29fe1731ed9b 100644 --- a/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +++ b/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js @@ -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', @@ -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; `; @@ -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; @@ -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; @@ -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 };`; } @@ -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`; @@ -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`; diff --git a/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js b/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js index 56674aa1097d14..de056566807d69 100644 --- a/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +++ b/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js @@ -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; } @@ -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; @@ -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; diff --git a/src/constants.js b/src/constants.js index c8cd5fe559ce35..0a3b5f0d4b4a37 100644 --- a/src/constants.js +++ b/src/constants.js @@ -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;