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

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 Shader入门精要第七章 基础纹理之遮罩纹理

    Unity系列文章目录 文章目录 Unity系列文章目录 前言 一 实践 参考 前言 遮罩纹理 mask texture 是本章要介绍的最后一种纹理 它非常有用 在很多商业游戏中 都可以见到它的身影 那么什么是遮罩呢 简单来讲 遮罩允许我们
  • 泊松重建算法原理介绍

    目录 1 泊松重建算法 2 泊松重建核心思想及原理 3 泊松算法流程 本文出自CSDN点云侠 原文链接 爬虫自重 把自己当个人 1 泊松重建算法 泊松重建是Kazhdan M在2006年提出的基于八叉树和泊松方程的一种网格三维重建算法 其本
  • UnityVR--组件3--Line Renderer--线性渲染

    目录 线性渲染组件简介 绘制线条Line Renderer组件介绍 绘制拖尾Trail Renderer组件介绍 应用1 使用Line Renderer绘制线段 应用1实现 使用系统工具或自定义工具绘制线段 应用2 Trail Render
  • Unity3d 插件 系列——DoTweenPro介绍(图文详细+案例)

    Unity3d 插件 系列 DoTweenPro介绍 图文详细 案例 前言 一 DoTweenPro简介 二 DoTweenPro安装 三 DoTweenPro主要组件 1 DoTweenAnimation 2 DoTweenPath 3
  • Unity中UI框架的使用1-添加面板、显示Loading页面

    其中BasePanel和Canvas都是挂在面板的预制物上的 1 导入我们的UI框架 本篇文章中有用的是两个UIPanelType NUIManager和NBasePanel 会放在文章最后供大家使用 2 先将我们做好的Panel设置成预制
  • Unity与Android的Back键冲突解决

    Unity与Android的Back键冲突解决 上一篇的最后留下了两个问题 Unity视图下横屏闪退 Unity视图下Android无法响应back返回上一activity 对于第一个问题 应该是Unity横屏下视图的某些设置跟Androi
  • Unity 键盘控制人物移动——之输入方式代码的编写

    键盘输入 控制人物移动 在我们制作游戏中最常见的需求之一就是使用键盘移动游戏角色 那么我们首先需要获取键盘输入 以下提供两种方法获取键盘 这里尽量通过截图解释让大家理解代码的含义 GetInput void FixedUpdate Move
  • Unity打包WebGL的优化常用操作?

    1 贴图部分优化 如果贴图格式时2048 在不影响画面效果的情况下 改成1024或者5 12 还可以缩小包体 2 压缩和解压缩问题 WebGL打包的时候分三种压缩情况 gzip 比Brotli文件打 但打包快 http和https都支持 B
  • 用Czerny-Turner系统检测钠灯双线

    1 摘要 Czerny Turner系统被广泛用于分析光源的光谱信息 通常 首先用抛物面反射镜对光源进行准直 然后用衍射光栅对颜色进行空间分离 在这个例子中 我们提出了一种由反射镜和衍射光栅组成的Czerny Turner系统 用于检测钠双
  • unity dots jobSystem 记录

    Looking for a way to get started writing safe multithreaded code Learn the principles behind our Job System and how it w
  • unity3d 自定义的图片无法放入source image中

    须将图片的texture type改为 sprite
  • unity3d image组件不显示

    需要将UI组件放到画布下面
  • 微信游戏如何开发

    中懿游游戏软件开发 微信游戏开发通常涉及使用微信小游戏平台进行开发 微信小游戏是一种在微信平台上运行的轻量级游戏 用户可以在微信中直接体验 无需下载安装 以下是在微信平台上开发小游戏的一般步骤 1 注册微信开发者账号 访问 微信开放平台 注
  • 【转载】【Unity】WebSocket通信

    1 前言 Unity客户端常用的与服务器通信的方式有socket http webSocket 本文主要实现一个简单的WebSocket通信案例 包含客户端 服务器 实现了两端的通信以及客户端向服务器发送关闭连接请求的功能 实现上没有使用U
  • 短视频账号矩阵系统3年独立开发正规接口源码搭建部署开发

    一 矩阵系统源码主要有三种框架 短视频账号矩阵源码的框架有很多种 以下列举其中几种 1 星图矩阵 星图矩阵是抖音官方向商家提供的短视频广告推广平台 是抖音官方的赚钱工具 商家可利用星图矩阵进行广告推广 同时短视频创作者也能通过星图平台获取收
  • Unity学习笔记

    一 旋转欧拉角 四元数 Vector3 rotate new Vector3 0 30 0 Quaternion quaternion Quaternion identity quaternion Quaternion Euler rota
  • Unity中URP下的指数雾

    文章目录 前言 一 指数雾 雾效因子 1 FOG EXP 2 FOG EXP2 二 MixFog 1 ComputeFogIntensity 雾效强度计算 2 lerp fogColor fragColor fogIntensity 雾效颜
  • 矩阵基本操作

    问题描述 已知一个n n的矩阵 方阵n lt 100 把矩阵主副对角线上的元素值加上x 然后输出这个新矩阵 输入格式 一行两个变量 用空格隔开 代表n和x 接下来的n行每行n列 表示矩阵的数值 用空格隔开 输出格式 输出新矩阵 每个数字5个
  • 游戏开发常见操作梳理之角色选择一

    进入游戏后 我们经常会进入角色选择的界面 通常是左右两个按钮可以更改角色供玩家选择 对于这种界面我们通常使用数据持久化将角色信息存储起来 接下来的笔记中 我将使用自带的数据持久化系统对其进行操作 实现角色的选择页面 后续会更新xml系列的文
  • 游戏开发常见操作系列之敌人系统的开发一(U3D)

    在开发游戏的过程中 我们常常会出现一些敌人攻击我们玩家 并且实现掉血以及死亡的现象 敌人还会源源不断地生成 这是怎么制作的呢 接下来为大家提供方法 其中使用了NGUI 后续会更新其它方法 敬请期待 使用HUDText实现扣血时显示文本 直接

随机推荐

  • 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区域