当前位置: 首页 > 知识库问答 >
问题:

OpenGL着色器-Gouraud和Phong着色中的法线?

谭修然
2023-03-14

我似乎无法理解从顶点到像素的OpenGL管道过程

有人能告诉我顶点法线在这两种着色技术中有多重要吗?据我所知,在gouraud中,在每个顶点计算照明,然后在顶点之间的多边形上插值结果颜色(在光栅化之前,这是在片段操作中完成的吗?),phong着色包括首先插值顶点法线,然后计算每个法线上的照明。

另一件事是,当凹凸贴图应用于一个平面(2个三角形)和一个砖纹理作为漫反射时,使用其相应的凹凸贴图,所有这些都使用gouraud着色。凹凸贴图包括根据凹凸贴图通过渐变改变法线。但它会在何时(在片段着色器处)改变什么法线如果只有4条法线(4个顶点=平面),且所有4条法线都相同。在Gouraud中,在照明计算后插值每个顶点的颜色,但此计算是在更改法线后完成的。

灯光是如何工作的?

共有3个答案

詹斌蔚
2023-03-14

首先,编写一个简单的着色器不需要了解整个图形管道:)。但是,当然,你应该知道发生了什么。你可以阅读《实时渲染》(real-time rendering,第三版)中的图形管道章节(möller,hofmann,akenine moller)。你所描述的是逐顶点和逐片段照明。对于这两种计算,顶点法线都是方程的一部分。对于凹凸贴图着色器,可以更改插值法线。所以在光栅化之后,你会有一些片段,其中缺失的数据必须被计算出来,以确定最终的像素颜色。

乐欣可
2023-03-14

法线贴图是模拟凹凸曲面的技术之一,它基本上会在计算像素上的光方程之前扰动每像素法线。

例如,一种实现方法需要插值曲面法线和副法线(2个切线空间基),并计算每像素的第三个(2个1向量,它们是切线基)。这种技术还需要对光矢量进行插值。有了这3个(2 1计算)向量(命名为tagent space basis),你就有了一种将光向量从对象空间更改为tagent空间的方法。这是因为这3个矢量可以被排列成3x3矩阵,可以用来改变光方向矢量的基础。

然后,只需使用tagent空间光向量并计算每个像素的光方程,其中最基本的形式是tagent空间光向量和法线贴图(凹凸纹理)之间的点积。

这就是法线贴图的外观(法线组件存储在纹理的每个通道中,并且已经在切线空间中):

这是一种方法,您可以在视图空间中计算事物,但上述方法更容易理解。

旧的凹凸贴图要简单得多,也是一种假效果。

所有凹凸贴图技术都在像素级操作,因为它们以某种方式干扰曲面的渲染方式。即使是旧的浮雕凹凸贴图也会按像素进行一些计算。

编辑:我添加了更多的澄清,当我有空闲时间时,我会尝试添加一些数学和示例。尽管有很多资源可以详细解释这一点。

荆梓
2023-03-14

顶点法线对于Gouraud和Phong着色都是绝对必要的。

在Gouraud着色中,照明是逐顶点计算的,然后在三角形上插值。

在Phong着色中,法线沿三角形插值,然后按像素/片段进行计算。

凹凸贴图指的是一系列不同的技术。在进行法线映射(可能是当今最常见的一种)时,会按顶点计算法线、双切线(通常被错误地称为双法线)和切线,以构建基础矩阵。然后在三角形上插值该基矩阵。然后,从法线贴图检索的法线通过该基矩阵进行变换,然后按像素执行照明。

上面的法线贴图技术有一些扩展,允许凹凸在后面隐藏其他凹凸。这通常是通过将高度贴图与法线贴图一起存储,然后光线在高度贴图中移动以查找被遮挡的部分来执行的。这种技术被称为地形测绘。

还有其他较旧的形式,如DUDV凹凸映射(在DirectX 6中作为环境映射、凹凸映射或EMBM实现)。

还有浮雕凹凸贴图这是凹凸贴图的早期方法

编辑:作为对你评论的回应,浮雕凹凸映射可以在古鲁德阴影三角形上执行。其他形式的凹凸映射必然是每像素(因为它们是通过在每像素(或至少每像素)的基础上修改表面法线来工作的)。如果有其他方法可以在每顶点照明下执行,我不会感到惊讶,但我想不出任何方法。不过,与在每像素的基础上进行相比,结果看起来相当垃圾。

Re:切线和双切线实际上非常简单,一旦你了解它们(虽然花了我很多年,tbh;)。任何3D坐标框架都可以由一组形成正交基矩阵的向量来定义。通过设置每个顶点的法线、切线和双切线,您只需在每个顶点设置坐标框架。由此,您可以将世界或对象空间向量转换为三角形自己的坐标框架。从这里您可以简单地将光向量(或位置)转换为三角形表面上给定像素的坐标框架。这意味着法线贴图中的法线不需要存储在对象的空间中,因此当这些三角形四处移动时(例如,当被动画时),法线已经在它们自己的本地空间中被处理。

 类似资料:
  • OpenGL的渲染管线分为几个步骤。一个简单的OpenGL渲染管线将包含一个顶点着色器和一个片段着色器。 顶点着色器接收顶点数据,并且在程序最后赋值给gl_Position。然后,顶点将会被裁剪,转换和栅格化后作为像素输出。 片段(像素)进入片段着色器,进一步对片段操作并将结果的颜色赋值给gl_FragColor。顶点着色器调用多边形每个角的点(顶点=3D中的点),负责这些点的3D处理。片段(片度

  • WebGL的着色器代码分为顶点着色器代码和片元着色器代码两部分,顶点着色器代码会在GPU的顶点着色器单元执行,片元着色器代码会在GPU的片元着色器单元执行,在WebGL渲染管线流程中,或者说GPU的渲染流程中,顶点着色器代码先执行处理顶点,得到一系列片元,然后再执行片元着色器代码处理片元。 main()函数 顶点着色器和片元着色器代码都有一个唯一的主函数main(),attribute、varyi

  • 我是OpenGL的新手,在整理如何将纹理和着色器绑定到VBOs时遇到了困难。 我正在使用Cinder的纹理和着色器类。以下是我绘制方法的一部分: 在上面的代码中,如果我注释掉对mShader的调用。bind(),我的球体VBO将显示纹理(myImage)。我的着色器适用于普通(无纹理)形状,但当我在绘制任何带有包裹纹理的形状之前绑定着色器时,它会阻止纹理显示。 这是我使用的着色器的问题,还是我不理

  • 在Hello Triangle教程中提到,着色器(Shader)是运行在GPU上的小程序。这些小程序为图形渲染管线的某个特定部分而运行。从基本意义上来说,着色器只是一种把输入转化为输出的程序。着色器也是一种非常独立的程序,因为它们之间不能相互通信;它们之间唯一的沟通只有通过输入和输出。 前面的教程里我们简要地触及了一点着色器的皮毛,并了解了如何恰当地使用它们。现在我们会用一种更加广泛的形式详细解释

  • 我正在尝试实现现代OpenGL,但问题是:大多数教程都是基于3.3的,说到GLSL330,我只有GLSL130。因此,许多事情显然是不同的,因为我的VBO不起作用。 你能给我一个一般的提示或教程,解释如何使用GLSL 130与VBO的?在我的例子中,我加载了vbo,但是当我使用我的着色程序时,只有用glVertex调用的顶点被渲染,就像vbo被忽略(没有输入)。这个怎么解决? 你能在没有着色器的情