我正在学习本教程:http://blog.bignerdranch.com/754-scenekit-in-mountain-lion/
我对使用Scene Kit感兴趣,但我的场景可能有数千个球体.要对Scene Kit进行压力测试,我试过这个:
SCNSphere *sphere = [SCNSphere sphereWithRadius:0.5];
for (int i=0; i<10; i++) {
for(int j=0; j<10; j++){
for(int k=0; k<10; k++){
SCNNode *myNode = [SCNNode nodeWithGeometry:sphere];
myNode.position = SCNVector3Make(i,j,k);
[root addChildNode:myNode];
}
}
}
Run Code Online (Sandbox Code Playgroud)
这适用于1000球(10 ^ 3),但是对于1,000,000个球(100 ^ 3)而言失败(也许不足为奇).我不介意不能使用一百万个球体,但我想弄清楚明智的上限是什么(5,000?15,000?)以及如何增加它.
我该怎么做才能缓解这种情况?例如,我已经尝试了sphere.segmentCount = 3,虽然这加快了渲染速度,但它对内存使用没有太大影响,我怀疑这是限制因素.
此外,似乎没有SCNPoint类.我在考虑切换到仅在球体数量太高时显示一个点,但我无法从SceneKit文档中看到如何显示一个简单的点 - 我能看到的最简单的是一个三角形.
任何帮助深表感谢.
编辑: @toyos建议将SCNSphere对象合并到单个SCNGeometry对象中(前提是它们不需要独立动画,但它们不需要),但我找不到一种简单的方法来执行此操作.
SCNGeometry是使用此处[SCNGeometry geometryWithSources:(* NSArray)sources geometryWithElements:(* NSArray) elements]记录的创建的,但我不清楚如何从我的领域创建一个对象.SCNGeometry
例如,对于单个球体,我可以看到使用sphere.geometryElementCount获取元素的数量,然后使用它来填充数组,使用[sphere geometryElementAtIndex:(NSInteger)elementIndex]它可以给我元素,但我不知道如何获得"源"(或者它们甚至是什么)是).获取几何源的方法是[sphere geometrySourcesForSemantic:(NSString*) semantic],但这个语义字符串是什么?(它意味着是"法线"还是"顶点"还是其他的东西?文档非常有用地说语义是"几何源的语义值."而没有说出语义的可能值是什么)
这只是一个单一的球体,这将是毫无意义的(因为SCNSphere它只是一个SCNGeometry无论如何的子类),所以现在我必须添加多个球体.那么在将它们添加到我的SCNGeometry对象时,我是否必须手动转换球体的顶点? …
我正在尝试使用大约6个图像的数组将场景的背景内容设置为天空盒效果.
我已经按照正确的顺序创建了图像数组,我知道我需要使用它
+ (instancetype) materialPropertyWithContents:(id)contents
Run Code Online (Sandbox Code Playgroud)
但是我正在努力弄清楚我是如何以及在何处使用该类方法来返回包含多维数据集映射的属性.
我在3D编程方面遇到了更多的数学问题,我希望你能帮助我!
我正在尝试使用具有等角度的Scenekit创建3D游戏.
这段代码创建了我的正交相机:
var cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.name = "Camera"
cameraNode.position = SCNVector3Make(-5.0, -5.0, 10.0)
cameraNode.eulerAngles = SCNVector3Make(PI / 3.0, 0.0, -PI / 4.0)
cameraNode.camera?.usesOrthographicProjection = true
cameraNode.camera?.orthographicScale = 7.0
scene.rootNode.addChildNode(cameraNode)
Run Code Online (Sandbox Code Playgroud)
现在我想使用平移手势移动相机,产生滚动感.为了实现这一点,相机不应垂直移动,只能水平移动.移动时,屏幕上的触摸位置和3D世界中未投影的位置应保持不变.
我考虑过计算2D平移到3D差异并忽略垂直分量.这段代码实际上可以工作,几乎可以产生所需的结果,但速度不正确.如果我平移,相机似乎加速并且没有正确反应:
var previousTranslation = CGPointMake(0.0, 0.0)
func pan(gesture: UIPanGestureRecognizer)
{
let view = self.view as SCNView
let translation = gesture.translationInView(view)
let location = gesture.locationInView(view)
let diffTrans = translation - previousTranslation
previousTranslation = translation
let cameraNode = scene.rootNode.childNodeWithName("Camera", recursively: false)
let worldPointTrans = view.unprojectPoint(SCNVector3Make(-Float(diffTrans.x), -Float(diffTrans.y), 0.0)) …Run Code Online (Sandbox Code Playgroud) 我是iOS中的SceneKit和3D空间的新手.我目前正在制作一个简单的游戏,显示一个包含28个段的立方体(如果你想要的话,可以使用"迷你立方体").
我想通过点击它们来移动迷你立方体,但我无法理解如何选择特定节点(大立方体的子节点).
任何人都可以帮我或发布一个关于傻瓜的SceneKit教程的链接?我一直在寻找几天,并没有找到我正在寻找的东西.
干杯
我查看了WWDC中的Banana游戏,它是用Objective-C编写的,它试图将代码转换为swift以导入动画并在它们之间进行转换,但是我遇到了从DAE文件中快速运行动画的问题.
我有来自3DSMAx和openCollada格式的AutoDesk格式的导出器DAE文件.autodeskformat animtation是针对每个骨骼所以我无法按名称调用动画,因此我只需导入场景并执行以下操作,以便在文件加载后立即启动动画.
scene = SCNScene(named: "monster.scnassets/monsterScene.DAE")
scene2 = SCNScene(named:"monster.scnassets/monster.DAE")
var heroNode = SCNNode()
heroNode = scene.rootNode.childNodeWithName("heroNode", recursively: false)!
var nodeArray = scene2.rootNode.childNodes
for childNode in nodeArray {
heroNode.addChildNode(childNode as SCNNode)
}
Run Code Online (Sandbox Code Playgroud)
尽管动画在场景开始时播放,但我知道如何存储动画.
如果我使用openCollada导出collada文件.我可以使用以下命令来运行get并运行动画,因为在AutoDesk collada格式的情况下,整个对象只有一个动画而不是每个骨骼.通过这种方式,我也可以使用CAAnimation存储动画.
var anim = scene2.rootNode.animationForKey("monster-1")
childNode.addAnimation(anim, forKey: "monster-1")
Run Code Online (Sandbox Code Playgroud)
但是然后角色以某个角度运行并且来回运行而不是在同一个地方跑.
使用openCollada也可以更好地照明.我只想使用openCollada而不是autodesk collada export.现在我使用openCollada格式导出场景,使用autodesk导出字符.
如何在SceneKit中快速存储动画并在它们之间进行过渡?谢谢.:d
假设我有一个collada文件,其中有一个框,我将dae文件导入到场景中.现在在场景中导入后我知道dae对象是一个盒子.在将场景添加到场景后,如何获取场景包中的框的尺寸
如果我将节点作为SCNBox导入,则会收到错误消息,指出SNCBox不是SCNNode的子类型.
floorNode = scene.rootNode.childNodeWithName("floor", recursively: false) as SCNBox
floorNode?.physicsBody = SCNPhysicsBody.staticBody()
floorNode?.physicsBody?.categoryBitMask = 2
let floorGeo: SCNBox = floorNode.geometry! as SCNBox
Run Code Online (Sandbox Code Playgroud)
如果SCNNode是导入节点的唯一方法,我如何获得维度?
我正在尝试在我的SCNView中使用SKVideoNode作为SCNSphere的视频纹理源
我正在听这个答案:
SKVideoNode(嵌入在SKScene中)作为Scene Kit节点无法正常工作的纹理
通过我的代码(粘贴在问题的末尾),我确实获得了视频和音频播放.
问题是,映射仅发生在球体的四分之一上(所有xy-正四分之一).
cameraNode位于球体内(0,0,0)并独立于sphereNode.
我确实将一个比例应用于球体节点,只是为了反转纹理的节点:
sphereNode.scale = SCNVector3Make(-1, 1, 1)
Run Code Online (Sandbox Code Playgroud)
但评论说没有效果.
这都是在设备上测试的(iphone 6+,使用iOS 9.1):
let sphere = SCNSphere(radius: 1)
.
.
.
func setupView() {
// setup the sphere
sphere.segmentCount = 55
// sphere material
sceneMaterial = SCNMaterial()
// setup the sphereNode
sphereNode = SCNNode(geometry: sphere)
sphereNode.position = SCNVector3Make(0, 0, 0)
sphereNode.scale = SCNVector3Make(-1, 1, 1)
let apperture = 75.0
// setup the camera
camera = SCNCamera()
camera.xFov = apperture
camera.zFar = 10000
camera.yFov = apperture
camera.zNear …Run Code Online (Sandbox Code Playgroud) 目标是子类化SCNNode.根据类docs,init(geometry geometry: SCNGeometry?)是一个指定的初始化器(没有convenience列出关键字),所以这个代码是不是调用了它的超类的指定初始化器?
为什么Xcode显示以下错误?
必须调用超类SCNNode的指定初始值设定项
class PreviewNode: SCNNode {
// Constants
let PreviewNodeColor = gRedColor
let Size = CGFloat(1.0)
let ChamferRadius = CGFloat(0.0)
override init() {
let previewBox = SCNBox(width: Size, height: Size, length: Size, chamferRadius: ChamferRadius)
previewBox.firstMaterial!.diffuse.contents = PreviewNodeColor
previewBox.firstMaterial!.transparency = 0.2
previewBox.firstMaterial!.specular.contents = UIColor.whiteColor()
super.init(geometry: previewBox)
}
}
Run Code Online (Sandbox Code Playgroud) 我正在查看SceneKit的句柄绑定方法与SCNBufferBindingBlock回调,如下所述:
https://developer.apple.com/documentation/scenekit/scnbufferbindingblock
有没有人有一个如何工作的例子?
let program = SCNProgram()
program.handleBinding(ofBufferNamed: "", frequency: .perFrame) { (steam, theNode, theShadable, theRenderer) in
}
Run Code Online (Sandbox Code Playgroud)
对我来说,它就像我可以在SCNNode上使用*.metal着色器而不必经历SCNTechniques的麻烦....任何接受者?
问题:是否有办法将着色器修饰符应用于特定的SCNMaterial或SCNGeometry(因为这些是采用SCNShadable协议的唯一类),而是应用于一组SCNNodes,例如所选择的一个子节点?
问题我试图解决:我有着色器代码,它discard通过统一参数的计算来剪辑(碎片)几何.实际上,它可以按轴坐标或随机"块"体积的形式剪切模型.
我没有找到有关剪辑模型的任何信息,SceneKit因此我决定坚持使用着色器.将着色器修改器应用于每个节点似乎不正确.然而,它确实在模拟器上工作,但它不适用于真实设备,因为它超出了资源限制.我也试过,SCNTechnique但我发现它看起来像是适合后处理而不是处理片段渲染.
将着色器修改器应用于场景rootNode将是一种去恕我直言的方法,但我不确定它是否可能.我是否想念在SceneKit中使用着色器?或者有更好的方法来执行参数几何裁剪?
scenekit ×10
ios ×6
swift ×4
shader ×2
3d ×1
animation ×1
avfoundation ×1
cocoa ×1
hittest ×1
math ×1
metal ×1
objective-c ×1
scenegraph ×1
scnnode ×1
skybox ×1
sprite-kit ×1
translation ×1
video ×1