Graphics Reference
In-Depth Information
The first part of the fragment shader consists of a series of uniform declarations
for the ambient, diffuse, and specular colors. These values are stored in the
uniform variables u_ambient , u_diffuse , and u_specular , respectively.
The shader is also configured with two samplers, s_baseMap and s_bumpMap ,
which are bound to a base color map and the normal map, respectively.
The first part of the fragment shader fetches the base color from the base
map and the normal values from the normal map. As described earlier,
the normal vector fetched from the texture map is scaled and biased and
then normalized so that it is a unit vector with components in the [−1, 1]
range. Next, the light vector and view vector are normalized and stored
in lightDirection and viewDirection . Normalization is necessary
because of the way fragment shader input variables are interpolated across
a primitive. The fragment shader input variables are linearly interpolated
across the primitive. When linear interpolation is done between two vectors,
the results can become denormalized during interpolation. To compensate
for this artifact, the vectors must be normalized in the fragment shader.
Lighting Equations
At this point in the fragment shader, we now have a normal, light vector,
and direction vector all normalized and in the same space. This gives
us the inputs needed to compute the lighting equations. The lighting
computations performed in this shader are as follows:
Ambient = k Ambient × C Base
Diffuse = k Diffuse × N L × C Base
Specular = k Specular × pow(max( R V , 0.0), k Specular Power
The k constants for ambient, diffuse, and specular colors come from the
u_ambient , u_diffuse , and u_specular uniform variables. The C Base is
the base color fetched from the base texture map. The dot product of the
light vector and the normal vector, N • L , is computed and stored in the
nDotL variable in the shader. This value is used to compute the diffuse
lighting term. Finally, the specular computation requires R , which is the
reflection vector computed from the equation
R = 2 × N × ( N L ) − L
Notice that the reflection vector also requires N L , so the computation
used for the diffuse lighting term can be reused in the reflection vector
computation. Finally, the lighting terms are stored in the ambient ,
diffuse , and specular variables in the shader. These results are summed
 
 
Search WWH ::




Custom Search