2014-06-22 15 views
7

Sto provando a impostare il contenuto dello sfondo di una scena su un effetto skybox usando circa un array di 6 immagini.Come impostare il contenuto dello sfondo di Scenekit sulla mappa del cubo

ho creato la serie di immagini nell'ordine corretto, so che ho bisogno quindi utilizzare per

+ (instancetype) materialPropertyWithContents:(id)contents 

Comunque sto lottando per capire come e dove esattamente io uso che metodo di classe per restituire la proprietà contenente la mappa del cubo.

risposta

17

La proprietà "background" di SCNScene appartiene alla classe SCNMaterialProperty. In questo modo è possibile impostare il contenuto direttamente su una serie di 6 immagini per impostare skybox (vedere SCNScene.h).

aScene.background.contents = @[@"Right.png", @"Left.png", @"Top.png", @"Bottom.png", @"Back.png", @"Front.png"]; 

Assicurarsi che le 6 immagini siano quadrate e con le stesse dimensioni.

+0

È possibile animare la skybox? –

+0

Vale anche la pena notare che la dimensione delle immagini deve essere una potenza di 2. – gargantuan

2

HERES mia awakeFromNib per una sottoclasse ScnView

sì, il suo fuorviante in quanto il valore assegnato al contenuto è id e c'è così pochi campioni.

HERES mia awakeFromNib per uno ScnView sottoclasse

utilizzare alcun 6 immagini di stesse dimensioni. TGA non richiesto.

Google skybox per trovare esempi.

Questo esempio crea uno skybox e applica le stesse immagini a un cubo che lo fa sembrare speculare al cielo.

controllo della telecamera è quindi basta spostare il mouse per ruotare quella che appare come un cubo a specchio

// 
// SkyBoxSceneView.h 
// SceneKit_Skybox 
// 
// Created by Brian Clear on 12/06/2014. 
// Copyright (c) 2014 Brian Clear. All rights reserved. 
// 
#import <SceneKit/SceneKit.h> 


@interface SkyBoxSceneView : SCNView 

@end 



// 
// SkyBoxSceneView.m 
// SceneKit_Skybox 
// 
// Created by Brian Clear on 12/06/2014. 
// Copyright (c) 2014 Brian Clear. All rights reserved. 
// 

#import "SkyBoxSceneView.h" 


@implementation SkyBoxSceneView 


-(void)awakeFromNib 
{ 
    // create a new scene 
    SCNScene *scene = [SCNScene scene]; 






    //----------------------------------------------------------------------------------- 
    //SET THE SKYBOX 
    //----------------------------------------------------------------------------------- 
    //it took me a while to get it working 
    //"APPLE IF YOU WANT SCENE KIT TO SUCCEED YOU NEED A FULL BLOWN GUIDE!!" 
    //----------------------------------------------------------------------------------- 
    //FIRST ISSUE - Error:scene.background is readonly 

    // I misread the help as "to set skybox set the scene.background" 
    /* 
    scene.background = ;   //INCORRECT 
    scene.background.contents = ; //OK 
    */ 
    //I should have read it as "to set skybox set the scene.background content e.g. scene.background.contents" 


    //----------------------------------------------------------------------------------- 
    //ONLY EXAMPLE OF setting material.reflective DOESNT WORK for scene.background.content 
    /* 
    I couldnt get sky box to work for ages because the only example of using reflective property I found was in 
    in the 2014 sample code 
    AAPLSlideMaterialLayer.m 
    https://developer.apple.com/library/prerelease/mac/samplecode/SceneKitWWDC2014/Listings/Scene_Kit_Session_WWDC_2014_Sources_Slides_AAPLSlideMaterialLayer_m.html#//apple_ref/doc/uid/TP40014551-Scene_Kit_Session_WWDC_2014_Sources_Slides_AAPLSlideMaterialLayer_m-DontLinkElementID_62 

    _material.reflective.contents = @[@"right.tga", @"left.tga", @"top.tga", @"bottom.tga", @"back.tga", @"front.tga"]; 

    so I tried it on scene.background.contents = 

    but didnt work 
    */ 
    //WRONG 
    //scene.background.contents = @[@"right.png", @"left.png", @"top.png", @"bottom.png", @"back.png", @"front.png"]; 

    //----------------------------------------------------------------------------------- 
    //ATTEMPT 3 - I changed all tga to png but still nothing 

    //----------------------------------------------------------------------------------- 
    //ATTEMPT 4 - Note this is very wrong. I was way off here 
    //when I saw this 
    // _material.reflective.contents = @[@"right.tga", @"left.tga", @"top.tga", @"bottom.tga", @"back.tga", @"front.tga"]; 
    //I then saw this 
    //scene.background.contents = ... 
    //I made the mistake of presuming that both "content" properties were the same 
    //SceneKit take a lot of id properties so WITHOUT A GUIDE you have to guess what goes into thes id properties 

    //I though scene.background was a SCNMaterialProperty cos it had scene.background.content 
    //same as material.reflective.content - reflective is a SCNMaterialProperty 

    //----------------------------------------------------------------------------------- 
    //tried it with SCNMaterialProperty.content 
    //but would never work as scene.background isnt a SCNMaterialProperty.content 
    // SCNMaterialProperty *scnMaterialProperty = [SCNMaterialProperty materialPropertyWithContents: @[@"right.tga", @"left.tga", @"top.tga", @"bottom.tga", @"back.tga", @"front.tga"]]; 
    //----------------------------------------------------------------------------------- 
    //tried with png but same issue 
    // SCNMaterialProperty *scnMaterialProperty = [SCNMaterialProperty materialPropertyWithContents: @[@"right.png", @"left.png", @"top.png", @"bottom.png", @"back.png", @"front.png"]]; 
    //----------------------------------------------------------------------------------- 
    //I had tried passing NSImage instead of NSString for material which worked 
    //boxNode.geometry.firstMaterial.reflective.contents = @[[NSImage imageNamed:@"right.tga"],.... 
    //so tried that for scne.background.content 
    //but was doomed as not a SCNMaterialProperty 
    // SCNMaterialProperty *scnMaterialProperty = [SCNMaterialProperty materialPropertyWithContents: @[[NSImage imageNamed:@"right.tga"], 
    //  [NSImage imageNamed:@"left.tga"], 
    //  [NSImage imageNamed:@"top.tga"], 
    //  [NSImage imageNamed:@"bottom.tga"], 
    //  [NSImage imageNamed:@"back.tga"], 
    //  [NSImage imageNamed:@"front.tga"]]]; 

    //----------------------------------------------------------------------------------- 
    //Test 4 - try with one image 

    //WORKS - set whole background to one image 
    //scene.background.contents = [NSImage imageNamed:@"left.tga"];//OK 

    //this proved that the image does load 
    //----------------------------------------------------------------------------------- 

    //use same one image in a SCNMaterialProperty 
    //DOESNT WORK - so issue is the SCNMaterialProperty 
    // SCNMaterialProperty *scnMaterialProperty = [SCNMaterialProperty materialPropertyWithContents:[NSImage imageNamed:@"right.tga"]]; 
    // scnMaterialProperty.intensity = 0.7; 
    // scene.background.contents = scnMaterialProperty;//OK 
    //----------------------------------------------------------------------------------- 
    //----------------------------------------------------------------------------------- 
    //SKYBOX WORKS!!!! 
    //----------------------------------------------------------------------------------- 
    //----------------------------------------------------------------------------------- 

    //version3 - pass array in directly (NOT through SCNMaterialProperty!!!!) 
    scene.background.contents = @[[NSImage imageNamed:@"right.tga"], 
            [NSImage imageNamed:@"left.tga"], 
            [NSImage imageNamed:@"top.tga"], 
            [NSImage imageNamed:@"bottom.tga"], 
            [NSImage imageNamed:@"back.tga"], 
            [NSImage imageNamed:@"front.tga"]]; 

    //----------------------------------------------------------------------------------- 
    //DOESNT WORK 
    //scene.background.contents = @"frozen.mov";// 

    //----------------------------------------------------------------------------------- 
    //CAMERA and CUBE 
    //----------------------------------------------------------------------------------- 
    // create and add a camera to the scene 
    SCNNode *cameraNode = [SCNNode node]; 
    cameraNode.camera = [SCNCamera camera]; 
    [scene.rootNode addChildNode:cameraNode]; 

    // place the camera 
    cameraNode.position = SCNVector3Make(0, 0, 2); 

    // create and add a 3d box to the scene 
    SCNNode *boxNode = [SCNNode node]; 
    boxNode.geometry = [SCNBox boxWithWidth:1 height:1 length:1 chamferRadius:0.02]; 
    [scene.rootNode addChildNode:boxNode]; 
    //----------------------------------------------------------------------------------- 

    // create and configure a material 
// SCNMaterial *material = [SCNMaterial material]; 
// material.diffuse.contents = [NSColor brownColor];//= [NSImage imageNamed:@"texture"]; 
// material.specular.contents = [NSColor brownColor]; 
// material.specular.intensity = 0.2; 
// material.locksAmbientWithDiffuse = YES; 
//  

// //material.reflective.contents = @[@"right.tga", @"left.tga", @"top.tga", @"bottom.tga", @"back.tga", @"front.tga"]; 
// material.reflective.contents = @[@"right.png", @"left.png", @"top.png", @"bottom.png", @"back.png", @"front.png"]; 
//  
// material.diffuse.contents = [NSColor blackColor]; 
//  
//  
// // set the material to the 3d object geometry 
// boxNode.geometry.firstMaterial = material; 
//  
// earth-reflective.jpg 
// boxNode.geometry.firstMaterial.reflective.intensity = 0.7; 
//  

    //boxNode.geometry.firstMaterial.reflective.contents = [NSImage imageNamed:@"earth-reflective"]; 
// boxNode.geometry.firstMaterial.reflective.contents = @[@"right.tga", @"left.tga", @"top.tga", @"bottom.tga", @"back.tga", @"front.tga"]; 



    //----------------------------------------------------------------------------------- 
    //CUBE MATERIAL 
    //----------------------------------------------------------------------------------- 

    //make the cube reflect the sky 
    //the sky isnt really being reflected comment out line above "scene.background.contents = ...." 
    //and cube will still reflect the sky 
    //also comment out both of these lines "boxNode.geometry.firstMaterial.reflective 
    //and sky box will still work 
    //----------------------------------------------------------------------------------- 

    //VERSION 1 - ALSO WORKS! 
    boxNode.geometry.firstMaterial.reflective.contents = @[[NSImage imageNamed:@"right.tga"], 
                  [NSImage imageNamed:@"left.tga"], 
                  [NSImage imageNamed:@"top.tga"], 
                  [NSImage imageNamed:@"bottom.tga"], 
                  [NSImage imageNamed:@"back.tga"], 
                  [NSImage imageNamed:@"front.tga"]]; 

    boxNode.geometry.firstMaterial.reflective.intensity = 0.7; 
    //----------------------------------------------------------------------------------- 
    //VERSION 2 - ALSO WORKS! 
    //this uses same image for all sides of the cube 
    //boxNode.geometry.firstMaterial.reflective.contents = [NSImage imageNamed:@"right.tga"];//ok 
    //boxNode.geometry.firstMaterial.reflective.intensity = 0.7; 


    //----------------------------------------------------------------------------------- 
    //VERSION 3 - BLACK 2010 a space odyssey shiny cube 
    //get the earth-reflective.jpg from 
    //https://developer.apple.com/library/mac/samplecode/SceneKit_Slides_WWDC2013/Introduction/Intro.html 
// boxNode.geometry.firstMaterial.reflective.contents = [NSImage imageNamed:@"earth-reflective"]; 
// boxNode.geometry.firstMaterial.reflective.intensity = 0.7; 

    //----------------------------------------------------------------------------------- 
    //----------------------------------------------------------------------------------- 
    //REQUIRED else above reflections look weird 
    boxNode.geometry.firstMaterial.diffuse.contents = [NSColor blackColor]; 
    boxNode.geometry.firstMaterial.specular.intensity = 0.0; 

    //----------------------------------------------------------------------------------- 
    // animate the 3d object - camera control is on so cube spins with the sky 
    //comment in to animate cube 

// CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"rotation"]; 
// animation.toValue = [NSValue valueWithSCNVector4:SCNVector4Make(1, 1, 0, M_PI*2)]; 
// animation.duration = 5; 
// animation.repeatCount = MAXFLOAT; //repeat forever 
// [boxNode addAnimation:animation forKey:nil]; 

    // set the scene to the view 
    self.scene = scene; 

    // allows the user to manipulate the camera 
    self.allowsCameraControl = YES; 

    // show statistics such as fps and timing information 
    self.showsStatistics = YES; 

} 
@end 
+0

Per la definizione di SCNMaterialProperty.contents, è possibile utilizzare uno qualsiasi di: 1. Un'immagine di striscia orizzontale dove '6 * image.height == image.width ' 2. Un'immagine di striscia verticale dove' image.height == 6 * image.width' 3. Un'immagine incrociata orizzontale dove '4 * image.height == 3 * image.width' 4. Un'immagine a croce verticale dove '3 * image.height == 4 * image.width' 5. Un'immagine lat/long dove' image.height == 2 * image.width' 6. Un NSArray di 6 immagini. – alexchandel