顶点着色, 正常处理顶点
// ADS Point lighting Shader
// Vertex Shader
// Richard S. Wright Jr.
// OpenGL SuperBible
#version 130
// Incoming per vertex... position and normal
in vec4 vVertex;
in vec3 vNormal;
in vec2 vTexCoords0;
uniform mat4 mvpMatrix;
uniform mat4 mvMatrix;
uniform mat3 normalMatrix;
uniform vec3 vLightPosition;
// Color to fragment program
smooth out vec3 vVaryingNormal;
smooth out vec3 vVaryingLightDir;
smooth out vec2 vVaryingTexCoord;
void main(void)
{
// Pass on the texture coordinates
vVaryingTexCoord = vTexCoords0;
// Get surface normal in eye coordinates
vVaryingNormal = normalMatrix * vNormal;
// Get vertex position in eye coordinates
vec4 vPosition4 = mvMatrix * vVertex;
vec3 vPosition3 = vPosition4.xyz / vPosition4.w;
// Get vector to light source
vVaryingLightDir = normalize(vLightPosition - vPosition3);
// Don't forget to transform the geometry!
gl_Position = mvpMatrix * vVertex;
}
片断着色:discard指令
// ADS Point lighting Shader
// Fragment Shader
// Richard S. Wright Jr.
// OpenGL SuperBible
#version 130
out vec4 vFragColor;
uniform vec4 ambientColor;
uniform vec4 diffuseColor;
uniform vec4 specularColor;
uniform sampler2D cloudTexture; // 存放dissvole纹理
uniform float dissolveFactor; // 每帧都变化的阈值
smooth in vec3 vVaryingNormal;
smooth in vec3 vVaryingLightDir;
smooth in vec2 vVaryingTexCoord;
void main(void)
{
vec4 vCloudSample = texture(cloudTexture, vVaryingTexCoord);
if(vCloudSample.r < dissolveFactor)
discard; // 如果小于阈值,就抛弃该片断
// Dot product gives us diffuse intensity
float diff = max(0.0, dot(normalize(vVaryingNormal), normalize(vVaryingLightDir)));
// Multiply intensity by diffuse color, force alpha to 1.0
vFragColor = diff * diffuseColor;
// Add in ambient light
vFragColor += ambientColor;
// Specular Light
vec3 vReflection = normalize(reflect(-normalize(vVaryingLightDir), normalize(vVaryingNormal)));
float spec = max(0.0, dot(normalize(vVaryingNormal), vReflection));
if(diff != 0) {
float fSpec = pow(spec, 128.0);
vFragColor.rgb += vec3(fSpec, fSpec, fSpec);
}
}
纹理图片:
运行效果截图:
