【Shading】Applying Textures 应用纹理

Applying Textures 应用纹理

原理:屏幕上的任何一个点找到对应的纹理上的点,然后直接查,这个点对应纹理上的哪个点。
在这里插入图片描述
那如果这么简单就好了!那么我们这么查,有什么问题呢?


Texture Magnification 纹理放大

What if the texture is too small?

如果纹理太小,我们去查,纹理就会被拉大,导致我们看到这样的现象:

Generally don’t want this — insufficient texture resolution
通常,我们不希望纹理不足,我们希望纹理上的一个像素就对应屏幕上的一个像素。

当一个点去查找纹理,查找的不是一个整数时怎么办?这个时候就四舍五入了,找一个近似的。但是这样就会挺丑的,肯定会造成不连续的现象,也就是锯齿。

在这里插入图片描述

A pixel on a texture — a texel
纹理上的一个像素也是有名字的:texel

Bilinear Interpolation 双线性插值

在这里插入图片描述
显然,这个时候就没有映射到纹理上的整点位置。按照最近查找,那么一定会找到这个点:
在这里插入图片描述
然后就会产生锯齿的感觉。

我们多找几个点,找临近的4个点试一试:

Take 4 nearest sample locations, with texture values as labeled.
取4个最近的样本位置,用纹理值作为标记。
在这里插入图片描述
And fractional offsets, ( s , t ) (s,t) (s,t) as shown
分数偏移量 ( s , t ) (s,t) (s,t),如图所示
在这里插入图片描述
Linear interpolation 线性插值 (1D)
lerp ⁡ ( x , v 0 , v 1 ) = v 0 + x ( v 1 − v 0 ) \operatorname{lerp}\left(x, v_{0}, v_{1}\right)=v_{0}+x\left(v_{1}-v_{0}\right) lerp(x,v0,v1)=v0+x(v1v0)
Two helper lerps 两个辅助的差值
u 0 = lerp ⁡ ( s , u 00 , u 10 ) u 1 = lerp ⁡ ( s , u 01 , u 11 ) \begin{aligned} &u_{0}=\operatorname{lerp}\left(s, u_{00}, u_{10}\right) \\ &u_{1}=\operatorname{lerp}\left(s, u_{01}, u_{11}\right) \end{aligned} u0=lerp(s,u00,u10)u1=lerp(s,u01,u11)
Final vertical lerp, to get result: 最后一次差值,得出结果:
f ( x , y ) = lerp ⁡ ( t , u 0 , u 1 ) f(x, y)=\operatorname{lerp}\left(t, u_{0}, u_{1}\right) f(x,y)=lerp(t,u0,u1)

这里就是做了两趟差值,水平差值两次,竖直差值一次,所以我们叫它双线性插值。

我的个人看法,就是将附近的四个点的颜色值进行加权平均。

处理出来的图像效果如下所示:
在这里插入图片描述

Bicubic 双立方插值

相比双线性差值,Bicubic不止取4个样本,而是取16个样本,每次4个进行差值,增大了开销,但也细化了图像。(虽然这张图看上去就那样,我们就假设看到的比Bilinear更清晰吧XD )
在这里插入图片描述

What if the texture is too large?

如果纹理过大,又会导致什么问题呢?
Point Sampling Textures — Problem

可以看到,远处出现了摩尔纹,近处出现了锯齿。
在这里插入图片描述
这个是什么形成的呢?当我们还在用中心点对中心点的方式时,会发现,像素覆盖的纹理区域过大时,也会走样。
在这里插入图片描述
那么,超采样能得到结果么?
在这里插入图片描述
答案是能,但是消耗太大了。

Antialiasing — Supersampling?

Will supersampling work?

  • Yes, high quality, but costly 是的,质量高,但开销也高
  • When highly minified, many texels in pixel footprint 当高度缩小时,许多texels会在像素覆盖面中出现
  • Signal frequency too large in a pixel 在一个像素内的信号频率过大
  • Need even higher sampling frequency甚至需要更高的采样频率

Let’s understand this problem in another way

  • What if we don’t sample? 如果我们可以避免采样?
  • Just need to get the average value within a range!只需要在一个范围内的平均值!

如果不采样就能知道这里的平均值是多少?那就好办了!

Point Query 点查询 vs. (Avg.) Range Query 范围查询

现在我们考虑一个问题:点查询和范围查询。

Different Pixels -> Different-Sized Footprints

假设我们用到的是同样的纹理,那么这幅图中的远处的像素就会覆盖到很多的纹理。
在这里插入图片描述
这里就要引入一个在图形学上广泛运用的经典概念——Mipmap

Mipmap

Allowing (fast, approx, square) range queries 允许(快速、近似、仅为正方形)的范围查询

它将纹理分成了很多层,不同的层的分辨率都不一样,每一层都在上一层的基础上将分辨率砍一半。

因此,它有 l o g 2 N log_2N log2N层。

在这里插入图片描述
在这里插入图片描述

那么,我们原本只有一张图,现在我们生成了这么多张图,我们总共引入了多大的额外的存储呢?

很简单,大家可以自己算一算。

就是原本的图的1/3。

这个额外的存储量似乎还比较可以接受。

Computing Mipmap Level D

计算第D层的Mipmap
在这里插入图片描述
Estimate texture footprint using texture coordinates of neighboring screen samples
使用相邻屏幕样本的纹理坐标来估计纹理覆盖面
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
可以用这张图来理解:越暖越深的颜色,表示层数越少,比如深红色表示第0层,蓝色表示查询第n层。
在这里插入图片描述
但是,这样查询的出来的图像一定会有缝。假如我们想查询第1.8层,怎么办呢?

差值。我们求出第一层和第二层的值,并且进行一个差值。

这就是三线性插值。

Trilinear Interpolation 三线性插值

相比之前不做第三次差值,开销只是多了一次差值计算,是可以接受的。

在这里插入图片描述
用了三线性插值的图像也变得很漂亮了

(当然,柱子上还是有不正常的地方,那是图形本身的问题,在这里我们不考虑。)
在这里插入图片描述

Mipmap Limitations

Mipmap的限制
在这里插入图片描述
远处的图像看上去就……已经完全合成一整块了,这个比Supersampling 512x的效果可差多了。

Anisotropic Filtering 各向异性过滤

在这里插入图片描述

各向异性过滤允许我们对长条形的这种区域进行快速的范围查询,结果也会好很多。生成的各向异性过滤图,总共的开销也会是原本的3倍,对比Mipmap,存储的代价变高了。

当然,在打游戏的时候,只要你显存足够,就把各向异性过滤开到最高就好。

各向异性过滤生成的这张图的名字叫Ripmap
在这里插入图片描述
但是对于斜着的区域,它查询得就不是很好。

Irregular Pixel Footprint in Texture
在这里插入图片描述

EWA filtering

EWA过滤

  • Use multiple lookups
    使用多个查找
  • Weighted average
    加权平均值
  • Mipmap hierarchy still helps
    Mipmap层次结构仍然有帮助
  • Can handle irregular footprints
    可以处理不规则的覆盖面
    在这里插入图片描述
    用很多不同的圆形,去覆盖这个不规则的图形。但是代价就是多次查询。

纹理的作用

Many, Many Uses for Texturing 纹理真的有很多用途
In modern GPUs, texture = memory + range query (filtering) 在现代gpu中,纹理=内存+范围查询(过滤)

  • Environment lighting 环境光
  • Store microgeometry 存储微几何图形
  • Procedural textures 可编程纹理
  • Solid modeling 实体造型
  • Volume rendering 立体渲染

Environment Map

环境光照、环境贴图:只记录它们的方向信息,认为它们无限远,没有深度信息。
在这里插入图片描述

Environmental Lighting 环境光照

在这里插入图片描述
在这里插入图片描述
正如世界地图那样,欧洲比地图上画的要大,南极洲也是。在世界地图上,靠近极点的位置被强烈地扭曲,这就是问题。
在这里插入图片描述
用一个立方体把球包住,创造一个球的包围盒。把光照信息存在立方体的表面上,得到立方体的六个表面。
每个球表面的像素都作法线,在立方体上找到对应的像素。这样可以减少扭曲。
在这里插入图片描述
扭曲变少了,但是需要根据方向来寻找在立方体上的哪一个面,增加了计算量。
在这里插入图片描述
利用纹理定义相对基本表面的高度,在纹理上查询相对高度,使法线发生变化(实际上是人为做的假的法线),法线变化引起着色变化,让球面看起来凹凸不平。
在这里插入图片描述

Bump Mapping 法线贴图

通过法线贴图定义一个纹理,但不去改变任何几何信息,该多少个三角形还是多少个三角形。
然后把任何一个像素的法线都做一个扰动。
扰动:通过定义不同位置的高度,与邻近位置的高度差,来重新计算法线。
由纹理定义的每个纹理的“高度移动”。
在这里插入图片描述
How to perturb the normal (in flatland) 如何计算扰动(不考虑二维和三维的空间,只考虑函数)

  • 假设原本的点的法线 n ( p ) = ( 0 , 1 ) n(p)=(0,1) n(p)=(0,1)
  • 在任何一个点处,计算凹凸贴图给出来的梯度(导数)——取邻近的两个点的高度相减,得到切线
  • 得到法线,就是垂直于切线的方向。
  • 在一维的情况下,求法线就是简单的几何函数,因为其实并没有求导,只是拿邻近的高度相减来代替真正的求导过程,这个过程就求了一个斜率k。再求一个垂直于切线的方向作为法线: ( a , b ) (a,b) (a,b)的垂直向量为 ( − b , a ) (-b,a) (b,a),又因为 b = k a b=ka b=ka,因此垂直向量为 ( − k a , a ) (-ka,a) (ka,a),约分 a a a,就是 ( − k , 1 ) (-k,1) (k,1)
    在这里插入图片描述
    How to perturb the normal (in 3D) 如何计算扰动(3d)
  • 假设原本的法线 n ( p ) = ( 0 , 0 , 1 ) n(p)=(0,0,1) n(p)=(0,0,1)
  • 求出梯度,分别在水平和竖直方向变化一个单位,求出斜率
  • 求出不同方向的导数(实际上是近似的)之后,就可以利用类似上一页的原理,直接改变正负来求出法线。
  • 在局部坐标系里,原本的法线设为 ( 0 , 0 , 1 ) (0,0,1) (0,0,1),代入原本法线时,进行简单的坐标变换。

Displacement mapping 位移贴图

和凹凸贴图一样,都是用纹理定义高度。但位移贴图实际上会把顶点真的进行位移。
在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值