递归::如何在自身之上创建自身的 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;

我很确定这不是一个很好的方法,但它对我有用。