对 SceneKit 中相机的正交投影感到困惑 [英] Confused about Orthographic Projection of camera in SceneKit

查看:19
本文介绍了对 SceneKit 中相机的正交投影感到困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用正交投影在我的应用中显示 3D 场景.在我的代码中,我在场景中放置了一个框,并设置了视点的正交投影,如打击.(0,0,500) 处的相机看 -z 方向,并在世界的原点框.所以相机应该能够捕捉到盒子.

让 cameraNode = SCNNode()让 pov = SCNCamera()pov.usesOrthographicProjection = true让宽度 = UISreen.main.bounds.size.width让 glMat = GLKMatrix4MakeOrtho(-width/2, width/2, -width/2, width/2, 1, 1000)pov.projectionTransform = SCNMatrix4FromGLKMatrix4(glMat)cameraNode.camera = povcameraNode.position = SCNVector3.init(0, 0, 500)场景.rootNode.addChildNode(cameraNode)让 boxGeo = SCNBox.init(宽度:100,高度:100,长度:1,倒角半径:0)让 box = SCNNode.init(几何:boxGeo)场景.rootNode.addChildNode(box)

但我什么也看不见.我发现如果将 orthographicScale 设置为 width/2.0 将正常工作.

pov.orthographicScale = Double(width/2);

问题 1:我不知道为什么会这样.我阅读了苹果的文档,但仍然感到困惑.

问题 2: 我还发现如果我创建像 Blow 这样的投影矩阵,它的工作原理和以前一样.

让 glMat = GLKMatrix4MakeOrtho(0, width, 0, width, 1, 1000)

在OpenGL中表示不同的观察框,会显示不同的场景分区.

感谢任何帮助!

解决方案

我想,你在使用 GLKMatrix4MakeOrtho 的场景中看不到你的 3D 对象,因为有这么多类适用于 iOS 和 macOS 的 GLKit 现已弃用.

为了查看您的 3D 对象,您需要在 Attributes Inspector 中手动设置 Far Z Clipping 参数.这两个字段分别是正交相机截头体的 nearfar 剪切平面.默认值 Far=100 不允许您看到 100 单位以外的场景.

<块引用>

然后使用 Scale 属性为正交视图中的对象设置比例因子.

为了通过 GLKMatrix4MakeOrtho 以编程方式使用它,您需要导入 GLKitOpenGL 模块(以及所有必要的委托协议) 首先进入您的项目.

导入 GLKit导入 OpenGL//Obj-C GLKMatrix4GLK_INLINE GLKMatrix4 GLKMatrix4MakeOrtho(向左浮动,向右浮动,浮底,浮在上面,漂浮在Z附近,浮动远Z){浮动 ral = 右 + 左;浮动 rsl = 右 - 左;浮动标签 = 顶部 + 底部;浮动 tsb = 顶部 - 底部;浮动风扇 = farZ + nearZ;浮动 fsn = farZ - nearZ;GLKMatrix4 m = { 2.0f/rsl, 0.0f, 0.0f, 0.0f,0.0f, 2.0f/tsb, 0.0f, 0.0f,0.0f, 0.0f, -2.0f/fsn, 0.0f,-ral/rsl,-tab/tsb,-fan/fsn,1.0f};返回米;}

<块引用>

此外,在 iOS 上,GLKit 需要 OpenGL ES 2.0 上下文.在 macOS 中,GLKit 需要支持 OpenGL 3.2 Core Profile 的 OpenGL 上下文.

但请记住!许多 GL 功能已弃用,因此您最好使用 Metal 框架.查看已弃用的 GLKit 类.

I want to use orthographic projection to display 3D scene in my app. In my code I put a box in scene and set orthographic projection of Point of view like blow. Camera at (0,0,500) look at -z direction, and box at origin of world. So camera should be able to capture the box.

let cameraNode = SCNNode()
let pov = SCNCamera()
pov.usesOrthographicProjection = true
let width = UISreen.main.bounds.size.width
let glMat = GLKMatrix4MakeOrtho(-width/2, width/2, -width/2, width/2, 1, 1000)
pov.projectionTransform = SCNMatrix4FromGLKMatrix4(glMat)
cameraNode.camera = pov
cameraNode.position = SCNVector3.init(0, 0, 500)
scene.rootNode.addChildNode(cameraNode)

let boxGeo = SCNBox.init(width: 100, height: 100, length: 1, chamferRadius: 0)
let box = SCNNode.init(geometry: boxGeo)
scene.rootNode.addChildNode(box)

But I can see nothing. I find out If set orthographicScale to width/2.0 will works correctly.

pov.orthographicScale = Double(width/2);

Question 1 : I don't know why this works. I read docs of apple but still confused. https://developer.apple.com/documentation/scenekit/scncamera/1436612-orthographicscale?language=objc

orthographicScale

Specifies the camera’s magnification factor when using an orthographic projection.

Why I need magnify orthographic projection? I already set the dimension of it through GLKMatrix4MakeOrtho.

I'm not sure whether it is relate to viewport transform? Because viewport transform in OpenGL computed as follows: https://docs.microsoft.com/en-us/windows/desktop/opengl/glviewport

Question 2 : I also find If I create projection matrix like blow it works same as before.

let glMat = GLKMatrix4MakeOrtho(0, width, 0, width, 1, 1000)

In OpenGL it means different viewing box and will display different partition of scene.

Any help is appreciated!

解决方案

I suppose, you can't see your 3D objects in the scene using GLKMatrix4MakeOrtho, due to the fact that so many classes of GLKit for iOS and macOS are deprecated now.

In order to see your 3D object, you need to manually set Far Z Clipping parameter in Attributes Inspector. These two fields are near and far clipping planes of the frustum of your Orthographic Camera. A default value of Far=100 doesn't allow you see the scene further than 100 units away.

Then use a Scale property to set a scale factor for your objects in an ortho view.

In order to use it programmatically via GLKMatrix4MakeOrtho, you need to import GLKit and OpenGL modules (as well as all the necessary delegate protocols) into your project at first.

import GLKit
import OpenGL

// Obj-C GLKMatrix4

GLK_INLINE GLKMatrix4 GLKMatrix4MakeOrtho(float left, 
                                          float right,
                                          float bottom, 
                                          float top,
                                          float nearZ, 
                                          float farZ) {
    float ral = right + left;
    float rsl = right - left;
    float tab = top + bottom;
    float tsb = top - bottom;
    float fan = farZ + nearZ;
    float fsn = farZ - nearZ;

    GLKMatrix4 m = { 2.0f / rsl, 0.0f, 0.0f, 0.0f,
                     0.0f, 2.0f / tsb, 0.0f, 0.0f,
                     0.0f, 0.0f, -2.0f / fsn, 0.0f,
                     -ral / rsl, -tab / tsb, -fan / fsn, 1.0f };

    return m;
}

Also, on iOS, GLKit requires an OpenGL ES 2.0 context. In macOS, GLKit requires an OpenGL context that supports the OpenGL 3.2 Core Profile.

But remember! Many GL Features are deprecated, so you'd better use Metal framework. Look at deprecated classes of GLKit.

这篇关于对 SceneKit 中相机的正交投影感到困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆