HLSL的应用—反射环境映射

HLSL的应用—反射环境映射

 

 

反射环境映射有两种,静态环境映射和动态环境映射,我们从简单的即静态的开始看

 

 

静态的环境映射其实很简单,原理是主程序中先把CUBE贴图生成好,然后在shader里面计算出相对视线的反射向量,然后用一个texCUBE采样函数就可以了.来看看shader代码:

//--------------------------------------------------------------

// Desc: 效果文件

//--------------------------------------------------------------

 

//--------------------------------------------------------------

// 全局变量

//--------------------------------------------------------------

float4x4 matWorldViewProj;

float4x4 matWorld;

float4x4 matView;

float4   vecEye;

 

 

//---------------------------------------------------------------

// 立方体纹理采样器

//---------------------------------------------------------------

texture CubeMap;

samplerCUBE CubeMapSampler = sampler_state

{

   Texture = <CubeMap>;

   MinFilter = Linear;

   MagFilter = Linear;

   AddressU = Wrap;

   AddressV = Wrap;

};

 

 

//--------------------------------------------------------------

//顶点渲染器输出结构

//--------------------------------------------------------------

struct VS_OUTPUT

{

    float4 Pos : POSITION;

     float3 Reflect: TEXCOORD4;   

};

 

//-------------------------------------------------------------

// 顶点渲染器主函数

//-------------------------------------------------------------

VS_OUTPUT VS(float4 Pos : POSITION, float2 Tex : TEXCOORD, float3 Normal : NORMAL)

{

    VS_OUTPUT Out = (VS_OUTPUT)0;

   

    //坐标变换   

    Out.Pos = mul(Pos, matWorldViewProj);

   

    //计算世界空间中的顶点法线并标准化

    float3 Norm = normalize(mul(Normal, matWorld));

  

    //计算从顶点指向观察点的方向向量并标准化

    float3 PosWorld = normalize(mul(Pos, matWorld));

    float3 Incident = normalize(PosWorld - vecEye);

   

     //计算立方体映射的反射向量

     Out.Reflect = normalize(reflect(Incident, Norm));

    

    return Out;

}

//-------------------------------------------------------------

// 像素渲染器主函数

//-------------------------------------------------------------

float4 PS(VS_OUTPUT In) : COLOR

{

     return texCUBE(CubeMapSampler, In.Reflect);   

}

 

 

//-------------------------------------------------------------

// 技术

//-------------------------------------------------------------

technique TShader

{

    pass P0

    {

        VertexShader = compile vs_2_0 VS();

        PixelShader = compile ps_2_0 PS();

    }

}

 

 

实现很简单,这里主要说明一下HLSL库提供的reflect函数.它是用来计算反射向量的,其第一个参数是视线向量,第二个参数是法向量,返回视线向量经法向量所在平面反射后的向量.

R = I-2*N*dot(I,N); 用矢量图画画就出来了.

算出这个反射向量后再把它传到texCUBE里面去采样,得出的即是正确的颜色值了.

然后再拓展一下,刚才我们实现了反射效果,我们再来看看怎么实现折射效果,这个也不难,只是结果不是那么精确,因为我们不知道观察物体的折射率.因此我们在反射计算时加个小小的步骤,把法向量缩放一下,得出近似的折射向量.

//折射向量

     float3 ShortNorm = mul(Norm, 0.4);

     Out.Reflect2 = normalize(reflect(Incident, ShortNorm));

其他的和上例一样.

好了静态的就先到此,下面我们来看动态的

动态的环境映射也就是要动态的更新环境贴图,怎么更新呢?只要在所观察的物体的六个方向分别拍下快照,然后作为无缝的拼成一张CUBE贴图就可以了.具体怎么拍这个快照呢,DirectX已经有一个接口可以做这件事了,就是ID3DXRenderToEnvMap,具体的用法SDK里说的很详细.动态建好cube贴图后其他的就和静态的一样了!不难吧~!发现自己越来越浮躁了,什么时候自己动手写写就知道艰难了….

转帖

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值