欢迎光临
我们一直在努力

Drawing a triangle -- Graphics pipeline basics -- Introduction

引言

在接下来的几个章节中,我们将搭建一个图形管线(graphics pipeline),用于绘制我们的第一个三角形。图形管线是一系列操作的集合,它能将网格的顶点(vertices)和纹理(textures)最终转化为渲染目标(render targets)中的像素(pixels)。以下是简化的概述:

图形管线各阶段说明

  • 输入装配器(Input Assembler):从你指定的缓冲区(buffers)中收集原始顶点数据,还可使用索引缓冲区(index buffer)重复某些元素,无需重复存储顶点数据本身。
  • 顶点着色器(Vertex Shader):对每个顶点执行一次,通常用于执行变换操作,将顶点位置从模型空间(model space)转换到屏幕空间(screen space),同时将逐顶点数据(per-vertex data)向下传递到管线的后续阶段。
  • 曲面细分着色器(Tessellation Shaders):允许根据特定规则细分几何图形(geometry),以提高网格质量。这常用于使砖墙、楼梯等表面在靠近观察时显得不那么平坦。
  • 几何着色器(Geometry Shader):对每个图元(primitive,如三角形、线段、点)执行一次,可丢弃图元或输出比输入更多的图元。它与曲面细分着色器类似,但灵活性更高。然而,如今的应用程序中很少使用它,因为除了英特尔的集成显卡(integrated GPUs)外,大多数显卡上的性能表现并不理想。此外,几乎所有几何着色器的使用场景都可以通过更现代的网格着色器管线(Mesh shader pipeline)来替代 —— 该管线与光线追踪(ray tracing)类似,是一种全新的管线解决方案,因此独立于标准图形管线设置之外。我们将在后续的教程章节中讨论该管线。
  • 光栅化阶段(Rasterization Stage):将图元分解为片元(fragments),这些片元是它们在帧缓冲区(framebuffer)上覆盖的像素元素。任何超出屏幕范围的片元都会被丢弃,顶点着色器输出的属性会在片元上进行插值(interpolated),如图所示。通常,由于深度测试(depth testing),位于其他图元片元后方的片元也会在此被丢弃。
  • 片元着色器(Fragment Shader):对每个存活的片元调用一次,决定片元写入哪些帧缓冲区以及对应的颜色和深度值。它可以利用顶点着色器传递的插值数据(包括纹理坐标、用于光照计算的法向量等)来实现这一功能。
  • 颜色混合阶段(Color Blending Stage):对映射到帧缓冲区中同一像素的不同片元执行混合操作。片元可以直接覆盖彼此、累加,或根据透明度(transparency)进行混合。
  • 管线阶段类型

    • 绿色标记的阶段为固定功能阶段(fixed-function stages):这些阶段允许你通过参数调整其操作,但工作方式是预定义的。
    • 橙色标记的阶段为可编程阶段(programmable):你可以将自定义代码上传到显卡,以执行完全符合需求的操作。例如,利用片元着色器,你可以实现从纹理映射(texturing)、光照(lighting)到光线追踪(ray tracers)等各类功能。这些程序在多个 GPU 核心上并行运行,同时处理大量对象(如顶点和片元)。

    如果你之前使用过 OpenGL、Direct3D 等较旧的 API,可能习惯通过glBlendFunc、OMSetBlendState等调用随意修改管线设置。但 Vulkan 中的图形管线几乎是完全不可变的(immutable),因此如果需要更换着色器(shaders)、绑定不同的帧缓冲区或修改混合函数(blend function),必须重新创建整个管线。其缺点是你需要创建多个管线,以覆盖渲染操作中可能用到的所有状态组合。但优势在于,由于管线中所有操作都是预先确定的,驱动程序(driver)可以进行更充分的优化。

    部分可编程阶段是可选的,具体取决于你的使用场景。例如,若仅绘制简单几何图形,可禁用曲面细分着色器和几何着色器;若仅关注深度值(depth values),可禁用片元着色器 —— 这在阴影贴图生成(shadow map generation)中非常实用。

    在下一章节中,我们将首先创建在屏幕上绘制三角形所需的两个可编程阶段:顶点着色器和片元着色器。混合模式(blending mode)、视口(viewport)、光栅化等固定功能配置将在后续章节中设置。Vulkan 图形管线搭建的最后一步是指定输入和输出帧缓冲区。

    代码实现

    创建一个createGraphicsPipeline函数,并在initVulkan函数中的createImageViews调用之后执行。后续章节将逐步完善该函数的实现。

    void initVulkan() {
    createInstance();
    setupDebugMessenger();
    createSurface();
    pickPhysicalDevice();
    createLogicalDevice();
    createSwapChain();
    createImageViews();
    createGraphicsPipeline();
    }

    void createGraphicsPipeline() {

    }

    下一章节将介绍在屏幕上实际渲染内容所需的着色器模块(shader modules)。

    赞(0)
    未经允许不得转载:171主机测评 » Drawing a triangle -- Graphics pipeline basics -- Introduction
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址