« Shader快速复习:Per Pixel Lighting(逐像素光照)WINDOWS游戏编程大师技巧笔记之——学海无崖 »

Shader快速复习:Cube Mapping(立方环境贴图)

Shader快速复习,巩固知识,加强感觉。今天的内容是Cube Mapping(立方环境贴图)。——ZwqXin.com

广告:Shader快速复习:Per Pixel Lighting(逐象素光照)

本文来源于 ZwqXin (http://www.zwqxin.cn/), 转载请注明
      原文地址:http://www.zwqxin.cn/archives/shaderglsl/review-cube-mapping-shader.html

与Cube map认识挺久了,至少在认识GLSL之前就认识了。在固定管道上应用cubemap也比较简单,不过既然与今天的主题无关,就不多说了(给个连接:CUBE MAP OPENGL TUTORIAL)。

Cube map技术说到底就是用一个虚拟的立方体(cube)包围住物体,眼睛到物体某处的向量eyevec经过反射(以该处的法线为对称轴),反射向量reflectvec射到立方体上,就在该立方体上获得一个纹素了(见下图)。明显,我们需要一个类似天空盒般的6张纹理贴在这个虚拟的立方体上。按CUBE MAPPING原意,就是一种enviroment map,因此把周围场景渲染到这6张纹理里是“正统”的。也就是每次渲染时,都作一次离线渲染,分别在每个矩形中心放置相机“拍下”场景,用FBO渲染到纹理,然后把这张纹理作为一个cube map对象的六纹理之一。这样即使是动态之物也能被映射到物体表面了(虽然缺点是不能映射物体自身的任何部分)。

以上这些都需要在opengl实现里完成,而我接下来只想应用shader,就只用一个天空盒的六张图好了,也暂不设置opengl实现了(反正rendermonkey里内置了些cubemap)。

  1. uniform vec4 eyepos;
  2. varying vec3 reflectvec;
  3.  
  4. void main(void)
  5. {
  6.    vec4 pos = normalize(gl_ModelViewMatrix * gl_Vertex);
  7.    pos = pos / pos.w;
  8.    
  9.    vec3 eyevec = normalize(eyepos.xyz - pos.xyz);
  10.    vec3 norm = normalize(gl_NormalMatrix * gl_Normal);
  11.    
  12.    reflectvec = reflect(-eyevec, norm);
  13.    
  14.    gl_Position = ftransform();
  15. }

一切都很单纯,在vertex shader里,依靠传入的眼睛位置计算单位化视线向量eyevec,并依靠正确处理好的顶点法线作为对称轴求出反射向量,注意reflect函数接受一个入射向量,产出出射向量,而-eyevec才是入射向量(入射点 - 光线发出点[眼睛])。

  1. uniform samplerCube cubemap;
  2. varying vec3 reflectvec;
  3.  
  4. void main(void)
  5. {
  6.    vec4 texcolor = textureCube(cubemap, reflectvec);
  7.  
  8.    gl_FragColor = texcolor;
  9. }

fragment shader更加简洁,不过就是检取一个纹理对象而已。不过用的检索器是samplerCube而不是单纯的二维纹理检索器sampler2D。颜色提取函数也是cube map版本的textureCube,索引就正是反射向量!显然这里不需要单位化的向量也可。物体象素颜色就取用纹素颜色就可以了。当然可以做些其他处理,譬如加了天蓝色散射光最后进行混合。结果分别如下:

zwqxin.com  cubemap shader
zwqxin.com  cubemap shader
(换模型,换cubemap后:)
zwqxin.com  cubemap shader

(参考资料:OpenGL Shading Language Secong Edition)

本文来源于 ZwqXin (http://www.zwqxin.cn/), 转载请注明
      原文地址:http://www.zwqxin.cn/archives/shaderglsl/review-cube-mapping-shader.html

  • quote 1.zyc
  • eyepos的值应该怎么设置?我是在opengl ES2.0里面做的,没有设置lookat的函数
    zwqxin 于 2012-5-8 22:39:44 回复
    摄像机的位置。glu的lookat函数其实是设置并左乘一个矩阵,这些都可以自己去做的,或者你去找一些矩阵库帮你完成这样的事情,譬如glm。
  • 2012-5-8 9:52:37 回复该留言

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

IE下本页面显示有问题?

→点击地址栏右侧【兼容视图】←

日历

Search

网站分类

最新评论及回复

最近发表

Powered By Z-Blog 1.8 Walle Build 100427

Copyright 2008-2024 ZwqXin. All Rights Reserved. Theme edited from ipati.