render lamp with per-node translation
This commit is contained in:
parent
48b3929cd4
commit
c60666e7a1
18
build.sh
18
build.sh
@ -14,6 +14,24 @@ clang++ \
|
|||||||
-o rotate.wasm \
|
-o rotate.wasm \
|
||||||
rotate.c
|
rotate.c
|
||||||
|
|
||||||
|
clang++ \
|
||||||
|
-v \
|
||||||
|
--target=wasm32 \
|
||||||
|
-O3 \
|
||||||
|
-flto \
|
||||||
|
-nostdlib \
|
||||||
|
-Wl,--no-entry \
|
||||||
|
-Wl,--export=mem_size \
|
||||||
|
-Wl,--export=mem_alloc \
|
||||||
|
-Wl,--export=node_alloc \
|
||||||
|
-Wl,--export=node_init_translation \
|
||||||
|
-Wl,--lto-O3 \
|
||||||
|
-Wl,--print-map \
|
||||||
|
-Wl,--import-memory \
|
||||||
|
-D_XM_NO_INTRINSICS_ \
|
||||||
|
-I. \
|
||||||
|
-o memory.wasm \
|
||||||
|
memory.cpp
|
||||||
|
|
||||||
# clang \
|
# clang \
|
||||||
# -O1 \
|
# -O1 \
|
||||||
|
|||||||
25
gltf.js
25
gltf.js
@ -7,6 +7,29 @@ function jsonChunk(buffer, offset, length)
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function splitGltf(jsonPath, binPath)
|
||||||
|
{
|
||||||
|
const jsonResponse = await fetch(jsonPath);
|
||||||
|
const jsonBuffer = await jsonResponse.arrayBuffer();
|
||||||
|
const json = jsonChunk(jsonBuffer, 0, jsonBuffer.byteLength);
|
||||||
|
|
||||||
|
const binResponse = await fetch(binPath);
|
||||||
|
const binBuffer = await binResponse.arrayBuffer();
|
||||||
|
return {
|
||||||
|
json: json,
|
||||||
|
bin: [{ buffer: binBuffer, offset: 0, length: binBuffer.byteLength }],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function transformMatrix()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildTransfomMatrices(json)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
function parseGltfChunks(buffer)
|
function parseGltfChunks(buffer)
|
||||||
{
|
{
|
||||||
const view = new DataView(buffer);
|
const view = new DataView(buffer);
|
||||||
@ -165,4 +188,4 @@ function vertexBufferLayouts(gltf, accessors)
|
|||||||
return layouts;
|
return layouts;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { parseGltfChunks, vertexBufferLayouts, primitiveAccessors };
|
export { parseGltfChunks, vertexBufferLayouts, primitiveAccessors, splitGltf };
|
||||||
|
|||||||
12
gltf.wgsl
12
gltf.wgsl
@ -4,11 +4,20 @@ struct Configuration {
|
|||||||
};
|
};
|
||||||
|
|
||||||
@group(0) @binding(0) var<uniform> config: Configuration;
|
@group(0) @binding(0) var<uniform> config: Configuration;
|
||||||
|
@group(0) @binding(1) var<storage> nodeMatrix: array<mat4x4f>;
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct Imm {
|
||||||
|
nodeIndex: i32,
|
||||||
|
};
|
||||||
|
var<immediate> imm: Imm;
|
||||||
|
*/
|
||||||
|
|
||||||
struct VertexInput {
|
struct VertexInput {
|
||||||
@location(0) position: vec3f,
|
@location(0) position: vec3f,
|
||||||
@location(1) normal: vec3f,
|
@location(1) normal: vec3f,
|
||||||
@location(2) texture: vec2f,
|
@location(2) texture: vec2f,
|
||||||
|
@builtin(instance_index) instance: u32,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertexOutput {
|
struct VertexOutput {
|
||||||
@ -25,7 +34,8 @@ struct FragmentInput {
|
|||||||
@vertex
|
@vertex
|
||||||
fn vertexMain(input: VertexInput) -> VertexOutput
|
fn vertexMain(input: VertexInput) -> VertexOutput
|
||||||
{
|
{
|
||||||
let position = vec4f(input.position, 1);
|
let position = nodeMatrix[input.instance] * vec4f(input.position, 1);
|
||||||
|
//let position = vec4f(input.position, 1);
|
||||||
let normal = vec4f(input.normal, 0.0f);
|
let normal = vec4f(input.normal, 0.0f);
|
||||||
var output: VertexOutput;
|
var output: VertexOutput;
|
||||||
output.position = config.matrix * position;
|
output.position = config.matrix * position;
|
||||||
|
|||||||
BIN
gltf/Image_0.png
Normal file
BIN
gltf/Image_0.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.3 MiB |
BIN
gltf/Image_1.png
Normal file
BIN
gltf/Image_1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 MiB |
BIN
gltf/Image_2.png
Normal file
BIN
gltf/Image_2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 MiB |
BIN
gltf/Image_3.png
Normal file
BIN
gltf/Image_3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 165 KiB |
BIN
gltf/lamp.bin
Normal file
BIN
gltf/lamp.bin
Normal file
Binary file not shown.
395
gltf/lamp.gltf
Normal file
395
gltf/lamp.gltf
Normal file
@ -0,0 +1,395 @@
|
|||||||
|
{
|
||||||
|
"asset":{
|
||||||
|
"generator":"Khronos glTF Blender I/O v5.2.39",
|
||||||
|
"version":"2.0"
|
||||||
|
},
|
||||||
|
"scene":0,
|
||||||
|
"scenes":[
|
||||||
|
{
|
||||||
|
"name":"Scene",
|
||||||
|
"nodes":[
|
||||||
|
3
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nodes":[
|
||||||
|
{
|
||||||
|
"mesh":0,
|
||||||
|
"name":"LanternPole_Body",
|
||||||
|
"translation":[
|
||||||
|
-3.8231542110443115,
|
||||||
|
13.016030311584473,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mesh":1,
|
||||||
|
"name":"LanternPole_Chain",
|
||||||
|
"translation":[
|
||||||
|
-9.582000732421875,
|
||||||
|
21.037872314453125,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mesh":2,
|
||||||
|
"name":"LanternPole_Lantern",
|
||||||
|
"translation":[
|
||||||
|
-9.58200740814209,
|
||||||
|
18.009151458740234,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"children":[
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
"name":"Lantern",
|
||||||
|
"rotation":[
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"materials":[
|
||||||
|
{
|
||||||
|
"emissiveFactor":[
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"emissiveTexture":{
|
||||||
|
"index":0
|
||||||
|
},
|
||||||
|
"name":"LanternPost_Mat",
|
||||||
|
"normalTexture":{
|
||||||
|
"index":1
|
||||||
|
},
|
||||||
|
"pbrMetallicRoughness":{
|
||||||
|
"baseColorTexture":{
|
||||||
|
"index":2
|
||||||
|
},
|
||||||
|
"metallicRoughnessTexture":{
|
||||||
|
"index":3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meshes":[
|
||||||
|
{
|
||||||
|
"name":"LanternPole_Body",
|
||||||
|
"primitives":[
|
||||||
|
{
|
||||||
|
"attributes":{
|
||||||
|
"POSITION":0,
|
||||||
|
"NORMAL":1,
|
||||||
|
"TEXCOORD_0":2,
|
||||||
|
"TANGENT":3
|
||||||
|
},
|
||||||
|
"indices":4,
|
||||||
|
"material":0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"LanternPole_Chain",
|
||||||
|
"primitives":[
|
||||||
|
{
|
||||||
|
"attributes":{
|
||||||
|
"POSITION":5,
|
||||||
|
"NORMAL":6,
|
||||||
|
"TEXCOORD_0":7,
|
||||||
|
"TANGENT":8
|
||||||
|
},
|
||||||
|
"indices":9,
|
||||||
|
"material":0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"LanternPole_Lantern",
|
||||||
|
"primitives":[
|
||||||
|
{
|
||||||
|
"attributes":{
|
||||||
|
"POSITION":10,
|
||||||
|
"NORMAL":11,
|
||||||
|
"TEXCOORD_0":12,
|
||||||
|
"TANGENT":13
|
||||||
|
},
|
||||||
|
"indices":14,
|
||||||
|
"material":0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"textures":[
|
||||||
|
{
|
||||||
|
"sampler":0,
|
||||||
|
"source":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sampler":0,
|
||||||
|
"source":1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sampler":0,
|
||||||
|
"source":2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sampler":0,
|
||||||
|
"source":3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"images":[
|
||||||
|
{
|
||||||
|
"mimeType":"image/png",
|
||||||
|
"name":"Image_3",
|
||||||
|
"uri":"Image_3.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mimeType":"image/png",
|
||||||
|
"name":"Image_2",
|
||||||
|
"uri":"Image_2.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mimeType":"image/png",
|
||||||
|
"name":"Image_0",
|
||||||
|
"uri":"Image_0.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mimeType":"image/png",
|
||||||
|
"name":"Image_1",
|
||||||
|
"uri":"Image_1.png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"accessors":[
|
||||||
|
{
|
||||||
|
"bufferView":0,
|
||||||
|
"componentType":5126,
|
||||||
|
"count":941,
|
||||||
|
"max":[
|
||||||
|
7.745599269866943,
|
||||||
|
12.832109451293945,
|
||||||
|
2.3157098293304443
|
||||||
|
],
|
||||||
|
"min":[
|
||||||
|
-7.745599269866943,
|
||||||
|
-12.832109451293945,
|
||||||
|
-2.3157098293304443
|
||||||
|
],
|
||||||
|
"type":"VEC3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView":1,
|
||||||
|
"componentType":5126,
|
||||||
|
"count":941,
|
||||||
|
"type":"VEC3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView":2,
|
||||||
|
"componentType":5126,
|
||||||
|
"count":941,
|
||||||
|
"type":"VEC2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView":3,
|
||||||
|
"componentType":5126,
|
||||||
|
"count":941,
|
||||||
|
"type":"VEC4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView":4,
|
||||||
|
"componentType":5123,
|
||||||
|
"count":2616,
|
||||||
|
"type":"SCALAR"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView":5,
|
||||||
|
"componentType":5126,
|
||||||
|
"count":756,
|
||||||
|
"max":[
|
||||||
|
0.12920807301998138,
|
||||||
|
0.6523504257202148,
|
||||||
|
0.12920807301998138
|
||||||
|
],
|
||||||
|
"min":[
|
||||||
|
-0.12920807301998138,
|
||||||
|
-0.6523504257202148,
|
||||||
|
-0.12920807301998138
|
||||||
|
],
|
||||||
|
"type":"VEC3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView":6,
|
||||||
|
"componentType":5126,
|
||||||
|
"count":756,
|
||||||
|
"type":"VEC3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView":7,
|
||||||
|
"componentType":5126,
|
||||||
|
"count":756,
|
||||||
|
"type":"VEC2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView":8,
|
||||||
|
"componentType":5126,
|
||||||
|
"count":756,
|
||||||
|
"type":"VEC4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView":9,
|
||||||
|
"componentType":5123,
|
||||||
|
"count":3744,
|
||||||
|
"type":"SCALAR"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView":10,
|
||||||
|
"componentType":5126,
|
||||||
|
"count":2543,
|
||||||
|
"max":[
|
||||||
|
1.034082293510437,
|
||||||
|
2.5292809009552,
|
||||||
|
1.034084677696228
|
||||||
|
],
|
||||||
|
"min":[
|
||||||
|
-1.034082293510437,
|
||||||
|
-2.5292809009552,
|
||||||
|
-1.034084677696228
|
||||||
|
],
|
||||||
|
"type":"VEC3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView":11,
|
||||||
|
"componentType":5126,
|
||||||
|
"count":2543,
|
||||||
|
"type":"VEC3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView":12,
|
||||||
|
"componentType":5126,
|
||||||
|
"count":2543,
|
||||||
|
"type":"VEC2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView":13,
|
||||||
|
"componentType":5126,
|
||||||
|
"count":2543,
|
||||||
|
"type":"VEC4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView":14,
|
||||||
|
"componentType":5123,
|
||||||
|
"count":9822,
|
||||||
|
"type":"SCALAR"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bufferViews":[
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":11292,
|
||||||
|
"byteOffset":0,
|
||||||
|
"target":34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":11292,
|
||||||
|
"byteOffset":11292,
|
||||||
|
"target":34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":7528,
|
||||||
|
"byteOffset":22584,
|
||||||
|
"target":34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":15056,
|
||||||
|
"byteOffset":30112,
|
||||||
|
"target":34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":5232,
|
||||||
|
"byteOffset":45168,
|
||||||
|
"target":34963
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":9072,
|
||||||
|
"byteOffset":50400,
|
||||||
|
"target":34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":9072,
|
||||||
|
"byteOffset":59472,
|
||||||
|
"target":34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":6048,
|
||||||
|
"byteOffset":68544,
|
||||||
|
"target":34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":12096,
|
||||||
|
"byteOffset":74592,
|
||||||
|
"target":34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":7488,
|
||||||
|
"byteOffset":86688,
|
||||||
|
"target":34963
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":30516,
|
||||||
|
"byteOffset":94176,
|
||||||
|
"target":34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":30516,
|
||||||
|
"byteOffset":124692,
|
||||||
|
"target":34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":20344,
|
||||||
|
"byteOffset":155208,
|
||||||
|
"target":34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":40688,
|
||||||
|
"byteOffset":175552,
|
||||||
|
"target":34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":19644,
|
||||||
|
"byteOffset":216240,
|
||||||
|
"target":34963
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"samplers":[
|
||||||
|
{
|
||||||
|
"magFilter":9729,
|
||||||
|
"minFilter":9987
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buffers":[
|
||||||
|
{
|
||||||
|
"byteLength":235884,
|
||||||
|
"uri":"lamp.bin"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
10
index.js
10
index.js
@ -256,6 +256,13 @@ const rotate = await WebAssembly.instantiateStreaming(fetch("rotate.wasm"), {
|
|||||||
env: { memory: memory }
|
env: { memory: memory }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const memory2 = new WebAssembly.Memory({ initial: 2 });
|
||||||
|
const mem = await WebAssembly.instantiateStreaming(fetch("memory.wasm"), {
|
||||||
|
env: { memory: memory2 }
|
||||||
|
});
|
||||||
|
console.log("mem");
|
||||||
|
document.mem = mem;
|
||||||
|
|
||||||
const uniformBuffer = device.createBuffer({
|
const uniformBuffer = device.createBuffer({
|
||||||
label: "grid uniform",
|
label: "grid uniform",
|
||||||
size: uniformArraySize,
|
size: uniformArraySize,
|
||||||
@ -432,7 +439,8 @@ function render()
|
|||||||
}
|
}
|
||||||
//requestAnimationFrame(render);
|
//requestAnimationFrame(render);
|
||||||
|
|
||||||
const gltfRenderer = await loadGltf(device, canvasFormat);
|
const gltfRenderer = await loadGltf(device, canvasFormat, memory2, mem);
|
||||||
|
|
||||||
function render2()
|
function render2()
|
||||||
{
|
{
|
||||||
recreateDepth();
|
recreateDepth();
|
||||||
|
|||||||
121
index2.js
121
index2.js
@ -1,5 +1,40 @@
|
|||||||
import { getPath } from "./common.js";
|
import { getPath } from "./common.js";
|
||||||
import { parseGltfChunks, vertexBufferLayouts, primitiveAccessors } from "./gltf.js";
|
import { parseGltfChunks, vertexBufferLayouts, primitiveAccessors, splitGltf } from "./gltf.js";
|
||||||
|
|
||||||
|
|
||||||
|
function loadGltfNode(mem, handle, gltf, nodeIndex)
|
||||||
|
{
|
||||||
|
const node = gltf.json.nodes[nodeIndex];
|
||||||
|
var translation = [0, 0, 0];
|
||||||
|
if ("translation" in node) {
|
||||||
|
translation = node.translation;
|
||||||
|
}
|
||||||
|
console.log("init", nodeIndex, translation);
|
||||||
|
mem.instance.exports.node_init_translation(handle, nodeIndex, translation[0], translation[1], translation[2]);
|
||||||
|
|
||||||
|
if ("children" in node) {
|
||||||
|
for (let childIndex in node.children) {
|
||||||
|
loadGltfNode(mem, handle, gltf, childIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadGltfNodes(mem, gltf)
|
||||||
|
{
|
||||||
|
const nodesHandle = mem.instance.exports.node_alloc(gltf.json.nodes.length);
|
||||||
|
for (let nodeIndex of gltf.json.scenes[0].nodes) {
|
||||||
|
loadGltfNode(mem, nodesHandle, gltf, nodeIndex);
|
||||||
|
}
|
||||||
|
return nodesHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
function printMatrix(m, o)
|
||||||
|
{
|
||||||
|
console.log(m[o+0], m[o+1], m[o+2], m[o+3]);
|
||||||
|
console.log(m[o+4], m[o+5], m[o+6], m[o+7]);
|
||||||
|
console.log(m[o+8], m[o+9], m[o+10], m[o+11]);
|
||||||
|
console.log(m[o+12], m[o+13], m[o+14], m[o+15]);
|
||||||
|
}
|
||||||
|
|
||||||
class GltfRenderer {
|
class GltfRenderer {
|
||||||
constructor(device, canvasFormat, shaderModule, gltf)
|
constructor(device, canvasFormat, shaderModule, gltf)
|
||||||
@ -12,9 +47,9 @@ class GltfRenderer {
|
|||||||
|
|
||||||
this.buffers = [];
|
this.buffers = [];
|
||||||
|
|
||||||
console.assert(gltf.json.buffers.length === gltf.bin.length);
|
//console.assert(gltf.json.buffers.length === gltf.bin.length);
|
||||||
for (let i = 0; i < gltf.bin.length; i++) {
|
for (let i = 0; i < gltf.bin.length; i++) {
|
||||||
console.assert(gltf.json.buffers[i].byteLength == gltf.bin[i].length);
|
//console.assert(gltf.json.buffers[i].byteLength == gltf.bin[i].length);
|
||||||
const buffer = device.createBuffer({
|
const buffer = device.createBuffer({
|
||||||
label: `gltf vertex buffer {i}`,
|
label: `gltf vertex buffer {i}`,
|
||||||
size: gltf.bin[i].length,
|
size: gltf.bin[i].length,
|
||||||
@ -36,6 +71,10 @@ class GltfRenderer {
|
|||||||
binding: 0,
|
binding: 0,
|
||||||
visibility: GPUShaderStage.VERTEX,
|
visibility: GPUShaderStage.VERTEX,
|
||||||
buffer: { type: "uniform" }
|
buffer: { type: "uniform" }
|
||||||
|
}, {
|
||||||
|
binding: 1,
|
||||||
|
visibility: GPUShaderStage.VERTEX,
|
||||||
|
buffer: { type: "read-only-storage" }
|
||||||
}]
|
}]
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
@ -98,13 +137,21 @@ class GltfRenderer {
|
|||||||
// bind group
|
// bind group
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
this.uniformBufferSize = (4 * 4 * 4) * 2;
|
const matrixSize = 4 * 4 * 4;
|
||||||
|
this.uniformBufferSize = matrixSize * 2;
|
||||||
this.uniformBuffer = device.createBuffer({
|
this.uniformBuffer = device.createBuffer({
|
||||||
label: "gltf uniform 0",
|
label: "gltf uniform 0",
|
||||||
size: this.uniformBufferSize,
|
size: this.uniformBufferSize,
|
||||||
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.nodeBufferSize = matrixSize * this.gltf.json.nodes.length;
|
||||||
|
this.nodeBuffer = device.createBuffer({
|
||||||
|
label: "gltf node buffer",
|
||||||
|
size: this.nodeBufferSize,
|
||||||
|
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
|
||||||
|
});
|
||||||
|
|
||||||
this.bindGroups = [
|
this.bindGroups = [
|
||||||
device.createBindGroup({
|
device.createBindGroup({
|
||||||
label: "cell bind group 0",
|
label: "cell bind group 0",
|
||||||
@ -112,12 +159,15 @@ class GltfRenderer {
|
|||||||
entries: [{
|
entries: [{
|
||||||
binding: 0,
|
binding: 0,
|
||||||
resource: { buffer: this.uniformBuffer },
|
resource: { buffer: this.uniformBuffer },
|
||||||
|
}, {
|
||||||
|
binding: 1,
|
||||||
|
resource: { buffer: this.nodeBuffer },
|
||||||
}]
|
}]
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPrimitive(renderPass, accessors, indices)
|
renderPrimitive(renderPass, accessors, indices, nodeIndex)
|
||||||
{
|
{
|
||||||
for (let i = 0; i < accessors.length; i++) {
|
for (let i = 0; i < accessors.length; i++) {
|
||||||
const accessor = accessors[i];
|
const accessor = accessors[i];
|
||||||
@ -135,7 +185,33 @@ class GltfRenderer {
|
|||||||
indicesBufferView.byteLength);
|
indicesBufferView.byteLength);
|
||||||
|
|
||||||
renderPass.setBindGroup(0, this.bindGroups[0]);
|
renderPass.setBindGroup(0, this.bindGroups[0]);
|
||||||
renderPass.drawIndexed(indicesAccessor.count);
|
//console.log("drawIndexed", nodeIndex);
|
||||||
|
renderPass.drawIndexed(indicesAccessor.count, 1, 0, 0, nodeIndex);
|
||||||
|
//renderPass.drawIndexed(indicesAccessor.count);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderNode(renderPass, lastKey, nodeIndex)
|
||||||
|
{
|
||||||
|
const node = this.gltf.json.nodes[nodeIndex];
|
||||||
|
|
||||||
|
if ("mesh" in node) {
|
||||||
|
const mesh = this.gltf.json.meshes[node.mesh];
|
||||||
|
for (let j = 0; j < mesh.primitives.length; j++) {
|
||||||
|
const [key, accessors] = this.meshes[node.mesh][j];
|
||||||
|
if (key !== lastKey)
|
||||||
|
renderPass.setPipeline(this.renderPipelines[key]);
|
||||||
|
lastKey = key;
|
||||||
|
const primitive = mesh.primitives[j];
|
||||||
|
this.renderPrimitive(renderPass, accessors, primitive.indices, nodeIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("children" in node) {
|
||||||
|
for (let childIndex of node.children) {
|
||||||
|
lastKey = this.renderNode(renderPass, lastKey, childIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lastKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
render(device, colorView, depthTexture)
|
render(device, colorView, depthTexture)
|
||||||
@ -157,17 +233,8 @@ class GltfRenderer {
|
|||||||
});
|
});
|
||||||
|
|
||||||
var lastKey = undefined;
|
var lastKey = undefined;
|
||||||
for (let i = 0; i < this.gltf.json.meshes.length; i++) {
|
for (let nodeIndex of this.gltf.json.scenes[0].nodes) {
|
||||||
const mesh = this.gltf.json.meshes[i];
|
lastKey = this.renderNode(renderPass, lastKey, nodeIndex);
|
||||||
for (let j = 0; j < mesh.primitives.length; j++) {
|
|
||||||
const [key, accessors] = this.meshes[i][j];
|
|
||||||
if (key !== lastKey)
|
|
||||||
renderPass.setPipeline(this.renderPipelines[key]);
|
|
||||||
lastKey = key;
|
|
||||||
|
|
||||||
const primitive = mesh.primitives[j];
|
|
||||||
this.renderPrimitive(renderPass, accessors, primitive.indices);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPass.end();
|
renderPass.end();
|
||||||
@ -177,12 +244,17 @@ class GltfRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadGltf(device, canvasFormat)
|
async function loadGltf(device, canvasFormat, memory, mem)
|
||||||
{
|
{
|
||||||
const response = await fetch("monkey.glb");
|
const gltf = await splitGltf("gltf/lamp.gltf", "gltf/lamp.bin");
|
||||||
const buffer = await response.arrayBuffer();
|
const nodesHandle = loadGltfNodes(mem, gltf);
|
||||||
const gltf = parseGltfChunks(buffer);
|
|
||||||
console.log(gltf);
|
const nodesM = new Float32Array(memory.buffer, nodesHandle);
|
||||||
|
for (let i = 0; i < gltf.json.nodes.length; i++) {
|
||||||
|
console.log("[", i, "]");
|
||||||
|
printMatrix(nodesM, i * 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const code = await getPath("gltf.wgsl");
|
const code = await getPath("gltf.wgsl");
|
||||||
const shaderModule = device.createShaderModule({
|
const shaderModule = device.createShaderModule({
|
||||||
@ -190,7 +262,10 @@ async function loadGltf(device, canvasFormat)
|
|||||||
code: await code,
|
code: await code,
|
||||||
});
|
});
|
||||||
|
|
||||||
const renderer = new GltfRenderer(device, canvasFormat, shaderModule, gltf);
|
const renderer = new GltfRenderer(device, canvasFormat, shaderModule, gltf, nodesHandle);
|
||||||
|
console.log(renderer.nodeBuffer);
|
||||||
|
device.queue.writeBuffer(renderer.nodeBuffer, 0,
|
||||||
|
memory.buffer, nodesHandle, (4 * 4 * 4) * gltf.json.nodes.length);
|
||||||
|
|
||||||
return renderer;
|
return renderer;
|
||||||
}
|
}
|
||||||
|
|||||||
71
memory.cpp
Normal file
71
memory.cpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "directxmath/directxmath.h"
|
||||||
|
|
||||||
|
//size_t __builtin_wasm_memory_grow(int, size_t);
|
||||||
|
//size_t __builtin_wasm_memory_size(int);
|
||||||
|
|
||||||
|
extern char __heap_base[];
|
||||||
|
extern char __heap_end[];
|
||||||
|
|
||||||
|
static size_t heap_pages = 0;
|
||||||
|
static size_t alloc_index = 0;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
size_t mem_size();
|
||||||
|
size_t mem_alloc(size_t length);
|
||||||
|
size_t node_alloc(int count);
|
||||||
|
|
||||||
|
void node_init_translation(size_t handle, int index, float x, float y, float z);
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline size_t memory_heap_base()
|
||||||
|
{
|
||||||
|
return (size_t)&__heap_base[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t align(size_t n, size_t m)
|
||||||
|
{
|
||||||
|
return (n + (m - 1)) & (~(m - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void memory_grow(size_t npages)
|
||||||
|
{
|
||||||
|
__builtin_wasm_memory_grow(0, npages);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t mem_size()
|
||||||
|
{
|
||||||
|
return __builtin_wasm_memory_size(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t mem_alloc(size_t length)
|
||||||
|
{
|
||||||
|
size_t base = memory_heap_base();
|
||||||
|
|
||||||
|
size_t heap_end = (heap_pages << 16);
|
||||||
|
|
||||||
|
size_t address = alloc_index;
|
||||||
|
|
||||||
|
alloc_index += align(length, 16);
|
||||||
|
|
||||||
|
if (heap_end < alloc_index) {
|
||||||
|
size_t npages = align(alloc_index - heap_end, 65536) >> 16;
|
||||||
|
memory_grow(npages);
|
||||||
|
heap_pages += npages;
|
||||||
|
}
|
||||||
|
return base + address;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t node_alloc(int count)
|
||||||
|
{
|
||||||
|
return mem_alloc((sizeof (XMFLOAT4X4)) * count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void node_init_translation(size_t handle, int index, float x, float y, float z)
|
||||||
|
{
|
||||||
|
XMFLOAT4X4 * nodes = reinterpret_cast<XMFLOAT4X4 *>(handle);
|
||||||
|
//XMMATRIX XMLoadFloat4x4(&nodes[index]);
|
||||||
|
XMMATRIX mat = XMMatrixTranslation(x, y, z);
|
||||||
|
XMStoreFloat4x4(&nodes[index], mat);
|
||||||
|
}
|
||||||
2
rotate.c
2
rotate.c
@ -9,7 +9,7 @@ void rotate(float angle, float aspect, float * buffer)
|
|||||||
//XMMATRIX mat2 = XMMatrixTranslation(0, 0, 1);
|
//XMMATRIX mat2 = XMMatrixTranslation(0, 0, 1);
|
||||||
//XMStoreFloat4x4((XMFLOAT4X4*)buffer, mat * mat2);
|
//XMStoreFloat4x4((XMFLOAT4X4*)buffer, mat * mat2);
|
||||||
|
|
||||||
float d = 1.9;
|
float d = 50.9;
|
||||||
XMVECTOR eye = XMVectorSet(d, d / 2, d, 0);
|
XMVECTOR eye = XMVectorSet(d, d / 2, d, 0);
|
||||||
XMVECTOR at = XMVectorSet(0, 0, 0, 0);
|
XMVECTOR at = XMVectorSet(0, 0, 0, 0);
|
||||||
XMVECTOR up = XMVectorSet(0, 1, 0, 0);
|
XMVECTOR up = XMVectorSet(0, 1, 0, 0);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user