目 录CONTENT

文章目录

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

hananww
2026-09-19 / 0 评论 / 0 点赞 / 48 阅读 / 0 字
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。
%%{init: { "look": "classic", "theme": "base", "fontSize": 13, "flowchart": { "curve": "linear", "nodeSpacing": 16, "rankSpacing": 26, "useMaxWidth": true }, "themeVariables": { "primaryColor": "#f0f6ff", "primaryBorderColor": "#3664a8" } }}%% flowchart LR classDef importentNode fill:#e81224,stroke:#999,stroke-width:1px,color:#eff1f5; IA[ < 输入装配 > <br/>固定功能,可配置,读出顶点数据输出有序的顶点流] VS[顶点着色器<br/>可编程] IA --> VS subgraph CC[曲面细分,可选] direction TD HS[< 曲面细分控制器 > <br/>这块面要细分到多密 ,可编程] TS[< 细分器 > <br/>自动切割机-生成点,固定功能] DS[< 曲面细分评估着色器 > <br/>算出它真实的 3D 位置,可编程] end HS--> TS--> DS GS[几何着色器<br/>可选,可编程] VS --> CC --> GS VS -.可捕获.-> SO[流式输出 / Transform Feedback<br/>可选,写入 Buffer] GS -.可捕获.-> SO subgraph R[光栅器功能] direction TD A3_1[<图元装配><br>顶点组成:点线,三角形] A3_2[剪裁]:::importentNode A3_3[<透视除法><br>也就是:xyz ÷ w 得到 NDC] A3_4[<视口变换><br>将 NDC 坐标映射到屏幕] A3_5{正反面判定/剔除}:::importentNode end A3_1-->A3_2-->A3_3-->A3_4-->A3_5 GS --> R VS --> R R --> Ra[光栅化]

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

flowchart LR classDef importentNode fill:#e81224,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)→ 背面。
我们可以在 图形 api 中配置是逆时针顶点顺序决定三角形正面还是顺时针决定正面。
`IsFrontFaceCCW`:CCW = 逆时针为正面;CW = 顺时针为正面
  1. 剔除 指定的面
    • 是 GPU 几何处理阶段的固定步骤
    • 每个三角形都有正反面,由顶点顺序决定正反。
    • 不渲染三角形的背面,比如一个封闭的物体,相机正常来讲都看不到里边的面。
    • 他可以节省一半的性能。游戏引擎一般会默认开启
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

评论区