• Advertisement


  • Content count

  • Joined

  • Last visited

Community Reputation

114 Neutral

About Hashbrown

  • Rank

Personal Information

  • Interests
  1. Thanks a lot guys, Shaarigan was right, there something going on with my ray too. I'll do what unity does and draw lines and get that sorted out first. And JoeJ, you're also right, I was confused about when to normalize, I copied your code and as soon as I fix my ray issue, I'll use your code. I'll share what I learn once I do, thanks again guys
  2. Hey what's up Shaarigan? You mean instantiating another cube and testing the direction of the ray? I honestly haven't since I already tried with the one cube I show in the gifs above. cube.transform.position.x = Camera.main.ray.origin.x + Camera.main.ray.direction.x * 4; cube.transform.position.y = Camera.main.ray.origin.y + Camera.main.ray.direction.y * 4; cube.transform.position.z = Camera.main.ray.origin.z + Camera.main.ray.direction.z * 4; ..and the cube remains in front of me. Also, before this implementation I had another one, and that one was working perfectly only if I don't move the camera. I wasn't considering the direction I guess. So I'm guessing my ray is pointing towards the right direction. You got me wondering now.
  3. I'm stuck trying to make a simple ray sphere intersection test. I'm using this tutorial as my guide and taking code from there. As of now, I'm pretty sure I have the ray sorted out correctly. The way I'm testing my ray is by using the direction of the ray as the position of a cube, just to make sure it's in front of me. cube.transform.position.x = Camera.main.ray.origin.x + Camera.main.ray.direction.x * 4; cube.transform.position.y = Camera.main.ray.origin.y + Camera.main.ray.direction.y * 4; cube.transform.position.z = Camera.main.ray.origin.z + Camera.main.ray.direction.z * 4; So if I rotate the camera, the cube follows. So it's looking good. The problem occurs with the actual intersection algorithm. Here are the steps I'm taking, I'll be very brief: 1) I subtract the sphere center with the ray origin: L.x = entity.rigidbody.collider.center.x - ray.origin.x; L.y = entity.rigidbody.collider.center.y - ray.origin.y; L.z = entity.rigidbody.collider.center.z - ray.origin.z; L.normalize(); 2) I get the dot product of L and the ray direction: const b = Mathf.dot(L, ray.direction); 3) And also the dot product of L with itself (I'm not sure if I'm doing this step right): const c = Mathf.dot(L, L); 4) So now I can check if B is less than 0, which means it's behind the object. That's working very nicely. L.x = entity.rigidbody.collider.center.x - ray.origin.x; L.y = entity.rigidbody.collider.center.y - ray.origin.y; L.z = entity.rigidbody.collider.center.z - ray.origin.z; const b = Mathf.dot(L, ray.direction); const c = Mathf.dot(L, L); if (b < 0) return false; Problem starts here 5) I now do this: let d2 = (c * c) - (b * b); 6) ...and check if d2 > (entity.radius * entity.radius) and if it's greater: stop there by returning false. But it always passes, unless I don't normalize L and d2 ends up being a larger number and then it return false: const radius2 = entity.rigidbody.collider.radius * entity.rigidbody.collider.radius; if (d2 > radius2) return false; but again, since I'm normalizing, it NEVER stops in that step. Which worries me. 7) I then do this: let t1c = Math.sqrt(radius2 - d2); ...but it always returns a number in the range of 0.98, 0.97, if I'm standing still. But if I strafe left and right, the number lowers. If I rotate the camera, it makes no difference. Only if I strafe. So I'm clearly doing something wrong and stopped there. Hopefully I made sense
  4. Trouble with my Perspective Projection Matrix

    No, no, you explained very nicely. I'm actually the slow one here to be honest lol. But it's a longer learning process for some of us Update (Solved!): I got it! I went through all 16 slots in the array and changed them to see what each one does, also did the multiplication on paper. Here are the results, no warping, just slightly due to the FOV which is normal. If I want no warping I can go down to 45degs, but again, it's very minor and normal. (excuse the low framerate, had to lower the GIF size) Explanation No warping! Here's what I learned just in case somebody runs into a similar issue. Just as Shaarigan wisely indicated, I wasn't considering the aspect ratio in the Z axis. [ x, 0, 0, 0, 0, y, 0, 0, a, b, z, -1, 0, 0, w, 0 ] // Note: I did not use A and B, but I'll explain them. I won't explain the obvious ones like NEAR, FAR, and FOV, but I will get into the NEAR PLANE a little below in my DEPTH explanation. Scale x: Scales the width. Divide by the Aspect Ratio IF height > width. y: Scales the height. Divide by the Aspect Ratio IF width > height. z: How "deep" the depth will be, a ratio dividing by the zRange (NEAR - FAR) Depth w: I noticed the lower the number (into the screen), the further the NEAR PLANE would be. It's like if you had a screen a few units in front of you and once an object touches it, the object disappears. -1: Im not 100% sure about this one, but I noticed I can use it as a Z axis offset. It pushes the object back -1, and if I go lower, it pushes it further back. Leave it -1 though. Extra (Position?) a: This property was not very useful for me, It moves the object in the X axis. Note, it will move it with no perspective projection applied. So you won't see the side of a cube...it will move to the left or right with its face completely in front of you. Orthographic style. b: Same as A, but the Y Axis. (Also, if you use a or b, both axis are "inverted", as in +x will go left. -x will go right. Same with the y axis. So there you go. Shaarigan thanks again for helping out and pointing me towards the right direction. If anybody finds something wrong in my explanation, please let me know and I'll correct it. Also, here's the final working perspective projection matrix: const halfFOV = Math.tan(toRad(FOV/2.0)); let xScale, yScale; if (viewport.width > viewport.height) { xScale = 1.0 / (halfFOV); yScale = 1.0 / (halfFOV / viewport.aspect); } else { xScale = 1.0 / (halfFOV / viewport.aspect); yScale = 1.0 / (halfFOV); } const zRange = (NEAR - FAR); const zScale = (NEAR + FAR) / zRange const NEAR_PLANE = (2 * NEAR * FAR) / zRange; p.mat[0] = xScale; p.mat[5] = yScale; p.mat[10] = zScale; p.mat[11] = -1.0; p.mat[14] = NEAR_PLANE p.mat[15] = 0;
  5. Trouble with my Perspective Projection Matrix

    Thanks dietrich, I'm still a little confused but after Shaarigan's explanation, I'm going to work it out step by step on paper until I get it. I'm definitely messing up on something. I'll also check your link. Sharrigan, thank you again. As I mentioned above, I'm going to go through your solution step by step until I get it intuitively. I did try your matrix but unfortunately I still get that egg shape in the z axis I'm clearly doing something wrong. I also had to switch back to my perspective matrix because with yours made my objects look insideout. (perspective matrix calculations results in the screenshot) This is the window setup I tried with: Window Size 1160 x 310, Window Aspect 3.7419~ Near: 0.1 | Far: 1000 My new perspective matrix let b = NEAR * Math.tan(toRad(0.5 * FOV)); let t = -b; let l = t * aspect; let r = b * aspect; p.mat[0] = (2.0 * NEAR) / (r - l); p.mat[5] = (2.0 * NEAR) / (t - b); p.mat[8] = (r + l) / (r - l); p.mat[9] = (t + b) / (t - b); p.mat[10] = -(FAR + NEAR) / (FAR - NEAR); p.mat[11] = -1; p.mat[14] = -(2.0 * FAR * NEAR) / (FAR - NEAR); p.mat[15] = 0; ...but still the same egg z axis issue. I'm going to look over what you explained to get a better understanding.
  6. Trouble with my Perspective Projection Matrix

    Thanks for the quick answer Shaarigan. I'm afraid I'm not following left would be the -width of my window, and right would be +width? I was also wondering if I can still use FOV with your implementation. Strange, the only problem I have is the depth of the object. The width and height is great, but the z I guess stays the same, leaving that egg form. You're definitely right, I'm missing properties that consider the width and height in my depth.
  7. I'm trying to learn how to make my own model, view, projection setup. I've managed to translate, rotate, and scale my models, but have an issue with my perspective projection matrix. Even though I'm multiplying halfFOV with my aspect ratio, the image looks squished unless my window is a perfect square like this: If it's not a perfect square: the wider my window the more stretched my object looks in the Z axis like an egg. So it definitely has to do with with my projection matrix, specifically related to my aspect ratio. The way I'm multiplying my matrices is as follows, I'll show you my translation and projection keep it simple: Translation [1, 0, 0, 0, 0, 1 0, 0 0, 0, 1, 0, x, y, z, 1] Projection let halfFOV = Math.tan(toRad(FOV/2.0)); let zRange = (NEAR - FAR); let x = 1.0 / (halfFOV * aspect); let y = 1.0 / (halfFOV); let z = (NEAR + FAR) / zRange; let w = 2 * FAR * NEAR / zRange; [x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, -1, 0, 0, w, 0] I normally see the -1 where the w is, but for some reason I need to set it up the way you see it in my matrix, if not it won't work. I'll also share how I'm multiplying matrices very quickly: function (r, a, b) r.mat[0] = (a.mat[0] * b.mat[0]) + (a.mat[1] * b.mat[4]) + (a.mat[2] * b.mat[8]) + (a.mat[3] * b.mat[12]); r.mat[1] = (a.mat[0] * b.mat[1]) + (a.mat[1] * b.mat[5]) + (a.mat[2] * b.mat[9]) + (a.mat[3] * b.mat[13]); r.mat[2] = (a.mat[0] * b.mat[2]) + (a.mat[1] * b.mat[6]) + (a.mat[2] * b.mat[10]) + (a.mat[3] * b.mat[14]); r.mat[3] = (a.mat[0] * b.mat[3]) + (a.mat[1] * b.mat[7]) + (a.mat[2] * b.mat[11]) + (a.mat[3] * b.mat[15]); // don't need to add the rest of it... // How I use it Mathf.mul(resultMat, position, projection); So I take the left row and multiply it against the right column. I then get rows as a result as you can see. If you want to check out the full implementation it's here. I've also checked that I'm getting the correct window size. I divide width/height to get the aspect ratio too. Not sure what I'm doing wrong. I also tried multiplying my matrices on the gpu (glsl) and I gt the same results, so it's definitely my projection matrix Hope this all makes sense. Edit: I probably should have posted this thread in the Math categories, my apologies.
  8. Am I understanding fixed timestep games loop wrong?

    Yeah h8, I was not really understanding properly the concept. I found a great explanation here, just in case anybody else is interested. Thanks!
  9. Am I understanding fixed timestep games loop wrong?

    iedoc, thanks for your quick response. Hopefully I'm beginning to understand. If I wanted to let's say replay a character movement's, I could (and should) do it within a fixed time-step loop right? Since the time is fixed and I can always expect deterministic results. That's my understanding right now after reading your message. What I still don't know is if my way of managing accumulated time is correct? If you look at my code, I increment lag by Math.min(1, msDt). My delta time is always hitting somewhere around 16.6ms which is 60 fps, and my while loop iterates 60 times that way, then escapes the while loop and hits the render update once. Considering I'm using a 1/60 time step. But if I increment lag by Math.min(1, dt), which is msDt/1000.0, the while loop hits only once and immediately goes to the render loop. So I'm not sure if to increment lag by Math.min(1, dt) or Math.min(1, msDt). That's really the portion I'm confused about. Thanks again doc.
  10. I'm trying to make fixed time-step game loop following this wonderful site, but I suspect I'm not understanding the concept correctly. I'm working with JavaScript and the browser, but I'm sure you'll understand better than I do. Here are the steps I'm taking: - I'm using the 60fps update loop (requestAnimationFrame) provided by browsers. - Using a 30fps step (1.0/30.0) for my fixed update loop. - I'm currently getting all the necessary time data at the beginning of the frame: function updateFrame () { now = window.performance.now(); msDt = now - last; dt = msDt / 1000.0; // ignored lag += Math.min(1, msDt); last = now; } - I'm also separating the physics (fixed update) and rendering update loops like this: // within update frame loop while (lag >= fpsLimit) { lag -= fpsLimit; game.fixedUpdate(); } game.update(); game.render(); If you notice, I increment lag in milliseconds, not seconds (divided by 1000). That way, when I get to the while loop, lag decreases exactly 30 times and then moves down to rendering part. So if I log inside the while loop and after it, I get 30 logs from the while loop and 1 after it. Repeat. But if I do it the way the site recommends, which is to increment lag by seconds (divided by 1000), the number is lower, but the while loop only runs once. I'm guessing because I only increment by the fpsLimit (0.033) and it would take only one iteration to escape the while loop. I hope I made sense, I'm basically trying to do something similar to Unity. Have a fixed update I know will loop 30 times, and also update every frame. Not sure if I'm understand correctly though. Thanks if your read this far!
  • Advertisement