Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Natalia Berdys: Random Talk: The Consistent Wor...

Realm
September 01, 2016

Natalia Berdys: Random Talk: The Consistent World of Noise

Bio:
Natalia Berdys is an independent iOS developer from Poland. Within 2 years, she managed to become a self-taught developer, get a Mobile Engineering degree, speak at Apple WWDC and take her apps to #1 in 47 countries. Since she also holds a Master's Degree in American Literature, she has a very humanistic and poetic view of programming. Previously with Tutu Lab, now evolving into her next form.

Abstract:
Chance permeates our human existence - but it’s our instinct to seek order in chaos. In this talk, we’ll explore the fishy realm of randomness, and when it’s just too unnatural for our apps - let’s bend it to our will by making it evolve into coherent patterns with the GameplayKit framework. We’ll use the latest iOS 10 APIs and procedural noise to generate harmonious digital worlds, landscapes and textures - a comforting way to mine some creativity from silicon chips.

Twitter: https://twitter.com/batalia

Realm

September 01, 2016
Tweet

More Decks by Realm

Other Decks in Technology

Transcript

  1. True random number generators > method: ! (" ☢ $)

    > uniform: ✅ > independent: ✅ Pseudo-random number generators > method: ! "  > uniform: ✅ > independent: ❌ %
  2. THE ARC4 let randomSource = GKARC4RandomSource() Implements the ARC4 algorithm

    Independent from arc4random family. Middle ground between speed and randomness.
  3. SHUFFLING let fruitDeck = ["!", """, "#", "$"] let shuffledDeck

    = GKARC4RandomSource.sharedRandom() .arrayByShufflingObjects(in: fruitDeck) ! " # $
  4. RANDOM DISTRIBUTION OF SPEED let random = GKRandomDistribution(lowestValue: 10, highestValue:

    25) for ufo in ufoNode.children { ufo.run(SKAction.moveTo(y: -1500, duration: TimeInterval(random.nextInt()))) }
  5. GAUSSIAN DISTRIBUTION OF SPEED let gaussian = GKGaussianDistribution(lowestValue: 10, highestValue:

    25) for ufo in ufoNode.children { ufo.run(SKAction.moveTo(y: -1500, duration: TimeInterval(gaussian.nextInt()))) }
  6. ?

  7. GKNoiseSource ! GKPerlinNoiseSource ⛰ GKRidgedNoiseSource # GKBillowNoiseSource $ GKVoronoiNoiseSource %

    GKCylindersNoiseSource & GKSpheresNoiseSource ' GKCheckerboardNoiseSource 㽪 GKConstantNoiseSource
  8. ADJUST NOISE PARAMETERS let noiseSource = GKPerlinNoiseSource() noiseSource.frequency = 1

    noiseSource.octaveCount = 6 noiseSource.lacunarity = 2 noiseSource.persistence = 0.5 let noise = GKNoise(noiseSource:noiseSource)
  9. ADD COLOR let noiseSource = GKPerlinNoiseSource() let noise = GKNoise(noiseSource:noiseSource)

    noise.gradientColors = [-1 : !, 0 : ", 1 : ⚪] MAP TO TEXTURE let map = GKNoiseMap(noise: noise) let sprite = SKSpriteNode(texture: SKTexture(noiseMap: map))
  10. YOU CAN: > apply operations to noise values > combine

    noise objects > distort noise > apply geometric transformations
  11. ANIMATION let moveMap = SKAction.run { map = GKNoiseMap(noise: noise,

    size: vector2(2, 2), origin: (vector2(map.origin.x+0.01, 0)), sampleCount: vector2(300, 300), seamless: false) sprite.texture = SKTexture(noiseMap: map) } let moveMapForever = SKAction.repeatForever( (SKAction.sequence([moveMap, SKAction.wait(forDuration: 0.1)]))) sprite.run(moveMapForever)
  12. noise.move(by: (vector3(0.0, 0.01, 0.0))) let newMap = GKNoiseMap(noise: noise) let

    newTexture = SKTexture(noiseMap: newMap) sprite.texture = newTexture sprite2.texture = newTexture
  13. let timeStep = waveStep/3 + 0.3 * sin(M_2_PI * waveStep/3)

    let eyeBallFactorX = CGFloat( noiseHead.value(atPosition: (vector2(Float(timeStep), 0)))) let eyeBallFactorY = CGFloat( noiseHead.value(atPosition: (vector2(Float(timeStep+10)/2, 0))))
  14. GKRidgedNoiseSource let source = GKRidgedNoiseSource() source.lacunarity = 2 source.frequency =

    3 source.octaveCount = 6 noise.move(by: (vector3(0.0, 0.01, 0.0)
  15. GKRidgedNoiseSource let source = GKRidgedNoiseSource() source.lacunarity = 2 source.frequency =

    3 source.octaveCount = 6 noise.move(by: (vector3(0.0, 0.01, 0.0)
  16. COMBINING NOISE: HEIGHT MAP let combinedNoise = GKNoise( componentNoises: [noiseWater,

    noiseSand, noiseTrees, noiseMountains], selectionNoise: ridgedNoise, componentBoundaries: [-0.7, -0.6 ,0.5], boundaryBlendDistances: [0, 0.1, 0.3])
  17. USE WITH SCENEKIT let ball = SCNSphere(radius: 100) let materials

    = SCNMaterial() materials.locksAmbientWithDiffuse = true materials.diffuse.contents = UIImage(cgImage: (spriteCombined. texture?.cgImage())!) ball.firstMaterial = materials ball.isGeodesic = true
  18. !

  19. ACKNOWLEDGEMENTS: SOME GRAPHICS PROVIDED BY VECTEEZY.COM. 3D TEXTURE - PERLIN

    NOISE IMAGE BY AERON203 CC BY 3.0. SOURCES/FURTHER READING: Barrow, John D. (2008). 100 Essential Things You Didn't Know You Didn't Know. London: The Bodley Head. Mlodinow, Leonard (2008). The Drunkard's Walk: How Randomness Rules Our Lives. New York: Pantheon Books.