我有一个使用正交相机的 Screen 类,并想在其上放置 3D 模型。
@Override
public void show() {
....
mCamera = new OrthographicCamera();
mCamera.setToOrtho(false, width * sclWidth, height * sclWidth);
....
//3d instance initialization
modelBatch = new ModelBatch();
ModelBuilder modelBuilder = new ModelBuilder();
model = modelBuilder.createBox(0.5f,0.5f,0.5f, new Material(ColorAttribute.createDiffuse(Color.GREEN)), VertexAttributes.Usage.Position| VertexAttributes.Usage.Normal);
modelInstance = new ModelInstance(model, 128,128,128);
modelInstance.transform.set(mCamera.invProjectionView);
}
@Override
public void render(float delta) {
Gdx.gl.glClearColor(63 / 255f, 128 / 255f, 70 / 255f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
//mCamera.rotateAround(Vector3.Zero, new Vector3(0,1,0),1f);
mCamera.update();
mBatch.setProjectionMatrix(mCamera.combined);
mBatch.begin();
mBatch.draw(img, 128*10, 0);
mBatch.end();
modelBatch.begin(mCamera);
modelBatch.render(modelInstance);
modelBatch.end();
}
Run Code Online (Sandbox Code Playgroud)
它处于 2d 视图中,我可以根据屏幕宽度和高度将任何带有 x 和 y 的 2d 精灵放在屏幕上。
但做3D模型时,情况就完全不同了。
3D模型根据相机屏幕拉伸并渲染在屏幕中央。我找不到 3d 模型 setX 或 setY/SetZ 函数。
3D 模型应该如何定位以及应该使用哪些功能?任何对教程的建议或指导将不胜感激。
更新:相机位置:(768.0,192.0,0.0)相机投影:[0.0012019231|0.0|0.0|-0.0] [0.0|0.0021378205|0.0|-0.0] [0.0|0.0|-0.02|-1.0] [0.0|0.0 |0.0|1.0]
首先,您在坐标 128, 128, 128 处实例化了模型实例。我不确定相机的位置,但如果您想要一个居中的对象,模型实例的 X 和 Y 应该与相机位置。
另外,如果您希望整个模型可见,则需要将其沿 Z 方向移开。相机俯视 -Z 轴,因此模型实例的位置 Z 必须小于相机的 Z 位置才可见。
您的主要问题是这一行,应将其删除:
modelInstance.transform.set(mCamera.invProjectionView);
Run Code Online (Sandbox Code Playgroud)
您绝对不想应用相机的投影矩阵并将其用作模型的变换矩阵。
顶点位置通常(如在 ModelBatch 的默认着色器中)通过将其位置乘以一系列矩阵来从世界坐标映射到屏幕坐标。变换矩阵描述了 ModelInstance 的位置、旋转和缩放,因此它将原始模型的顶点位置转换到世界空间中。然后,视图矩阵将顶点转换到其相机相对位置(相机空间,也称为视图空间)。然后投影矩阵将顶点平移到屏幕空间(将其投影到矩形屏幕)。由于视图矩阵和投影矩阵都是由相机定义的,因此可以将它们预先相乘并一次性传递给批处理 ( camera.combined
)。
在着色器中,每个顶点位置乘以矩阵以将其放入屏幕空间。
因此,要在世界中移动模型实例,您需要对其变换矩阵执行操作,例如modelInstance.transform.translate(x,y,z)
。通常您不需要调用set
它。该生产线在幕后为您modelBatch.begin(mCamera);
处理矩阵。camera.combined
在 2D 中使用 SpriteBatch 时,您将直接将精灵放置在世界空间中,因为没有具有已定义顶点位置的源模型。这就是为什么在使用 SpriteBatch 时通常不需要使用变换矩阵(尽管它可以用于将整个精灵平面移动到 3D 世界空间中的某个位置)。