The result will look like the following image:
Getting ready
The vertex position, normal, and texture coordinates must be provided to the vertex shader from the OpenGL application. The position should be provided at location 0, the normal at location 1, and the texture coordinates at location 2. As in previous examples, the lighting parameters must be set from the OpenGL application via the appropriate uniform variables.
How to do it...
To create a shader program that discards fragments based on a square lattice (as in the preceding image), use the following code:
Use the following code for the vertex shader:
#version 400
layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;
layout (location = 2) in vec2 VertexTexCoord;
out vec3 FrontColor;
out vec3 BackColor;
out vec2 TexCoord;
struct LightInfo {
vec4 Position; // Light position in eye coords.
vec3 La; // Ambient light intensity
vec3 Ld; // Diffuse light intensity
vec3 Ls; // Specular light intensity
};
uniform LightInfo Light;
struct MaterialInfo {
vec3 Ka; // Ambient reflectivity
vec3 Kd; // Diffuse reflectivity
vec3 Ks; // Specular reflectivity
float Shininess; // Specular shininess factor
};
uniform MaterialInfo Material;
uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 MVP;
void getEyeSpace( out vec3 norm, out vec4 position )
{
norm = normalize( NormalMatrix * VertexNormal);
position = ModelViewMatrix * vec4(VertexPosition,1.0);
}
vec3 phongModel( vec4 position, vec3 norm )
{
// The ADS shading calculations go here (see: "Using
// functions in shaders," and "Implementing
// per-vertex ambient, diffuse and specular (ADS) shading")
...
}
void main()
{
vec3 eyeNorm;
vec4 eyePosition;
TexCoord = VertexTexCoord;
// Get the position and normal in eye space
getEyeSpace(eyeNorm, eyePosition);
FrontColor = phongModel( eyePosition, eyeNorm );
BackColor = phongModel( eyePosition, -eyeNorm );
gl_Position = MVP * vec4(VertexPosition,1.0);
}
Use the following code for the fragment shader:
#version 400
in vec3 FrontColor;
in vec3 BackColor;
in vec2 TexCoord;
layout( location = 0 ) out vec4 FragColor;
void main() {
const float scale = 15.0;
bvec2 toDiscard = greaterThan( fract(TexCoord * scale),
vec2(0.2,0.2) );
if( all(toDiscard) )
discard;
if( gl_FrontFacing )
FragColor = vec4(FrontColor, 1.0);
else
FragColor = vec4(BackColor, 1.0);
}
Compile and link both shaders within the OpenGL application, and install the shader program prior to rendering.
layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;
layout (location = 2) in vec2 VertexTexCoord;
out vec3 FrontColor;
out vec3 BackColor;
out vec2 TexCoord;
struct LightInfo {
vec4 Position; // Light position in eye coords.
vec3 La; // Ambient light intensity
vec3 Ld; // Diffuse light intensity
vec3 Ls; // Specular light intensity
};
uniform LightInfo Light;
struct MaterialInfo {
vec3 Ka; // Ambient reflectivity
vec3 Kd; // Diffuse reflectivity
vec3 Ks; // Specular reflectivity
float Shininess; // Specular shininess factor
};
uniform MaterialInfo Material;
uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 MVP;
void getEyeSpace( out vec3 norm, out vec4 position )
{
norm = normalize( NormalMatrix * VertexNormal);
position = ModelViewMatrix * vec4(VertexPosition,1.0);
}
vec3 phongModel( vec4 position, vec3 norm )
{
// The ADS shading calculations go here (see: "Using
// functions in shaders," and "Implementing
// per-vertex ambient, diffuse and specular (ADS) shading")
...
}
void main()
{
vec3 eyeNorm;
vec4 eyePosition;
TexCoord = VertexTexCoord;
// Get the position and normal in eye space
getEyeSpace(eyeNorm, eyePosition);
FrontColor = phongModel( eyePosition, eyeNorm );
BackColor = phongModel( eyePosition, -eyeNorm );
gl_Position = MVP * vec4(VertexPosition,1.0);
}
in vec3 FrontColor;
in vec3 BackColor;
in vec2 TexCoord;
layout( location = 0 ) out vec4 FragColor;
void main() {
const float scale = 15.0;
bvec2 toDiscard = greaterThan( fract(TexCoord * scale),
vec2(0.2,0.2) );
if( all(toDiscard) )
discard;
if( gl_FrontFacing )
FragColor = vec4(FrontColor, 1.0);
else
FragColor = vec4(BackColor, 1.0);
}