A. KONSEP SHADING
Shading bertujuan untuk membuat obyek tampak nyata Ada 3 macam model
shading:
- Flat Shading
- Smooth (Gouraud) Shading
- Phong Shading
1. FLAT SHADING
a. Langkah:
- Vektor l, n, dan v dibuat konstan
- Operasi shading dibuat hanya sekali disetiap bidang polygon
- Setiap polygon dibuat menggunakan shading yang sama
b. Kelemahan:
Bila digunakan pada permukaan yang halus, perbedaan shading antar polygon yang
berdekatan sangat jelas
c. Penerapan flat shading:
Pada OpenGL aktifkan model shading berikut
glShadeModel(GL_FLAT);
2. SMOOTH (GORAUD) SHADING
- Setiap vertex mempunyai warna / intensitas sendiri
- Setiap vertex dianggap mempunyai normal
- Normal pada vertex dihitung dari rata-rata normal dari polygon yang
terhubung dengan vertex.
- Smooth (goraud) shading dicapai dengan menginterpolasi intensitas pada
vertex
- Goraud shading dilakukan di vertex shader
a. Penerapan smooth (ground) shading:
Di OpenGL diaktifkan model shading sebagai berikut:
glShadeModel(GL_SMOOTH);
b. Ground shading pada vertex shader:
#version 150 core
// Material dan pencahayaan
uniform vec3 lightPos = vec3(10.0, 10.0, 20.0);
uniform vec3 lightDiffuse = vec3(0.5, 1.0, 1.0);
uniform vec3 lightSpecular = vec3(0.7);
uniform float powerSpecular = 128.0;
uniform vec3 lightAmbient = vec3(0.5, 0.5, 0.5);
varying vec4 color;
void main(void)
{
// hitung vektorposisi model
vec3 P = vec3(gl_ModelViewMatrix* gl_Vertex);
// hitung vektornormal
vec3 N = normalize(gl_NormalMatrix* gl_Normal);
// hitung vektorcahaya
vec3 L = normalize(gl_LightSource[0].position.xyz- P.xyz);
// hitung vektorpandang
vec3 V = normalize(-P);
// hitung vektorrefleksi
vec3 R = reflect(-L, N);
//hitung properti ambient, diffuse dan specular
vec4 ambient = gl_FrontLightProduct[0].ambient;
vec4 diffuse = max(dot(N, L), 0.0) *
gl_FrontLightProduct[0].diffuse;
diffuse = clamp(diffuse, 0.0, 1.0);
vec4 specular = pow(max(dot(R, V), 0.0),
gl_FrontMaterial.shininess) *
gl_FrontLightProduct[0].specular;
specular = clamp(specular, 0.0, 1.0);
//hitung warna untuk digunakan di fragment shaders
color = gl_FrontLightModelProduct.sceneColor+ ambient +
diffuse + specular;
//hitung posisiclipping model
gl_Position= gl_ModelViewProjectionMatrix* gl_Vertex;
}
c. Goraud shading pada fragment shader
#version 150 core
varying vec4 color;
void main(void)
{
// Write incoming color to the framebuffer
gl_FragColor = color;
}
3. PHONG SHADING
- Phong shading dicapai dengan menginterpolasi normal pada vertex.
- Normal pada setiap polygon yang berdekatan diinterpolasi untuk
menghitung normal pada vertex
- Normal disetiap vertex dan edge pada polygon merupakan hasil interpolasi
normal dari vertex yang menghubungkan polygon tersebut Diterapkan
pada fragment shader
a. Penerapan phong shading
1) Phong shading pada vertex shader
#version 150 core
varying vec3 N;
varying vec3 L;
varying vec3 V;
void main(void)
{
// hitung vektor posisi
vec3 P = vec3(gl_ModelViewMatrix * gl_Vertex);
// hitung vektor normal
N = gl_NormalMatrix * gl_Normal;
// hitung vektor cahaya
L = gl_LightSource[0].position.xyz - P.xyz;
// hitung vektor pandang
V = -P;
// hitung posisi clipping model
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
2) Phong shading pada fragment shader
#version 150 core
varying vec3 N;
varying vec3 L;
varying vec3 V;
void main(void)
{
// normalisasi semua vektor
vec3 tN = normalize(N);
vec3 tL = normalize(L);
vec3 tV = normalize(V);
// hitung vektor refleksi
vec3 tR = reflect(-tL, tN);
// hitung komponen diffuse dan specular
vec4 diffuse = max(dot(tN, tL), 0.0) *
gl_FrontLightProduct[0].diffuse;
vec4 specular = pow(max(dot(tR, tV), 0.0),
gl_FrontMaterial.shininess) *
gl_FrontLightProduct[0].specular;
// hitung warna ke frame buffer
gl_FragColor = gl_FrontLightModelProduct.sceneColor +
diffuse + specular;
}
B. NON-PHOTOREALISTIC SHADING
Pada obyek bisa diterapkan efek non-photorealistik shading Biasanya untuk
membuat obyek nampak seperti tampilan kartun Non-photorealistik shading
diterapkan dengan:
- Menggunakan sedikit warna
- Mempertegas tepian obyek
- Penerapan non-photorealistic shading
vec4 color1 = vec4(1.0, 1.0, 0.0, 1.0); // yellow
vec4 color2 = vec4(1.0, 0.0, 0.0, 1.0); // red
// efek warna yang berbeda
if (dot(L, N) > 0.5)
gl_FrontColor = color1;
else
gl_FrontColor = color2;
Atau
// efek silhouette
vec4 color3 = vec4(0.0, 0.0, 0.0, 1.0);
// black if (abs(dot(V, N) < 0.01))
glFrontColor = color3;
Contoh Penerapan Program Lightning
void setShaders()
{
char* vertex = readShaders("praktikum03_goraud.vert");
char* fragment = readShaders("praktikum03_goraud.frag");
vertexShaders = glCreateShader(GL_VERTEX_SHADER);
fragmentShaders = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vertexShaders, 1, (const char**)&vertex, 0);
glShaderSource(fragmentShaders, 1, (const char**)&fragment, 0);
glCompileShader(vertexShaders);
glCompileShader(fragmentShaders);
programShaders = glCreateProgram();
glAttachShader(programShaders, vertexShaders);
glAttachShader(programShaders, fragmentShaders);
glBindAttribLocation(programShaders, 0, "in_Position");
glBindAttribLocation(programShaders, 1, "in_Color");
glLinkProgram(programShaders);
glUseProgram(programShaders);
free(vertex);
free(fragment);
}
Shading bertujuan untuk membuat obyek tampak nyata Ada 3 macam model
shading:
- Flat Shading
- Smooth (Gouraud) Shading
- Phong Shading
1. FLAT SHADING
a. Langkah:
- Vektor l, n, dan v dibuat konstan
- Operasi shading dibuat hanya sekali disetiap bidang polygon
- Setiap polygon dibuat menggunakan shading yang sama
b. Kelemahan:
Bila digunakan pada permukaan yang halus, perbedaan shading antar polygon yang
berdekatan sangat jelas
c. Penerapan flat shading:
Pada OpenGL aktifkan model shading berikut
glShadeModel(GL_FLAT);
2. SMOOTH (GORAUD) SHADING
- Setiap vertex mempunyai warna / intensitas sendiri
- Setiap vertex dianggap mempunyai normal
- Normal pada vertex dihitung dari rata-rata normal dari polygon yang
terhubung dengan vertex.
- Smooth (goraud) shading dicapai dengan menginterpolasi intensitas pada
vertex
- Goraud shading dilakukan di vertex shader
a. Penerapan smooth (ground) shading:
Di OpenGL diaktifkan model shading sebagai berikut:
glShadeModel(GL_SMOOTH);
b. Ground shading pada vertex shader:
#version 150 core
// Material dan pencahayaan
uniform vec3 lightPos = vec3(10.0, 10.0, 20.0);
uniform vec3 lightDiffuse = vec3(0.5, 1.0, 1.0);
uniform vec3 lightSpecular = vec3(0.7);
uniform float powerSpecular = 128.0;
uniform vec3 lightAmbient = vec3(0.5, 0.5, 0.5);
varying vec4 color;
void main(void)
{
// hitung vektorposisi model
vec3 P = vec3(gl_ModelViewMatrix* gl_Vertex);
// hitung vektornormal
vec3 N = normalize(gl_NormalMatrix* gl_Normal);
// hitung vektorcahaya
vec3 L = normalize(gl_LightSource[0].position.xyz- P.xyz);
// hitung vektorpandang
vec3 V = normalize(-P);
// hitung vektorrefleksi
vec3 R = reflect(-L, N);
//hitung properti ambient, diffuse dan specular
vec4 ambient = gl_FrontLightProduct[0].ambient;
vec4 diffuse = max(dot(N, L), 0.0) *
gl_FrontLightProduct[0].diffuse;
diffuse = clamp(diffuse, 0.0, 1.0);
vec4 specular = pow(max(dot(R, V), 0.0),
gl_FrontMaterial.shininess) *
gl_FrontLightProduct[0].specular;
specular = clamp(specular, 0.0, 1.0);
//hitung warna untuk digunakan di fragment shaders
color = gl_FrontLightModelProduct.sceneColor+ ambient +
diffuse + specular;
//hitung posisiclipping model
gl_Position= gl_ModelViewProjectionMatrix* gl_Vertex;
}
c. Goraud shading pada fragment shader
#version 150 core
varying vec4 color;
void main(void)
{
// Write incoming color to the framebuffer
gl_FragColor = color;
}
3. PHONG SHADING
- Phong shading dicapai dengan menginterpolasi normal pada vertex.
- Normal pada setiap polygon yang berdekatan diinterpolasi untuk
menghitung normal pada vertex
- Normal disetiap vertex dan edge pada polygon merupakan hasil interpolasi
normal dari vertex yang menghubungkan polygon tersebut Diterapkan
pada fragment shader
a. Penerapan phong shading
1) Phong shading pada vertex shader
#version 150 core
varying vec3 N;
varying vec3 L;
varying vec3 V;
void main(void)
{
// hitung vektor posisi
vec3 P = vec3(gl_ModelViewMatrix * gl_Vertex);
// hitung vektor normal
N = gl_NormalMatrix * gl_Normal;
// hitung vektor cahaya
L = gl_LightSource[0].position.xyz - P.xyz;
// hitung vektor pandang
V = -P;
// hitung posisi clipping model
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
2) Phong shading pada fragment shader
#version 150 core
varying vec3 N;
varying vec3 L;
varying vec3 V;
void main(void)
{
// normalisasi semua vektor
vec3 tN = normalize(N);
vec3 tL = normalize(L);
vec3 tV = normalize(V);
// hitung vektor refleksi
vec3 tR = reflect(-tL, tN);
// hitung komponen diffuse dan specular
vec4 diffuse = max(dot(tN, tL), 0.0) *
gl_FrontLightProduct[0].diffuse;
vec4 specular = pow(max(dot(tR, tV), 0.0),
gl_FrontMaterial.shininess) *
gl_FrontLightProduct[0].specular;
// hitung warna ke frame buffer
gl_FragColor = gl_FrontLightModelProduct.sceneColor +
diffuse + specular;
}
B. NON-PHOTOREALISTIC SHADING
Pada obyek bisa diterapkan efek non-photorealistik shading Biasanya untuk
membuat obyek nampak seperti tampilan kartun Non-photorealistik shading
diterapkan dengan:
- Menggunakan sedikit warna
- Mempertegas tepian obyek
- Penerapan non-photorealistic shading
vec4 color1 = vec4(1.0, 1.0, 0.0, 1.0); // yellow
vec4 color2 = vec4(1.0, 0.0, 0.0, 1.0); // red
// efek warna yang berbeda
if (dot(L, N) > 0.5)
gl_FrontColor = color1;
else
gl_FrontColor = color2;
Atau
// efek silhouette
vec4 color3 = vec4(0.0, 0.0, 0.0, 1.0);
// black if (abs(dot(V, N) < 0.01))
glFrontColor = color3;
Contoh Penerapan Program Lightning
void setShaders()
{
char* vertex = readShaders("praktikum03_goraud.vert");
char* fragment = readShaders("praktikum03_goraud.frag");
vertexShaders = glCreateShader(GL_VERTEX_SHADER);
fragmentShaders = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vertexShaders, 1, (const char**)&vertex, 0);
glShaderSource(fragmentShaders, 1, (const char**)&fragment, 0);
glCompileShader(vertexShaders);
glCompileShader(fragmentShaders);
programShaders = glCreateProgram();
glAttachShader(programShaders, vertexShaders);
glAttachShader(programShaders, fragmentShaders);
glBindAttribLocation(programShaders, 0, "in_Position");
glBindAttribLocation(programShaders, 1, "in_Color");
glLinkProgram(programShaders);
glUseProgram(programShaders);
free(vertex);
free(fragment);
}