我想使用正交投影在我的应用程序中显示3D场景。在我的代码中,我在场景中放了一个盒子,并像打击一样设置了正交投影。在(0,0,500)处的相机将查看-z方向,并在世界原点处进行框选。因此相机应该能够捕捉盒子。

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)
但是我什么也看不到。我发现如果将orthographicScale设置为width/2.0可以正常工作。
pov.orthographicScale = Double(width/2);
问题1:我不知道为什么这样。我读了苹果的文档,但仍然感到困惑。 https://developer.apple.com/documentation/scenekit/scncamera/1436612-orthographicscale?language=objc

orthographicScale
指定使用正交投影时相机的放大倍数。

为什么我需要放大正投影?我已经通过GLKMatrix4MakeOrtho设置了它的尺寸。
我不确定是否与视口转换有关?因为OpenGL中的视口转换计算如下:https://docs.microsoft.com/en-us/windows/desktop/opengl/glviewport
ios - 对SceneKit中相机的正交投影感到困惑-LMLPHP
问题2:我也发现如果我像打击一样创建投影矩阵,其工作原理与以前相同。
let glMat = GLKMatrix4MakeOrtho(0, width, 0, width, 1, 1000)
在OpenGL中,这意味着不同的查看框,并且将显示不同的场景分区。
任何帮助表示赞赏!

最佳答案

我想,由于现在不推荐使用iOS和macOS的GLKit这么多的类,因此无法使用GLKMatrix4MakeOrtho在场景中看到3D对象。

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

ios - 对SceneKit中相机的正交投影感到困惑-LMLPHP

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

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

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;
}

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

但要记住!不建议使用许多GL功能,因此最好使用 Metal 框架。 Look at deprecated classes of GLKit

关于ios - 对SceneKit中相机的正交投影感到困惑,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52428397/

10-10 18:34
查看更多