Jump to content
  • Advertisement

cozzie

Member
  • Content Count

    1973
  • Joined

  • Last visited

Community Reputation

5043 Excellent

1 Follower

About cozzie

  • Rank
    Contributor

Recent Profile Visitors

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

  1. cozzie

    Missing pixels in mesh seams

    @Hodgman thanks, the explanation is pretty clear. I'm not planning for that large scaled scenes so far, but it's good to know. Not sure though how the 3rd 'in the middle' option would work, would it be something like this: - mul world with view on CPU - mul model space vtx with worldview - mul the result with projection? Btw; I did notice some clipping within a mesh with the new/ fixed solution, but not 100% sure if that was caused by the change (or just coincedence). It only occured when being 'very far' away from the mesh (could also be Z fighting/ precision). Update; just did a test changing it back, the clipping issue (Faces 'through each other') does occur at closer Z with the new approach, compared to the old approach (issue occurs only when further away). But in this case I think I need a better mesh
  2. cozzie

    Missing pixels in mesh seams

    @TeaTreeTim @Zakwayda I found it after a chat with @Hodgman. The solution is/ was a combination of 2 things: - I have a fixed timestep for updating, the state of the camera's view projection matrix is not correct, as used when rendering - the transformation of the vertex in the VS, using 2 separate world matrices (potentially, looking at possible accuracy/rounding issue. Old: // Transform to world space space. vout.PosW = mul(float4(vin.PosL, 1.0f), gPerObject.MatWorld).xyz; // Transform to homogeneous clip space. vout.PosH = mul(float4(vin.PosL, 1.0f), gPerObject.MatWorldViewProj); New: // Transform to world space space. vout.PosW = mul(float4(vin.PosL, 1.0f), gPerObject.MatWorld).xyz; // Transform to homogeneous clip space. vout.PosH = mul(float4(vout.PosW, 1.0f), gPerFrame.MatViewProj); Now the issue is gone. Currently figuring out how to exactly approach the view/projection matrix updating, for testing I just moved updating the CB per frame to the render function
  3. cozzie

    Missing pixels in mesh seams

    Thanks all. @Zakwayda I just did some debugging in renderdoc, checking the world matrix that's used in the VS. This looks as expected, with round numbers for the XYZ position of the plane (X -56, Y 10, Z -94). WorldViewProjection is not that easy to verify I also tried to statically position the camera in front of a plane, with 90 deg rotation etc., to better inspect WVP, but then I don't see the issue )-; Will try to debug further and see what I can find.
  4. Hi all, After seeing some missing pixels along the edges of meshes 'beside each other'/ connected, I first thought it was mesh specific/related. But after testing the following, I still see this occuring: - create a flat grid/plane, without textures - output only black, white background (buffer cleared) When I draw this plane twice, e.g. 0,0 (XZ) and 4,0 (XZ), with the plane being 4x4, I still see those strange pixels 'see through' (aiming for properly connected planes). After quite some researching and testing (disable skybox, change buffer clear color, disable depth buffer etc), I still keep getting this. I've been reading up on 't junction' issues, but I think here this isn't the case (verts all line up nicely). As a workaround/ solution for now, I've just made the black foundation planes (below the scene), boxes with minimal height and bottom triangles removed. This way basically these 'holes' are not visible because the boxes have sides. Here a screenshot of what I'm getting. I wonder if someone has thoughts on this, is this 'normal', do studios workaround this etc. There might be some rounding issues, but I wouldn't expect that with this 'full' numbers (all ,0).
  5. cozzie

    Material values, blinn phong

    Thanks, this helps in my search
  6. Hi all, Even though PBR is basically today’s standard. I was wondering what a good approach is to determine ambient, diffuse and specular values for different types of material, using the “old” blinn phong approach. Are there for example studies or reference data for common used materials, like grass, metals, concrete, tiles etc. Any input would be appreciated.
  7. Hi. I personally don’t know the answer, perhaps the other people who saw your post so far also didn’t. Perhaps you’re not that stupid and it’s a difficult question. tbh, I find it a hit harsh to burn down the forum because you feel your question’s not answered quick enough. Speaking from experience, the forum and a lot of people on it are pretty helpful.
  8. This is mostly just a decision initially taken when a Library is created. Which could also be because the lib is initially used with dx or OpenGL (which have different handedness). In the end there’s no right or wrong; most important is to stick with one throughout everything you do.
  9. cozzie

    Typedefing in a central *.h file

    No problem if you ask me, I do the same with uint (unsigned int 32), my IO folders etc. It's actually not more then 15 lines of code, so not getting out of hand. I use the forced include option in Visual Studio to make sure it's always there.
  10. Short update: managed to get the version as in Realtime collision, working. The issue was that the extents in my OBB werent half, multiplying by 0.5 solved that implementation. In my testcase I also made one of the 2 cubes static, to check if the other implementation suffers from 0 cross product issues, but still doesn’t work. Now figuring out what else could be the cause. Any thoughts appreciated. Other implementation also solved, static POS..... was only initialized once within the collision detection function.
  11. Thanks both, I'll try to debug and see what's returned for which axis I check. My test case are 2 cubes with are besides each other (0, -3, 0 and 0, -3 and - 1.5), which are rotating in the same direction, meaning all axis's are parallel. This might be the reason why implementation 1 doesn't work (no epsilon correction for 0 cross product). I'll try this one first, since it's a quick fix/ test. Or the other way around, disable rotation for one of the two cubes, so I don't have the potential 'parallel' issue'. @Randy Gaul true, but there's always a risk of copy/ pasting and making it 'fit' to my codebase.
  12. Hi all, I've been struggling to get my OBB - OBB intersection test working, using the Separating Axis theorem. After doing 2 different implementations, the 1st one always returns false, and the other implementation always returns true. Debugging shows valid OBB input passed to the functions (verified by debug drawing the OBB's by the renderer). Any input on what I might be doing wrong, is really appreciated. bool CBaseCollision::OBBOBBIntersect(const CR_OBB &pOBB1, const CR_OBB &pOBB2) { static CR_VECTOR3 rPos = pOBB2.Center - pOBB1.Center; CR_VECTOR3 xAxis1 = pOBB1.XHalfExtent; xAxis1.Normalize(); CR_VECTOR3 yAxis1 = pOBB1.YHalfExtent; yAxis1.Normalize(); CR_VECTOR3 zAxis1 = pOBB1.ZHalfExtent; zAxis1.Normalize(); CR_VECTOR3 xAxis2 = pOBB2.XHalfExtent; xAxis2.Normalize(); CR_VECTOR3 yAxis2 = pOBB2.YHalfExtent; yAxis2.Normalize(); CR_VECTOR3 zAxis2 = pOBB2.ZHalfExtent; zAxis2.Normalize(); if( SeparatingPlaneExists(rPos, xAxis1, pOBB1, pOBB2) || SeparatingPlaneExists(rPos, yAxis1, pOBB1, pOBB2) || SeparatingPlaneExists(rPos, zAxis1, pOBB1, pOBB2) || SeparatingPlaneExists(rPos, xAxis2, pOBB1, pOBB2) || SeparatingPlaneExists(rPos, yAxis2, pOBB1, pOBB2) || SeparatingPlaneExists(rPos, zAxis2, pOBB1, pOBB2) || SeparatingPlaneExists(rPos, CMathHelper::CrossVec3(xAxis1, xAxis2), pOBB1, pOBB2) || SeparatingPlaneExists(rPos, CMathHelper::CrossVec3(xAxis1, yAxis2), pOBB1, pOBB2) || SeparatingPlaneExists(rPos, CMathHelper::CrossVec3(xAxis1, zAxis2), pOBB1, pOBB2) || SeparatingPlaneExists(rPos, CMathHelper::CrossVec3(yAxis1, xAxis2), pOBB1, pOBB2) || SeparatingPlaneExists(rPos, CMathHelper::CrossVec3(yAxis1, yAxis2), pOBB1, pOBB2) || SeparatingPlaneExists(rPos, CMathHelper::CrossVec3(yAxis1, zAxis2), pOBB1, pOBB2) || SeparatingPlaneExists(rPos, CMathHelper::CrossVec3(zAxis1, xAxis2), pOBB1, pOBB2) || SeparatingPlaneExists(rPos, CMathHelper::CrossVec3(zAxis1, yAxis2), pOBB1, pOBB2) || SeparatingPlaneExists(rPos, CMathHelper::CrossVec3(zAxis1, zAxis2), pOBB1, pOBB2)) return false; return true; } bool CBaseCollision::SeparatingPlaneExists(const CR_VECTOR3 &pPos, const CR_VECTOR3 &pAxis, const CR_OBB &pObb1, const CR_OBB &pObb2) { float baseDist = fabs(CMathHelper::DotProductVec3(pPos, pAxis)); float compDist = fabs(CMathHelper::DotProductVec3(pObb1.XHalfExtent, pAxis)) + fabs(CMathHelper::DotProductVec3(pObb1.YHalfExtent, pAxis)) + fabs(CMathHelper::DotProductVec3(pObb1.ZHalfExtent, pAxis)) + fabs(CMathHelper::DotProductVec3(pObb2.XHalfExtent, pAxis)) + fabs(CMathHelper::DotProductVec3(pObb2.YHalfExtent, pAxis)) + fabs(CMathHelper::DotProductVec3(pObb2.ZHalfExtent, pAxis)); return(baseDist > compDist); } Implementation 2, based on the Realtime collision book implementation: bool CBaseCollision::OBBOBBIntersect(const CR_OBB &pOBB1, const CR_OBB &pOBB2) { float ra, rb; CR_VECTOR3 u_obb1[3]; CR_VECTOR3 u_obb2[3]; u_obb1[0] = pOBB1.XHalfExtent; u_obb1[0].Normalize(); u_obb1[1] = pOBB1.YHalfExtent; u_obb1[1].Normalize(); u_obb1[2] = pOBB1.ZHalfExtent; u_obb1[2].Normalize(); u_obb2[0] = pOBB2.XHalfExtent; u_obb2[0].Normalize(); u_obb2[1] = pOBB2.YHalfExtent; u_obb2[1].Normalize(); u_obb2[2] = pOBB2.ZHalfExtent; u_obb2[2].Normalize(); float e_obb1[3] = { pOBB1.Extents.x, pOBB1.Extents.y, pOBB1.Extents.z }; float e_obb2[3] = { pOBB2.Extents.x, pOBB2.Extents.y, pOBB2.Extents.z }; // compute rotation matrix expressing OBB2 in OBB1's coordinate frame float tR[3][3]; for(int i=0;i<3;++i) { for(int j=0;j<3;++j) { tR[i][j] = CMathHelper::DotProductVec3(u_obb1[i], u_obb2[j]); } } // compute translation vector t CR_VECTOR3 orgt = pOBB2.Center - pOBB1.Center; float t[3]; // bring translation into 1's coordinate space t[0] = CMathHelper::DotProductVec3(orgt, u_obb1[0]); t[1] = CMathHelper::DotProductVec3(orgt, u_obb1[2]); t[2] = CMathHelper::DotProductVec3(orgt, u_obb1[2]); // compute common subexpressions. Add epsilon, to prevent cross product being 0 for parallel vectors float tAbsR[3][3]; for(int i=0;i<3;++i) { for(int j=0;j<3;++j) { tAbsR[i][j] = abs(tR[i][j]) + 0.0002f; } } // test axes L = A0 / A1 / A2 for(int i=0;i<3;++i) { ra = e_obb1[i]; rb = e_obb2[0] * tAbsR[i][0] + e_obb2[1] * tAbsR[i][1] + e_obb2[2] * tAbsR[i][2]; if(fabs(t[i]) > ra + rb) return false; } // test axes L = B0 / B1 / B2 for(int i=0;i<3;++i) { ra = e_obb1[0] * tAbsR[0][i] + e_obb1[1] * tAbsR[1][i] + e_obb1[2] * tAbsR[2][i]; rb = e_obb2[i]; if(fabs(t[0] * tR[0][1] + t[1] * tR[1][i] + t[2] * tR[2][i]) > ra + rb) return false; } // Test axis L = A0 x B0 ra = e_obb1[1] * tAbsR[2][0] + e_obb1[2] * tAbsR[1][0]; rb = e_obb2[1] * tAbsR[0][2] + e_obb2[2] * tAbsR[0][1]; if(fabs(t[2] * tR[1][0] - t[1] * tR[2][0]) > ra + rb) return false; // Test axis L = A0 x B1 ra = e_obb1[1] * tAbsR[2][1] + e_obb1[2] * tAbsR[1][1]; rb = e_obb2[0] * tAbsR[0][2] + e_obb2[2] * tAbsR[0][0]; if(fabs(t[2] * tR[1][1] - t[1] * tR[2][1]) > ra + rb) return false; // Test axis L = A0 x B2 ra = e_obb1[1] * tAbsR[2][2] + e_obb1[2] * tAbsR[1][2]; rb = e_obb2[0] * tAbsR[0][1] + e_obb2[1] * tAbsR[0][0]; if(fabs(t[2] * tR[1][2] - t[1] * tR[2][2]) > ra + rb) return false; // Test axis L = A1 x B0 ra = e_obb1[0] * tAbsR[2][0] + e_obb1[2] * tAbsR[0][0]; rb = e_obb2[1] * tAbsR[1][2] + e_obb2[2] * tAbsR[1][1]; if(fabs(t[0] * tR[2][0] - t[2] * tR[0][0]) > ra + rb) return false; // Test axis L = A1 x B1 ra = e_obb1[0] * tAbsR[2][1] + e_obb1[2] * tAbsR[0][1]; rb = e_obb2[0] * tAbsR[1][2] + e_obb2[2] * tAbsR[1][0]; if(fabs(t[0] * tR[2][1] - t[2] * tR[0][1]) > ra + rb) return false; // Test axis L = A1 x B2 ra = e_obb1[0] * tAbsR[2][2] + e_obb1[2] * tAbsR[0][2]; rb = e_obb2[0] * tAbsR[1][1] + e_obb2[1] * tAbsR[1][0]; if(fabs(t[0] * tR[2][2] - t[2] * tR[0][2]) > ra + rb) return false; // Test axis L = A2 x B0 ra = e_obb1[0] * tAbsR[1][0] + e_obb1[1] * tAbsR[0][0]; rb = e_obb2[1] * tAbsR[2][2] + e_obb2[2] * tAbsR[2][1]; if(fabs(t[1] * tR[0][0] - t[0] * tR[1][0]) > ra + rb) return false; // Test axis L = A2 x B1 ra = e_obb1[0] * tAbsR[1][1] + e_obb1[1] * tAbsR[0][1]; rb = e_obb2[0] * tAbsR[2][2] + e_obb2[2] * tAbsR[2][0]; if(fabs(t[1] * tR[0][1] - t[0] * tR[1][1]) > ra + rb) return false; // Test axis L = A2 x B2 ra = e_obb1[0] * tAbsR[1][2] + e_obb1[1] * tAbsR[0][2]; rb = e_obb2[0] * tAbsR[2][1] + e_obb2[1] * tAbsR[2][0]; if(fabs(t[1] * tR[0][2] - t[0] * tR[1][2]) > ra + rb) return false; return true; }
  13. Thanks, with this input and a lot of chat on the Discord GD, I almost solved it. After some addition hour(s) of debugging the last issue seemed to be the order of matrix multiplication (Basis vectors and translation). All working like a charm now. For future reference/ others, here's the fixed code: bool CDebugDraw::AddArrow(const CR_VECTOR3 &pPos1, const CR_VECTOR3 &pPos2, const CR_VECTOR3 &pColor, const bool pDepthEnabled, const bool pPersistent, const uint64_t pLifeTime) { if(!AddLine(pPos1, pPos2, pColor, pDepthEnabled, pPersistent, pLifeTime)) return false; /* p1 / | \ / | \ / | \ p2 -----|-----p3 | | | | p0 */ // form new base vectors CR_VECTOR3 e3 = pPos2 - pPos1; e3.Normalize(); CR_VECTOR3 e1 = CMathHelper::CrossVec3(e3, CR_VECTOR3(0.0f, 1.0f, 0.0f)); // how about arrow direction 0 1 0 ? e1.Normalize(); CR_VECTOR3 e2 = CMathHelper::CrossVec3(e1, e3); // fill basis vectors into our 'B' matrix (transposed to work with Mathhelper/DXmath) CR_MATRIX4X4 bMat = CR_MATRIX4X4(CR_VECTOR4(e1, 0.0f), CR_VECTOR4(e2, 0.0f), CR_VECTOR4(e3, 0.0f), CR_VECTOR4(0.0f, 0.0f, 0.0f, 1.0f)); // translation matrix CR_MATRIX4X4 transMat; transMat.m41 = pPos2.x; transMat.m42 = pPos2.y; transMat.m43 = pPos2.z; transMat.m44 = 1.0f; // multiply B and translation CR_MATRIX4X4 finalMat; finalMat = CMathHelper::MatrixMultiply(bMat, transMat); // model space arrowhead lines CR_VECTOR3 p1 = CR_VECTOR3(0.0f, 0.0f, 0.0f); CR_VECTOR3 p2 = CR_VECTOR3(-0.1f, 0.0f, -0.1f); CR_VECTOR3 p3 = CR_VECTOR3(0.1f, 0.0f, -0.1f); // transform them p1 = CMathHelper::TransformVec3Coord(p1, finalMat); p2 = CMathHelper::TransformVec3Coord(p2, finalMat); p3 = CMathHelper::TransformVec3Coord(p3, finalMat); // draw lines if(!AddLine(p1, p2, pColor, pDepthEnabled, pPersistent, pLifeTime)) return false; if(!AddLine(p1, p3, pColor, pDepthEnabled, pPersistent, pLifeTime)) return false; return true; }
  14. Hi guys, I've been struggling to create a function to draw an arrow with 2 lines making up the arrowhead. The challenge is that I somehow can't get the rotation right. I've pasted the code below and an image of the result. Findings so far, when I replace the 3x3 part of the transform matrix to identity, I get the same visual result. Also when I switch colums A and C in the matrix, this specific arrow looks good (with is pointing in the positive X direction). Any input would be appreciated. bool CDebugDraw::AddArrow(const CR_VECTOR3 &pPos1, const CR_VECTOR3 &pPos2, const CR_VECTOR3 &pColor, const bool pDepthEnabled, const bool pPersistent, const uint64_t pLifeTime) { if(!AddLine(pPos1, pPos2, pColor, pDepthEnabled, pPersistent, pLifeTime)) return false; /* p1 ------- X / | \ | / | \ | / | \ | p2 -----|-----p3 | Z | | | | p0 */ CR_VECTOR3 arrowDir = pPos2 - pPos1; arrowDir.Normalize(); // model space CR_VECTOR3 p1 = CR_VECTOR3(0.0f, 0.0f, 0.0f); CR_VECTOR3 p2 = CR_VECTOR3(0.2f, 0.0f, -0.2f); CR_VECTOR3 p3 = CR_VECTOR3(-0.2f, 0.0f, -0.2f); // transformation: translate and rotate CR_VECTOR3 transl = pPos2; CR_VECTOR3 colA = arrowDir; CR_VECTOR3 tVec; if(colA.x != 0 && colA.z != 0) tVec = CR_VECTOR3(0.0f, 1.0f, 0.0); else tVec = CR_VECTOR3(0.0f, 0.0f, 1.0f); CR_VECTOR3 colB = CMathHelper::CrossVec3(colA, tVec); CR_VECTOR3 colC = CMathHelper::CrossVec3(colB, colA); CR_MATRIX4X4 transform; transform.m11 = colA.x; transform.m12 = colB.x; transform.m13 = colC.x; transform.m14 = 0.0f; transform.m21 = colA.y; transform.m22 = colB.y; transform.m23 = colC.y; transform.m24 = 0.0f; transform.m31 = colA.z; transform.m32 = colB.z; transform.m33 = colC.z; transform.m34 = 0.0f; transform.m41 = transl.x; transform.m42 = transl.y; transform.m43 = transl.z; transform.m44 = 1.0f; // transform = CMathHelper::ComposeWorldMatrix(transform, CR_VECTOR3(1.0f), CR_VECTOR3(0.0f, 90.0f, 0.0f), pPos2); // transform to worldspace p1 = CMathHelper::TransformVec3Coord(p1, transform); p2 = CMathHelper::TransformVec3Coord(p2, transform); p3 = CMathHelper::TransformVec3Coord(p3, transform); if(!AddLine(p1, p2, CR_VECTOR3(1.0f, 0.0f, 0.0f), pDepthEnabled, pPersistent, pLifeTime)) return false; if(!AddLine(p1, p3, CR_VECTOR3(1.0f, 0.0f, 0.0f), pDepthEnabled, pPersistent, pLifeTime)) return false; if(!AddCross(p2, 0.02f, CR_VECTOR3(0.0f, 0.0f, 1.0f), pDepthEnabled, pPersistent, pLifeTime)) return false; if(!AddCross(p3, 0.02f, CR_VECTOR3(0.0f, 0.0f, 1.0f), pDepthEnabled, pPersistent, pLifeTime)) return false; return true; } Incorrect result: Aimed/ correct result (independent of arrow direction):
  15. @d07RiV thanks for digging it up Articles and papers are not very clear/ consistent on if/ when to use the sign for the bitangent. My use-case is that I provide the normal and tangent to the GPU (via vtxbuffer), and then in the VS I calculate bitangent with a simple cross: if(gPerMaterial.Material.UseNormalMap == 1) { float3 tBitangent = cross(vin.Tangent, vin.NormalL); // TBN for normal mapping vout.TangentW = mul(vin.Tangent, (float3x3)gPerObject.WorldInvTranspose); vout.BitangentW = mul(tBitangent, (float3x3)gPerObject.WorldInvTranspose); vout.NormalW = mul(vin.NormalL, (float3x3)gPerObject.WorldInvTranspose); } else vout.NormalW = mul(vin.NormalL, (float3x3)gPerObject.WorldInvTranspose); Now the question is, is this the way to go (independent on mirrored/flipped situations), or do I have to do something like this: - check if untransformed normal.z > 0 or < 0, if > sign = +, if < sign = - - apply that sign to all 3 transformed vectors? (T, B and N) or before transforming? Note that the vectors are float3's, so no W component for storing anything Note 2: this is the original vertex normal, no normapmap involved yet
  • 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!