2014-11-02 4 views
0

y 축을 따라 세계 원점 (0,0,0)에 삼각형을 회전시키는이 작은 코드가 있습니다.Webgl에서 퍼스펙티브 매트릭스 구현

<!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){ 
    return (deg*MATH.PI/180); 
} 

function translation(x) { 
    m = identityMatrix; 
    return 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)); 
} 
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 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> 

는 지금, 나는 삼각형은 이제 사라졌다

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 perspective_matrix = gl.getUniformLocation (program, "u_perspective"); 

에 연결된 회전 기능을 추가

gl.uniformMatrix4fv(perspective_matrix,false, PERSPMATRIX); 

을 설정 한 . 콘솔을 확인하면 행렬 값이 정의되지 않은 값을 반환하므로 내가 정확히 어디에서 볼 수는 없지만 뭔가 잘못되었다고 생각됩니다. 전체 코드는 다음과 같습니다.

<!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)), 
    A =-(zMax+zMin)/(zMax-zMin), 
    B = (-2*zMax*zMin)/(zMax-zMin); 

    return [ .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){ 
    return (deg*Math.PI/180); 
} 

function translation(x) { 
    m = identityMatrix; 
    return 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)); 
} 
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); 

//link javascript variables with 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> 
+0

전체 코드를 세 번 게시 했습니까? ಠ_ಠ – Winchestro

+0

아니요, 매번 변경되었습니다. – Muteking

+0

오 오케이 * 당신의 * 전체 코드 * 버전 * – Winchestro

답변

1

이것은 특정 문제 만 지적합니다.

1) var identityMatrix = [ ... ]으로 배열을 만듭니다. var m = identityMatrix;으로 참조 할 때마다 은 새로운 배열을 만들지 않지만 항상 을 가리 킵니다. 이제 var m에서 항목을 변경하면 원래 identityMatrix에있는 동일한 항목이 변경되며 변경 사항은 전체 코드에서 모든 지점을 가리키게됩니다. 할 새 identityMatrix 시작하려는

var identityMatrix = function() {return [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];} 

때마다 :

가 identityMatrix 배열을 반환하는 함수를 확인

var m = identityMatrix(); // now you get new matrices not affecting each other 

이 같은이 var vertices 또는 var translationMatrix으로 발생할 수 있습니다, 나는 떠나 확인해.

2) 함수 translation()은 행렬을 반환하지 않고 숫자 만 반환합니다 (행렬의 13 번째 항목). 다음과 같아야합니다.

function translation(x) { 
    var m = identityMatrix; // don't miss the var keyword 
    m[12] += x; // change value at index 12 
    return m; // return the whole matrix 
} 

3) rotate 두 함수 모두 아무 것도 반환하지 않습니다. 내부에는 return m;이 있어야합니다.