Games101图形学笔记——着色

Shading

  • Z-buffering(深度缓冲) Shading(着色)
    • 画家算法
    • Z-Buffer
    • Shading(着色)
    • Blinn-Phong Reflectance Model(布林·冯反射模型)
    • 漫反射
    • 能量守恒
  • 着色高光
    • Blinn-Phong Reflection Model
    • ShadingFrequencies 着色频率
      • FlatShading(面着色)
      • GouraudShading(顶点着色)
      • PhongShading(像素着色)
    • 如何求逐顶点的法线
    • 如何求逐像素的法线
    • 图形管线/实时渲染管线
    • Shader
  • Shading -- 纹理处理
    • 重心坐标
    • 应用纹理
      • 纹理放大
    • 双线性插值
      • 纹理缩小
    • Mipmap
    • 各向异性过滤
    • EnvironmentMap -- 环境光贴图
    • BumpMapping -- 法线贴图
    • 位移贴图

Z-buffering(深度缓冲) Shading(着色)

画家算法

先画最远的物体,逐渐画近的物体,让近的物体覆盖远的物体

看起来是没问题的
在这里插入图片描述
但不是总生效的
在这里插入图片描述
这张图三个三角形互相遮挡,没办法定义深度关系,就不能采用画家算法

Z-Buffer

在这里插入图片描述
既然没办法判断三角形整体的深度,那么就判断每个像素的深度

像素内记录像素深度最浅的几何

对于深度来说,越小越近,越大越远

在渲染时不光要存渲染的图,也要存一张深度的图
在这里插入图片描述
算法如何进行?

对单个像素来说,逐步记录深度

如先画地板,先记录地板深度

物品来了后比对物品的深度和记录的深度

发现物品深度小于记录的地板深度,说明物品要遮挡住地板
在这里插入图片描述
下图一目了然
在这里插入图片描述
暂时假设不存在深度相同的像素

在浮点数的表示中,两个浮点数完全相同的概率很小

(实际上会有相同深度的,但本课中暂不考虑)

(透明物体Z-Buffer也处理不了,暂不考虑)

Shading(着色)

物体产生的颜色和光照、材质有关

Blinn-Phong Reflectance Model(布林·冯反射模型)

在这里插入图片描述
局部着色

对着色的描述是一个点

v、l、n都是单位向量

shininess表面有多亮(对比石膏和陶瓷)

不考虑阴影
在这里插入图片描述

漫反射

同样的光,以不同角度照上去,明暗不一样
在这里插入图片描述

  1. 物体表面法向量n,和光源方向l,的夹角θ,决定了明暗强度

可以把光当成能量,吸收的越多越亮

能量守恒

光的能量都集中在一个球壳上,一开始球壳的表面积很小,考虑到能量守恒的话,那么单位面积上光的能量就很多,光越向外扩散,单位面积的能量就越小
在这里插入图片描述
2. 通过球面公式可以计算出,距离光源为r的球壳上,单位面积上能量为I/r²
在这里插入图片描述
根据2.就知道有多少光从光源传播到shadingPoint处

再根据1.就知道有多少光被shadingPoint吸收

这样就能知道diffuse的公式

在这里插入图片描述

  • I/r² 表示有多少光到达了ShadingPoint(因为光会随着传播距离而衰减)

  • Kd表示了该点颜色的反射率

    如果Kd=0,那么该点完全没有反射光出去,该点吸收了所有光,那么该点表现为黑色

    如果Kd=1,那么该点反射了所有光,那么该点表现为白色

    如果用RGB三个通道表示Kd,那么Kd就是Color

  • Max(0,n·l)表示反射角度,nl都是单位向量,n·l = cosθ,当入射光从表面下面照入,θ>90°,cos<0,这种情况没有意义,因为我们只考虑反射光,不考虑折射等光线,所以需要和0比,取最大值
    在这里插入图片描述

着色高光

高光的方向 -> 越光滑 越趋于镜面反射的方向

观察的方向越接近镜面反射的方向 越能看到高光在这里插入图片描述
当观察方向接近镜面反射方向的时候 <=> 法线方向n 接近于 半程向量h

知道两个单位向量l和v,求他俩的角平分线向量很简单,将两个向量相加,并求归一化

在这里插入图片描述

所以为了知道能否看到高光,布林冯模型只需要知道n和h是否接近

如果用视线方向v和高光方向R来判断能否看到高光,就是冯模型

(点乘接近1即向量接近)(冯模型计算量大)
在这里插入图片描述
向量之间的夹角余弦确实可以衡量两向量是否接近,但容忍度太大了

在一次幂的cos曲线下可看到,当夹角很大时,仍然有很大的值,这样生成的高光就会很大

正常情况下,我们认为高光都是很小很亮的

随着指数增加,能看到在大约0~30°之内才可以看到高光,这样就算一个合理的模型

在布林冯模型下,一般来说,指数选在100-200之间,高光角度大约在3~5°之间,算是比较真实的
在这里插入图片描述

纵向来看,反射系数Ks越大,高光越亮

横向来看,指数p越大,高光越小
在这里插入图片描述

  • 环境光照
    在这里插入图片描述

一个茶杯,在光源并没有直接照射的方向上也有一定的亮度,因为一个光线可以弹射很多次,从四面八方打到任何一个点,这些光照就算是环境光照

由于环境光照非常复杂,这里我们假设一个点受到的环境光照永远都是相同的,强度称为Ⅰa

任何一个点都有自己的颜色,Ka相当于环境光的系数

可以近似的得到一个环境光La = KaⅠa

Blinn-Phong Reflection Model

环境光(无论方向)(常数颜色) + 漫反射(无论观测方向)(光照/法线) + 高光

= 布林冯反射模型
在这里插入图片描述

ShadingFrequencies 着色频率

三个球具有完全相同的空间信息,着色频率不同后表现不一样
在这里插入图片描述

FlatShading(面着色)

在这里插入图片描述

GouraudShading(顶点着色)

在这里插入图片描述

PhongShading(像素着色)

在这里插入图片描述

三种着色频率产生的效果也取决于模型本身
每一行的模型本身顶点数是一样的,越往下顶点数越多
当几何足够复杂时用FlatShading得到的效果也很好
反过来说,当几何的面数大于像素数量时FlatShading的性能也不会好于PhongShading
在这里插入图片描述

如何求逐顶点的法线

将和顶点相邻的面的法向量做加权平均

在这里插入图片描述

如何求逐像素的法线

已知顶点法线,如何求中间某一点的法线---->插值、重心坐标
在这里插入图片描述

图形管线/实时渲染管线

在这里插入图片描述

  • 顶点处理
    将三维空间的点投影在平面上

  • 三角形处理
    将这些点连接形成三角形

  • 光栅化
    将三角形离散成为屏幕上的Fragment(未经处理的像素)

  • 着色
    给像素上色

  • 后处理
    深度缓冲-处理遮挡关系,MSAA等抗锯齿

(以上操作都在硬件中处理好了,也就是gpu工作流程)

  • MVP变换 — 顶点处理
    MVP变换本质上就是将不同的顶点进行变换
    在这里插入图片描述

  • 对像素采样 — 光栅化
    在这里插入图片描述

  • 判定fragment是否可见 — Fragment处理
    Z-Buffer 深度测试
    在这里插入图片描述

  • Shading — 顶点 或 像素处理
    如果用的是GouraudShading,那么进行的就是顶点处理
    如果用的是PhongShading,那么进行的就是像素处理
    在这里插入图片描述

Shader

现代GPU中,这套渲染管线某些部分是可编程的,可以由开发者去定义顶点/像素如何着色

也就是用代码控制如何着色

这部分代码就叫Shader

Shader指定的是每一个像素/顶点如何着色,所以不能也不用去指定某一个像素如何着色

如果写的是顶点操作,这个shader就叫做VertexShader(顶点着色器)

如果写的是像素操作,这个shader就叫做FragmentShader(片段/片元着色器)/PixelShader(像素着色器)

在这里插入图片描述

TextureMapping — 纹理映射

我们希望得到一个三角形,三角形里面映射了一张图片,怎么得到?

Lecture 08 Shading 2 (Shading, Pipeline and Texture Mapping) P8 - 54:46

以球来说,我们发现不同位置有不同颜色,球整体其实公用同一个着色模型,唯一区别就是漫反射系数Kd不同

(Kd忘了的话看Lecture7末尾)

我们希望有一种方法,可以定义一个物体上任意一点的基本属性

3D物体的表面其实都是2D的,比如地球仪,将地球仪上的图撕下来,可以平铺成一张2D的图

物体的表面,通过这种方式可以和一张图有一一对应的关系,这张图就叫纹理

将这张图平铺/裁剪/拉伸到任何物体表面,就叫纹理映射

空间上模型的三角形怎么对应到纹理上的三角形?

由美术同学提供

纹理上的坐标系通常以UV来表示

通常约定U和V的范围[0,1]

当纹理不断重复贴到模型上,可以得到不错的效果,虽然看纹理效果可以看到两张纹理之间有很明显的变化,但是在场景中很自然的无缝衔接

说明这个纹理本身设计的好,这种纹理叫TilableTextures

Shading – 纹理处理

重心坐标

已知三角形顶点的属性,如何在三角形内部进行任何属性的插值?
在这里插入图片描述

  • 在三角形ABC所在的平面中任意一点(x,y),都可以用三角形三个顶点的线性组合来表示
  • ABC顶点前面的系数α + β + γ = 1,(α , β , γ)就是用来描述此三角形的重心坐标
  • 如果点在三角形内α β γ都必须 ≥ 0

(α + β + γ = 1,是为了限制要求的点在平面内)
在这里插入图片描述
根据上述定理可得

A点的重心坐标就是(1,0,0)
在这里插入图片描述

设三角形内一点,点P,连接PA,PB,PC,会形成三个小三角形Aa,Ab,Ac,P的重心坐标就是小三角形面积占大三角形面积的比

α = Aa/(Aa + Ab + Ac)

所以可以求一个特殊的点,三角形重心,三角形重心将三角形划分为三个等面积的小三角形。

所以三角形重心的重心坐标为
在这里插入图片描述
对于三维空间中的点,不能保证其被投影后的重心坐标不变

如果想插值三维空间中的属性,就应该插值三维空间中的坐标。

因为在做光栅化时,需要知道像素中心在三角形的什么位置,此时不能直接求重心坐标进行插值

需要将该点重新投影回三维空间中,在三维空间中计算重心坐标插值

应用纹理

在这里插入图片描述
屏幕上的采样点(x,y)可以用重心坐标算出在纹理中采样的uv,得到对应纹理

纹理放大

当低分辨率纹理应用到高分辨率的屏幕上,纹理就会被拉大。
在这里插入图片描述
对于任意一点,可以找到对应纹理上的位置,位置可能不是整数,将位置坐标四舍五入,然后取纹理上的值

这样的话,一个texel就可能会被映射到多个pixel上,也就说可能在3*3的像素内用了同一个纹理的元素(texel)

这样就会产生马赛克效果如图Nearest

双线性插值

在这里插入图片描述
先用U01 U11插值出来U1
再用U00 U10插值出来U0
再把U0和U1进行插值,得到红点的最终值,即为双线性插值
得到图Bilinear

图Bicubic是将周围16个进行立方插值(双三次插值)

纹理缩小

如果直接简单的使用线性插值进行采样会得到右图,远处有摩尔纹近处有锯齿
在这里插入图片描述
远处的一个像素就会覆盖很大一片的纹理区域,单纯以像素的中心是标准取纹理的值是不对的

这其实就是转变为了采样率不足的问题,之前解决采样率不足的问题我们可以使用SSAA,每个像素内分为若干小像素进行采样。

以512个小像素为例,得到的结果如下图

正确,但花费了512倍的性能

既然采样有问题,那我们如果可以直接查询而不采样呢?

Mipmap

纹理缩小时,一个屏幕上的像素对应了纹理上的多个纹素,使图像看起来就变得模糊。

所以引出了**Mipmap(多级渐远纹理)**技术

将原纹理提前用滤波处理得到很多更小的图像,当物体远离相机时,直接查询较小的纹理,得到正确的结果像素

Mipmap就可以实现我们需要的查询,但仅仅是近似的、正方形的查询
在这里插入图片描述
因为生成了多个较小的图像,需要额外储存生成的小图像

  • 所以Mipmap占用的额外空间是原来的1/3
    这是一种典型的空间换时间的思想

要查询在屏幕空间内的某像素,映射在纹理空间内占多大区域

可以将自己中心和邻居的中心分别投影到纹理空间内,这样就能知道在纹理空间中,该点和邻居点之间的距离L,要求的区域可以近似为以L为边长的正方形区域
在这里插入图片描述
但是会出现不连续的纹理映射,因为查的纹理都是整数层,比如我们无法直接查询1.5层的Mipmap
在这里插入图片描述
所以需要在两层之间进行插值,称为三线性插值
在这里插入图片描述
在这里插入图片描述

各向异性过滤

运用上述Mipmap后,在远处产生的图像很模糊,因为Mipmap是近似的、正方形的查询

只能查询正方形区域,而且三线性插值也是近似
在这里插入图片描述
屏幕上的像素映射到纹理上不一定是正方形,对于不是正方形的Mipmap就无法处理。

如下图,对于右边不是正方形但是是比较规则的矩形,我们可以用其他方法提供查询
在这里插入图片描述
将原图宽度不变长度压缩,长度不变宽度压缩就可以提供矩形的查找,即为各向异性过滤

经常看到的各向异性过滤x2x4等,指的是要生成多少层的压缩图,x2就是一层,x4就是两层。占用的空间逐渐向三倍靠拢
在这里插入图片描述
但各向异性过滤也只是能解决映射在纹理空间是比较规则的矩形的情况,当出现不规则矩形的时候也无法处理
在这里插入图片描述

在这里插入图片描述
所以又引出了EWA过滤,EWA过滤可以将任意形状拆分为很多大小不同的椭圆,经过多次查询,就能查询出最终的结果。

但是代价也是需要多次查询的时间

EnvironmentMap – 环境光贴图

纹理本质上就是提供了一个快捷的查询,不只局限于图像,光照也能同理进行查询
光照贴图认为光照是无限远的,忽略了光的位置信息
在这里插入图片描述
怎样描述环境光?
在这里插入图片描述
如果在房间中有一光滑的金属球,我们观察他就会发现它反射出来的就是环境光。

那我们就可以把环境光储存在球上面,并且也能把它展开成平面

但展开后发现球形图的上下会扭曲。

虽然我们能描述球上不同的位置,但无法均匀的描述
在这里插入图片描述
所以我们可以将信息记录在这个球的外接立方体,这样信息就变得均匀了–CubeMap
在这里插入图片描述
在这里插入图片描述

BumpMapping – 法线贴图

法线贴图是为了在不增加三角形面数的情况下,在着色时显示更多细节
对某一点进行着色时,需要判断该点的法线方向,从而计算光照和颜色
需要从原本的模型表面映射到法线贴图中,查询新的法线位置
在这里插入图片描述
法线贴图如何知道法线的方向呢?

先看一维中的简单示例

  • 先算该点切线
    切线可以用该点与下一个点的位置差计算出来
  • 将切线逆时针旋转90°,求归一化,得到法线
    在这里插入图片描述
    二维的贴图(3D空间)中如何求法线?

对u、v坐标分别求导,算出切线,旋转得到法线
在这里插入图片描述

位移贴图

在这里插入图片描述

环境光遮蔽也能预先计算好,存储到纹理中
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/426434.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

webGL 综合教程100+【目录】

webGL 综合教程100旨在为开发者提供两大方面的知识信息&#xff1a;&#xff08;1&#xff09;提供详细的每个api知识点的详解 &#xff08;2&#xff09;提供实战的示例&#xff0c;提供源代码。 在这量大系统性的知识下&#xff0c;给用户提供清晰的思路和示例参考&#xff0…

IEEE-754 32位十六进制数 转换为十进制浮点数

要将 IEEE-754 32位十六进制数 转换为 十进制浮点数&#xff0c;可以使用LabVIEW中的 Type Cast 函数。以下是一些具体步骤&#xff0c;以及相关实例的整理&#xff1a; 实现步骤&#xff1a; 输入十六进制数&#xff1a;在LabVIEW中&#xff0c;首先需要创建一个输入控制器&am…

传输层协议——udp/tcp

目录 再谈端口号 udp 协议 理解报头 udp特点 缓冲区 udp使用的注意事项 tcp协议 TCP的可靠性与提高效率的策略 序号/确认序号 窗口大小 ACK&#xff1a; PSH URG RST 保活机制 重传 三次握手(SYN) 四次挥手(FIN) 流量控制 滑动窗口 拥塞控制 延迟应答 捎带应答 面…

GPT撰写开题报告教程——课题确定及文献调研

撰写开题报告是一项复杂而重要的任务&#xff0c;需要涵盖从主题选择到文献综述、研究方法等多个环节。借助AI&#xff0c;如ChatGPT&#xff0c;可以显著提高这一过程的效率以及内容的质量。本文将详细探讨如何一步步利用ChatGPT撰写开题报告。 一、开题报告内容 一个清晰的…

[数据集][目标检测]智慧养殖场肉鸡健康状态检测数据集VOC+YOLO格式4657张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;4657 标注数量(xml文件个数)&#xff1a;4657 标注数量(txt文件个数)&#xff1a;4657 标注…

基于SpringBoot的社区宠物管理与推荐系统的设计与实现

文未可获取一份本项目的java源码和数据库参考。 1.课题的基本内容&#xff0c;可能遇到的困难&#xff0c;提出解决问题的方法和措施 2.1课题的基本内容 本课题主要研究基于SpringBoot的社区宠物管理与推荐系统的设计与实现。用户注册登录系统前端后可以可以实现对宠物信息的…

保护您的隐私:隐藏 IP 地址的重要性

在当今的数字时代&#xff0c;我们的在线隐私和安全变得比以往任何时候都更加重要。浏览互联网时保护自己的一种方法是隐藏您的 IP 地址。 但是为什么要隐藏您的 IP 地址以及如何有效地做到这一点&#xff1f; 隐藏您的 IP 地址有助于保护您的在线匿名性。您的 IP 地址就像您的…

vscode技巧-eslint配置

开发环境 jsvue3axios 下载插件 Eslint、Prettfier 配置过程 1.配置eslint 进入settings&#xff0c;输入eslint&#xff0c;在settings.json中替换一下文件 // #每次保存的时候自动格式化 {"editor.codeActionsOnSave": {"source.fixAll.eslint": &…

低代码开发平台系统架构概述

概述 织信低代码开发平台&#xff08;产品全称&#xff1a;织信Informat&#xff09;是一款集成了应用设计、运行与管理的综合性平台。它提供了丰富的功能模块&#xff0c;帮助用户快速构建、部署和维护应用程序。织信低代码平台通过集成丰富的功能模块&#xff0c;为用户提供…

国产分布式数据库-tidb单机部署文档

tidb单机部署文档 1、创建用户 #创建用户 useradd tidb #设置密码 passwd tidb2、配置免密码登录 编辑/etc/sudoers文件,文末加入&#xff1a; tidb ALL(ALL) NOPASSWD:ALL如果想要控制某个用户(或某个组用户)只能执行root权限中的一部分命令, 或者允许某些用户使用sudo时…

游戏各个知识小点汇总

抗锯齿原理记录 SSAA&#xff1a;把成像的图片放大N倍&#xff0c;然后每N个点进行平均值计算。一般N为2的倍数。比如原始尺寸是1000x1000&#xff0c;长宽各放大2倍变成2000x2000。 举例&#xff1a; 原始尺寸&#xff1a; 放大2倍后 最后平均值计算成像&#xff1a; MSAA&…

[OpenCV] 数字图像处理 C++ 学习——14霍夫变换直线、圆检测 附完整代码

文章目录 前言1.霍夫变换原理(1)霍夫变换检测直线的原理(2)霍夫变换检测圆的原理 2.代码实现(1)霍夫直线检测(2)霍夫圆检测 3.完整代码 前言 霍夫变换是一种有效的检测图像中的几何形状&#xff08;如直线、圆等&#xff09;的算法。霍夫变换通过将几何形状的检测问题转化为参…

python学习第十节:爬虫基于requests库的方法

python学习第十节&#xff1a;爬虫基于requests库的方法 requests模块的作用&#xff1a; 发送http请求&#xff0c;获取响应数据&#xff0c;requests 库是一个原生的 HTTP 库&#xff0c;比 urllib 库更为容易使用。requests 库发送原生的 HTTP 1.1 请求&#xff0c;无需手动…

引领智能家居新风尚,WTN6040F门铃解决方案——让家的呼唤更动听

在追求高效与便捷的智能家居时代&#xff0c;每一个细节都承载着我们对美好生活的向往。WTN6040F&#xff0c;作为一款专为现代家庭设计的低成本、高性能门铃解决方案&#xff0c;正以其独特的魅力&#xff0c;悄然改变着我们的居家生活体验。 芯片功能特点&#xff1a; 1.2.4…

关于订单信息的Excel数据分析报告

提升自己&#xff0c;掌握数据分析的能力&#xff0c;最快的方式就是实践&#xff01; 这里又是一个Excel数据分析项目的分析报告&#xff0c;有需要项目配套数据集的可以关注私信我免费获取(●◡●)

Skytower

一、安装配置靶机 下载地址: SkyTower: 1 ~ VulnHub 下载之后解压发现是VirtualBox格式的 我们下载一个VirtualBox&#xff0c;这是官网 Downloads – Oracle VirtualBox 安装到默认路径就 打开后点击注册 选择解压后的vbox文件 然后点击左上角管理 点击导出虚拟电脑&…

MUNIK谈ASPICE系列专题分享(十)ASPICE配置管理如何做

前言&#xff1a; ASPICE&#xff08;Automotive Software Process Improvement and Capability dEtermination&#xff09;是一种用于评估汽车行业软件开发过程成熟度的模型。配置管理是ASPICE中的一个关键过程领域&#xff08;KPA&#xff09;&#xff0c;它涉及到对软件项目…

【Linux篇】Http协议(1)(笔记)

目录 一、http基本认识 1. Web客户端和服务器 2. 资源 3. URI 4. URL 5. 事务 6. 方法 7. 状态码 二、HTTP报文 1. 报文的流动 &#xff08;1&#xff09;流入源端服务器 &#xff08;2&#xff09;向下游流动 2. 报文语法 三、TCP连接 1. TCP传输方式 2. TCP连…

Vue3.0组合式API:使用defineEmits()实现子组件向父组件传递数据

1、使用 defineEmits() 函数 父组件通过使用 Prop 为子组件传递数据&#xff0c;但如果子组件要把数据传递回去&#xff0c;就需要使用自定义事件来实现。父组件可以通过 v-on 指令&#xff08;简写形式“”&#xff09;监听子组件实例的自定义事件&#xff0c;而子组件可以通…

高密原型验证系统解决方案(下篇)

0 引言 我们在上篇中和大家探讨了用户在进行大规模 复杂 SoC 设计原型验证时在全局时钟及复位同步&#xff0c; 大规模设计分割以及高速接口与先进 Memory 控制 器 IP 验证等方面遇到的关键困难&#xff0c;并提出了相应的 解决方案帮助用户来克服这些困难。接下来我们会 和用户…