gpt4 book ai didi

javascript - WebGL 绘制循环和翻译

转载 作者:行者123 更新时间:2023-12-03 11:33:08 28 4
gpt4 key购买 nike

我希望我的 javascript 程序将三 Angular 形向右移动。我现在关注的是矩阵和绘制循环。我从来没有做过这样的事情,所以我可能偏离了道路,但出于学习目的,我正在尝试做的是:

-设置 webgl 管道,以便我正确显示三 Angular 形(确定)

-编写一个带有矩阵的函数,允许我传入翻译值(看起来不错,但我不确定)

var translation_prototype = [1,0,0,0,
0,1,0,0,
0,0,1,0,
tx,ty,0,1];

暂时忽略旋转、缩放和模型 View ,因为我对 webgl 提供的正交 View 非常满意(只是为了练习)。

-设置一个循环遍历drawArrays的循环(即使在这里我也不确定循环是否在正确的位置开始和结束)

我怀疑我真的很接近,但三 Angular 形没有移动(tx 保持不变)。

这是代码(我想我什至不需要清除颜色和深度缓冲区,因为我只在 x 轴上平移)

    <!DOCTYPE HTML>
<html>
<canvas id = "can" width="400" height="400">
</canvas>

<script>
var webgl_canvas = document.getElementById('can');
var gl = webgl_canvas.getContext('experimental-webgl');
var triangles = [-0.8,-0.8,0,0.8,-0.8,0,0,0.8,0];
var vertexBuffer = gl.createBuffer();
var tx = 0.1;
var ty = 0;
var translation_prototype = [1,0,0,0,
0,1,0,0,
0,0,1,0,
tx,ty,0,1];

var vertexShader_source = 'attribute vec3 a_position;' + 'uniform vec4 u_translation;' + 'void main() { gl_Position = u_translation * vec4 (a_position,1);}';
var fragmentShader_source = 'precision mediump float;' + 'void main() { gl_FragColor = vec4 (0.9,0,0.1,1); }';

function getTimeInSeconds () {
return Date.now() * 0.001;
}

function makeTranslation (tx, ty) {
return translation_prototype;
}

//Compile shaders
var buildShader = function (shaderSource, typeOfShader) {
var shader = gl.createShader(typeOfShader);
gl.shaderSource(shader, shaderSource);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert (gl.getShaderInfoLog(shader));
}
return shader;
}

var compiledVertexShader = buildShader (vertexShader_source, gl.VERTEX_SHADER);
var compiledFragmentShader = buildShader (fragmentShader_source, gl.FRAGMENT_SHADER);

//setup GLSL program
program = gl.createProgram();
gl.attachShader(program,compiledVertexShader);
gl.attachShader(program,compiledFragmentShader);
gl.linkProgram(program);

//Fill the buffer with vertex data

gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(triangles), gl.STATIC_DRAW);
vertexBuffer.itemSize = 3;
vertexBuffer.numItems = 3;

gl.clear(gl.COLOR_BUFFER_BIT);
var positionLocation = gl.getAttribLocation(program,"a_position");
gl.enableVertexAttribArray(positionLocation);
gl.useProgram(program);
var shaderTranlsationMatrix = gl.getUniformLocation(program, "u_translation");
gl.uniformMatrix4fv(shaderTranlsationMatrix,false,new Float32Array(translation_prototype));
gl.vertexAttribPointer(positionLocation, vertexBuffer.itemSize, gl.FLOAT, false, 0, 0);

var startTime = 0;
function animate (time) {
//Draw loop
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
var deltaTime = (time - startTime);
makeTranslation((tx*deltaTime),(ty*deltaTime));
console.log(tx,ty,deltaTime);

gl.drawArrays (gl.TRIANGLES, 0, vertexBuffer.numItems);
startTime = time;

window.requestAnimationFrame(animate);
}

animate(0);
</script>
</html>

<!-- start last edited snippet -->


<!DOCTYPE HTML>
<html>

<canvas id = "can" width="400" height="400">

</canvas>


<script>
var webgl_canvas = document.getElementById('can');
var gl = webgl_canvas.getContext('experimental-webgl');

var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array([-1,-1,0,1,-1,0,0,1,0]), gl.STATIC_DRAW);

vertexBuffer.itemSize = 3;
vertexBuffer.numItems = 3;

var identityMatrix = [1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1];

function translation (tx,ty,tz) {
return [1,0,0,0,
0,1,0,0,
0,0,1,0,
tx,ty,tz,1]
}


var vertexShader_source = 'attribute vec3 a_position;' + 'uniform mat4 u_move;' + 'void main() { gl_Position = u_move * vec4 (a_position,1); }';
var fragmentShader_source = 'precision mediump float;' + 'void main() { gl_FragColor = vec4 (0.9,0,0.1,1); }';







//Compile shaders
var buildShader = function (shaderSource, typeOfShader) {
var shader = gl.createShader(typeOfShader);
gl.shaderSource(shader, shaderSource);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert (gl.getShaderInfoLog(shader));
}
return shader;
}

var compiledVertexShader = buildShader (vertexShader_source, gl.VERTEX_SHADER);
var compiledFragmentShader = buildShader (fragmentShader_source, gl.FRAGMENT_SHADER);

//setup GLSL program
program = gl.createProgram();
gl.attachShader(program,compiledVertexShader);
gl.attachShader(program,compiledFragmentShader);
gl.linkProgram(program);



var positionLocation = gl.getAttribLocation(program,"a_position");
gl.enableVertexAttribArray(positionLocation);
gl.useProgram(program);


var tx = 0, ty = 0, tz = 0;
var translate = gl.getUniformLocation (program, "u_move");
gl.uniformMatrix4fv(translate,false,new Float32Array(identityMatrix));
gl.vertexAttribPointer(positionLocation, vertexBuffer.itemSize, gl.FLOAT, false, 0, 0);

//Draw
var start_time =0;
var animate=function(time) {
var dt= time-start_time;
tx+=0.5;
translation((dt*tx),0,0);
console.log(dt);
console.log(tx);
start_time=time;
gl.drawArrays (gl.TRIANGLES, 0, vertexBuffer.numItems);
window.requestAnimationFrame(animate);
}
animate(0);
</script>

</html>

<!-- end last edited snippet -->

最佳答案

这是工作片段

<强> JSFIDDLE

您的顶点着色器应如下所示:

attribute vec3 a_position;' + 'uniform mat4 u_translation;' + 'void main() { gl_Position = u_translation*vec4 (a_position,1);}
  • 为了使物体在空间中移动,您必须将所有向量和矩阵与位置向量相乘才能得到结果。 Tranlation Wiki

您必须在每个循环周期更新您的 translation_prototype 变量:

    deltaTime += 0.005;
makeTranslation(tx+deltaTime,ty+deltaTime);
  • deltaTime 在循环外部声明并在每个周期递增

此外,您的 makeTranslation 函数应如下所示:

function makeTranslation (x, y) {
translation_prototype =
[1,0,0,0,
0,1,0,0,
0,0,1,0,
x,y,0,1]
return translation_prototype;
}
  • (如果使用全局变量,则可以去掉 return 语句,但建议使用局部变量)

(我必须尝试这个新的代码片段功能:D)

 var webgl_canvas = document.getElementById('can');
var gl = webgl_canvas.getContext('experimental-webgl');
var triangles = [-0.5,-0.5,0,0.5,-0.5,0,0,0.5,0];
var vertexBuffer = gl.createBuffer();
var tx = 0;
var ty = 0;
var translation_prototype = [1,0,0,0,
- 0,1,0,0,
0,0,1,0,
0,0,0,1];

var vertexShader_source = 'attribute vec3 a_position;' + 'uniform mat4 u_translation;' + 'void main() { gl_Position = u_translation*vec4 (a_position,1);}';
var fragmentShader_source = 'precision mediump float;' + 'void main() { gl_FragColor = vec4 (0.9,0,0.1,1); }';



function getTimeInSeconds () {
return Date.now() * 0.001;
}

function makeTranslation (x, y) {
translation_prototype =
[1,0,0,0,
0,1,0,0,
0,0,1,0,
x,y,0,1]
return translation_prototype;
}


//Compile shaders
var buildShader = function (shaderSource, typeOfShader) {
var shader = gl.createShader(typeOfShader);
gl.shaderSource(shader, shaderSource);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert (gl.getShaderInfoLog(shader));
}
return shader;
}

var compiledVertexShader = buildShader (vertexShader_source, gl.VERTEX_SHADER);
var compiledFragmentShader = buildShader (fragmentShader_source, gl.FRAGMENT_SHADER);

//setup GLSL program
program = gl.createProgram();
gl.attachShader(program,compiledVertexShader);
gl.attachShader(program,compiledFragmentShader);
gl.linkProgram(program);

//Fill the buffer with vertex data

gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(triangles), gl.STATIC_DRAW);
vertexBuffer.itemSize = 3;
vertexBuffer.numItems = 3;


gl.clear(gl.COLOR_BUFFER_BIT);
var positionLocation = gl.getAttribLocation(program,"a_position");
gl.enableVertexAttribArray(positionLocation);
gl.useProgram(program);
var shaderTranlsationMatrix = gl.getUniformLocation(program, "u_translation");
gl.uniformMatrix4fv(shaderTranlsationMatrix,false,new Float32Array(translation_prototype));
gl.vertexAttribPointer(positionLocation, vertexBuffer.itemSize, gl.FLOAT, false, 0, 0);

var startTime = 0;
var deltaTime = 0;
function animate (time) {

//Draw loop
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
deltaTime += 0.005;
makeTranslation(tx+deltaTime,ty+deltaTime);

gl.useProgram(program);
var shaderTranlsationMatrix = gl.getUniformLocation(program, "u_translation");
gl.uniformMatrix4fv(shaderTranlsationMatrix,false,new Float32Array(translation_prototype));
gl.vertexAttribPointer(positionLocation, vertexBuffer.itemSize, gl.FLOAT, false, 0, 0);

gl.drawArrays (gl.TRIANGLES, 0, vertexBuffer.numItems);
startTime = time;

window.requestAnimationFrame(animate);
}

animate(0);
<canvas id = "can" width="300" height="300">

</canvas>

关于javascript - WebGL 绘制循环和翻译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26653198/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com