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

Natalia Berdys: Random Talk: The Consistent World of Noise

1fa9cb8c7997c8c4d3d251fb5e41f749?s=47 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

1fa9cb8c7997c8c4d3d251fb5e41f749?s=128

Realm

September 01, 2016
Tweet

Transcript

  1. RANDOM TALK: THE CONSISTENT WORLD OF NOISE

  2. None
  3. Which is random? ⚪""⚪"⚪"⚪""⚪"⚪"""⚪⚪""⚪"⚪⚪"""⚪"⚪⚪⚪ or ⚪⚪"⚪⚪""⚪"⚪⚪⚪⚪⚪"⚪⚪""⚪⚪"⚪⚪⚪⚪⚪⚪⚪⚪""

  4. WHICH IS RANDOM? 1 ⚪""⚪"⚪"⚪""⚪"⚪"""⚪⚪""⚪"⚪⚪"""⚪"⚪⚪⚪ OR ⚪⚪"⚪⚪""⚪"⚪⚪⚪⚪⚪"⚪⚪""⚪⚪"⚪⚪⚪⚪⚪⚪⚪⚪"" 1 Barrow, John

    D. (2008). 100 Essential Things You Didn't Know You Didn't Know.
  5. PATTERNS EVERYWHERE

  6. let randomness: Bool

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

    > uniform: ✅ > independent: ✅ Pseudo-random number generators > method: ! "  > uniform: ✅ > independent: ❌ %
  8. Pseudo-random number generator

  9. That's, like, so pseudo-random.

  10. Random numbers should not be generated with a method chosen

    at random — Donald Knuth
  11. None
  12. GKRandomSource

  13. LINEAR CONGRUENTIAL RANDOM NUMBER GENERATOR let randomSource = GKLinearCongruentialRandomSource() Fast,

    but biased
  14. THE MERSENNE TWISTER let randomSource = GKMersenneTwisterRandomSource() Period: Slower, but

    more random
  15. THE ARC4 let randomSource = GKARC4RandomSource() Implements the ARC4 algorithm

    Independent from arc4random family. Middle ground between speed and randomness.
  16. SHUFFLING

  17. SHUFFLING let fruitDeck = ["!", """, "#", "$"] let shuffledDeck

    = GKARC4RandomSource.sharedRandom() .arrayByShufflingObjects(in: fruitDeck) ! " # $
  18. None
  19. We're making it less random to make it feel more

    random — Steve Jobs
  20. DISTRIBUTION

  21. GAMEPLAYKIT GKGaussianDistribution GKShuffledDistribution GKRandomDistribution

  22. GAUSSIAN (NORMAL) DISTRIBUTION

  23. let ! = GKGaussianDistribution.d6() for roll in 1...6 { !.nextInt()

    } ⚃ ⚄ ⚃ ⚃ ⚂ ⚂
  24. let ! = GKShuffledDistribution.d6() for roll in 1...6 { !.nextInt()

    } ⚅ ⚁ ⚃ ⚀ ⚂ ⚄
  25. let ! = GKRandomDistribution.d6() for roll in 1...6 { !.nextInt()

    } ⚀ ⚀ ⚀ ⚅ ⚄ ⚄
  26. Random distribution of size let random = GKRandomDistribution(lowestValue: 3, highestValue:

    10) raccoon.setScale = CGFloat(random.nextInt()) * 0.1
  27. Gaussian distribution of size let gaussian = GKGaussianDistribution(lowestValue: 3, highestValue:

    10) raccoon.setScale = CGFloat(gaussian.nextInt()) * 0.1
  28. 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()))) }
  29. 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()))) }
  30. RANDOM

  31. ?

  32. PROCEDURAL NOISE

  33. PERLIN NOISE

  34. 1D PERLIN NOISE

  35. 2D PERLIN NOISE

  36. 3D PERLIN NOISE

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

    GKCylindersNoiseSource & GKSpheresNoiseSource ' GKCheckerboardNoiseSource 㽪 GKConstantNoiseSource
  38. let noiseSource = GKPerlinNoiseSource() let noise = GKNoise(noiseSource:noiseSource)

  39. noiseSource.octaveCount = 1 3 6

  40. noiseSource.frequency = 1 2 4

  41. ADJUST NOISE PARAMETERS let noiseSource = GKPerlinNoiseSource() noiseSource.frequency = 1

    noiseSource.octaveCount = 6 noiseSource.lacunarity = 2 noiseSource.persistence = 0.5 let noise = GKNoise(noiseSource:noiseSource)
  42. 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))
  43. YOU CAN: > apply operations to noise values > combine

    noise objects > distort noise > apply geometric transformations
  44. 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)
  45. 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
  46. myCamera.position.x = CGFloat(noise.value(atPosition: (vector2(Float(waveStep), 0))))*100 myCamera.position.y = CGFloat(noise.value(atPosition: (vector2(0, Float(waveStep)))))*100

    waveStep += 0.01
  47. 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))))
  48. GKRidgedNoiseSource let source = GKRidgedNoiseSource() source.lacunarity = 2 source.frequency =

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

    3 source.octaveCount = 6 noise.move(by: (vector3(0.0, 0.01, 0.0)
  50. GKRidgedNoiseSource

  51. GKVoronoiNoiseSource

  52. GKCylindersNoiseSource

  53. BIOMES

  54. 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])
  55. 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
  56. GKPerlinNoiseSource GKRidgedNoiseSource

  57. None
  58. DETERMINISM !"

  59. !

  60. 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.
  61. THANK YOU! NATALIA BERDYS @BATALIA TRY! SWIFT NYC 2016