glScissor的目的是什么?


32

我知道它比模板测试更有效,但我是否正确地假设使用带有视口的投影转换可以实现相同的功能?

Answers:


46

它们比其他选择更具互补性。您几乎总是希望将剪刀矩形设置为与视口相同的值。

glViewport()指定从标准化投影空间到屏幕空间的转换。多边形被裁剪​​到投影空间的边缘,但是其他绘制操作(例如glClear())却没有。因此,您可以使用glViewport()确定屏幕空间视口区域的位置和大小,但是光栅化器仍然偶尔可以在该区域之外渲染像素。

这就是剪刀的所在。glScissor()定义了一个屏幕空间矩形,超出该矩形则什么也没画(如果启用了剪刀测试)。

因此,例如,即使视口设置为较大窗口的一小部分,以下代码也将清除整个屏幕:

glViewport(200,200,100,100);
glClear(GL_COLOR_BUFFER_BIT);

添加glScissor()并启用剪刀测试(默认情况下处于禁用状态)会限制清除。

glViewport(200,200,100,100);
glScissor(200,200,100,100);
glEnable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT);

有时,您会遇到一个自动裁剪到视口区域但违反GL规范的实现。

除此之外,剪刀矩形还可以用于临时将图形限制为视口的子矩形,以实现特殊效果,UI元素等。


11
更清楚地说,Viewport修剪顶点计算。如果您绘制的线宽大于1的线或点的线宽大于1的线,gl_PointSize也会在视口之外绘制。
gman 2014年

13

它们在图形管线的两个完全不同的部分运行。

glViewport实际上指定了一个转换,它是在顶点着色器之后但在片段着色器之前发生的转换。如果有助于查看其概念上适合的位置,请考虑将其视为用于将顶点数据从世界空间转换为屏幕空间的转换的一部分(即,它与模型视图和投影相对紧密相关)。

剪刀测试在片段着色器之后以及当时发生的所有其他每片段操作(例如混合,深度/模板等)之后进行。当片段通过剪刀测试进行测试时,因此已经通过视口转换。

是的,剪刀测试可以更快地完成模板,因为它是基于片段的屏幕空间坐标的简单接受/拒绝,而模板需要与模板缓冲区中的当前值进行比较,可能会增加或减少当前值,也要考虑到深度测试的结果,等等。

因此,将所有这些放在一起,您可以了解为什么存在剪刀式测试。它使您能够将每个片段的操作限制在屏幕的矩形部分,而无需实际修改当前的视口变换。


6

我喜欢这种视觉上解释的东西。

在OnpenGL中,对于X和Y轴,我们都有从-1到+1的2D坐标。

在此处输入图片说明

然后,需要将此图像映射到窗口坐标。

假设我们有一个深色背景的窗口,而白色是透明的窗口。

最常见的情况是视口和剪刀覆盖整个屏幕。

在此处输入图片说明

但是我们可以将它们设置为屏幕的较小区域。

在此处输入图片说明

这些区域可以不同。在以下示例中,视口覆盖了整个屏幕,而剪刀是较小的框。

在此处输入图片说明

在最后一种情况下,剪刀覆盖整个屏幕,而视口是较小的框。注意这glClear会影响整个屏幕,因为那是由剪刀区域决定的。

在此处输入图片说明


1
这对我来说是最清晰的解释,它确实需要图纸。
Laurent Caillette

5

glScissors可以在屏幕的一部分上剪切几何图形。

例如,如果要渲染一个GUI框,其中的文本平滑滚动,则可能需要这样做。您想将所有几何图形剪切到GUI覆盖的屏幕部分之外,但保留仍在其中的部分文本或多边形。

glViewport将投影坐标映射到设备坐标,但不进行裁剪。

glStencil用于以更复杂的图案(例如不规则形状)遮盖各个像素。因此,glScissors更快。


1

glScissor比带视口的投影转换更简单。

glScissor测试指定渲染时要更改的像素,而glViewport更改gl应该如何从设备坐标映射到窗口坐标。

然后,将视口设置为要渲染到的矩形并调整投影矩阵以撤消视口所做的缩放比例有什么区别。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.