嘿在一起,網格開始跳上相機旋轉/運動
第一次在這裏發帖,因爲我該死的卡...
越遠的網格是從原點( 0,0,0)時,旋轉或移動相機時它越「跳躍」/「閃爍」。描述這種效果很難:它就像網格抖動/顫抖/有點顫抖,隨着距離原點的增加,這種顫抖變得越來越大。
對我來說,它開始在距離原點約100000個單位距離處觀察到,例如在(0,0,100000)處。翻譯的軸線和網格的類型(從Mesh.Create創建的默認網格...或者使用assimp.NET導入的3ds網格)都不會影響這種效果。當發生這種效應時,網格位置的值不會改變,通過記錄位置進行檢查。
如果我不是失去了一些東西,這個範圍縮小到兩種可能性:
- 我的相機代碼
- 的DirectX的設備
對於DirectX的設備,這是我的設備初始化代碼:
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);
}
我是否缺少一個標誌或renderstate?有什麼可能導致這種奇怪/扭曲的行爲?
我的相機類是基於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的距離,但我認爲這不會起作用,因爲隨着離原點的距離變大,「抖動」變大。縮小一切縮小的範圍 - 我認爲 - 也會縮小跳躍行爲。
我認爲這可能是您的問題。 DirectX使用通常具有6-7位精度的浮點數,這意味着當它們是152100000時,則表示的最小變化大約是10000單位。 – jcoder
感謝您的評論,從來沒有想過背後的數據類型。 然後縮小整個系統應該使問題消失。 –
縮小它的範圍,或者用更多的本地座標系統將你的世界分成更小的塊,這顯然是更多的工作,並且需要你以某種方式處理區域之間的移動 – jcoder