图形渲染管线

图形渲染管线 Graphics (Real-time Rendering) Pipeline

Graphics Pipeline

前面学的流程串起来,就是下图。里面还涉及到了 Shader 和 Texture Mapping 的时机。

Shader

一般指 Shader Programs ,是一个程序,会对一个像素点/片段进行处理、着色。可以用OpenGL的语言写,也就是GLSL

在线shader测试:http://shadertoy.com/view/ld3Gz2

shader展示:https://youtu.be/XuSnLbB1j6E

纹理映射 Texture Mapping

前面已经知道,每个像素点的漫反射系数kd乘以光照强度,会得到该像素点最终的颜色。显然,每个像素点的漫反射系数是由物体本身的颜色属性来决定的,而这个像素点的颜色属性我们会通过一张材质图来确定。这就是贴图。

uv

uv坐标是指纹理展开后,纹理上的坐标。u和v的范围,都定义在0-1之内。

纹理

前面已经学了,三角面内进行插值着色,是用重心坐标来计算出任一个点对应的uv贴图坐标的(也就是决定漫反射系数k)。那么会出现什么问题?

纹理拉伸(纹理图过小)

当纹理贴图太小了,多个像素点会映射到一个纹理点上去,看上去就像是拉伸了。纹理拉伸现象,可以通过**双线性插值 ** 来优化处理。

双线性插值 Bilinear Interpolation:当一个像素点映射到uv贴图上后,取出相邻的3个uv贴图点,进行2次水平、1次竖直方向上的插值,求出这个点在4个uv贴图点中的插值平滑结果(漫反射系数)。

纹理拉伸(纹理图过大)

纹理图过大时,一个像素点的映射区域会覆盖很大的范围,但是一个像素点只能映射一个颜色。最终会走样,产生大量摩尔纹和锯齿。

如果不考虑性能,可以考虑超采样来获取平均值。但是考虑到性能,我们可以用MipMap

MipMaps:只能做近似的、正方形的 范围查询。

先将原图进行一半分辨率的裁剪(比如32x32=>16x16),直到1x1。所有Mipmap大小之和为的原图1/3。

1.如何计算需要的数量:映射出像素点对应uv的范围是几x几。

2.如何查询某个中间值(比如1.8x1.8):三线性插值。比如1.8x1.8,就是把2x2和1x1的2张mipmap结果值,再进行一次线性插值,求出1.8的值作为最终结果。

通过上面2步完成一个正确的Mipmap处理,最终可以得到一个像素点映射连续变化的uv贴图(也就是色彩会平滑、渐变过度)。

上面说了只能做正方形的范围查询,那如果面对不同长宽比的情况(矩形)该怎么做来避免Overblur?

各向异性过滤 Ripmaps:水平和竖直方向上的表现各不相同,不是1:1时,生成长宽拉伸后的图以提供矩形查询,处理长宽比不同的情况。最终额外的贴图大小是原图的3倍。