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
What's New in Android 2026
veronikapj
0
250
改善しないと、タスクが回らない。 “てんこ盛りポジション” を引き継いだ情シスの、入社3ヶ月の業務改善録
krm963
0
250
仕様駆動開発の消費期限
watany
7
3.6k
Japan Community Day at Kubecon + CloudNativeCon Japan 2026: Learning Container Privilege Control by Building My Own Low-Level Container Runtime
ternbusty
1
130
Apache Hive: そしてCloud Native Lakehouseへ
okumin
1
200
仕様駆動開発へのトライを機に チームに適合する手法を模索し続けている話
freee
PRO
0
400
PHP Application における Kubernetes 内 gRPC 通信
ganchiku
0
580
全PRの83%がAIレビューだけでマージできるようになった開発組織はその後どうなったか
athug
1
1.4k
TSX の <Hoge<Fuga>> という構文に驚いた話 / tsx-type-argument-syntax
kanaru0928
0
200
ここ半年くらいでAIに作らせたR用ツール
eitsupi
0
360
なぜ関数型プログラミングで「型」と「証明」が語られるのか #fp_matsuri
kajitack
3
1.1k
属人化した知識を、 AIが辿れる地図にする
pkshadeck
PRO
1
140
Featured
See All Featured
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
1
390
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.2k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.5k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
350
Utilizing Notion as your number one productivity tool
mfonobong
4
510
We Have a Design System, Now What?
morganepeng
55
8.2k
Prompt Engineering for Job Search
mfonobong
0
390
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
250
The SEO identity crisis: Don't let AI make you average
varn
0
530
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
4 Signs Your Business is Dying
shpigford
187
22k
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
2
3.7k
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/