我有我编写的代码,用于将镜像显示为具有每帧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矩阵的方式并不完全正确,谢谢你的帮助。
答案 0 :(得分:1)
我没有使用XNA,但很久以前我做了一些Managed C#DX,所以我不记得太多,但你确定mirrorLookAt
应该指向cameraFinalTarget吗?因为基本上Matrix.CreateLookAt
应该从向上向量创建一个矩阵 - 在你的例子中,'to'是镜像所针对的点。您需要计算从摄像机位置到镜像位置的矢量然后反映它,我在您的代码中看不到。
除非您的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);
虽然我不知道你的镜子是否正常。另外,我注意到一行我无法理解
if (camera.isCrouched) camerafinalPosition.Y -= (camera.characterOffset.Y * 6 / 20);
有什么意义?我们假设您的相机已经蹲下 - 它的Y值是否应该降低?我不知道你如何渲染你的主摄像头,但看看镜子的渲染位置 - 它比你的主眼还要低。我不知道你如何使用你的IsCrouched
成员,但如果你想降低相机,只需给自己写一个方法Crouch()
或类似的东西,这会使Y值稍微降低。稍后您使用DrawRoom
方法,在其中传递camera.position
参数 - 然而,它不会被蹲伏值“降低”,它只是“纯粹”的相机。位置。这可能是它没有正确渲染的原因。让我知道如果这对你有所帮助。