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 【转】的更多相关文章

  1. Cesium源码剖析---Ambient Occlusion(环境光遮蔽)

    Ambient Occlusion简称AO,中文没有太确定的叫法,一般译作环境光遮蔽.百度百科上对AO的解释是这样的:AO是来描绘物体和物体相交或靠近的时候遮挡周围漫反射光线的效果,可以解决或改善漏光 ...

  2. Ambient Occlusion

    一般在光照模型中,ambient light的计算方法为:A = l * m,其中l表示表面接收到的来自光源的ambient light的总量,而m表示表面接收到ambient light后,反射和吸 ...

  3. TSSAO Temporal Screen-Space Ambient Occlusion (Unity3d 5 示例实现)

    前提 环境光(ambient occlusion)是一种GI,其简化形式SSAO可以用“微量高效”来形容,消耗得很少,得到的效果很好.环 境光遮蔽(ambient occlusion)的本质是计算在一 ...

  4. [帖子收集]环境光遮蔽(Ambient Occlusion)

    环境光遮蔽,效果示例图 图片左边是一条龙的简单模型,呈现在一个均匀照明的环境中.尽管模型中有一些明暗不同的区域,但大部分光照都是均匀的.虽然模型有着相当复杂的几何形状,但看上去比较光滑平坦,没有明显的 ...

  5. Dynamic Ambient Occlusion and Indirect Lighting

    This sample was presented on the Nvida witesite, which detail a new idea to calculate the ambient oc ...

  6. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二十一章:环境光遮蔽(AMBIENT OCCLUSION)

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二十一章:环境光遮蔽(AMBIENT OCCLUSION) 学习目标 ...

  7. OpenGL 3 and OpenGL 4 with GLSL

    Here are some OpenGL samples with advance features. NeHe OpenGL tutorial focus on the OpenGL fixed p ...

  8. UE4命令行使用,解释

    命令行在外部 从命令行运行编辑项目 1 导航到您的[LauncherInstall][VersionNumber]\Engine\Binaries\Win64 目录中. 2 右键单击上 UE4Edit ...

  9. OpenGL.教程

    5.第五课:带纹理的立方体.html(http://www.opengl-tutorial.org/cn/beginners-tutorials/tutorial-5-a-textured-cube/ ...

随机推荐

  1. Android 工程目录结构简介

    一般来说,一个Android工程的目录结构如下图所示. 1:src JAVA源代码都放在这里面. 2:gen 编译器自动生成的一些JAVA代码 3:Android 4.2 Android平台(本工程用 ...

  2. 【转】终于解决了Apache乱码问题

    之前开放了一个空间,给网友提供电台节目音频下载.由于多年节目的文件数量甚多,且分类没有特定格式,图省事,没有制作网页提供分类下载,而是直接利用Apache的目录浏览功能,简单直观. 不过,所在的美国服 ...

  3. .NET Remoting

    .NET Remoting   .NET Remoting是微软早期的分布式通信技术,虽然微软后来通过WCF通用基础通信框架整合掉了,但是通过回顾学习Remoting,反过来学习理解WCF也是很有帮助 ...

  4. POJ 2421 Constructing Roads

    题意:要在n个城市之间建造公路,使城市之间能互相联通,告诉每个城市之间建公路的费用,和已经建好的公路,求最小费用. 解法:最小生成树.先把已经建好的边加进去再跑kruskal或者prim什么的. 代码 ...

  5. 翻译【ElasticSearch Server】第一章:开始使用ElasticSearch集群(3)

    运行ElasticSearch(Running ElasticSearch) 让我们运行我们的第一个实例.转到bin目录并从命令行运行以下命令: ./elasticsearch –f (Linux o ...

  6. HDU 4267-A Simple Problem with Integers(多个BIT)

    题意: 2种操作 1 a b k c 在区间[a,b]中的(i-a)%k==0的位置i上的数+c 2 a 查询位置a的值 输出每次查询的值 分析: 开始想到多维的线段树,但比较麻烦,看了题解才知道,用 ...

  7. bzoj 1001: [BeiJing2006]狼抓兔子 平面图最小割

    平面图跑最大流 可以转换为其对偶图跑最短路 一个环对应一个割  找到最小环(即最短路)极为所求,注意辅助边的建立 加入读入优化  不过时间还是一般  估计是dij写的不好   大神勿喷~~~ /*** ...

  8. bzoj1150

    haha,贪心,边界条件折腾了我一会儿 #include<cstdio> #include<cctype> #include<queue> #include< ...

  9. Intellij IDEA,WebStorm-keymap(转)

    1. ctrl + shift + n: 打开工程中的文件2. ctrl + j: 输出模板3. ctrl + b: 跳到变量申明处4. ctrl + alt + T: 围绕包裹代码(包括zencod ...

  10. Install_pygments

    安装Pygments语法高亮 On OS X Leopard, Snow Leopard 1 $ sudo easy_install Pygments Alternatively on OS X wi ...