Posts match “ SceneKit ” tag:

What's new in SceneKit

WWDC 2014: What's new in SceneKit

Loading a 3D Scene

  • COLLADA .dae
  • Alembic .abc(animation)

SceneKit Editor

Loading a DAE

SCNScene *scene = [SCNScene sceneNamed:@"demo.dae"];

SceneKit Assets Catalog

.scnassets folders

Displaying the Scene

// Assign the scene
aSCNView.scene = aScene;

// modifiy a node
aNode.position = SCNVector3Make(0,0,0);
aNode.scale = SCNVector3Make(2,2,2);
aNode.rotation = SCNVector4Make(x,y,z,angle);
aNode.opacity = 0.5;

Animating a Scene

  • Per-frame updates
  • Animations
  • Actions *new*
  • Physics
  • Constraints

Animations

// Begin a transaction
[SCNTransaction begin];
[SCNTransation setAnimationDuration:2.0];

// Change properties
aNode.opacity = 1.0;
aNode.rotation = SCNVector4(0,1,0,M_PI*4);

// Commit
[SCNTransaction commit];

or

// Create a animation
animation = [CABasicAnimation animationWithKeyPath:@"rotation"];

// Configure
animation.duration = 2.0;
animation.toValue = [NSValue valueWithSCNVector4:SCNVector4Make(0,1,0,M_PI*2)];
animation.repeatCount = MAXFLOAT;

// Play the animation
[aNode addAnimation:animation forKey:@"myAnimation"];

Animation Events

Smooth transitions

// 音效 Playing a sound at 60 percent
SCNAnimationEvent *anEvent = [SCNAnimationEvent animationEventWithKeyTime:0.6 block:aSoundBlock];
anAnimation.animationEvents = @[anEvent, anotherEvent];
// 轉換動作(idle->attack->idle)加上淡入淡出
anAnimation.fadeInDuration = 0.3;
anAnimation.fadeOutDuration = 0.3;

Actions

Easy to sequence, group, and repeat

[aNode runAction:[SCNAction repeatActionForever:[SCNAtion rotateByX:0 y:M_PI*2 z:0 duration:5.0]]];
// 如果需要取得移動中物件位置,可以用 presentationNode.position
node.position != node.presentationNode.position

Physics

// Dynamic body: Make a node dynamic
aNode.physicsBody = [SCNPhysicsBody dynamicBody];

// Manipulate with forces
// Apply an impulse
[aNode.phsicsBody appleyForce:aVector3 atPosition:aVector3 impulse:YES];

// Staic bodies: Make a node static
aNode.physicsBody = [SCNPhysicsBody staticBody];

// Kinematic body: Make a node kinematic(不受碰撞/重力影響,但是可以用程式的方式加入速度)
aNode.physicsBody = [SCNPhysicsBody kinematicBody];

// Physics shape: SceneKit 會自動建立,也可以用手動的方式指定,如下:
aNode.physicsBody.physicsShape = [SCNPhysicsShape shapeWithGeometry:aGeometry options:options];

// Physics behavior
SCNPhysicsHingeJoint *joint = [SCNPhysicsHingeJoint
  jointWithBodyA:nodeA.physicsBody axisA:[...] anchorA:[...]
  jointWithBodyB:nodeB.physicsBody axisB:[...] anchorB:[...]];
[scene.physicsWorld addBehavior:joint];

// Remove behavior
[scene.physicsWorld removeBehavior:joint];

Constraints

Applied sequentially at render time
Only affect presentation values

aNode.constraints = @[aConstraints, anotherConstraints, ...];

// Custom constraint on a node's transform
aConstrains = [SCNTransformConstrain transformConstrainInWorldSpace:Yes withBlock:
  ^SCNMatrix4(SCNNode *node, SCNMatrix4 transform) {
    transform.m43 = 0.0;
    return transform;
}];

// Makes a node to look at another node: 頭部/眼睛/攝影機都適用
nodeA.constraints = @[SCNLookAtConstraint lookAtConstrainWithTarget:nodeB];

// SCNIKConstraint: 拳頭朝目標物體揮動,連帶會牽動手臂及全身

Scriptability

可與 javascript 整合

  • Javascript bridge
  • Tools
  • Debugging

Rendering

// Color
material.diffuse.contents = [UIColor redColor];

// Image
material.diffuse.contents = @"slate.jpg";

// SKTexture
material.normal.content = [SKTexture textureByGeneratingNormalMap];

// Dynamic content:Video using SKVideo node

// Cube map
/*
        Top
Left   Back   Right   Front
      Bottom
*/
material.reflective.contents = @[@"right.png",@"left.png",...@"front"];

// Custom material: Shader Modifier
// 常用在液體流動材質的呈現或是光暈的表現
material.shaderModifiers = @{<Entry Point>:<GLSL Code>};

// SpriteKit Overlays
sceneView.overlaySKScene = aSKScene;

Effects

Particles

SCNParticleSystem

Shadows

  • static: 效能最好,但不會隨著物體轉動或移動,而跟著變化
  • Dynamic: 最吃效能
  • Projected: 效能介於 static 與 Dynamic 中間,可以指定圖形來呈現陰影
// Static
aMaterial.multiply.contents = aShadowMap;

// Dynamic
aLight.castsShadow = YES;

// Projected
aLight.shadowMode = SCNShadowModeModulated;
aLight.gobo = anImage;

Fog

aScene.fogColor = aColor;
aScene.fogStartDistance = 50;
aScene.fogEndDistance = 100;

Depth of Field

// 景深
aCamera.focalDistance = 16.0;
aCamera.focalBlurRadius = 8.0;

Core Image Filters

aNode.filters = @[gaussianBlurs, distortion, pixelate];

Multi-Pass Effects

合併多種效果

// Load a technique
SCNTechnique *technique = [SCNTechnique techniqueWithDictionary:aDictionary];

// Chain techniques
technique = [SCNTechnique techniqueBySequencingTechniques:@[t1,t2...]];

// Set a technique
aSCNView.technique = technique;

Summary

  • SceneKit available on iOS
  • Casual game ready
  • Full featured rendering
  • Extendable

Morphing

  • Can be loaded from DAE
  • Can be created programmatically
  • topology must match

Skinning

  • Can be loaded from DAE
  • Can not be created programmatically

Performance

Lighting
  • Minimize the number of lights
  • Prefer staic to dynamic shadows
  • Use the "multiply" material property
Texturing
  • Avoid unnecessarily large images
  • Lock ambient with diffuse
    aMaterial.locksAmbientWithDiffuse = YES;
    
  • Use mipmaps
    aMaterial.diffuse.mipFilter = SCNFilterModeLinear;
    
  • Levels of Detail(依遠近呈現不同精細度的物件)