GaiaStars
HTML
<canvas style="height: 100%; width: 100%;"></canvas>>
JavaScript
async function main() {
const adapter = await navigator.gpu?.requestAdapter();
const device = await adapter?.requestDevice();
if (!device) {
fail('need a browser that supports WebGPU');
return;
}
// Get a WebGPU context from the canvas and configure it
const canvas = document.querySelector('canvas');
const context = canvas.getContext('webgpu');
const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
context.configure({
device,
format: presentationFormat,
});
const module = device.createShaderModule({
code: `
struct Star {
ra: f32,
dec: f32,
d: f32,
m: f32
};
struct InOut {
@builtin(position) position: vec4f,
@location(0) tex: vec2f,
};
struct UniformData {
time: f32,
};
@group(0) @binding(0) var<storage, read> stars: array<Star>;
@group(0) @binding(1) var<uniform> uniformData: UniformData;
@vertex fn vs( @builtin(vertex_index) vertexIndex : u32 ) -> InOut {
let pos = array(
vec2f( -1, -1),
vec2f( -1, 1),
vec2f( 1, -1),
vec2f( 1, 1),
vec2f( 1, -1),
vec2f( -1, 1)
);
var star = stars[vertexIndex/6];
star.ra += uniformData.time;
let flux = pow(-star.m/2.5,10);
let size = max(0.02,0.0002*sqrt(flux));
let x = size*pos[vertexIndex%6].x + sin(star.ra/180.0*3.1415) * cos(star.dec/180.0*3.1415);
let y = size*pos[vertexIndex%6].y + cos(star.ra/180.0*3.1415) * cos(star.dec/180.0*3.1415);
let z = sin(star.dec/180.0*3.1415);
var inOut: InOut;
inOut.position = vec4f( x, y, z, 1.0);
inOut.tex = pos[vertexIndex%6];
return inOut;
}
@fragment fn fs(inOut: InOut) -> @location(0) vec4f {
let phi = atan2(inOut.tex.y,inOut.tex.x);
var r = 1.0-length(inOut.tex);
let a = pow(clamp(sin(phi*6.0),0.0,1.0),5.0/r);
...