学习SceneKit之材质

本系列所有文章目录

获取示例代码


前言

前面我们介绍了几何体的相关知识,这篇我将为大家介绍材质,那什么是材质呢?简单来说,就是你的几何体的外观,比如是什么颜色,反光强度等等。那么在SceneKit中我们可以改变几何体的哪些外观呢?接下来我将一一介绍。

光照模型

提到材质就不得不提到光照模型。在现实生活中,我们有太阳,日光灯,蜡烛等可以产生光的光源,光照射在物体上,不同的物体呈现出不同的质感,这些都是很平常的事情。但是在计算机里,想要使用光源照射3D模型,产生出想要的质感就不是那么平常了。在OpenGL中,我们需要使用Shader根据提供的材质参数和光照来计算每个像素的颜色,从而产生物体被光照射的感觉。想要了解Shader中是如何实现光照模型的可以看我的两篇文章基本光照高级光照。其中有涉及到lambert和blinn两种光照模型。下面我将结合SceneKit简单的介绍这两种光照模型。

Lambert

在SceneKit中,使用SCNMaterial来表示材质。SCNMaterial的一个属性lightingModel表示的就是使用何种光照模型。如果我们选择Lambert光照模型,并且设置如下属性,并且把material赋给球形几何体geometry

let material = SCNMaterial()
material.lightingModel = .lambert
material.diffuse.contents = UIColor.red
material.ambient.contents = UIColor.init(white: 0.1, alpha: 1)
material.locksAmbientWithDiffuse = false
geometry.materials = [material]

那么渲染出来的球体将会如下所示。


我们使用的灯光在(0,6,3)处,所以球体上面是照射到灯光的,下面是灰色的。这里涉及到了两个光照分量,diffuseambientdiffuse表示几何体的本色,所以灯光照射到的部分就是本色红色,注意我用的灯光是白色的,如果灯光是其他颜色,则会和几何体的本色混合,也就是两个颜色进行3维向量乘法。那灯光照射不到的地方呢?就是ambient环境光。环境光的出现是为了让灯光照射不到的地方不会是全黑,你可以试试把环境光改成其他颜色,看看渲染结果如何。由于PBR光照模型中ambientdiffuse是锁定的,所以需要把locksAmbientWithDiffuse设置为false,否则ambient只能和diffuse取相同的值。关于PBR光照模型我会在后面的文章单独介绍。最后将material赋值给几何体,这里material是被放在一个数组里赋值的,如果你的几何体有多个element,系统会根据顺序为每个element提供不同的材质。第n个element会得到第n%材质个数个材质。

diffuse还和法线相关,法线和光线的夹脚越小,则越亮。法线就是上一篇代码里的normals

总的来说,Lambert模型就是最终颜色=光线和法线夹脚系数*光照颜色*本色diffuse + 环境色ambient

Blinn

Blinn光照模型其实就是在lambert基础上加上高光,我们将光照模型修改为.blinn,再设置高光的属性。

material.lightingModel = .blinn
material.specular.contents = UIColor.white
material.shininess = 1.0

当光线被反射后和我们视线的夹脚比较小的时候,在金属或者玻璃等反光材质下,会看到非常亮的区域,我们称之为高光。越是光滑的物体,高光区域会越小。我们用shininess来表示物体的表面有多闪(光滑),它的值从0到1。值越大,越光滑。下面是值为0.2和1的效果图。material.specular表示高光的颜色,不过最终呈现的高光颜色受material.specular和灯光的颜色共同影响,是它们颜色值的三维向量相乘。

shininess = 0.2

shininess = 1.0

材质参数的取值

上面我只给材质的参数赋予了颜色值,除了颜色,还可以赋予贴图,或者说是图片。diffusespecular都是可以接受图片对象的。比如给diffuse赋值一张地球的贴图。

material.diffuse.contents = UIImage.init(named: "earth.jpg")
从google淘来的地球贴图

效果如下。



specular接受的贴图就比较特殊,是一张黑白两色的图。图中黑色对应的地方将没有高光。


下面两张图分别是使用了和没使用specular贴图的效果图。第一张图中明显大海部分没有高光。


使用了specular贴图

没有使用specular贴图

不管是什么贴图,都是需要几何体提供UV数据的,也就是所谓的贴图坐标,在上一篇的代码中有涉及到。

let uvs: [CGPoint] = [
        CGPoint(x: 0, y: 1),
        CGPoint(x: 0, y: 0),
        CGPoint(x: 1, y: 0),
        CGPoint(x: 1, y: 1),
        ]
    let uvSource = SCNGeometrySource.init(textureCoordinates:
uvs)

系统提供的球形几何体已经有了UV数据,所以才可以轻松的进行贴图,关于贴图的更多信息,会在后面的文章中介绍,或者你也可以去看我写的基于OpenGL的贴图文章

反射贴图

SceneKit还提供了反射贴图功能,可以使用CubeMap或者SphereMap来当作环境贴图。这里我只为大家演示一下,更深入的介绍会在后面的文章中进行。下面是设置反射贴图的代码。cube-X.jpg等图片都在demo项目中。

material.reflective.contents = [
    UIImage.init(named: "cube-1.jpg"),
    UIImage.init(named: "cube-2.jpg"),
    UIImage.init(named: "cube-3.jpg"),
    UIImage.init(named: "cube-4.jpg"),
    UIImage.init(named: "cube-5.jpg"),
    UIImage.init(named: "cube-6.jpg"),
]
material.fresnelExponent = 1.7

效果图如下。是不是有一种被玻璃包裹的感觉。反射贴图主要就是通过对CubeMap或者SphereMap的反射,模拟物体反射周围环境的一种技术。


法线贴图

我们上面有说过我们会给几何体提供法线数据,但是这些数据是每个顶点才有一个,顶点之间区域的法线就只能通过线性插值来计算了。法线贴图则是通过贴图的方式来弥补这一缺陷,更多原理性质的介绍就不在这展开了,下面是例子用的法线贴图。


通过CrazyBump生成

代码设置也很简单。

material.normal.contents = UIImage.init(named: "earth_NRM.png")

效果如下。是不是瞬间有了凹凸感。


总结

这篇文章主要介绍了材质的一些基本功能,还有很多其他的功能是没有提到的。东西其实很多,要在一篇文章中全部铺开不现实,看完这一篇读者心中对光照模型和材质有个基本了解就可以了。后面的文章会针对材质中比较复杂的特性逐一进行深入介绍。

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

推荐阅读更多精彩内容