OpenGL教程翻译 第九课 插值

本教程探讨了OpenGL渲染管线中的插值概念,解释了光栅器如何在顶点着色器输出的变量之间进行插值,特别是在三角形内进行颜色和纹理坐标的插值。插值用于计算每个像素的特定法线和纹理坐标,以实现更真实的光照和纹理覆盖效果。代码示例展示了如何在顶点着色器中设置颜色,并在片元着色器中进行插值处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

OpenGL教程翻译 第九课 插值

原文地址:http://ogldev.atspace.co.uk/(源码请从原文主页下载)

Background

本章讲述三维渲染管线中的一个非常重要的部分——插值,它是光栅器对从顶点着色器输出的变量所做的操作。正如你已经看到的,为了在屏幕上得到一些有意义的东西,你需要指定VS输出变量中的一个为“gl_Position”。这是一个四维向量,含有顶点的其次坐标。这个变量中的XYZ分量被除以其W分量(这是一个透视分割的过程,后面的教程会另对其进行详细说明)并且任何超出规范边框(XY介于【-1,1】间;Z介于【0,1】之间)的成分都将被减掉。其结果会被转换到屏幕空间坐标,然后光栅器将此三角形(或任何受支持的图元类型)渲染到屏幕上。

光栅器在三角形的三个顶点之间执行插值(沿着线或者其他技术),并且通过执行片元着色器来“访问”三角形内的每一个像素点。片元着色器会返回此片元的颜色值,光栅器将将这个颜色值放置于颜色缓冲区内并最终显示出来(在通过一些其他测试例如深度测试之后),而来自顶点着色器的其他任何变量都不经历上述步骤。如果片元着色器没有明确的表示要使用那个变量(你可以用相同的顶点着色器混合并匹配多个片元着色器),那么一个共同的驱动优化将丢弃VS中的任何只影响该变量的指令(为那个特定的结合此VS和FS为一对的着色器程序)。然而如果FS确实用到这个变量,那么光栅器在光栅化过程对其进行插值。这通常意味着紧挨着的两个像素点的值彼此之间会有一点差异(尽管三角形离相机越来越元这种现象变得更不大可能)。

常见的两个依赖于这种插值的变量是三角形法线和纹理坐标。顶点法线的值通常通过计算包含此顶点的所有三角形的法线的平均值来得到。如果该对象不是平面的,这通常意味着这三个三角形的的共同顶点的顶点法线将彼此不同。在这种情况下我们依靠插值来计算每一个像素的特定法线。这个特定法线用于光照计算中使用,为的是使得光照效果更加逼真。纹理坐标插值与此类似。这些坐标是模型的一部分,被指定于每个顶点。为了用纹理“覆盖”三角形,你需要对每一个像素点做同样的处理,并为其指定正确的纹理坐标。这些坐标是插值的结果。

本章中我们将会看到对三角形表面的不同颜色进行差值得到的效果。因为鄙人较懒,我们就在VS中得到颜色吧。还有一个更加乏味的方法:让顶点缓冲器提供颜色。通常你不从顶点缓冲器获取颜色。你提供纹理坐标并从中采样。而颜色则会在之后的光照计算中进行处理


Code Walkthru

out vec4 Color;

参数在渲染管线之间传递时必须用“out”关键字进行声明,并且必须是着色器中的全局变量。颜色是一个4-vector,因为XYZ分量(分别)携带RGB值,而W是alpha值(像素的透明度)。

 

Color = vec4(clamp(Position, 0.0, 1.0), 1.0);

在渲染管线中的颜色通常用一个在【0.0,1.0】范围内的浮点值。对于每一个颜色通道(共计有16M颜色),这个值之后都被映射到从0到255之间的整数作为一个颜色的颜色通道。我们通过一个关于顶点位置的函数来为片元设置颜色。首先我们用内置的clamp()函数来确保这些值不会跑出0.0-1.0的范围。原因是三角形左下方的顶点位于-1,-1.如果我们不进行clamp()转换,那么这个值就会被光栅化程序插值,并且在X和Y取值达到0之前我们将什么都看不见,因为每一个小于或等于0的值都会被渲染为黑色。这意味着每个方向的边的一半,在颜色通过0点而变得有意义之前,将会是黑色。通过clamping,我们使仅三角形左下角的顶点为黑色,而离它越远的地方颜色很快变得越来越亮。试着玩一玩clamp函数——将他全部删除或者改变其参数查看效果。

Clamp函数的结果不直接作为输出变量,因为输出变量是一个四维向量而位置是一个三维向量(clamp不会改变分量的个数,只改变他们的值)。从GLSL的观点看这里没有默认的转换,对此我们必须清楚明白。因而我们使用“vec4(vec3,W)”,它通过将三维向量和用户提供的W值来创建一个四维向量。本例中我们使用1.0,因为它作为颜色的alpha部分,而且我们想要像素点是完全不透明的。

 

in vec4 Color;

VS的输出颜色是FS的输入颜色。这个变量通过光栅化程序进行插值,所以每一个FS(可能)会获得不同的颜色。

FragColor = Color;

我们用经过插值的颜色直接作为片元着色器的颜色而没有进一步的改变,本章到此结束。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值