Skip to content

Commit

Permalink
feat: add double precision matrix support
Browse files Browse the repository at this point in the history
  • Loading branch information
Codeboy-cn committed Sep 24, 2024
1 parent c542e1b commit 2cf0a03
Show file tree
Hide file tree
Showing 19 changed files with 138 additions and 86 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@orillusion/core",
"version": "0.8.3",
"version": "0.8.4-dev.1",
"author": "Orillusion",
"description": "Orillusion WebGPU Engine",
"type": "module",
Expand Down
61 changes: 32 additions & 29 deletions packages/wasm-matrix/WasmMatrix.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,32 @@
import { Matrix4 } from '../../src';
import matrixjs from './matrix?raw'
import { Engine3D, Matrix4 } from '../../src';
import matrix from './matrix';

export type FloatArray = Float32Array | Float64Array;

export function CreateFloatArray(buffer: ArrayBufferLike, byteOffset?: number, length?: number) {
if (Engine3D.setting.doublePrecision)
return new Float64Array(buffer, byteOffset, length);
return new Float32Array(buffer, byteOffset, length);
}

export class WasmMatrix {

public static matrixBuffer: Float32Array;
public static matrixSRTBuffer: Float32Array;
public static matrixContinuedSRTBuffer: Float32Array;
public static matrixBuffer: FloatArray;
public static matrixSRTBuffer: FloatArray;
public static matrixContinuedSRTBuffer: FloatArray;
public static matrixStateBuffer: Int32Array;
static matrixBufferPtr: number;
static matrixSRTBufferPtr: number;
static matrixContinuedSRTBufferPtr: number;
static matrixStateBufferPtr: number;
static wasm: any;
static wasm: typeof matrix;
static stateStruct: number = 4;
static useDoublePrecision: boolean = false;

public static async init(count: number) {
await new Promise((resolve)=>{
const script = document.createElement('script');
script.async = true;
script.type = "text/javascript";
script.src = URL.createObjectURL(new Blob([matrixjs]));
document.head.appendChild(script)
script.onload = () => {
let check = ()=>{
this.wasm = window['wasmMatrix'];
if (this.wasm && this.wasm['calledRun'])
resolve(true)
else
setTimeout(check, 20)
}
check()
}
})
// this.wasm = window['wasmMatrix'];
public static async init(count: number, useDoublePrecision: boolean = false) {
this.wasm = await matrix();
this.useDoublePrecision = useDoublePrecision;
this.wasm._initialize(count, useDoublePrecision, 0);
this.allocMatrix(count);
}

Expand All @@ -41,16 +35,25 @@ export class WasmMatrix {
console.error(`The maximum allocation size is exceeded! current:${count}, limit:${Matrix4.maxCount}`);
}

this.wasm._allocation(count);
this.wasm._allocMatrix(count);

this.matrixBufferPtr = this.wasm._getMatrixBufferPtr();
this.matrixSRTBufferPtr = this.wasm._getSRTPtr();
this.matrixStateBufferPtr = this.wasm._getInfoPtr();
this.matrixContinuedSRTBufferPtr = this.wasm._getContinuedSRTPtr();

this.matrixBuffer = new Float32Array(this.wasm.HEAPF32.buffer, this.matrixBufferPtr, 16 * count);
this.matrixSRTBuffer = new Float32Array(this.wasm.HEAPF32.buffer, this.matrixSRTBufferPtr, (3 * 3) * count);
this.matrixContinuedSRTBuffer = new Float32Array(this.wasm.HEAPF32.buffer, this.matrixContinuedSRTBufferPtr, (3 * 3) * count);
if (this.useDoublePrecision) {
this.matrixBuffer = CreateFloatArray(this.wasm.HEAPF64.buffer, this.matrixBufferPtr, 16 * count);
this.matrixSRTBuffer = CreateFloatArray(this.wasm.HEAPF64.buffer, this.matrixSRTBufferPtr, (3 * 3) * count);
this.matrixContinuedSRTBuffer = CreateFloatArray(this.wasm.HEAPF64.buffer, this.matrixContinuedSRTBufferPtr, (3 * 3) * count);
Matrix4.blockBytes = Matrix4.block * 8;
} else {
this.matrixBuffer = CreateFloatArray(this.wasm.HEAPF32.buffer, this.matrixBufferPtr, 16 * count);
this.matrixSRTBuffer = CreateFloatArray(this.wasm.HEAPF32.buffer, this.matrixSRTBufferPtr, (3 * 3) * count);
this.matrixContinuedSRTBuffer = CreateFloatArray(this.wasm.HEAPF32.buffer, this.matrixContinuedSRTBufferPtr, (3 * 3) * count);
Matrix4.blockBytes = Matrix4.block * 4;
}

this.matrixStateBuffer = new Int32Array(this.wasm.HEAP32.buffer, this.matrixStateBufferPtr, (WasmMatrix.stateStruct) * count);

Matrix4.allocMatrix(count);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@ declare module Module {
const HEAPF32: Float32Array;
const HEAPF64: Float64Array;

function _initialize(count: number);
function _initialize(count: number, useDoublePrecision: boolean, offset: number);

function _allocMatrix(count: number);

function _updateAllMatrixTransform(start: number, end: number);

function _updateAllMatrixContinueTransform(start: number, end: number);
function _updateAllMatrixContinueTransform(start: number, end: number, dt: number);

function _printMatrix(index: number);


function _getSRTPtr(): number;

function _getInfoPtr(): number;
Expand Down
18 changes: 13 additions & 5 deletions packages/wasm-matrix/matrix.js

Large diffs are not rendered by default.

Binary file removed packages/wasm-matrix/matrix.wasm
Binary file not shown.
1 change: 0 additions & 1 deletion packages/wasm-matrix/matrix.worker.js

This file was deleted.

8 changes: 4 additions & 4 deletions packages/wasm-matrix/package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "@orillusion/wasm-matrix",
"version": "0.7.0",
"version": "0.8.3",
"author": "Orillusion",
"description": "Orillusion WebGPU Engine",
"description": "Update matrix by WASM",
"main": "matrix.js",
"types": "_WasmMatrix4.d.ts",
"types": "matrix.d.ts",
"files": [
"matrix.js",
"_WasmMatrix4.d.ts"
"matrix.d.ts"
],
"license": "MIT",
"repository": {
Expand Down
2 changes: 2 additions & 0 deletions samples/base/Sample_MatrixAllocation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { GUIUtil } from '@samples/utils/GUIUtil';

class Sample_MatrixAllocation {
async run() {
Engine3D.setting.doublePrecision = true;

Matrix4.allocCount = 10;
Matrix4.allocOnceCount = 5;

Expand Down
7 changes: 3 additions & 4 deletions src/Engine3D.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import { InputSystem } from './io/InputSystem';
import { View3D } from './core/View3D';
import { version } from '../package.json';

import { GPUTextureFormat } from './gfx/graphics/webGpu/WebGPUConst';
import { webGPUContext } from './gfx/graphics/webGpu/Context3D';
import { RTResourceConfig } from './gfx/renderJob/config/RTResourceConfig';
import { RTResourceMap } from './gfx/renderJob/frame/RTResourceMap';

import { ForwardRenderJob } from './gfx/renderJob/jobs/ForwardRenderJob';
Expand All @@ -20,7 +18,6 @@ import { ShaderLib } from './assets/shader/ShaderLib';
import { ShaderUtil } from './gfx/graphics/webGpu/shader/util/ShaderUtil';
import { ComponentCollect } from './gfx/renderJob/collect/ComponentCollect';
import { ShadowLightsCollect } from './gfx/renderJob/collect/ShadowLightsCollect';
import { GUIConfig } from './components/gui/GUIConfig';
import { WasmMatrix } from '@orillusion/wasm-matrix/WasmMatrix';
import { Matrix4 } from './math/Matrix4';
import { FXAAPost } from './gfx/renderJob/post/FXAAPost';
Expand Down Expand Up @@ -109,6 +106,8 @@ export class Engine3D {
* engine setting
*/
public static setting: EngineSetting = {
doublePrecision: false,

occlusionQuery: {
enable: true,
debug: false,
Expand Down Expand Up @@ -325,7 +324,7 @@ export class Engine3D {

this.setting = { ...this.setting, ...descriptor.engineSetting }

await WasmMatrix.init(Matrix4.allocCount);
await WasmMatrix.init(Matrix4.allocCount, this.setting.doublePrecision);

await webGPUContext.init(descriptor.canvasConfig);

Expand Down
3 changes: 2 additions & 1 deletion src/components/anim/AnimatorComponent.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { FloatArray } from "@orillusion/wasm-matrix/WasmMatrix";
import { Engine3D, Matrix4, MeshRenderer, Object3D, PrefabAvatarData, Quaternion, RenderNode, RendererMask, RendererMaskUtil, SkinnedMeshRenderer2, StorageGPUBuffer, Time, Vector3, Vector4, View3D } from "../..";
import { PropertyAnimationClip } from "../../math/AnimationCurveClip";
import { RegisterComponent } from "../../util/SerializeDecoration";
Expand All @@ -8,7 +9,7 @@ export class AnimatorComponent extends ComponentBase {
public timeScale: number = 1.0;
public jointMatrixIndexTableBuffer: StorageGPUBuffer;
public playBlendShapeLoop: boolean = false;
protected inverseBindMatrices: Float32Array[];
protected inverseBindMatrices: FloatArray[];
protected _avatar: PrefabAvatarData;
protected _rendererList: SkinnedMeshRenderer2[];
protected propertyCache: Map<RenderNode, { [name: string]: any }>
Expand Down
2 changes: 1 addition & 1 deletion src/components/renderer/SkinnedMeshRenderer2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class SkinnedMeshRenderer2 extends MeshRenderer {
this.skinJointsName = value.skinNames;
let matrixList: Float32Array[] = [];
for (let i = 0; i < value.bindPose.length; i++) {
matrixList.push(value.bindPose[i].rawData.slice(0, 16));
matrixList.push(new Float32Array(value.bindPose[i].rawData.slice(0, 16)));
}
this.skinInverseBindMatrices = matrixList;
super.geometry = value;
Expand Down
14 changes: 14 additions & 0 deletions src/core/pool/memory/MemoryInfo.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { FloatArray } from '@orillusion/wasm-matrix/WasmMatrix';
import { Color } from '../../../math/Color';
import { Quaternion } from '../../../math/Quaternion';
import { Vector2 } from '../../../math/Vector2';
Expand Down Expand Up @@ -174,6 +175,19 @@ export class MemoryInfo {
tmp.set(data);
}

public setFloatArray(index: number, value: FloatArray) {
let data: Float32Array;
if (value instanceof Float32Array) {
data = value;
} else {
// GPU nonsupport f64
data = new Float32Array(value)
}

let tmp = new Float32Array(this.dataBytes.buffer, this.dataBytes.byteOffset + index * Float32Array.BYTES_PER_ELEMENT, data.length);
tmp.set(data);
}

public setArrayBuffer(index: number, arrayBuffer: ArrayBuffer) {
if (arrayBuffer instanceof Uint8Array) {
this.setUint8Array(index, arrayBuffer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export class GlobalUniformGroup {

createBindGroup() {
this.uniformByteLength = this.uniformGPUBuffer.memory.shareDataBuffer.byteLength;
this.matrixesByteLength = Matrix4.blockBytes * Matrix4.maxCount;
this.matrixesByteLength = (Matrix4.block * 4) * Matrix4.maxCount;

this.globalBindGroup = webGPUContext.device.createBindGroup({
label: `global_bindGroupLayout`,
Expand Down
18 changes: 15 additions & 3 deletions src/gfx/graphics/webGpu/core/buffer/GPUBufferBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Struct } from "../../../../../util/struct/Struct";
import { webGPUContext } from "../../Context3D";
import { MemoryDO } from "../../../../../core/pool/memory/MemoryDO";
import { MemoryInfo } from "../../../../../core/pool/memory/MemoryInfo";
import { FloatArray } from "@orillusion/wasm-matrix/WasmMatrix";

/**
* @internal
Expand Down Expand Up @@ -279,7 +280,8 @@ export class GPUBufferBase {
node = this.memory.allocation_node(16 * 4);
this.memoryNodes.set(name, node);
}
node.setFloat32Array(0, mat.rawData);

node.setFloatArray(0, mat.rawData);
}

public setMatrixArray(name: string, mats: Matrix4[]) {
Expand All @@ -290,7 +292,7 @@ export class GPUBufferBase {
}
for (let i = 0; i < mats.length; i++) {
const mat = mats[i];
node.setFloat32Array(i * 16, mat.rawData);
node.setFloatArray(i * 16, mat.rawData);
}
}

Expand Down Expand Up @@ -365,6 +367,10 @@ export class GPUBufferBase {
node.writeFloat32Array(value);
break;

case `Float64Array`:
node.writeFloat32Array(new Float32Array(value));
break;

case `Vector2`:
node.writeVector2(value);
break;
Expand Down Expand Up @@ -410,7 +416,13 @@ export class GPUBufferBase {
// this.applyMapAsync();
}

public mapAsyncWrite(mapAsyncArray: Float32Array, len: number) {
public mapAsyncWrite(floatArray: FloatArray, len: number) {
let mapAsyncArray: Float32Array;
if (floatArray instanceof Float64Array) {
mapAsyncArray = new Float32Array(floatArray);
} else {
mapAsyncArray = floatArray as Float32Array;
}
// Upload data using mapAsync and a queue of staging buffers.
let bytesLen = len;
let device = webGPUContext.device;
Expand Down
9 changes: 8 additions & 1 deletion src/gfx/graphics/webGpu/core/buffer/MatrixGPUBuffer.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { FloatArray } from '@orillusion/wasm-matrix/WasmMatrix';
import { webGPUContext } from '../../Context3D';
import { ArrayBufferData } from './ArrayBufferData';
import { GPUBufferBase } from './GPUBufferBase';
Expand All @@ -20,7 +21,13 @@ export class MatrixGPUBuffer extends GPUBufferBase {
this.createBuffer(GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | usage, size, data, "MatrixGPUBuffer");
}

public writeBufferByHeap(mapAsyncArray: Float32Array, len: number) {
public writeBufferByHeap(floatArray: FloatArray, len: number) {
let mapAsyncArray: Float32Array;
if (floatArray instanceof Float64Array) {
mapAsyncArray = new Float32Array(floatArray);
} else {
mapAsyncArray = floatArray as Float32Array;
}
// Upload data using mapAsync and a queue of staging buffers.
let bytesLen = len;
let device = webGPUContext.device;
Expand Down
2 changes: 1 addition & 1 deletion src/math/MathUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ export class MathUtil {
*/
public static transformVector(matrix: Matrix4, vector: Vector3, result: Vector3 = null): Vector3 {
result ||= new Vector3();
let raw: Float32Array = matrix.rawData;
let raw = matrix.rawData;
let a: number = raw[0];
let e: number = raw[1];
let i: number = raw[2];
Expand Down
Loading

0 comments on commit 2cf0a03

Please sign in to comment.