- GLProgram:근본적으로 Shader이다.정점shader와 픽셀shader를 포함하고 있다.
- 상태속성:근본적으로 말하자면 shader 의 uniform 변수이다.
- 만약 구체가 카메라에서 멀어진다면 퀄리티가 떨어지는 텍스처를 사용하고 싶다면?
- 만약 벽돌에 블러효과를 넣고 싶다면?
- 만약 조명을 On/Off 하고 싶을 경우는?
- 재질은 하나이상의 렌더링방법을 가질수 있다.(technique)
- 렌더링방법마다 하나이상의 pass를 가질수 있다.
- pass마다 아래와 같은것을 가지고 있다:
- 하나의 RenderState.
- uniform변수를 포함한 Shader를 포함하고 있다.
- RenderState:GPU 상태메시지를 포함한다.(예를들면: depthTest, cullFace, stencilTest 등등)
- GLProgramState:사용할 Shader와 uniform변수들을 포함하고 있다.
- 재질 파일의 확장명은 중요하지 않다.확장자를 .material을 사용하는걸 추천한다.
- 정점 셰이더와 픽셀셰이더의 확장자도 중요하지 않으니 .vert와 .frag를 사용하는것을 추천한다.
- Id는 재질(Material),렌더링방법(Technique),pass의 선택적 속성이다.
- Material은 parent_material_id를 통하여 다른 재질의 값을 상속받을수 있다.
- Scalar 는 스칼라값을 의미한다.float,int,bool 타입을 사용할수 있다.
- Vector는 콤마로 구분된 일련의 float 타입으로 이뤄져있다.
- 미리 정의된 uniform 변수
- CC_PMatrix: A mat4 with the projection matrix
- CC_MVMatrix: A mat4 with the Model View matrix
- CC_MVPMatrix: A mat4 with the Model View Projection matrix
- CC_NormalMatrix: A mat4 with Normal Matrix
- CC_Time: a vec4 with the elapsed time since the game was started
- CC_Time[0] = time / 10;
- CC_Time[1] = time;
- CC_Time[2] = time * 2;
- CC_Time[3] = time * 4;
- CC_SinTime: a vec4 with the elapsed time since the game was started:
- CC_SinTime[0] = time / 8;
- CC_SinTime[1] = time / 4;
- CC_SinTime[2] = time / 2;
- CC_SinTime[3] = sinf(time);
- CC_CosTime: a vec4 with the elapsed time since the game was started:
- CC_CosTime[0] = time / 8;
- CC_CosTime[1] = time / 4;
- CC_CosTime[2] = time / 2;
- CC_CosTime[3] = cosf(time);
- CC_Random01: A vec4 with four random numbers between 0.0f and 1.0f
- CC_Texture0: A sampler2D
- CC_Texture1: A sampler2D
- CC_Texture2: A sampler2D
- CC_Texture3: A sampler2D
Shader 와 Material
Shader란 무엇인가?
위키백과:
컴퓨터 그래픽스 분야에서 셰이더(shader)는 소프트웨어 명령의 집합으로 주로 그래픽 하드웨어의 렌더링 효과를 계산하는 데 쓰인다. 셰이더는 그래픽 처리 장치(GPU)의 프로그래밍이 가능한 렌더링 파이프라인을 프로그래밍하는 데 쓰인다.
비 전문가가 정의한다면 : 컴퓨터가 어떻게 특정한 방식으로 어떤물건을 렌더링할지 결정하는 프로그램이다.간단하게 말하면 Shader는 GPU상에서 어떻게 렌더링할지 결정하는 프로그램이다.
Cocos2d-x는 이것을 이용해서 노드를 렌더링한다.
Cocos2d-x가 사용하는 Shader 언어는 OpenGL ES Shading Language v1.0 이다.
GLSL언어를 설명하는것은 본문건의 범위를 벗어나기 때문에 더 자세히 알고싶다면 가이드북 을 보기 바란다.
Cocos2d-x에서 모든 렌더링 가능한 노드객체는 셰이더를 사용한다.
Shader 설정하기
개발자는 어떤 Cocos2d-x의 객체든지 직접 작성한 셰이더를 설정할수 있습니다.
Shader를 추가하는 예시:
C++
sprite->setGLProgramState(programState);
sprite3d->setGLProgramState(programState);
GLProgramState 객체는 아래 두개의 중요한것을 포함하고 있다.
만약 당신이 uniform변수에 대해 익숙하지 않고 왜 이것이 필요한지 알고싶다면 GLSL 가이드북을 보기 바란다.
아래와 같이 Uniform변수를 GLProgramState 에 쉽게 설정할수 있다
C++
glProgramState->setUniformFloat("u_progress", 0.9);
glProgramState->setUniformVec2("u_position", Vec2(x,y));
glProgramState->setUniformMat4("u_transform", matrix);
콜백함수를 uniform변수로 설정할수도 있다.아래는 람다표현식을 콜백함수로 사용한 예제이다:
C++
glProgramState->setUniformCallback("u_progress", [](GLProgram* glProgram, Uniform* uniform)
{
float random = CCRANDOM_0_1();
glProgram->setUniformLocationWith1f(uniform->location, random);
}
);
GLProgramState 객체를 수동설정할수 있지만 더욱 간단한 방법은 Material객체를 사용하는 것이다.
재질(Material)이란 무엇인가
게임에서 아래와 같은 구체를 그리고 싶다면
당신이 첫번쨰로 해야할 일은 기하구조를 아래와 같이 정의하는것이다.
그다음 벽돌 텍스처를 정의하는것이다.
이렇게 하면 목표했던 효과를 달성할수 있다.하지만 더 나아가서 생각해봐야 할것은
답은 간단한 텍스처를 사용하는것이 아니라 재질(Material)을 사용하는 것이다.
재질은 여러 텍스처를 사용할수 있고 다른 어떤 특성을 가지고 있을수 있다.
예를들면 다중렌더링같은 경우이다.
아래는 Material 파일이다.
JavaScript
// A "Material" file can contain one or more materials
material spaceship
{
// A Material contains one or more Techniques.
// In case more than one Technique is present, the first one will be the default one
// A "Technique" describes how the material is going to be renderer
// Techniques could:
// - define the render quality of the model: high quality, low quality, etc.
// - lit or unlit an object
// etc...
technique normal
{
// A technique can contain one or more passes
// A "Pass" describes the "draws" that will be needed
// in order to achieve the desired technique
// The 3 properties of the Passes are shader, renderState and sampler
pass 0
{
// shader: responsible for the vertex and frag shaders, and its uniforms
shader
{
vertexShader = Shaders3D/3d_position_tex.vert
fragmentShader = Shaders3D/3d_color_tex.frag
// uniforms, including samplers go here
u_color = 0.9,0.8,0.7
// sampler: the id is the uniform name
sampler u_sampler0
{
path = Sprite3DTest/boss.png
mipmap = true
wrapS = CLAMP
wrapT = CLAMP
minFilter = NEAREST_MIPMAP_LINEAR
magFilter = LINEAR
}
}
// renderState: responsible for depth buffer, cullface, stencil, blending, etc.
renderState
{
cullFace = true
cullFaceSide = FRONT
depthTest = true
}
}
}
}
재질을 Sprite3D 에 설정하는 방법:
C++
Material* material = Material::createWithFilename("Materials/3d_effects.material");
sprite3d->setMaterial(material);
만약 당신이 다른 렌더링방법으로 변경하고 싶다면 아래와 같이 하면 된다.
C++
material->setTechnique("normal");
렌더링 방법(Technique)
당신은 Sprite3D 객체마다 하나의 재질만 설정할수 있다.
그렇다고 하나의 렌더링방식으로 고정되어 있다는 뜻은 아니다.
재질은 여러 렌더링방식(Technique)을 포함시킬수 있는 특성이 있기때문이다.
재질이 로딩될때 모든 Technique도 로딩된다.
이런 특성이 있어서 당신은 런타임때에 빠르게 객체의 렌더링효과를 변경시킬수 있다.
Material::setTechnique(const std::string& name) 메서드를 사용하여 Technique의 전환을 할수있다.이런 특성은 각기 다른 조명효과로 변환을 하고플때 사용할수도 있고 렌더링할 객체가 카메라에서 멀어졌을때 퀄리티가 낮은 텍스처를 사용하고 싶을때 처리할수 있다.
Pass
하나의 Technique에는 여러개의 pass가 있다.
개중에 하나의 pass는 한번의 렌더링에 대응된다.
여러 pass가 있다는것은 하나의 객체가 여러 번 렌더링된다는것을 의미한다.
이것이 다중 pass 렌더링 or 다중렌더링 이라고 불린다.pass마다 아래 두개의 중요한 객체가 필요하다.
재질(Material)파일 포맷
Cocos2d-x의 재질파일은 최적화된 포맷을 사용함과 동시에 다른 오픈소스 엔진의 재질파일포맷과 유사하다(GamePlay3D,OGRE3D 엔진들)
주의해야 할점:
C++
// When the .material file contains one material
sprite3D->setMaterial("Materials/box.material");
// When the .material file contains multiple materials
sprite3D->setMaterial("Materials/circle.material#wood");
필드 정의
material material_id : parent_material_id |
|
|
{ |
|
|
renderState {} |
[0..1] |
block |
technique id {} |
[0..*] |
block |
} |
|
|
technique technique_id |
|
|
{ |
|
|
renderState {} |
[0..1] |
block |
pass id {} |
[0..*] |
block |
} |
|
|
pass pass_id |
|
|
{ |
|
|
renderState {} |
[0..1] |
block |
shader {} |
[0..1] |
block |
} |
|
|
renderState |
|
|
{ |
|
|
blend = false |
[0..1] |
bool |
blendSrc = BLEND_ENUM |
[0..1] |
enum |
blendDst = BLEND_ENUM |
[0..1] |
enum |
cullFace = false |
[0..1] |
bool |
depthTest = false |
[0..1] |
bool |
depthWrite = false |
[0..1] |
bool |
} |
|
|
frontFace = CW | CCW |
[0..1] |
enum |
depthTest = false |
[0..1] |
bool |
depthWrite = false |
[0..1] |
bool |
depthFunc = FUNC_ENUM |
[0..1] |
enum |
stencilTest = false |
[0..1] |
bool |
stencilWrite = 4294967295 |
[0..1] |
uint |
stencilFunc = FUNC_ENUM |
[0..1] |
enum |
stencilFuncRef = 0 |
[0..1] |
int |
stencilFuncMask = 4294967295 |
[0..1] |
uint |
stencilOpSfail = STENCIL_OPERATION_ENUM |
[0..1] |
enum |
stencilOpDpfail = STENCIL_OPERATION_ENUM |
[0..1] |
enum |
stencilOpDppass = STENCIL_OPERATION_ENUM |
[0..1] |
enum |
shadershader_id |
|
|
{ |
|
|
vertexShader = res/colored.vert |
[0..1] |
file path |
fragmentShader = res/colored.frag |
[0..1] |
file path |
defines = semicolon separated list |
[0..1] |
string |
[0..*] |
uniform |
|
uniform_name = AUTO_BIND_ENUM |
[0..*] |
enum |
sampler uniform_name {} |
[0..*] |
block |
} |
|
|
sampler uniform_name |
|
|
{ |
|
|
path = res/wood.png | @wood |
[0..1] |
image path |
mipmap = bool |
[0..1] |
bool |
wrapS = REPEAT | CLAMP |
[0..1] |
enum |
wrapT = REPEAT | CLAMP |
[0..1] |
enum |
minFilter = TEXTURE_MIN_FILTER_ENUM |
[0..1] |
enum |
magFilter = TEXTURE_MAG_FILTER_ENUM |
[0..1] |
enum |
} |
|
|
열거형 정의
TEXTURE_MIN_FILTER_ENUM |
|
NEAREST |
Lowest quality non-mipmapped |
LINEAR |
Better quality non-mipmapped |
NEAREST_MIPMAP_NEAREST |
Fast but low quality mipmapping |
LINEAR_MIPMAP_NEAREST |
|
NEAREST_MIPMAP_LINEAR |
|
LINEAR_MIPMAP_LINEAR |
Best quality mipmapping |
TEXTURE_MAG_FILTER_ENUM |
|
NEAREST |
Lowest quality |
LINEAR |
Better quality |
BLEND_ENUM |
|
ZERO |
ONE_MINUS_DST_ALPHA |
ONE |
CONSTANT_ALPHA |
SRC_ALPHA |
ONE_MINUS_CONSTANT_ALPHA |
ONE_MINUS_SRC_ALPHA |
SRC_ALPHA_SATURATE |
DST_ALPHA |
|
CULL_FACE_SIDE_ENUM |
|
BACK |
Cull back-facing polygons. |
FRONT |
Cull front-facing polygons. |
FRONT_AND_BACK |
Cull front and back-facing polygons. |
FUNC_ENUM |
|
NEVER |
ALWAYS |
LESS |
GREATER |
EQUAL |
NOTEQUAL |
LEQUAL |
GEQUAL |
STENCIL_OPERATION_ENUM |
|
KEEP |
REPLACE |
ZERO |
INVERT |
INCR |
DECR |
INCR_WRAP |
DECR_WRAP |
데이터 타입
아래는 Cocos2d-x가 미리 정의한 uniform변수들이다.
당신은 직접 셰이더를 작성할때 이것들을 사용할수 있다.
출처: <http://cocos2d-x.org/docs/cocos2d-x/zh/advanced_topics/shaders.html>
'Cocos2d-x v3.17 > 고급 기능' 카테고리의 다른 글
[Cocos2d-x 고급기능]그래픽 성능 최적화 및 SQLite (0) | 2018.08.11 |
---|---|
[Cocos2d-x 고급기능]네트워크 액세스 (0) | 2018.08.11 |
[Cocos2d-x 고급기능]파일 시스템 접근 (0) | 2018.08.11 |
[Cocos2d-x 고급기능]고급 사운드 기능 (0) | 2018.08.11 |
[Cocos2d-x 고급기능]소리 제어 (0) | 2018.08.11 |