WebGPU小白实践(一)

112 阅读1分钟

刚开始学习webGPU,记录一下,之前没有接触过踩了很多坑,很多都不太能看得懂 做了一个简易的柱状图,参考了Orillusion/orillusion-web: The official doc website of Orillusion (github.com)(其实基本照的)

1-1.png 圆柱体模型(用的三角形渲染的) 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;
}

然后把圆柱形放入管线中渲染就成了。 目前实现:模型旋转缩放 下个目标:贴图