Tuesday, 15 September 2015

javascript - Implementing perspective matrix in webgl -



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