刚开始学习webGPU,记录一下,之前没有接触过踩了很多坑,很多都不太能看得懂 做了一个简易的柱状图,参考了Orillusion/orillusion-web: The official doc website of Orillusion (github.com)(其实基本照的)
圆柱体模型(用的三角形渲染的)
ps:
三个点构成一个三角形,每个点5个参数
正面的三角形三个点是顺时针,反面的三角三个点是逆时针顺序读入的
let str = '';
let index=new Float32Array( [-r,0.1,0.0]);
let indexN=new Float32Array( [-r,0.1,width]);
//63的189刚好是一个圆
for(let i=0;i<63;i++){
circle+="0.0,0.0,0.0,1.0,1.0,";
circleN+="0.0,0.0,"+width+",1.0,1.0,";
circle+=index.toString()+',1.0,1.0,';
let back=indexN.toString()+',1.0,1.0,';
let pre = "";
let next = "";
next = index.toString() +',0.0,0.0,'
pre = indexN.toString() +',0.0,0.0,'
vec3.rotateZ(indexN, indexN, new Float32Array([0.0,0.0,width]), 0.1);
pre += indexN.toString() +',0.0,0.0,' +index.toString() +',0.0,0.0,'
vec3.rotateZ(index, index, new Float32Array([0.0,0.0,0.0]), 0.1);
next = indexN.toString() +',0.0,0.0,' +index.toString() +',0.0,0.0,' +next
circle+=index.toString()+',1.0,1.0,';
circleN=circleN+indexN.toString()+',1.0,1.0,'+back;
listmid += pre+next;
}
str = circle+listmid+circleN
const vertex = new Float32Array(str.split(',').map(x=>parseFloat(x)));
const vertexCount = 756;
创建一个圆柱形,添加监听事件,鼠标点击移动可以旋转圆柱形
export async function initCircle(device: GPUDevice,canvas:HTMLCanvasElement):Promise<vertexFormat> {
// create vertex buffer
const vertexBuffer = device.createBuffer({
label: 'GPUBuffer store vertex',
size: cube.vertex.byteLength,
usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
})
device.queue.writeBuffer(vertexBuffer, 0, cube.vertex)
const eventList = [] as Array<eventFormat>;
const rotation = {x: 0, y: 0, z:0};
const scale = {x:1, y:1, z:1};
const position = {x:0, y:0, z: -9};
/**
*
* @returns 返回监听事件列表
*/
function rotaionEvent():Array<eventFormat>{
const eventList= [] as Array<eventFormat>;
const model = {
width:0.0,
height:0.0
}
let eventL = (e1:MouseEvent)=>{
let width = e1.clientX;
let height = e1.clientY;
let edgeX = rotation.x + (model.height - height)/canvas.height;
let edgeY = rotation.y + (model.width - width)/canvas.width;
rotation.x = wrapPi(edgeX);
rotation.y = wrapPi(edgeY);
model.width = width;
model.height = height;
};
let eventM = (e2:MouseEvent)=>{
canvas.removeEventListener('mousemove',eventL);
}
const eventDown = (e:MouseEvent)=>{
model.width = e.clientX;
model.height = e.clientY;
canvas.removeEventListener('mouseup',eventM);
canvas.addEventListener('mousemove',eventL )
canvas.addEventListener('mouseup', eventM)
};
window.addEventListener('mousedown', eventDown)
return eventList;
}
// create a mvp matrix buffer
let obj = {
vertexbuffer:vertexBuffer,
indexbuffer:vertexBuffer,
indexCount:cube.vertexCount,
position: position,
scale: scale,
rotation: rotation,
eventList:rotaionEvent()
}
return obj;
}
然后把圆柱形放入管线中渲染就成了。 目前实现:模型旋转缩放 下个目标:贴图