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
100
Sign In with Apple (client + server). Петр Третьяков
cocoaheads
0
300
Эволюция антипаттернов в Java и Kotlin. Михаил Горюнов
cocoaheads
0
190
Рефакторинг в условиях быстрорастущего стартапа. Егор Фесенко
cocoaheads
0
76
Make Experiments Great Again, или Как iOS Браузер А/Б тестирование улучшал
cocoaheads
0
140
Лотерея в приложении: отрисовка, анимация и никакого мошенничества
cocoaheads
0
110
Микроинтеракции в iOS
cocoaheads
0
260
Пишем под iOS на Flutter
cocoaheads
0
170
Выходные с Kotlin/Native
cocoaheads
0
78
Other Decks in Programming
See All in Programming
Terraform標準の組織で AWS CDKをどう使うか
mu7889yoon
1
480
言語を使う側から、作る側へ。 自作 Lisp で得た新たな気づき。
andpad
0
150
php-fpmのプロセスが枯渇した日-調査・対処・そして本当にやるべきだったこと-
shibuchaaaan
0
220
改善しないと、タスクが回らない。 “てんこ盛りポジション” を引き継いだ情シスの、入社3ヶ月の業務改善録
krm963
0
250
OpenSpecのproposalにbrainstormingを持たせてみた
tigertora7571
1
200
為什麼你並不需要ViewModel / No, you don't need a ViewModel
lovee
1
480
仕様駆動開発へのトライを機に チームに適合する手法を模索し続けている話
freee
PRO
0
400
20260722_microCMSで考える、AI時代のコンテンツ運用設計
yosh1
0
350
PHPだって関数型したい 〜できること、できないこと〜 / fp-in-php
jsoizo
1
270
変わらないものが、変わるものを決める — 意図駆動開発 × イベントソーシング × イミュータブル | What Doesn't Change Decides What Can — IDD × Event Sourcing × Immutability
tomohisa
0
1.2k
言葉の格闘技のススメ~紙とペンと言葉から始める、キャリアの描き方~
progresscicada
1
120
琵琶湖の水は止められてもNet--HTTPのリトライは止められない / You might be able to stop the water flow of Lake Biwa but you can't stop Net::HTTP retries
luccafort
PRO
0
560
Featured
See All Featured
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
270
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
470
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
200
Navigating Team Friction
lara
192
16k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
My Coaching Mixtape
mlcsv
0
190
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
250
Thoughts on Productivity
jonyablonski
76
5.3k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
530
Build your cross-platform service in a week with App Engine
jlugia
234
19k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
440
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/