个人的Directx9研究总结 (2)

4 篇文章 0 订阅
3 篇文章 1 订阅

 

Directx9的小型游戏引擎第二篇。由于1月份旧电脑显卡爆掉,因此新电脑配置环境花了不少时间。

继续上篇,本篇为一些关于Shader的经验总结

1.NormalMapping方式实现Bump map

Bump map是一种表现凹凸感的方式,其中比较早期的方法是使用一张Height Map来移动网格的顶点从而表现顶点。而现在更为广泛的使用方法是使用一张Normal Map,对这张纹理采样。在转换为3D空间向量坐标代替原本的法线。这种方法可以让低模野获得高模的质感,配合高光下更明显。

               

如图,左边是使用NormalMapping,右边是使用原法线的情况。可以看出左边的质感有较大提升。

但是仅仅这样是无法反映任何角度下光照情况的,光使用新法线仅能对应原本法线n指向z的正方向的情况。而模型的法线是定义在模型空间中,指向四面八方的。因此完整的方法是在切线空间(tangent space)里计算光照。

    // 模型法线
    float3 N = normalize(mul(In.Normal, (float3x3) mtxWorldInverseTranspose));

    // 模型切线
    float3 T = normalize(mul(In.Tangent, (float3x3) mtxWorldInverseTranspose));

    // 叉乘计算副切线
    float3 B = cross(N, T);

     // TBN逆矩阵
    float3x3 TBNMatrix = float3x3(T.x, B.x, N.x,
	                              T.y, B.y, N.y,
	                              T.z, B.z, N.z);

    // 切线空间半向量
    outVS.THalfVector = mul(halfVector, TBNMatrix);

    // 切线空间光线向量
    outVS.TLightDir = mul(lightdirection, TBNMatrix);

切线空间中由三条垂直的向量:法线切线和副切线构成。由这三条线构成的TBN矩阵。

之后可以用采样取得的法线与TBN相乘来把法线转换到世界坐标系中,或者使用TBN的逆矩阵计算光照来让光照变量都在一个坐标系中完成计算。第一种方法比较简单但是需要在像素着色器中才能完成计算,第二种方法的则可以都在顶点着色器完成计算。上面代码采用第二种方法。

Directx9中采用法线贴图的步骤:

  1. D3DVERTEXELEMENT9宣言中带法线和切线的顶点。
  2. D3DXComputeTangentFrameEx计算模型中法线和切线。
  3. Shader中计算TBN矩阵

 

 

2.IBL与MatCap

IBL(Image-Based Lighting)就是基与图像的光照,早期立方体贴图通常用来做天空盒或者物体的环境贴图,那么既然立方体贴图可以做环境贴图。不也可以把漫反射的结果保存下来,然后直接使用吗?这就是IBL的想法。使用纹理来反映光照结果。下图是Unity Matcap Shader用的图片。

如图,无纹理情况下漫反射计算后结果

如图,漫反射结果乘上根据法线采样的纹理

而MatCap算是一个进阶用法,使用Unity的人应该比较了解。MatCap继承了IBL的思想,不过不是使用需要六张纹理的立方体贴图。而且一张球状的纹理。再通过把模型法线转换到2D空间,使用该2D向量作为球状纹理的UV坐标。

    // 根据模型法线计算Matcap用UV坐标
    float2 normaltoUV = float2(In.WNormal.xy * 0.5f + 0.5f);

不过仅仅这样只适用于静止的摄像机,所以再让法线再乘上观察矩阵让视线移动纹理也跟着移动。就有了相对比较好的视觉效果。

如图,原本贴图结合MatCap,左边是加算,右边是乘算。

MatCap用很低的成本就可以体现需要复杂计算的光照效果,与移动端或者卡通渲染等非真实渲染等结合效果很好。

Directx9中采用Matcap的步骤:

方法同立方体贴图做环境贴图,只需要多一部计算UV坐标的步骤即可

3.PostProcessing 屏幕后处理

运用RTT可以把当前场景渲染成一张纹理。而渲染成一张纹理后便可以使用各种后期处理(PostProcessing),后处理都是基于像素着色器,修改纹理从而产生各种各样效果。

只需要消耗很少的资源就可以达成各种各样效果。

例如反色:

outPS.Color = float4(1.0f - originalcolor.r, 
1.0f - originalcolor.g, 
1.0f - originalcolor.b, 
1.0f);

使用卷积的锐化效果:

运用后处理可以在不改变素材的情况下制造各种风格化的画面效果。

Directx9中采用PostProcessing的步骤:

RTT渲染当前场景到一张纹理,之后对该纹理使用像素着色器来进行后处理。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值