球形环境映射之angular方式的两种形式
图形学中,某些物体带有反射属性,会反射周围的环境。一种做法是沿着反射方向发一条光线,与场景求交,获取到交点的颜色值,作为反射的颜色。显然这种方法比较低效,更高效的方法是将被渲染物体所处的环境保存到一张贴图中,渲染时先求出渲染点的反射方向,然后将这个反射方向(向量)变换到uv坐标,进而在贴图中查询到相应点的颜色值。过程中关键的一步是反射方向到uv坐标的变换,另外,在某种程度上,贴图的制作方式决定了变换方式。除了球形环境映射还有一种更为高质量的立方环境映射。球形环境映射又分为latlong(经纬)和angular方式,本文只讲angular方式下的两种不同的映射方式(反射方向到uv坐标的变换),这也就是前文的“在某种程度上”存在的意义。
话休絮烦,环境贴图的制作方式:待渲染物体的位置放一个铬球,相机拍摄铬球,考虑到透视投影,相机并不能拍到铬球的整个前半部分,换句话说,铬球的反射光线中不存在指向z轴正方向的光线,使用右手系,下同。但是该铬球已经很好的对大部分环境进行了反射,只有铬球正后方的一部分环境没被反射,该“被忽略”部分的大小取决于相机与铬球的距离,如果距离无限大,那么只有跟铬球最大截面等大的环境未被反射,但此时反射方向已经包含了z轴正方向,这种矛盾提醒了我们在环境不是无穷远时,该方法是不准确的,因为未考虑物体的形状(凹的物体可能发生自反射)和大小。
最常见的一种映射方式便是利用了贴图的制作方式,认为贴图是相机在无穷远处拍摄铬球得来,于是入射光线即(0,0,1),假设我们在渲染点处求得归一化的反射光线(x,y,z),法线即(x+0,y+0,z+1),很显然,归一化的法线顶点在xoy面上的投影位置即对应所要映射的贴图上的位置。考虑到纹理坐标的范围是0~1,我们进行除2加0.5的操作。RSL中代码如下(代码出自animallogic公司的mayaman头文件):
float m = 2*sqrt(x*x+y*y+(z+1)*(z+1));
U_COORD = y/m + 0.5;
V_COORD = x/m + 0.5;

另一种映射方式来自http://www.pauldebevec.com/Probes/,如果uv坐标的范围都是-1~1,我们先考虑如何把给定的某个uv坐标变换为反射方向,使用球面坐标,反射方向与z轴负方向夹角为phi,反射方向投影与x轴正向夹角为theta,theta=atan2(v,u), phi=pi*sqrt(u*u+v*v)。其中,theta的求法是显而易见的,但是phi的公式仅仅保证变换的区间及增减性正确。我们可以如此验证,取u=0.5,v=0,phi为pi/2,而实际上该点的反射方向与z轴负向夹角仍是锐角。反过来,给定反射方向(Dx, Dy, Dz),其对应的uv坐标即(Dx*r,Dy*r),其中, r=(1/pi)*acos(Dz)/sqrt(Dx^2 + Dy^2)。很显然,将原帖图贴到镜面球上之后,第一种映射方式再现了制作贴图时铬球的面貌,而第二种方式对贴图中间部分进行了放大,可如此分析,取反射方向为(1,0,0),不难计算uv坐标为(0.5,0),实际应该映射的是(0.707,0),见图。


贴图文件为
注:为避免透视投影对结果的影响(其实影响比较小),均使用平行投影。
球形环境映射之angular方式的两种形式的更多相关文章
- C++:一般情况下,设计函数的形参只需要两种形式
C++:一般情况下,设计函数的形参只需要两种形式.一,是引用形参,例如 void function (int &p_para):二,是常量引用形参,例如 void function(const ...
- jquery插件的两种形式
这里总结一下jquery插件的两种形式,一种是通过字面量的形式组织代码,另一种是通过构造函数的方式.下面就两种形式来分析俩个例子. 例子1: ;(function ($,window,document ...
- Controller@实现Controller的两种形式
实现Controller的两种形式 形式1:仅仅实现IController接口,自定义Controller对Request的实现.形式2:在实现IController接口以后,继承Controller ...
- 基于 Scrapy-redis 两种形式的分布式爬虫
基于 Scrapy-redis 两种形式的分布式爬虫 .caret, .dropup > .btn > .caret { border-top-color: #000 !important ...
- SQL 关于apply的两种形式cross apply 和 outer apply(转)
转载链接:http://www.cnblogs.com/shuangnet/archive/2013/04/02/2995798.html apply有两种形式: cross apply 和 oute ...
- SQL 关于apply的两种形式cross apply 和 outer apply
SQL 关于apply的两种形式cross apply 和 outer apply 例子: CREATE TABLE [dbo].[Customers]( ) COLLATE Chinese_PRC_ ...
- SQL关于apply的两种形式cross apply和outer apply(转载)
SQL 关于apply的两种形式cross apply 和 outer apply apply有两种形式: cross apply 和 outer apply 先看看语法: <lef ...
- 在 Perl看来, 字符串只有两种形式. 一种是octets, 即8位序列, 也就是我们通常说的字节数组. 另一种utf8编码的字符串, perl管它叫string. 也就是说: Perl只熟悉两种编
在 Perl看来, 字符串只有两种形式. 一种是octets, 即8位序列, 也就是我们通常说的字节数组. 另一种utf8编码的字符串, perl管它叫string. 也就是说: Perl只熟悉两种编 ...
- 在sql中case子句的两种形式
case子句,在select后面可以进行逻辑判断. 两种形式:判断相等.判断不等 一.判断相等的语法: case 列名 when ... then ... when ... then ... el ...
随机推荐
- 再谈Bellman-Ford
这几天学校女生节,挺累的,感觉还是挺好玩的,前几天看了一下最短路,Bellman-fort算法果然比较厉害,今天又参考了刘汝佳的两本书,有了一点新的认识. 废话不说,先上代码: #include &l ...
- (1) 深入理解Java虚拟机到底是什么?
好文转载:http://blog.csdn.net/zhangjg_blog/article/details/20380971 什么是Java虚拟机 作为一个Java程序员,我们每天都在写Java ...
- void与void *
转载:http://blog.csdn.net/geekcome/article/details/6249151 void的含义 void即“无类型”,void *则为“无类型指针”,可以指向任何数据 ...
- 【双标记线段树】bzoj1798维护序列seq
一.题目 描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列 ...
- 【Java】一个小程序,计算它包含的代码所需的耗时
写一个小程序,用来计算它包含的代码所需的耗时.虽然简单,测试代码是否耗时还是有点用的,不用重新写嘛~ import java.util.Date; import java.util.concurren ...
- SQL Server书籍整理
1.<Microsoft SQL Server企业级平台管理实践>徐海蔚2.<SQL Server 2005 Performance Tuning性能调校>胡百敬3.<M ...
- 我的android学习经历37
android虚拟机没有键盘的问题,那是因为建立虚拟机的时候没有选择skin,重新编辑选择skin就可以了
- 关于listview视图的 作业
代码运行目录 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android=& ...
- zoj3494BCD Code(ac自动机+数位dp)
l链接 这题想了好一会呢..刚开始想错了,以为用自动机预处理出k长度可以包含的合法的数的个数,然后再数位dp一下就行了,写到一半发现不对,还要处理当前走的时候是不是为合法的,这一点无法移到trie树上 ...
- 机器学习职位 & 面经
http://www.cnblogs.com/peileyuan/p/4775453.html <浅谈机器学习的职业发展方向> http://blog.sina.com.cn/s/blog ...