【图形与渲染】相机平面镜反射与斜裁剪矩阵(下)-斜裁剪矩阵

2023-11-16

上一篇文章分析了平面镜反射效果实现中,如何计算镜像矩阵,我们已经可以得到镜像相机并渲染出镜像后的效果了,但是只是纯粹的镜像会遇到以下问题:


如图,当相机镜像到C’位置后,其视锥体裁剪范围是A+B,但实际应该位于反射贴图中的区域仅仅只有A区域,也就是我们需要根据平面P对相机C’裁剪。


投影矩阵:

先回顾一下渲染管线中的投影变换阶段,该阶段将相机空间的坐标变换到投影空间,以便于裁剪。

投影变换后会得到一个归一化设备坐标(NDC),其值在视锥体内的范围分别是x:[-1,1],y[-1,1],z:[-1,1](Direct3D中是[0,1],OpenGL中是[-1,1],unity采用了OpenGL的NDC)


投影矩阵可以通过相机的相关参数计算得到:

透视投影:

| 1/(tan(fov/2)*aspect) 0 0 0|

|0 1/tan(fov/2) 0 0|

|0 0 -(far+near)/(far-near) -2*near*far/(far-near)|

|0 0 -1 0|


正交投影:

|1/(aspect*size) 0 0 0|

|0 1/size 0 0|

|0 0 -2/(far-near) -(far+near)/(far-near)|

|0 0 0 1|


投影矩阵的详细推导可以参考相关文章,这里限于篇幅只给出具体的公式以方便下面的计算。

投影矩阵的推导:http://www.songho.ca/opengl/gl_projectionmatrix.html


近裁面和远裁面:

相机的视锥体由六个平面围成,其每个平面都可以用投影矩阵中的分量计算得到,但对于我们要实现的镜面反射效果,最重要的就是近裁面和远裁面,因此这里只考虑这两个平面。



根据投影变换的相关知识,实际上我们可以把投影空间看出一个”正方体”,它由六个面围成,

其中,近裁面为法线为(0,0,1),且过点(0,0,-1)的平面,则投影空间的近裁面P’near = <0,0,1,1>

远裁面为法线为(0,0,-1),且过点(0,0,1)的平面,则投影空间的远裁面P’far = <0,0,-1,1>


那么我们通过投影矩阵M即可求得相机空间对应的平面的表示,关于平面的变化可以参考:

http://www.lsngo.net/2018/01/07/graphics_plane/


因此,对于投影空间的平面L’,其相机空间对应的L即为:



即我们通过上述投影矩阵的转置矩阵可以求得相机空间的近裁面和远裁面,

最终计算结果,发现相机空间的近裁面和远裁面与投影矩阵刚好满足下列关系:

near = M4+M3

far = M4-M3

M4和M3表示矩阵M的第四行和第三行,这一步的结论对后序的推导十分重要。


替换近裁面:

有了以上基础知识后,我们就可以开始替换近裁面了,根据前面的实现,我们现在需要使用前面的平面P来替换近裁面,目前平面P是一个世界空间下的平面,我们需要先计算得到相机空间的平面Pc,由于近裁面near=M4+M3,因此替换近裁面后则有Pc=M4+M3。


通过对投影矩阵的推导可知投影矩阵的第四阶需要保持相机空间深度信息,且该阶需要对顶点透视校正插值,因此不可修改该阶的值,只能修改M3,即M3’=Pc-M4。

已知far=M4-M3,则替换近裁面后的远裁面far’=M4-M3’=M4-Pc+M4=2M4-Pc


但仅仅是这样求得新的远裁面far’并不一定能满足要求,大部分情况下,新的近裁面Pc和远裁面far’都不平行(只要Pc的x或y坐标有一个不为0),此时投影深度将不再表示延z坐标轴的距离,而仅仅只是新的近裁面和远裁面之间的一个点,这会对深度的精度产生影响。不过平面Pc中包含一个可以调节的比例系数,可以调整远裁面的方向,使得近裁面和远裁面不平行的情况下,近裁面和远裁面的夹角最小,且不对原始视锥进行裁剪。


修改远裁面:

far’=2M4-u*Pc

对于平面Pc,乘上比例系数u后,其表示的平面仍然是原平面。


我们知道在投影空间中,远裁面上的四个角点的坐标分别是:(-1,-1,1,1),(-1,1,1,1),(1,-1,1,1),(1,1,1,1),为了使新的远裁面far’在不裁剪原视锥的同时又与近裁面夹角最小,其必须要经过一个离近裁面最远的角点,如下图:



此时的远裁面F经过离近裁面C最远的角点Q,这时的裁剪空间不会对原视锥进行裁剪,同时又使得夹角最小,

假设该点Q在投影空间对应的点为Q’,令Pc’为平面Pc在投影空间对应的平面,根据Pc’的法线可以计算得到点Q’的坐标为(sign(Pc’x),sign(Pc’y),1,1),(即和平面Pc’的法线同符号)


最后再利用投影矩阵M的逆矩阵计算得到相机空间的点Q,为了使远裁面far’包含Q,只需far’·Q=0,即可,

即far’ = 2M4-uPc

far’·Q=0,

最后得到u = (2*M4·Q)/(Pc·Q)

通过该u最终可以计算得到M3′


private Matrix4x4 ObliqueMatrix(Vector4 plane)
    {
        //世界空间的平面先变换到相机空间
        plane = (m_MirrorCamera.worldToCameraMatrix.inverse).transpose * plane;
 
         
        Matrix4x4 proj = m_MirrorCamera.projectionMatrix;
 
        //计算近裁面的最远角点Q
        Vector4 q = default(Vector4);
        q.x = (Mathf.Sign(plane.x) + proj.m02) / proj.m00;
        q.y = (Mathf.Sign(plane.y) + proj.m12) / proj.m11;
        q.z = -1.0f;
        q.w = (1.0f + proj.m22) / proj.m23;
        Vector4 c = plane * (2.0f / Vector4.Dot(plane, q));
 
        //计算M3'
        proj.m20 = c.x;
        proj.m21 = c.y;
        proj.m22 = c.z + 1.0f;
        proj.m23 = c.w;
        return proj;
    }

最后渲染得到的RenderTexture传入shader,并在shader中计算投影坐标:


sampler2D _ReflTex;
            half4 _Color;
             
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.proj = ComputeGrabScreenPos(o.vertex);
                return o;
            }
             
            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2Dproj(_ReflTex, i.proj);
                col.rgb = lerp(col.rgb, _Color.rgb, 0.5);
                return col;
            }


渲染效果如下:



以上就是斜裁剪矩阵的推导。


最后,关于在unity引擎中实现斜裁剪,unity还提供了一个更方便的API,可以直接根据相机计算出斜裁剪矩阵:m_Camera.CalculateObliqueMatrix(clipPlane),可以直接使用这个API计算出斜裁剪矩阵,效果和上述方法是一样的。


更多内容请浏览我的博客原文:http://www.lsngo.net/2018/01/07/graphics_mirrorcamera_2/


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【图形与渲染】相机平面镜反射与斜裁剪矩阵(下)-斜裁剪矩阵 的相关文章

  • Unity-AR 简介

    Unity AR 简介 现有Unity AR Sdk ARKit 苹果推出的AR开发平台 ARCore Google 推出的增强现实 SDK ARFoundation ARFoundation是ARKit XR插件和ARCore XR插件
  • FBX导入Unity中模型没有材质的处理

    一 3dMax导出FBX时的注意事项 导出时 确保maps文件存在 里面放着fbx用到的image 二 在Unity中的设置 1 文件拖入Unity的Assets文件夹中 2 查看模型的材质是否存在 如下所示 材质为None 此时拖入sce
  • Unity动画系统详解

    目录 动画编辑器 编辑器面板 动画复用 前言 人形重定向动画 Humanoid 通用动画 Generic 旧版本动画 Legacy 动画控制器 系统状态 切换条件 状态机脚本 IK动画 反向动力学 BlendTree 混合树 Animato
  • Unity中UI框架的使用1-添加面板、显示Loading页面

    其中BasePanel和Canvas都是挂在面板的预制物上的 1 导入我们的UI框架 本篇文章中有用的是两个UIPanelType NUIManager和NBasePanel 会放在文章最后供大家使用 2 先将我们做好的Panel设置成预制
  • GooglePlay提审警告(com.google.android.gms:play-services-safetynet:17.0.0)

    1 Goole在今年6月份出的新政策 不在使用safetynet 而使用Play Integrity API 2 项目本身没有使用过safetynet 3 使用了firebase 查阅资料 解决方案如下 implementation pla
  • 在silverlight中定制自己的MessageBox(消息框)

    在silverlight中 如果想使用 消息框 可使用下面的方法 即 HtmlPage Window Alert 消息框内容 如果想要显示更加复杂的内容或定义消息框样式的话 基本上没有什么好的方法 最近在网上看到了一篇文章 该文章的作者也谈
  • Unity打开工程时卡住的问题

    自从Unity升级了一个版本后 Unity打开工程卡住的问题越来越严重了 具体表现为 选择工程后 Unity窗口消失 但进程还在 有时候等个几分钟能出来 有时候等10分钟都不见得能出来 直观感受上看 似乎是Unity加载工程的时候某一步卡了
  • unity3d大型互动照片墙

    1 本次应客户需求 制作一个大型照片墙互动 输出分辨率为9600 4320 注 unity3d官方推荐最大分辨率为8192 3686 4 经过现场长达24小时暴力测试中途未发生问题 姑且判定可以达到正常标准 废话不多说 先上效果 unity
  • mac下搭建cocos2d-x3.2开发环境

    1 软件 Xcode Ant apache ant 1 9 4 bin tar gz Jdk jdk 8u45 macosx x64 dmg 有的mac系统上没有自带 Ndk android ndk r10d darwin x86 64 b
  • Unity保存图片到相册

    Unity保存图片到Android相册 Java 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
  • Unity旋转以及万向锁问题

    我之前研读了一些关于unity旋转相关的博客 一直想抽个时间写个总结 但是由于实习太忙一直没有写 趁着今天请了假晚上有时间把这段时间一些学习心得写出来 Unity inspector面板中的Rotation 在unity中 想必大家最先接触
  • Unity万向节死锁解决方案(2023/12/4)

    1 万向节死锁无法解决 这是因为它的特性就是如此 就像玻璃杯就是玻璃 这不可否认 别钻牛角尖昂 2 大多数情况下欧拉角足够用 例如 CF 摄像机不可能绕z轴旋转 x轴旋转也不会超过九十度 因为那样人物的腰子会被扭断 塔防游戏 保卫萝卜 吃鸡
  • 【原神游戏开发日志1】缘起

    原神游戏开发日志1 缘起 版权声明 本文为 优梦创客 原创文章 您可以自由转载 但必须加入完整的版权声明 文章内容不得删减 修改 演绎 相关学习资源见文末 大家好 最近看到原神在TGA上频频获奖 作为一个14年经验的游戏开发行业的老兵 我就
  • 华为OD机试真题-螺旋数字矩阵-2023年OD统一考试(C卷)

    题目描述 疫情期间 小明隔离在家 百无聊赖 在纸上写数字玩 他发明了一种写法 给出数字 个数n 和 行数m 0 lt n 999 0 lt m 999 从左上角的1开始 按照 顺时针螺旋向内写 方式 依次写出2 3 n 最终形成一个 m行矩
  • 华为OD机试真题-螺旋数字矩阵-2023年OD统一考试(C卷)

    题目描述 疫情期间 小明隔离在家 百无聊赖 在纸上写数字玩 他发明了一种写法 给出数字 个数n 和 行数m 0 lt n 999 0 lt m 999 从左上角的1开始 按照 顺时针螺旋向内写 方式 依次写出2 3 n 最终形成一个 m行矩
  • 矩阵基本操作3

    题目描述 问题描述 定义一个N M N M lt 100 的矩阵 将一个该矩阵的行和列的元素互换 存到另一个二维数组中 输入格式 一行两个整数 N M 中间用空格隔开 表示矩阵有N行 M列 接下来共N行M列表示矩阵 输出格式 输出转置以后的
  • U3D游戏开发中摇杆的制作(NGUI版)

    在PC端模拟摇杆 实现控制摇杆让玩家或者物体移动 以下是完整代码 using System Collections using System Collections Generic using UnityEngine public clas
  • 游戏开发常见操作梳理之NPC任务系统

    多数游戏存在任务系统 接下来介绍通过NPC触发任务的游戏制作代码 using System Collections using System Collections Generic using UnityEngine
  • 游戏开发常见操作梳理之小地图的制作

    游戏中一般存在小地图系统 实际上就是设置一个新的摄像机放置在玩家的正上方 然后在小地图上显示新摄像机看见的东西就可以了 在小地图上一般存在放大地图和缩小地图的按钮可以方便放大和缩小地图 这些操作是如何实现的呢 接下来直接上核心代码 usin
  • 5_机械臂运动学基础_矩阵

    上次说的向量空间是为矩阵服务的 1 学科回顾 从科技实践中来的数学问题无非分为两类 一类是线性问题 一类是非线性问题 线性问题是研究最久 理论最完善的 而非线性问题则可以在一定基础上转化为线性问题求解 线性变换 数域 F 上线性空间V中的变

随机推荐

  • Mrtk 如何动态开启关闭网格渲染

    protected void Show IMixedRealityDataProviderAccess dataProviderAccess CoreServices SpatialAwarenessSystem as IMixedReal
  • Unity编辑器随机生成物体,更换场景之后物体丢失问题解决

    前言 obj GameObject PrefabUtility InstantiatePrefab configData bigMainScene 我在编辑器开发的时候实例化预制体到场景中之后 在跳转场景之后 然后在返回实例化过物体的场景会
  • 【Ansible自动化运维实战】使用Asible批量部署yum仓库

    Ansible自动化运维实战 使用Asible批量部署yum仓库 一 时间要求及目的 二 playbook内容 三 运行palybook 一 时间要求及目的 使用华为镜像源作为yum仓库批量分发达到所有受控端 二 playbook内容 ro
  • 【成电860考研】电子科技大学软件工程860考研专业课真题考频总结

    博主最近考研上岸啦 成电软件工程860专业课考了122 总分不高 这篇文章主要介绍专业课 我就不分享别的啦 博主考研的时候收集了几乎全网的资料 找到了几乎所有能找到的860资料进行汇总分析 得到了最后的真题考频 为了帮助学弟学妹们 博主决定
  • 4261. 孤独的照片

    数据范围为500 000 所以应该控制在O nlogn 或O n 我们发现要枚举的子串它其中有一个字母只出现一次 所以 我们可以去枚举只出现一次的字母是哪个 假设在第i个位置的字母为G 我们要枚举包含这个字母的 且只包含一个G的 且长度大于
  • QGroupBox布局中简单的操作

    QGroupBox中布局各个控件的使用 注意 我是先用了Qt designer设计 然后根据转成的 py文件代码 进行适当修改得到的 将进行三个示例讲解 目录 QGroupBox上添加栅格布局 某一组件充满整个QGroupBox QGrou
  • 抖音小程序实践三:接口开发指南

    通过官方文档可以更系统的学习到所有的接口 我这边罗列一下我自己用到测试过的接口供大家参考 前端 小程序对接官方文档 https microapp bytedance com docs zh CN mini app develop api o
  • RDMA技术详解——DMA和RDMA概念

    1 1 DMA DMA Direct Memory Access 直接内存访问 是一种能力 允许在计算机主板上的设备直接把数据发送到内存中去 数据搬运不需要CPU的参与 如下图所示 红线部分为传统内存访问 需要通过CPU进行数据copy来移
  • python导入数学函数_Python 数学函数模块(Math)

    1 内置的数学函数 min 和max 函数可用于查找可迭代的最小值或最大值 例如 x min 5 10 25 y max 5 10 25 print x print y abs 函数返回指定数字的绝对 正 值 例如 x abs 7 25 p
  • 微信小程序之 navigateTo

    navigateTo页面跳转传参 使用标签的方式跳转 变量需要 A页面
  • UE-从鼠标出进行射线检测

    第一种方式 Convert Mouse Location To World Space 将鼠标屏幕2D位置转换为场景空间3D位置和方向 将鼠标位置从2D转换成3D 第二种方式 Deprohiect Screen to World 将给定的2
  • 自动化驱动程序管理

    在部署操作系统时 每次都从下载和分发所需的驱动程序中实现真正的独立性可能是一场艰苦的战斗 特别是具有硬件多样化的环境 并且需要支持新的硬件类型时 借助 OS Deployer 可以对所有端点使用一个映像 无论品牌和型号如何 驱动程序将自动处
  • 数据结构与算法-队列

    定义 队列是ListInsert发生表尾 ListDelete发生在表头的线性表 主要操作 入队 出队 术语 表头 队头 表尾 队尾 插入 入队 删除 出队 特点 先入先出 FIFO 插入的位置是length 1 删除的位置的是1 一般读取
  • 【图像分割】基于形态学实现视网膜血管分割附matlab代码

    1 简介 目的 影像中血管的分割与特征提取 对疾病的早期诊断具有重要意义 针对很多视网膜血管提取算法分割精度不高的问题 提出了运用数学形态学中的高帽变换的方法对其进行检测 方法 首先 选取结构元素为 圆盘形 的形态学对图像进行高帽变换 经过
  • 期货开户抓住每一个波段利润

    个人认为 小资金帐户做趋势没太大意义 原因在于资金绝对值太小 1000万的帐户因其资金绝对值较大 所以30 的回报率就很可观 但10万的帐户即使做到100 资金回报也微不足道 大资金做趋势 小资金做波段这也成为了期货投机市场的普遍规律 如你
  • 【WIN_server_2008】实现【Web服务器】的安装与配置

    1 网络互通 一 WIN7 WIN 2008 WIN10菜单栏 编辑 虚拟机网络编辑器 VMnet1 如上篇文章设置 二 WIN7 WIN 2008 虚拟机设置 网络适配器 如下图配置 三 WIN7 WIN 2008 WIN10的IP 子网
  • ODPS-SQL多维度交叉的优化方法探究

    一 背景 odps是阿里集团的大数据计算平台 odps sql语法类似于hive 最近做了一个 项目 需求中用到了大量的维度交叉 等到需求实现后却发现新的问题 cube的交叉维度太多了 最初有17个 而且指标的计算逻辑比较复杂 造成数据加工
  • 【满分】【华为OD机试真题2023 JS】找数字

    华为OD机试真题 2023年度机试题库全覆盖 刷题指南点这里 找数字 知识点哈希表 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 给一个二维数组nums 对于每一个元素num i 找出距离最近的且值相等的元素 输出横纵坐标
  • sci期刊投稿指南 计算机科学 人工智能方向 145本sci期刊目录 从一区到四区(2022年 最新影响因子更新了)

    SCI期刊投稿指南 计算机科学 人工智能方向 140本sci期刊目录 从一区到四区总有一本适合你 有时候论文写好了 却不知道人工智能方向有哪些期刊可以投稿 自己也不知道哪里找 这里为大家罗列了当前人工智能方向可以投稿的145本SCI期刊 方
  • 【图形与渲染】相机平面镜反射与斜裁剪矩阵(下)-斜裁剪矩阵

    上一篇文章分析了平面镜反射效果实现中 如何计算镜像矩阵 我们已经可以得到镜像相机并渲染出镜像后的效果了 但是只是纯粹的镜像会遇到以下问题 如图 当相机镜像到C 位置后 其视锥体裁剪范围是A B 但实际应该位于反射贴图中的区域仅仅只有A区域