Cube Mapping Example

1.有一种称为“环境映射”(environment mapping)的技术可以不依赖ray-trace而实现复杂环境我反射,这种技术使用一个或多个纹理来模拟外部环境的反射,这种技术最适合于应用到具有高亮镜面的物体。

2.有多种方法来实现环境纹理映射,包括球面纹理映射( SPHERE MAPPING )和立方体纹理映射( CUBE MAPPING ),这两者在标准的OPENGL中的都是支持的。本例我们使用GLSL的CUBE MAPPING 方法来实现环境纹理,我们假设(注意是假设assume)在物体的表层有一层类似于物体散射色的底色,这个底色的散射部分与环境反射光相融合形成了每个像素的最终颜色。

  

2.立方体纹理映射可以想像成一由6副2D纹理组成的立体体,物体处于该立方体的正中心处,并以该点为原点,引出一个3维的坐标系统出来,显卡可以把由该坐标系统产生的3维纹理坐标当作一个方向向量来看待,自动的计算出这个向量与立方体某面的交点,并将交点所在的颜色值返回。这也是GLSL内置函数中textureCube的原理,所以当我们使用textureCube函数时,需要给他传递当前顶点的反射向量以及环境纹理的sample值。

 

3.顶点着色器代码

这里很简单,就做了两件事,计算顶点的光强和反射光向量,并将其传给片断着色器。注意光强里并没有计算反射光。

varying vec3 ReflectDir; varying float LightIntensity; uniform vec3 LightPos; void main() { gl_Position = ftransform(); vec3 normal = normalize(gl_NormalMatrix * gl_Normal); vec4 pos = gl_ModelViewMatrix * gl_Vertex; vec3 eyeDir = pos.xyz; ReflectDir = reflect(eyeDir, normal); LightIntensity = max(dot(normalize(LightPos - eyeDir), normal),0.0); }

 

4.片断着色器

(1)BaseColor就是前面讲的底色,其实也可以不要,那就是不存在任何融合计算,完全的纹理贴图了。

(2)MixRatio 底色与环境纹理色的融合值:mix(envColor, base, MixRatio);mixRatio越大纹理越明显,mixRatio越小,底色越突出,这个可以表现整个光照的强暗。
(3)    vec3 envColor = vec3(textureCube(EnvMap, ReflectDir));

 textureCube内置函数,本例的核心。通过该点的反射向量与环境贴图,得到环境纹理对应的颜色值。底色乘上光强,再融合这个环境环境颜色值就OK了。

uniform vec3 BaseColor; uniform float MixRatio; uniform samplerCube EnvMap; varying vec3 ReflectDir; varying float LightIntensity; void main() { // Look up environment map value in cube map vec3 envColor = vec3(textureCube(EnvMap, ReflectDir)); // Add lighting to base color and mix vec3 base = LightIntensity * BaseColor; envColor = mix(envColor, base, MixRatio); gl_FragColor = vec4(envColor, 1.0); }

注意此处的环境贴图是 samplerCube,所以在opengl程序中应该建立的是一个GL_TEXTURE_CUBE_MAP,具体代码可如下操作:

glBindtexture( GL_TEXTURE_CUBE_MAP,  tex1 );

glTexParamteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,  GL_CLAMP_TO_EDGE );

glTexParamteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,  GL_CLAMP_TO_EDGE );

glTexParamteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R,  GL_CLAMP_TO_EDGE );

glTexParamteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,  GL_LINEAR );

glTexParamteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_FILTER,  GL_LINEAR );

glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );

 

glTexImage( GL_TEXTURE_CUBE_MAP_POSITIVE_X )......

glTexImage( GL_TEXTURE_CUBE_MAP_NEGETIVE_X )......

glTexImage( GL_TEXTURE_CUBE_MAP_POSITIVE_Y )......

glTexImage( GL_TEXTURE_CUBE_MAP_NEGETIVE_Y )......

glTexImage( GL_TEXTURE_CUBE_MAP_POSITIVE_Z )......

glTexImage( GL_TEXTURE_CUBE_MAP_NEGETIVE_Z )......

 

glEnable( GL_TEXTURE_CUBE_MAP );

 

这种环境贴图也有很多不利的地方,比如模拟环境的贴图一般是静态图片,所以环境不能发生变化。还有如果同时渲染多个物体,每个物体不能把其他的物体反射到表面,想要达到这种效果要使用ray tracing(光线跟踪)或 render to texture(渲染到纹理)技术。

你可能感兴趣的:(filter,UP,float)