递归::如何在自身之上创建自身的 3d 场景包的迷你视图?
Recursion:: How to create a mini-view of 3d scenekit of self on top of self?
我有一个带有 SceneKit 的 3d 世界,效果很好,可以平移、缩放 in/out 但我想在更大的 3d 世界之上创建 3d 世界的迷你视图。因此,如果用户放大到非常精细的分辨率,他们仍然知道他们在 space.
中的位置
大多数示例似乎在 SceneKit VC 之上覆盖了一个不同的 VC 之类的 SpriteKit,并带有 overlaySKScene
之类的东西。迷你版不会缩放 in/out 但会平移、改变照明等,但它不接受手势。这更像是递归如何将 self 的迷你版本放在 self 之上。
有多种方法可以做到这一点。
您只需在另一个视图之上添加另一个 SCNView
。单个 SCNScene
可以由多个视图使用不同的视角呈现。
您还可以使用 SCNTechnique
创建一个 "mini-view" 通道,它将在子视口中使用另一个视角重新渲染您的场景。
在 SCNTechnique
头文件的摘录中,您可以看到您可以提供所需的名称 pointOfView
:
sequence: ["Pass1", "Pass2", ...],
passes: {
"Pass1": {
outputs: <outputs>
inputs: <inputs>
draw: <draw command>
program: <program name>
colorStates: <color states>
depthStates: <depth states>
stencilStates: <stencil states>
cullMode: <cull mode>
blendStates: <blend states>
viewport: <custom viewport>
pointOfView: <node name> // Point of view
samples: <sample count>
excludeCategoryMask: <category bitMask>
includeCategoryMask: <category bitMask>
},
"Pass2" : {
[...]
}
}
因此,在您的 SCNScene
中添加一项技术(它符合 SCNTechniqueSupport
)并通过 DRAW_SCENE
应该可行。
我是这样做的:
您可以简单地在场景中添加另一个相机,然后渲染到 SCNLayer。然后,您可以在场景中将此层用作 material,或将其添加为场景顶部的自定义视图。
SCNScene *scene2 =[SCNScene scene];
// We duplicate the scene by cloning the root node.
// I found that you cannot share the scene if you
// use the layer within it.
[[scene2 rootNode] addChildNode:[root clone]];
// Create a SCNLayer, set the scene and size
SCNLayer *scnlayer = [SCNLayer layer];
scnlayer.scene = scene2;
scnlayer.frame = CGRectMake(0, 0, 600, 800);
// "Layer" should be the name of your second camera
scnlayer.pointOfView = [scene.rootNode childNodeWithName:@"Layer" recursively:YES];
// Make sure it gets updated
scnlayer.playing = YES;
// Make a parent layer with a black background
CALayer *backgroundLayer = [CALayer layer];
backgroundLayer.backgroundColor = CGColorGetConstantColor(kCGColorBlack);
backgroundLayer.frame = CGRectMake(0, 0, 600, 800);
// Add the SCNLayer
[backgroundLayer addSublayer:scnlayer];
// Set the layer as the emissive material of an object
SCNMaterial *material = plane.geometry.firstMaterial;
material.emission.contents = scnlayer;
我很确定这不是一个很好的方法,但它对我有用。
我有一个带有 SceneKit 的 3d 世界,效果很好,可以平移、缩放 in/out 但我想在更大的 3d 世界之上创建 3d 世界的迷你视图。因此,如果用户放大到非常精细的分辨率,他们仍然知道他们在 space.
中的位置大多数示例似乎在 SceneKit VC 之上覆盖了一个不同的 VC 之类的 SpriteKit,并带有 overlaySKScene
之类的东西。迷你版不会缩放 in/out 但会平移、改变照明等,但它不接受手势。这更像是递归如何将 self 的迷你版本放在 self 之上。
有多种方法可以做到这一点。
您只需在另一个视图之上添加另一个 SCNView
。单个 SCNScene
可以由多个视图使用不同的视角呈现。
您还可以使用 SCNTechnique
创建一个 "mini-view" 通道,它将在子视口中使用另一个视角重新渲染您的场景。
在 SCNTechnique
头文件的摘录中,您可以看到您可以提供所需的名称 pointOfView
:
sequence: ["Pass1", "Pass2", ...],
passes: {
"Pass1": {
outputs: <outputs>
inputs: <inputs>
draw: <draw command>
program: <program name>
colorStates: <color states>
depthStates: <depth states>
stencilStates: <stencil states>
cullMode: <cull mode>
blendStates: <blend states>
viewport: <custom viewport>
pointOfView: <node name> // Point of view
samples: <sample count>
excludeCategoryMask: <category bitMask>
includeCategoryMask: <category bitMask>
},
"Pass2" : {
[...]
}
}
因此,在您的 SCNScene
中添加一项技术(它符合 SCNTechniqueSupport
)并通过 DRAW_SCENE
应该可行。
我是这样做的:
您可以简单地在场景中添加另一个相机,然后渲染到 SCNLayer。然后,您可以在场景中将此层用作 material,或将其添加为场景顶部的自定义视图。
SCNScene *scene2 =[SCNScene scene];
// We duplicate the scene by cloning the root node.
// I found that you cannot share the scene if you
// use the layer within it.
[[scene2 rootNode] addChildNode:[root clone]];
// Create a SCNLayer, set the scene and size
SCNLayer *scnlayer = [SCNLayer layer];
scnlayer.scene = scene2;
scnlayer.frame = CGRectMake(0, 0, 600, 800);
// "Layer" should be the name of your second camera
scnlayer.pointOfView = [scene.rootNode childNodeWithName:@"Layer" recursively:YES];
// Make sure it gets updated
scnlayer.playing = YES;
// Make a parent layer with a black background
CALayer *backgroundLayer = [CALayer layer];
backgroundLayer.backgroundColor = CGColorGetConstantColor(kCGColorBlack);
backgroundLayer.frame = CGRectMake(0, 0, 600, 800);
// Add the SCNLayer
[backgroundLayer addSublayer:scnlayer];
// Set the layer as the emissive material of an object
SCNMaterial *material = plane.geometry.firstMaterial;
material.emission.contents = scnlayer;
我很确定这不是一个很好的方法,但它对我有用。