이전에 vertex 값에 삼각형을 넣고 이동하는 실습까지 했었다.
큐브는 z값을 다르게 두고 각 면들을 표현해주어야 한다.
drawArray
를 사용하면 총 32개의 vertex를 모두 설정해주어야 하지만,
drawElements
를 사용하면 총 8개의 vertex 만으로도 큐브를 만들 수 있다.
대신 추가로 index array를 사용해서 각 면에 필요한 vertex들을 연결해주어야 한다.
drawElements를 사용할 때, vertexbuffer 값으로 색상 값을 같이 넣어주게되면 그라데이션을 가진 큐브가 만들어진다.
그러나 나는 각 면마다 단색인 큐브를 그려주고 싶었기 때문에 결국 32개의 vertex를 주고, color 값을 일일이 주었다.
v_Color=a_Color; // in vs
gl_FragColor =v_Color; // in fs
Primitive 삼각형을 12개 그려 큐브를 그려줄 수 있다.
=> 삼각형 1개= vertex 3개 이므로, 총 36개의 vertex에 대하여 drawElements
를 해주면 된다.
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); // VS에 vertexBuffer 배열 값을 넘겨준다.
gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, 4 * 3, 0);
// 위치 값으로 쓸 값이 어디에 있는지 알려준다. (vector3 값을 주었으므로 float*3 만큼씩 읽어온다)
gl.enableVertexAttribArray(a_Position); // a_Position 값을 attribute로 배열 값을 가져오게 열어준다
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); // color에 대해서도 VS에 값을 넘겨준다.
gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, 4 * 4, 0); //color는 vercor4 값
gl.enableVertexAttribArray(a_Color);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
// vertex값에 따라, 어떤 vertex로 각 면을 만들것인지를 indexbuffer에 담아 VS에 전달한다.
gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);
//index, vertex,color 값을 참고하여 36개의 점으로 삼각형을 그린다.
이대로는 회전이 없어서 큐브가 만들어진건지, 한 면만 그려진 것인지 확인할 수 없다
requestAnimationFrame
을 사용해서 tick 애니메이션을 만들어주었다.
cuon-matrix.js
에 있는 Matrix4.rotate
함수를 사용해서 (1,1,1)만큼 회전하는 애니메이션을 만들었다
var tick = function () {
WorldMatrix.rotate(1, 1, 1, 1); //(1,1,1)씩 회전
draw(gl, vertexBuffer); //그려주기
requestAnimationFrame(tick); //frame마다 tick 실행해서 rotate하게하기
};
모든 면이 제대로 그려진 것을 확인할 수 있다.
가장 단순한 drawElements
를 해보자
const vertices = [
-1.0,-1.0,1.0, 1.0,1.0,1.0, // BLACK
1.0,-1.0,1.0, 1.0,0.0,0.0, //RED
1.0,1.0,1.0, 0.0,1.0,0.0, //GREEN
-1.0,1.0,1.0, 0.0,0.0,1.0, //BLUE
-1.0,-1.0,-1.0, 1.0,1.0,0.0, //YELLOW
1.0,-1.0,-1.0, 0.0,1.0,1.0, //CYAN
1.0,1.0,-1.0, 1.0,0.0,1.0, //MAGENTA
-1.0,1.0,-1.0, 0.0,0.0,0.0 //WHITE
]
const indices = [
0, 1, 2, 0, 2, 3, // front
4, 5, 6, 4, 6, 7, // back
3, 2, 6, 3, 6, 7, // top
0, 1, 5, 0, 5, 4, // bottom
1, 5, 6, 1, 6, 2, // right
4, 0, 3, 4, 3, 7, // left
];
만약 colors 배열을 만들어 따로 연결해주고그린다면 각 면마다 단색으로 그리기도 가능하다.
큐브 그리기
https://runebook.dev/ko/docs/dom/webgl_api/tutorial/creating_3d_objects_using_webgl