javascript - Implementing perspective matrix in webgl -
i have little code spins triangle @ world origin (0,0,0) along y axis.
<!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 width = gl.width; var vertices = [-1,-1,0,1,-1,0,0,1,0]; var vertexbuffer = gl.createbuffer(); gl.bindbuffer(gl.array_buffer, vertexbuffer); gl.bufferdata(gl.array_buffer,new float32array(vertices), gl.static_draw); vertexbuffer.itemsize = 3; vertexbuffer.numitems = parseint(vertices.length/vertexbuffer.itemsize); var tx = 0, ty = 0, tz = 0; var degrees = 0.1; function roty (degrees) { m = identitymatrix; var c = math.cos(degrees); var s = math.sin(degrees); var mv0=m[0], mv4=m[4], mv8=m[8]; m[0]=c*m[0]+s*m[2]; m[4]=c*m[4]+s*m[6]; m[8]=c*m[8]+s*m[10]; m[2]=c*m[2]-s*mv0; m[6]=c*m[6]-s*mv4; m[10]=c*m[10]-s*mv8; } var identitymatrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]; var translationmatrix = [1,0,0,tx, 0,1,0,ty, 0,0,1,tz, 0,0,0,1]; function degtoradians(deg){ homecoming (deg*math.pi/180); } function translation(x) { m = identitymatrix; homecoming m[12] += x; } 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)); } homecoming shader; } var compiledvertexshader = buildshader (vertexshader_source, gl.vertex_shader); var compiledfragmentshader = buildshader (fragmentshader_source, gl.fragment_shader); //setup glsl programme 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 translate = gl.getuniformlocation (program, "u_move"); //draw var start_time =0; var animate=function(time) { var dt= time-start_time; var matrix = roty(degrees); gl.uniformmatrix4fv(translate,false,new float32array(identitymatrix)); gl.vertexattribpointer(positionlocation, vertexbuffer.itemsize, gl.float, false, 0, 0); gl.bindbuffer(gl.array_buffer, vertexbuffer); //console.log(dt); start_time=time; gl.drawarrays (gl.triangles, 0, vertexbuffer.numitems); window.requestanimationframe(animate); } animate(0); </script> </html>
now, i've added rotation function
function roty (degrees) { m = identitymatrix; console.log(identitymatrix); var c = math.cos(degrees); var s = math.sin(degrees); var mv0=m[0], mv4=m[4], mv8=m[8]; m[0]=c*m[0]+s*m[2]; m[4]=c*m[4]+s*m[6]; m[8]=c*m[8]+s*m[10]; m[2]=c*m[2]-s*mv0; m[6]=c*m[6]-s*mv4; m[10]=c*m[10]-s*mv8; }
linked uniform
var perspective_matrix = gl.getuniformlocation (program, "u_perspective");
and enabled
gl.uniformmatrix4fv(perspective_matrix,false, perspmatrix);
the triangle has disappeared. checking console matrix value returns undefined suspect i've wrong there, though i'm not seeing where. total code follows
<!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'); webgl_canvas.width=window.innerwidth; webgl_canvas.height=window.innerheight; var width = gl.width; var vertices = [-1,-1,0,1,-1,0,0,1,0]; var vertexbuffer = gl.createbuffer(); gl.bindbuffer(gl.array_buffer, vertexbuffer); gl.bufferdata(gl.array_buffer,new float32array(vertices), gl.static_draw); vertexbuffer.itemsize = 3; vertexbuffer.numitems = parseint(vertices.length/vertexbuffer.itemsize); var tx = 0, ty = 0, tz = 0; var degrees = 0.1; var identitymatrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]; function perspective(angle,aspect,zmin,zmax){ var tan = math.tan(degtoradians(0.5*angle)), =-(zmax+zmin)/(zmax-zmin), b = (-2*zmax*zmin)/(zmax-zmin); homecoming [ .5/tan,0,0,0, 0, .5*aspect/tan, 0, 0, 0,0,a,-1, 0,0,b,0 ]; } function rotx (degrees) { m = identitymatrix; var c = math.cos(degrees); var s = math.sin(degrees); var mv1=m[1], mv5=m[5], mv9=m[9]; m[1]=m[1]*c-m[2]*s; m[5]=m[5]*c-m[6]*s; m[9]=m[9]*c-m[10]*s; m[2]=m[2]*c+mv1*s; m[6]=m[6]*c+mv5*s; m[10]=m[10]*c+mv9*s; } function roty (degrees) { m = identitymatrix; console.log(identitymatrix); var c = math.cos(degrees); var s = math.sin(degrees); var mv0=m[0], mv4=m[4], mv8=m[8]; m[0]=c*m[0]+s*m[2]; m[4]=c*m[4]+s*m[6]; m[8]=c*m[8]+s*m[10]; m[2]=c*m[2]-s*mv0; m[6]=c*m[6]-s*mv4; m[10]=c*m[10]-s*mv8; } var translationmatrix = [1,0,0,tx, 0,1,0,ty, 0,0,1,tz, 0,0,0,1]; function degtoradians(deg){ homecoming (deg*math.pi/180); } function translation(x) { m = identitymatrix; homecoming m[12] += x; } var vertexshader_source = 'attribute vec3 a_position;' + 'uniform mat4 u_move;' + 'uniform mat4 u_perspective;' + 'void main() { gl_position = u_perspective * 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)); } homecoming shader; } var compiledvertexshader = buildshader (vertexshader_source, gl.vertex_shader); var compiledfragmentshader = buildshader (fragmentshader_source, gl.fragment_shader); //setup glsl programme program = gl.createprogram(); gl.attachshader(program,compiledvertexshader); gl.attachshader(program,compiledfragmentshader); gl.linkprogram(program); //link javascript variables shaders uniforms var perspective_matrix = gl.getuniformlocation (program, "u_perspective"); var translate = gl.getuniformlocation (program, "u_move"); var positionlocation = gl.getattriblocation(program,"a_position"); gl.enablevertexattribarray(positionlocation); gl.useprogram(program); var perspmatrix = perspective(40,webgl_canvas.width/webgl_canvas.height,1,100); //draw var start_time =0; var animate=function(time) { var dt= time-start_time; var matrix = rotx(degrees); console.log(matrix); gl.uniformmatrix4fv(perspective_matrix,false, perspmatrix); gl.uniformmatrix4fv(translate,false,identitymatrix); gl.vertexattribpointer(positionlocation, vertexbuffer.itemsize, gl.float, false, 0, 0); gl.bindbuffer(gl.array_buffer, vertexbuffer); start_time=time; gl.drawarrays (gl.triangles, 0, vertexbuffer.numitems); window.requestanimationframe(animate); } animate(0); </script> </html>
this point out particular issues.
1) var identitymatrix = [ ... ]
create array. each time reference var m = identitymatrix;
not create new array points to original. when alter item in var m
alter same item in original identitymatrix
, , changes appear @ places whereever point in whole code.
make identitymatrix function returning array:
var identitymatrix = function() {return [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];}
and each time want start new identitymatrix do:
var m = identitymatrix(); // new matrices not affecting each other
the same may happen var vertices
or var translationmatrix
, leave check you.
2) function translation()
not homecoming matrix number (the 13th item of matrix). must be:
function translation(x) { var m = identitymatrix; // don't miss var keyword m[12] += x; // alter value @ index 12 homecoming m; // homecoming whole matrix }
3) both rotate
-functions doesn't homecoming anything. there should return m;
inside.
javascript webgl
No comments:
Post a Comment