目 录CONTENT

文章目录

04_✔️几何处理阶段_00_图元装配_剪裁_透视除法与NDC坐标_视口变换_剔除

hananww
2026-09-19 / 0 评论 / 0 点赞 / 0 阅读 / 0 字
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。
flowchart LR classDef importentNode fill:#f7630c,stroke:#999,stroke-width:1px,color:#eff1f5; subgraph A[几何处理] direction TD A1[输入装配] A2[顶点着色器] A4[<图元装配><br>顶点组成:点线,三角形] A5[剪裁]:::importentNode A6[<透视除法><br>也就是:xyz ÷ w 得到 NDC ] A7[<视口变换><br>将 NDC 坐标映射到屏幕] A8[正反面判定与剔除]:::importentNode end subgraph A3[可选阶段] direction TD A3_1[几何着色器] A3_2[曲面细分] A3_3[流式输出] end A1-->A2-->A3-->A4-->A5-->A6-->A7-->A8 A2-->|可以不选|A4

图元装配_剪裁_透视除法与NDC坐标_视口变换_剔除

flowchart LR classDef importentNode fill:#f7630c,stroke:#999,stroke-width:1px,color:#eff1f5; classDef note fill:#16c60c,stroke:#999,stroke-width:1px,color:#eff1f5; subgraph A[剪裁与剔除] direction LR A1[图元装配] A2[裁剪]:::importentNode A3[透视除法] A4[视口变换] A5[正反面判定与剔除]:::importentNode A6[/输出/] end A1-->A2-->A3-->A4-->A5-->A6

🟠剪裁

  • 剪裁就是沿着视锥的边界,把三角形露在视野外的部分切掉,在边界上插入新顶点,只保留视野里的部分

  • 剪裁在 剪裁空间里干活,判断顶点着色器输出的剪裁空间的顶点坐标,是否在视锥内。

    • 一个顶点在视锥内的判断规则:
      • -w ≤ x ≤ w
      • -w ≤ y ≤ w
      • -w ≤ z ≤ w
    • 正好对应视锥的 6 个面:左、右、上、下、近、远,共 6 个边界。
  • 剪裁输入输出

    • 剪裁接收图元装配阶段的完整图元,每个顶点都带有顶点着色器输出的全部属性:顶点剪裁空间位置(x,y,z,w)、法线、颜色、UV等。

🟠剔除(这里一般说的是背面剔除)

  • 封闭物体的背面,从摄像机方向永远看不见,那干脆就不画了。它可以手动切换剔除模式。
  1. 做三角形的正反面判定
    • 对每一个三角形,用 NDC 空间的三个顶点,计算环绕顺序,判断是正面还是背面在 NDC 里看是逆时针(CCW)→ 正面,是顺时针(CW)→ 背面。

[!note] 我们可以在 图形 api 中配置是逆时针顶点顺序决定三角形正面还是顺时针决定正面。

`IsFrontFaceCCW`:CCW = 逆时针为正面;CW = 顺时针为正面
  1. 剔除 指定的面
    • 是 GPU 几何处理阶段的固定步骤
    • 每个三角形都有正反面,由顶点顺序决定正反。
    • 不渲染三角形的背面,比如一个封闭的物体,相机正常来讲都看不到里边的面。
    • 他可以节省一半的性能。游戏引擎一般会默认开启

[!note] cocos 中的背面剔除

  • 在cocos 材质属性面板中 可以更改pipeline state 中的cull mode 来决定使用什么 背面剔除模式
  • 剔除模式 效果 使用场景
    BACK 默认值,剔除背面,只渲染正面 绝大多数封闭的 3D 物体(立方体、角色、建筑等),性能最好
    FRONT 剔除正面,只渲染背面 用来做 “从物体内部看” 的特殊效果、比如天空球
    NONE 不剔除,正反面都渲染 薄物体(树叶、纸张、布料)、透明面片、需要双面显示的物体

[!error] cocos 中,阴影投射 pass2 : Shadow-caster 也默认开启了背面剔除模式。会导致单面不封闭模型投射出来的阴影缺失


🟢透视除法_NDC坐标_视口变换

裁剪空间:四维,边界随 w 改变
        ↓ xyz / w
NDC:三维,统一落在规范立方体内
        ↓ 视口变换
屏幕/窗口坐标:以像素计
flowchart LR classDef importentNode fill:#f7630c,stroke:#999,stroke-width:1px,color:#eff1f5; classDef note fill:#16c60c,stroke:#999,stroke-width:1px,color:#eff1f5; subgraph A[透视除法_NDC坐标_视口变换] direction LR A1[< 裁剪空间 ><br>四维,边界随 w 改变] A2[< NDC空间 ><br>三维,落在规范立方体内] A3[< 屏幕空间 ><br>二维,以像素计算] end A1-->|透视除法|A2-->|视口变换|A3

透视除法

  • 透视除法 = 把裁剪空间的 x、y、z 全都除以 w
    • 除以 w 之后,远处物体坐标被压缩,自动实现近大远小的透视效果。也就是自动实现了透视相机的效果
    • 如果想要正交相机的效果,w=1 除以 w 坐标不变就能实现

NDC 坐标空间

NDC 是一个正方形立方体(归一化盒子)
在NDC空间中的所有可见顶点坐标都会被归一化: x ∈ [-1, 1]y ∈ [-1, 1]z ∈ [-1,1]

视口变换

  • 下面是视口变换的公式
    • ​screen_x=(x_{ndc}+1)\times0.5\times viewportWidth+viewportX
    • ​screen_y=(y_{ndc}+1)\times0.5\times viewportHeight+viewportY
screenX = (ndc.x + 1) * 0.5 * viewportWidth + viewportX
screenY = (ndc.y + 1) * 0.5 * viewportHeight + viewportY

+ viewportX 是为了把“视口内部坐标”平移到“整个渲染目标中的实际位置”。

0

评论区