自己做的网站被篡改怎么办徐州网站设计
2026/1/8 21:10:36 网站建设 项目流程
自己做的网站被篡改怎么办,徐州网站设计,滁州新手跨境电商建站哪家好,摄影网站采用照片做宣传_版权费是多少?把点投影到裁剪空间#xff08;Clip Space#xff09;#xff0c;本质上就是#xff1a; 把“从摄像机看到的那块三维视锥世界”#xff0c;压扁变成一个规则的“标准盒子”#xff0c; 方便 GPU 后面统一裁剪、归一化、映射到屏幕。听着很玄#xff0c;其实特别生活化Clip Space本质上就是把“从摄像机看到的那块三维视锥世界”压扁变成一个规则的“标准盒子”方便 GPU 后面统一裁剪、归一化、映射到屏幕。听着很玄其实特别生活化你眼前真实的世界大小不一、远近不同、形状乱七八糟GPU 比较懒喜欢处理“统一格式”的数据于是它想办法把“能看到的那块空间”捏成一个标准尺寸的长方体中心是 0左右上下前后就是 -1 到 1一种约定所有看得见的点都被塞进这个盒子里超出盒子之外的直接剪掉裁剪盒子内部再往屏幕上“摊平”就成了一张图。这篇文章我们就用大白话把下面这几个问题讲透裁剪空间Clip Space到底是个啥为什么非要把三维世界变成一个“标准盒子”投影矩阵Projection Matrix在整个过程里干了啥那个看起来很怪的w分量以及“除以 w透视除法”是在干嘛点是怎么一步步从世界 → 摄像机 → 裁剪空间 → NDC → 屏幕的GPU 在 Clip Space 里做了哪些操作裁剪、可见性实际写 Shader / 引擎时你会怎么接触到 Clip Space看完之后你在脑子里看到“Clip Space / 投影矩阵 / gl_Position”这些词时就不会觉得是在念咒而是知道它们到底在做哪一步“压盒子”的事。一、先回顾一下我们为什么会走到“裁剪空间”这一步把坐标系整个链条先捋一遍模型空间Model / Local Space模型自己家里的坐标只描述它长啥样。比如立方体顶点(-1,-1,-1) ~ (1,1,1)。世界空间World Space整个游戏世界统一的坐标系。所有物体摆到同一张地图上。摄像机空间View / Camera Space以摄像机为原点和坐标轴的坐标系。所有东西变成“离相机前后左右上下多少”。到这里我们已经有了“以相机为中心、能看到的一块三维区域”——视锥体Frustum。接下来要做两件事把这块“视锥体”的三维点投影成一个规则的“标准盒子”这个标准盒子就是裁剪空间Clip Space做透视除法前然后再做除以 w变成 [-1,1] 的归一化坐标叫NDCNormalized Device Coordinates归一化设备坐标。这一整套主要由一个矩阵负责投影矩阵Projection Matrix。二、先形象一点视锥体 VS 标准盒子2.1 视锥体是个啥想象你拿着一个相机你眼前能看到的空间大致像一个“前面开的锥形截头体”离你太近的摄像机前面的一小块看不到被 near plane 裁掉离你太远的也看不到被 far plane 裁掉左右、上下有一个 FOV视野角。这块空间叫做视锥体View Frustum。形状大概像这样侧视图/| / | 相机/ | 可见范围 \ | \ | \|近裁剪面 远裁剪面 左右上下 4 个平面一共 6 个平面包围着这一块空间。2.2 Clip Space 要做的事情把这个不规整的锥体 → 变成标准长方体GPU 数学家们有一个习惯不喜欢直接处理“斜着的、不规整的锥体”喜欢统一把东西变成一个标准的长方体盒子。为什么规则盒子更好判断点在不在里面只要 x、y、z 在某个范围内就行更适合硬件里一套固定的裁剪逻辑为后续的归一化、屏幕映射打基础。所以投影矩阵干的第一件大事就是把摄像机空间里的视锥体“拉伸 扭曲”成一个标准长方体这个长方体对应的坐标就是剪裁空间Clip Space。三、Clip Space 是个什么样子的“标准盒子”在大多数学库/API 中Clip Space 是一个用齐次坐标表示的四维空间一个点在 Clip Space 中通常写成(x, y, z, w)后面会用x/w, y/w, z/w得到 NDC归一化设备坐标。在做“判断点在不在可见空间里面”之前Clip Space 中有这么一个约定在透视除法之前点要满足-w ≤ x ≤ w-w ≤ y ≤ w以及 z 与 w 的某些范围关系比如 -w ≤ z ≤ w或 0 ≤ z ≤ w。简单说就是一个“以原点为中心边界是 ±w 的四维盒子”。虽然听起来抽象但你可以这样理解把 w 当成一个“缩放参考值”当前帧能看见的东西都被挤压到这个“x,y,z ∈ [-w, w]”的区域内之后通过/w把这个盒子缩成 [-1,1] 的标准立方体NDC。所以Clip Space 投影矩阵刚变换完的、还没除以 w 前的空间NDC Clip Space 除以 w 之后的 [-1,1] 标准盒子。四、投影矩阵Projection Matrix负责“压盒子”的核心角色我们先不用公式吓自己用直觉描述投影矩阵要做的三个事让远处的东西看起来更小透视把视野角、宽高比、近远平面这些乱七八糟的参数编码进坐标变换中把不规整的“斜锥”变成规整可控的“盒子”。4.1 透视投影 vs 正交投影一般游戏里常用两种投影方式透视投影Perspective Projection模拟人眼 / 相机的效果近大远小适合 3D 场景。正交投影Orthographic Projection不考虑距离引起的缩放远处物体大小不变看起来像工程图或某些 2D / 策略游戏的效果用于 UI、某些编辑器视图。这两种投影对应不同的 Projection 矩阵但它们都完成了“把视锥或视体映射到标准盒子”的任务。4.2 透视投影近大远小是怎么“装”进矩阵里的在 Camera Space 中一个点的坐标是(x, y, z)平常的直觉是离相机越远|z|越大这个点投影到屏幕上应该越接近中心、越小。简单的透视关系像这样x_screen ∝ x / z y_screen ∝ y / z也就是说x 和 y 需要除以 z才能体现近大远小。但是我们的矩阵变换喜欢做的是“线性变换”M * (x,y,z,1)而/z是个非线性的操作。怎么办人类想出一个骚操作引入第四个分量 w用齐次坐标。投影矩阵会把 Camera Space 坐标(x,y,z,1)变成ClipPos (x, y, z, w)并且设计成x’ 和 y’ 里面“偷偷包含了 z 的信息”使得最后ndc.x x / w ndc.y y / w刚好就等价于之前那个x / z,y / z的透视关系。大白话投影矩阵把“除以 z”这件事藏进了“除以 w”的步骤里。所以你在代码里只看到clipPos Proj * viewPos; ndc clipPos / clipPos.w;而透视效果就在/w那一下完成了。4.3 近远平面、视野角、宽高比怎么藏进矩阵投影矩阵的参数一般包括fovField of View视野角aspect宽高比screenWidth / screenHeightnear近裁剪面距离far远裁剪面距离。这些参数会影响x,y 的缩放范围视野越大x,y 范围越宽z 的映射如何把 [near,far] 映射到 Clip Space 的 z范围再到 NDC再到深度缓冲的数值。你不用背公式只要记住投影矩阵根据 fov、aspect、near、far决定“视锥体的形状”和“如何把它压成盒子”。五、那个神秘的 w 分量 透视除法Perspective Divide现在我们来正面聊一聊大家最容易迷糊的地方齐次坐标和 w。5.1 为啥要多一个 w原来的 (x,y,z) 不够用吗如果我们只用 3 维坐标(x,y,z)做线性变换vec3 M3x3 * vec3 t它能表达的是平移、旋转、缩放、剪切、线性变换等等但没办法用一个矩阵统一表达“透视投影”这种带除法的非线性操作。引入齐次坐标(x,y,z,w)后可以把各种仿射变换、投影变换统一表示成一个 4x4 矩阵乘法然后统一通过一次/w完成以前那些“看起来非线性”的缩放。你可以用一个很粗糙但好记的比喻w 就像是一个“还没结算的缩放因子”先把所有变换放在 (x,y,z,w) 里最后一次除以 w来“结账”得到最终的 3D 坐标。5.2 Clip Space 到 NDC透视除法在顶点着色器里你经常会看到这样的代码以 OpenGL 为例gl_Position ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(localPos, 1.0);这里的gl_Position就是 Clip Space 坐标(x, y, z, w)。GPU 在后续阶段会自动做ndc.x gl_Position.x / gl_Position.w; ndc.y gl_Position.y / gl_Position.w; ndc.z gl_Position.z / gl_Position.w;这一行叫做透视除法Perspective Divide。除完以后(ndc.x, ndc.y, ndc.z)一般都落在 [-1,1] 的范围内在视野里的点这些点就落到了所谓的 NDC 空间归一化设备坐标。远处的点z 大w 也会按设计变大导致 x/w、y/w 更接近 0——于是被投影到屏幕中心附近看上去更小近处的点z 小比例更大被投影到屏幕边缘更开阔的位置看起来更大。透视感的本质就体现在这一步/w上。六、Clip Space 到 NDC再到屏幕盒子缩小 → 平铺到屏幕我们已经知道Clip Space(x, y, z, w)透视除法后NDC(x/w, y/w, z/w)。6.1 NDC一个固定 [-1,1] 的标准立方体NDC 中x ∈ [-1, 1]-1 左边界1 右边界y ∈ [-1, 1]-1 下边界OpenGL 或上边界视 API 而定1 上边界或下边界。z ∈ [-1, 1] 或 [0, 1]视 API 而定表示深度最终会映射到深度缓冲里。此时我们的三维世界被统一压到了一个“单位立方体”里。6.2 再从 NDC 到屏幕像素最后一步把 [-1,1] 的立方体投影到实际屏幕的像素坐标系0 ~ width, 0 ~ height。示意公式以左下角为 (0,0) 为例screenX(ndc.x*0.5f0.5f)*ScreenWidth;screenY(ndc.y*0.5f0.5f)*ScreenHeight;如果你的屏幕 y 轴向下则可能是screenY(1.0f-(ndc.y*0.5f0.5f))*ScreenHeight;到这一步我们终于从模型空间点 → 世界空间 → 摄像机空间 → Clip Space → NDC → 屏幕像素一路走到底完成了“从 3D 点到 2D 像素”的整个投影过程。七、GPU 在 Clip Space 里做啥“裁剪”的重点来了名字叫Clip Space“Clip” 就是 “裁剪、截断” 的意思。7.1 裁剪啥很简单裁剪那些“在视野外”的部分——也就是超出标准盒子范围的点和三角形。在 Clip Space或者 NDC里如果一个顶点的坐标在 [-w, w]或 [-1,1]之外说明在视野外GPU 会自动对这些三角形做裁剪完全在外面的直接丢弃一部分在内、一部分在外的会在边界上“切一刀”只保留可见部分。这样就有两个好处后面光栅化阶段就不会为看不到的区域生成片元像素节省大量计算裁剪逻辑在硬件中是高度优化的基于 Clip Space 统一处理。7.2 为什么不在世界空间里裁剪理论上也可以直接在世界空间中用视锥平面来裁剪但那样不同摄像机视野形状不同数学复杂度高硬件实现上难以统一和优化。而 Clip Space / NDC 的好处是已经把“各种各样的视锥体”压成了“统一的标准盒子”所以裁剪就是检查 ±1/±w 的简单范围问题。GPU 的设计就是围绕这个“标准盒子”来的。八、用一个完整的小故事再走一遍一个点的一生我们来给一个 3D 点编一个“人生经历”帮助你把整个流程串成一条线。场景设定模型一辆车模型空间下顶点之一是 LocalPos (1,0,0)这辆车放到世界空间的 (10,0,50)略微旋转了一下摄像机在世界位置 (0,3,0)看向世界 ZFOV 60°近裁剪 0.1远裁剪 100。1. 模型空间LocalLocalPos (1,0,0) 表示在车的模型内部这个顶点是“右侧边上某一点”。2. 世界空间WorldWorldPosModelMatrix*LocalPos;ModelMatrix 根据车的位置 / 旋转 / 缩放生成。得到 WorldPos比如(10.8, 0.2, 50.5)含义在整个游戏世界地图中这个点在 (10.8, 0.2, 50.5)。3. 摄像机空间View / CameraViewPosViewMatrix*WorldPos;ViewMatrix 把世界坐标变到“以摄像机为原点”的坐标系中。假设得到ViewPos (vx, vy, vz)比如 (1.5, -0.3, 20.0)含义从摄像机眼睛看出去这个点在右边 1.5、下面 0.3、前方 20 距离处。4. Clip Space透视投影前ClipPosProjectionMatrix*ViewPos;// 得到 (cx, cy, cz, cw)投影矩阵把视锥体压成“标准盒子”。ClipPos 可能是(30, -6, 19, 20)暂时不要管数值只知道x,y,z,w 内部都编码了“远近位置 视野边界”的信息。5. 透视除法变成 NDCndc.x30/201.5ndc.y-6/20-0.3ndc.z19/200.95明显 ndc.x 1.5 超出 [-1,1]说明这个点或所在三角形的一部分已经在屏幕右侧外面了。根据三角形其他顶点位置GPU 会决定如何裁剪。如果是另外一个点ndc 落在 [-1,1] 内那么就表示在可见范围中。6. 映射到屏幕像素假设 ndc 在 [-1,1] 内再做screenX(ndc.x*0.50.5)*width;screenY(1-(ndc.y*0.50.5))*height;最终得到一个(screenX, screenY)那个像素就是这辆车这个顶点投影到屏幕上的位置。九、工程实践中你实际“看见 / 使用” Clip Space 的地方9.1 顶点着色器里的 gl_Position / SV_Position在 OpenGL / GLSL 中gl_Position Projection * View * Model * vec4(localPos, 1.0);这里的gl_Position就是Clip Space 坐标。在 HLSL / DirectX 中类似float4 clipPos mul(Proj, mul(View, mul(Model, localPos))); return clipPos; // 语义 SV_Position这个返回值被标记为SV_Position就是裁剪空间中的位置。你不需要手写“除以 w”GPU 会在后续针对每个顶点统一做。9.2 手写投影矩阵的情况不常见但有时需要大部分时候你会用引擎 APIUnityMatrix4x4.Perspective(fov, aspect, near, far)DirectXXMMatrixPerspectiveFovLHGLMCglm::perspective(...)但有时候你需要更高级玩法比如自定义投影、非对称视锥就得自己构造 Projection Matrix这时理解 Clip Space 的“标准盒子”就很重要了你要知道你的矩阵最后要把点变成哪种范围的 box才能和 GPU 默认裁剪逻辑对得上。9.3 做反向推导从屏幕坐标 / NDC 反推回世界坐标一些高级效果需要你从屏幕坐标 / 深度信息反推 3D 位置例如屏幕空间反射SSR屏幕空间环境光遮蔽SSAO根据点击屏幕位置射线选中 3D 对象鼠标 picking。这些都需要你把屏幕坐标 → NDC反向 viewport把 NDC → Clip Space乘以 w 或构造一个适当的 clipPosClip → View乘以投影矩阵的逆View → World再乘 View 矩阵的逆。这整个反向链路正是建立在你理解 Clip Space 和 Projection 的基础上。十、最后用几句话把“投影到裁剪空间”压缩在脑子里我们再用特别大白话的方式把这个概念彻底钉牢摄像机空间里有一个“视锥体”就是你能看到那一块 3D 空间。投影矩阵做的事把这个不规整的“视锥体”压扁、拉伸变成一个统一标准的“盒子”Clip Space顺便把透视近大远小、视野角、近平面/远平面这些都编码进去。Clip Space 是变换后的中间状态点用齐次坐标(x,y,z,w)表示还没进行/w的透视除法但已经具备了“用 ±w 来判断是否在视野内”的结构。透视除法除以 w → NDCndc clipPos / clipPos.w这一步实现了近大远小把整个可见空间变成 [-1,1] 的标准立方体NDC。GPU 在 Clip/NDC 空间里做裁剪超出边界的三角形部分被剪掉只留下盒子里面的部分进入光栅化阶段。最后从 NDC 映射到屏幕像素再把 [-1,1] 映射到 [0,width]/[0,height]每个点就成了屏幕上的一个像素位置。如果用一句特别形象的话总结“投影到裁剪空间”就是把你眼前那块立体的视野世界压成一个 GPU 最爱处理的“标准盒子格式”然后再从这个盒子里剪剪剪剩下的部分摊平成屏幕上的一帧画面。以后你再看到gl_Position Projection * View * Model * vec4(localPos, 1.0);就可以在心里翻译成“好现在我要把这个 3D 点一路送到那个标准视锥盒子里去方便 GPU 帮我裁剪、投影、画到屏幕上。”

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询