Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
SceneKit на практике
Search
CocoaHeads
September 29, 2018
Programming
150
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
SceneKit на практике
CocoaHeads
September 29, 2018
More Decks by CocoaHeads
See All by CocoaHeads
Тесты: Повторение. Виктор Суриков
cocoaheads
0
98
Sign In with Apple (client + server). Петр Третьяков
cocoaheads
0
290
Эволюция антипаттернов в Java и Kotlin. Михаил Горюнов
cocoaheads
0
190
Рефакторинг в условиях быстрорастущего стартапа. Егор Фесенко
cocoaheads
0
71
Make Experiments Great Again, или Как iOS Браузер А/Б тестирование улучшал
cocoaheads
0
130
Лотерея в приложении: отрисовка, анимация и никакого мошенничества
cocoaheads
0
110
Микроинтеракции в iOS
cocoaheads
0
250
Пишем под iOS на Flutter
cocoaheads
0
170
Выходные с Kotlin/Native
cocoaheads
0
76
Other Decks in Programming
See All in Programming
「なぜそう決めたのか」を残し続ける仕組み ― Notion AI カスタムエージェント × Slack連携による設計判断の自動記録 - NIKKEI Tech Talk #47
niftycorp
PRO
0
180
コンテキストの使い捨てをやめる — ビジネスルール駆動開発と miko —
ioki
0
210
TSKaigi Night Talks 2026_TypeScriptでサプライチェーンの整合性を型に閉じ込める
geekplus_tech
0
350
AIとASP.NET Coreで雑Webアプリを作った話
mayuki
0
640
気づいたらRubyで100作品 ー クリエイティブコーディングが生活の一部になるまで / 100 Ruby Sketches Later: How Creative Coding Became Part of My Life
chobishiba
3
580
依存関係から依存物へ―Dependencyという言葉の歴史をひも解く
j_lee
0
120
JavaDoc 再入門
nagise
1
360
Go1.27で導入されるジェネリクスメソッドでできること
mackee
0
130
過去最大のMCPアップデート! 2026-07-28 RC版の謎に迫る
licux
6
340
Claspは野良GASの夢をみるか
takter00
0
190
The NotImplementedError Problem in Ruby
koic
1
810
Oxlintのカスタムルールの現況
syumai
6
1.1k
Featured
See All Featured
Building Adaptive Systems
keathley
44
3.1k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
620
Color Theory Basics | Prateek | Gurzu
gurzu
0
360
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
290
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
Why Our Code Smells
bkeepers
PRO
340
58k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
Odyssey Design
rkendrick25
PRO
2
700
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
590
The agentic SEO stack - context over prompts
schlessera
0
820
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
490
How to make the Groovebox
asonas
2
2.2k
Transcript
Вячеслав Гилевич, разработчик SceneKit на практике
None
› Загрузка моделей › Уменьшение размера ресурсов › Констрейнты ›
Зеркальные отражения › Видеотекстуры › Модификаторы шейдров › Запись видео SceneKit на практике 3
Немного про SceneKit
SceneKit — фреймворк для 3D сцен 5 Как создать сцену?
› Геометрия › Материалы › Освещение › Камеры › Анимация
SceneKit — фреймворк для 3D сцен. Кроме графики, в
нём есть: › Генератор частиц › Физический движок 6
Загрузка моделей в SceneKit
› Из бандла › По URL › Через MDLAsset ›
Через ReferenceNode Варианты загрузки 3D модели 8
SCNScene.init(url:options:) › Настраиваемый импорт › Поддерживает .scn и .dae файлы
› Синхронная загрузка › Необходимо копировать структуру из сцены в ноду URL + настройки импорта 9
SCNScene.init(mdlAsset:) › Загружает obj, ply, stl, usd, usda, usdc, usdz,
abc, bsp, vox, md3 › Синхронная загрузка › Необходимо копировать структуру сцены › Оверхед на конвертацию Используем MDLAsset 10
SCNReferenceNode.init(url:) › Поддерживает .scn и .dae файлы › Ленивая загрузка
› Теряет глобальные параметры сцены Используем SCNReferenceNode 11
› Конвертируйте в .scn заранее › Проверяйте сцену в Xcode
› Конвертируйте все ресурсы в .heic › Загружайте сцену с ассетами архивом Загрузка моделей: советы 12
Добавление эффектов: Констрейнты
› SCNBillboardConstraint › SCNLookAtConstraint › SCNDistanceConstraint › SCNAvoidOccluderConstraint › SCNSliderConstraint
› SCNReplicatorConstraint › SCNIKConstraint Констрейнты 14
Просто повторяет позицию, поворот и размер, и добавляет дополнительное оффсеты.
SCNReplicatorConstraint 15
Параметры констрейнтов 16 Стандартные параметры Уменьшили силу в 10 раз
Параметры констрейнтов 17 Стандартные параметры Уменьшили силу в 10 раз
и убрали инкрементальность
Используется для: › Деревьев вдалеке › Мелких объектов › Спецэффектов,
вроде огня или взрыва › Привязка камеры к персонажу SCNBillboardConstraint | SCNLookAtConstraint 18
SCNDistanceConstraint | SCNSliderConstraint 19 Держит дистанцию между выбранными объектами Держит
дистанцию до всех физических тел
› Inverse Kinematics из коробки › Нет возможности задать ориентацию
› Нет ограничений углов в зависимости от оси SCNIKConstraint 20
Добавление эффектов: Тени
Тени для ARKit’a: › Включи отложенные тени › Отключи запись
всех компонент Тени на прозрачной поверхности 22
Добавление эффектов: Зеркала
Как сделать? › SCNFloor › Своя модель поверх него Зеркальные
отражения 24
Зеркальные отражения с картой нормалей 25 Вода на зеркале Кривое
зеркало
Добавление эффектов: Видеотекстуры
Как сделать? › SKScene › SKVideoNode › SCNMaterialProperty Видеотекстуры 27
Как заставить работать? › Поправить Binary Plist › Внутри Binary
Plist’а › Внутри другуго Binary Plist’а Видеотекстуры: сохранение 28
Добавление эффектов: Shader Modifiers
› Доступны в визуальном редакторе › Поддерживают glsl и metal
shading language › Доступны результаты работы стандартных шейдеров Shader Modifiers 30
Мех и Parallax Mapping 31 Мех Parallax Mapping
Ray Casting 32
Запись видео
Запись видео 34 На девайсе Записывается
Запись видео: ReplayKit 35 RPScreenRecorder.shared() Начать запись: Закончить запись: RPScreenRecorder.shared()
func startRecording() func stopRecording(callback:)
› Работает в пару строк кода › Нельзя записывать конкретную
вьюху › Неудобный стандартный превью Запись видео: ReplayKit 36
Запись видео: основы 37 AVAssetWriter Процесс записи: Закончить запись: AVAssetWriterInput
func appendPixelBuffer(…) func markAsFinished() AVAssetWriterInput AVAssetWriterInputPixelBufferAdaptor AVAssetWriter func finishWriting()
UIImage → CVPixelBuffer 38 var pixelBuffer: CVPixelBuffer? = nil guard
CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_32BGRA , nil, &pixelBuffer) == kCVReturnSuccess else { return } CVPixelBufferLockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags.init(rawValue: 0)) let data = CVPixelBufferGetBaseAddress(pixelBuffer!) let rgbColorSpace = CGColorSpaceCreateDeviceRGB() let bitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue) let context = CGContext(data: data, width: width, height: height, bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer!), space: rgbColorSpace, bitmapInfo: bitmapInfo.rawValue) context?.draw(image, in: CGRect(x: 0, y: 0, width: image.width, height: image.height)) CVPixelBufferUnlockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
UIImage → CVPixelBuffer 39 CVPixelBufferCreate(… width:height:pixelFormat: …) CVPixelBufferLockBaseAddress(_ pixelBuffer:) CVPixelBufferGetBaseAddress(_
pixelBuffer:) CGContext(data: ... bitsPerComponent: bytesPerRow:… colorSpace: ...) CVPixelBufferUnlockBaseAddress(_ pixelBuffer:) func draw(image: UIImage)
Теперь нужно это делать каждый кадр 40 CADisplayLink(target:selector) Начать запись:
Закончить запись: func add(to:forModes:) func invalidate()
Производительность 41
Оптимизации: раунд 1! 42 DispatchQueue.global() func async(execute:)
Оптимизации: раунд 1! 43
Оптимизации: раунд 1.5! 44 DispatchQueue.global() func async(execute:) guard isRecording else
{ return } isRecording = true isRecording = false
Оптимизации: раунд 1.5! 45
Оптимизации: раунд 2! 46 Причина Следствие
Оптимизации: раунд 2! 47 ? CAMetalDrawable CAMetalLayer SCNView ? ✓
via backingLayer()
Пул CAMetalLayer’а 48 Drawable 0 Drawable 1 Drawable 2 Drawable
3 func present()
Оптимизации: раунд 2! 49 ✓ via nextDrawable() CAMetalDrawable CAMetalLayer SCNView
✓ via backingLayer() ?
Оптимизации: раунд 2! 50 CVPixelBufferCreate(… width:height:pixelFormat: …) CVPixelBufferLockBaseAddress(_ pixelBuffer:) CVPixelBufferGetBaseAddress(_
pixelBuffer:) CGContext(data: ... bitsPerComponent: bytesPerRow:… colorSpace: ...) CVPixelBufferUnlockBaseAddress(_ pixelBuffer:) func draw(image: UIImage) CAMetalDrawable var texture: MTLTexture func getBytes(data: …)
Оптимизации, раунд 3? 51
Оптимизации, раунд 3! 52
Оптимизации, раунд 3! 53
Оптимизации, раунд 3! 54
Оптимизации, раунд 3! 55
Оптимизации, раунд 3! 56
Оптимизации, раунд 3! 57
› Загрузка моделей › Уменьшение размера ресурсов › Констрейнты ›
Зеркальные отражения › Видеотекстуры › Модификаторы шейдров › Запись видео SceneKit на практике 58
За выходные дня города: › Пройдено > 2000 км ›
Показано > 3000 объектов › Записано > 1000 видео Немного статистики 59
Подписывайтесь на наш блог! https://medium.com/yandex-maps-ios/