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