www.pudn.com > AndreasHalm-src.zip > cube_sides_bm4p.fragmentshader


// specular+cubemap+texture+bumpmap shader 
// uses the varyings below to calculate specular reflection 
// the cube map is multiplied into the diffuse channel 
// where texture 0 is not transparent: 
// - a different specular lighting is applied, so that the 
//   texture is always readable. the lighting has a smaller 
//   "specular cone" and is less bright (0.5) 
// - the cubemap affects the diffuse lighting to a smaller 
//   degree (0.3) 
 
// the bumpmapping is calculated via accessing the texture 
// at the pixels in four directions. the difference in 
// alpha value is used to calculate a deviation vector 
// which is added to the current normal before normalization. 
// we don't need the trick we used with 2p-bumpmapping 
// and the texture is drawn as-is. on the other hand, we 
// need two more texture accesses. 
 
const vec4 AMBIENT = vec4( 0.1, 0.1, 0.1, 1.0 ); 
const vec4 SPECULAR = vec4( 1.0, 1.0, 1.0, 1.0 ); 
 
varying vec4 Cd; 
varying vec4 V_eye; 
varying vec4 L_eye; 
varying vec4 N_eye; 
varying vec3 eyespace_position; 
 
uniform sampler2D tex0; 
uniform samplerCube texCube; 
 
// vectors in s,t direction (compared to tex0) 
varying vec4 tex0_s_eye; 
varying vec4 tex0_t_eye; 
 
void main(void) 
{ 
   // compute height/elevation 
   vec2 fw = fwidth(gl_TexCoord[0].st); 
   //vec2 fw = vec2(1.0/256.0,1.0/256.0); 
   vec2 tex_coord_top    = vec2( gl_TexCoord[0].s, gl_TexCoord[0].t-fw.t ); 
   vec2 tex_coord_left   = vec2( gl_TexCoord[0].s-fw.s, gl_TexCoord[0].t ); 
   vec2 tex_coord_bottom = vec2( gl_TexCoord[0].s, gl_TexCoord[0].t+fw.t ); 
   vec2 tex_coord_right  = vec2( gl_TexCoord[0].s+fw.s, gl_TexCoord[0].t ); 
   vec4 tex_top    = texture2D(tex0,tex_coord_top   ); 
   vec4 tex_left   = texture2D(tex0,tex_coord_left  ); 
   vec4 tex_bottom = texture2D(tex0,tex_coord_bottom); 
   vec4 tex_right  = texture2D(tex0,tex_coord_right ); 
   float s_elevation = -0.5*(tex_right.a-tex_left.a); 
   float t_elevation = -0.5*(tex_bottom.a-tex_top.a); 
   vec4 elevation = s_elevation*tex0_s_eye + t_elevation*tex0_t_eye; 
   // the texture at this pixel 
   vec4 texture = texture2D(tex0,gl_TexCoord[0].st); 
   // lighting 
   vec3 V = normalize(vec3(V_eye)); 
   vec3 L = normalize(vec3(L_eye)); 
   vec3 N = normalize(vec3(N_eye)+vec3(elevation)); 
   float diffuse = clamp(dot(L, N), 0.0, 1.0); 
   vec3 H = normalize(L + V); 
   float specular = clamp(pow(dot(N, H), 20.0), 0.0, 1.0); 
   float sharp_specular = smoothstep(0.9, 0.999, specular); 
   // cubemap stuff 
   vec3 u = normalize(eyespace_position); 
   vec3 texcube_coord = reflect(u,vec3(N_eye)); 
   vec4 texture_cubemap = textureCube(texCube,texcube_coord); 
   // the cubemap gets multiplied into the diffuse color 
   vec4 color = AMBIENT + (Cd*diffuse*texture_cubemap) + (SPECULAR*specular); 
   // modify the lighting model for textured areas 
   vec4 tex0_cubemap_modifier = vec4(0.7,0.7,0.7,1.0) + texture_cubemap*0.3; 
   vec4 texture_lit = AMBIENT + (texture*diffuse*tex0_cubemap_modifier) + (SPECULAR*0.5*sharp_specular); 
   // mix via texture alpha 
   vec3 col = mix(color.rgb,texture_lit.rgb,texture.a); 
   gl_FragColor = vec4(col,color.a); 
}