球形环境映射之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 ...
随机推荐
- 制作web字体:CSS3 @font-face
@font-face是CSS3中的一个模块,他主要是把自己定义的Web字体嵌入到你的网页中,随着@font-face模块的出现,我们在Web的开发中使用字体不怕只能使用Web安全字体,另外@font- ...
- Linux Shell 文本处理工具集锦
本文将介绍Linux下使用Shell处理文本时最常用的工具:find.grep.xargs.sort.uniq.tr.cut.paste.wc.sed.awk:提供的例子和参数都是最常用和最为实用的: ...
- (转)内联(inline)函数与虚函数(virtual)的讨论
本文转自: http://topic.csdn.net/t/20051220/09/4469273.html 函数的inline属性是在编译时确定的, 然而,virtual的性质是在运行时确定的,这两 ...
- 转 一个典型的 C++ 程序员成长经历:
1. 完整的学一遍 C++ 所有语言特性,典型书籍 "The C++ Programming Language" Part1, Part2, "C++ Primer&q ...
- fifter常见的运用场景
没配置过滤器 package servlet; import java.io.IOException; import javax.servlet.ServletException; import ja ...
- CSSOM之getComputedStyle,currentStyle,getPropertyValue,getAttribute
js关于CSSOM编程的样式相关几个常用的方法 webkit:getComputedStyle,getPropertyValue IE:currentStyle,getAttribute 前言 jqu ...
- hdu2297Run(凸包的巧妙应用)
链接 很巧妙的一道题,参考 把距离和速度分别作为x和y坐标,以斜率代表追赶速率,简直炫酷~ 具体看上面的博客,画的很清楚,就不再抄写一遍了. #include <iostream> #in ...
- QQ授权登录
这两天在做网站第三方登录,总结一下QQ登录吧,支付宝就不用了(下载dome把ID什么的换一换就基本可以了.),本文主要说的是代码的实现方式,逻辑部分主要还是根据帮助文档来的.不懂的同学可以先看看文档. ...
- Python_Day2_基础2
python基础之数据类型与变量 一.变量 变量作用:保存状态(程序的运行本质是一系列状态的变化,变量的目的就是用来保存状态,变量值的变化就构成了程序运行的不同结果.) Age=10 ----> ...
- UIApplication sharedApplication详细解释-IOS
iPhone应用程序是由主函数main启动,它负责调用UIApplicationMain函数,该函数的形式如下所示: int UIApplicationMain ( int argc, char *a ...