如何将场景背景的内容设置为立方体贴图

我试图设置一个场景的背景内容使用大约6个图像的天空盒效果。

我以正确的顺序创build了图像数组,我知道我需要使用

+ (instancetype) materialPropertyWithContents:(id)contents 

不过,我正在努力解决如何以及在哪里使用该类方法返回包含立方体贴图的属性。

SCNScene的“背景”属性是SCNMaterialProperty类。 所以你可以直接将它的内容设置为6个图像的数组来设置你的天空盒(见SCNScene.h)。

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

确保你的6张图片是正方形的,尺寸相同。

我的一个ScnView子类的awakeFromNib

是的,因为分配给内容的值是id,所以很less有样本。

我的一个ScnView子类的awakeFromNib

使用任何6个相同大小的图像。 TGA不需要。

谷歌skyboxfind例子。

这个样本制作一个天空盒,并将相同的图像应用到一个立方体,使它看起来像镜子的天空。

摄像头控制就这样刚刚移动鼠标旋转看起来像镜像立方体

 // // 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 eg 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