Fixes
This commit is contained in:
parent
69e2be5778
commit
4f20212a07
3
bun.lock
3
bun.lock
|
|
@ -5,6 +5,7 @@
|
||||||
"name": "stars",
|
"name": "stars",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@webgpu/types": "^0.1.64",
|
"@webgpu/types": "^0.1.64",
|
||||||
|
"lil-gui": "^0.20.0",
|
||||||
"stats.ts": "^1.1.0",
|
"stats.ts": "^1.1.0",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
@ -28,6 +29,8 @@
|
||||||
|
|
||||||
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||||
|
|
||||||
|
"lil-gui": ["lil-gui@0.20.0", "", {}, "sha512-k7Ipr0ztqslMA2XvM5z5ZaWhxQtnEOwJBfI/hmSuRh6q4iMG9L0boqqrnZSzBR1jzyJ28OMl47l65ILzRe1TdA=="],
|
||||||
|
|
||||||
"stats.ts": ["stats.ts@1.1.0", "", {}, "sha512-mokWb6xGU0elmDlUT6Y5E4zsUs/Enlq5fpyE7pfffpJg9Lg83GlL7B9zHEPA0eDvDC3Ko0ZZ50cjIN8yYJRPoQ=="],
|
"stats.ts": ["stats.ts@1.1.0", "", {}, "sha512-mokWb6xGU0elmDlUT6Y5E4zsUs/Enlq5fpyE7pfffpJg9Lg83GlL7B9zHEPA0eDvDC3Ko0ZZ50cjIN8yYJRPoQ=="],
|
||||||
|
|
||||||
"typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="],
|
"typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="],
|
||||||
|
|
|
||||||
957011
data/stars.json
957011
data/stars.json
File diff suppressed because one or more lines are too long
236
main.ts
236
main.ts
|
|
@ -1,35 +1,45 @@
|
||||||
import untypedStars from './data/stars.json';
|
import untypedStars from './data/stars.json';
|
||||||
import untypedConstellations from './data/constellations.json';
|
import untypedConstellations from './data/constellations.json';
|
||||||
import { Stats } from 'stats.ts';
|
import { Stats } from 'stats.ts';
|
||||||
|
import GUI from 'lil-gui';
|
||||||
|
|
||||||
const shaderCode = `
|
const shaderCode = `
|
||||||
struct VertexOut {
|
struct VertexOut {
|
||||||
@builtin(position) position: vec4f,
|
@builtin(position) position: vec4f,
|
||||||
@location(0) color: vec4f
|
@location(1) uv: vec2f
|
||||||
}
|
}
|
||||||
struct Star {
|
struct Star {
|
||||||
pos: vec3f,
|
dec: f32,
|
||||||
|
ra: f32,
|
||||||
|
dist: f32,
|
||||||
lum: f32
|
lum: f32
|
||||||
}
|
}
|
||||||
struct Uniform {
|
struct Uniform {
|
||||||
_View: mat4x4f,
|
_View: mat4x4f,
|
||||||
_Projection: mat4x4f
|
_Projection: mat4x4f,
|
||||||
|
_Distance: f32,
|
||||||
|
_Intensity: f32
|
||||||
}
|
}
|
||||||
|
|
||||||
@group(0) @binding(0) var<uniform> uniforms: Uniform;
|
@group(0) @binding(0) var<uniform> uniforms: Uniform;
|
||||||
@group(0) @binding(1) var<storage, read> stars: array<Star>;
|
@group(0) @binding(1) var<storage, read> stars: array<Star>;
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
fn vertex_main(@location(0) position: vec3f, @builtin(instance_index) instance_index: u32) -> VertexOut
|
fn vertex_main(@location(0) position: vec2f, @location(1) uv: vec2f, @builtin(instance_index) instance_index: u32) -> VertexOut
|
||||||
{
|
{
|
||||||
var star: Star = stars[instance_index];
|
var star: Star = stars[instance_index];
|
||||||
var output: VertexOut;
|
var output: VertexOut;
|
||||||
|
|
||||||
var star_pos = uniforms._View * vec4f(star.pos, 1.0);
|
var decCos: f32 = cos(star.dec);
|
||||||
var billboard_pos = star_pos + vec4f(position, 0.0);
|
var decSin: f32 = sin(star.dec);
|
||||||
|
var raCos: f32 = cos(star.ra);
|
||||||
|
var raSin: f32 = sin(star.ra);
|
||||||
|
var dist: f32 = uniforms._Distance;
|
||||||
|
|
||||||
|
var star_pos: vec4f = vec4f(dist * decCos * raCos, dist * decCos * raSin, dist * decSin, 1.0);
|
||||||
|
|
||||||
output.position = uniforms._Projection * billboard_pos;
|
output.position = uniforms._Projection * (uniforms._View * star_pos + vec4f(position * star.lum * uniforms._Intensity, 0.0, 0.0));
|
||||||
output.color = vec4(star.lum, star.lum, star.lum, 1);
|
output.uv = uv;
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
@ -37,20 +47,21 @@ fn vertex_main(@location(0) position: vec3f, @builtin(instance_index) instance_i
|
||||||
@fragment
|
@fragment
|
||||||
fn fragment_main(fragData: VertexOut) -> @location(0) vec4f
|
fn fragment_main(fragData: VertexOut) -> @location(0) vec4f
|
||||||
{
|
{
|
||||||
//var dist = distance(fragData.uv, vec2f(0.5, 0.5));
|
var dist = distance(fragData.uv * 2.0, vec2f(1, 1));
|
||||||
//return vec4f(1 - dist, 1 - dist, 1 - dist, dist);
|
return vec4f(1 - dist, 1 - dist, 1 - dist, 1 - dist);
|
||||||
return vec4f(1.0, 1.0, 1.0, 1.0);
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
type StarID = number;
|
type StarID = string;
|
||||||
type Star = {
|
type Star = {
|
||||||
id: StarID;
|
id: StarID;
|
||||||
x: number;
|
bayer: string;
|
||||||
y: number;
|
hip: string;
|
||||||
z: number;
|
ra: string;
|
||||||
ci: number;
|
dec: string;
|
||||||
lum: number;
|
mag: string;
|
||||||
|
dist: string;
|
||||||
|
color: [number, number, number];
|
||||||
};
|
};
|
||||||
type Constellation = {
|
type Constellation = {
|
||||||
con: string;
|
con: string;
|
||||||
|
|
@ -321,57 +332,57 @@ class Matrix4x4
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
lookat(eye: Position, target: Position): this
|
aim(eye: Position, target: Position, up: Position): this
|
||||||
{
|
{
|
||||||
const forward = { //zAxis
|
const z = {
|
||||||
x: eye.x - target.x,
|
x: eye.x - target.x,
|
||||||
y: eye.y - target.y,
|
y: eye.y - target.y,
|
||||||
z: eye.z - target.z
|
z: eye.z - target.z
|
||||||
};
|
};
|
||||||
|
|
||||||
// Normalize
|
// Normalize
|
||||||
const forwardLen = Math.sqrt(forward.x * forward.x + forward.y * forward.y + forward.z * forward.z);
|
const zLen = Math.sqrt(z.x * z.x + z.y * z.y + z.z * z.z);
|
||||||
forward.x /= forwardLen;
|
z.x /= zLen;
|
||||||
forward.y /= forwardLen;
|
z.y /= zLen;
|
||||||
forward.z /= forwardLen;
|
z.z /= zLen;
|
||||||
|
|
||||||
const right = { //xAxis
|
const x = {
|
||||||
x: 1 * forward.z - 0 * forward.y,
|
x: up.y * z.z - up.z * z.y,
|
||||||
y: 0 * forward.x - 0 * forward.z,
|
y: up.z * z.x - up.x * z.z,
|
||||||
z: 0 * forward.y - 1 * forward.x
|
z: up.x * z.y - up.y * z.x
|
||||||
};
|
};
|
||||||
|
|
||||||
// Normalize
|
// Normalize
|
||||||
const rightLen = Math.sqrt(right.x * right.x + right.y * right.y + right.z * right.z);
|
const xLen = Math.sqrt(x.x * x.x + x.y * x.y + x.z * x.z);
|
||||||
right.x /= rightLen;
|
x.x /= xLen;
|
||||||
right.y /= rightLen;
|
x.y /= xLen;
|
||||||
right.z /= rightLen;
|
x.z /= xLen;
|
||||||
|
|
||||||
const up = { //yAxis
|
const y = {
|
||||||
x: forward.y * right.z - forward.z * right.y,
|
x: z.y * x.z - z.z * x.y,
|
||||||
y: forward.z * right.x - forward.x * right.z,
|
y: z.z * x.x - z.x * x.z,
|
||||||
z: forward.x * right.y - forward.y * right.x
|
z: z.x * x.y - z.y * x.x
|
||||||
};
|
};
|
||||||
|
|
||||||
// Normalize
|
// Normalize
|
||||||
const upLen = Math.sqrt(up.x * up.x + up.y * up.y + up.z * up.z);
|
const yLen = Math.sqrt(y.x * y.x + y.y * y.y + y.z * y.z);
|
||||||
up.x /= upLen;
|
y.x /= yLen;
|
||||||
up.y /= upLen;
|
y.y /= yLen;
|
||||||
up.z /= upLen;
|
y.z /= yLen;
|
||||||
|
|
||||||
this._view[ 0] = right.x;
|
this._view[ 0] = x.x;
|
||||||
this._view[ 1] = right.y;
|
this._view[ 1] = x.y;
|
||||||
this._view[ 2] = right.z;
|
this._view[ 2] = x.z;
|
||||||
this._view[ 3] = 0;
|
this._view[ 3] = 0;
|
||||||
|
|
||||||
this._view[ 4] = up.x;
|
this._view[ 4] = y.x;
|
||||||
this._view[ 5] = up.y;
|
this._view[ 5] = y.y;
|
||||||
this._view[ 6] = up.z;
|
this._view[ 6] = y.z;
|
||||||
this._view[ 7] = 0;
|
this._view[ 7] = 0;
|
||||||
|
|
||||||
this._view[ 8] = forward.x;
|
this._view[ 8] = z.x;
|
||||||
this._view[ 9] = forward.y;
|
this._view[ 9] = z.y;
|
||||||
this._view[10] = forward.z;
|
this._view[10] = z.z;
|
||||||
this._view[11] = 0;
|
this._view[11] = 0;
|
||||||
|
|
||||||
this._view[12] = eye.x;
|
this._view[12] = eye.x;
|
||||||
|
|
@ -382,29 +393,35 @@ class Matrix4x4
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
perspective(aspect: number, fovY: number, near: number, far: number): this
|
perspective(left: number, right: number, top: number, bottom: number, near: number, far: number): this
|
||||||
{
|
{
|
||||||
const f = Math.tan(Math.PI * 0.5 - 0.5 * fovY);
|
const x = 2 * near / ( right - left );
|
||||||
const rangeInv = 1 / (near - far);
|
const y = 2 * near / ( top - bottom );
|
||||||
|
|
||||||
this._view[0] = f / aspect;
|
const a = ( right + left ) / ( right - left );
|
||||||
this._view[1] = 0;
|
const b = ( top + bottom ) / ( top - bottom );
|
||||||
this._view[2] = 0;
|
|
||||||
this._view[3] = 0;
|
|
||||||
|
|
||||||
this._view[4] = 0;
|
const c = -( far + near ) / ( far - near );
|
||||||
this._view[5] = f;
|
const d = -( 2 * far * near ) / ( far - near );
|
||||||
this._view[6] = 0;
|
|
||||||
this._view[7] = 0;
|
|
||||||
|
|
||||||
this._view[8] = 0;
|
this._view[0 ] = x;
|
||||||
this._view[9] = 0;
|
this._view[1 ] = 0;
|
||||||
this._view[10] = far * rangeInv;
|
this._view[2 ] = 0;
|
||||||
|
this._view[3 ] = 0;
|
||||||
|
|
||||||
|
this._view[4 ] = 0;
|
||||||
|
this._view[5 ] = y;
|
||||||
|
this._view[6 ] = 0;
|
||||||
|
this._view[7 ] = 0;
|
||||||
|
|
||||||
|
this._view[8 ] = a;
|
||||||
|
this._view[9 ] = b;
|
||||||
|
this._view[10] = c;
|
||||||
this._view[11] = -1;
|
this._view[11] = -1;
|
||||||
|
|
||||||
this._view[12] = 0;
|
this._view[12] = 0;
|
||||||
this._view[13] = 0;
|
this._view[13] = 0;
|
||||||
this._view[14] = near * far * rangeInv;
|
this._view[14] = d;
|
||||||
this._view[15] = 0;
|
this._view[15] = 0;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
|
@ -477,7 +494,7 @@ class Camera
|
||||||
{
|
{
|
||||||
pitch = 0;
|
pitch = 0;
|
||||||
yaw = 0;
|
yaw = 0;
|
||||||
distance = 25
|
distance = 25;
|
||||||
view = new Matrix4x4();
|
view = new Matrix4x4();
|
||||||
|
|
||||||
constructor(distance?: number, yaw?: number, pitch?: number)
|
constructor(distance?: number, yaw?: number, pitch?: number)
|
||||||
|
|
@ -498,23 +515,23 @@ class Camera
|
||||||
const pitchCos = Math.cos(this.pitch), pitchSin = Math.sin(this.pitch);
|
const pitchCos = Math.cos(this.pitch), pitchSin = Math.sin(this.pitch);
|
||||||
const yawCos = Math.cos(this.yaw), yawSin = Math.sin(this.yaw);
|
const yawCos = Math.cos(this.yaw), yawSin = Math.sin(this.yaw);
|
||||||
|
|
||||||
this.distance = clamp(this.distance + (Inputs.zoom * elapsed * 1000), 1, 10000);
|
this.distance = clamp(this.distance + (Inputs.zoom * elapsed * 1000), 0.1, 10000);
|
||||||
|
|
||||||
const x = this.distance * yawSin * pitchCos;
|
const x = this.distance * yawCos * pitchCos;
|
||||||
const y = this.distance * yawSin * pitchSin;
|
const y = this.distance * yawCos * pitchSin;
|
||||||
const z = this.distance * yawCos;
|
const z = this.distance * yawSin;
|
||||||
|
|
||||||
device!.queue.writeBuffer(target, 0, this.view.lookat({ x, y, z }, { x: 0, y: 0, z: 0 }).view.buffer);
|
device!.queue.writeBuffer(target, 0, this.view.aim({ x, y, z }, { x: 0, y: 0, z: 0 }, { x: 0, y: 1, z: 0 }).invert().view.buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
const stars: Star[] = untypedStars;
|
const stars: Star[] = untypedStars;
|
||||||
const constellations: Constellation[] = untypedConstellations;
|
//const constellations: Constellation[] = untypedConstellations;
|
||||||
let canvas: HTMLCanvasElement, device: GPUDevice | undefined, pipeline: GPURenderPipeline, context: GPUCanvasContext | null, bindGroup: GPUBindGroup, viewport: DOMRect, uniforms: GPUBuffer, indirect: GPUBuffer;
|
let canvas: HTMLCanvasElement, device: GPUDevice | undefined, pipeline: GPURenderPipeline, context: GPUCanvasContext | null, bindGroup: GPUBindGroup, viewport: DOMRect, uniforms: GPUBuffer, indirect: GPUBuffer;
|
||||||
let vertex: GPUBuffer, index: GPUBuffer;
|
let vertex: GPUBuffer, index: GPUBuffer;
|
||||||
let camera: Camera, projectionMatrix = new Matrix4x4(), lastTime: DOMHighResTimeStamp;
|
let camera: Camera, projectionMatrix = new Matrix4x4(), lastTime: DOMHighResTimeStamp;
|
||||||
let stats: Stats, dom: HTMLElement;
|
let stats: Stats, dom: HTMLElement, gui: GUI, parameters: Record<string, any> = { distance: 125, intensity: 5 };
|
||||||
|
|
||||||
function clamp(x: number, min: number, max: number): number
|
function clamp(x: number, min: number, max: number): number
|
||||||
{
|
{
|
||||||
|
|
@ -530,18 +547,18 @@ function fillBuffer(buffer: ArrayBuffer)
|
||||||
|
|
||||||
for(let i = 0; i < stars.length; i++)
|
for(let i = 0; i < stars.length; i++)
|
||||||
{
|
{
|
||||||
array[i * 5 + 0] = stars[i]!.x;
|
const star = stars[i]!;
|
||||||
array[i * 5 + 1] = stars[i]!.y;
|
array[i * 5 + 0] = parseFloat(star.dec) / 180 * Math.PI;
|
||||||
array[i * 5 + 2] = stars[i]!.z;
|
array[i * 5 + 1] = parseFloat(star.ra) / 12 * Math.PI;
|
||||||
array[i * 5 + 3] = stars[i]!.lum;
|
array[i * 5 + 2] = parseFloat(star.dist);
|
||||||
//array[i * 5 + 4] = stars[i]!.ci;
|
array[i * 5 + 3] = parseFloat(star.mag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function resize()
|
function resize()
|
||||||
{
|
{
|
||||||
viewport = document.body.getBoundingClientRect();
|
viewport = document.body.getBoundingClientRect();
|
||||||
canvas!.width = viewport.width; canvas!.height = viewport.height;
|
canvas!.width = viewport.width; canvas!.height = viewport.height;
|
||||||
device!.queue.writeBuffer(uniforms, 64, projectionMatrix.perspective(viewport.width / viewport.height, 60, 0.1, 2000000).view.buffer);
|
device!.queue.writeBuffer(uniforms, 64, projectionMatrix.perspective(-viewport.width / 2, viewport.width / 2, viewport.height / 2, -viewport.height / 2, 0.1, 10000).view.buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function init()
|
async function init()
|
||||||
|
|
@ -552,7 +569,9 @@ async function init()
|
||||||
Inputs.init(canvas);
|
Inputs.init(canvas);
|
||||||
|
|
||||||
stats = new Stats();
|
stats = new Stats();
|
||||||
|
gui = new GUI();
|
||||||
document.body.appendChild(stats.dom);
|
document.body.appendChild(stats.dom);
|
||||||
|
document.body.appendChild(gui.domElement);
|
||||||
|
|
||||||
const adapter = await navigator.gpu.requestAdapter({ });
|
const adapter = await navigator.gpu.requestAdapter({ });
|
||||||
device = await adapter?.requestDevice({ label: 'Device' });
|
device = await adapter?.requestDevice({ label: 'Device' });
|
||||||
|
|
@ -569,17 +588,28 @@ async function init()
|
||||||
fillBuffer(arrayBuffer);
|
fillBuffer(arrayBuffer);
|
||||||
device.queue.writeBuffer(buffer, 0, arrayBuffer);
|
device.queue.writeBuffer(buffer, 0, arrayBuffer);
|
||||||
|
|
||||||
uniforms = device.createBuffer({ size: 16 * 4 * 2, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, label: 'uniforms_buffer' });
|
uniforms = device.createBuffer({ size: 16 * 4 + 16 * 4 + 16, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, label: 'uniforms_buffer' });
|
||||||
|
const tmpBuffer = new Float32Array([parameters.distance, parameters.intensity]);
|
||||||
|
gui.add(parameters, 'distance', 0, 1000).onChange((v: number) => {
|
||||||
|
tmpBuffer[0] = v;
|
||||||
|
device!.queue.writeBuffer(uniforms, 128, tmpBuffer);
|
||||||
|
});
|
||||||
|
gui.add(parameters, 'intensity', 0.01, 10).onChange((v: number) => {
|
||||||
|
tmpBuffer[1] = v;
|
||||||
|
device!.queue.writeBuffer(uniforms, 128, tmpBuffer);
|
||||||
|
});
|
||||||
camera = new Camera();
|
camera = new Camera();
|
||||||
|
|
||||||
indirect = device.createBuffer({ size: 5 * 4, usage: GPUBufferUsage.INDIRECT | GPUBufferUsage.COPY_DST, label: 'indirect_buffer' });
|
{
|
||||||
const indirectArray = new Uint32Array([ 6, stars.length, 0, 0, 0 ]);
|
indirect = device.createBuffer({ size: 5 * 4, usage: GPUBufferUsage.INDIRECT | GPUBufferUsage.COPY_DST, label: 'indirect_buffer' });
|
||||||
const indirectSignedArray = new Int32Array(indirectArray.buffer);
|
const indirectArray = new Uint32Array([ 6, stars.length, 0, 0, 0 ]);
|
||||||
indirectSignedArray[3] = 0;
|
const indirectSignedArray = new Int32Array(indirectArray.buffer);
|
||||||
device.queue.writeBuffer(indirect, 0, indirectArray.buffer);
|
indirectSignedArray[3] = 0;
|
||||||
|
device.queue.writeBuffer(indirect, 0, indirectArray.buffer);
|
||||||
|
}
|
||||||
|
|
||||||
vertex = device.createBuffer({ size: 3 * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST, label: 'vertex_buffer' });
|
vertex = device.createBuffer({ size: 4 * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST, label: 'vertex_buffer' });
|
||||||
device.queue.writeBuffer(vertex, 0, new Float32Array([ -0.5, -0.5, 0.0, 0.5, -0.5, 0.0, 0.5, 0.5, 0.0, -0.5, 0.5, 0.0, ]));
|
device.queue.writeBuffer(vertex, 0, new Float32Array([ -0.5, -0.5, 0, 0, 0.5, -0.5, 1, 0, 0.5, 0.5, 1, 1, -0.5, 0.5, 0, 1, ]));
|
||||||
|
|
||||||
index = device.createBuffer({ size: 6 * 2, usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST, label: 'index_buffer' });
|
index = device.createBuffer({ size: 6 * 2, usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST, label: 'index_buffer' });
|
||||||
device.queue.writeBuffer(index, 0, new Uint16Array([ 0, 1, 2, 0, 2, 3 ]));
|
device.queue.writeBuffer(index, 0, new Uint16Array([ 0, 1, 2, 0, 2, 3 ]));
|
||||||
|
|
@ -604,7 +634,7 @@ async function init()
|
||||||
layout: bindGroupLayout,
|
layout: bindGroupLayout,
|
||||||
entries: [{
|
entries: [{
|
||||||
binding: 0,
|
binding: 0,
|
||||||
resource: { buffer: uniforms, }
|
resource: { buffer: uniforms }
|
||||||
}, {
|
}, {
|
||||||
binding: 1,
|
binding: 1,
|
||||||
resource: { buffer: buffer, }
|
resource: { buffer: buffer, }
|
||||||
|
|
@ -620,21 +650,39 @@ async function init()
|
||||||
entryPoint: 'vertex_main',
|
entryPoint: 'vertex_main',
|
||||||
buffers: [{
|
buffers: [{
|
||||||
attributes: [{
|
attributes: [{
|
||||||
format: 'float32x3',
|
format: 'float32x2',
|
||||||
offset: 0,
|
offset: 0,
|
||||||
shaderLocation: 0
|
shaderLocation: 0
|
||||||
|
}, {
|
||||||
|
format: 'float32x2',
|
||||||
|
offset: 8,
|
||||||
|
shaderLocation: 1
|
||||||
}],
|
}],
|
||||||
arrayStride: 4 * 3,
|
arrayStride: 4 * 4,
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
fragment: {
|
fragment: {
|
||||||
targets: [{ format: navigator.gpu.getPreferredCanvasFormat() }],
|
targets: [{
|
||||||
|
format: navigator.gpu.getPreferredCanvasFormat(),
|
||||||
|
blend: {
|
||||||
|
color: {
|
||||||
|
operation: 'add',
|
||||||
|
srcFactor: 'one',
|
||||||
|
dstFactor: 'one'
|
||||||
|
},
|
||||||
|
alpha: {
|
||||||
|
operation: 'add',
|
||||||
|
srcFactor: 'one',
|
||||||
|
dstFactor: 'one'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}],
|
||||||
module: shader,
|
module: shader,
|
||||||
entryPoint: 'fragment_main'
|
entryPoint: 'fragment_main',
|
||||||
},
|
},
|
||||||
primitive: {
|
primitive: {
|
||||||
topology: 'triangle-list',
|
topology: 'triangle-list',
|
||||||
cullMode: 'front',
|
cullMode: 'none',
|
||||||
frontFace: 'cw'
|
frontFace: 'cw'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -646,7 +694,7 @@ async function init()
|
||||||
context.configure({
|
context.configure({
|
||||||
device,
|
device,
|
||||||
format: navigator.gpu.getPreferredCanvasFormat(),
|
format: navigator.gpu.getPreferredCanvasFormat(),
|
||||||
alphaMode: 'premultiplied',
|
alphaMode: 'opaque',
|
||||||
});
|
});
|
||||||
|
|
||||||
dom = document.createElement('pre');
|
dom = document.createElement('pre');
|
||||||
|
|
@ -670,7 +718,9 @@ function render(time: DOMHighResTimeStamp)
|
||||||
{
|
{
|
||||||
const elapsed = time - lastTime;
|
const elapsed = time - lastTime;
|
||||||
lastTime = time;
|
lastTime = time;
|
||||||
|
|
||||||
stats.begin();
|
stats.begin();
|
||||||
|
|
||||||
const commandEncoder = device!.createCommandEncoder({ label: 'command-encoder' });
|
const commandEncoder = device!.createCommandEncoder({ label: 'command-encoder' });
|
||||||
const pass = commandEncoder.beginRenderPass({ label: 'render-pass', colorAttachments: [{
|
const pass = commandEncoder.beginRenderPass({ label: 'render-pass', colorAttachments: [{
|
||||||
loadOp: "clear",
|
loadOp: "clear",
|
||||||
|
|
@ -691,8 +741,8 @@ function render(time: DOMHighResTimeStamp)
|
||||||
pass.end();
|
pass.end();
|
||||||
|
|
||||||
device!.queue.submit([ commandEncoder.finish() ]);
|
device!.queue.submit([ commandEncoder.finish() ]);
|
||||||
|
device!.queue.onSubmittedWorkDone().then(() => stats.end());
|
||||||
|
|
||||||
stats.end();
|
|
||||||
requestAnimationFrame(render);
|
requestAnimationFrame(render);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@webgpu/types": "^0.1.64",
|
"@webgpu/types": "^0.1.64",
|
||||||
|
"lil-gui": "^0.20.0",
|
||||||
"stats.ts": "^1.1.0"
|
"stats.ts": "^1.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue