Games101图形学笔记——着色

news2024/9/21 5:39:33

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.coloradmin.cn/o/2144617.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Cpp输出多字符常量警告

Cpp输出多字符常量警告 Cpp中用单引号(single quotes)表示单个字符(single character)&#xff0c;例如a&#xff0c;$&#xff0c;用双引号(double quotes)表示字符串文本(text)&#xff0c;例如"Hello World! " 当在一个单引号里面存在多个字符时&#xff0c;Cpp…

怎么增加音频的音量?这几种方法可以轻松增加音频的音量!

怎么增加音频的音量&#xff1f;在日常生活的纷繁场景中&#xff0c;音频音量偏低的问题往往悄然成为我们不可忽视的困扰&#xff0c;它虽非重大难题&#xff0c;却能在关键时刻带来诸多不便与挑战&#xff0c;设想一下&#xff0c;在喧嚣的街头或拥挤的咖啡馆里&#xff0c;微…

ES分词导致查询结果不准确

问题现象 索引里面有数据&#xff0c;而没有查询出来。 如下图所示&#xff0c;术语库&#xff08;索引&#xff09;中里面有一条数据的原文是“层”&#xff0c;而根据完整的原文来查询该原文中的术语&#xff0c;并未将该术语查询出来。 根据原文查询该原文中的术语&#x…

FreeRTOS学习——接口宏portmacro.h

FreeRTOS学习——接口宏portmacro.h&#xff0c;仅用于记录自己阅读与学习源码 FreeRTOS Kernel V10.5.1 portmacro版本&#xff1a;GCC/ARM_CM7 portmacro.h是什么 portmacro.h头文件&#xff0c;用于定义与特定硬件平台相关的数据类型和常量。 在移植过程中&#xff0c;…

VulhubDC-4靶机详解

项目地址 https://download.vulnhub.com/dc/DC-4.zip实验过程 将下载好的靶机导入到VMware中&#xff0c;设置网络模式为NAT模式&#xff0c;然后开启靶机虚拟机 使用nmap进行主机发现&#xff0c;获取靶机IP地址 nmap 192.168.47.1-254根据对比可知DC-4的一个ip地址为192.1…

无人机光电吊舱的技术!!

1. 成像技术 可见光成像&#xff1a;通过高分辨率相机捕捉地面或空中目标的清晰图像&#xff0c;提供直观的视觉信息。 红外热成像&#xff1a;利用红外辐射探测目标的温度分布&#xff0c;实现夜间或恶劣天气条件下的隐蔽目标发现。 多光谱成像&#xff1a;通过不同波段的光…

日用百货小程序如何渠道经营开店

将货更多的卖出去是每位商家的心声&#xff0c;日用百货商家手中的货具备多样性&#xff0c;挑选的用户也多&#xff0c;由于货单价较低&#xff0c;因此不断获客并其多买/复购/留存/裂变等是长期发展的关键点。 如何获得更多经营渠道&#xff0c;线上找寻出路是方法之一&…

ROS和ROS2借助智能大模型的学习和研究方法

机器人相关知识的本身和价值-CSDN博客 知识本身在智能时代毫无价值&#xff0c;需要基于知识应用和创新才有价值。 学历报废并非来自扩招&#xff0c;而是智能模型的快速发展。-CSDN blink-领先的开发者技术社区 2024年中秋&#xff0c;智能模型实力已经如此&#xff0c;但还…

智算筑基,九章云极DataCanvas公司闪耀2024年服贸会

9月12日&#xff0c;2024年中国国际服务贸易交易会&#xff08;以下简称“服贸会”&#xff09;在北京隆重开幕&#xff0c;九章云极DataCanvas公司携AI智算产品系列深度参展本届服贸会&#xff0c;为观众奉上技术与应用深度融合的参展盛宴。 本届服贸会由中华人民共和国商务部…

文心一言 VS 讯飞星火 VS chatgpt (349)-- 算法导论23.2 8题

八、Borden教授提出了一个新的分治算法来计算最小生成树。该算法的原理如下:给定图 G ( V , E ) G(V,E) G(V,E)&#xff0c;将 V V V划分为两个集合 V 1 V_1 V1​和 V 2 V_2 V2​&#xff0c;使得 ∣ V 1 ∣ |V_1| ∣V1​∣和 ∣ V 2 ∣ |V_2| ∣V2​∣的差最多为1。设 E 1 E_…

2.使用 VSCode 过程中的英语积累 - Edit 菜单(每一次重点积累 5 个单词)

前言 学习可以不局限于传统的书籍和课堂&#xff0c;各种生活的元素也都可以做为我们的学习对象&#xff0c;本文将利用 VSCode 页面上的各种英文元素来做英语的积累&#xff0c;如此做有 3 大利 这些软件在我们工作中是时时刻刻接触的&#xff0c;借此做英语积累再合适不过&a…

【每日刷题】Day124

【每日刷题】Day124 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. LCR 079. 子集 - 力扣&#xff08;LeetCode&#xff09; 2. 1863. 找出所有子集的异或总和再求和 …

超详细超实用!!!零基础java开发之云风笔记接口开发之删除笔记(十一)

云风网 云风笔记 云风知识库 一、service/NoteApi新增delNode接口定义 public interface NoteApi {...int deleteNote(NoteManage noteManage); }二、service/impl/NoteServiceImpl接口实现逻辑 public class NoteServiceImpl implements NoteApi {AutowiredNoteMapper note…

LVM硬盘挂载

LVM硬盘挂载 一、基础概念 sda/sdb/nvme0n1/nvme0n2&#xff1a; 硬盘的命名方式&#xff0c;中括号的字母为第三位按不同硬盘的加载顺序排序。sda1/sda2/sdb1&#xff1a; 第4位为分区号&#xff0c;数字为不同分区的依序命名lvm: LVM是一种逻辑卷管理器&#xff0c;允许管理…

springboot实战学习笔记(2)

目录 1、手动创建springboot工程&#xff0c;选择Maven构建。 2、Maven生成的&#xff0c;可能需要再main目录下new一个resources目录&#xff0c;再在其下目录new一个配置文件。 3、 pom文件中让当前的工程继承父工程依赖&#xff1a;、删去无用依赖。 4、引入后端环境所需要的…

STL,智能指针和线程安全,线程安全的单例模式和懒汉饿汉的实现,以及读者写者问题

&#x1f351;个人主页&#xff1a;Jupiter. &#x1f680; 所属专栏&#xff1a;Linux从入门到进阶 欢迎大家点赞收藏评论&#x1f60a; 目录 &#x1f4da;STL&#xff0c;智能指针和线程安全 &#x1f4d5;STL中的容器是否是线程安全的?&#x1f4a1;智能指针是否是线程安全…

【C语言零基础入门篇 - 7】:拆解函数的奥秘:定义、声明、变量,传递须知,嵌套玩转,递归惊艳

文章目录 函数函数的定义与声明局部变量和全局变量、静态变量静态变量和动态变量函数的值传递函数参数的地址传值 函数的嵌套使用函数的递归调用 函数 函数的定义与声明 函数的概念&#xff1a;函数是C语言项目的基本组成单位。实现一个功能可以封装一个函数来实现。定义函数的…

图片转PDF技巧揭秘:四款高效工具推荐!

在数字化办公和学习的今天&#xff0c;将图片或其他文件格式转换为PDF已成为一种常见需求。以下是几款推荐的转换工具&#xff0c;它们各自具有独特的功能和使用体验&#xff0c;可帮助大家轻松实现图片转PDF及其他PDF相关操作。 福昕PDF转换大师&#xff08;365客户端&#x…

关于 Qt运行加载内存较大崩溃添加扩大运行内存 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/142341544 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

【重学 MySQL】三十三、流程控制函数

【重学 MySQL】三十三、流程控制函数 IF函数IFNULL函数CASE函数总结 在MySQL中&#xff0c;流程控制函数是用于在SQL查询、存储过程或函数中根据特定条件执行不同流程的重要工具。这些函数可以帮助我们实现复杂的逻辑判断和数据转换。 IF函数 IF函数是MySQL中最基本的流程控制…