当前位置:   article > 正文

[Unity]在Shader中获取摄像机角度、视线的问题

unity 摄像机视口上夹角度数

又踩了一坑,好在谷歌到了之前的一个人遇到相同的问题,顺利解决。

先说说问题背景,我目前的毕设是体数据渲染,实现的办法是raycast。最基本的一点就是在fragment program里,获取raycast的方向。

问题出现在加入阴影之后。在这之前,获取方向是没问题的。

在透视相机中,可以简单地用float3 viewDir = normalize(worldPos - _WorldSpaceCameraPos);来获取方向。

在正交相机中,我们需要换个方法,来获取相机的朝向(对正交相机来说,朝向就是raycast的方向)。Unity提供了一个参数来表示当前相机的类型。
871155-20170504204820773-1785251757.png

因此我们可以用这样的式子替换,来适应两种相机

  1. float3 viewDir =
  2. unity_OrthoParams.w * -UNITY_MATRIX_V[2].xyz //这个-UNITY_MATRIX_V[2].xyz可以用来表示相机的朝向,即C#代码里的transform.forward
  3. +
  4. (1- unity_OrthoParams.w) * (worldPos - _WorldSpaceCameraPos);

这个时候我用常规的办法加入了阴影(引入ShadowCaster的pass)。并且用同样的办法计算深度然后输出。然后……就出问题了,主要表现是在Shadow Map里渲染错位。

一番排查之后发现了问题。目前我只考虑单个Directional Light,下面也都按照Directional Light来说。按照Shadow Map的流程,我们会需要Directional Light为相机渲染一次Shadow Map。此时该Light相当于一个正交相机。尽管之前我们对两种相机都做了适应,但是……在渲染ShadowMap的时候,这个unity_OrthoParams,是不管用的,因此viewDir的计算是按照透视相机来的,于是就错位了。

所以我们得自己判断正交还是透视了。好在有大神给出了解答:使用UNITY_MATRIX_P[3][3] 进行判断。为0表示透视,1表示正交。具体原理我也不清楚,不过测试之后是完全可行的。

修改后的viewDir如下:

  1. float3 viewDir = normalize(
  2. UNITY_MATRIX_P[3][3] * -UNITY_MATRIX_V[2].xyz
  3. +
  4. (1 - UNITY_MATRIX_P[3][3]) * (worldPos - _WorldSpaceCameraPos));

另外推荐一个系列教程:http://catlikecoding.com/unity/tutorials/ 其中包括了shader编程,由浅入深地把unity5的standard surface shader复现了一遍,包括编辑器界面。同时包括了各种技术的原理、实现。看一遍绝对是受益颇多。除开shader的教程,其他的几个教程也是非常有意思。总之强烈推荐。

转载于:https://www.cnblogs.com/yangrouchuan/p/6809814.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/83443
推荐阅读
相关标签
  

闽ICP备14008679号