第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

WebGL:使用不同的程序渲染大量對(duì)象

WebGL:使用不同的程序渲染大量對(duì)象

慕妹3242003 2022-07-08 17:43:50
我現(xiàn)在正在學(xué)習(xí) WebGL。我用 10 個(gè)三角形制作了一個(gè)簡(jiǎn)單的場(chǎng)景,當(dāng)我將三角形數(shù)量增加到 1000 個(gè)時(shí),場(chǎng)景開始凍結(jié)。我使用 3 個(gè)著色器和 2 個(gè)程序(用于模擬真實(shí)環(huán)境)。我知道我應(yīng)該從渲染循環(huán)體中取出一些東西,但我不知道是什么。我的代碼如下:function render() {  requestAnimationFrame(render);  context.clear(context.COLOR_BUFFER_BIT);  for (let i = 0; i < 10; i++) {    const currentProgram = i % 2 === 0 ? blueProgram : redProgram;    context.useProgram(currentProgram);    const a_Position = context.getAttribLocation(currentProgram, "a_Position");    const triangleGeometry = getTriangleGeometry(); // returns Float32Array filled with randoms    const buffer = context.createBuffer();    context.bindBuffer(context.ARRAY_BUFFER, buffer);    context.bufferData(context.ARRAY_BUFFER, triangleGeometry, context.STATIC_DRAW);    context.enableVertexAttribArray(a_Position);    context.vertexAttribPointer(      a_Position,      2,      context.FLOAT,      false,      0,      0,    );    context.drawArrays(context.TRIANGLES, 0, 3);  }}requestAnimationFrame(render);任何想法我可以為性能優(yōu)化做些什么?
查看完整描述

1 回答

?
慕無(wú)忌1623718

TA貢獻(xiàn)1744條經(jīng)驗(yàn) 獲得超4個(gè)贊

有很多方法可以優(yōu)化繪制很多東西,但由于 yoi 剛剛開始,最重要的是通常設(shè)置緩沖區(qū)應(yīng)該發(fā)生在初始化時(shí)間,而不是渲染時(shí)間。

請(qǐng)參閱在 WebGL 中繪制多個(gè)模型

問題中的代碼是查找每個(gè)三角形的位置。它應(yīng)該將位置查找為初始時(shí)間。

該代碼還為每個(gè)三角形創(chuàng)建一個(gè)新緩沖區(qū)。創(chuàng)建一個(gè)緩沖區(qū)并使用新三角形更新它會(huì)更快,當(dāng)然最終它會(huì)耗盡內(nèi)存來(lái)創(chuàng)建新緩沖區(qū)。

const context = document.querySelector('canvas').getContext('webgl');


const vs = `

attribute vec4 a_Position;

void main() {

  gl_Position = a_Position;

}

`;


const redFS = `

precision highp float;

void main() {

  gl_FragColor = vec4(1, 0, 0, 1);

}

`;


const blueFS = `

precision highp float;

void main() {

  gl_FragColor = vec4(0, 0, 1, 1);

}

`;


const blueProgram = twgl.createProgram(context, [vs, blueFS]);

const blueProgramInfo = {

  program: blueProgram,

  a_PositionLocation: context.getAttribLocation(blueProgram, "a_Position"),

};


const redProgram = twgl.createProgram(context, [vs, redFS]);

const redProgramInfo = {

  program: redProgram,

  a_PositionLocation: context.getAttribLocation(redProgram, "a_Position"),

};


const buffer = context.createBuffer();


function rand(min, max) {

  return Math.random() * (max - min) + min;

}


// pre allocate

const triangleData = new Float32Array(6);  // 3 vertices, 2 values per


function getTriangleGeometry() {

  const x = rand(-1, 1);

  const y = rand(-1, 1);

  triangleData[0] = x; 

  triangleData[1] = y;

  triangleData[2] = x + rand(-0.1, 0.1);

  triangleData[3] = y + rand(-0.1, 0.1);

  triangleData[4] = x + rand(-0.1, 0.1);

  triangleData[5] = y + rand(-0.1, 0.1);

  return triangleData;

}


function render() {

  context.clear(context.COLOR_BUFFER_BIT);


  for (let i = 0; i < 100; i++) {

    const currentProgramInfo = i % 2 === 0 ? blueProgramInfo : redProgramInfo;

    context.useProgram(currentProgramInfo.program);


    const a_Position = currentProgramInfo.a_PositionLocation;


    const triangleGeometry = getTriangleGeometry(); // returns Float32Array filled with randoms


    context.bindBuffer(context.ARRAY_BUFFER, buffer);

    context.bufferData(context.ARRAY_BUFFER, triangleGeometry, context.STATIC_DRAW);

    context.enableVertexAttribArray(a_Position);

    context.vertexAttribPointer(

      a_Position,

      2,

      context.FLOAT,

      false,

      0,

      0,

    );


    context.drawArrays(context.TRIANGLES, 0, 3);

  }

  requestAnimationFrame(render);

}


requestAnimationFrame(render);

<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>

<canvas></canvas>

問題中的代碼似乎使用了 2 個(gè)程序,一個(gè)繪制藍(lán)色,一個(gè)繪制紅色。讓一個(gè)帶有制服的程序來(lái)選擇顏色可能會(huì)更快。

const context = document.querySelector('canvas').getContext('webgl');


const vs = `

attribute vec4 a_Position;

void main() {

  gl_Position = a_Position;

}

`;


const fs = `

precision highp float;

uniform vec4 u_Color;

void main() {

  gl_FragColor = u_Color;

}

`;



const program = twgl.createProgram(context, [vs, fs]);

const programInfo = {

  program: program,

  a_PositionLocation: context.getAttribLocation(program, "a_Position"),

  u_ColorLocation: context.getUniformLocation(program, "u_Color"),

};


const buffer = context.createBuffer();


function rand(min, max) {

  return Math.random() * (max - min) + min;

}


// pre allocate

const triangleData = new Float32Array(6);  // 3 vertices, 2 values per


function getTriangleGeometry() {

  const x = rand(-1, 1);

  const y = rand(-1, 1);

  triangleData[0] = x; 

  triangleData[1] = y;

  triangleData[2] = x + rand(-0.1, 0.1);

  triangleData[3] = y + rand(-0.1, 0.1);

  triangleData[4] = x + rand(-0.1, 0.1);

  triangleData[5] = y + rand(-0.1, 0.1);

  return triangleData;

}


const blue = [0, 0, 1, 1];

const red = [1, 0, 0, 1];


function render() {

  context.clear(context.COLOR_BUFFER_BIT);


  context.useProgram(programInfo.program);

  

  const a_Position = programInfo.a_PositionLocation;

  context.bindBuffer(context.ARRAY_BUFFER, buffer);

  context.enableVertexAttribArray(a_Position);

  context.vertexAttribPointer(

    a_Position,

    2,

    context.FLOAT,

    false,

    0,

    0,

  );


  for (let i = 0; i < 100; i++) {

    const color = i % 2 === 0 ? blue : red;

    context.uniform4fv(programInfo.u_ColorLocation, color);

   

    const triangleGeometry = getTriangleGeometry(); // returns Float32Array filled with randoms

    context.bufferData(context.ARRAY_BUFFER, triangleGeometry, context.STATIC_DRAW);


    context.drawArrays(context.TRIANGLES, 0, 3);

  }

  requestAnimationFrame(render);

}


requestAnimationFrame(render);

<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>

<canvas></canvas>

如果在初始化時(shí)將所有三角形放在一個(gè)緩沖區(qū)中,并且在初始化時(shí)將每個(gè)三角形的頂點(diǎn)顏色放在緩沖區(qū)中,然后在渲染時(shí)使用單個(gè)繪制調(diào)用繪制它們,速度會(huì)明顯更快。如果您想要每幀隨機(jī)三角形,那么在初始化時(shí)創(chuàng)建一個(gè)緩沖區(qū),在單個(gè)緩沖區(qū)中填充 N 個(gè)隨機(jī)三角形,然后在一次繪制調(diào)用中將它們?nèi)坷L制出來(lái),仍然會(huì)更快。

const context = document.querySelector('canvas').getContext('webgl');


const vs = `

attribute vec4 a_Position;

attribute vec4 a_Color;


varying vec4 v_Color;


void main() {

  gl_Position = a_Position;

  v_Color = a_Color;

}

`;


const fs = `

precision highp float;

varying vec4 v_Color;

void main() {

  gl_FragColor = v_Color;

}

`;



const program = twgl.createProgram(context, [vs, fs]);

const programInfo = {

  program: program,

  a_PositionLocation: context.getAttribLocation(program, "a_Position"),

  a_ColorLocation: context.getAttribLocation(program, "a_Color"),

  u_ColorLocation: context.getUniformLocation(program, "u_Color"),

};


const positionBuffer = context.createBuffer();

const colorBuffer = context.createBuffer();


function rand(min, max) {

  return Math.random() * (max - min) + min;

}


const numTriangles = 1000;


const positionData = new Float32Array(numTriangles * 3 * 2);  

const colorData = new Float32Array(numTriangles * 3 * 4);


const blue = [0, 0, 1, 1];

const red = [1, 0, 0, 1];


// the color data does not change so fill it out at init time

for (let i = 0; i < numTriangles; ++i) {

  const offset = i * 4;

  colorData.set(i % 2 === 0 ? blue : red, offset);

}

context.bindBuffer(context.ARRAY_BUFFER, colorBuffer);

context.bufferData(context.ARRAY_BUFFER, colorData, context.STATIC_DRAW);


function getTriangleGeometry() {

  for (let i = 0; i < numTriangles; ++i) {

    const offset = i * 3 * 2;  // 3 verts per tri, 2 values per ver

    const x = rand(-1, 1);

    const y = rand(-1, 1);

    positionData[offset    ] = x; 

    positionData[offset + 1] = y;

    positionData[offset + 2] = x + rand(-0.1, 0.1);

    positionData[offset + 3] = y + rand(-0.1, 0.1);

    positionData[offset + 4] = x + rand(-0.1, 0.1);

    positionData[offset + 5] = y + rand(-0.1, 0.1);

  }

  return positionData;

}



function render() {

  context.clear(context.COLOR_BUFFER_BIT);


  context.useProgram(programInfo.program);

  

  const a_Position = programInfo.a_PositionLocation;

  context.bindBuffer(context.ARRAY_BUFFER, positionBuffer);

  const triangleGeometry = getTriangleGeometry(); // returns Float32Array filled with randoms

  context.bufferData(context.ARRAY_BUFFER, triangleGeometry, context.DYNAMIC_DRAW);

  context.enableVertexAttribArray(a_Position);

  context.vertexAttribPointer(

    a_Position,

    2,

    context.FLOAT,

    false,

    0,

    0,

  );

  

  const a_Color = programInfo.a_ColorLocation;

  context.bindBuffer(context.ARRAY_BUFFER, colorBuffer);

  context.enableVertexAttribArray(a_Color);

  context.vertexAttribPointer(

    a_Color,

    4,

    context.FLOAT,

    false,

    0,

    0,

  );


  context.drawArrays(context.TRIANGLES, 0, numTriangles * 3);

  requestAnimationFrame(render);

}


requestAnimationFrame(render);

<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>

<canvas></canvas>

像上面那樣在每一幀中繪制一堆隨機(jī)三角形可以說(shuō)是一個(gè)例外。大多數(shù) WebGL 應(yīng)用程序繪制在建模包中創(chuàng)建的 3D 模型,因此更常見的是在初始化時(shí)將數(shù)據(jù)放入緩沖區(qū)一次(如立方體、球體、汽車、人、樹的數(shù)據(jù)),然后在渲染時(shí)繪制它。

另請(qǐng)注意,GPU 只能繪制這么多像素,因此如果您的三角形很大(如整個(gè)屏幕的大?。?,您將只能繪制 10 到幾百個(gè))。1920x1080 的屏幕約為 2 百萬(wàn)像素。所以每個(gè)全屏三角形也將是大約 200 萬(wàn)像素。繪制其中的 1000 個(gè)是 2000 * 200 萬(wàn)或 40 億像素。每秒 60 幀 2400 億像素。中高端 GPU 每秒只能繪制 100 億幀,這是理論上的最大值,因此它最多只能以每秒 2 幀的速度進(jìn)行繪制。

大多數(shù) 3D 應(yīng)用程序繪制的場(chǎng)景中,大多數(shù)三角形都很遠(yuǎn)且很小。他們還使用深度緩沖區(qū)并從前到后繪制不透明對(duì)象,這樣后面的像素就不會(huì)被繪制。


查看完整回答
反對(duì) 回復(fù) 2022-07-08
  • 1 回答
  • 0 關(guān)注
  • 115 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)