0

我有我编写的代码,用于将镜子显示为平面,每帧都有来自 RenderTarget2D 的纹理。

这一切都很好,但我仍然认为反射的方式有问题(比如,镜子没有精确地看在它应该看的地方)。

有一张镜子的截图,看起来还不错,失真主要发生在玩家靠近镜子时。

镜像样本图像

这是我创建镜像纹理的代码,请注意镜像在 X 轴上旋转了 15 度。

RenderTarget2D rt;

...

rt = new RenderTarget2D(device, (int)(graphics.PreferredBackBufferWidth * 1.5), (int)(graphics.PreferredBackBufferHeight * 1.5));

...

device.SetRenderTarget(rt);
device.Clear(Color.Black);

Vector3 camerafinalPosition = camera.position;
if (camera.isCrouched) camerafinalPosition.Y -= (camera.characterOffset.Y * 6 / 20);

Vector3 mirrorPos = new Vector3((room.boundingBoxes[8].Min.X + room.boundingBoxes[8].Max.X) / 2, (room.boundingBoxes[8].Min.Y + room.boundingBoxes[8].Max.Y) / 2, (room.boundingBoxes[8].Min.Z + room.boundingBoxes[8].Max.Z) / 2);

Vector3 cameraFinalTarget = new Vector3((2 * mirrorPos.X) - camera.position.X, (2 * mirrorPos.Y) - camerafinalPosition.Y, camera.position.Z);
cameraFinalTarget = Vector3.Transform(cameraFinalTarget - mirrorPos, Matrix.CreateRotationX(MathHelper.ToRadians(-15))) + mirrorPos;

Matrix mirrorLookAt = Matrix.CreateLookAt(mirrorPos, cameraFinalTarget, Vector3.Up);

room.DrawRoom(mirrorLookAt, camera.projection, camera.position, camera.characterOffset, camera.isCrouched);

device.SetRenderTarget(null);

rt然后使用纹理绘制镜子。我认为反射物理或我创建 LookAt 矩阵的方式并不完全正确,感谢您的帮助。

4

1 回答 1

1

我没有使用XNA,但我很久以前做过一些Managed C# DX,所以我不记得太多了,但是您确定mirrorLookAt应该指向cameraFinalTarget吗?因为基本上Matrix.CreateLookAt应该从从上到上的向量创建一个矩阵 - 在您的示例中,“到”是镜像目标的一个点。您需要计算从相机位置到镜像位置的矢量,然后反射它,我在您的代码中没有看到。

除非您的room.DrawRoom方法不计算另一个mirrorLookAt矩阵,否则我很确定您的镜像目标向量是问题所在。

编辑:您的反射向量将是

Vector3 vectorToMirror = new Vector3(mirrorPos.X-camera.position.Y, mirrorPos.Y-camera.position.Y, mirrorPos.Z-camera.position.Z);
Vector3 mirrorReflectionVector = new Vector3(vectorToMirror-2*(Vector3.Dot(vectorToMirror, mirrorNormal)) * mirrorNormal);

另外我不记得 mirrorReflectionVector 是否不应该倒置(无论是指向镜像还是来自镜像)。只需检查两种方式,您就会看到。然后你创建你mirrorLookAt

Matrix mirrorLookAt = Matrix.CreateLookAt(mirrorPos, mirrorReflectionVector, Vector3.Up);

虽然我不知道你镜子的法线在哪里。另外,我注意到 1 行我不太明白

if (camera.isCrouched) camerafinalPosition.Y -= (camera.characterOffset.Y * 6 / 20);

那有什么意义呢?让我们假设你的相机是蹲着的——它的 Y 值不应该已经降低了吗?我不知道你如何渲染你的主相机,但是看看镜子的渲染位置 - 它比你的主眼低得多。我不知道您如何使用您的IsCrouched会员,但是如果您想降低相机,只需给自己写一个方法Crouch()或类似的东西,这会降低 Y 值。稍后您将使用您的DrawRoom方法,在该方法中传递camera.position参数-然而,它并没有被蹲伏值“降低”,它只是“纯”camera.position。这可能是它无法正确渲染的原因。让我知道这是否对您有任何帮助。

于 2013-08-22T13:01:40.467 回答