ARKit进阶:材质

相关

到底有多强?苹果的增强现实框架:ARKit
ARKit进阶:物理世界
ARKit实战:如何实现任意门

Scenekit lights and materials

光照与材质,是决定3D世界中的模型如何渲染的关键参数。许多时候模型的渲染对与不对,往往只是一种视觉的感受。由于不是测试驱动的,所以多数情况下,考验的不是你的逻辑,而是不断调试到理想的效果。熟悉光照与材质的着色方式,能够快速定位与解决问题。

Materials

材质指定了引擎如何在渲染阶段对几何体的每个像素着色。
SceneKit 中,每个SCNMaterial有八个决定视觉感官的属性(SCNMaterialProperty),其实就是3D建模时的光照贴图,当然每个属性也可以设置成纯色。SCNMaterial是可以复用的,但是要更改时,如果不想影响到其他模型,最好先复制一份。

Order of materials

有人对 SceneKit 的每个几何体都可以拥有一组材质不理解。他们是用来对几何体子元素着色的。如果几何体的子元素与材质数量对应,那么二者的索引是一一对应的。这里的子元素,一般就是引擎根据几何体顶点算出的多边形面。
例如有一个box,那么显然它是由6个多边形面,如果 box.materials 有6个材质,那么每个面就应用对应的材质。几何体的子元素引用顺序是固定的,对于这个box,多边形引用顺序是 front -> right -> back -> left -> top -> bottom。如果我们需要这个box只有顶面与底面显示,其他面隐藏,就可以这么设置:

self.boxGeometry.materials = @[transparentMaterial, transparentMaterial, 
transparentMaterial, transparentMaterial, topMaterial, bottomMaterial];

如果材质与子元素的数量不匹配,那么按照求余的方式去映射。

elements[index] <-> materials[index % numOfMaterial]

Appearance of Material

材质的表现由它的视觉属性决定,它们都是SCNMaterialProperty对象。SceneKit在渲染场景时,就是依据视觉属性与光照来决定最终的像素颜色。

Material property

材质所拥有的一组SCNMaterialProperty,被称为视觉属性,它们决定了材质“长什么样”。SCNMaterialProperty.content可以是纯色(相当于提供纯色纹理)也可以是纹理, 或者数字(主要用于 roughness 等 physicallyBased 模式的属性)。当内容是纹理时,SceneKit会采用纹理映射的方式采样相应的点作为材质属性。
纹理的读取源有以下四种:

  1. UIImage
  2. 全景格式的图像,如cube images(六张图像)
  3. CALayer
  4. SpriteKit scene
  5. SKTexture, MDLTexture, MTLTexture, GLKTextureInfo

SceneKit cannot use a layer that is already being displayed elsewhere (for example, the backing layer of a UIView object).

在使用CALayer作为内容时,如果是UIView.layer并且该UIView已经添加到其他层级中,那么内容设置会失效。

visual properties

当渲染材质时,由材质的光照模型lightModel确定要用到的视觉属性(diffuse/specular/normal),再配合场景中的光照,计算出每个点的颜色。

  • diffuse

diffuse 指定了材质对光照的漫反射。人眼看到物体,实际上人眼接收到物体的漫反射光。所以diffuse实际上是物理的基本样貌,任何光照模型都会用到diffuse这个最基本属性。

diffuse

  • ambient

ambient指定了材质对环境光的漫反射。一般情况下,diffuse已经包含环境光与方向光的漫反射,当locksAmbientWithDiffuse为NO时,ambient才会生效。这个属性只有在想突出环境光的情况下才会用到,一般diffuse已经足够,且效率更高。

ambient

  • specular

specular指定了材质的镜面反射,,用来表现材质的光滑程度。这个很好理解,漫反射是对各个方向的反射光,而镜面反射的角度一般不超过90度,角度越小看着越光滑。不管是 phong 还是 blinn-phong 光照模型,镜面反射都与材质的shininess相关, shinness越大,反射效果对比度越高,类似玻璃反射。
specular map 的亮度与材质的光滑程度成正比,specualr默认是纯黑色,即全粗糙表面。

specular

  • normal

normal指定了材质表面每个点的法线方向,在处理光照时,会根据normal计算阴影。
在光滑的表面,normal提供了一种假的几何凸起,而不用去增加几何复杂度。在 normal map 时,normal纹理的 R, G, B, 就是材质对应点法向量的X, Y, Z。当normal是纯色时,normal map 会自动失效。

normal

  • reflective

relective指定了材质对周围环境的反射。例如在树林里和在房间里,材质表面的反射效果应该是不同的,树林的环境下材质会泛绿。relective就用来做这件事,只需要将relective.content赋值为周围环境的图像。

reflective

  • emission

emission指定了材质表面发光(亮度较高)的位置。emission并不能让材质发光,只不过在计算光照是,emission 纹理中较亮的点不会参与到光照计算中,使这些点在阴暗的环境下显得更亮一些。emission默认是纯黑色,相当于提供了纯黑的纹理,emission无效。

emission

  • transparent

transparent指定了材质表面每个点的透明度。不同于transparency控制整个材质的透明度,transparent精准地控制每个点,其透明度等于 transparent 纹理的像素点 alpha 值。

transparent

  • multiply

multiply的内容,会在材质渲染完成之后,叠加在材质之上。multiply默认无效,内容是纯白色。

multiply

  • ambientOcclusion

ambientOcclusion,环境光遮蔽是一项用于提高模型细节的技术。由于环境光是不产生阴影的,引擎只会渲染方向光的阴影,这使得细节比较复杂的模型表现是真。传统的环境光是依靠射线追踪实现的,由于要处理每一个点,这种技术非常耗时。对于静态的模型,我们可以设置已经计算好的环境光遮蔽图,这样既能够有良好的细节,又不会造成大的性能损耗。

ambient occlusion

Physically based properties

以下几个属性,只有 physicallyBased 光照模型下的材质才有用,它们的效果比传统的光照模型更真实,值得多多尝试。

  • selfIllumination

selfIllumination 能会覆盖物体的亮度计算结果, 能让材质自己定义表面的亮度。在昏暗的环境下,模型由于不在光照范围可能会模糊不清,这时使用selfIllumination可以调节模型的亮度。

  • metalness

metalness 顾名思义,用来模拟材质表面的金属感。metalness 纹理的亮度决定材质的金属感,越亮越像金属。在设置 SCNScene.lightingEnvironment 后,引擎会根据真实的反射、折射参数去模拟金属表面的反光,效果很棒。

metalness

  • roughness

roughnessspecular 相似,用来表现模型表面的光滑程度。roughness 的计算规则是模拟真实世界的物理参数,与specular相比少了一些塑料感。roughness 纹理的亮度决定越粗糙,越亮越粗糙。

Light model of material

材质的光照模型,决定光照如何参与到材质的着色计算中。对于没有特殊需要的模型,SceneKit team 推荐使用 physicallyBased,它能根据实时的场景变化渲染出更加真实的效果。
SceneKit支持五种光照模型:

1. constant
在计算模型表面的颜色时,只考虑环境光。在我们不需要模型的self-shadows时,可以将模型设置成constant model。相关问题

2. physicallyBased
根据真实世界的光照与材质效果,渲染模型表面。physicallyBased 的算法对于lighting environment的反射效果非常好,尤其是金属材质能以假乱真。
physicallyBased 主要根据材质的 diffuse ,roughness, metalness ,ambientOcclusion来计算着色。

3. lambert
根据lambert算法渲染模型表面,只考虑环境光与方向光在模型表面产生的漫反射。

color = ambient * al + diffuse * max(0, dot(N, L))

算法的公式就是将两种不同光的漫反射效果相加,lambert 主要根据材质的diffuseambient来计算着色。

4. phong
在计算Lambert漫反射的基础上,加上了用phong算法计算的镜面反射。

color = ambient * al + diffuse * max(0, dot(N, L)) + specular * pow(max(0, dot(R, E)), shininess)

公式的最后一项就是phong算法计算的镜面反射。phong 主要根据材质的diffuseambient, specular, shininess来计算着色。

5. blinn
在计算Lambert漫反射的基础上,加上了用blinn-phong算法计算的镜面反射。blinn-phong 的镜面反射光过渡更平滑,效果更真实,也是大多数渲染管线的默认光照模型。

color = ambient * al + diffuse * max(0, dot(N, L)) + specular * pow(max(0, dot(H, N)), shininess)

blinn 依据的材质与 phong 一样,只有计算参数不同。

Configuration of materials

除了设置材质的视觉属性和光照模型,我们还需要确定材质渲染到场景中的规则。比较常用的有以下几个:

transparency & transparencyMode
transparencyMode 为 aOne 时,SceneKit 提取 transparent 纹理的alpha通道值作为透明信息。
为 rgbZero 时,提取transparent 纹理的亮度信息作为透明信息。
对于材质上的每一个点,SceneKit通过将transparencytransparent纹理映射点的透明信息相乘,获得最终的像素透明度。transparency控制材质整体的透明度,类似的效果也可以通过控制SCNNode.opacity来获得。

blendMode
blendMode指定了材质的像素点在渲染阶段是如何与背景混合的。默认
SCNBlendModeAlpha 模式依据各个混合像素点的alpha值,来确定最终颜色的透明度。比较有用的是SCNBlendModeAdd模式,它指定在混合时,将各个混合像素的颜色相加,这会造成材质的一种半透明感。

writesToDepthBuffer & readsFromDepthBuffer
SceneKit 在渲染每个像素点时,会比较像素的深度信息,若在同一位置有多个像素重合,那么只渲染离摄像机最近的那个。深度缓冲技术依靠深度缓冲寄存器,比传统的画家算法要高效很多。这篇文章介绍的很不错

writesToDepthBufferreadsFromDepthBuffer,前者影响其他物体的绘制,后者影响自己的绘制,相互配合能解决一些比较棘手的问题,如绘制玩家数据时,它应该始终在最上层,所以不用读取深度缓冲。
在某些情况下,也可以用来尝试解决深度冲突问题

最后

材质是决定模型表现最关键的因素,同时也是设计师与程序员能够直接对接的环节。熟练掌握3D渲染的材质相关知识,不仅能沟通起来事半功倍,也能轻度参与到模型的视觉调整中,毕竟看起来舒服的东西才让人更有动力参与。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • <转>我也忘了转自哪里,抱歉,感谢原作者 什么是Shader Shader(着色器)是一段能够针对3D对象进行操作...
    星易乾川阅读 5,505评论 1 16
  • 一、Surface Output (表面着色器的标准输出结构)Surface Shader的标准输出结构-第一要素...
    CarlDonitz阅读 860评论 0 1
  • 梦境的可怕!!一次次影响着我!昨晚的梦(梦到男盆友带去见男方父母,被男方母亲各种嫌弃,各种讨厌,粗心,不细心,不谦...
    阿边边边010阅读 176评论 0 0
  • 喜欢上了绣花,觉得这个比十字绣有意思多了,绣的比较随意,不过我还是挺满意的,哈哈!
    田橙姑娘阅读 412评论 0 0
  • 我是一只鱼
    小z_af5b阅读 200评论 0 0