草庐IT

objective-c - SceneKit Cocoa 添加贴花

coder 2023-09-07 原文

是否有足够的方法向 SCNNode 添加贴花(纹理)? 现在我所能做的就是用 SCNPlane 几何体创建新的 SCNNode 为其漫反射内容分配纹理并将其添加到场景中...... 这种方法非常低效。

我想添加一个不会成为场景一部分的贴花 - 以提高游戏的性能。 因为我想在地板节点上有比较多的贴花。

也许有点类似于粒子内部的工作原理? 或者其他一些快速图像绘制方法。

我已经尝试过@rickster 的建议 1

Use SKEffectNode as a buffer in the SpriteKit scene — throw splatters into an effect node until it gets to a certain number of children, then turn on its shouldRasterize option so that it doesn't re-render its children anymore (and start using a new effect node for more splatters).

在同一个 SceneKit showreel 项目中 - 仅此一项就已经取得了不错的结果,FPS 在继续播放场景后 5 分钟内没有下降,这很好。

期待实现建议 #2 - 我相信它会减少 2D 场景渲染时间(现在这是相当长的时间)。

在这个屏幕截图中有 5k 个贴花

最佳答案

我建议使用 SpriteKit 场景作为“溅射”几何体的 Material 。苹果有sample code这说明了很多你在这里的目的:

  1. 制作一个作为 SceneKit 几何体 Material 的 SpriteKit 场景。
  2. 当 3D 世界中的某些东西需要飞溅时,使用 HitTest 来查找 Material 中的纹理坐标并将其转换为 SpriteKit 场景坐标。
  3. 在 SpriteKit 场景中的该位置放置一个 Sprite 以创建贴花。

根据您的 other question 判断您似乎已经开始朝着这个方向前进...如果您详细说明问题,也许您会得到更好的帮助?


注意:该示例代码在 iOS 9/macOS 10.11 及更高版本上存在错误,会干扰飞溅效果。您可以通过在 AAPLGameViewController.m 中找到这一行来解决它:

    ball.physicsBody.collisionBitMask = ~(0x4);

并在其后添加这一行:

    ball.physicsBody.contactTestBitMask = ~(0x4);

您可能会在该演示中注意到,一段时间后,您的帧速率开始下降 — SpriteKit 场景中 Sprite 数量的不断增加使得 2D 渲染占用了越来越多的渲染循环。

(也许这是提示您 other question 的问题?)

不过,即使没有“截屏”纹理的能力,也有一些方法可以针对这种情况进行优化。调查的一些想法:

  1. 使用 SKEffectNode 作为 SpriteKit 场景中的缓冲区 — 将飞溅物扔到效果节点中,直到达到一定数量的子节点,然后打开其 shouldRasterize选项,这样它就不会再重新渲染它的子节点(并开始使用新的效果节点来获得更多的飞溅效果)。

  2. 很多 2D 时间都浪费在绘制不可见的 SK Sprite 上,因为它们被其他 Sprite 掩埋了。 (或者大部分被掩埋,只有几个像素可见。)因为你的,嗯,“油漆”都是相同的颜色,你可以使用一些简单的方法将你的 SpriteKit 场景分 block 成区域,并决定一个区域何时被绘制完全覆盖——此时,您可以从该区域移除所有 Sprite ,用一个“完全覆盖” Sprite 替换它们,并停止在该区域添加新 Sprite 。 quadtree可能是在这里使用的好工具。

  3. 如果您想通过着色器修改器而不是使用基于 SpriteKit 的 Material 进行自定义绘图,那么 SceneKit HitTest 到纹理坐标映射技巧同样有效,您也许可以找到更有效的方法在那里进行长期覆盖跟踪(可能借助#3 中的一些技巧)。

  4. 如果您的飞溅不是经常发生,您可以在 CPU 上渲染它们并在 Material 上设置一个新图像。

  5. 一个想法的远景,不知道它是否可行或性能良好:使用 Core Image as an accumulation buffer绘制飞溅,并将其渲染到与 Material 内容设置相同的 MTLTexture 中。 (使用 SceneKit 的 willRenderScene 回调每帧渲染一次。)

关于objective-c - SceneKit Cocoa 添加贴花,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40913688/

有关objective-c - SceneKit Cocoa 添加贴花的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  3. ruby - 将 Bootstrap Less 添加到 Sinatra - 2

    我有一个ModularSinatra应用程序,我正在尝试将Bootstrap添加到应用程序中。get'/bootstrap/application.css'doless:"bootstrap/bootstrap"end我在views/bootstrap中有所有less文件,包括bootstrap.less。我收到这个错误:Less::ParseErrorat/bootstrap/application.css'reset.less'wasn'tfound.Bootstrap.less的第一行是://CSSReset@import"reset.less";我尝试了所有不同的路径格式,但它

  4. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  5. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  6. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  7. ruby - 可以通过多少种方法将方法添加到 ruby​​ 对象? - 2

    当谈到运行时自省(introspection)和动态代码生成时,我认为ruby​​没有任何竞争对手,可能除了一些lisp方言。前几天,我正在做一些代码练习来探索ruby​​的动态功能,我开始想知道如何向现有对象添加方法。以下是我能想到的3种方法:obj=Object.new#addamethoddirectlydefobj.new_method...end#addamethodindirectlywiththesingletonclassclass这只是冰山一角,因为我还没有探索instance_eval、module_eval和define_method的各种组合。是否有在线/离线资

  8. ruby - 如何在 Ruby 中向现有方法定义添加语句 - 2

    我注意到类定义,如果我打开classMyClass,并在不覆盖的情况下添加一些东西我仍然得到了之前定义的原始方法。添加的新语句扩充了现有语句。但是对于方法定义,我仍然想要与类定义相同的行为,但是当我打开defmy_method时似乎,def中的现有语句和end被覆盖了,我需要重写一遍。那么有什么方法可以使方法定义的行为与定义相同,类似于super,但不一定是子类? 最佳答案 我想您正在寻找alias_method:classAalias_method:old_func,:funcdeffuncold_func#similartoca

  9. ruby-on-rails - 添加回形针新样式不影响旧上传的图像 - 2

    我有带有Logo图像的公司模型has_attached_file:logo我用他们的Logo创建了许多公司。现在,我需要添加新样式has_attached_file:logo,:styles=>{:small=>"30x15>",:medium=>"155x85>"}我是否应该重新上传所有旧数据以重新生成新样式?我不这么认为……或者有什么rake任务可以重新生成样式吗? 最佳答案 参见Thumbnail-Generation.如果rake任务不适合你,你应该能够在控制台中使用一个片段来调用重新处理!关于相关公司

  10. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

随机推荐