其基本原理很多例子上有講到。下面給出一些比較合適的鏈接
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