이전의 예제 004. WebGL - Prac03 - DrawPoints, DrawLines, DrawTriangles. 에서 단색의 삼각형을 렌더링하여 보았다. 이는 아래와 같이 Fragment Shader에서 붉은색으로만 색상값을 지정하고 있기 때문이다.
이제부터 단색이 아닌, 사용자가 직접 각 Vertex 마다 다른 색상을 지정해 보도록 하겠다.
우선 위와같이 작성되어 있던 Fragment Shader 코드를 아래와 같이 수정한다.
<script id="FragmentShader" type="x-shader/x-vertex">
void main(){
gl_FragColor= vec4(1.0, 0.0, 0.0, 1.0);
}
</script>
이제부터 단색이 아닌, 사용자가 직접 각 Vertex 마다 다른 색상을 지정해 보도록 하겠다.
우선 위와같이 작성되어 있던 Fragment Shader 코드를 아래와 같이 수정한다.
<script id="FragmentShader" type="x-shader/x-vertex">
precision mediump vec4;
varying vec4 vColor;
void main(){
gl_FragColor= vColor;
}
</script>
위의 코드에 사용된, 변수명 vColor의 값은 Vertex에서 지정할것이다.
두번째로, Vertex Shader 코드를 아래와 같이 수정한다.
<script id="VertexShader" type="x-shader/x-vertex">
attribute vec3 aPos;
attribute vec4 aColor;
varying vec4 vColor;
void main(){
gl_Position= vec4(aPos, 1.0);
vColor= aColor;
}
</script>
이전에 작성했던 코드에 4~5라인 정도가 추가되었다. 위의 Vertex Shader 코드를 보면, Fragment Shader코드에서 사용하게될 vColor값을 설정하는 것을 볼 수 있다. Vertex/Fragment Shader 코드 모두 varying vec4 vColor;의 구문을 지니고 있음 기억해 둔다. vColor의 값을 aColor의 값을 그대로 복사하고 있는데, aColor이 선언 방식이 버텍스의 위치값으로 사용되었던 aPos와 동일함을 볼 수 있다. 이전에 aPos에 대해 수행했던 그대로, aColor역시 변수에 대한 핸들을 얻어와야 한다.
vertexColorAttribute= gl.getAttribLocation(shaderProgram, "aColor");
if( vertexColorAttribute==-1 ){
alert("Unable to find Vertex Color Attribute Location.");
return false;
}
gl.enableVertexAttribArray(vertexColorAttribute);
변수명 vertexColorAttribute는 자신의 프로그램 구조에 맞는 적당한 곳에 두면된다.
여기까지 코딩이 완료되었다면, Shader에게 Color 정보를 넘기기 위한 준비작업이 끝난것이다.
이제, Color 정보를 작성해 보도록 하자.
var colorAry= [
1.0, 0.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
0.0, 0.0, 1.0, 1.0
];
var triangleColorBuffer= gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, triangleColorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colorAry), gl.STATIC_DRAW);
앞서 버턱스 좌표값을 위해 수행하였던 구문와 동일한 함수들을 사용한 것을 볼 수 있다. 1.버퍼를 만들고, 2.버퍼를바인딩하고, 3. 바인딩된 버퍼에 값을 쓰는 과정이 나타나 있다. 렌더링될 버텍스가 3개이므로 색상의 개수도 3개인 것에 유의한다. 만약 생상의 개수가 더 많으면 아무런 의미가 없고, 적다면 흰색으로 렌더링될 것이다.
여기까지의 코딩은, Shader에게 넘겨줄 Color 정보 채우기를 완료한 상태이다.
이제, Shader에게 Color 정보를 넘겨 보도록 하겠다.
gl.bindBuffer(gl.ARRAY_BUFFER, triangleColorBuffer);
gl.vertexAttribPointer(vertexColorAttribute, 4, gl.FLOAT, false, 0, 0);
앞서 생성하였던 색상 버퍼(triangleColorBuffer)를 vertexColorAttribute라는 핸들을 통해 Shader로 전담함을 볼 수 있다. Color 값은 RGBA의 4개의 채널을 갖고, 데이터 타입은 float형이다.
최종 결과는 아래와 같다.
전체 코드는 아래와 같다.
<html>
<head>
<title>WebGL - Prac05 - DrawTriangleWithColor</title>
<script type="text/javascript">
var gl;
var vertexPositionAttribute;
var vertexColorAttribute;
function start(){
if( !initWebGL() ){
return;
}
if( !initShader() ){
return;
}
var verAry= [
0.0, 0.0, 0.0,
0.5, 0.0, 0.0,
0.0, 1.0, 0.0
];
var colorAry= [
1.0, 0.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
0.0, 0.0, 1.0, 1.0
];
var triangleVertBuffer= gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verAry), gl.STATIC_DRAW);
//색상 버퍼 생성
var triangleColorBuffer= gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, triangleColorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colorAry), gl.STATIC_DRAW);
gl.clearColor(0.4, 0.5, 0.6, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertBuffer);
gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
//색상 버퍼를 Shder에 넘김
gl.bindBuffer(gl.ARRAY_BUFFER, triangleColorBuffer);
gl.vertexAttribPointer(vertexColorAttribute, 4, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, 3);
alert("finish!");
}
function initWebGL(){
var canvas= document.getElementById("WebGL-Canvas");
if( !canvas ){
alert("Can't find WebGL-Canvas.");
return false;
}
try{
gl= canvas.getContext("experimental-webgl");
}catch(e){
}
if( !gl ){
alert("Unable to initialize WebGL. Your browser may not support it.");
return false;
}
return true;
}
function initShader(){
var vertexShaderDesc= getShader("VertexShader");
var vertexShader= gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderDesc);
gl.compileShader(vertexShader);
if( !gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS) ){
alert("Error(VertexShader): " + gl.getShaderInfoLog(vertexShader));
return false;
}
var fragmentShaderDesc= getShader("FragmentShader");
var fragmentShader= gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderDesc);
gl.compileShader(fragmentShader);
if( !gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS) ){
alert("Error(PixelShader): " + gl.getShaderInfoLog(fragmentShader));
return false;
}
var shaderProgram= gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if( !gl.getProgramParameter(shaderProgram, gl.LINK_STATUS) ){
alert("Unagle to initialize the shader program.");
return false;
}
gl.useProgram(shaderProgram);
vertexPositionAttribute= gl.getAttribLocation(shaderProgram, "aPos");
if( vertexPositionAttribute==-1 ){
alert("Unable to find Vertex Attribute Location.");
return false;
}
gl.enableVertexAttribArray(vertexPositionAttribute);
//색상 값을 전달할, GLSL에서의 변수명 "aColor"에 대한 핸들을 얻어온다.
vertexColorAttribute= gl.getAttribLocation(shaderProgram, "aColor");
if( vertexColorAttribute==-1 ){
alert("Unable to find Vertex Color Attribute Location.");
return false;
}
gl.enableVertexAttribArray(vertexColorAttribute);
return true;
}
function getShader(id){
var shaderScript= document.getElementById(id);
if( !shaderScript ){
alert("Unable to get shader script. id='" + id + "'");
return null;
}
var shaderDesc= "";
var currentChild= shaderScript.firstChild;
while( currentChild ){
if( currentChild.nodeType==3 ){
shaderDesc+= currentChild.textContent;
}
currentChild= currentChild.nextSibling;
}
return shaderDesc;
}
</script>
<script id="VertexShader" type="x-shader/x-vertex">
attribute vec3 aPos;
attribute vec4 aColor;
varying vec4 vColor;
void main(){
gl_Position= vec4(aPos, 1.0);
vColor= aColor;
}
</script>
<script id="FragmentShader" type="x-shader/x-vertex">
precision mediump vec4;
varying vec4 vColor;
void main(){
gl_FragColor= vColor;
}
</script>
</head>
<body onload="start()">
<canvas id="WebGL-Canvas" style="border: 1px solid green" width="400" height="300">
Your browser doesn't appear to support the HTML5 <canvas> element.
</canvas>
</body>
</html>
'Computer > WebGL' 카테고리의 다른 글
008. WebGL - Prac07 - JavaScript 파일 (0) | 2010.04.07 |
---|---|
007. WebGL - Prac06 - Animation (0) | 2010.04.07 |
005. WebGL - Prac04 - Shader를 위한 Script 구문 (0) | 2010.04.06 |
004. WebGL - Prac03 - DrawPoints, DrawLines, DrawTriangles. (0) | 2010.04.05 |
003. WebGL - Prac01 - Graphics의 HelloWorld인 ClearColor (0) | 2010.04.05 |