GAMES101 学习8——着色(着色频率、图形管线、纹理映射)

lutianfei 发表于 2022/05/06 15:36:30 2022/05/06
【摘要】 一、Shading Frequencies着色频率(指着色应用在哪些点上)1.感性认知从左到右依次应用为 面 → 顶点 →像素2.三个方法的正规定义①Flat shading(应用在表面)两边做叉积→三角形的法线②Gouraud shading(逐顶点)算出顶点法线,然后插值③Phong shading(逐像素)区分:Phong shading 是一种着色频率,和布林冯着色模型不是一个概念...

一、Shading Frequencies着色频率(指着色应用在哪些点上)

引起着色的不同主要就是因为着色频率不同所导致的,如下图:
从左到右依次应用为 面 → 顶点 →像素
image.png

这里主要分成对三角形进行着色,对顶点进行着色,对像素进行着色三种着色方案进行讨论

1.1 Flat shading(应用在表面,对三角形进行着色)

对每个三角形着色也称为Flat shading ,它是指每项属性例如纹理,法向,颜色,都是属于一个三角形的,所以三角形内部不会有插值变化。所以,三角形内部只会根据面法向量对光线反射进行计算,所有的三角形反射都看做一个平面,给人以一种块状的效果(三角形较少时),如下图:

简言之:两边做叉积→三角形的法线
image.png

1.2 Gouraud shading(逐顶点)

对顶点进行着色也称为gouraud shading,它发生在顶点着色器阶段。对于每个多边形的顶点都存在一个法向量,但是他的着色是先通过这些法向量对顶点计算出光照颜色,然后用光照颜色来进行三角形内部插值,如下图:

简言之:算出顶点法线,然后插值
image.png

定义逐顶点法线求法

认为顶点的法线为相邻面的法线的平均(更优办法是根据面积加权平均)
image.png

1.3 Phong shading(逐像素)

对每个像素着色也称phong shading,它发生在片段着色器阶段。它是通过对多边形每个顶点的法向量进行插值,然后我们通过插值得到的法向量(每个像素都有自己的法向量),再去计算光照颜色,如下图:

image.png

注意:Phong shading 是一种着色频率,和布林冯着色模型不是一个概念。

使用不同的着色方案会得到不同的结果,但是也不能说某种方案就一定差于另一种方案,当顶点数足够多时,对三角形进行着色不一定会比对像素进行着色效果差,对应的内存开销也不一定比对像素进行着色小。

image.png

通过求重心坐标获取逐像素发现(后边讲)
image.png

说明:
由于片段着色器阶段计算的坐标都是处于世界坐标系中,所以在计算光照时,所用的法向量也要转换到世界坐标系下。还记得之前我们把坐标转换到世界坐标是乘以model矩阵,但是法向量是不可以直接乘以model矩阵的,因为它仅仅是一个向量,而且也不是齐次坐标表示,所以这里需要一个法线矩阵(它是model矩阵逆的转置)来进行转换,使法向量也处于世界坐标下,详细推导可以看这里:链接: http://www.lighthouse3d.com/tutorials/glsl-12-tutorial/the-normal-matrix

二、渲染管线 Graphics (Real-time Rendering)Pipeline

2.1 渲染管线流程

通过图形渲染管线都是流水线形式,上一阶段的输出作为下一阶段的输入,该课程的一个图形渲染管线(也是前向渲染管线)流程如下:
image.png

总体来说:顶点 →光栅化 →着色
用mvp举例:
MVP(Model, View, Projection transforms)→采样 →z-buffer test →shading →Texture mapping
image.png

具体来说:

  1. 首先我们有一系列三维点坐标,可能是从某些文件读入。然后我们把它们输入给Vertex Processing阶段(顶点着色器),该阶段主要进行的操作是modelviewprojection变换,将三维坐标变换到二维裁剪空间(通过投影丢掉了不可见的区域),也可以进行gouraud shading等操作。
    image.png

  2. 随后把顶点着色器的输出,作为输入给Triangle Processing阶段,这里主要是进行一些图元的绘制,包括把点连接成三角形,或者制作一些顶点的副本等

  3. 下一个阶段是Rasterization阶段(光栅化),该阶段将三维图元作为输入,通过采样将其绘制在二维屏幕上,并以片段的形式作为输出。

片段、像素 关系说明:

  • 片段(Fragment):三维顶点光栅化后的数据集合,还没有经过深度测试
  • 像素:片段经过深度测试、模板测试、alpha混合之后的结果
  • 片段的个数远远多于像素,因为有的片段会在测试和混合阶段被丢弃,无法被渲染成像素

image.png

  1. Fragment Processing 把片段作为输入。该阶段主要进行深度测试计算光照以及纹理映射等,所以该阶段输出的结果基本上已经确定了像素最终的颜色。
    image.png

image.png

image.png

2.2 管线渲染编程

通常可以在Vertex Processing阶段(顶点着色器) 和 Fragment Processing阶段(片段着色器) 进行编程,这些编程的小程序被称为Shader Programs,里面常用的语言有glsl等。

shader编写学习资料: https://www.shadertoy.com/.

2.2.1 Shader programs概念说明

  1. 能在硬件上执行的语言
  2. 每个顶点/像素执行一次(通用的,不用for循环)
    • 顶点的操作→顶点着色器vertex shader
    • 像素的操作→像素/片元着色器fragment shader

一个GLSL中的例子:下面的示例程序简单描述了一个着色器的工作,uniform表示从cpu传来的变量,varying 表示从上一个阶段传来的变量,void diffuseShader() 为着色函数, texture2d是内置函数,它表示将纹理myTexture 对应到uv向量,gl_FragColor 可以看做是内置参数,它是屏幕上用来显示的最终颜色。

uniform sampler2D myTexture; // program parameter 
uniform vec3 lightDir;   // program parameter 
varying vec2 uv;    // per fragment value (interp. by rasterizer)
varying vec3 norm;   // per fragment value (interp. by rasterizer) 
void diffuseShader() 
{   
	vec3 kd;   
	kd = texture2d(myTexture, uv);    // material color from texture  
	kd *= clamp(dot(–lightDir, norm), 0.0, 1.0);  // Lambertian shading model   
	gl_FragColor = vec4(kd, 1.0);    // output fragment color 
}

2.2.2 Snail Shader Program 在线Shader编写网站

https://www.shadertoy.com/view/ld3Gz2

3.GPU
①gpu:-独显;-核显
②gpu可以理解成高度并行化的处理器
(核心数量理解为并行线程的数量)
gpu并行度惊人,远超过cpu

三、Texture Mapping纹理映射

纹理映射就是将纹理空间中的纹理像素映射到屏幕空间中的像素的过程。通俗来说可以认为是一张二维纹理把一个三维物体“包裹”了起来,因此三维物体获得了一些表面纹理:

image.png
image.png

纹理坐标系

纹理也是有坐标的,它的坐标空间是由uv构成(通常[0,1]),里面对应的元素是纹素,是计算机图形纹理空间中的基本单元,如下图:
image.png

纹素像素不一样,因为它们是处于不同坐标下的,纹素处于纹理空间,而像素处于屏幕空间。在对三维表面铺设纹理的时候,通过纹理映射技术将纹素映射到恰当的输出图像像素上,这种映射不是简单的一一对应,因为会受到视角的影响,如果以一种斜的姿势观察物体,一个像素对应的纹理区域很可能是比较扭曲的,可以看下图:
image.png

纹理和着色的区别与联系
纹理用来定义着色的时候需要的不同点的属性(不希望每一个点相同着色,用纹理来改变)

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请发送邮件至:cloudbbs@huaweicloud.com;如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。