<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      WebGPU學(xué)習(xí)(七):學(xué)習(xí)“twoCubes”和“instancedCube”示例

      大家好,本文學(xué)習(xí)Chrome->webgpu-samplers->twoCubes和instancedCube示例。

      這兩個(gè)示例都與“rotatingCube”示例差不多。建議大家先學(xué)習(xí)該示例,再學(xué)習(xí)本文的兩個(gè)示例

      上一篇博文:
      WebGPU學(xué)習(xí)(六):學(xué)習(xí)“rotatingCube”示例

      下一篇博文:
      WebGPU學(xué)習(xí)(八):學(xué)習(xí)“texturedCube”示例

      學(xué)習(xí)twoCubes.ts

      該示例繪制了兩個(gè)立方體。

      與“rotatingCube”示例相比,該示例增加了以下的內(nèi)容:

      • 一個(gè)ubo保存兩個(gè)立方體的mvp矩陣
      • 每幀更新兩個(gè)mvp矩陣數(shù)據(jù)
      • draw兩次,分別設(shè)置對(duì)應(yīng)的uniformBindGroup

      下面,我們打開twoCubes.ts文件,依次來看下新增內(nèi)容:

      一個(gè)ubo保存兩個(gè)立方體的mvp矩陣

      • vertex shader定義uniform block

      因?yàn)橹挥幸粋€(gè)ubo,所以只有一個(gè)uniform block,代碼與rotatingCube示例相同:

        const vertexShaderGLSL = `#version 450
        layout(set = 0, binding = 0) uniform Uniforms {
          mat4 modelViewProjectionMatrix;
        } uniforms;
        ...
        void main() {
          gl_Position = uniforms.modelViewProjectionMatrix * position;
          ...
        }
        `;
      
      • 創(chuàng)建uniform buffer

      代碼如下:

        const matrixSize = 4 * 16; // BYTES_PER_ELEMENT(4) * matrix length(4 * 4 = 16)
        const offset = 256; // uniformBindGroup offset must be 256-byte aligned
        const uniformBufferSize = offset + matrixSize;
      
        const uniformBuffer = device.createBuffer({
          size: uniformBufferSize,
          usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
        });
      

      uniform buffer要保存兩個(gè)mvp矩陣的數(shù)據(jù),但是它們不能連續(xù)存放,它們的起始位置必須為256的倍數(shù),所以u(píng)niform buffer實(shí)際的內(nèi)存布局為:
      0-63:第一個(gè)mvp矩陣
      64-255:0(占位)
      256-319:第二個(gè)mvp矩陣

      uniform buffer的size為256+64=320

      • 創(chuàng)建uniform bind group

      創(chuàng)建兩個(gè)uniform bind group,通過指定offset和size,對(duì)應(yīng)到同一個(gè)uniform buffer:

        const uniformBindGroup1 = device.createBindGroup({
          layout: uniformsBindGroupLayout,
          bindings: [{
            binding: 0,
            resource: {
              buffer: uniformBuffer,
              offset: 0,
              size: matrixSize
            }
          }],
        });
      
        const uniformBindGroup2 = device.createBindGroup({
          layout: uniformsBindGroupLayout,
          bindings: [{
            binding: 0,
            resource: {
              buffer: uniformBuffer,
              offset: offset,
              size: matrixSize
            }
          }]
        });
      
      • 創(chuàng)建2個(gè)mvp矩陣

      代碼如下:

        //因?yàn)槭枪潭ㄏ鄼C(jī),所以只需要計(jì)算一次projection矩陣
        const aspect = Math.abs(canvas.width / canvas.height);
        let projectionMatrix = mat4.create();
        mat4.perspective(projectionMatrix, (2 * Math.PI) / 5, aspect, 1, 100.0);
        ...
        
        let modelMatrix1 = mat4.create();
        mat4.translate(modelMatrix1, modelMatrix1, vec3.fromValues(-2, 0, 0));
        let modelMatrix2 = mat4.create();
        mat4.translate(modelMatrix2, modelMatrix2, vec3.fromValues(2, 0, 0));
        //創(chuàng)建兩個(gè)mvp矩陣
        let modelViewProjectionMatrix1 = mat4.create();
        let modelViewProjectionMatrix2 = mat4.create();
        //因?yàn)槭枪潭ㄏ鄼C(jī),所以只需要計(jì)算一次view矩陣
        let viewMatrix = mat4.create();
        mat4.translate(viewMatrix, viewMatrix, vec3.fromValues(0, 0, -7));
      
        let tmpMat41 = mat4.create();
        let tmpMat42 = mat4.create();
      

      每幀更新兩個(gè)mvp矩陣數(shù)據(jù)

      相關(guān)代碼如下所示:

        function updateTransformationMatrix() {
          let now = Date.now() / 1000;
      
          mat4.rotate(tmpMat41, modelMatrix1, 1, vec3.fromValues(Math.sin(now), Math.cos(now), 0));
          mat4.rotate(tmpMat42, modelMatrix2, 1, vec3.fromValues(Math.cos(now), Math.sin(now), 0));
      
          mat4.multiply(modelViewProjectionMatrix1, viewMatrix, tmpMat41);
          mat4.multiply(modelViewProjectionMatrix1, projectionMatrix, modelViewProjectionMatrix1);
          mat4.multiply(modelViewProjectionMatrix2, viewMatrix, tmpMat42);
          mat4.multiply(modelViewProjectionMatrix2, projectionMatrix, modelViewProjectionMatrix2);
        }
      
        return function frame() {
          updateTransformationMatrix();
      
          ...
      
          uniformBuffer.setSubData(0, modelViewProjectionMatrix1);
          uniformBuffer.setSubData(offset, modelViewProjectionMatrix2);
          ...
        }
      

      updateTransformationMatrix函數(shù)更新兩個(gè)mvp矩陣;
      調(diào)用兩次setSubData,分別將更新后的mvp矩陣數(shù)據(jù)更新到同一個(gè)uniform buffer中。

      draw兩次,分別設(shè)置對(duì)應(yīng)的uniformBindGroup

      代碼如下:

        return function frame() {
          ...
          const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
          ...
      
          passEncoder.setBindGroup(0, uniformBindGroup1);
          passEncoder.draw(36, 1, 0, 0);
      
          passEncoder.setBindGroup(0, uniformBindGroup2);
          passEncoder.draw(36, 1, 0, 0);
      
          passEncoder.endPass();
      
          ...
        }
      

      第一次draw,繪制第一個(gè)cube,設(shè)置對(duì)應(yīng)的uniformBindGroup1;
      第二次draw,繪制第二個(gè)cube,設(shè)置對(duì)應(yīng)的uniformBindGroup2。

      最終渲染結(jié)果

      截屏2019-12-22下午4.18.16.png-55kB

      學(xué)習(xí)instancedCube.ts

      該示例使用instance技術(shù),通過一次draw,繪制了多個(gè)立方體實(shí)例。

      與“rotatingCube”示例相比,該示例增加了以下的內(nèi)容:

      • 一個(gè)ubo保存所有立方體實(shí)例的mvp矩陣
      • 每幀更新所有立方體實(shí)例的mvp矩陣數(shù)據(jù)
      • 指定實(shí)例個(gè)數(shù),draw一次

      下面,我們打開instancedCube.ts文件,依次來看下新增內(nèi)容:

      一個(gè)ubo保存所有立方體實(shí)例的mvp矩陣

      • vertex shader定義uniform block

      代碼如下:

        const vertexShaderGLSL = `#version 450
        //總共16個(gè)實(shí)例
        #define MAX_NUM_INSTANCES 16
        layout(set = 0, binding = 0) uniform Uniforms {
          //ubo包含mvp矩陣數(shù)組,數(shù)組長度為16
          mat4 modelViewProjectionMatrix[MAX_NUM_INSTANCES];
        } uniforms;
        layout(location = 0) in vec4 position;
        layout(location = 1) in vec4 color;
        ...
        void main() {
          //使用gl_InstanceIndex取到當(dāng)前實(shí)例的序號(hào)(0-15),通過它獲取對(duì)應(yīng)的mvp矩陣
          gl_Position = uniforms.modelViewProjectionMatrix[gl_InstanceIndex] * position;
          ...
        }`;
      
      • 創(chuàng)建uniform buffer

      代碼如下:

        //16個(gè)立方體的排列順序是x方向4個(gè)、y方向4個(gè)
        const xCount = 4;
        const yCount = 4;
        const numInstances = xCount * yCount;
        const matrixFloatCount = 16;
        // BYTES_PER_ELEMENT(4) * matrix length(4 * 4 = 16)
        const matrixSize = 4 * matrixFloatCount;
        const uniformBufferSize = numInstances * matrixSize;
      
        const uniformBuffer = device.createBuffer({
          size: uniformBufferSize,
          usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
        });
      

      這里與twoCubes不同的是,不同實(shí)例的mvp矩陣的數(shù)據(jù)是連續(xù)存放的,所以u(píng)niform buffer的size為numInstances(16個(gè))* matrixSize。

      • 創(chuàng)建uniform bind group

      只創(chuàng)建一個(gè):

        const uniformBindGroup = device.createBindGroup({
          layout: uniformsBindGroupLayout,
          bindings: [{
            binding: 0,
            resource: {
              buffer: uniformBuffer,
            }
          }],
        });
      
      • 準(zhǔn)備mvp矩陣數(shù)據(jù)

      代碼如下:

        //因?yàn)槭枪潭ㄏ鄼C(jī),所以只需要計(jì)算一次projection矩陣
        const aspect = Math.abs(canvas.width / canvas.height);
        let projectionMatrix = mat4.create();
        mat4.perspective(projectionMatrix, (2 * Math.PI) / 5, aspect, 1, 100.0);
        ...
        
        
        
        let modelMatrices = new Array(numInstances);
        //mvpMatricesData用來依次存放所有立方體實(shí)例的mvp矩陣數(shù)據(jù)
        let mvpMatricesData = new Float32Array(matrixFloatCount * numInstances);
      
        let step = 4.0;
      
        let m = 0;
        //準(zhǔn)備modelMatrices數(shù)據(jù)
        for (let x = 0; x < xCount; x++) {
          for (let y = 0; y < yCount; y++) {
            modelMatrices[m] = mat4.create();
            mat4.translate(modelMatrices[m], modelMatrices[m], vec3.fromValues(
              step * (x - xCount / 2 + 0.5),
              step * (y - yCount / 2 + 0.5),
              0
            ));
            m++;
          }
        }
      
        //因?yàn)槭枪潭ㄏ鄼C(jī),所以只需要計(jì)算一次view矩陣
        let viewMatrix = mat4.create();
        mat4.translate(viewMatrix, viewMatrix, vec3.fromValues(0, 0, -12));
      
        let tmpMat4 = mat4.create();
      

      每幀更新所有立方體實(shí)例的mvp矩陣數(shù)據(jù)

      相關(guān)代碼如下所示:

        function updateTransformationMatrix() {
      
          let now = Date.now() / 1000;
      
          let m = 0, i = 0;
          for (let x = 0; x < xCount; x++) {
            for (let y = 0; y < yCount; y++) {
              mat4.rotate(tmpMat4, modelMatrices[i], 1, vec3.fromValues(Math.sin((x + 0.5) * now), Math.cos((y + 0.5) * now), 0));
      
              mat4.multiply(tmpMat4, viewMatrix, tmpMat4);
              mat4.multiply(tmpMat4, projectionMatrix, tmpMat4);
      
              mvpMatricesData.set(tmpMat4, m);
      
              i++;
              m += matrixFloatCount;
            }
          }
        }
      
        return function frame() {
          updateTransformationMatrix();
          ...
          uniformBuffer.setSubData(0, mvpMatricesData);
          ...
        }
      

      updateTransformationMatrix函數(shù)更新mvpMatricesData;
      調(diào)用一次setSubData,將更新后的mvpMatricesData設(shè)置到uniform buffer中。

      指定實(shí)例個(gè)數(shù),draw一次

      代碼如下:

        return function frame() {
          ...
          const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
          ...
      
      
          //設(shè)置對(duì)應(yīng)的uniformBindGroup
          passEncoder.setBindGroup(0, uniformBindGroup);
          //指定實(shí)例個(gè)數(shù)為numInstances
          passEncoder.draw(36, numInstances, 0, 0);
          ...
        }
      

      最終渲染結(jié)果

      截屏2019-12-22下午4.18.23.png-143.2kB

      參考資料

      WebGPU規(guī)范
      webgpu-samplers Github Repo

      posted @ 2019-12-22 20:52  楊元超  閱讀(603)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 久久精品国产再热青青青| 精品无码老熟妇magnet| 久久久久成人精品无码中文字幕| 97人人模人人爽人人少妇| 日韩中文字幕有码午夜美女| 精品国产成人国产在线观看 | 国产精品二区中文字幕| 无码一区中文字幕| 天堂在线www天堂中文在线 | 在线视频一区二区三区色| 最新国产精品中文字幕| 无码人妻丰满熟妇区五十路在线| 国产福利深夜在线播放| 亚洲AV无码东方伊甸园| 亚洲人成色99999在线观看| 马尔康县| 狠狠亚洲色一日本高清色| 国产精品免费中文字幕| 四虎国产精品永久免费网址| 国产在线无遮挡免费观看| 蜜臀av人妻国产精品建身房| 麻豆一区二区三区精品蜜桃| 久久综合97丁香色香蕉| 国产小受被做到哭咬床单GV| 亚洲综合色网一区二区三区| 99热成人精品热久久66| 久热这里有精品免费视频| 麻豆国产传媒精品视频| 国产中文字幕一区二区| 亚洲乱码一二三四区国产| 人妻无码av中文系列久| 日本一区二区三区在线播放| 无码乱人伦一区二区亚洲一 | 激情五月开心婷婷深爱| 成 人免费va视频| 国产成人亚洲一区二区三区| 最新国产在线拍揄自揄视频| 国产精品国产三级国产专业| 精品国产高清中文字幕| 乱妇乱女熟妇熟女网站| 亚洲精品综合网二三区|