Unity中Shader裁剪空间推导(在Shader中使用)

文章目录

  • 前言
  • 一、在Shader中使用转化矩阵
    • 1、在顶点着色器中定义转化矩阵
    • 2、用 UNITY_NEAR_CLIP_VALUE 区分平台矩阵
    • 3、定义一个枚举用于区分当前是处于什么相机
  • 二、我们在DirectX平台下,看看效果
    • 1、正交相机下
    • 2、透视相机下
    • 3、最终代码


前言

在上一篇文章中,我们推导得出了 透视相机到裁剪空间的转化矩阵

  • Unity中Shader裁剪空间推导(透视相机到裁剪空间的转化矩阵)

我们在正交矩阵Shader的基础上,继续测试

  • Unity中Shader裁剪空间推导(在Shader中实现)

在这篇文章中,我们在Shader中使用该矩阵测试一下。

  • OpenGL
    [ 2 v w 0 0 0 0 2 n h 0 0 0 0 n + f n − f 2 n f n − f 0 0 − 1 0 ] \begin{bmatrix} \frac{2v}{w} & 0 & 0 & 0 \\ 0 & \frac{2n}{h} & 0 &0\\ 0 & 0 & \frac{n+f}{n-f} &\frac{2nf}{n-f}\\ 0 & 0 & -1 & 0\\ \end{bmatrix} w2v0000h2n0000nfn+f100nf2nf0
  • DirectX
    [ 2 v w 0 0 0 0 2 n h 0 0 0 0 n f − n n f f − n 0 0 − 1 0 ] \begin{bmatrix} \frac{2v}{w} & 0 & 0 & 0 \\ 0 & \frac{2n}{h} & 0 &0\\ 0 & 0 & \frac{n}{f-n} &\frac{nf}{f-n}\\ 0 & 0 & -1 & 0\\ \end{bmatrix} w2v0000h2n0000fnn100fnnf0

一、在Shader中使用转化矩阵

1、在顶点着色器中定义转化矩阵

  • OpenGL:

M_clipP = float4x4
(
2n/w,0,0,0,
0,2
n/h,0,0,
0,0,(n+f)/(n-f),(2nf)/(n-f),
0,0,-1,0
);

  • DirectX:

M_clipP = float4x4
(
2n/w,0,0,0,
0,2
n/h,0,0,
0,0,n/(f-n),(n*f)/(f-n),
0,0,-1,0
);

2、用 UNITY_NEAR_CLIP_VALUE 区分平台矩阵

  • 1为OpenGL
  • -1为DirectX

3、定义一个枚举用于区分当前是处于什么相机

[Enum(OrthoGraphic,0,Perspective,1)]_CameraType(“CameraType”,Float) = 0

  • 在手动转化矩阵时使用三目运算符来决定使用哪一个矩阵

float4x4 M_clip = _CameraType ? M_clipP : M_clipO;
o.vertexCS = mul(M_clip,float4(vertexVS,1));


二、我们在DirectX平台下,看看效果

1、正交相机下

在这里插入图片描述

2、透视相机下

在这里插入图片描述

3、最终代码

//平移变换
//缩放变换
//旋转变换(四维)
//视图空间矩阵
//正交相机视图空间 -> 裁剪空间
Shader "MyShader/URP/P3_7_6"
{Properties{[Header(MainTexx)]_MainTex("MainTex",2D) = "white"{}[Header(Transtion)]_Translate("Translate(XYZ)",Vector) = (0,0,0,0)_Scale("Scale(XYZ)",Vector)= (1,1,1,1)_Rotation("Rotation(XYZ)",Vector) = (0,0,0,0)[Header(View)]_ViewPos("View Pos",vector) = (0,0,0,0)_ViewTarget("View Target",vector) = (0,0,0,0)[Header(Camera)]_CameraParams("Size(X),Near(Y),Far(Z) Ratio(W)",Vector) = (0,0,0,1.777)[Enum(OrthoGraphic,0,Perspective,1)]_CameraType("CameraType",Float) = 0}SubShader{Tags{"PenderPipeline"="UniversalPipeline""RenderType"="Opaque""Queue"="Geometry"}Pass{HLSLPROGRAM#pragma vertex vert#pragma fragment frag#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"struct Attribute{float4 vertexOS : POSITION;float2 uv : TEXCOORD0;};struct Varying{float4 vertexCS : SV_POSITION;float2 uv : TEXCOORD0;};CBUFFER_START(UnityPerMaterial)float4 _Translate;float4 _Scale;float4 _Rotation;float4 _ViewPos;float4 _ViewTarget;float4 _CameraParams;float _CameraType;CBUFFER_ENDTEXTURE2D(_MainTex);SAMPLER(sampler_MainTex);Varying vert (Attribute v){Varying o;o.uv = v.uv;//平移变换float4x4 M_Translate = float4x4(1,0,0,_Translate.x,0,1,0,_Translate.y,0,0,1,_Translate.z,0,0,0,1);v.vertexOS = mul(M_Translate,v.vertexOS);//缩放交换float4x4 M_Scale = float4x4(_Scale.x,0,0,0,0,_Scale.y,0,0,0,0,_Scale.z,0,0,0,0,1);v.vertexOS = mul(M_Scale,v.vertexOS);//旋转变换float4x4 M_rotateX = float4x4(1,0,0,0,0,cos(_Rotation.x),sin(_Rotation.x),0,0,-sin(_Rotation.x),cos(_Rotation.x),0,0,0,0,1);float4x4 M_rotateY = float4x4(cos(_Rotation.y),0,sin(_Rotation.y),0,0,1,0,0,-sin(_Rotation.y),0,cos(_Rotation.y),0,0,0,0,1);float4x4 M_rotateZ = float4x4(cos(_Rotation.z),sin(_Rotation.z),0,0,-sin(_Rotation.z),cos(_Rotation.z),0,0,0,0,1,0,0,0,0,1);v.vertexOS = mul(M_rotateX,v.vertexOS);v.vertexOS = mul(M_rotateY,v.vertexOS);v.vertexOS = mul(M_rotateZ,v.vertexOS);//观察空间矩阵推导//P_view = [W_view] * P_world//P_view = [V_world]^-1 * P_world//P_view = [V_world]^T * P_worldfloat3 ViewZ = normalize(_ViewPos.xyz - _ViewTarget.xyz);float3 ViewY = float3(0,1,0);float3 ViewX = cross(ViewZ,ViewY);ViewY = cross(ViewX,ViewZ);float4x4 M_viewTemp = float4x4(ViewX.x,ViewX.y,ViewX.z,0,ViewY.x,ViewY.y,ViewY.z,0,ViewZ.x,ViewZ.y,ViewZ.z,0,0,0,0,1);float4x4 M_viewTranslate = float4x4(1,0,0,-_ViewPos.x,0,1,0,-_ViewPos.y,0,0,1,-_ViewPos.z,0,0,0,1);float4x4 M_view = mul(M_viewTemp,M_viewTranslate);float3 vertexWS = TransformObjectToWorld(v.vertexOS.xyz);//世界空间转化到观察空间float3 vertexVS = mul(M_view,float4(vertexWS,1)).xyz;//相机参数float h = _CameraParams.x * 2;float w = h * _CameraParams.w;float n = _CameraParams.y;float f = _CameraParams.z;//正交相机投影矩阵//P_Clip = [M_Clip] * P_viewfloat4x4 M_clipO;if(UNITY_NEAR_CLIP_VALUE==-1){//OpenGLM_clipO = float4x4(2/w,0,0,0,0,2/h,0,0,0,0,2/(n - f),(n + f) / (n - f),0,0,0,1);}if(UNITY_NEAR_CLIP_VALUE==1){//DirectXM_clipO = float4x4(2/w,0,0,0,0,2/h,0,0,0,0,1/(f-n),f/(f-n),0,0,0,1);}//透视相机投影矩阵float4x4 M_clipP;if(UNITY_NEAR_CLIP_VALUE==-1){//OpenGLM_clipP = float4x4(2*n/w,0,0,0,0,2*n/h,0,0,0,0,(n+f)/(n-f),(2*n*f)/(n-f),0,0,-1,0);}if(UNITY_NEAR_CLIP_VALUE==1){//DirectXM_clipP = float4x4(2*n/w,0,0,0,0,2*n/h,0,0,0,0,n/(f-n),(n*f)/(f-n),0,0,-1,0);}//手动将观察空间下的坐标转换到裁剪空间下float4x4 M_clip = _CameraType ? M_clipP : M_clipO;o.vertexCS = mul(M_clip,float4(vertexVS,1));//观察空间 转化到 齐次裁剪空间//o.vertexCS = TransformWViewToHClip(vertexVS);//o.vertexCS = TransformObjectToHClip(v.vertexOS.xyz);return o;}half4 frag (Varying i) : SV_Target{float4 mainTex = SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,i.uv);return mainTex;}ENDHLSL}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/584993.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高光回眸:阿里云容器服务如何全面助力精彩亚运

作者:刘佳旭 谢乘胜 贤维 引言 2023 年,第 19 届杭州亚运会在杭州成功举办。在亚运之光和科技之光的交相辉映下,这届亚运会成为亚运史上首届“云上亚运”,用云计算创造了历史,赛事核心系统和转播全面上云&#xff0c…

[足式机器人]Part2 Dr. CAN学习笔记-自动控制原理Ch1-6根轨迹Root locus

本文仅供学习使用 本文参考: B站:DR_CAN Dr. CAN学习笔记-自动控制原理Ch1-6根轨迹Root locus 1. 根的作用2. 手绘技巧3. 分离点/汇合点&根轨迹的几何性质 1. 根的作用 G ( s ) s 3 s 2 2 s 4 G\left( s \right) \frac{s3}{s^22s4} G(s)s22s4s3​…

Qt Quick 用cmake怎么玩子项目

以下内容为本人的著作,如需要转载,请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/o-_aGqreuQda-ZmKktvxwA 以往在公司开发众多的项目中,都会出现要求本项目里部分功能模块代码需要具备保密性。如果需要对外输出demo工程&…

如何拍摄好VR全景图片,VR全景图片后期处理有什么技巧

引言: VR全景图片是一种以全景视角呈现场景的图片,通过VR技术可以将用户带入虚拟的环境中,给人一种身临其境的感觉,那么如何才能更好的制作让人满意的全景图片呢? 一.如何拍摄好VR全景图片 1.选择合适的拍…

vue中常见的指令

简单介绍一下常见的vue中用到的指令 v-on 指定当前的事件&#xff0c;语法糖为&#xff0c;如例子所示&#xff0c;指定按钮的事件为addCounter&#xff0c;点击会使变量counter 1 <!DOCTYPE html> <html><head><meta charset"utf-8" />…

Unity JSON编码解码之LitJson 深度剖析

把LitJson的代码库放入到项目中&#xff0c;如图所示:JSON在游戏开发中是一种序列化/反序列化常用的技术&#xff0c;把游戏相关的数据,如地图组成,通过JSON编码&#xff0c;序列化成JSON文本&#xff0c;传输或存储, 要使用的时候再通过JSON技术把文本解析成数据对象&#xff…

2023-12-29 服务器开发-centos-安装php8

摘要: 2023-12-29 服务器开发-centos-安装php8 centos-安装php8 必备条件 Minimal CentOS 8 / RHEL 8User with sudo rightsInternet Connection (1) 更新系统 更新系统 $ sudo dnf update $ sudo dnf upgrade 重启系统 $ sudo reboot (2) 启用 EPEL & Remi 软件库…

【教学类-43-03】20231229 N宫格数独3.0(n=1、2、3、4、6、8、9) (ChatGPT AI对话大师生成 回溯算法)

作品展示&#xff1a; 背景需求&#xff1a; 大4班20号说&#xff1a;我不会做这种&#xff08;九宫格&#xff09;&#xff0c;我做的是小格子的&#xff0c; 他把手工纸翻过来&#xff0c;在反面自己画了矩阵格子。向我展示&#xff1a;“我会做这种&#xff01;” 原来他会…

Android笔记(二十三):Paging3分页加载库结合Compose的实现分层数据源访问

在Android笔记&#xff08;二十二&#xff09;&#xff1a;Paging3分页加载库结合Compose的实现网络单一数据源访问一文中&#xff0c;实现了单一数据源的访问。在实际运行中&#xff0c;往往希望不是单纯地访问网络数据&#xff0c;更希望将访问的网络数据保存到移动终端的SQL…

GitHub Copilot 终极详细介绍

编写代码通常是一项乏味且耗时的任务。现代开发人员一直在寻找新的方法来提高编程的生产力、准确性和效率。 像 GitHub Copilot 这样的自动代码生成工具可以使这成为可能。 GitHub Copilot 到底是什么&#xff1f; GitHub Copilot 于 2021 年 10 月推出&#xff0c;是 GitHub 的…

【无标题】《巴黎图书馆》,又发现一本书

我喜愛看的书(https://img-blog.csdnimg.cn/8cd84d33e6724f09a46831f75abe6464.jpg)在这里插入图片描述

c语言-string.h库函数初识

目录 前言一、库函数strlen()1.1 strlen()介绍1.2 模拟实现strlen() 二、库函数strcpy()2.1 strcpy()介绍2.2 模拟实现strcpy() 三、库函数strcmp()3.1 strcmp()介绍3.3 模拟实现strcmp() 总结 前言 本篇文章介绍c语言<string.h>头文件中的库函数&#xff0c;包含strlen…

网络交换机端口管理会面临的问题

交换机端口管理是跟踪网络交换机及其端口连接详细信息的过程&#xff0c;在大型网络中&#xff0c;交换机端口管理过程通常使用自动化交换机端口管理工具执行。 通过网络交换机端口提供的完全控制和可见性使交换机端口管理工具在管理网络时必不可少&#xff0c;在网络中部署交…

权重函数设计

1e4/(0.5*s^21*s1) 1.4125 抑制驱动器饱和 1e-4*(s1)/(0.001*s1) 10*(s10)/(s1000) 1e-6*(s1)/(0.001*s1) [0.01,0.1],[0.001,1] 0.5*(0.05*s1)/(0.0001*s0.01)

Vue2 - v-model 简介

目录 1&#xff0c;原理1.1&#xff0c;作用于表单元素1.2&#xff0c;作用于自定义组件 2&#xff0c;编译结果展示2.2&#xff0c;表单元素2.1&#xff0c;自定义组件 1&#xff0c;原理 官网参考 v-model 是一个语法糖&#xff0c;最终会生成一个属性和一个事件。并且即可…

彻底理解前端安全面试题(1)—— XSS 攻击,3种XSS攻击详解,建议收藏(含源码)

前言 前端关于网络安全看似高深莫测&#xff0c;其实来来回回就那么点东西&#xff0c;我总结一下就是 3 1 4&#xff0c;3个用字母描述的【分别是 XSS、CSRF、CORS】 一个中间人攻击。当然 CORS 同源策略是为了防止攻击的安全策略&#xff0c;其他的都是网络攻击。除了这…

FFmpeg学习笔记--Centos8安装FFmpeg

1--安装指令 sudo yum install epel-releasesudo yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-8.noarch.rpmsudo yum install ffmpeg ffmpeg-develffmpeg -version 2--版本信息

【c语言】飞机大战(1)

提前准备好游戏要的素材&#xff0c;可以到爱给网去找&#xff0c;飞机大战我们需要的是一个我方战机图片&#xff0c;一个背景图&#xff0c;三个敌方战机的图&#xff0c;我方战机的图片&#xff0c;敌方战机的图片&#xff0c;并且将图片和.cpp放在同一文件夹下. 这里创建.…

如何在MAC OS中的XCODE下添加 <bits/stdc++.h>

mac上使用的编译器是Clang&#xff0c;但是没有万能头文件bits/stdc.h\&#xff0c;本文介绍如何添加万能头文件 Xcode 版本&#xff1a;15.1 - 打开应用程序-Xcode-右键显示包内容 Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/includ…

Java基础语法

文章目录 注意&#xff1a;day01 - Java基础语法1. 人机交互1.1 什么是cmd&#xff1f;1.2 如何打开CMD窗口&#xff1f;1.3 常用CMD命令1.4 CMD练习1.5 环境变量 2. Java概述1.1 Java是什么&#xff1f;1.2下载和安装1.2.1 下载1.2.2 安装1.2.3 JDK的安装目录介绍 1.3 HelloWo…