CubeMap视线反射方向计算详解

简介:

其基本原理很多例子上有讲到。下面给出一些比较合适的链接

http://developer.nvidia.com/object/cube_map_ogl_tutorial.html    NVIDIA官网上的 Opengl Cube texture mapping
http://www.zwqxin.com/archives/shaderglsl/review-cube-mapping-shader.html  某位兄弟的个人BLOG。
以上两位都适合OPENGL控。
本文给出一个DX HLSL例子。并解释了反射方向计算的数学模型。希望能给大家一定的帮助。
CUBE映射主要分为两步:
一、在VS中根据法线和观察位置计算反射方向,并且得到观察空间中的反射方向。
反射方向有两种计算方法。
1、在世界坐标系空间中计算,然后再将计算到的反射方向转换到观察空间。 这要求我们转入观察位置。
2、在观察空间中进行计算,此时观察位置已经为0,0,0,于是不需要传入观察位置,并且得到的向量即为所求。本文的代码采用此种方式。


值得说明的一点是。在进行计算时,入射方向和反射方向以及法线方向并未要求一定要单位化。
二、用这个反射方向在PS中对CUBE纹理进行采样。

下面是一个对反射向量计算的通用求解过程。

我们假设顶点位置为Pos 即点O,视点为Eye 即点A (均为同一坐标系空间)
那么,我们的观察方向便是Pos-Eye, 即AO。而我们的反射方向便是OC。 法线为OB或OD方向。
下面我们来看看反射方向的求法
而由上图可知,OC = AD ;
而又由OA+AD = OD;OD = 2*OB;可得
 OC = 2*OB-OA;
而OA = Eye-Pos;
可得,OC = 2*OB-(Eye-Pos);
那么,最后我们可以看出,只要求出OB,则可以求出OC。
而从图上我们可以看到OB即为OA在(法线)OD上的投影。 由此可知, OB = dot(OA,Normal);
于是可以写出如下公式。
float3 EyeR = Eye - Pos;  float3 reflectVec = 2*dot(EyeR,Normal)*Normal - EyeR;

当然,你也可以使用高级语言中的reflect函数来求反射
在HLSL中。
ret reflect(i, n)

v = i - 2 * dot(i, n) * n

上面的公式中。i为入射方向,v为反射方向,n为法线。
由于EyeR 为观察方向的反方向,即入射方向的反方向
所以 reflectVec = reflect(-EyeR,Normal)即可求得。

最后将reflectVec转换到观察空间,然后对CUBE纹理进行采样即可。

下面是HLSL中我使用的代码。该代码在D3D SDK的HDRCubeMap.fx中可见。

// VS
float4x4 matView;
float4x4 matProjection;
struct  VS_INPUT 
{
   float4 Position : POSITION0;
   float2 Texcoord : TEXCOORD0;
   float3 Normal :NORMAL;
}
;

struct  VS_OUTPUT 
{
   float4 Position : POSITION0;
   float3 Texcoord : TEXCOORD0;
}
;

VS_OUTPUT vs_main( VS_INPUT Input )
{
   VS_OUTPUT Output;
   Output.Position 
= mul(Input.Position,matView);
   
   float3 vN 
= mul(Input.Normal,matView);
   float3 vEyeR 
= -normalize(Output.Position);
  
   Output.Texcoord 
= 2 * dot( vEyeR, vN ) * vN - vEyeR;
   
   Output.Position 
= mul(Output.Position,matProjection);
   
return( Output );
}


// PS
samplerCUBE baseMap;

struct  PS_INPUT 
{
   float3 Texcoord : TEXCOORD0;
   
}
;

float4 ps_main( PS_INPUT Input ) : COLOR0
{
   
return texCUBE( baseMap, Input.Texcoord );
   
}


在此对float3 vEyeR = -normalize(Output.Position);作一下解释。
我们上面讲到的 EyeR的计算为Eye- Pos。 但是,由于N和Pos已转入摄相机空间。则此时的Eye为(0,0,0)。 并且,不一定要单位化vEyeR 
所以上面的解法可以让你不用再传入观察点。
最后,我们来围观一下效果。




我是在RenderMonkey中测试的SHADER,所以,上面贴出来的,即为原码。
下面是用到的cubemap图的样子


OK,谢谢欣赏,欢迎交流
GMAIL :BoYueGame

作者:码瘾少年·麒麟子 
出处:http://www.cnblogs.com/geniusalex/ 
蛮牛专栏:麒麟子 
简介:09年入行,喜欢游戏和编程,对3D游戏和引擎尤其感兴趣。 
版权声明:本文版权归作者和博客园共有,欢迎转载。转载必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载:http://www.cnblogs.com/geniusalex/archive/2011/01/07/1929667.html

目录
打赏
0
0
0
0
248
分享
相关文章
一种求任意多边形内部水平方向似最大矩形的算法
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景        在前一篇中,我们探讨了如何求凸多边形中的似最大圆,但是针对实际情况需求,我们并没有完全解决问题。
3010 0
三维之外的更高维度,数学家发现了无限可能的黑洞形状
三维之外的更高维度,数学家发现了无限可能的黑洞形状
178 0
遥感物理基础(2)物体的发射与反射辐射特征
本文内容主要介绍地物的发射和反射辐射特征,通过名词解释与案例,认识地物特征与遥感影像成像的联系,结合实践理解晦涩难懂的原理
501 0
技术好文共享:辅助角公式的几何意义
技术好文共享:辅助角公式的几何意义
半全局立体匹配方法调研,以及一些立体匹配方向的思考
写大论文的时候看到了这篇文章,感叹到作者科研的创新 《A Non-Local Cost Aggregation Method for Stereo Matching》 一种非局部代价聚合立体匹配方法           对于基于局部信息的立体匹配,采用的一般都是滑动窗口,作者创造性的...
1309 0
《在纹线方向上进行平滑滤波,在纹线的垂直方向上进行锐化滤波》 --Gabor增强的具体实践
《在纹线方向上进行平滑滤波,在纹线的垂直方向上进行锐化滤波》                                          --Gabor增强的具体实践     一、问题提出             一般认为“Gabor小波感受野模拟线性滤波器,能对图像进行较好的智能收敛,从而智能增强图像。
1553 0

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等