WebGL Lesson 1 – A triangle and a square 에 대한 자습서 이고, 너무 길어서 나누어 올린다.
Lesson 2부터는 상당히 짧아질 것 같다. NeHe의 Article을 참고 하고 있다. Lesson 1의 소스는 GitHub에 있고, 라이브 데모는 여기. 이전 포스트에서 이어진다.

initShaers()를 보기전에

initShader()를 볼려면, getShadr()를 먼저 봐야 하고, getShader()가 호출하는 shader script(소스상단의 x-shader type의 script)를 먼저 알아야 하고, shader script를 알려면 그전에 shader를 알아야 한다.

Shader and GLSL
3D를 모르는 보통 개발자(?)의 언어로 포현하면... shader란 3D에서 인스턴스를 만들기 위한 class 소스이며, 화면에 뿌릴 객체 자체이기도 하다. shader를 정의하기 위한 전용 language가 있으며, OpenGL Shader를 위한 Shading Language를 GLSL(OpenGL Shading Language)라 한다.
shader를 이용하는 3D엔진은 SL소스를 문자열로 읽어들여서 엔진 내부에서 컴파일을 한다. 그리고 이렇게 컴파일해서 반환되는 shader객체를 이용해서 화면에 표시할 오브젝트들을 만든다. 이 과정은 엔진내부에서 돌아가는 과정을 설명하는게 아니라 '짜야' 한다. 이를 수행하는게 shader script, getShader(), initShaders()이다.

형태로서 GLSL
레슨에선 자바스크립트처럼 script element를 사용하여 정의하였지만, type이 x-shader/x-fragment와 x-shader/x-vertex인 스크립트 소스는 브라우저에서 인지하는 소스가 아니다. WebGL에서 사용하기 위해 GLSL소스를 자바스크립트와 구분하기 위해 적어놓은 String일 뿐이다. 사실 아래와 완전히 같다.


var shader-fs = "#ifdef GL_ES
    precision highp float;
    #endif

    void main(void) {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }";
var shader-vs = "attribute vec3 aVertexPosition;

    uniform mat4 uMVMatrix;
    uniform mat4 uPMatrix;

    void main(void) {
        gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
    }";
  
 

레슨의 소스에는 GLSL로 fragment shader와 vertex shader 두가지가 정의 되어있다.  GLSL단계에서 알아야 할 개념들을 정리해본다.

vertex shader
vertex는 도형의 꼭지점을 말한다. vertex shader는 이 꼭지점들을 관리하는 shader이다. (혹은 꼭지점으로만 이루어진 shader) vertex들의 위치, 색상, 사이즈, 꼭지점기반의 텍스처의 좌표, 광원 등을 관리한다. 그걸 관리하기 위한 인자와 메소드 등을 가지고 있는 GLSL로 된 vertex shader 소스가 아래의 레슨 소스이다.


<script id="shader-vs" type="x-shader/x-vertex">
    attribute vec3 aVertexPosition;

    uniform mat4 uMVMatrix;
    uniform mat4 uPMatrix;

    void main(void) {
        gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
    }
</script>



fragment shader
fragment를 우리말로 뭐라 불러야 할지 잘 모르겠지만, '면이 채워진 도형'이라 하자. vertex shader를 넘겨받아서 그 vertex기반으로 색상, 텍스처, 안개처리를 한다. vertex별로 색상이 있다면, 그 vertex들 사이 픽셀을 색으로 채워주고 광원이 있다면 텍스터에 광원효과를 반영한다. GLSL로 된 fragment shader 소스가 아래의 레슨 소스이다.


<script id="shader-fs" type="x-shader/x-fragment">
    #ifdef GL_ES
    precision highp float;
    #endif

    void main(void) {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
</script>


shader input/output type
위에서 shader는 GLSL로 되어있는 화면에 뿌리기위한 객체의 소스라고 이야기했다. GLSL에서는 이런 처리를 위해 3가지의 input/output 타입을 제공한다. attributes, uniforms, varyings 이다.

attributes
attributes는 vertex shader에만 있으며, vertex별로 달라지는 값을 관리한다. 좌표값, 색등이 여기에 해당한다. 이번 레슨에서는 좌표값인 aVertexPostion 만 정의하고 있다.

uniforms
uniforms은 vertex 별로 변경되지 않는 값이다. viewport의 위치, 광원의 위치등 fragement shader에서 렌더링을 할때 변경되지 않는 값을 의미한다. 이번 레슨에서는 그린 도형을 바라볼 위치와 관련된 uMVMatrix, uPMatrix만 정의하고 있다.

varyings
attributes와 uniforms는 shader별 input/output 값인 반면에, varyings은 vertex shader에서 fragment shader로 데이터를 보낼떄 사용한다. vertex shader에서 정의한 gl_Position은 fragment shader에서 사용된다. (소스상에는 없다. ) 이번 레슨에서는 두 shader에서 gl_Position, gl_FragColor가 varyings에 해당한다.
당연한 이야기지만 vertex shader에서 gl_Position varying은 필수 값이다. 꼭지점을 3D공간에 정의한 역활을 하는 shader에서 그 좌표값은 필수일 수 밖에.

정리해보면
vertex shader는 attribute인  aVertexPosition  와 uniform인 uMVMatrix, pMatrix 변수를 통해 javascript 에서 input을 받아서 gl_Position이라는 varying을 정의한다.
그리고 이 vertex shader를 이용하여 fragment shader에서 gl_FragColor 를 흰색으로 정의하고 vertex사이의 색을 칠한다.

다음은 진짜 getShader()와 initShader()

2011/04/21 02:46 2011/04/21 02:46
Trackback address :: http://zziuni.pe.kr/zziuni/trackback/562

Comments List

Write a comment.

[로그인][오픈아이디란?]