벽돌 무늬에서 필요한 값들은 다음과 같다.
// GLSL 쉐이더에서 "BrickColor" uniform의 위치를 얻음
char BrickColor = ProgramManagerObj->ProgramGetUniformLocation(program, (char*)"BrickColor");
// GLSL 쉐이더에서 "MortarColor" (시멘트 색상) uniform의 위치를 얻음
char MortarColor = ProgramManagerObj->ProgramGetUniformLocation(program, (char*)"MortarColor");
// 하나의 벽돌 셀 크기 (width, height)를 지정하는 uniform 위치
char RectangularSize = ProgramManagerObj->ProgramGetUniformLocation(program, (char*)"RectangularSize");
// 셀 안에서 벽돌이 차지하는 비율 (x%, y%)을 지정하는 uniform 위치
char BrickPercent = ProgramManagerObj->ProgramGetUniformLocation(program, (char*)"BrickPercent");
if (BrickColor >= 0){
// 벽돌 색상을 빨간 계열로 설정 (RGB: 1.0, 0.3, 0.2)
glUniform3f(BrickColor, 1.0, 0.3, 0.2);
}
if (MortarColor >= 0){
// 시멘트 색상을 밝은 회색 계열로 설정 (RGB: 0.85, 0.86, 0.84)
glUniform3f(MortarColor, 0.85, 0.86, 0.84);
}
if (RectangularSize >= 0){
// 벽돌 셀 하나의 크기를 (0.50, 0.10)으로 설정 (가로 0.5, 세로 0.1 단위)
glUniform2f(RectangularSize, 0.50, 0.10);
}
if (BrickPercent >= 0){
// 벽돌이 셀 내에서 차지하는 비율을 90% x축, 85% y축으로 설정
// 즉, 나머지 10%, 15%는 시멘트로 간주
glUniform2f(BrickPercent, 0.90, 0.85);
}
Vertex Shader
#version 300 es
// Vertex information
layout(location = 0) in vec4 VertexPosition;
layout(location = 1) in vec3 Normal;
// Model View Project matrix
uniform mat4 ModelViewProjectionMatrix;
uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
out vec3 nNormal;
out vec3 eyeCoord;
out vec3 ObjectCoord;
void main()
{
nNormal = normalize ( NormalMatrix * Normal );
eyeCoord = vec3 ( ModelViewMatrix * VertexPosition );
ObjectCoord = VertexPosition.xyz;
gl_Position = ModelViewProjectionMatrix * VertexPosition;
}
Fragment Shader
아래 코드는 지그재그나 체크무늬를 만들때 자주 사용하는 코드이다.
- if (fract(position.y * 0.5 ) > 0.5) position.x += 0.5;
position.y 값의 범위 | fract(position.y * 0.5의 값 |
0 ~ 1 | < 0.5 |
1 ~ 2 | > 0.5 |
2 ~ 3 | < 0.5 |
3 ~ 4 | > 0.5 |
즉 Y의 정수값이 홀수인 경우만, 조건이 true가 된다.
그러므로 홀수인 경우 x 좌표가 우측으로 0.5 이동하기 때문에 벽돌이 지그재그 형태로 보인다.
#version 300 es
precision mediump float;
uniform vec3 MaterialAmbient;
uniform vec3 MaterialSpecular;
uniform vec3 MaterialDiffuse;
uniform vec3 LightAmbient;
uniform vec3 LightSpecular;
uniform vec3 LightDiffuse;
uniform vec3 LightPosition;
uniform float ShininessFactor;
in vec3 nNormal;
in vec3 eyeCoord;
in vec3 ObjectCoord;
layout(location = 0) out vec4 FinalColor;
// Brick uniform parameters
uniform vec3 BrickColor, MortarColor;
uniform vec2 RectangularSize, BrickPercent;
vec3 PhongShading()
{
vec3 normalDir = normalize ( nNormal );
vec3 normalPosition = normalize( eyeCoord );
vec3 nLight = normalize( LightPosition - eyeCoord );
// Diffuse Intensity
float cosAngle = max( 0.0, dot( normalDir, nLight ));
// Specular Intensity
vec3 V = -normalPosition;
vec3 R = reflect( -nLight, normalDir );
float sIntensity = pow( max( 0.0, dot( R, V ) ), ShininessFactor );
// ADS color as result of Material & Light interaction
vec3 ambient = MaterialAmbient * LightAmbient;
vec3 diffuse = MaterialDiffuse * LightDiffuse * cosAngle;
vec3 specular = MaterialSpecular * LightSpecular * sIntensity;
return ambient + diffuse + specular;
}
vec3 color;
vec2 position, useBrick;
void main() {
// 오브젝트 공간 좌표를 벽돌 셀 크기로 나눠서, 각 픽셀이 몇 번째 셀에 있는지 구함
position = ObjectCoord.xy / RectangularSize;
// 홀수 번째 y줄에서는 벽돌 위치를 반 셀만큼 x축으로 밀어 지그재그(벽돌 무늬)를 만듦
if (fract(position.y * 0.5) > 0.5) {
position.x += 0.5;
}
// 셀 내부의 상대 좌표 (0~1 범위)로 변환
position = fract(position);
// step(edge, x): x < edge → 0, x ≥ edge → 1
// → x, y 좌표가 BrickPercent보다 작을 때만 벽돌 내부로 판단
useBrick = step(position, BrickPercent);
// 벽돌 내부면 BrickColor, 아니면 MortarColor(시멘트 색)를 사용
color = mix(MortarColor, BrickColor, useBrick.x * useBrick.y);
// Phong 조명 효과를 색상에 곱한 후 최종 출력
FinalColor = vec4(color * PhongShading(), 1.0);
}
'Opengles 3.0 with Android' 카테고리의 다른 글
Chapter 6.4 Polka Dot (0) | 2025.04.24 |
---|---|
Chapter 6.1 Pattern Effect - Circle (0) | 2025.04.16 |
Chapter 6.0 Warble Effect (0) | 2025.04.16 |
Chapter 5.2 Multi Light (0) | 2025.04.15 |
Chapter 5.1 Phong Shader (0) | 2025.03.24 |