GLSL实现Fresnel And Chromatic aberration 【转】
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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2011-06-24 std::set用法(转)
2011-06-24 STL中map用法详解(转)