#objective-c #swift #scenekit
#objective-c #swift #scenekit
Вопрос:
Согласно WWDC 2017, motionBlurIntensity была добавлена в качестве свойства в SCNCamera. Я пробовал следующее, но не смог заставить SceneKit размыть мою сцену при перемещении камеры:
- Установите wantsHDR в true
- Добавьте SCNDisableWideGamut в виде логического значения со значением YES в каждый Info.plist в моем проекте Xcode
- Переместите SCNBox, изменив положение его SCNNode перед камерой, установив для motionBlurIntensity значение 1.0
- Переместите саму камеру, изменив положение ее SCNNode, установив для motionBlurIntensity значение 1.0
- Анимируйте камеру, используя SCNTransaction с motionBlurIntensity, установленной на 1.0, вместо того, чтобы менять ее положение каждый кадр
- Проделайте вышеуказанное, установив интенсивность motionBlurIntensity равной 500 или выше
Я запускаю следующий код для каждого отображаемого кадра следующим образом:
camNode.position = SCNVector3Make(cx, cy, cz);
camNode.eulerAngles = SCNVector3Make(rotx, roty, rotz);
camNode.camera.wantsDepthOfField = enableDOF;
camNode.camera.wantsHDR = enableHDR;
camNode.camera.zNear = camNearVal;
camNode.camera.zFar = camFarVal;
camNode.camera.focalLength = camFocalLength;
camNode.camera.usesOrthographicProjection = usingOrthoProjection;
if(!usingOrthoProjection)
{
camNode.camera.projectionTransform = SCNMatrix4FromGLKMatrix4(GLKMatrix4MakeWithArray(projection));
}
else
{
// Ortho options
camNode.camera.orthographicScale = orthoScale;
if(cam_projectionDir == 1)
camNode.camera.projectionDirection = SCNCameraProjectionDirectionHorizontal;
else
camNode.camera.projectionDirection = SCNCameraProjectionDirectionVertical;
}
// DOF
camNode.camera.sensorHeight = dof_sensorHeight;
camNode.camera.focusDistance = dof_focusDistance;
camNode.camera.fStop = dof_fStop;
camNode.camera.apertureBladeCount = dof_apertureBladeCount;
camNode.camera.focalBlurSampleCount = dof_focalBlurSampleCount;
// Motion blur
camNode.camera.motionBlurIntensity = motionBlurIntensity;
И здесь SCNRenderer устанавливает свой pointOfView для камеры:
mainRenderer.scene = mainScene;
mainRenderer.pointOfView = camNode;
id<MTLCommandBuffer> myCommandBuffer = [_commandQueue commandBuffer];
[mainRenderer updateAtTime: currentFrame];
[mainRenderer renderWithViewport:CGRectMake(0,0,(CGFloat)_viewWidth, (CGFloat)_viewHeight) commandBuffer:myCommandBuffer passDescriptor:_renderPassDescriptor];
[myCommandBuffer commit];
Эффекты HDR, такие как Bloom и SSAO, работают должным образом, но не размытие при движении.
Я использую Xcode версии 10.1 на macOS Mojave.
Я запустил пример приложения Badger, и motion blur в этом проекте работает на моем компьютере.
Я что-то здесь упускаю? Любая информация была бы высоко оценена.
Комментарии:
1. Попробуйте один раз установить интенсивность размытия движения камеры на 1.0, а не на каждом кадре.
2. Спасибо за ответ. Проверял, не повезло. Тем не менее, я думаю, у меня есть представление о том, что здесь не так. Я пытаюсь визуализировать по одному кадру за раз. Возможно, данные предыдущего кадра недоступны SceneKit, если они не выполняются непрерывно? Я знаю, что в примере Badger для рендеринга материала используется SCNView.
Ответ №1:
Значение
motionBlurIntensity
свойства по умолчанию равно0.0
. Это не приводит к эффекту motion blur. Более высокие значения (максимально приближающиеся к 1.0) создают более выраженные эффекты motion blur. Размытие при движении не поддерживается, когда включена цветопередача с широким диапазоном. Рендеринг с широким охватом включен по умолчанию на поддерживаемых устройствах; чтобы отказаться, установите ключ SCNDisableWideGamut в файле Info.plist вашего приложения.
Протестируйте это с помощью моего кода:
let cameraNode1 = SCNNode()
cameraNode1.camera = SCNCamera()
cameraNode1.camera?.motionBlurIntensity = 3 // MOTION BLUR
scene.rootNode.addChildNode(cameraNode1)
let move = CABasicAnimation(keyPath: "translation")
move.fromValue = NSValue(scnVector3: SCNVector3(x: 7, y: -5, z: 0))
move.toValue = NSValue(scnVector3: SCNVector3(x: 7, y: 5, z: 0))
move.duration = 0.5
move.repeatCount = 20
move.autoreverses = true
move.repeatCount = .infinity
let sphereNode1 = SCNNode()
sphereNode1.geometry = SCNSphere(radius: 2)
sphereNode1.addAnimation(move, forKey: "back and forth")
scene.rootNode.addChildNode(sphereNode1)
Работает отлично.