GLSL实现Ambient Occlusion 【转】
http://blog.csdn.net/a3070173/archive/2008/11/04/3221181.aspx
相信使用OpenGl或DirectX3D的朋友都知道到固定功能管线在光照处理主要由环境光,散射光和镜面光构成,这样一个光照处理模型在被光 的地方将以统一的环境光进行着色,导致一种不自然的不真实效果.本文介绍的Ambient Occlusion方法将使用不当预计算的方式离线的生成模型的AO图,并在片元着色器中将对此AO图进行采样的结果与环境光和散射光效果进行相乘以适当 削弱环境光和散射光的强度,以增加模型的真实感.
那么什么是AO图呢?AO图其实是Ambient Occlusion纹理图的简称,其包含了模型各顶点的AO因子(即削弱因子).关于此削弱因子是如何计算的请参考http://www.ozone3d.net/tutorials/ambient_occlusion.php.这里只介绍效果的具体实现.
由于这个效果主要在GLSL着色器上进行实现所以以下贴出的Ambient Occlusion着色器代码.
顶点着色器:
uniform float g_fScale;
varying vec2 g_vec2TexCoord0;
varying vec3 g_vec3Normal;
varying vec3 g_vec3Vertex;
void main()
{
g_vec2TexCoord0 = vec2(gl_MultiTexCoord0.s, 1.0 - gl_MultiTexCoord0.t);
g_vec3Normal = vec3(gl_Normal);
g_vec3Vertex = vec3(gl_Vertex);
gl_Position = ftransform();
}
片元着色器:
const vec3 g_vec3AmbientResult = vec3(0.2, 0.2, 0.2);
const vec3 g_vec3DiffuseResult = vec3(0.64, 0.64, 0.64);
const vec3 g_vec3SpecularResult = vec3(1.0, 1.0, 1.0);
const float g_fShininess = 100.0;
uniform vec3 g_vec3CameraPositinInModel; // 模型空间照相机位置
uniform vec3 g_vec3LightPositionInModel; // 模型空间光源位置
uniform sampler2D g_AmbientOcclusion;
uniform bool g_bUseAmbientGene; // 是否使用Ambient Occlusion的标志
varying vec2 g_vec2TexCoord0;
varying vec3 g_vec3Normal;
varying vec3 g_vec3Vertex;
void main()
{
// 采样Ambient Occlusion因子
float fAmbientGene = texture2D(g_AmbientOcclusion, g_vec2TexCoord0).r;
// 计算散射因子
vec3 L = normalize(g_vec3LightPositionInModel - g_vec3Vertex);
vec3 N = normalize(g_vec3Normal);
float fDiffuseGene = max(dot(N, L), 0.0);
// 计算镜面光因子
float fSpecularGene = 0.0;
if (fDiffuseGene > 0.0)
{
vec3 V = normalize(g_vec3CameraPositinInModel - g_vec3Vertex);
vec3 H = normalize(L + V);
fSpecularGene = pow(max(dot(N, H), 0.0), g_fShininess);
}
// 计算最终颜色
if (g_bUseAmbientGene)
{
// Ambient Occlusion只影响环境和散射选项
gl_FragColor = vec4(fAmbientGene*(g_vec3AmbientResult +
fDiffuseGene*g_vec3DiffuseResult) +
fSpecularGene*g_vec3SpecularResult,
1.0);
}
else
{
gl_FragColor = vec4(g_vec3AmbientResult +
fDiffuseGene*g_vec3DiffuseResult +
fSpecularGene*g_vec3SpecularResult,
1.0);
}
}
在整个着色过程中唯一需要注意的是由于AO图是上下颠倒的,所以带计算纹理坐标时需要将t坐标被1.0f相减.
Demo效果图:
不启动Ambient Occlusion:

启动Ambient Occlusion:

GLSL实现Ambient Occlusion 【转】的更多相关文章
- Cesium源码剖析---Ambient Occlusion(环境光遮蔽)
Ambient Occlusion简称AO,中文没有太确定的叫法,一般译作环境光遮蔽.百度百科上对AO的解释是这样的:AO是来描绘物体和物体相交或靠近的时候遮挡周围漫反射光线的效果,可以解决或改善漏光 ...
- Ambient Occlusion
一般在光照模型中,ambient light的计算方法为:A = l * m,其中l表示表面接收到的来自光源的ambient light的总量,而m表示表面接收到ambient light后,反射和吸 ...
- TSSAO Temporal Screen-Space Ambient Occlusion (Unity3d 5 示例实现)
前提 环境光(ambient occlusion)是一种GI,其简化形式SSAO可以用“微量高效”来形容,消耗得很少,得到的效果很好.环 境光遮蔽(ambient occlusion)的本质是计算在一 ...
- [帖子收集]环境光遮蔽(Ambient Occlusion)
环境光遮蔽,效果示例图 图片左边是一条龙的简单模型,呈现在一个均匀照明的环境中.尽管模型中有一些明暗不同的区域,但大部分光照都是均匀的.虽然模型有着相当复杂的几何形状,但看上去比较光滑平坦,没有明显的 ...
- Dynamic Ambient Occlusion and Indirect Lighting
This sample was presented on the Nvida witesite, which detail a new idea to calculate the ambient oc ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二十一章:环境光遮蔽(AMBIENT OCCLUSION)
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二十一章:环境光遮蔽(AMBIENT OCCLUSION) 学习目标 ...
- OpenGL 3 and OpenGL 4 with GLSL
Here are some OpenGL samples with advance features. NeHe OpenGL tutorial focus on the OpenGL fixed p ...
- UE4命令行使用,解释
命令行在外部 从命令行运行编辑项目 1 导航到您的[LauncherInstall][VersionNumber]\Engine\Binaries\Win64 目录中. 2 右键单击上 UE4Edit ...
- OpenGL.教程
5.第五课:带纹理的立方体.html(http://www.opengl-tutorial.org/cn/beginners-tutorials/tutorial-5-a-textured-cube/ ...
随机推荐
- 漂亮灵活设置的jquery通知提示插件toastr
toastr是一款非常棒的基于jquery库的非阻塞通知提示插件,toastr可设定四种通知模式:成功,出错,警告,提示,而提示窗口的位置,动画效果都可以通过能数来设置,在官方站可以通过勾选参数来生成 ...
- RMQ(dp)
我一开始是不知道有这么个东西,但是由于最近在学习后缀数组,碰到一道题需要用到后缀数组+RMQ解决的所以不得不学习了. 原理:用A[1...n]表示一组数,dp[i][j]表示从A[i]到A[i+2^j ...
- [Everyday Mathematics]20150115
试计算积分 $$\bex \int_{-\pi}^\pi \frac{\sin nx}{(1+2^x)\sin x}\rd x, \eex$$ 其中 $n$ 是自然数.
- POJ2987 Firing 最大权闭合图
详情请参考http://www.cnblogs.com/kane0526/archive/2013/04/05/3001557.html 值得注意的地方,割边会把图分成两部分,一部分和起点相连,另一部 ...
- delegate 为什么用 weak属性
weak指针主要用于“父-子”关系,父亲拥有一个儿子的strong指针,因此是儿子的所有者:但是为了阻止所有权回环,儿子需要使用weak指针指向父亲:你的viewcontroller通过strong指 ...
- WeChat Official Account Admin Platform API Introduction
Keyword: WeChat API Introduction Message and GeneralAuthor: PondBay Studio[WeChat Developer EXPERT] ...
- c#调用c++ dll的几种类型(转)
http://www.sosuo8.com/article-2012/dllleixingzhuanhuan.htm 在合作开发时,C#时常需要调用C++DLL,当传递参数时时常遇到问题,尤其是传 ...
- [Java基础]Java通配符
转自:http://peiquan.blog.51cto.com/7518552/1303768 本以为这会是一篇比较基础的博客,可一旦深究的时候,才发现很多有意思的东西,也发现了很多令人迷惑的地方. ...
- 关于python的import
在软件包里,必须添加__init__.py文件. 想要对外公开的module必须在__init__.py内import一次,这样这些module才能被外部代码import并调用.
- ArrayList、LinkedList、HashMap的遍历及遍历过程中增、删元素
ArrayList.LinkedList.HashMap是Java中常用到的几种集合类型,遍历它们是时常遇到的情况.当然还有一些变态的时候,那就是在遍历的过程中动态增加或者删除其中的元素. 下面的例子 ...