http://blog.csdn.net/a3070173/archive/2008/11/13/3290091.aspx

使用Shader实现菲涅尔和颜色色散效果很简单,在Cg教程和OpenGL Shader Language都有较
为详细的介绍,个人觉得需要注意的地方是反射向量和折射向量应该在世界空间中进行计算,
在模型空间和照相机空间中计算都会导致错误的结果.

具体着色器代码:
顶点着色器:
const float g_fEta = 0.66; // 空气和玻璃的折射材质比例
const float g_fEtaR = 0.65;
const float g_fEtaG = 0.67;
const float g_fEtaB = 0.69;
const float g_fFresnelPower = 0.8;
const float f = ((1.0-g_fEta) * (1.0-g_fEta)) / ((1.0+g_fEta) * (1.0+g_fEta));
uniform vec3 g_vec3CamerePositionInWorld;
uniform int g_iRenderMode;
varying vec3  g_vec3Reflect;
varying vec3  g_vec3Refract;
varying vec3  g_vec3Refract_R;
varying vec3  g_vec3Refract_G;
varying vec3  g_vec3Refract_B;
varying float g_fFresnelRatio;
void main()
{
    vec3 NV = normalize(gl_Vertex.xyz - g_vec3CamerePositionInWorld);
 vec3 N = gl_Normal;
 
 // 计算Fresnel比例
    g_fFresnelRatio = f + (1.0 - f) * pow((1.0 - dot(-NV, N)), g_fFresnelPower);
 // 计算反射和折射光线
 if (g_iRenderMode == 0)
 {
  g_vec3Reflect = reflect(NV, N);
  g_vec3Reflect.y = -g_vec3Reflect.y;
 }
 else if (g_iRenderMode == 1)
 {
  g_vec3Refract = refract(NV, N, g_fEta);
  g_vec3Refract.y = -g_vec3Refract.y;
 }
 else if (g_iRenderMode == 2)
 {
  g_vec3Reflect = reflect(NV, N);
  g_vec3Reflect.y = -g_vec3Reflect.y;
  g_vec3Refract = refract(NV, N, g_fEta);
  g_vec3Refract.y = -g_vec3Refract.y;
 }
 else
 {
  g_vec3Reflect = reflect(NV, N);
  g_vec3Reflect.y = -g_vec3Reflect.y;
  g_vec3Refract_R = refract(NV, N, g_fEtaR);
  g_vec3Refract_R.y = -g_vec3Refract_R.y;
  g_vec3Refract_G = refract(NV, N, g_fEtaG);
  g_vec3Refract_G.y = -g_vec3Refract_G.y;
  g_vec3Refract_B = refract(NV, N, g_fEtaB);
  g_vec3Refract_B.y = -g_vec3Refract_B.y;
 }
    gl_Position = ftransform();
}
}
片元着色器:
varying vec3  g_vec3Reflect;
varying vec3  g_vec3Refract;
varying vec3  g_vec3Refract_R;
varying vec3  g_vec3Refract_G;
varying vec3  g_vec3Refract_B;
varying float g_fFresnelRatio;
uniform samplerCube g_Cubemap;
uniform int g_iRenderMode;
void main()
{
 vec3 vec3FinalColor = vec3(0.0);
 
 if (g_iRenderMode == 0)
 {
  vec3FinalColor = vec3(textureCube(g_Cubemap, g_vec3Reflect));
 }
 else if (g_iRenderMode == 1)
 {
  vec3FinalColor = vec3(textureCube(g_Cubemap, g_vec3Refract));
 }
 else if (g_iRenderMode == 2)
 {
  vec3 vec3ReflectColor = vec3(textureCube(g_Cubemap, g_vec3Reflect));
  vec3 vec3RefractColor = vec3(textureCube(g_Cubemap, g_vec3Refract));
  vec3FinalColor = mix(vec3RefractColor, vec3ReflectColor, g_fFresnelRatio);
 }
 else
 {
  vec3 vec3ReflectColor = vec3(textureCube(g_Cubemap, g_vec3Reflect));
  vec3 vec3RefractColor = vec3(0.0);
  vec3RefractColor.r = vec3(textureCube(g_Cubemap, g_vec3Refract_R)).r;
  vec3RefractColor.g = vec3(textureCube(g_Cubemap, g_vec3Refract_G)).g;
  vec3RefractColor.b = vec3(textureCube(g_Cubemap, g_vec3Refract_B)).b;
  vec3FinalColor = mix(vec3RefractColor, vec3ReflectColor, g_fFresnelRatio);
 }
 
    gl_FragColor = vec4(vec3FinalColor, 1.0);
}

Demo效果图:

exe文件:http://www.fileupyours.com/view/219112/GLSL/Fresnel%20And%20Chromatic%20aberration%20Demo.rar

最新文章

  1. ajax实现局部刷新
  2. 理解JAVA - 面向对象(object) - 属性,方法
  3. 关于Linux 下 Mysql 远程访问时出现的Access denied for user '用户名'@'IP地址' (using password:NO)
  4. Python的闭包
  5. SOAP: java+xfire(web service) + php客户端
  6. PAT 1038 体验Python之美
  7. 基于HBase0.98.13搭建HBase HA分布式集群
  8. [转载]为什么使用%lf读取double型的值,而用%f进行显示?
  9. Swift - 19 - 字典的初始化
  10. UVA196-Spreadsheet(拓扑排序)
  11. python 循环使用 while 或 for 语句实现用户名密码输错三次退出
  12. pymongo中的连接操作:Connection()与MongoClient()
  13. xml 转换成对象(采用反射机制对对对象属性赋值)
  14. cp2102 驱动 win7x64 -2018
  15. canvas刮刮乐游戏等
  16. linux学习笔记-目录结构(2)
  17. Netty 内存回收之 noCleaner 策略
  18. BZOJ4766:文艺计算姬(矩阵树定理)
  19. CSS属性书写顺序及命名规则
  20. maven mvn package 打包项目时,出现错误导致失败的解决方法

热门文章

  1. POJ 1251 Jungle Roads
  2. Generate Parentheses java实现
  3. util-判断当前年份所处的季度,并返回当前季度开始的月份
  4. Delphi 操作word 表格
  5. htmlcss笔记--标签默认值样式重置css reset(2)
  6. c++ 概念及学习/c++ concept&learning(一)
  7. NetAdvantage 笔记
  8. Codevs No.1281 Xn数列
  9. leetcode@ [354] Russian Doll Envelopes (Dynamic Programming)
  10. vim 操作