zoukankan      html  css  js  c++  java
  • Unity-Shader-动态阴影(上) 投影的矩阵变换过程

    【旧博客转移 - 2017年1月20日 01:20 

    前面的话

    最近很长时间没写博文了,一是太忙 ( lan ) 了,二是这段时间又领悟了一些东西,脑子里很混乱,不知道从何写起。但感觉不能再拖延下去了,来不及解释了,快上车(一脸滑稽)

    目前我在做一款3D二次元动作游戏,后面可能会用到动态阴影,有的人可能会直接找一个插件分分钟就把阴影做出来了,这样做当然可以,但自己不去熟悉一下底层原理只是使用工具的话,很难知道性能瓶颈在哪,如果要做一些改动,只能跟策划说:改不了咯

    先看效果

    这个菊花是投影到地上的,这样的平地可能感觉不出来什么是投影

    但是像这样遇到凹凸地形的时候就会明显了,菊花不会直接插入平地,而是贴在球体的表面,就像一个投影机把幻灯片照上去的感觉

    实现原理

    如上图所示,左边的图是一个顶点渲染到我们的屏幕上要经过这么多的矩阵变换,这里来复习下MVP变化

    顶点从模型坐标空间转换到世界坐标空间 X ModelMaterix

    然后从世界坐标空间转换到视点空间 X CameraViewMaterix

    再从视点空间转换到裁剪空间 X CameraProjectionMatrix

    经过其次空间变化后就到了NDC空间,最后到了屏幕空间

    经过这些步骤,一个顶点就确定了在屏幕上的位置

    右边是将视点当作投影机,根据模型空间的坐标求出投影纹理的坐标的流程,两边前面的步骤都差不多,但是计算投影纹理坐标需要将投影顶点坐标归一化到【0 ,1 】空间中,实现这一步,可以在需要左乘矩阵normalMatrix , 也可以在着色程序中对顶点投影坐标的每个分量先乘以1/2 然后再加上1/2

    总结出投影坐标的矩阵公式为:

    textViewProjMatrix = NormalMatrix x ProjectionMatrix x ViewMatrix x WorldMatrix

    而Unity的Shader中已经为我们算好了这个矩阵,叫做unity_Projector

    我们只需要在vext函数中把顶点左乘这个矩阵就得到了齐次投影纹理坐标

    o.proj = mul(_Projector, v.vertex);

    使用的时候还需要除以最后一个分量w

    o.proj.xy = o.proj.xy / o.proj.xy.w;

    当然也可以使用CG里的函数tex2DProj进行纹理采样也是一样的

    tex2DProj 函数与 tex2D 函数的区别就在于:前者会对齐次纹理坐标除以最后一个分量 q ,然后再进行纹理检索

    总结

    现在我们知道了投影纹理是如何计算出来的,矩阵的变化过程是怎样的。但是这个Shader是运行在谁身上呢?是在地形上,还是在球上?这个问题我现在也不知道..但是后面我会继续去研究把这个搞懂,然后写一个动态阴影出来

  • 相关阅读:
    马赛克算法及iOS代码实现
    iOS制作Static Library(静态库),实现多工程的连编
    iOS由ImageIO.framework实现gif的系统解码
    KVC和KVO实现监听容器类(数组等)的变化
    Dynamicaly Typed(动态定型), Objective-C Runtime Programming
    Mac OSX下修改hosts文件
    MAC配置SVN服务器
    Encoding非常用编码转换
    Block作为参数使用
    UITextField关闭系统自动联想和首字母大写功能
  • 原文地址:https://www.cnblogs.com/lijiajia/p/6861657.html
Copyright © 2011-2022 走看看