Jump to content
  • Advertisement

komilll

Member
  • Content Count

    28
  • Joined

  • Last visited

Community Reputation

3 Neutral

About komilll

  • Rank
    Member

Personal Information

  • Role
    Programmer
  • Interests
    Programming

Social

  • Github
    komilll

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. @Zakwayda That's exactly where the problem was. Using XMVector3TrassformNormal for vector (not point) solved the problem. Thank you for all of your help. You're great! For all of you looking for final solution: XMFLOAT3 GetMinBounds(ModelClass * const model) const { return{ model->GetBounds().minX, model->GetBounds().minY, model->GetBounds().minZ }; } XMFLOAT3 GetMaxBounds(ModelClass * const model) const { return{ model->GetBounds().maxX, model->GetBounds().maxY, model->GetBounds().maxZ }; } MouseRaycastResult RaycastToModel(ModelClass* const model) { //Go to [-1, 1] coordinates float x = GetCurrentMousePosition().first; float y = GetCurrentMousePosition().second; if (x > 1.0f) x = 1.0f; else if (x < -1.0f) x = -1.0f; if (y > 1.0f) y = 1.0f; else if (y < -1.0f) y = -1.0f; XMMATRIX projectionMatrix, viewMatrix; //Transform by projection matrix m_D3D->GetProjectionMatrix(projectionMatrix); x = x / projectionMatrix.r[0].m128_f32[0]; y = y / projectionMatrix.r[1].m128_f32[1]; //Create inverse matrix m_Camera->GetViewMatrix(viewMatrix); const XMMATRIX inverseViewMatrix = XMMatrixInverse(nullptr, viewMatrix); //Find ray direction in world space const XMVECTOR direction = { (x * inverseViewMatrix.r[0].m128_f32[0]) + (y * inverseViewMatrix.r[1].m128_f32[0]) + inverseViewMatrix.r[2].m128_f32[0], (x * inverseViewMatrix.r[0].m128_f32[1]) + (y * inverseViewMatrix.r[1].m128_f32[1]) + inverseViewMatrix.r[2].m128_f32[1], (x * inverseViewMatrix.r[0].m128_f32[2]) + (y * inverseViewMatrix.r[1].m128_f32[2]) + inverseViewMatrix.r[2].m128_f32[2] }; //Origin is equal to camera position in world space; //Dir is transformed, not-normalized, not-inversed ray const XMFLOAT3 dir = { direction.m128_f32[0], direction.m128_f32[1], direction.m128_f32[2] }; return MouseRaycastResult{ m_Camera->GetPosition(), dir }; } bool GraphicsClass::TestAABBIntersection(XMFLOAT3 lb, XMFLOAT3 rt, XMFLOAT3 origin, XMFLOAT3 dir, float& distance) { assert(lb.x <= rt.x); assert(lb.y <= rt.y); assert(lb.z <= rt.z); const XMFLOAT3 dirfrac = { 1.0f / dir.x, 1.0f / dir.y, 1.0f / dir.z }; const float t1 = (lb.x - origin.x)*dirfrac.x; const float t2 = (rt.x - origin.x)*dirfrac.x; const float t3 = (lb.y - origin.y)*dirfrac.y; const float t4 = (rt.y - origin.y)*dirfrac.y; const float t5 = (lb.z - origin.z)*dirfrac.z; const float t6 = (rt.z - origin.z)*dirfrac.z; const float tmin = max(max(min(t1, t2), min(t3, t4)), min(t5, t6)); const float tmax = min(min(max(t1, t2), max(t3, t4)), max(t5, t6)); // if tmax < 0, ray (line) is intersecting AABB, but the whole AABB is behind us if (tmax < 0) { return false; } // if tmin > tmax, ray doesn't intersect AABB if (tmin > tmax) { return false; } distance = tmin; return true; } bool GraphicsClass::TestOBBIntersection(ModelClass* model, XMFLOAT3 origin, XMFLOAT3 dir, XMFLOAT3 lb, XMFLOAT3 rt, float & dist) { //Create inverse world matrix XMMATRIX worldMatrix = XMMatrixIdentity(); worldMatrix = DirectX::XMMatrixMultiply(worldMatrix, DirectX::XMMatrixScaling(model->GetScale().x, model->GetScale().y, model->GetScale().z)); worldMatrix = DirectX::XMMatrixMultiply(worldMatrix, DirectX::XMMatrixRotationX(model->GetRotation().x * 0.0174532925f)); worldMatrix = DirectX::XMMatrixMultiply(worldMatrix, DirectX::XMMatrixRotationY(model->GetRotation().y * 0.0174532925f)); worldMatrix = DirectX::XMMatrixMultiply(worldMatrix, DirectX::XMMatrixRotationZ(model->GetRotation().z * 0.0174532925f)); worldMatrix = DirectX::XMMatrixMultiply(worldMatrix, XMMatrixTranslation(model->GetPosition().x, model->GetPosition().y, model->GetPosition().z)); const XMMATRIX inverseWorldMatrix = XMMatrixInverse(NULL, worldMatrix); //Transform origin point and direction ray vector const XMVECTOR originTransformed = XMVector3Transform({ origin.x, origin.y, origin.z }, inverseWorldMatrix); const XMVECTOR dirTransformed = XMVector3TransformNormal({ dir.x, dir.y, dir.z }, inverseWorldMatrix); origin = { originTransformed.m128_f32[0], originTransformed.m128_f32[1], originTransformed.m128_f32[2] }; dir = { dirTransformed.m128_f32[0], dirTransformed.m128_f32[1], dirTransformed.m128_f32[2] }; //Draw debug ray m_raycastModel->Initialize(m_D3D, origin, { origin.x + dir.x * 100.0f, origin.y + dir.y * 100.0f, origin.z + dir.z * 100.0f }); //Call AABB test for origin, ray transformed to OBB-space return TestAABBIntersection(lb, rt, origin, dir, dist); }
  2. @Zakwayda I cleaned code a little and here is a result: bool TestOBBIntersection(ModelClass* model, XMFLOAT3 origin, XMFLOAT3 dir, XMFLOAT3 lb, XMFLOAT3 rt, float & dist) { //Create inverse world matrix XMMATRIX worldMatrix = XMMatrixIdentity(); //worldMatrix = DirectX::XMMatrixMultiply(worldMatrix, DirectX::XMMatrixScaling(model->GetScale().x, model->GetScale().y, model->GetScale().z)); worldMatrix = DirectX::XMMatrixMultiply(worldMatrix, DirectX::XMMatrixRotationX(model->GetRotation().x * 0.0174532925f)); worldMatrix = DirectX::XMMatrixMultiply(worldMatrix, DirectX::XMMatrixRotationY(model->GetRotation().y * 0.0174532925f)); worldMatrix = DirectX::XMMatrixMultiply(worldMatrix, DirectX::XMMatrixRotationZ(model->GetRotation().z * 0.0174532925f)); //worldMatrix = DirectX::XMMatrixMultiply(worldMatrix, XMMatrixTranslation(model->GetPosition().x, model->GetPosition().y, model->GetPosition().z)); const XMMATRIX inverseWorldMatrix = XMMatrixInverse(NULL, worldMatrix); //Transform origin point and direction ray vector const XMVECTOR originTransformed = XMVector3Transform({ origin.x, origin.y, origin.z }, inverseWorldMatrix); const XMVECTOR dirTransformed = XMVector3Transform({ dir.x, dir.y, dir.z }, inverseWorldMatrix); origin = { originTransformed.m128_f32[0], originTransformed.m128_f32[1], originTransformed.m128_f32[2] }; dir = { dirTransformed.m128_f32[0], dirTransformed.m128_f32[1], dirTransformed.m128_f32[2] }; //Draw debug ray m_raycastModel->Initialize(m_D3D, origin, { origin.x + dir.x * 100.0f, origin.y + dir.y * 100.0f, origin.z + dir.z * 100.0f }); //Call AABB test for origin, ray transformed to OBB-space return TestAABBIntersection(lb, rt, origin, dir, dist); } MouseRaycastResult RaycastToModel(ModelClass* const model) { //Go to [-1, 1] coordinates float x = GetCurrentMousePosition().first; float y = GetCurrentMousePosition().second; if (x > 1.0f) x = 1.0f; else if (x < -1.0f) x = -1.0f; if (y > 1.0f) y = 1.0f; else if (y < -1.0f) y = -1.0f; float pointX, pointY; XMMATRIX projectionMatrix, viewMatrix, inverseViewMatrix; XMVECTOR direction; pointX = x; pointY = y; m_D3D->GetProjectionMatrix(projectionMatrix); pointX = pointX / projectionMatrix.r[0].m128_f32[0]; pointY = pointY / projectionMatrix.r[1].m128_f32[1]; m_Camera->GetViewMatrix(viewMatrix); inverseViewMatrix = XMMatrixInverse(nullptr, viewMatrix); direction = { (pointX * inverseViewMatrix.r[0].m128_f32[0]) + (pointY * inverseViewMatrix.r[1].m128_f32[0]) + inverseViewMatrix.r[2].m128_f32[0], (pointX * inverseViewMatrix.r[0].m128_f32[1]) + (pointY * inverseViewMatrix.r[1].m128_f32[1]) + inverseViewMatrix.r[2].m128_f32[1], (pointX * inverseViewMatrix.r[0].m128_f32[2]) + (pointY * inverseViewMatrix.r[1].m128_f32[2]) + inverseViewMatrix.r[2].m128_f32[2] }; const XMFLOAT3 dir = { direction.m128_f32[0], direction.m128_f32[1], direction.m128_f32[2] }; return MouseRaycastResult{m_Camera->GetPosition(), dir }; } XMFLOAT3 GetMinBounds(ModelClass * const model) const { return{ model->GetBounds().minX + model->GetPositionXYZ().x, model->GetBounds().minY + model->GetPositionXYZ().y, model->GetBounds().minZ + model->GetPositionXYZ().z };; } XMFLOAT3 GetMaxBounds(ModelClass * const model) const { return{ model->GetBounds().maxX + model->GetPositionXYZ().x, model->GetBounds().maxY + model->GetPositionXYZ().y, model->GetBounds().maxZ + model->GetPositionXYZ().z };; } Brief explanation - I got ray pure direction (not inverse, not normalized) from RaycastToModel. Origin is simply camera world-space position. Then origin point and ray direction are transformed by inverse world matrix in TestOBBIntersection. lb/rt are equal to GetMinBounds and GetMaxBounds. It still works for AABB in any position. OBB only for model position in (0, 0, 0). Camera origin (ray origin) might be doesn't matter. Commented lines - scale is always (1, 1, 1) so that's identity matrix, we don't care. Uncommenting position multiplication makes even AABB not to work and OBB even for (0, 0, 0).
  3. @Zakwayda You had good point about what's actually passed in 'dir'. I created raycast debug line and found out where actual error is. Thank you! I was returning dir as 1.0f / dir and then transforming it. I changed it to pass dir without inversion, transform it to OBB space and then inverse it and OBB works fine. However I found out, that it works only for location (0, 0, 0). Do you know what might be a problem?
  4. I will check rotation operation using Euler-angle to make sure there aren't any errors. I think there isn't any. I was just testing some code and I'm pretty sure that normalized or not, it gives the same results. So I think you can ignore that, as it is just inversed non-normalized direction.
  5. I was using many tutorials and forgot to rename some parameters after iterating on it. Do you mean ray-AABB or ray-OBB? I have no idea why it doesn't work for all rotations, just 0/90/180 degrees.
  6. @Zakwayda I believe that ray-AABB is correctly implemented. I was already using it for a month or so. I have setup you can see on screen with model raypicking and axis arrows to move model arround. It work for different models and different positions and different camera angles. lb stands for left bottom (min bounds); rt stands for right top (max bounds); origin is camera position in world space. That's my fault of bad naming. It should also be dirfrac. That's what passed down. MouseRaycastResult RaycastToModel(ModelClass* const model) { //Go to [-1, 1] coordinates float x = GetCurrentMousePosition().first; float y = GetCurrentMousePosition().second; if (x > 1.0f) x = 1.0f; else if (x < -1.0f) x = -1.0f; if (y > 1.0f) y = 1.0f; else if (y < -1.0f) y = -1.0f; float pointX, pointY; XMMATRIX projectionMatrix, viewMatrix, inverseViewMatrix, worldMatrix, translateMatrix, inverseWorldMatrix; XMVECTOR origin, rayOrigin, direction, rayDirection; pointX = x; pointY = y; m_D3D->GetProjectionMatrix(projectionMatrix); pointX = pointX / projectionMatrix.r[0].m128_f32[0]; pointY = pointY / projectionMatrix.r[1].m128_f32[1]; m_Camera->GetViewMatrix(viewMatrix); inverseViewMatrix = XMMatrixInverse(nullptr, viewMatrix); direction = { (pointX * inverseViewMatrix.r[0].m128_f32[0]) + (pointY * inverseViewMatrix.r[1].m128_f32[0]) + inverseViewMatrix.r[2].m128_f32[0], (pointX * inverseViewMatrix.r[0].m128_f32[1]) + (pointY * inverseViewMatrix.r[1].m128_f32[1]) + inverseViewMatrix.r[2].m128_f32[1], (pointX * inverseViewMatrix.r[0].m128_f32[2]) + (pointY * inverseViewMatrix.r[1].m128_f32[2]) + inverseViewMatrix.r[2].m128_f32[2] }; origin = { m_Camera->GetPosition().x, m_Camera->GetPosition().y, m_Camera->GetPosition().z }; m_D3D->GetWorldMatrix(worldMatrix); translateMatrix = XMMatrixTranslation(model->GetPosition().x, model->GetPosition().y, model->GetPosition().z); worldMatrix = XMMatrixMultiply(worldMatrix, translateMatrix); inverseWorldMatrix = XMMatrixInverse(nullptr, worldMatrix); rayOrigin = XMVector3TransformCoord(origin, inverseWorldMatrix); rayDirection = XMVector3TransformNormal(direction, inverseWorldMatrix); rayDirection = XMVector3Normalize(rayDirection); const XMFLOAT3 dirfrac{ 1.0f / rayDirection.m128_f32[0], 1.0f / rayDirection.m128_f32[1], 1.0f / rayDirection.m128_f32[2] }; const XMVECTOR dirfracNormalized = XMVector3Normalize({ dirfrac.x, dirfrac.y, dirfrac.z }); const XMFLOAT3 dir = { dirfracNormalized.m128_f32[0], dirfracNormalized.m128_f32[1], dirfracNormalized.m128_f32[2] }; return MouseRaycastResult{ {origin.m128_f32[0], origin.m128_f32[1], origin.m128_f32[2] }, dir }; } I am finding ray by clicking mouse on screen and finding its direction. What I return is normalized inversed direction. I am using Euler-angle rotation for every model operations in my code, I believe lb, rt are min-max bounds in world-space. I take bounds in model-space and add current model position to it to transform to world-space Does it make sense or am I mistaken on any part? @Krypt0n I am using dir returned in the code above. Is it right?
  7. Hey, I had already implemented AABB raypicking using slab intersection, but I couldn't get it working with rotation to create OBB raypicking. bool TestAABBIntersection(XMFLOAT3 lb, XMFLOAT3 rt, XMFLOAT3 origin, XMFLOAT3 dirfrac, float& distance) { assert(lb.x <= rt.x); assert(lb.y <= rt.y); assert(lb.z <= rt.z); const float t1 = (lb.x - origin.x)*dirfrac.x; const float t2 = (rt.x - origin.x)*dirfrac.x; const float t3 = (lb.y - origin.y)*dirfrac.y; const float t4 = (rt.y - origin.y)*dirfrac.y; const float t5 = (lb.z - origin.z)*dirfrac.z; const float t6 = (rt.z - origin.z)*dirfrac.z; const float tmin = max(max(min(t1, t2), min(t3, t4)), min(t5, t6)); const float tmax = min(min(max(t1, t2), max(t3, t4)), max(t5, t6)); // if tmax < 0, ray (line) is intersecting AABB, but the whole AABB is behind us if (tmax < 0) { return false; } // if tmin > tmax, ray doesn't intersect AABB if (tmin > tmax) { return false; } distance = tmin; return true; } bool TestOBBIntersection(ModelClass* model, XMFLOAT3 origin, XMFLOAT3 dir, XMFLOAT3 lb, XMFLOAT3 rt, float & dist) { XMMATRIX worldMatrix = XMMatrixIdentity(); worldMatrix = DirectX::XMMatrixMultiply(worldMatrix, DirectX::XMMatrixRotationX(model->GetRotation().x * 0.0174532925f)); worldMatrix = DirectX::XMMatrixMultiply(worldMatrix, DirectX::XMMatrixRotationY(model->GetRotation().y * 0.0174532925f)); worldMatrix = DirectX::XMMatrixMultiply(worldMatrix, DirectX::XMMatrixRotationZ(model->GetRotation().z * 0.0174532925f)); worldMatrix = XMMatrixInverse(NULL, worldMatrix); const XMVECTOR originTransformed = XMVector3Transform({ origin.x, origin.y, origin.z }, worldMatrix); const XMVECTOR dirTransformed = XMVector3Transform({ dir.x, dir.y, dir.z }, worldMatrix); origin = { originTransformed.m128_f32[0],originTransformed.m128_f32[1],originTransformed.m128_f32[2] }; dir = { dirTransformed.m128_f32[0], dirTransformed.m128_f32[1], dirTransformed.m128_f32[2] }; return TestAABBIntersection(lb, rt, origin, dir, dist); } What I am doing is multiplying ray origin and ray direction by inverse rotation matrix and then perform Ray-AABB test in OBB-space. It works only for 0, 90 and 180 degrees rotation. Where might be a problem?
  8. komilll

    Wrong HLSL buffer width

    You are seeing broken code on that changeset. Newest code uses registers - here is .h and .cpp - https://github.com/komilll/LEngine/tree/master/LEngine/src And here is blur shader - https://github.com/komilll/LEngine/blob/master/LEngine/blurHorizontal.vs
  9. komilll

    Wrong HLSL buffer width

    I started with RasterTek tutorials but yea, I started noticing that there are many flaws regarding C++ and I was rewritting it to use C++11. But as I begin creating system with that convention, I continue to naming shader classes in that way. What's the difference between .fx and .vs/.ps? Can I modify .fx on runtime and continue to use it? I had no idea, I wasn't thinking about it back then. However, do you still recommend using std::array<float> or C-style array instead of storing XMFLOAT4 in buffer struct? Or is it ok for feature level 10.0?
  10. @MJP Well, my previous assumption was only partially right. In post above I managed to get version without skybox working, but I was investigating it for the last two days and I find why it actually doesn't work with skybox. Render scene to texture (msaa x2) Render skybox Resolve texture Present After resolve step, render target is black and just black screen is presented at the end. However, when I am not using msaa it works without problem. When I am not using skybox, it also works ok. Problem is that I don't know how to use MSAA with skybox. I am using CreateDDSTextureFromFile for importing .DDS skybox file.
  11. komilll

    Wrong HLSL buffer width

    https://github.com/komilll/LEngine/blob/1a415024affbcb838e3fecf9f5e99eb66477352b/LEngine/src/BlurShaderClass.cpp https://github.com/komilll/LEngine/blob/1a415024affbcb838e3fecf9f5e99eb66477352b/LEngine/src/BaseShaderClass.cpp https://github.com/komilll/LEngine/blob/1a415024affbcb838e3fecf9f5e99eb66477352b/LEngine/blurHorizontal.vs BlurShaderClass inherits from BaseShaderClass. In BlurShaderClass::SetShaderParameters I am setting matrix buffer (through BaseShaderClass::SetShaderParameters) and ScreenSizeBuffer.
  12. komilll

    Wrong HLSL buffer width

    I stated in the first post:
  13. komilll

    Wrong HLSL buffer width

    @Adam Miles Maybe problem was somewhere else then, maybe buffer was still 16 bytes. However it doesn't change a fact that value in that cbuffer was always set to 1 (Nsight was saying that but also the output made me 100% it has value equal to 1).
  14. Thank you, sir. I had no idea that such debug options exist in DirectX, that's a great tool for debuging, thanks once again. But back to what a problem was - I was using only one DepthStencilView for everything. When there was an intention to render data that doesn't use MSAA, there was a count mismatch, because the only stencil view was the one with MSAA. That means that I created new StencilView: m_depthStencilViewBackBuffer = CreateDepthBufferReturn(1, 1); //Size multiplier = 1 (higher values for SSAA), depth buffer count = 1 //... void D3DClass::SetBackBufferRenderTarget() const //Use for non-MSAA rendering; Render MSAA directly to texture and resolve { m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilViewBackBuffer); } However MSAA was working even without resolving texture, which is weird, I guess? Here is a result of MSAAx2 without resolving texture. Aftering uncommenting resolving, results are the same.
  15. It's more of a discussion question than actual problem with code, because I managed to fix it. I had VS shader with 2 constant buffers: cbuffer MatrixBuffer : register(cb0) { matrix worldMatrix; matrix viewMatrix; matrix projectionMatrix; }; cbuffer ScreenSizeBuffer : register(cb1) { float screenSize; float g_padding1; float g_padding2; float g_padding3; }; Nsight says that MatrixBuffer is 192 width (correct) and ScreenSizeBuffer is 192 width (wrong, should be 16). screenSize variable is always equal to 1. Removing MatrixBuffer fixes a problem, ScreenSizeBuffer is back 16 width and screenSize value is passed correctly. Why is that? Why previous buffer width is passed to next buffer?
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!