添加WebGPU渲染器和着色器

This commit is contained in:
SpecialX
2025-11-18 18:38:37 +08:00
parent 81a2b5c71e
commit 186fb4515e
2 changed files with 80 additions and 1 deletions

View File

@@ -1,6 +1,10 @@
import shaderSource from './shaders/shader.wgsl?raw';
class Renderer{
private device! : GPUDevice;
private context! : GPUCanvasContext;
private pipeline! : GPURenderPipeline;
public async initialize()
{
@@ -32,6 +36,7 @@ class Renderer{
format: navigator.gpu.getPreferredCanvasFormat()
})
this.prepareModel();
}
public draw()
@@ -42,7 +47,7 @@ class Renderer{
const renderPassDescriptor:GPURenderPassDescriptor = {
colorAttachments:[{
view: textureView,
clearValue: {r: 1, g: 0, b: 0, a: 1},
clearValue: {r: 0, g: 0, b: 0, a: 1},
loadOp: 'clear',
storeOp:'store'
}]
@@ -50,12 +55,51 @@ class Renderer{
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
//Draw here
passEncoder.setPipeline(this.pipeline );
passEncoder.draw(3);
passEncoder.end();
this.device.queue.submit([commandEncoder.finish()]);
}
private prepareModel() {
const shaderModule = this.device.createShaderModule({code: shaderSource});
const vertexState: GPUVertexState = {
module : shaderModule,
entryPoint: "VertexMain",
buffers: []
}
const fragmentState: GPUFragmentState = {
module : shaderModule,
entryPoint: "FragmentMain",
targets: [
{
format: navigator.gpu.getPreferredCanvasFormat()
}
]
}
this.pipeline = this.device.createRenderPipeline({
vertex: vertexState,
fragment: fragmentState,
primitive:{
topology: 'triangle-list',
},
layout: "auto"
});
}
}
const renderer = new Renderer();
renderer.initialize()

35
src/shaders/shader.wgsl Normal file
View File

@@ -0,0 +1,35 @@
// 定义顶点着色器传递给片元着色器的数据结构
struct VertexOut {
@builtin(position) pos: vec4<f32>,
@location(0) color: vec4<f32>,
}
// 顶点着色器主函数
@vertex
fn VertexMain(
@builtin(vertex_index) vertexIndex: u32,
) -> VertexOut
{
// 定义一个三角形的三个顶点位置 (在 NDC 空间)
let pos = array(
vec2<f32>(-0.5, -0.5),
vec2<f32>( 0.5, -0.5),
vec2<f32>( 0.0, 0.5)
);
var output : VertexOut;
// 根据顶点索引设置最终位置
output.pos = vec4<f32>(pos[vertexIndex], 0.0, 1.0);
// 为所有顶点设置一个固定的红色
output.color = vec4<f32>(1.0, 0.0, 0.0, 1.0);
return output;
}
// 片元着色器主函数
@fragment
fn FragmentMain(fragData: VertexOut) -> @location(0) vec4<f32>
{
// 直接返回从顶点着色器经过插值后的颜色
return fragData.color;
}