Shader理论(2):Unity中的各种坐标系

目录

前言

一、坐标系

1.1 世界坐标系(World Space)

1.2 本地坐标系(Local Space):模型坐标系

1.3 屏幕坐标系(Screen Space)

1.4 观察坐标系(ViewPort Space):视口坐标系

1.5 裁剪坐标(Clip Space)

1.6 UI坐标系

1.7 UV坐标系

二、坐标系的转化

三、其他

3.1 求物体(顶点)与摄像机的距离:

3.2 求物体(顶点)与摄像机的方向:

参考资料:


前言

第二部分是关于写shader时经常会碰到的坐标系和坐标系转化相关的问题。

一、坐标系

1.1 世界坐标系(World Space)

世界坐标是按照笛卡尔坐标系定义出来的绝对坐标系,即空间直角坐标系。在unity中采用的是左手坐标系,即x为左右,y为上下,z为前后

获取方式:tranform.position

1.2 本地坐标系(Local Space):模型坐标系

模型自身的坐标系,在创建模型时就已确定,需要在第三方建模软件中才能修改,在unity中无法修改坐标原点。

获取方式:transform.localPosition

在shader中默认输入的就是模型坐标

1.3 屏幕坐标系(Screen Space)

屏幕坐标系即将屏幕作为一个坐标系,以左下角为原点(0, 0)

1.4 观察坐标系(ViewPort Space):视口坐标系

每个相机都是一个观察者,每个观察者都有自己的视界,将画面投影到该视口上,左下角为原点(0,0),右上角为(1,1)

1.5 裁剪坐标(Clip Space)

裁剪坐标是将观察世界的一部分截取出来。摄像机在取景的时候使用一个六面体去处理可视的区域,所有在这个区域的物体才会被显示。那么你肯定会有以为,为什么不直接用观察坐标,为什么一定要用这个裁剪呢? 首先,相机有两种模式,即透视相机与正交镜头(没有近大远小的透视效果)。这两种模式的切换会在裁剪坐标中处理。其次裁剪坐标规定了那些模型计算后可以显示,那些模型计算后但不用显示。所以必须有这个步骤(参考链接:unity 七种坐标系统详解与互相转换的方法 模型坐标、世界坐标、观察坐标(视口坐标)、裁剪坐标、屏幕坐标、ui坐标、uv坐标_千年奇葩的博客-CSDN博客_模型坐标和世界坐标

1.6 UI坐标系

ui坐标系是可视化窗口的最顶层,世界坐标系的物体都会被ui坐标系遮挡

1.7 UV坐标系

uv坐标系只负责定位贴图和模型的关系

二、坐标系的转化

名称 shader中的变量名 数据类型 说明
vertex POSITION float4 顶点在空间中的位置
normal NORMAL float4 法线
tangent TANGENT float4 切线
direction float3 顶点在空间中的朝向
distance float4 两点之间的距离
texcoord TEXCOORD0 float4 处理贴图的uv坐标
模型空间 裁剪空间 观察空间 世界空间
模型空间

顶点:

vec = UnityObjectToClipPos(v.vertex);

顶点:

vec = UnityObjectToViewPos(v.vertex);

顶点:

vec = UnityObjectToWorldDir(v.vertex);

法线:

vec = UnityObjectToWorldNormal(v.vertex);

裁剪空间
观察空间

顶点:

vec = UnityViewToClipPos(v.vertex);

世界空间

法线:

vec = UnityWorldToObjectDir(v.vertex);

顶点:

vec = UnityWorldToClipPos(v.vertex);

顶点:

vec = UnityWorldToViewPos(v.vertex);

//将顶点从模型空间转换为裁剪空间
float3 vec;
//模型空间转为裁剪空间
vec = UnityObjectToClipPos(v.vertex);
// vec =  UnityObjectToClipPos(float4(v.vertex), 1.0));
                    
//模型空间转换为观察空间
vec =  UnityObjectToViewPos(v.vertex);
// vec =  mul(UNITY_MATRIX_MV, float4(v.vertex), 1.0)).xyz;
//从世界空间转到观察空间
vec =  UnityWorldToViewPos(v.vertex);

//模型空间转换到世界空间
vec =  UnityObjectToWorldDir(v.vertex);
//观察空间转为裁剪空间
vec =  UnityViewToClipPos(v.vertex);
//世界空间转到裁剪空间
vec =  UnityWorldToClipPos(v.vertex);

//法线
//法线从模型空间转换到世界空间
vec =  UnityObjectToWorldNormal(v.vertex);
//世界空间转到模型空间
vec =  UnityWorldToObjectDir(v.vertex);
                    
//摄像机相关
//输入一个object空间顶点位置,返回世界空间中从该点到摄像机的观察方向。
vec =  WorldSpaceViewDir(v.vertex); 
//输入一个object空间顶点位置,返回object空间中从该点到摄像机的观察方向。
vec =  ObjSpaceViewDir (v.vertex);

//灯光
//仅用于前向渲染,输入一个object空间顶点的位置,返回世界空间中从该点到光源的光照方向
vec =  WorldSpaceLightDir (v.vertex);
//仅用于前向渲染,输入一个object空间顶点的位置,返回object空间中从该点到光源的光照方向
vec = ObjSpaceLightDir (v.vertex);

三、其他

3.1 求物体(顶点)与摄像机的距离:

//先将坐标转换至裁剪空间
float3 viewPos = UnityObjectToClipPos(v.vertex);
//物体(顶点)与镜头距离
float distance = length(posView);

3.2 求物体(顶点)与摄像机的方向:

//先将坐标从模型空间转为世界空间
float3 worldPos = UnityObjectToWorldDir(v.vertex);
//物体(顶点)与摄像机的方向
o.viewDir = normalize(UnityWorldSpaceViewDir(worldPos));

参考资料:

[1] 详解Unity中的各种坐标系_梦天幼的博客-CSDN博客_unity世界坐标和自身坐标

[2] unity 七种坐标系统详解与互相转换的方法 模型坐标、世界坐标、观察坐标(视口坐标)、裁剪坐标、屏幕坐标、ui坐标、uv坐标_千年奇葩的博客-CSDN博客_模型坐标和世界坐标

[3] Unity ShaderLab 坐标空间转换及方法_千年奇葩的博客-CSDN博客

unity 七种坐标系统详解与互相转换的方法 模型坐标、世界坐标、观察坐标(视口坐标)、裁剪坐标、屏幕坐标、ui坐标、uv坐标_千年奇葩的博客-CSDN博客_模型坐标和世界坐标介绍 unity 总共有四种坐标: 1,鼠标所在的屏幕坐标,只包含x,y值,数据类型是vector2 2,ui坐标,在canvas中的ui坐标。数据类型是vector3 3,世界坐标,三维世界坐标 数据类型是vector3 Unity3D的四种坐标系 【Unity3D的四种坐标系】1、World Space(世界坐标):我们在场景中添加物体(如:Cube...https://blog.csdn.net/lengyoumo/article/details/80772323

猜你喜欢

转载自blog.csdn.net/qq_41904236/article/details/125138688