gpt4 book ai didi

c# - 网格开始在相机旋转/移动时跳跃

转载 作者:行者123 更新时间:2023-11-30 17:57:21 27 4
gpt4 key购买 nike

一起嗨,

第一次在这里发帖,因为我该死的卡住了......

网格离原点 (0, 0, 0) 越远,在旋转或移动相机时它“跳跃”/“闪烁”得越多。很难描述这种效果:它就像网格在抖动/颤抖/颤抖一点点,随着距离原点的距离越来越远,这种颤抖变得越来越大。
对我来说,它开始在距原点约 100000 个单位的距离处可见,例如 (0, 0, 100000)。平移轴和网格类型(从 Mesh.Create 创建的默认网格...或使用 assimp.NET 导入的 3ds 网格)都不会影响此效果。当这种效果发生时,网格位置的值不会改变,通过记录位置来检查这一点。

如果我没有遗漏任何东西,这会将其缩小为两种可能性:

  1. 我的相机代码
  2. DirectX 设备

对于DirectX-Device,这是我的设备初始化代码:

    private void InitializeDevice()
{
//Initialize D3D
_d3dObj = new D3D9.Direct3D();

//Set presentation parameters
_presParams = new D3D9.PresentParameters();
_presParams.Windowed = true;
_presParams.SwapEffect = D3D9.SwapEffect.Discard;
_presParams.AutoDepthStencilFormat = D3D9.Format.D16;
_presParams.EnableAutoDepthStencil = true;
_presParams.PresentationInterval = D3D9.PresentInterval.One;
_presParams.BackBufferFormat = _d3dObj.Adapters.DefaultAdapter.CurrentDisplayMode.Format;
_presParams.BackBufferHeight = _d3dObj.Adapters.DefaultAdapter.CurrentDisplayMode.Height;
_presParams.BackBufferWidth = _d3dObj.Adapters.DefaultAdapter.CurrentDisplayMode.Width;

//Set form width and height to current backbuffer width und height
this.Width = _presParams.BackBufferWidth;
this.Height = _presParams.BackBufferHeight;

//Checking device capabilities
D3D9.Capabilities caps = _d3dObj.GetDeviceCaps(0, D3D9.DeviceType.Hardware);
D3D9.CreateFlags devFlags = D3D9.CreateFlags.SoftwareVertexProcessing;
D3D9.DeviceType devType = D3D9.DeviceType.Reference;

//setting device flags according to device capabilities
if ((caps.VertexShaderVersion >= new Version(2, 0)) && (caps.PixelShaderVersion >= new Version(2, 0)))
{
//if device supports vertexshader and pixelshader >= 2.0
//then use the hardware device
devType = D3D9.DeviceType.Hardware;

if (caps.DeviceCaps.HasFlag(D3D9.DeviceCaps.HWTransformAndLight))
{
devFlags = D3D9.CreateFlags.HardwareVertexProcessing;
}
if (caps.DeviceCaps.HasFlag(D3D9.DeviceCaps.PureDevice))
{
devFlags |= D3D9.CreateFlags.PureDevice;
}
}

//initialize the device
_device = new D3D9.Device(_d3dObj, 0, devType, this.Handle, devFlags, _presParams);
//set culling
_device.SetRenderState(D3D9.RenderState.CullMode, D3D9.Cull.Counterclockwise);
//set texturewrapping (needed for seamless spheremapping)
_device.SetRenderState(D3D9.RenderState.Wrap0, D3D9.TextureWrapping.All);
//set lighting
_device.SetRenderState(D3D9.RenderState.Lighting, false);
//enabling the z-buffer
_device.SetRenderState(D3D9.RenderState.ZEnable, D3D9.ZBufferType.UseZBuffer);
//and setting write-access exlicitly to true...
//i'm a little paranoid about this since i had to struggle for a few days with weirdly overlapping meshes
_device.SetRenderState(D3D9.RenderState.ZWriteEnable, true);
}

我是否缺少标志或渲染状态?有什么东西会导致这种奇怪/扭曲的行为吗?

我的相机类基于 Michael Silvermans C++ Quaternion Camera :

//every variable prefixed with an underscore is 
//a private static variable initialized beforehand
public static class Camera
{
//gets called every frame
public static void Update()
{
if (_filter)
{
_filteredPos = Vector3.Lerp(_filteredPos, _pos, _filterAlpha);
_filteredRot = Quaternion.Slerp(_filteredRot, _rot, _filterAlpha);
}

_device.SetTransform(D3D9.TransformState.Projection, Matrix.PerspectiveFovLH(_fov, _screenAspect, _nearClippingPlane, _farClippingPlane));
_device.SetTransform(D3D9.TransformState.View, GetViewMatrix());
}

public static void Move(Vector3 delta)
{
_pos += delta;
}

public static void RotationYaw(float theta)
{
_rot = Quaternion.Multiply(Quaternion.RotationAxis(_up, -theta), _rot);
}

public static void RotationPitch(float theta)
{
_rot = Quaternion.Multiply(_rot, Quaternion.RotationAxis(_right, theta));
}

public static void SetTarget(Vector3 target, Vector3 up)
{
SetPositionAndTarget(_pos, target, up);
}

public static void SetPositionAndTarget(Vector3 position, Vector3 target, Vector3 upVec)
{
_pos = position;

Vector3 up, right, lookAt = target - _pos;

lookAt = Vector3.Normalize(lookAt);
right = Vector3.Cross(upVec, lookAt);
right = Vector3.Normalize(right);
up = Vector3.Cross(lookAt, right);
up = Vector3.Normalize(up);

SetAxis(lookAt, up, right);
}

public static void SetAxis(Vector3 lookAt, Vector3 up, Vector3 right)
{
Matrix rot = Matrix.Identity;

rot.M11 = right.X;
rot.M12 = up.X;
rot.M13 = lookAt.X;

rot.M21 = right.Y;
rot.M22 = up.Y;
rot.M23 = lookAt.Y;

rot.M31 = right.Z;
rot.M32 = up.Z;
rot.M33 = lookAt.Z;

_rot = Quaternion.RotationMatrix(rot);
}

public static void ViewScene(BoundingSphere sphere)
{
SetPositionAndTarget(sphere.Center - new Vector3((sphere.Radius + 150) / (float)Math.Sin(_fov / 2), 0, 0), sphere.Center, new Vector3(0, 1, 0));
}

public static Vector3 GetLookAt()
{
Matrix rot = Matrix.RotationQuaternion(_rot);
return new Vector3(rot.M13, rot.M23, rot.M33);
}

public static Vector3 GetRight()
{
Matrix rot = Matrix.RotationQuaternion(_rot);
return new Vector3(rot.M11, rot.M21, rot.M31);
}

public static Vector3 GetUp()
{
Matrix rot = Matrix.RotationQuaternion(_rot);
return new Vector3(rot.M12, rot.M22, rot.M32);
}

public static Matrix GetViewMatrix()
{
Matrix viewMatrix, translation = Matrix.Identity;
Vector3 position;
Quaternion rotation;

if (_filter)
{
position = _filteredPos;
rotation = _filteredRot;
}
else
{
position = _pos;
rotation = _rot;
}

translation = Matrix.Translation(-position.X, -position.Y, -position.Z);
viewMatrix = Matrix.Multiply(translation, Matrix.RotationQuaternion(rotation));

return viewMatrix;
}
}

您是否在相机代码中发现任何可能导致此行为的内容?

我无法想象 DirectX 无法处理大于 100k 的距离。我应该渲染太阳系,我使用 1 个单位 = 1 公里。因此,地球将在 (0, 0, 152100000) 处以其与太阳的最大距离呈现(仅作为示例)。如果这些“跳跃”不断发生,这将变得不可能。最后我考虑缩小一切,这样系统就不会超过距原点 100k/-100k 的距离,但我认为这行不通,因为随着距原点的距离变大,“抖动”也会变大。缩小一切都会 - 我认为 - 也会缩小跳跃行为。

最佳答案

只是为了不让这个问题悬而未决(归功于 @jcoder ,请参阅问题评论):

网格的怪异行为来自 DX 的浮点精度。您的世界越大,准确计算位置的精度就越低。

解决这个问题有两种可能:

  1. 缩小整个世界
    这在“银河式”世界中可能会有问题,在这种世界中,您的位置偏移量非常大,也有非常小的位置偏移量(即行星与其太阳的距离非常大,但宇宙飞船在轨道上的距离星球可能真的很小)
  2. 将世界分成更小的 block
    这样你要么表达所有相对于其他事物的位置(见 stackoverflow.com/questions/1930421 )要么创造多个世界并以某种方式在它们之间移动

关于c# - 网格开始在相机旋转/移动时跳跃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13290098/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com