博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Unity]在Shader中获取摄像机角度、视线的问题
阅读量:6794 次
发布时间:2019-06-26

本文共 1307 字,大约阅读时间需要 4 分钟。

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

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

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

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

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

871155-20170504204820773-1785251757.png

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

float3 viewDir =        unity_OrthoParams.w * -UNITY_MATRIX_V[2].xyz    //这个-UNITY_MATRIX_V[2].xyz可以用来表示相机的朝向,即C#代码里的transform.forward        +        (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如下:

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

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

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

你可能感兴趣的文章
STL实例
查看>>
CCNP sla,route-map结合应用实现负载均衡和冗余
查看>>
大学生微信卖吃喝月入10万,创业因女友娇气
查看>>
VC非ASCII语言复制到剪切板乱码问题
查看>>
QT+OPENCV摄像头的三种效果显示
查看>>
ant编译乱码
查看>>
Netty 实现 WebSocket 聊天功能
查看>>
php isset+{} 判断字符串长度
查看>>
oral_quiz->#字符串的排列、组合#
查看>>
【转】OSI七层模型详解
查看>>
核心产品开源项目配置说明
查看>>
自定义AlertDialog
查看>>
nova创建虚拟机的过程(二)
查看>>
json转字符串
查看>>
Unity3D人物角色连招(只放了三招)
查看>>
spark性能调优
查看>>
postgresql中schema概念
查看>>
@ResponseBody和Json序列化处理流程
查看>>
PHP Convert array into csv
查看>>
easyui tree 点击文字展开节点
查看>>