专栏首页每日一篇技术文章SceneKit-BlendMode混合模式

SceneKit-BlendMode混合模式

本节学习目标 演示多种混合模式对几何模型渲染的作用

SCNMaterial 有一个属性blendMode,这个属性主要控制的是渲染模式的选择,默认值是 SCNBlendModeAlpha

public enum SCNBlendMode : Int {
  case alpha 
  case add  
  case subtract 
  case multiply 
  case screen 
  case replace 
}

下面我们开始进入实验,实验此示例请先去除光照的影响 首先我们创建两个几何模型添加到scene中去,效果如下

image.png

代码如下

第一步 创建场景

    let scene = SCNScene()

第二步 添加照相机

    let cameraNode = SCNNode()
    cameraNode.camera = SCNCamera()
    scene.rootNode.addChildNode(cameraNode)
    cameraNode.position = SCNVector3(x: 0, y: 0, z: 30)

第三步 给scnview视图设置场景

   let scnView = self.view as! SCNView
    scnView.scene = scene

第四步 添加两个几何体到场景中去

    let srcNode = SCNNode()
    srcNode.geometry = SCNBox(width: 10, height: 10, length: 10, chamferRadius: 0)
    srcNode.geometry?.firstMaterial?.diffuse.contents = UIColor(colorLiteralRed: 1, green: 0, blue: 0, alpha: 1)
    scene.rootNode.addChildNode(srcNode)

    let desNode = SCNNode()
    desNode.geometry = SCNBox(width: 10, height: 10, length: 10, chamferRadius: 0)
    desNode.position = SCNVector3Make(0, 0, -20)
    desNode.geometry?.firstMaterial?.diffuse.contents = UIColor(colorLiteralRed: 0, green: 1, blue: 0, alpha: 1)
    scene.rootNode.addChildNode(desNode)

第五步 设置允许操作摄像机,方便我们查看效果

scnView.allowsCameraControl = true

准备工作已经完毕,进入今天的主题

我们修改靠近相机的几何模型,即如图的红色正方体

1.alpha模式

srcNode.geometry?.firstMaterial?.diffuse.contents = UIColor(colorLiteralRed: 1, green: 0, blue: 0, alpha: 0.5)
srcNode.geometry?.firstMaterial?.blendMode = .alpha
desNode.geometry?.firstMaterial?.diffuse.contents = UIColor(colorLiteralRed: 0, green: 1, blue: 0, alpha: 1)

alpha模式效果图如下

image.png

那么这种效果怎么计算出来的呢?

srcAlpha * (sR,sG,sB) + (1-srcAlpha)*(tR,tG,sB)

红色部分后面是黑色 所以最终的结果为srcAlpha * (sR,sG,sB) ,即前面物体本身的颜色0.5*(1,0,0)+(1-0)*(0,0,0),绿色部分为:0.5*(0.5,0,0)+0.5*(0,1,0)

2.add模式

   srcNode.geometry?.firstMaterial?.diffuse.contents = UIColor(colorLiteralRed: 1, green: 0, blue: 0, alpha: 1)
   srcNode.geometry?.firstMaterial?.blendMode = .add
   desNode.geometry?.firstMaterial?.diffuse.contents = UIColor(colorLiteralRed: 0, green: 1, blue: 0, alpha: 1)

计算公式

(sR+tR,sG+tG,sB+tB)

就是讲模型自身的颜色和场景目标的颜色值进行相加得到一个新的颜色值,注意相加的值最大取1

image.png

3.subtract

    srcNode.geometry?.firstMaterial?.diffuse.contents = UIColor(colorLiteralRed: 1, green: 1, blue: 0, alpha: 1)
    srcNode.geometry?.firstMaterial?.blendMode = .subtract
    desNode.geometry?.firstMaterial?.diffuse.contents = UIColor(colorLiteralRed: 0, green: 1, blue: 1, alpha: 1)

image.png

前面的物体即boxNode 的实际颜色为

image.png

后面的物体,实际的颜色为

image.png

我们将给第一个模型srcNode 开启subtract 混合,最终的颜色为

image.png

计算公式

(tR-sR,tG-sG,tB-sB)

使用目标颜色减去模型自身的颜色,注意相减的值不能小于1,物体1和物体2重叠部分的计算公式为(0-1,1-1,1-0)->(0,0,1) 最终为蓝色,没有重叠的部分(0-1,0-1,0-1) -> (0,0,0)

4.multiply 模式

    srcNode.geometry?.firstMaterial?.diffuse.contents = UIColor(colorLiteralRed: 1, green: 0, blue: 0, alpha: 1)
    srcNode.geometry?.firstMaterial?.blendMode = .multiply
    desNode.geometry?.firstMaterial?.diffuse.contents = UIColor(colorLiteralRed: 0, green: 1, blue: 0, alpha: 1)

效果图为

image.png

渲染出来的颜色为黑色,为什么是这样的?

后面物体的颜色为(0,1,0),前面物体颜色为(1,0,0)

计算公式为两种颜色相乘 (10,01,0*0) -> (0,0,0)

接下来,我们前面的颜色为(1,1,1) 后面颜色为 (0,0,1) 渲染效果如下

image.png

5.screen 模式

    srcNode.geometry?.firstMaterial?.diffuse.contents = UIColor(colorLiteralRed: 1, green: 0, blue: 0, alpha: 1)
    srcNode.geometry?.firstMaterial?.blendMode = .screen
    desNode.geometry?.firstMaterial?.diffuse.contents = UIColor(colorLiteralRed: 0, green: 1, blue: 0, alpha: 1)

自身颜色(1,0,0) 目标颜色 (0,1,0)

计算公式 ((1-sR)tR,(1-sG)tR,(1-sB)*tB) + (sR,sG,sB)

重叠部分颜色计算((1-1)1,(1-0)1+(1-0)*0)+(1,0,0)->(1,1,0),没有重叠的颜色为(1,0,0) 即自身颜色

实验结果如下

image.png

6.replace 模式

    srcNode.geometry?.firstMaterial?.diffuse.contents = UIColor(colorLiteralRed: 1, green: 0, blue: 0, alpha: 0.5)
    srcNode.geometry?.firstMaterial?.blendMode = .replace
    desNode.geometry?.firstMaterial?.diffuse.contents = UIColor(colorLiteralRed: 0, green: 1, blue: 0, alpha: 1)

这个比较简单就是取代的的意思

计算公式

(sR,sG,sB)

在此示例中,我们可以看到设置了透明度为0.5,但是实际效果如下

image.png

以上就是本节的全部内容,如果您方便的话,烦请给应用评个分,鼓励我写更多有用的文章。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 内置变量和函数

    以上是go里面的内置builtin 包里面的函数和变量,由于函数方法使用都比较简单,这里就不在赘述了

    酷走天涯
  • 如何创建库源码文件

    util 是存放date.go time.go 的目录 但是包不见得就是util 因为声明的包名可以和文件夹的名字不一致,但是规范的做法最好是一致的

    酷走天涯
  • react-native 自动化构建过程(ipa包)

    准备工作 1.安装xcode 2.安装cocospod 3.react-native源文件(git获取源码) 4.安装npm包管理工具 5.安装rea...

    酷走天涯
  • MySQL数据库备份实操

    当前xtrabackup的8.0.13已经支持 mysql 8.0.20版本(8.0.20版本对innodb的数据文件模式进行了修改)

    技术路漫漫
  • Tomcat Put(CVE-2017-12615)复现

    根据描述,在 Windows 服务器下,将 readonly 参数设置为 false 时,即可通过 PUT 方式创建一个 JSP 文件,并可以执行任意代码。

    墙角睡大觉
  • 谁是存储界的美军F-35统一作战平台?

    统一作战平台 在军工界,为了降低成本,美军发起F35战斗机研发项目。与传统而昂贵空战的F-22战斗力不同,F35不再是一款简单的战机,而是开启云作战新模式。F-...

    魏新宇
  • 观察者模式在One Order回调函数中的应用

    例如需求是搞清楚function module CRM_PRODUCT_I_A_CHANGE_ORGM_EC在什么样的场景下会被调用。当然最费时间的做法是设一个...

    Jerry Wang
  • Kubernetes DaemonSet的滚动升级

    DaemonSet好比Kubernetes集群Node的守护进程,可以保证在每个Node上(或者一部分Node上)都运行同一个Pod。 目前我们的线上环境主要用...

    domain0
  • 微信小程序|顶部导航标签栏

    当我们在一个小程序中想要查看某些信息,总是以页面顶部的一个导航栏展示出来,点击该导航栏上的各个标签则会出现对应页面内容。而如何实现顶部的标签导航,则需要我们引入...

    算法与编程之美
  • css笔记 - 张鑫旭css课程笔记之 padding 篇

    对于block元素 1.没宽度设置的情况:垂直向外扩张,水平向内挤压 上下padding会增加元素占据的尺寸(即看上去高度在增加),左右因为元素宽度...

    xing.org1^

扫码关注云+社区

领取腾讯云代金券