这篇文章里讲一下在GLSL如何使用函数和子程序(subroutines)。
在GLSL中使用函数
GLSL支持函数,它们的语法结构和C很相似。但是调用约定会有所不同。下面,我们以一个普通的ADS(ambient,diffuse,specular)shader为例,熟悉一下GLSL中函数的用法。
Vertex Shader:
#version 400
layout (location = 0)in vec3 VertexPosition;
layout (location = 1)in vec3 VertexNormal;
out vec3LightIntensity;
struct LightInfo {
vec4 Position; // Light position in eyecoords.
vec3 La; // Ambient light intensity
vec3 Ld; // Diffuse light intensity
vec3 Ls; // Specular light intensity
};
uniform LightInfoLight;
struct MaterialInfo {
vec3 Ka; // Ambient reflectivity
vec3 Kd; // Diffuse reflectivity
vec3 Ks; // Specular reflectivity
float Shininess; // Specular shininessfactor
};
uniform MaterialInfoMaterial;
uniform mat4ModelViewMatrix;
uniform mat3NormalMatrix;
uniform mat4ProjectionMatrix;
uniform mat4 MVP;
void getEyeSpace( outvec3 norm, out vec4 position )
{
norm = normalize( NormalMatrix *VertexNormal);
position = ModelViewMatrix *vec4(VertexPosition,1.0);
}
vec3 phongModel( vec4position, vec3 norm )
{
vec3 s = normalize(vec3(Light.Position -position));
vec3 v = normalize(-position.xyz);
vec3 r = reflect( -s, norm );
vec3 ambient = Light.La * Material.Ka;
float sDotN = max( dot(s,norm), 0.0 );
vec3 diffuse = Light.Ld * Material.Kd *sDotN;
vec3 spec = vec3(0.0);
if( sDotN > 0.0 )
spec = Light.Ls * Material.Ks *
pow( max( dot(r,v), 0.0 ),Material.Shininess );
return ambient + diffuse + spec;
}
void main()
{
vec3 eyeNorm;
vec4 eyePosition;
// Get the position and normal in eye space
getEyeSpace(eyeNorm, eyePosition);
// Evaluate the lighting equation.
LightIntensity = phongModel( eyePosition,eyeNorm );
gl_Position = MVP * vec4(VertexPosition,1.0);
}
上面的shader略微有点长……没事,我们一点一点来看。
layout (location = 0)in vec3 VertexPosition;
layout (location = 1)in vec3 VertexNormal;
out vec3LightIntensity;
struct LightInfo {
vec4 Position; // Light position in eyecoords.
vec3 La; // Ambient light intensity
vec3 Ld; // Diffuse light intensity
vec3 Ls; // Specular light intensity
};
uniform LightInfoLight;
struct MaterialInfo {
vec3 Ka; // Ambient reflectivity
vec3 Kd; // Diffuse reflectivi