14.7 OpenGL图元装配和光栅化:早期各片段测试

早期各片段测试 Early Per-Fragment Tests

layout(early_fragment_tests) in;
如果片段着色器指定了 Early_fragment_tests 布局限定符,则将在片段着色器执行之前执行本节中描述的每个片段测试。 否则,它们将在片段着色器执行后执行。

在光栅化阶段生成片段之后,会在片段着色器执行之前对每个片段进行一系列的每片段操作。如果在这些操作中的任何一处片段被丢弃,则该片段将不会被后续任何阶段处理,包括片段着色器的执行。

按照以下顺序,对每个片段执行三个基本的片段操作以及可选的另外三个操作:

  1. 像素所有权测试:确定当前片段是否属于当前视口范围内的有效像素。
  2. 剪裁测试:检查片段是否位于剪裁区域内,即窗口坐标系下的可见区域。
  3. 多采样片段操作:当启用多重采样时,会处理每个片段对应的所有样本点,并根据它们的结果来决定最终片段的颜色和深度值。

若启用了早期每片段操作,还会进行以下测试:

  1. 模板测试:根据模板缓冲区的内容判断片段是否应该被绘制或剔除。
  2. 深度缓冲测试:对比片段的深度值与深度缓冲区中的现有值,以确定片段是否遮挡了已有的片段或者应该被遮挡。
  3. 遮挡查询样本计数:在进行性能分析或优化时,用于统计通过所有测试并可能影响屏幕输出的片段数量。

像素所有权测试 Pixel Ownership Test

第一个测试是确定帧缓冲中位置(xw,yw)处的像素当前是否由GL(更准确地说,由此GL上下文)所拥有。如果不是,则窗口系统决定了传入片段的命运。可能的结果是丢弃片段,或者将一些后续逐片段操作应用于片段的某个子集。此测试允许窗口系统控制GL的行为,例如,当GL窗口被遮挡时。

如果绘制帧缓冲是帧缓冲对象(参见第17.4.1节),则像素所有权测试始终通过,因为帧缓冲对象的像素由GL拥有,而不是窗口系统。如果绘制帧缓冲是默认帧缓冲,则窗口系统控制像素所有权。

剪裁测试 Scissor Test

剪切测试(Scissor Test)是一种图形渲染过程中的功能,它用于判断像素坐标(xw, yw)是否位于每个视口所定义的剪切矩形区域内。在OpenGL等图形API中,通过设置剪切矩形可以限制帧缓冲区中某个指定区域进行绘制或清除操作。

具体来说,剪切矩形由四个值确定:左边界(left)、下边界(bottom)、宽度(width)和高度(height)。这些值可以通过调用相应的API函数如glScissor()来设置,并且针对每个视口都可以独立定义一个剪切矩形。

当光栅化过程中产生的片段(fragment)的窗口坐标(xw, yw)满足以下条件时,该片段通过剪切测试:

  • 左边界小于等于xw并且xw小于左边界加上宽度,即 left ≤ xw < left + width
  • 下边界小于等于yw并且yw小于下边界加上高度,即 bottom ≤ yw < bottom + height

若片段坐标不在剪切矩形范围内,则该片段将被丢弃,不会进行后续的绘制操作。这对于限制渲染到屏幕特定区域、优化性能以及实现一些特殊效果非常有用。

void glScissorArrayv( uint first, sizei count, const int *v );
void glScissorIndexed( uint index, int left, int bottom, sizei width, sizei height );
void glScissorIndexedv( uint index, int *v );
void glScissor( int left, int bottom, sizei width, sizei height );glEnable(GL_SCISSOR_TEST);
glDisable(GL_SCISSOR_TEST);void glEnablei( enum target, uint index );
void glDisablei( enum target, uint index );
boolean glIsEnabledi( enum target, uint index );
设置一组裁剪矩形,每个矩形应用于相应的视口
void glScissorArrayv( uint first, sizei count, const int *v );
  • first:要修改的第一个裁剪矩形的索引。
  • count:裁剪矩形的数量。
  • v:一个整数数组的地址,依次包含裁剪矩形的左边、底部、宽度和高度。
int scissors[8] = { 0,    0,  300, 200,  // 视口 0 的 左下宽高350, 50,  200, 200   // 视口 1 的 左下宽高
};
glScissorArrayv(0, 2, scissors); // 使用ScissorArrayv设置剪切矩形
glEnable(GL_SCISSOR_TEST); // 确保剪切测试已启用// 对于第一个视口,其剪切矩形范围是[  0,  0]到[300, 200];
// 对于第二个视口,其剪切矩形范围是[350, 50]到[550, 250]。
void glScissorIndexed( uint index, int left, int bottom, sizei width, sizei height );// 等价于int v[] = { lef t, bottom, width, height };
glScissorArrayv(index, 1, v);
void glScissor( int left, int bottom, sizei width, sizei height );// 等价于for (uint i = 0; i < MAX_VIEWPORTS; i++) {glScissorIndexed(i, left, bottom, width, height);
}
void glScissorIndexedv( uint index, int *v );// 等价于glScissorArrayv(index, 1, v);
// 启用或禁用所有视口的剪切测试
glEnable(GL_SCISSOR_TEST);
glDisable(GL_SCISSOR_TEST);// 针对单个视口独立启用或禁用剪切测试
glEnablei(GL_SCISSOR_TEST, viewportIndex); // 启用指定视口的剪切测试
glDisablei(GL_SCISSOR_TEST, viewportIndex); // 禁用指定视口的剪切测试// 查询特定视口的剪切测试状态
GLboolean isEnabled = glIsEnabledi(GL_SCISSOR_TEST, viewportIndex);// 如果要查询默认视口(即索引为0的视口)的剪切测试状态
GLboolean isEnabledDefaultViewport = glIsEnabled(GL_SCISSOR_TEST);

多采样片段操作 Multisample Fragment Operations

在OpenGL或其他类似的图形渲染管线中,片段覆盖(fragment coverage)的修改步骤是一个关键阶段,它涉及到多个状态变量,包括SAMPLE_COVERAGE、SAMPLE_COVERAGE_VALUE、SAMPLE_COVERAGE_INVERT、SAMPLE_MASK和SAMPLE_MASK_VALUE。这一过程发生在多采样(MULTISAMPLE)功能启用且SAMPLE_BUFFERS值为1的情况下。

首先,片段着色器输出的alpha值仅针对颜色编号0、索引0的组件,并且若着色器未写入该alpha值,则其为未定义。

样本覆盖率相关的操作可以通过Enable和Disable函数控制,对应的目标分别为SAMPLE_COVERAGE和SAMPLE_MASK。当SAMPLE_COVERAGE启用时,会根据SAMPLE_COVERAGE_VALUE生成一个临时覆盖掩码,并与当前片段覆盖进行逻辑AND运算。如果SAMPLE_COVERAGE_INVERT设为TRUE,还会先对这个临时掩码进行反转操作。

进一步,如果SAMPLE_MASK也被启用,片段覆盖还需与SAMPLE_MASK_VALUE做AND运算以更新最终的片段覆盖值。

SAMPLE_COVERAGE_VALUE和是否反转的设置通过SampleCoverage函数完成,其中value参数代表覆盖率数值,invert参数指示是否翻转掩码。而SAMPLE_MASK_VALUE则由SampleMaski函数设定,该函数允许指定特定掩码字中的位掩码。

这些值的转换算法不强制具体实现方式,但通常期望保证一定比例关系和伪随机性,以避免图像出现因采样位置规律性导致的瑕疵。查询上述状态变量的具体值,可以使用相应的查询函数。

void glSampleCoverage( float value, boolean invert );
  • value参数是样本覆盖率的数值(SAMPLE_COVERAGE_VALUE)。它被限制在区间 [0, 1] 内,表示覆盖的样本比例。如果所有的样本都覆盖,value应为1.0;如果没有样本覆盖,value应为0.0。
  • invert参数是否反转样本覆盖率(SAMPLE_COVERAGE_INVERT)。如果设置为true,则覆盖率会被反转。
void glSampleMaski( uint maskNumber, bitfield mask );
  • maskNumber:表示要修改的掩码编号,因为在OpenGL 4.2及更高版本中,可以针对不同的视口或者同一视口中不同的掩码单元进行独立设置。

  • mask:这是一个位域值,每一位对应于一个子样本,如果该位为1,则相应的子样本会被启用;如果为0,则对应的子样本被禁用。掩码长度应与当前激活帧缓冲区的样本数量相匹配。

早期片段测试限定符 The Early Fragment Test Qualifier

在OpenGL等图形渲染管线中,模板测试(stencil test)、深度缓冲区测试(depth buffer test)和遮挡查询样本计数(occlusion query sample counting)的操作执行时机取决于当前激活的片段着色器是否启用了早期片段测试功能(参见第15.2.4节)。当开启早期每个片段操作时,这些测试将在片段着色器执行前进行,并根据测试结果相应地更新模板缓冲区、深度缓冲区的内容以及遮挡查询的样本计数。一旦片段着色器执行完毕后,将不再重复执行这些操作。

如果当前没有活动程序,或者活动程序中没有片段着色器,或者程序链接时关闭了早期片段测试,那么这些操作会在片段着色器执行之后按第17.3节描述的顺序执行。

另外,如果开启了早期片段测试,片段着色器计算出的深度值将不会对最终深度判断产生影响。同时要注意的是,即使片段或样本由于后期片段操作(例如alpha-to-coverage测试)导致被丢弃,它们仍然可能会更新模板缓冲区、深度缓冲区的数据以及遮挡查询的样本计数。这意味着,在决定是否绘制某个像素之前,可能会先完成某些相关的缓冲区更新和统计计算。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/681048.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自动化测试工具

自动化测试工具有很多种&#xff0c;比如&#xff1a; Appium 。Appium是一个移动端自动化测试开源工具&#xff0c;支持iOS和Android平台&#xff0c;支持Python、Java等语言&#xff0c;即同一套Java或Python脚本可以同时运行在iOS和Android平台。 Appium是一个开源测试自动…

8个Python编程进阶常用技巧!

前言 介绍 Python 炫酷功能&#xff08;例如&#xff0c;变量解包&#xff0c;偏函数&#xff0c;枚举可迭代对象等&#xff09;的文章层出不穷。但是还有很多 Python 的编程小技巧鲜被提及。因此&#xff0c;本文会试着介绍一些其它文章没有提到的小技巧&#xff0c;这些小技…

多态

多态的基本语法 多态分为两类 静态多态: 函数重载 和 运算符重载属于静态多态&#xff0c;复用函数名动态多态: 派生类和虚函数实现运行时多态 静态多态和动态多态区别&#xff1a; 静态多态的函数地址早绑定 - 编译阶段确定函数地址动态多态的函数地址晚绑定 - 运行阶段确…

中科大计网学习记录笔记(十):P2P 应用

前言&#xff1a; 学习视频&#xff1a;中科大郑烇、杨坚全套《计算机网络&#xff08;自顶向下方法 第7版&#xff0c;James F.Kurose&#xff0c;Keith W.Ross&#xff09;》课程 该视频是B站非常著名的计网学习视频&#xff0c;但相信很多朋友和我一样在听完前面的部分发现信…

Centos7离线安装MySQL5.7

卸载mariadb rpm -e --nodeps mariadb-libs可以使用rpm -qa|grep mariadb命令检测是否卸载完成。 关闭selinux 将/etc/selinux/config文件中的SELINUX设置为disabled下载MySql的相关rpm包 打开https://dev.mysql.com/downloads/mysql/ 选择Red Hat Enterprise Linux / Oracle L…

Linux 终端入门

简介 这个教程是 Linux 基础知识系列中的第一篇&#xff0c;涵盖了如何开始使用终端、Linux 命令行以及执行命令。如果你是 Linux 新手&#xff0c;你需要熟悉终端&#xff0c;因为它是与 Linux 服务器交互的标准方式。 这个教程是针对 Ubuntu 22.04 服务器编写的&#xff0c…

离散数学截图

二元运算及其性质 二元运算中的特殊元 半群和独异点 代数系统的同态与同构 下确界是最大的下界&#xff0c;而在4、5、6三个下界里面&#xff0c;4和5都比6大。可4和5之间没办法分出大小&#xff0c;所以这个哈斯图没有下确界

操作系统面试问题——说一下什么是零拷贝?

零拷贝是一种IO操作优化技术&#xff0c;主要用于减少CPU在用户态和内核态之间的上下文切换次数以及减少数据拷贝次数&#xff0c;可以显著提高数据传输的效率。 传统的拷贝方式需要频繁的切换状态&#xff0c;读数据时需要将数据从硬盘加载到内核缓冲区&#xff0c;再从内核缓…

Git、github与gitee码云

1.git核心是两个仓库&#xff1a;本地仓库和远程仓库 主要用于团队合作和代码版本控制&#xff08;个人现有版本代码出错可回溯上个提交版本的代码&#xff09; 远程仓库国际主流githut&#xff0c;但外网速度问题&#xff0c;国内可使用码云gitee github&#xff1a;https:…

Ping的过程详解

Ping是一种常用的网络工具&#xff0c;用于测试与目标主机之间的网络连接和延迟。下面是Ping的基本过程&#xff1a; 发送ICMP Echo请求&#xff1a; 发起Ping操作的主机&#xff08;通常是客户端&#xff09;会构建一个ICMP Echo请求报文&#xff0c;将其发送给目标主机&…

腾讯云4核8G12M轻量应用服务器性能够用吗?支持多少人?

腾讯云轻量4核8G12M轻量应用服务器支持多少人同时在线&#xff1f;通用型-4核8G-180G-2000G&#xff0c;2000GB月流量&#xff0c;系统盘为180GB SSD盘&#xff0c;12M公网带宽&#xff0c;下载速度峰值为1536KB/s&#xff0c;即1.5M/秒&#xff0c;假设网站内页平均大小为60KB…

备战蓝桥杯---组合数学2

本专题主要介绍容斥原理。 大家高中的时候肯定接触过韦恩图&#xff0c;容斥原理比较通俗的理解就是减去所有可能并加上重叠的部分。 我们直接看公式&#xff1a; 知道后&#xff0c;我们先看道模板题&#xff1a; 下面是AC代码&#xff1a; #include<bits/stdc.h> us…

VMware虚拟机安装openEuler系统(二)(2024)

下面我们进行openEuler系统的一些简单配置。 1. 开启openEuler系统 在VMware Workstation Pro虚拟机软件中找到安装好的openEuler操作系统虚拟机并开启。 等待开启。 2. 安装配置 进入后选择第一个“Install openEuler 20.03-LTS”。 3. 选择系统语言 为虚拟机设置系统语言…

分享94个jQuery特效,总有一款适合您

分享94个jQuery特效&#xff0c;总有一款适合您 94个jQuery特效下载链接&#xff1a;https://pan.baidu.com/s/19AsyTWJUPcCX9DN3am53Sg?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整理…

秋招上岸大厂,分享一下经验

文章目录 秋招过程学习过程项目经验简历经验面试经验offer选择总结 秋招过程 今天是除夕&#xff0c;秋招已经正式结束了&#xff0c;等春节过完就到了春招的时间点了。 运气比较好&#xff0c;能在秋招的末尾进入一家大厂&#xff0c;拿到20k的sp offer。 从九月份十月份就开…

大文件上传如何做断点续传?

文章目录 一、是什么分片上传断点续传 二、实现思路三、使用场景小结 参考文献 一、是什么 不管怎样简单的需求&#xff0c;在量级达到一定层次时&#xff0c;都会变得异常复杂 文件上传简单&#xff0c;文件变大就复杂 上传大文件时&#xff0c;以下几个变量会影响我们的用…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之ImageAnimator组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之ImageAnimator组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、ImageAnimator组件 提供分隔器组件&#xff0c;分隔不同内容块/内容元素…

JAVA-数组查找元素

无序数组查找元素 循环遍历查找 通过对无序数组进行遍历&#xff0c;将数组中的每个元素与指定元素比较&#xff0c;从而确定该数组中是否存在指定元素。 字符串数组 public static void main(String[] args) {String[] arr {"Megatron","s司马铁锤",&q…

HiveSQL——设计一张最近180天的注册、活跃留存表

0 问题描述 现有一个用户活跃表user_active(user_id,active_date)、 用户注册表user_regist(user_id,regist_date)&#xff0c;表中分区字段都为dt(yyyy-MM-dd)&#xff0c;用户字段均为user_id; 设计一张 1-180天的注册活跃留存表&#xff1b;表结构如下&#xff1a; 1 数据分…

ctfshow-php特性(web102-web115)

目录 web102 web103 web104 web105 web106 web107 web108 web109 web110 web111 web112 web113 web114 web115 实践是检验真理的 要多多尝试 web102 <?php highlight_file(__FILE__); $v1$_POST[V1]; $v2$_GET[v2]; $v3$_GET[v3]; $v4is_numeric($v2)and is…