|
@@ -1,5 +1,6 @@
|
|
|
-import { GPUIndexFormat, GPUCompareFunction, GPUFrontFace, GPUCullMode, GPUVertexFormat, GPUBlendFactor, GPUBlendOperation, BlendColorFactor, OneMinusBlendColorFactor, GPUColorWriteFlags, GPUStencilOperation, GPUInputStepMode } from './constants.js';
|
|
|
+import { GPUIndexFormat, GPUCompareFunction, GPUFrontFace, GPUCullMode, GPUBlendFactor, GPUBlendOperation, BlendColorFactor, OneMinusBlendColorFactor, GPUColorWriteFlags, GPUStencilOperation, GPUInputStepMode } from './constants.js';
|
|
|
import {
|
|
|
+ Float16BufferAttribute,
|
|
|
FrontSide, BackSide, DoubleSide,
|
|
|
NeverDepth, AlwaysDepth, LessDepth, LessEqualDepth, EqualDepth, GreaterEqualDepth, GreaterDepth, NotEqualDepth,
|
|
|
NeverStencilFunc, AlwaysStencilFunc, LessStencilFunc, LessEqualStencilFunc, EqualStencilFunc, GreaterEqualStencilFunc, GreaterStencilFunc, NotEqualStencilFunc,
|
|
@@ -9,6 +10,26 @@ import {
|
|
|
ZeroFactor, OneFactor, SrcColorFactor, OneMinusSrcColorFactor, SrcAlphaFactor, OneMinusSrcAlphaFactor, DstAlphaFactor, OneMinusDstAlphaFactor, DstColorFactor, OneMinusDstColorFactor, SrcAlphaSaturateFactor
|
|
|
} from 'three';
|
|
|
|
|
|
+const typedArraysToVertexFormatPrefix = new Map( [
|
|
|
+ [ Int8Array, [ 'sint8', 'snorm8' ]],
|
|
|
+ [ Uint8Array, [ 'uint8', 'unorm8' ]],
|
|
|
+ [ Int16Array, [ 'sint16', 'snorm16' ]],
|
|
|
+ [ Uint16Array, [ 'uint16', 'unorm16' ]],
|
|
|
+ [ Int32Array, [ 'sint32', 'snorm32' ]],
|
|
|
+ [ Uint32Array, [ 'uint32', 'unorm32' ]],
|
|
|
+ [ Float32Array, [ 'float32', ]],
|
|
|
+] );
|
|
|
+
|
|
|
+const typedAttributeToVertexFormatPrefix = new Map( [
|
|
|
+ [ Float16BufferAttribute, [ 'float16', ]],
|
|
|
+] );
|
|
|
+
|
|
|
+const typeArraysToVertexFormatPrefixForItemSize1 = new Map( [
|
|
|
+ [ Int32Array, 'sint32' ],
|
|
|
+ [ Uint32Array, 'uint32' ],
|
|
|
+ [ Float32Array, 'float32' ]
|
|
|
+] );
|
|
|
+
|
|
|
class WebGPURenderPipeline {
|
|
|
|
|
|
constructor( device, utils ) {
|
|
@@ -561,127 +582,48 @@ class WebGPURenderPipeline {
|
|
|
|
|
|
}
|
|
|
|
|
|
- _getVertexFormat( type, bytesPerElement ) {
|
|
|
-
|
|
|
- // float
|
|
|
-
|
|
|
- if ( type === 'float' ) return GPUVertexFormat.Float32;
|
|
|
-
|
|
|
- if ( type === 'vec2' ) {
|
|
|
-
|
|
|
- if ( bytesPerElement === 2 ) {
|
|
|
-
|
|
|
- return GPUVertexFormat.Float16x2;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- return GPUVertexFormat.Float32x2;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( type === 'vec3' ) return GPUVertexFormat.Float32x3;
|
|
|
-
|
|
|
- if ( type === 'vec4' ) {
|
|
|
+ _getVertexFormat( geometryAttribute ) {
|
|
|
|
|
|
- if ( bytesPerElement === 2 ) {
|
|
|
+ const { itemSize, normalized } = geometryAttribute;
|
|
|
+ const ArrayType = geometryAttribute.array.constructor;
|
|
|
+ const AttributeType = geometryAttribute.constructor;
|
|
|
|
|
|
- return GPUVertexFormat.Float16x4;
|
|
|
+ let format;
|
|
|
|
|
|
- } else {
|
|
|
+ if ( itemSize == 1 ) {
|
|
|
|
|
|
- return GPUVertexFormat.Float32x4;
|
|
|
+ format = typeArraysToVertexFormatPrefixForItemSize1.get( ArrayType );
|
|
|
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // int
|
|
|
-
|
|
|
- if ( type === 'int' ) return GPUVertexFormat.Sint32;
|
|
|
-
|
|
|
- if ( type === 'ivec2' ) {
|
|
|
-
|
|
|
- if ( bytesPerElement === 1 ) {
|
|
|
-
|
|
|
- return GPUVertexFormat.Sint8x2;
|
|
|
-
|
|
|
- } else if ( bytesPerElement === 2 ) {
|
|
|
-
|
|
|
- return GPUVertexFormat.Sint16x2;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- return GPUVertexFormat.Sint32x2;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( type === 'ivec3' ) return GPUVertexFormat.Sint32x3;
|
|
|
-
|
|
|
- if ( type === 'ivec4' ) {
|
|
|
-
|
|
|
- if ( bytesPerElement === 1 ) {
|
|
|
-
|
|
|
- return GPUVertexFormat.Sint8x4;
|
|
|
-
|
|
|
- } else if ( bytesPerElement === 2 ) {
|
|
|
-
|
|
|
- return GPUVertexFormat.Sint16x4;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- return GPUVertexFormat.Sint32x4;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // uint
|
|
|
-
|
|
|
- if ( type === 'uint' ) return GPUVertexFormat.Uint32;
|
|
|
+ } else {
|
|
|
|
|
|
- if ( type === 'uvec2' ) {
|
|
|
+ const prefixOptions = typedAttributeToVertexFormatPrefix.get( AttributeType ) || typedArraysToVertexFormatPrefix.get( ArrayType );
|
|
|
+ const prefix = prefixOptions[ normalized ? 1 : 0 ];
|
|
|
|
|
|
- if ( bytesPerElement === 1 ) {
|
|
|
+ if ( prefix ) {
|
|
|
|
|
|
- return GPUVertexFormat.Uint8x2;
|
|
|
+ const bytesPerUnit = ArrayType.BYTES_PER_ELEMENT * itemSize;
|
|
|
+ const paddedBytesPerUnit = Math.floor( ( bytesPerUnit + 3 ) / 4 ) * 4;
|
|
|
+ const paddedItemSize = paddedBytesPerUnit / ArrayType.BYTES_PER_ELEMENT;
|
|
|
|
|
|
- } else if ( bytesPerElement === 2 ) {
|
|
|
+ if ( paddedItemSize % 1 ) {
|
|
|
|
|
|
- return GPUVertexFormat.Uint16x2;
|
|
|
+ throw new Error( 'THREE.WebGPURenderer: Bad vertex format item size.' );
|
|
|
|
|
|
- } else {
|
|
|
+ }
|
|
|
|
|
|
- return GPUVertexFormat.Uint32x2;
|
|
|
+ format = `${prefix}x${paddedItemSize}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
- if ( type === 'uvec3' ) return GPUVertexFormat.Uint32x3;
|
|
|
-
|
|
|
- if ( type === 'uvec4' ) {
|
|
|
-
|
|
|
- if ( bytesPerElement === 1 ) {
|
|
|
-
|
|
|
- return GPUVertexFormat.Uint8x4;
|
|
|
+ if ( ! format ) {
|
|
|
|
|
|
- } else if ( bytesPerElement === 2 ) {
|
|
|
-
|
|
|
- return GPUVertexFormat.Uint16x4;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- return GPUVertexFormat.Uint32x4;
|
|
|
-
|
|
|
- }
|
|
|
+ console.error( 'THREE.WebGPURenderer: Vertex format not supported yet.' );
|
|
|
|
|
|
}
|
|
|
|
|
|
- console.error( 'THREE.WebGPURenderer: Shader variable type not supported yet.', type );
|
|
|
+ return format;
|
|
|
|
|
|
}
|
|
|
|
|
@@ -693,14 +635,12 @@ class WebGPURenderPipeline {
|
|
|
for ( let slot = 0; slot < nodeAttributes.length; slot ++ ) {
|
|
|
|
|
|
const nodeAttribute = nodeAttributes[ slot ];
|
|
|
-
|
|
|
const name = nodeAttribute.name;
|
|
|
- const type = nodeAttribute.type;
|
|
|
|
|
|
const geometryAttribute = geometry.getAttribute( name );
|
|
|
const bytesPerElement = geometryAttribute.array.BYTES_PER_ELEMENT;
|
|
|
|
|
|
- const format = this._getVertexFormat( type, bytesPerElement );
|
|
|
+ const format = this._getVertexFormat( geometryAttribute );
|
|
|
|
|
|
let arrayStride = geometryAttribute.itemSize * bytesPerElement;
|
|
|
let offset = 0;
|