원본링크 : https://www.opengl.org/sdk/docs/tutorials/TyphoonLabs/
내가 읽기위한 내맘대로 번역
Shader 'Input' Data
쉐이더의 입력데이타
Programmers can write self-contained standalone shaders, which don’t require any extra data to run, in order to produce desired results
프로그래머는 실행시에 추가적인 데이타가 필요없는 쉐이더를 작성할수있다
Shaders (both vertex and fragment) usually obtain some input values, such as textures, limit and timing values, colors, light positions, tangents, bi-normals, and pre-computed values, which are used to compute the final vertex position/fragment color for any given surface.
vertex shader와 fragment shader 둘다 일반적으로 입력값을 가진다.
(시간, 색, 빛, 위치...) 그 값들은 최종 꼭지점의 위치와 fragment 색을 계산하는데 사용된다.
Uniform Variables
Uniform variables can use one of the GLSL-defined types. These read-only values (which should be treated as constants, as they cannot be changed) are then passed from the host OpenGL application to the shader.
Uniform 변수
Uniform 변수는 GLSL데이타타입중에 하나를 사용한다.
이것들은 상수(읽기전용)다.
host어플리케이션(OpenGL어플리케이션)에서 쉐이더에게 값을 넘겨줘야 한다.
From the host application, values could be passed to the shader as follows:
host어플리케이션에서 다음과같이 쉐이더에 값을 넘길수 있다:
location = glGetUniformLocationARB(program,”light0Color”);
float color[4] = {0.4f,0,1,1};
glUniform4fARB(location ,color);
The shader must first declare the variable before it can be used, which can be done as follows:
쉐이더에서는 다음과같이 변수를 사용하기전에 미리 선언해야 한다.
uniform vec4 light0Color;
If the variable light0Color is queried by the shader, it would return the value
light0Color 변수는 쉐이더안에서 아래의 값을 가지게 된다
{0.4, 0, 1, 1}.
Textures must also be passed via uniforms.
When passing textures, the developer must send an integer, which represents the texture unit number.
For example, passing 0 would tell the shader to use GL_TEXTURE0, and so on:
텍스쳐또한 uniforms에 넘겨줘야 한다.
텍스쳐를 넘길때 개발자는 반드시 정수를 넘겨야 한다 (텍스쳐unit number)
예를들어, 0을 넘기면 쉐이더에게 GL_TEXTURE0 번의 텍스쳐unit을 사용하라는 뜻이다.
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mytexturebaseID);
location = glGetUniformLocationARB(program, ”baseTexture”);
glUniform1iARB(location, 0); // Bind baseTexture to TU 0.
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, mytexturebumpID);
location=glGetUniformLocationARB(program, ”bumpTexture”);
glUniform1iARB(location, 1); // Bind bumpTexture to TU 1.
The uniforms are declared as sampler2D within the shader (though the actual texture unit will be discussed at a later point):
쉐이더안에서 텍스쳐를 넘겨받는 변수는 sampler2D로 선언되었다.
(texture unit은 나중에 논의하자)
uniform sampler2D baseTexture;
uniform sampler2D bumpTexture;
Vertex Attributes
These variables can only be used within vertex shaders to pass per-vertex values. There are two types of attributes: defined and generic.
Defined attributes are normals, texture coordinates, per-vertex color materials, etc. Even the vertex position is a vertex attribute.
Generic attributes are those which the developer defines for meshes, like tangents, bi-normals, particle properties, and skinning information (bones).
이 변수들은 vertex쉐이더안에서만 사용되고, 꼭지점(정점)값을 넘긴다.
attributes는 2가지 타입이 있다. 미리정의된것과 일반적인것
미리정의된 attributes : 법선, 텍스쳐좌표, 정점 color material, 정점위치 등
일반적인 attributes : 개발자가 정의한 것들
When the developer creates a mesh, they must specify the ‘Vertex Format.’ This format is a collection of vertex attributes which will be sent to the vertex shader (like position, color, normal, texture coordinate, and tangent). For defined attributes, we have standard OpenGL functions like glVertex3f, glNormal3f, glColor, and glTexCoord2f. For generic attributes, we have the glVertexAttrib call.
개발자가 도형(mesh)을 만들때 반드시 정점(꼭지점)포맷을 기술해야 한다.
이 포맷은 vertex쉐이더에 전달되는 정점attributes의 모음이다(위치, 색, 법선, 텍스쳐좌표, 탄젠트...)
미리정의된attributes일때는 표준OpenGL함수를 사용한다(glVertex3f, glNormal3f, glColor, glTexCoord2f)
일반적인attributes일때는 glVertexAttrib함수를 사용한다
이석우 추가설명:
도형을 만들려면 정점의위치, 색, 법선, 텍스쳐좌표등을 vertex쉐이더에 넘겨야 하고,
이것들은 미리정의된 함수를 쓰면 되고, 나머지 추가로 넘길 데이타는 glVertexAttrib
함수로 넘겨주면 된다는 뜻.
The method for passing generic attributes is a little different. The GL_ARB_vertex_program extension holds a number of slots where attributes can be placed. These slots are shared between the defined and generic attributes, meaning defined slots can be overwritten and their attribute lost. Defined attributes always use the same slot numbers, so you can choose which one to overwrite, or use a free slot (you can ask OpenGL for a free slot).
The following code could be used to pass a generic attribute to a shader through a given slot:
일반적인attributes에 값을 넘기는 방법은 조금 다르다.
attributes가 위치할 슬롯의 번호를 알아야한다. 이 슬롯들은 미리정의된attributes와 일반적인attributes가 공유한다.
이 뜻은 미리정의된 슬롯은 덮어써져서 값을 잃어버릴수 있다.
미리정의된attributes는 항상 같은 슬롯번호를 사용한다. 너는 그 슬롯중하나를 선택해서 엎어쓸수도 있고,
비어있는 슬롯을 사용할수도 있다(OpenGL에서 비어있는 슬롯을 알려달라고 요청할수 있다)
다음코드는 일반적인attribute를 특정슬롯번호를 통해서 쉐이더에 넘겨주는 방법이다.
int slot = 9; //A random slot.
glBindAttribLocationARB(program, slot, “fooAttribute”);
glBegin(GL_TRIANGLES);
glVertexAttrib3fARB(slot,2,3,1);
glVertex3f(0,1,0);
glNormal3f(1,0,0);
glVertexAttrib3fARB(slot,2,1,1);
glVertex3f(0,0,1);
glNormal3f(1,0,0);
glVertexAttrib3fARB(slot,2,3,2);
glVertex3f(1,0,0);
glNormal3f(1,0,0);
glEnd();
이석우 추가설명 : 나는 이런방법을 안쓴다.
To access the attribute from the vertex shader, the variable has to be declared as follows:
vertex쉐이더안에서 이 attribute에 접근하려면, 다음처럼 선언되어 있어야 한다.
attribute vec3 fooAttribute;
Attributes only can be declared with float, vec2, vec3, vec4, mat2, mat3, and mat4.
Attribute variables cannot be declared as arrays or structures.
attriubtes는 float, vec2, vec3, vec4, mat2, mat3, mat4로만 선언되어야 하고
배열이나 구조체는 쓸수 없다.
Vertex arrays can also be used to pass attributes, with calls like glVertexAttribPointerARB, glEnableVertexAttribArrayARB, glBindAttribLocationARB and glDisableVertexAttribArrayARB. See the appendix for how to use these generic vertex attribute calls.
정점배열은 다음 함수들을 호출해서 attributes에 전달된다.
glVertexAttribPointerARB, glEnableVertexAttribArrayARB
glBindAttribLocationARB, glDisableVertexAttribArrayARB
이것들의 사용법은 부록을 봐라.
이석우 추가설명 : 쉐이더안에서 attribute변수는 배열이 될수 없는데, 정점배열을 어떻게 넘기는가?
vertex쉐이더는 정점배열의 갯수만큼 실행된다. 따라서 정점배열에서 하나씩 꺼내서
vertex쉐이더에 넘겨서 실행되는거 같다. 따라서 vertex쉐이더안에서는 vec3 또는 vec4로
선언하면 되는것이다.
Varying Variables
It is possible for a vertex shader to pass data to a fragment shader by use of another type of variable. Varying variables will be written by the vertex shader and read into the fragment shader (though the actual variable within the vertex shader will not be passed). The fragment shader will then receive the perspective-corrected and interpolated (across the primitive’s surface) value of the variable written by the vertex shader. The best example of varying variables (sometimes called interpolators) is texture coordinates. Texture coordinates are established by the vertex shader, loaded as vertex attributes, and then written into varying variables in order to pass an interpolated value in a perspective- correct fashion into the fragment shader.
vertex쉐이더가 fragment쉐이더에 데이타를 넘기는것이 가능하다
varying변수는 vertex쉐이더안에서 생성되고 fragment쉐이더안에서 읽을수 있다.
이때 fragment쉐이더는 투영보정, 보간된 값을 받는다.
varying변수의 좋은예는 텍스쳐좌표이다.
텍스쳐좌표는 vertex쉐이더에 의해서 만들어지고 vertex attributes로 로드되고,
varying변수에 담겨서 gragment쉐이더로 넘어간다 (투영에의해 보간된 값으로)
Shader 'Output' Data
Vertex Shader
The main objective of the vertex shader is to compute the vertex position within the clip-space coordinates. To do this, GLSL's built-in gl_Position variable can be used (which has a vec4 type) in one of two ways:
vertex쉐이더의 주목적은 공간좌표에서 정점의 위치를 계산하는것이다.
이를 위하여 GLSL안에 내장된 vec4타입의 gl_Position변수가 사용된다.
a) gl_Position = ftransform();
This is usually the best way, as ftransform() keeps the invariance within a built-in fixed function.
일반적으로 제일좋은 방법이다. 항상 고정기능과 동일한 결과를 얻을수 있다.
b) gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
This will compute the correct vertex position, as it multiplies the vertex position (gl_Vertex) by the model-view which is once again multiplied by the projection matrix (gl_ModelViewProjectionMatrix is a built- in uniform mat4 variable, which holds the result of gl_ModelViewMatrix * gl_ProjectionMatrix). However, this will not keep the invariance within a fixed function, and could prove problematic in multi-pass algorithms.
정점위치와 모델뷰행렬과 투영행렬을 곱해서 올바른 정점위치를 계산한다.
gl_ModelViewProjectionMatrix : 내장된 uniform mat4타입의 변수. gl_ModelViewMatrix * gl_ProjectionMatrix 의 결과를 가지고 있음
항상 고정기능과 동일한 결과를 얻을수 있는건 아니고, 다중패스알고리즘에 문제가 있을수도 있다.
Fragment Shader
The main objective of a fragment shader is to compute the final color (and optionally, depth) of the fragment being computed. To do this, GLSL's built-in gl_FragColor variable can be used (which also has a vec4 type):
gl_FragColor = vec4(1, 0, 0, 0);
The above example will write a pure red color with an alpha value of 0 to the frame buffer.
fragment쉐이더의 주목적은 최종색을 계산하는것이다 (깊이도)
이를 위하여 GLSL안에 내장된 vec4타입의 gl_FragColor 변수가 사용된다
위의 예는 알파값0을 갖는 빨간색을 framebuffer에 기록한다.
There are more values that can be written within the vertex and fragment shaders, like information relating to clipping plane(s), point parameters. and fragdepth, but all of these are optional.
vertex쉐이더와 fragement쉐이더에서 사용하는 더많은 값들이 있지만 다 옵션들이다.
If a vertex shader doesn’t contain a gl_Position variable, it won’t compile, and instead will simply generate compilation errors instead. The same is true of fragment shaders if gl_FragColor is not used. These two variables are absolutely mandatory for a successful shader.
만약 vertex쉐이더에서 gl_Position변수값을 설정하지 않으면 컴파일되지 않고, 에러가 발생한다.
만약 fragment쉐이더에서 gl_FragColor변수값을 설정하지 않으면 컴파일되지 않고, 에러가 발생한다.
이 2개의 변수는 쉐이더에 필수다.
이 뒤의 내용은 TyphoonLab의 OpenGL Shader Designer라는 둘에 대한 사용법인데.
인터넷 찾아보니 버그투성이에 안좋다고 해서, 그냥 스킵~~~
'OpenGLES 초보' 카테고리의 다른 글
Blender. bone. 리깅. (0) | 2017.01.13 |
---|---|
shader 기본 지식 (0) | 2015.10.21 |
[번역] All about OpenGL ES 2.x - (part 2/3) (0) | 2014.11.25 |
frame buffer, render buffer, vbo (0) | 2014.11.11 |
[번역] OpenGL Tutorial for iOS: OpenGL ES 2.0 (1) | 2014.10.31 |