我是WebGPU和3D渲染世界的新手。
我正在尝试做的是在Typescript和wgsl中绘制一个矩形。
我知道网格是一组顶点。由3个顶点组成的网格绘制三角形。4个顶点的网格不是画了一个矩形吗?这就是我在这里所做的,但结果仍然是在浏览器上给我一个三角形。不考虑最后一个顶点。
这是我的代码(基于GetIntoGameDev):
rectangle_mesh.ts
export class RectangleMesh {
public buffer: GPUBuffer;
public bufferLayout: GPUVertexBufferLayout;
constructor(public device: GPUDevice) {
const vertices: Float32Array = new Float32Array(
[
-0.5, 0.5, 1, 1, 1,
0.5, 0.5, 0, 1, 0,
0.5, -0.5, 1, 0, 1,
-0.5, -0.5, 0, 0, 0, // This vertex is not working
]
);
const usage: GPUBufferUsageFlags = GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST;
const descriptor: GPUBufferDescriptor = {
size: vertices.byteLength,
usage: usage,
mappedAtCreation: true
};
this.buffer = device.createBuffer(descriptor);
new Float32Array(this.buffer.getMappedRange()).set(vertices);
this.buffer.unmap();
this.bufferLayout = {
arrayStride: 20, // row_num * 4bytes
attributes: [
{
shaderLocation: 0,
format: "float32x2",
offset: 0
},
{
shaderLocation: 1,
format: "float32x3",
offset: 8
}
]
}
}
}
shader.wgsl
struct Fragment {
@builtin(position) Position : vec4<f32>,
@location(0) Color : vec4<f32>
};
@vertex
fn vs_main(@location(0) vertexPosition: vec2<f32>, @location(1) vertexColor: vec3<f32>) -> Fragment {
var output : Fragment;
output.Position = vec4<f32>(vertexPosition, 0.0, 1.0);
output.Color = vec4<f32>(vertexColor, 1.0);
return output;
}
@fragment
fn fs_main(@location(0) Color: vec4<f32>) -> @location(0) vec4<f32> {
return Color;
}
main.ts
import { RectangleMesh } from "./rectangle_mesh";
import shader from "./shaders/shader.wgsl";
import { TriangleMesh } from "./triangle_mesh";
const Initialize = async() => {
const canvas : HTMLCanvasElement = <HTMLCanvasElement> document.getElementById("game_window");
//adapter: wrapper around (physical) GPU.
//Describes features and limits
const adapter : GPUAdapter = <GPUAdapter> await navigator.gpu?.requestAdapter();
//device: wrapper around GPU functionality
//Function calls are made through the device
const device : GPUDevice = <GPUDevice> await adapter?.requestDevice();
//context: similar to vulkan instance (or OpenGL context)
const context : GPUCanvasContext = <GPUCanvasContext><unknown>canvas.getContext("webgpu");
const format : GPUTextureFormat = "bgra8unorm";
context.configure({
device: device,
format: format,
alphaMode: "opaque"
});
const bindGroupLayout = device.createBindGroupLayout({
entries: [],
});
const bindGroup = device.createBindGroup({
layout: bindGroupLayout,
entries: []
});
const pipelineLayout = device.createPipelineLayout({
bindGroupLayouts: [bindGroupLayout]
});
// const triangleMesh = new TriangleMesh(device);
const rectangleMesh = new RectangleMesh(device);
const pipeline = device.createRenderPipeline({
vertex : {
module : device.createShaderModule({
code : shader
}),
entryPoint : "vs_main",
buffers: [rectangleMesh.bufferLayout, ]
},
fragment : {
module : device.createShaderModule({
code : shader
}),
entryPoint : "fs_main",
targets : [{
format : format
}]
},
primitive : {
topology : "triangle-list"
},
layout: pipelineLayout
});
//command encoder: records draw commands for submission
const commandEncoder : GPUCommandEncoder = device.createCommandEncoder();
//texture view: image view to the color buffer in this case
const textureView : GPUTextureView = context.getCurrentTexture().createView();
//renderpass: holds draw commands, allocated from command encoder
const renderpass : GPURenderPassEncoder = commandEncoder.beginRenderPass({
// set the background color
colorAttachments: [{
view: textureView,
clearValue: {r: 52/255, g: 124/255, b: 235/255, a: 1.0},
loadOp: "clear",
storeOp: "store"
}]
});
renderpass.setPipeline(pipeline);
renderpass.setBindGroup(0, bindGroup)
renderpass.setVertexBuffer(0, rectangleMesh.buffer) // use the buffer from triangle
renderpass.draw(4, 1, 0, 0);
renderpass.end();
device.queue.submit([commandEncoder.finish()]);
}
function InitializeScreen() {
console.log("Width = ", window.innerWidth.toString());
console.log("Height = ", window.innerHeight.toString());
document.getElementById("game_window")?.setAttribute("width", window.innerWidth.toString());
document.getElementById("game_window")?.setAttribute("height", window.innerHeight.toString());
}
window.onresize = () => {
console.log("Resizing ...");
InitializeScreen();
Initialize();
}
InitializeScreen();
Initialize();
这是输出:
1条答案
按热度按时间gfttwv5a1#
所以,经过一些研究,我发现一个矩形只是两个三角形放在一起。
折点应该是这样的
我们不应该忘记更新draw()方法中的顶点数