图形学笔记- 3. 着色Shading


Visibility/ occlusion
Z-buffering
Shading
Illumination Shading
Graphics Pipline

Painter’s Algorithm

灵感来自画家的绘画方式,从后到前绘制,覆盖帧缓冲区
逐步覆盖
请添加图片描述
需要对深度排序(O(n log n)对于n个三角形)
但会有不可解析的深度顺序
请添加图片描述
遮挡

Z-buffer

这就是最终获胜的算法。
思想:

  • 存储每个样本(像素)的当前最小z值
  • 需要一个额外的深度值缓冲区
    • 帧缓冲区存储颜色值
    • 深度缓冲区(z-buffer)存储深度
      important:为了简单起见,我们假设z总是正的
      (小z ->近,大z ->远)请添加图片描述
初始化depth buffer to $\infty$
在光栅化期间:
	for(each triagle T)
		for(each sample (x,y,z) in T)
			if(z < zbuffer[x,y])  //当前最近的样本
				framebuffer[x,y]=rgb;  //更新颜色
				zbuffer[x,y]=z; //更新深度
			else
				; // 该点被遮挡

请添加图片描述
复杂度 O ( n ) O(n) O(n) n个三角形,假设每个三角形有一定大小
用不同的顺序画三角形?
最重要的可见性算法
为所有GPU在硬件上实现

处理不了透明

着色

请添加图片描述
请添加图片描述
在韦氏词典中
Shad·ing, [[s] e / d / n],名词
用平行线或色块使插图或图表变暗或上色

材质material应用到物体上的过程。

Blinn-Phong反射模型

感性的观察:请添加图片描述
镜面高光、漫反射、环境照明

着色是局部的

计算在特定着色点反射到相机的光
请添加图片描述
输入:

  • 观察方向, v v v
  • 表面法向量, n n n
  • 光方向, l l l()
  • 表面参数(颜色colro, 反光度shininess

不会产生阴影shadows!(着色≠阴影)
请添加图片描述

漫反射

光在各个方向均匀地散射
表面颜色对所有观看方向是相同的

请添加图片描述
但是接收了多少光(能量)呢?
Lambert’s cosine law朗伯余弦定律请添加图片描述
灯光衰减Light Falloff 能量守恒请添加图片描述

Lambertian(漫反射)着色

着色独立于视图方向请添加图片描述
产生扩散外观diffuse appearance请添加图片描述

Specular 镜面高光

强度取决于观察方向

  • 明亮的近镜反射方向请添加图片描述
    接近镜像方向的v⇔接近法线的半程矢量
    用单位向量的点积来度量“近”请添加图片描述
    Cosine Power Plots
    增加 p p p使反射lobe变窄请添加图片描述
    请添加图片描述
Ambient Term

认为是恒定的
着色不依赖于任何东西

  • 添加恒定的颜色来解释忽略的照明和填充黑色阴影
  • 这是近似的/假的!请添加图片描述
Blinn-Phong Reflection Model

请添加图片描述
L = L a + L d + L s = k a I a + k d ( I / r 2 ) max ⁡ ( 0 , n ⋅ l ) + k s ( I / r 2 ) max ⁡ ( 0 , n ⋅ h ) p L=L_a+L_d+L_s=k_aI_a+k_d(I/r^2)\max(0,\mathbf{n}\cdot \mathbf{l})+k_s(I/r^2)\max(0,\mathbf{n}\cdot \mathbf{h})^p L=La+Ld+Ls=kaIa+kd(I/r2)max(0,nl)+ks(I/r2)max(0,nh)p

Shading Frequencies 着色频率

请添加图片描述

着色每个三角形(平面着色)

三角形面是平的-一个法向量
不适合光滑的表面

请添加图片描述

着色每个顶点(Gouraud着色)

从三角形的顶点插值颜色
每个顶点都有一个法向量(如何?)请添加图片描述

像素着色(冯氏着色Phong)

在每个三角形上插值法向量
在每个像素处计算完整的着色模型
不是Blinn-Phong反射模型
请添加图片描述

着色频率:面,顶点或像素

请添加图片描述

定义每个顶点的法向量

最好从底层几何中获得顶点法线
考虑一个球:请添加图片描述
否则必须从三角形面推断顶点法线

  • 简单方案:**取周围面法线的平均值
    请添加图片描述
    N v = ∑ i N i ∣ ∣ ∑ i N i ∣ ∣ N_v=\frac{\sum_i N_i}{||\sum_iN_i||} Nv=∣∣iNi∣∣iNi

顶点法线的重心插值Barycentric interpolation
请添加图片描述
不要忘记对插值方向进行规范化

图形(实时渲染) 管线

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

着色器编程Shader Programs

编程顶点和片段处理阶段
描述对单个顶点(或片段)的操作

示例GLSL片段着色编程、

uniform sampler2D myTexture; // program parameter
uniform vec3 lightDir; // program parameter
varying vec2 uv; // per fragment value (interp. by rasterizer)
arying 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
}

Shader函数每个片段fragment执行一次。
输出当前片段屏幕样本位置表面的颜色。
这个着色器执行纹理查找以获得表面的材质颜色,然后执行漫射照明计算。

蜗牛着色器
Snail
请添加图片描述
目标:高度复杂的3D场景在实时
一个场景中有成千上万到数百万个三角形
复杂的顶点和片段着色计算
高分辨率(200 - 400万像素+超采样)
每秒30-60帧(VR更高)

图形管道实现:gpu
用于执行图形管道计算的专用处理器
请添加图片描述
GPU:异构多核处理器
请添加图片描述

Texture Mapping纹理映射

不同的地方有不同的颜色?
请添加图片描述
表面是二维的
表面存在于三维世界空间
每个3D表面点在2D图像(纹理)中也有一个位置。请添加图片描述
纹理应用于表面请添加图片描述
每个三角形将纹理图像的一部分“复制”到表面。
纹理坐标的可视化
每个三角形顶点分配一个纹理坐标(u,v)请添加图片描述
纹理应用于表面请添加图片描述
请添加图片描述
纹理坐标的可视化请添加图片描述
纹理可以多次使用请添加图片描述

三角形内部插值:重心坐标

  • 重心坐标
  • 纹理问题
  • 纹理应用

为什么要插值

  • 指定顶点处的值
  • 在三角形上获得平滑变化的值
    插什么
  • 纹理坐标,颜色,法向量,…
    如何
  • 重心坐标

一个三角形的坐标系统 ( α , β , γ ) (\alpha,\beta,\gamma) (α,β,γ)请添加图片描述
( x , y ) = α A + β B + γ C , α + β + γ = 1 (x,y)=\alpha A+\beta B + \gamma C, \alpha+\beta+\gamma=1 (x,y)=αA+βB+γC,α+β+γ=1如果三个坐标非负,则点在三角形内部
A = ( 1 , 0 , 0 ) A=(1,0,0) A=(1,0,0)
几何视角-成比的例面积
请添加图片描述
α = A A A A + A B + A C \alpha=\frac{A_A}{A_A+A_B+A_C} α=AA+AB+ACAA
β = A B A A + A B + A C \beta=\frac{A_B}{A_A+A_B+A_C} β=AA+AB+ACAB
γ = A C A A + A B + A C \gamma=\frac{A_C}{A_A+A_B+A_C} γ=AA+AB+ACAC请添加图片描述
质心的重心坐标 ( 1 3 , 1 3 , 1 3 ) (\frac{1}{3},\frac{1}{3},\frac{1}{3}) (31,31,31)

公式:请添加图片描述
在顶点处线性插值值
请添加图片描述
VA、VB、VC可以进行位置、纹理坐标、颜色、法线、深度、材质属性…
然而,重心坐标在投影下不是不变的。在三维空间做插值

应用纹理

简单纹理映射:漫反射颜色

for each resterized screen sample(x,y)://通常是一个像素的中心
	(u,v) = evaluate texture coordinate at (x,y);//使用重心坐标
	texcolor = texture.sample(u,v);
	set sample’s color to texcolor;//通常是漫射反照率Kd(回想一下Blinn-Phong反射模型)

纹理放大 Texture Magnification

如果纹理太小怎么办?
简单情形:
一般不希望这样-纹理分辨率不足
纹理上的一个像素——一个纹理(纹理元素、纹素)
插值方法:请添加图片描述

双线性插值

请添加图片描述
请添加图片描述
请添加图片描述
双线性插值通常以合理的成本给出相当好的结果
困难情形 如果纹理太大怎么办?
点采样纹理 - 问题 锯齿 摩尔纹
请添加图片描述
纹理中的屏幕像素“足迹”
请添加图片描述
超采样做抗锯齿请添加图片描述
有效,但代价高

  • 当高度缩小时,许多像素占用空间
  • 一个像素的信号频率太大
  • 需要更高的采样频率
    让我们用另一种方式来理解这个问题
  • 如果我们不取样呢
  • 只需要得到一个范围内的平均值
点查询Point Query与(平均)范围查询Range Query

不同像素->不同大小的足迹请添加图片描述

Mipmap 多级贴图

允许(快,近似,方形)范围查询 (图像金字塔)
“Mip”来自拉丁语“multum in parvo”,意思是一个小空间里的许多人请添加图片描述
请添加图片描述
mipmap的存储开销是多少?(1+1/4+1/16+…=4/3)
也即多了三分之一
计算Mipmap层次D请添加图片描述
使用相邻屏幕样本的纹理坐标估计纹理占用请添加图片描述
请添加图片描述
Mipmap层级的可视化请添加图片描述
1.5层怎么办?

三维插值请添加图片描述
请添加图片描述
限制:请添加图片描述
请添加图片描述

请添加图片描述
Anisotropic Filtering各向异性过滤
请添加图片描述
纹理中的不规则像素足迹请添加图片描述
Ripmaps和summed area tables求和面积表

  • 可以查找轴对齐的矩形区域
  • 对角线仍然是个问题请添加图片描述

EWA过滤

  • 使用多个查找
  • 加权平均
  • Mipmap层次结构仍然有帮助
  • 能处理不规则足迹
    请添加图片描述

纹理的应用

在现代GPU中,纹理=内存+范围查询(过滤)

  • 将数据带入段计算的一般方法

许多应用程序

  • 环境光照
  • 存储微观几何图形 microgeometry
  • 程序纹理
  • 实体建模
  • 体绘制

环境贴图

![[Pasted image 20241117145600.png]]

环境光照

![[Pasted image 20241117145641.png]]

球面环境贴图

![[Pasted image 20241117145734.png]]

球面贴图 - 问题
![[Pasted image 20241117145824.png]]

容易出现变现(上下部分)

立方体贴图

![[Pasted image 20241117145937.png]]

一个矢量沿着这个方向映射到一个立方体点。
立方体有6个正方形纹理贴图。
![[Pasted image 20241117150145.png]]

更少的失真

纹理可以影响阴影!

纹理不一定只代表颜色

  • 如果它存储高度/法线呢?
  • 凹凸/法线贴图
  • 模拟(fake)细节几何
    ![[Pasted image 20241117152658.png]]
凹凸贴图Bump mapping

添加表面细节而不添加更多三角形

  • 每像素的扰动表面法线 (只适用于阴影计算)
  • 每个纹理定义的“高度移动”
  • 如何修改法向量?
    ![[Pasted image 20241117153400.png]]

如何扰乱常态(在二维平面上flatland)

  • 原曲面法向 n ( p ) = ( 0 , 1 ) n(p) = (0,1) n(p)=(0,1)
  • p点的导数是 d p = c ∗ [ h ( p + 1 ) − h ( p ) ] dp = c * [h(p+1) - h(p)] dp=c[h(p+1)h(p)]
  • 则扰动法线为 n ( p ) = ( − d p , 1 ) . n o r m a l i z e d ( ) n(p) = (-dp, 1).normalized() n(p)=(dp,1).normalized()
    ![[Pasted image 20241117160934.png]]

在3d表面上
原始表面法线 n ( p ) = ( 0 , 0 , 1 ) n(p) = (0, 0, 1) n(p)=(0,0,1)
p点的导数是
d p / d u = c 1 ∗ [ h ( u + 1 ) − h ( u ) ] dp/du=c1 * [h(u+1) - h(u)] dp/du=c1[h(u+1)h(u)]
d p / d v = c 2 ∗ [ h ( v + 1 ) − h ( v ) ] dp/dv = c2 * [h(v+1) - h(v)] dp/dv=c2[h(v+1)h(v)]
扰动法线是 n = ( − d p / d u , − d p / d v , 1 ) . n o r m a l i z e d ( ) n = (-dp/du, -dp/dv, 1).normalized() n=(dp/du,dp/dv,1).normalized()
注意,这是在局部坐标!local coordinate
更多细节将在HW3的FAQ中详细说明

位移贴图Displacement mapping——一种更高级的方法
使用与凹凸贴图相同的纹理
实际上是移动顶点
代价:模型的三角形要更细致。
在这里插入图片描述

3D程序噪声Procedural Noise+实体建模
![[Pasted image 20241117235138.png]]

提供预先计算的阴影
![[Pasted image 20241117235202.png]]

3D纹理和体渲染
![[Pasted image 20241117235225.png]]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不知不道abc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值