什么是Shader(shader编程可以干什么)「建议收藏」

什么是Shader(shader编程可以干什么)「建议收藏」编辑导语:作为一名产品设计师,你知道计算机是如何实时理解和渲染3D项目的吗?相信你已经被这个问题困扰了。在这篇文章中,作者总结了相应的理论问题,这可能有助于你突破三维和H5之间的障碍。 前言设计师将…

大家好,我是讯享网,大家多多关注。

编辑导语:作为一名产品设计师,你知道计算机是如何实时理解和渲染3D项目的吗?相信你已经被这个问题困扰了。在这篇文章中,作者总结了相应的理论问题,这可能有助于你突破三维和H5之间的障碍。

和所有前端神仙一起做项目,也一起撞见了对爱与痛的理解。总而言之,我希望通往H5的3D道路将成为一条通途。

本手册主要分为两部分:

Part 1理论:主要是让设计师了解计算机是如何真正理解并实时渲染我们设计的3D项目,以及three.js材质与预期材质的对应关系。

第二部分实践:基于three.js的实现,提供场景、制作纹理贴图的思路、gltf工作流程,动态讨论项目中经常遇到的复原问题。

本文主要针对初学3D图形的设计师,只截取最常用的理论知识与大家一起学习。

一些涉及技术艺术或计算机图形的描述可能不严谨。希望大家多交流,多讨论。

其实H5开发不管用哪个webGL,设计相关的资料基本都是基于PBR思路做的,所以我建议你可以看看《PBR指南》这本官方的实体宝典。

理论篇

设计师在还原3D互动H5项目时,一定思考过宇宙的终极问题:为什么H5/Web实现的3D效果与C4D渲染的如此不同?

其实这是我们对实时渲染引擎(UE,Unity,three.js等)区别的误解。)和离线渲染工具(Redshift、Octane、Vray等。).第一,离线渲染工具是基于真实的光照环境来计算每个像素的颜色,而实时渲染如果要达到这个效果,模拟光照就需要更多的硬件基础和计算能力(没有好的显卡是开不了的)。

虽然UE5的实时渲染技术和硬件兼容性让大家大吃一惊,但是在实际项目中渲染能力还是比较有限,尤其是H5,需要兼容低端设备。第二,对于游戏或H5互动网站的实际应用来说,流畅的交互体验往往优先于屏幕精细度,因此牺牲视觉性能是常见的。

OCE离线渲染效果VS three.js实时渲染效果

材质细节、全局光照和投影、抗锯齿性能都有明显的区别。

当实时渲染效果与设计预期差距过大时,设计者可以多了解一些计算机图形学的基础知识,或许可以更好地与开发同学讨论性价比高的可视化实现和资源优化方案(以及更多的战斗筹码)。

1. 着色器与着色算法差异(靴靴微硬核预警)

首先要知道,计算机之所以能在2D屏幕上绘制出3D图像,是因为有一个着色器绘图,它用光照信息将我们3D 空空间中的模型进行转换,栅格化成2D图像。在计算机图形学中,着色器是一个用于处理图像材质(光照、亮度、颜色)的程序。

常用的着色器分为四种类型:像素/片段着色器、顶点着色器、几何着色器和镶嵌着色器。

像素/片段着色器和顶点着色器都在webGL处理中使用。顶点着色器首先转换和组装模型中每个顶点的位置、纹理坐标、颜色等信息,然后片段着色器将3D信息光栅化并转换为2D屏幕信息。(对于着色器差异,感兴趣的同学可以直接跳到附录。)

着色器如何将顶点中的光照、纹理和其他信息转换和重建为2D图像的像素?GPU由不同的着色算法实现。

一种是对每个三角形进行插值。这种方法称为逐顶点照明,但是当三角形很大时,插值不够精确。这时可以用另一种方法,逐像素光照,来计算每个像素的光照信息,这样可以达到更好的渲染效果,但往往会带来更多的计算量。

有三种常见的计算机图形着色算法:平面着色、Gouraud着色和Phong着色。虽然这些算法看起来和我们设计师没什么关系,但其实我们后面了解three.js素材的时候,就会发现它们在渲染上的不同。

Flat染色法、Gouraud染色法和Blinn-Phong染色法的比较[F1,️stefano·谢吉]

1)用平面着色法进行平面着色

这种着色方法认为模型中的所有面都是平面,同一多边形上任意点的法线方向都是相同的。着色时,将首先选择多边形的第一个顶点或三角形的几何中心来计算颜色。在实践中,这种着色方法的效果与低表面模型非常相似,也适用于高速渲染场景。值得注意的是,这种上色方法很难做出平滑的高光。

2)用Gaulod平滑着色法进行Gouraud着色

这是一种平滑的着色方法。着色时,会先计算三角形各顶点的光照特征,用双线插值法填充三角形区域内其他像素的颜色。与平面明暗法相比,这种明暗法增加了插值的细节,在渲染单个像素的光照特性方面也比Phong明暗法有更高的性能。

但是,在渲染高光时,由于无法获得准确的光照值,可能会出现一些不自然的过渡(或者丁字接头容易绘制错误)。这时候可以考虑细分模型或者使用漫反射材质。

3)Phong平滑着色法Phong明暗法

与Gouraud着色不同,它对顶点的法线进行插值,并通过每个像素的法线向量来计算照明特征。这种方法可以画出精致精确的曲面,但需要大量的计算。Blinn-Phong是Phong的高级版本,着色性能更好,高光分散更自然。

2. 基本光照模型 Illumination Model

在了解了简单的计算机如何绘制3D图形之后,我们来看看它是如何具体理解我们设计的3D场景的。

在将3D转换为2D的过程中,也就是3D光栅化的过程中,每个像素的颜色都需要基于其所处的环境进行计算,基于渲染对象表面某一点的光照强度计算模型称为光照模型或光线模型。通过计算光照模型获得表面位置对应的像素颜色的过程称为表面渲染。

*请注意,这里所说的光照模型并不是指设计师所理解的3D立体模型,而是指模型物体表面光照效果的数学计算模型。

影响光照模型的因素有两个,一个是光学特性(颜色反射系数,表面纹理,透明度等。)由渲染对象本身设置,另一个是场景中的光源和环境光(场景中每个被照亮对象的反射光)。

传统的照明模型是漫反射和镜面反射的理想化模拟。为了恢复基于真实物理世界的效果,照明模型需要遵循能量守恒定律:物体可以反射的光必须小于它接收到的光。实际上,漫反射更强、更粗糙的物体会反射更暗、更宽的高光,反之亦然。

基于PBR的光模型应该遵循能量守恒定律[F2,️joe·威尔森]。

在不同的渲染要求下,光照模型和明暗处理的组合将有不同的应用:

真实感渲染(Photorealistic Rendering):目的是基于真实物理世界对3D场景进行仿真还原。非真实感渲染(Unphotorealistic Rendering):也被成为风格化渲染(Stylistic Rendering),会更抽象化地对模型进行重绘。照片级真实渲染和照片级真实渲染的比较[F3,️Autodesk]

1)照片真实感渲染照片真实感渲染

考虑到真实感渲染对硬件的依赖,目前webGL中一般采用简单的局部光照模型(只计算光源对物体的光照效果,不计算物体之间的相互作用,我们看到的“假反射”通常是通过贴图模拟的)。根据反射形式,经典的照明模型如下:

朗伯漫反射模型;

这种模型的粗糙表面(如塑料、石头等。)会从各个方向反射反射光,这种光反射也叫漫反射。理想的漫反射器通常被称为朗伯反射器,这是我们熟悉的橡胶材料。

漫反射模型与其他光照模型的比较[F4,️ViroCore]

Phong镜面反射模型;

这是一个基于实验和观察的非物理模型。其表面反射兼具粗糙表面漫反射和光滑表面镜面反射,但Phong模型在高光下存在过渡缺陷。

Phong镜面反射模型的视觉构成[F5]

Blinn-Phong模型:

它是OpenGL和Direct3D中的默认着色模型,direct 3d是一种优化的非物理Phong模型。顶点之间的像素插值使用Gouraud明暗算法,比Phong明暗算法性能更好,高光效果更平滑。

Phong和Blinn-Phong镜面反射模型的比较[F6]

库克-托伦斯/GGX照明模型:

如果你使用了默认的C4D渲染器,你一定在材质的反射通道设置中看到过它们。

这是一个比较高级的光照模型,不同于Phong和Blinn-Phong模型,它们只是理想化了漫反射和镜面反射。这两种光照模型基于不同的物理材质加入了Microfacet的概念,并考虑了表面粗糙度对反射的影响,优化了镜面反射,使得高光的长尾分散更加自然。它也是目前PBR渲染管道(Unity,UE)中常用的光照模型。

Phong、Blinn-Phong和GGX镜面反射模型的比较[F7,️ridgestd]

地下散射地下散射/SSS模型;

最后,设计师之间有一个共同的理念。次表面散射是指光线穿透不透明物体(皮肤、液体、毛玻璃等)时的散射现象。).现实中大多数物体都是半透明的,光线会先穿透物体表面,然后在物体中被吸收,多次反射,然后在不同的点穿过物体。以皮肤为例,只有6%左右的反射是直接反射,而94%的反射是次表面散射。

BSSRDF(双向次表面反射分布函数)是一种用于描述介质内部入射光的光照模型,在最新的虚拟角色皮肤实时渲染中也有使用。但是由于SSS材质的计算依赖于深度/厚度数据,所以webGL对这种高级灯光效果的还原程度还是比较有限的。

在Unity中模拟次表面散射照明模型效果[F8,️alan·祖科尼]

2)非真实感渲染-NPR

也就是我们常说的3底纹2,非写实的渲染风格,是从人们对2D绘画或者3D场景的自然媒体材质的需求演变而来的。因此,非真实感渲染技术实际上是不同光照模型和不同明暗处理的风格化输出。目前在动漫和游戏中也有广泛应用。例如,《英雄联盟:双城战,蜘蛛侠:平行宇宙》就是一部顶级的三重着色杰作。

真实感渲染和真实感渲染在不同通道中的混合应用[F9,多边形跑道]

网格阴影/卡通阴影:

卡通上色,最常见的用3D技术模拟平面风格的上色形式,通常以极简色彩、渐变、轮廓清晰等卡通元素为特点。

搅拌机中不同类型的卡通着色器效果[F10,搅拌机NPR]

日本创意程序员中野美崎制作了一个非常有趣的卡通阴影H5互动页面。您可以体验不同着色形式的非凡模型的视觉表现。搜索:https://mnmxmx.github.io/toon-shading/dst/index.html

中野美崎的卡通着色器互动网站[F11,中野美崎]

自定义底纹:

目前,越来越多的渲染器可以支持设计师和工程师根据项目需求定制着色,从而产生更加风格化和艺术化的着色效果。比如工业插画中常用的古奇底纹,以及影线着色、油画和水墨画等更具绘画质感的自然媒介着色,已经深入到我们的日常创作中。

在Unity中,基于真实感渲染的贴图效果与NPR水墨的风格化上色效果进行了对比[F11,邓佳迪]

3. Three.js 材质着色对比

说完了真实感渲染和照片级渲染的区别,我们再来看看Three.js中的材质

和很多渲染引擎一样,除了原生材质之外,webGL的材质和着色都可以根据需求定制,但这往往会带来高昂的开发成本和兼容性风险。考虑到H5项目的实际应用场景,下表列出了Three.js的原物料对比,包括物料特性的优势、质感的差异、适用场景等。您可以根据项目要求快速选择和混合它们:

three.js材料对比表

4. 色彩描述与管理 Color Space

虽然着色、光照模型、材质渲染对3D性能的影响最为直观,但3D工作流程中还有一个秘密且关键的环节——色彩管理。

在现实世界中,根据物理定律,如果光的强度增加一倍,亮度也会增加一倍,这是一个线性关系。理想情况下,显示屏上像素的亮度也应该是线性的,这样才符合人眼对现实世界的观察效果(如图B:横坐标是像素的物理亮度,纵坐标是像素显示时的实际亮度)。

但由于电压的影响,输出亮度与电压的关系是亮度等于电压的1.7-2.3次方的非线性关系,导致当电压线性变化时,在较暗的地方亮度变化较慢。如果不校正显示,暗的地方颜色会整体变暗(如图C)。目前大多数显示器的Gamma值在2.2左右,所以可以理解为Gamma2.2是所有显示器固有的遗传病。

上曲线=γ0.45 = sRGB空间绿色下曲线=γ2.2 =显示器真实成像缺陷=蓝色对角线=γ1.0 =线性空间真实物理世界线性关系为了修正显示器的非线性问题(从图C到图B),我们需要对其进行2.2次方的逆运算(如图A)。数学上这是一个0.45左右的幂运算(Gamma0.45经过0.45幂运算和显示器2.2幂输出,最终颜色与实际实物一致空。这组校正操作是伽马校正。

而我们常见的sRGB就是Gamma0.45所在的color room 空,这是微软和惠普在1996年联合开发的标准color room 空。照片素材一开始存放在sRGB空时,相当于带了一个γ0.45的遗传病抗体,当它被监视器显示时,会自动中和监视器γ2.2的缺陷,从而呈现出与物理世界一致的亮度。

校正的另一个原因是人眼对光的敏感度不是线性的。人对暗区更敏感,对亮区不太敏感。而且人眼感知的光强正好与光的物理强度成对数关系。为了在暗部呈现更多人眼可感知的细节,像素的实际亮度会高于其在Gamma0.45的color 空空间中的物理亮度(如图A)。

人眼感知的光强与发射光的实际物理强度的比较

上面那段确实有点绕路,不过话说回来,为什么渲染的时候建议用线性空空间?因为在计算机图形学中,着色器的操作基本上都是基于物理世界的光照模型来保证渲染的真实性。如果模型的纹理输入值是非线性的(sRGB),那么运算的前提就不是统一的,输出结果自然就不那么真实。

在大多数工作流和渲染软件中,大部分贴图资源默认导出到sRGB(设计师的绘图环境一般在sRGB,所见即所得),而法线贴图、光照贴图等纹理(纯数值纹理,仅用于计算)是线性的。这部分需要我们根据渲染引擎本身的特点来判断不同的地图是否需要不同的“去抠图”过程(WebGL,Unity

对所有贴图进行去Gamma并统一为Linear空后,引擎会在渲染输出时统一进行Gamma校正。这时显示屏上会显示出接近真实世界的效果。

更多色彩之间的实际效果对比空,可以看看Unity的文档:线性/伽玛渲染对比:

https://docs . unity 3d . com/Manual/linear rendering-linearorgammaworkflow . html

回到H5使用的Three.js,默认情况下它的着色器计算也是在Linear空之间。如果在最终渲染中没有转换为sRGB,设备显示时可能会导致颜色失真。three.js中色彩管理的工作流程会根据导入模型资产的不同而不同。如果将地图和模型分别导入到场景中,建议尝试以下过程:

1)将贴图数据sRGB输入到线性:将带色贴图(基础材质、环境、光照)设置为sRGB (texture.encoding = sRGB编码),或者将渲染设置renderer.gammaInput设置为True,这样可以将原来的srgb贴图转换为线性,而原来的纯数值贴图(法线、凹凸等。)保持线性;该操作可以保证地图输入数据的正确性和统一性。

2)刷新物料:物料编码类型修改后,需要将Material.needsUpdate设置为True来重新编译物料。

3)线性输出渲染到sRGB:校正渲染输出值的伽马:renderer.gamma output = truerenderer.gammaFactor = 2.2以便显示屏能够正确显示颜色。

“第一部分-理论”先告一段落。如果偶尔失眠,建议可以反复咀嚼延伸阅读内容。

Part2- Practice将继续完善three.js的场景、制作纹理贴图的思路、gltf工作流程,并动态讨论项目中经常遇到的修复问题。

2022年,我们需要再次见到你。

附录

1)着色器差异

①像素着色器像素着色器

也称为片段着色器,是一种二维着色器。它记录每个像素的颜色、深度和透明度信息。最简单的像素着色器可用于记录颜色。像素着色器通常使用相同的色标来表示照明属性,以实现凹凸、阴影、高光、透明和其他贴图。同时,它们也可以用来修改每个像素的深度(Z缓冲)。

但是,在3D图像中,像素着色器可能无法实现一些复杂的效果,因为它只能控制独立的像素,并且不包含场景中模型的顶点信息。但是像素着色器有屏幕的坐标信息,可以根据屏幕或者相邻像素的材质进行采样和增强,比如Cel着色器的边缘增强或者一些后期的模糊效果。

②顶点着色器Vextex着色器

是最常见的3D着色器,记录了模型每个顶点的位置、纹理坐标、颜色等信息。它将每个顶点的3D位置信息转换成2D屏幕坐标。顶点着色器可以处理位置、颜色和纹理的坐标,但不能添加新的顶点。

③几何着色器几何着色器

是一个新兴的着色器,在Direct3D 10和Open GL3.2中都有引用,这个着色器可以在图元之外生成新的顶点,这些顶点可以转换成新的图元(如点、线、三角形等。),而且它的优点是可以直接在明暗处理中添加模型细节,从而减轻CPU负担。设置着色器的常见场景包括点精灵生成(粒子动画)、细分曲面、体积阴影等。

④镶嵌着色器镶嵌着色器

出现在OpenGL4.0和Direct3D 11中,可以在图元中嵌入更多的三角形。传统模型中增加了两个新的着色步骤(一个是细分控制着色,也称为Hull Shader,另一个是细分评估着色,也称为Domain Shader)。两者结合可以使简单模型快速获得细分曲面。(比如细分曲面效果加置换贴图的模型,可以获得极其逼真细腻的模型)

2)对一些术语的简单理解

Gl:图形库,图形函数库。

GL: Web Graphics Library,一个Html 5可访问的3D绘图协议/函数库,可以为H5画布的3D渲染提供各种API。

z缓冲:

深度缓冲区:当3D图像被着色时,每个生成像素的深度将被存储在缓冲区中。如果另一个对象也在同一个像素产生渲染结果,那么GPU会比较两个对象的深度,优先渲染距离较近的对象。这个过程被称为Z剔除。当两个对象相互靠近(16位)时,可能会出现Z斗,即重叠闪烁。使用24位或32位缓冲区可以有效缓解。

渲染管道:

渲染管道/渲染管道/像素管道,是GPU的处理工作流程,是GPU为图形分配颜色的特殊通道。管道越多,画面越流畅,越漂亮。

呈现管道详细信息工作流[F12]

光栅化:

栅格化/栅格化/栅格化是将流水线处理的图元转换成屏幕上可见的一系列像素。该过程包括图元组装、三角形遍历、像素处理和合并。

3)参考文献+延伸阅读

[1]赫恩博士和贝克议员,2004年。计算机图形学与OpenGL,第四版计算机图形学。新泽西州上马鞍河:皮尔森普伦蒂斯霍尔。

[2]t .阿克宁-默勒、e .海恩斯和n .霍夫曼,2019年。实时渲染。Crc出版社。

[3]瑞·孟瑞,经典照明模型。

https://blog.csdn.net/qq_34552886/article/details/79089418

[4]克利须那瓦米,A;GVG巴罗诺斯基(2004年)。“基于生物物理学的光与人类皮肤相互作用的光谱模型”(PDF)。

[5]常用着色算法列表:

https://en . Wikipedia . org/wiki/List _ of _ common _ shading _ algorithms

[6] 0渴望0,解析虚幻引擎对超现实人体的渲染技术第一部分——概览与皮肤渲染

https://www.cnblogs.com/timlly/p/11098212.html

[7]毛星云,【提炼总结《实时渲染3号》】(10)第11章。非真实感绘制相关技术综述(NPR)

https://zhuanlan.zhihu.com/p/31194204

[8]一个吵闹的仙女,局部光照模型的杂注[兰伯特/冯/布兰-冯/BRDF/bs SRF/库克-托伦斯]

https://www.jianshu.com/p/96ca495669d6

[9] Puppet _ Masterterm,Unity Shader-Mat Cap(材质捕捉)

https://blog . csdn . net/puppet _ master/article/details/83582477

[10] WestLangley,关于伽马校正的文件不正确?#11110

https://github.com/mrdoob/three.js/issues/11110

[11] donmccurdy,色彩管理的最佳实践

https://github.com/aframevr/aframe/issues/3509

https://github . com/mrdoob/three . js/issues/11337 # issue comment-440795075

[12] alteredq,关于在WebGL渲染器#1488中使用伽马校正的问题

https://github.com/mrdoob/three.js/issues/1488

[13] Friksel,gammaFactor是怎么回事?

https://discourse . three js . org/t/whats-this-about-gamma factor/4264/3

[14] pzzb,线性空间闪电,伽马,sRGB细节:

https://zhuanlan.zhihu.com/p/66558476

[15]学习OpenGL,伽玛校正

https://learnopengl.com/Advanced-Lighting/Gamma-Correction

[16]柯灵杰,三维图形基础:

https://zhuanlan.zhihu.com/p/27846162?来源= post _ page——B1 CDE 1 f 23 ADF—————

[17] Klayge游戏引擎,关于D3D11你必须知道的几件事(3)

http://www.klayge.org/? p = 1404

[18]先锋狗,GPU渲染流水线介绍

https://zhuanlan.zhihu.com/p/61949898

[19]史蒂夫·贝克,学会爱你的Z缓冲器。

https://www.sjbaker.org/steve/omniv/love_your_z_buffer.html

20史蒂夫·贝克,阿尔法混合和Z缓冲区。

https://www.sjbaker.org/steve/omniv/alpha_sorting.html

[21]微软,Direct3D 11图形-镶嵌阶段

https://docs . Microsoft . com/en-us/windows/win32/direct 3d 11/direct 3d-11-高级-stages-tessellation # domain-shader-stage

[F1] Stefano Scheggi,平面底纹与Gouraud底纹和Blinn-Phong底纹

https://www.youtube.com/watch? v = VR w3 guvdldo

乔·威尔森,基于物理的渲染,你也可以!

https://marmoset . co/posts/basic-theory-of-physical-based-rendering/

[F3] Autodesk,应用视觉效果

https://download . Autodesk . com/us/mudbox/help 2011 _ 5/index . html?url=。/files/ws1a 9193826455 F5 ff 5 cf 1d 02511 B1 d 000978-6b 44 . htm,topicNumber=d0e8759

[F4] Virocore,照明和材料

https://viro core . viro media . com/v 1 . 0 . 0/docs/3d-场景照明

[F5]维基百科,Phong反射模型

https://en.wikipedia.org/wiki/Phong_reflection_model

[F6]维基百科,Blinn–Phong反射模型

https://en . Wikipedia . org/wiki/Blinn % E2 % 80% 93 Phong _ reflection _ model # cite _ note-4

[F7] Ridgestd,从微法到GGX反射模型

http://ridgestd.github.io/2019/03/18/ggx-shader/

[F8]艾伦·祖科尼,Unity中的快速地下散射(第二部分)

https://www.alanzucconi.com/tag/sss/

[F9]多边形跑道,卡通着色教程搅拌机2.8与评论

https://www.youtube.com/watch?五世= kriKwtzZWFg

[F10]搅拌机npr,基本卡通着色器与搅拌机

]http://blender NPR . org/basic-toon-shaders-with-blender-internal/

[F11]邓佳迪,水墨风格统一的3D渲染尝试

https://zhuanlan.zhihu.com/p/25346977

[F12]维基百科,图形管道

https://en.wikipedia.org/wiki/Graphics_pipeline

本文由@腾讯ISUX原创发布。每个人都是产品经理。未经许可,禁止复制。

题目来自Unsplash,基于CC0协议。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。
本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://51itzy.com/36930.html
(0)
上一篇 2022年 12月 18日 23:40
下一篇 2022年 12月 19日 00:00

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注