图形学入门自学笔记——lec9【纹理映射】

Texture Mapping:用图片或者pattern提供像素的颜色,有1d, 2d, 3d, 4d纹理
在这里插入图片描述

Environment Mapping:用物体周围的环境作为纹理
在这里插入图片描述

Bump Mapping:用来在着色时扰动法向量
在这里插入图片描述

Texture Space

通常是二维图片空间[0,1]×[0,1]
纹理坐标(u, v)或者(s, t)
每个顶点设置对应的纹理坐标
在这里插入图片描述

Texture Mapping

三维World space到二维Texture space的一个映射,增加真实效果同时不提高模型复杂度。
在这里插入图片描述
思路:
网格顶点(x, y, z )映射到纹理坐标(u, v)保角映射,等面积映射,等距映射
图元的纹理坐标在屏幕空间用重心坐标插值
读取(u, v)对应的纹理颜色,作为漫反射系数KdK_dKd

Texture Mapping in OpenGL

基本流程:

  • 启用纹理功能
  • 创建纹理对象
    • 绑定纹理(状态)
    • 读图文件或者生成纹理图案
  • 设置纹理参数
    • Wrapping
    • Filtering
    • Mipmapping
  • 对每个顶点设置纹理坐标
    在这里插入图片描述

在流程中需要的地方启用纹理,一般是display回调函数里
glEnable(GL_TEXTURE_2D)
DrawObject()…
glDisable(GL_TEXTURE_2D)

创建和绑定纹理对象(OpenGL状态)
GLuint handles[2];
glGenTextures(2, handles);//生成texture ID 或names

//绑定第一个纹理ID为当前纹理
glBindTexture(GL_TEXTURE_2D, handles[0]);

//可以对不同的物体,切换到另一个纹理ID
glBindTexture(GL_TEXTURE_2D, handles[1]);

设置纹理环境参数(纹理贴图和材质颜色的计算方式)
glTexEnv{fi}[v](GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, param)
混合模式param:

  • 默认GL_MODULATE:j结合光照和纹理(乘积,纹理作为物体材质)
  • GL_DECAL:只采用纹理的颜色(如果透明,会混合物体的颜色)
  • GL_REPLACE:只采用纹理的颜色(包括透明度)
  • GL_BLEND:混合周围的颜色(GL_TEXTURE_ENV_COLOR)
  • GL_ADD:物体的颜色加上纹理颜色

Specify Texture Image

生成棋盘纹理

  • Glubyte check_board[64][64]
  • 离散采点:在这里插入图片描述
    &:按位与,在这里的效果是每隔8位,i&8==0的值变一次
    实现棋盘格纹理在这里插入图片描述

读取图片数据

  • ppm:可移植像素格式,按格式读取文本
  • jpg(stb_image.h):
    • 使用stbi_load()读取JPG图片
    • 使用stbi_image_free()释放jpg缓存
      在这里插入图片描述

棋盘纹理

用数学公式生成复杂的棋盘纹理
在这里插入图片描述
在这里插入图片描述
用数学公式生成复杂棋盘纹理
在这里插入图片描述

对当前纹理对象设置图片数据
调用glTexImage2D(target, level, components, w, h, border, fromat, type. texels)

  • target: GL_TEXTURE_2D
  • level: mipmap level
  • components: 纹理颜色通道数
  • w, h: 纹理的宽高
  • border: used for smoothing
  • format and type: 纹理数据格式
  • texels: 纹理数据
    在这里插入图片描述
    OpenGL纹理的尺寸要求是2的指数次方
    对于图文件,可以转换
  • gluScaleImage(format, w_in, h_in, type_in, *data_in, w_out, h_out, type_out, *data_out);

透视纠正

纹理坐标使用重心坐标插值设置内部像素纹理,在透视后会出现扭曲
在这里插入图片描述
透视纠正的深度插值:在这里插入图片描述

设置当前纹理参数

设置纹理映射的参数

Texture Wrapping(超出纹理坐标标准范围时)

  • GL_TEXTURE_WRAP_S: S轴方向
  • GL_TEXTURE_WRAP_T: T轴方向

如果纹理坐标超出[0, 1]

  • 默认GL_REPEAT, 重复贴图
  • 设置GL_CLAMP,截断
  • glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
  • glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
    在这里插入图片描述
    Repeating = (s%1, t%1)
  • GL_REPEAT
  • GL_MORRORED_REPEAT每次重复沿着一个轴镜像翻转

Clamping = (min(s/t, 1), max(s/t, 0))

  • GL_CLAMP
  • GL_CLAMP_TO_EDGE
  • GL_CLAMP_TO_BORDER
    在这里插入图片描述

Texture Filtering(纹理采样的策略)

  • GL_TEXTURE_MAG_FILTER
  • GL_TEXTURE_MIN_FILTER

纹理坐标可以是任意浮点数,不依赖图片的分辨率(width,height)

纹理采样的两种情况:

  • 三角形覆盖像素比对应纹理元素要多:比如图片分辨率很低。需要一个纹理元素对应到多个屏幕像素(放大)

  • 三角形覆盖像素比对应纹理元素要少:比如三角形在远处。需要多个纹理元素对应同一个屏幕像素(缩小)
    Mipmap(多级渐远纹理,消除摩尔纹失真)

**Magnification:**一个纹理对应多个屏幕像素
**Minification:**多个纹理点对应一个屏幕像素
采样(最近点,线性插值)解决
在这里插入图片描述

Magnification

纹理过小,多个屏幕点对应一个纹理点

  • 最近原则(Nearest)
  • 双线性插值(Bilinear Interpolation)

在这里插入图片描述

Minification

纹理过大:多个纹理点对应一个屏幕点
容易导致更严重的走样
在这里插入图片描述

纹理参数的设置

调用glTexParameteri(target, type, mode)

  • 纹理填充方式
    • glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
    • glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
  • 纹理采样方式
    • glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
    • glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)

Mipmap

纹理精度高于物体显示精度时,用Mipmap解决取样问题

生成一组金字塔型的图片 :6464、3232、1616…11
在这里插入图片描述
生成不同Level的纹理

  • Level = 0: 128*128
  • Level = 1: 64*64
  • Level = 2: 32*32
  • Level = 3: 16*16

远处采用level大的纹理
利用屏幕像素的相邻像素点估算
在这里插入图片描述

在这里插入图片描述
如果Mipmap level D = logL不是整数

  • 四舍五入后,在对应图层上双线性插值
  • 三线性插值:
    • 对D向上、向下取整
    • 分别双线性插值后,再对[D, D+1]线性插值

先设置Mipmap Level:glTexImage2D(GL_TEXTURE_*D, level, …)
level默认为0

GLU mipmap builder

  • gluBuild2DMipmaps(…)

Mipmap采样方式

  • 当前图层的采样方式 + 取用哪个图层方式
  • GL_NEAREST_MIPMAP_NEAREST
  • GL_LINEAR_MIPMAP_NEAREST
  • GL_NEAREST_MIPMAP_LINEAR
  • GL_LINEAR_MIPMAP_LINEAR

Mapping a Texture

通过glTexCoord*()设置每个顶点的纹理坐标
在这里插入图片描述
对绘制物体设置纹理坐标
例如
• glBegin(GL_TRIANGLES);
glColor3f(r0, g0, b0);
glNormal3f(u0, v0, w0);
glTexCoord2f(s0, t0);
glVertex3f(x0, y0, z0);
glColor3f(r1, g1, b1);
glNormal3f(u1, v1, w1);
glTexCoord2f(s1, t1);
glVertex3f(x1, y1, z1);
……
• glEnd();

纹理坐标

  • OpenGL可以自动生成纹理坐标

    • glTexGen{ifd}[v](GL_S, GL_TEXTURE_GEN_MODE, params)
    • 生成模式params
      • GL_OBJECT_LINEAR(固定纹理)
      • GL_EYE_LINEAR(按视角变动纹理)
      • GL_SPHERE_MAP(环境映射)
  • 设置投影平面

    • glTexGenfv(GL_T, GL_OBJECT_PLANE, xPlane)
  • 启用

    • glEnable(GL_TEXTURE_GEN_S)
    • glEnable(GL_TEXTURE_GEN_T)
  • 关闭glDisable

圆柱体

圆柱体可以展开为平面,圆柱体的参数坐标是(φ,y)(\varphi,y)(φ,y)

  • x=rcosφx=rcos\varphix=rcosφ
  • y=yy=yy=y
  • z=rsinφz=rsin\varphiz=rsinφ
  • φ∈[0,2π],y∈[−h,h]\varphi\isin[0,2\pi], y\isin[-h,h]φ[0,2π],y[h,h]

圆柱上点(φ,y)(\varphi,y)(φ,y)映射到纹理空间

  • s=φ/2πs=\varphi/2\pis=φ/2π
  • t=(y+h)/2ht=(y+h)/2ht=(y+h)/2h
    在这里插入图片描述
    根据参数方程,生成
  • 顶点坐标:(rcosφ,y,rsinφ)(rcos\varphi,y,rsin\varphi)(rcosφ,y,rsinφ)
  • 法向量:(cosφ,0,sinφ)(cos\varphi,0,sin\varphi)(cosφ,0,sinφ)
  • 纹理坐标:(φ/2π,y/h)(\varphi/2\pi,y/h)(φ/2π,y/h)
    在这里插入图片描述
    在这里插入图片描述

球面

球面的参数坐标是(θ,φ)(\theta, \varphi)(θ,φ)

  • x=rsinθcosφx=rsin\theta cos\varphix=rsinθcosφ
  • y=rsinθsinφy=rsin\theta sin\varphiy=rsinθsinφ
  • z=rcosθz=rcos\thetaz=rcosθ
  • θ∈[0,π],φ∈[0,2π]\theta\isin[0,\pi],\varphi\isin[0,2\pi]θ[0,π],φ[0,2π]

球面上点(θ,φ)(\theta,\varphi)(θ,φ)映射到纹理空间

  • s=φ/2πs=\varphi/2\pis=φ/2π
  • t=θ/πt=\theta/\pit=θ/π

在这里插入图片描述
根据参数方程,生成

  • 顶点坐标:(rsinθcosφ,rsinθsinφ,rcosθ)(rsin\theta cos\varphi,rsin\theta sin\varphi, rcos\theta)(rsinθcosφ,rsinθsinφ,rcosθ)
  • 法向量:(sinθcosφ,sinθsinφ.cosθ)(sin\theta cos\varphi,sin\theta sin\varphi.cos\theta)(sinθcosφ,sinθsinφ.cosθ)
  • 纹理坐标:(φ/2π,θ/π)( \varphi/2\pi,\theta/\pi)(φ/2π,θ/π)
    在这里插入图片描述
    在这里插入图片描述

正方体

  • 正面z = 1
  • 反面z = -1
  • 右面x = 1
  • 左面x = -1
  • 上面y = 1
  • 下面y = -1
    在这里插入图片描述

一般物体

Intermediate Mapping Methods
基于投射,把物体投射到中间曲面:平面/圆柱体/球面/正方体
在这里插入图片描述
在这里插入图片描述

平面投射

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

在这里插入图片描述

圆柱体投射

从物体中心到顶点的射线与圆柱体交点(相交于侧面、圆盘)
在这里插入图片描述

球体投射

在这里插入图片描述

南北极变形严重

立方体投射

不变形、速度快
在这里插入图片描述
标准立方体:

  • 右面0(x>0),左面1(x<0)
  • 上面2(y>0),下面3(y<0)
  • 正面4(z>0),反面5(z<0)

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值