Jump to content
  • Advertisement

Mrfence97

Member
  • Content Count

    11
  • Joined

  • Last visited

Community Reputation

122 Neutral

About Mrfence97

  • Rank
    Member
  1. I am attempting to make a 3D FPS game from scratch, and I am having trouble keeping the gun (in the bottom right corner, as in Call of Duty or Counter Strike etc.) appear stationary as the player moves the camera.   If the player is standing still and looks straight ahead and then just yaws left or right, the gun appears to stay stationary on the screen as expected; if the player pitches up or down, however, the front of the gun appears to move slightly downwards relative to the back. This isn't a problem as such when the gun is at the hip (is looks rather good actually), but when the player is looking down the sights, it means that the front sight goes out of alignment with the back when looking up or down at angles greater than 45 degrees or so.   At the moment, I am calculating the transform that the gun should have as follows: Move the gun in world coordinates to the position it should be if the camera was facing along (0,0,1) [i.e. straight ahead] and was positioned at the origin. Multiply by a rotation matrix that matches the one the camera is using to rotate it's 'look at position'. Matrix::CreateYawPitchRoll(cam.yaw, -cam.pitch, 0); Multiply by a translation matrix to move the gun to the current position of the camera. This order seems to make sense in my head and it has worked with a few numerical tests, but it doesn't work for the gun! Does anyone know how I can fix this problem? Or do you have another solution for making a 3D object appear stationary to the camera?   I can upload pictures if requested.   Many thanks, Mrfence   P.S. If I use a quaternion to represent the rotation in (2), the same problem occurs.
  2. Mrfence97

    Using the Stencil Buffer

    I have managed to fix the problem! It was a rather stupid mistake in the end - in-between setting the correct DSS and actually drawing the scene, I was calling a function that was resetting the bound DSS back to the 'default' state for the project, hence why none of the stenciling was working!   Thanks for all your help everyone .
  3. Mrfence97

    Using the Stencil Buffer

    That last part of your comment is exactly what I'm trying to achieve, I can't get the D3D11_DEPTH_STENCIL_DESC parameters correct to get it to work, however! At the moment I have this: // Depth stencil desc for decal drawing // Create depth stencil state corresponding to step one of the article. D3D11_DEPTH_STENCIL_DESC dsDescFirstpass; dsDescFirstpass.DepthEnable = true; dsDescFirstpass.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; dsDescFirstpass.DepthFunc = D3D11_COMPARISON_LESS; // Stencil test parameters dsDescFirstpass.StencilEnable = true; dsDescFirstpass.StencilReadMask = 0xFF; dsDescFirstpass.StencilWriteMask = 0xFF; // Stencil operations if pixel is front-facing. // Keep original value on fail. dsDescFirstpass.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dsDescFirstpass.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; // Write to the stencil on pass. dsDescFirstpass.FrontFace.StencilPassOp = D3D11_STENCIL_OP_INCR_SAT; dsDescFirstpass.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Stencil operations if pixel is back-facing. // Since we do not care about back-facing pixels, always keep original value. dsDescFirstpass.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dsDescFirstpass.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; dsDescFirstpass.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; dsDescFirstpass.BackFace.StencilFunc = D3D11_COMPARISON_NEVER; //I then create the DSS, and set it using device->OMSetDepthStencilState(dssFirstpass, 0); //Depth stencil desc for re-drawing the main scene, using the stencil as a mask D3D11_DEPTH_STENCIL_DESC dsDescSecondpass; dsDescSecondpass.DepthEnable = true; dsDescSecondpass.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL; dsDescSecondpass.DepthFunc = D3D10_COMPARISON_LESS; dsDescSecondpass.StencilEnable = true; dsDescSecondpass.StencilReadMask = 0xFF; dsDescSecondpass.StencilWriteMask = 0xFF; // It does not matter what we write since we are not using the values after this step. // In other words, we are only using the values to mask pixels. dsDescSecondpass.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dsDescSecondpass.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; dsDescSecondpass.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; // The stencil test passes if the passed parameter is equal to value in the buffer. dsDescSecondpass.FrontFace.StencilFunc = D3D11_COMPARISON_NOT_EQUAL; // Again, we do not care about back-facing pixels. dsDescSecondpass.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dsDescSecondpass.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; dsDescSecondpass.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; dsDescSecondpass.BackFace.StencilFunc = D3D11_COMPARISON_NEVER; //I then create the DSS and set it with: device->OMSetDepthStencilState(dssSecondpass, 0); You can see that the reference value for both passes is set to 0, so the not equal comparison should mean that pixels that have been drawn to (so the stencil buffer is not 0) should pass the test, but the opposite happens! The pixels that have been drawn to fail, and the rest pass. If I then change from NOT_EQUAL to EQUAL, the exact same happens! Is there some glaringly obvious mistake?   (Also, I am clearing the stencil buffer to 0 before each frame).   Thanks for your help again 
  4. Mrfence97

    Using the Stencil Buffer

    That's exactly the effect I'm looking for, but if I were to do that, I'd either have to re-render the whole scene as max resolution, or use a lower resolution that wouldn't look good close-up.   The idea of using the stencil buffer is so that it could be used as a mask, so I could render the scene at full resolution but only the areas that are required would actually be computed!
  5. Mrfence97

    Using the Stencil Buffer

    I basically want a visual effect similar to the portals in 'Portal' (composting one view of the scene in another through a small window - the portal). The way I planned to do it was to draw the main scene as usual, before then rendering a small plane where the portal would be while incrementing those pixels in the stencil buffer. I would then render the scene from the point of view of the other portal, while using the data in the stencil buffer as a mask to prevent superfluous pixel calculations.   Hopefully that makes sense! I jumped to using the stencil buffer, because masking/compositing seems one of the main uses for it!   Thanks for the quick reply 
  6. Currently, I'm trying to implement what I suppose is a standard use for the stencil buffer; I can't however, find any tutorials or samples describing what the D3D11_DEPTH_STENCIL_DESC parameters should be set to to carry this functionality out. I'll describe what I want to do: Draw an object (with the usual z-buffer depth testing functionality), but also increment the value in the stencil buffer for each pixel, if the pixel is drawn. Clear the depth buffer back to 1.0, while preserving the newly written stencil buffer data (this will be done using the D3D11_CLEAR_DEPTH flag only, I imagine). Draw the 'main' scene using the newly cleared z-buffer for depth testing, but only draw pixels if the value in the stencil buffer is greater than 0 (i.e. the pixel was drawn to in the first pass). Clear the depth and stencil buffer, repeat etc. Does anyone know how I would do this in DirectX 11? I could show the code that I have currently, if requested, but it's not working at all. Many thanks!
  7. Mrfence97

    How To Apply Skinning

    The mesh does have a parent frame (when exported as a .x file that is), but it is a simple rotation to get it from Blender to DirectX's coordinate system, which I already account for.   The root frame again does have a transformation matrix, when exported as a .x, but it again looks like a rotation, and if I use that instead of the identity matrix with the Calc functions, it just rotates the bone affected vertices and makes it even more wrong!   I use exactly the same shader calls the only difference being: xBones[i] = _boneArray[i]->finalMatrix; //Bind pose //vs xBones[i] = _boneArray[i]->keyFrames[frameNo]; //"Animated" pose I have also decided to attach a picture showing what exactly is wrong with the model, on the left is Blender at ~frame 0 and 90, compared to in my app on the right. It appears that the forehead's movement in my app has been rotated 90 degrees downwards so it is going into the Monkey's face, rather than forward and out. This makes me think it is something to do with the rotation keys I'm exporting, or maybe the order I'm using to create the initial bone space matrices per frame; is Scale * Rotation * Translation correct?   http://imgur.com/Fz9Ma1Z   Thanks again for any insight you can give 
  8. Mrfence97

    How To Apply Skinning

    Yes, I call both functions exactly as you've written - the "Bind" one immediately after I have loaded in the localMatrix, and the other one after I have loaded in the animation data. I'm pretty sure there is a keyframe matrix for each bone, as I said, I've written the exporter myself, and for debugging it exports every frame with every bone, exporting it's position, rotation and scale (all values are exactly the same as a .x file I have also exported as a comparison, so the exporter isn't at fault). I will initialize the key frame matrices with the bind pose matrix, however, just to make sure! Well in my shader Pos is initially set to the vertex position, so if the weight is zero, I still want it to draw the vertex in it's regular position (again, this is for debugging purposes). All unused weights are 0 I'm afraid!
  9. Mrfence97

    How To Apply Skinning

    To update, I have managed to display the model in bind position correctly (at last!), but when I try to apply any actual animation, it deforms with the correct weights/indices etc. but the model is simply not in the right final position.   My code for generating the "finalMatrix" that is sent to the GPU to display the model in bind position is as follows (based upon the links Buckeye gave): void CalcBindFinalMatrix(Bone* bone, Matrix &parentMatrix) { bone->combinedMatrix = bone->localMatrix * parentMatrix; bone->finalMatrix = bone->offsetMatrix * bone->combinedMatrix; for(auto child = bone->children.begin(); child != bone->children.end(); ++child) { CalcBindFinalMatrix(*child, bone->combinedMatrix); } } This displays correctly, as expected. However, this function (which is run for every frame of animation) which is almost identical, gives weird transformations, almost like the whole model should be rotated 90 degrees.   The bone space transformations for each frame are originally stored in bone->keyFrames[frameNo], and once multiplied etc. they are also the matrices sent to GPU. void CalcPoseFinalMatrix(Bone* bone, Matrix &parentMatrix, UINT frameNo) { Matrix com = bone->keyFrames[frameNo] * parentMatrix; bone->keyFrames[frameNo] = bone->offsetMatrix * com; for(auto child = bone->children.begin(); child != bone->children.end(); ++child) { CalcPoseFinalMatrix(*child, com, frameNo); } } Also, by HLSL code for performing the skinning is as follows : //b = bone indices //w = bone weights float4 Pos1 = mul(Pos, xBones[b[0]]); float4 Pos2 = mul(Pos, xBones[b[1]]); float4 Pos3 = mul(Pos, xBones[b[2]]); float4 Pos4 = mul(Pos, xBones[b[3]]); if(w[0] != 0.0) { Pos = (Pos1 * w[0]) + (Pos2 * w[1]) + (Pos3 * w[2]) + (Pos4 * w[3]); } outputPos = mulWorldViewProj(Pos, xWorld, xView, xProj); Is there anything inherently wrong with my code to cause these issues? I'll post some pictures of what's going wrong if needed!   Many thanks.
  10. Mrfence97

    How To Apply Skinning

    Thanks for the links, I shall definitely be having a look at them!   In answer to your question about whether I export the indices correctly, my exporter is based on the OBJ exporter but with vertex weights added, so everything else is exported/loaded fine.   Thanks for your time!
  11. I'm attempting to add animation to my game using skinning; however, I do not know how to actually apply it to my model's vertices.   Currently, I have written my own exporter for Blender that (correctly) outputs the vertex weights for each vertex, and I have loaded that into my DX11 app. But how do I then apply the various bone transforms to the vertices? What information do I need? I intend to again write my own exporter, but looking at the .x format, it appears you export the position, rotation and scale of each bone relative to its parent per frame (which I imagine you then turn into a matrix, for that frame).   But I then go on to read about how I have to transform each vertex into the "Bone space", then "Armature space" (what I imagine the .x file exports), and then finally "World space" (using your world matrix). How do I calculate this "Bone space" matrix? I've tried using the inverse matrix of the bone in it's "rest position" and then multiplying this by the pose matrix for the bone, but this doesn't appear to work.   How do I go about this skinning?   Many thanks for any help you can provide.
  • 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!