• Advertisement

# STufaro

Member

52

183 Neutral

• Rank
Member
1. ## [Solved] Thick (Constant-Width) Lines Using Quads

Jason, Thanks for the fast reply and the idea! It turns out that the point where the triangles cross will be the W = 0 point, so your thinking was spot-on and a lot more exact than mine [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img] (I was taking potshots in the dark hoping that the point I picked would keep the perspective--I'm glad I now know the reason). However, your reply inspired me to try something else, and [b]I managed to solve my problem![/b] I was solving for the point where the triangles crossed by parametrizing the equations of the 3D lines, not realizing that if I had a line in the pure Z direction (which I did since I'm making a grid), I could not always rely on the X and Y vectors of the line to parametrize it, since I would occasionally get a NaN in (I parametrize and solve for the line intersection point as shown in this link: [url="http://mathforum.org/library/drmath/view/63719.html"]http://mathforum.org...view/63719.html[/url]) Therefore, I needed to add a bit to my code: [CODE] if ((extrudeScale1 < 0) ^ (extrudeScale2 < 0)) { // just assume line direction won't be hurt by using X and Y float x1 = line1start.X; float x2 = line2start.X; float y1 = line1start.Y; float y2 = line2start.Y; float a1 = line1vec.X; float a2 = line2vec.X; float b1 = line1vec.Y; float b2 = line2vec.Y; if ((Math.Abs(lineDirection.Y) < 0.001f) && (Math.Abs(lineDirection.X) < 0.001f)) { // if the line is purely in the Z direction, however, we need to use Z instead of Y y1 = line1start.Z; y2 = line2start.Z; b1 = line1vec.Z; b2 = line2vec.Z; } else if ((Math.Abs(lineDirection.X) < 0.001f) && (Math.Abs(lineDirection.Z) < 0.001f)) { // and similarly, if purely in the Y direction, we need to use Z instead of X x1 = line1start.Z; x2 = line2start.Z; a1 = line1vec.Z; a2 = line2vec.Z; } float t1 = (y1 - y2 - b2 * ((x1 - x2) / a2)) / (b2 * a1 / a2 - b1); float x = line1vec.X * t1 + line1start.X; float y = line1vec.Y * t1 + line1start.Y; float z = line1vec.Z * t1 + line1start.Z; } [/CODE] Where line1vec and line1start are the starts of the _diagonals_ of the quad, and lineDirection is the direction of the line we are _drawing_. Sorry it's not very clean...and there's probably some optimization to be made too. As usual I don't make any guarantees...[img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img] I don't completely understand I had to use Z instead of X when drawing a Y-line (I assume it has to do with the extrusion direction being in the pure X-direction when I was sitting along the Z-axis?), but it did work. Now I have thick lines! (I'm wondering if it was worth the effort and hair-pulling for my little project--but hopefully it will be for someone else). [img]http://i40.tinypic.com/moo7t.png[/img] They're not exactly award-winning without a fair amount of AA, and even then they're pretty ugly. There may even still be some artifacts in there...but I think I'm ready to call them good-enough for my game [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img] Thanks again, Jason, for your help--without the help and encouragement of the GD community I'd have made far less progress on my project. Best regards, -- Steve
2. ## [Solved] Thick (Constant-Width) Lines Using Quads

Well, after a little bit of struggling yesterday I've come up with a buggy, but somewhat-working, implementation. My basic steps are as follows:[list=1] [*][b]Get the vector of the line:[/b] [CODE]lineDirection = (lineStart - lineEnd)[/CODE] [*][b]Find our soon-to-be constructed quad's normal as:[/b] [CODE]quadNormal = cameraPosition - lineMidpoint[/CODE] Where lineMidpoint = ((lineStart + lineEnd) / 2). I reason this should be the quad's normal since the quad will always be facing the camera, like a billboard. [*][b]Get the direction along which we should extrude vertices from our line[/b], which is the cross product of lineDirection and quadNormal: [CODE]extrudeDirection = Vector3.Cross(lineDirection, quadNormal)[/CODE] Normalize extrudeDirection. [*][b]Get the W of lineStart and lineEnd by transforming them by the viewMatrix * projectionMatrix.[/b] [CODE]wStart = (Vector3.Transform(lineStart, viewMatrix * projectionMatrix)).W wEnd = (Vector3.Transform(lineEnd, viewMatrix * projectionMatrix)).W[/CODE] [*][b]Extrude vertices from the line along the extrudeDirection vector, in some multiple of the W.[/b] [CODE]Vector3 startVert1 = lineStart + extrudeDirection * wStart * lineWeight Vector3 startVert2 = lineStart - extrudeDirection * wStart * lineWeight Vector3 endVert1 = lineEnd + extrudeDirection * wEnd * lineWeight Vector3 endVert2 = lineEnd - extrudeDirection * wEnd * lineWeight[/CODE] [*][b]Connect the vertices to form a quad.[/b] [/list] And therein lies the hitch, which took some unraveling for me. If you are far from the line, both W's will be positive, which is fine, since presumably you connected your four vertices to form a quad with the diagonal of the triangles being shared between them. Un-projected, this quad looks like a trapezoid, with bases on either side, and one base larger than the other to cancel out the W-divide. Everything works well. However, if you get close to the line and rotate the camera a bit to face one end, one vertex will go off-screen and behind the camera, and thus one of the W's will be negative. This mathematically legit, I've reasoned, but your vertices that you extrude will be created on opposite sides of the line. If you don't change the way your vertices are connected in this situation, your triangle's diagonals will cross, because on one side of the quad the vertices have been flipped over the line. The result is you get an extra "flap" of the triangle either below or above your line, which confused me to no end yesterday. In the below [s](high-quality rendering)[/s] diagram, the red section is what I'm talking about. [img]http://i44.tinypic.com/b4x24m.png[/img] To get rid of the red section, I adjusted the vertices of the triangles to the [b]point where the diagonals cross[/b] [b]when one of the W's was negative.[/b] That way, you'd get just the white part of the two triangles. (To get this point, I solve the equations of the two lines in 3D (since they're coplanar, they will intersect).) That seemed to solve the problem in one little test I did, but when I scaled up and made a bunch of lines for my in-game grid, problems galore popped up, including some of the same problems the D3DXLine class seems to have (it appears to negate the transforms when you get close), which is not a good sign. If anyone had the patience to read my essay on drawing lines with quads and has an idea on where in this process I went wrong, please do let me know--I'm very curious. I also don't want to abandon thick lines, but for now I'm just using a LINE_LIST to draw my grid. I'll keep us updated if I come up with anything else, too. Best, -- Steve
3. ## [Solved] Thick (Constant-Width) Lines Using Quads

Hi all, I am making a 3D level editor for my game and would like to add grid lines, but ones better (namely, thicker) than the thin 1-px lines created by rendering a LINE_LIST. I've run across several posts using D3DXLine, and tried it myself, but found that the transforms were buggy, so I set out to make 3D lines from quads aligned to face the camera (i.e., billboards). I do not completely understand billboards, but I've been playing with them long enough to have a general feel of how they work and can create some on my own. I would like to keep the lines a constant thickness, no matter how close or far the camera is from them. I tried using an orthographic projection to no avail, and I've also tried doing a perspective divide manipulation (or rather, multiplication) on my billboard's vertices to find out how much I should scale them. No attempt so far I've made looks even remotely correct, and I think I'm just confusing myself trying to mess with different things for an easy solution... Can anyone outline the basic steps of how I would go about doing this (e.g., step 1, make quad vertices, step 2, rotate, step 3...etc.)? How would you solve this problem? An external link of someone solving the same problem, but without perspective (plus I'd rather not use a vertex shader and am having trouble understanding his assembly code): [url="http://stackoverflow.com/questions/3818287/drawing-lines-in-3d-directx"]http://stackoverflow...s-in-3d-directx[/url] (Just a note--working in Direct3D9 via SlimDX and C#, so that's why I reference Direct3D-specific names, but I have no need for API-specific examples--anything should work for me.) Best regards, -- Steve ----- [size=5][b]Edit: SOLVED! And I'm very happy...See the following posts...[/b][/size]
4. ## How to tell if triangles enclose a volume

Emergent, alvaro, These were two great answers and a great discussion to read--I must admit I'm not following completely on the math, but the methods you've suggested make sense to me. For the purposes of the game I'm writing, I am not concerned about the fringe case Klein bottle, but that is an interesting point since a Klein bottle doesn't enclose anything I really like the painting solution, though. When I find the time to implement it, I'll give it a shot and [hopefully remember to] post the results. Much thanks for the ideas--the contents of your posts and the support of this community gives me both the confidence and the willpower to finish what I started...(when I find the time!) Best, -- Steve.
5. ## Limit quaternion rotation speed

[quote name='BleuBleu' timestamp='1298867108' post='4779960'] So, suppose I want to go from a rotation q1 to a rotation q2 and I don't want to rotate by more than x radians per frame. I tried this, but for some reason, it seem to introduce some unexpected rotations from time to time, any idea why? 1) Find delta rotation that will transform q1 into q2: delta = q2 * q1.Inverse() 2) Convert delta rotation to axis + angle 3) Clamp the angle to x 4) Reconstruct new (clamped) delta rotation 5) My final, clamped rotaiton should now be: delta * v1 Ideas? Suggestions? Thanks! -Mat [/quote] Mat, I'm not sure where the unexpected rotations come from--are you using Euler angles at any point? They might be because of a phenomenon known as gimbal lock--see this wiki article: [url="http://en.wikipedia.org/wiki/Gimbal_lock."]http://en.wikipedia....ki/Gimbal_lock.[/url] This happens when you go to Euler angles from quaternions (quaternions avoid the problem), because you have a series of rotations, and depending on which order you apply them (e.g., X-Y-Z, Z-X-Y), it may change things. That shouldn't affect axis-angle, though, but my hunch is the way to get around it is just keep everything as quaternions. I know that you can simply add two quaternions and divide them to "average" them out, resulting in a smoother transition. I had an application where there was a tank rolling over a heightmap--I noticed the tank "snapped" to the normals of each triangle it rolled over, so I averaged the normals between frames and smoothed the transitions a lot. [code] Quaternion approach (Quaternion initialRotation, Quaternion finalRotation) { return (initialRotation + finalRotation)/2; } [/code] If you keep feeding that back into itself after each frame, you'll get a fast movement at first and a slow movement toward the end, which looks nice. Using the same principle, you can get a quaternion somewhere between your initial and final: [code] Quaternion approach (Quaternion initialRotation, Quaternion finalRotation, float position) { // position between 0 and 1 return (1 - position) * initialRotation + position * finalRotation; } [/code] Correct me if I'm wrong, or let me know if that helps. Best of luck, -- Steve.
6. ## How to tell if triangles enclose a volume

Hi all, I was wondering if anyone might know where to start on this problem: Given a bunch of primitives (triangles in my case), ensure that they completely enclose at least one volume. My initial approach was to make sure all the edges were matched up with those of other triangles, but I also wanted to allow for the faces of primitives to enclose volumes (leaving the edges free and "hanging" off the side), or for a primitive to be connected to one of the faces of the volume by only one edge. I did some Googling on the matter and found these things related to Maya: [url="http://www.vfxoverflow.com/questions/81/getting-the-volume-of-an-arbitrary-closed-mesh"]http://www.vfxoverfl...ary-closed-mesh[/url] [url="http://forums.cgsociety.org/archive/index.php/t-754789.html"]http://forums.cgsoci...p/t-754789.html[/url] These work on the assumption that there's already a closed volume in the first place, or that having a free edge is bad, which are not necessarily true in my case. Thinking more robustly: from a programming perspective, I thought I could begin by testing all my triangles to see if they enclose a volume. The minimum is four triangles (a tetrahedron), so I would have to test all my triangles that share three edges with others in groups of four (in all combinations), then in groups of five (in all combinations), six, seven, and so on. That method only accounts for edge-connected triangles. So this: [img]http://i56.tinypic.com/263x4kh.gif[/img] which is a poorly-drawn pyramid stuck to a square plate (completely enclosed, but with free edges--should pass my test) would be rejected, even though I want to accept that. However, this triangle stuck to the top of a closed cube, also okay by my standards, would pass successfully: [img]http://i54.tinypic.com/15pmmo8.gif[/img] But, since that figure would be made up of 9 triangles, it would take (at most) 1784 tests (http://www.wolframalpha.com/input/?i=13+choose+4+%2B+13+choose+5+%2B+13+choose+6+%2B+13+choose+7+%2B+13+choose+8+%2B+13+choose+9+%2B+13+choose+10+%2B+13+choose+11+%2B+13+choose+12+%2B+13+choose+13) to figure that out. Note that in that last case the triangle's bottom edge spans a face that would be made up of two separate triangles--that adds an extra wrinkle to the problem, I guess. So, not only does my method require n C 4 + n C 5 + ... + n C n - 1 + n C n tests at most (where "C" means "in combinations of" ), but it doesn't immediately take care of the other cases I want to allow for either. Might anyone be able to come up with a better method off the top of his/her head? I'm stumped on this one. Regards, -- Steve.
7. ## DX11 [slimDX] textures on the simpletriangle

Your HLSL shader that you posted -- is that the complete shader? You never defined "txDiffuse," so it'll tell you that it doesn't exist when it tries to compile the shader. You're going to want to take a look at Riemer's XNA or Managed DirectX tutorials for this problem; it's explained nicely. This has exactly what you're looking for: http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series3/Textured_triangle.php The basics as I understand them in DirectX 9 are this: You need to set up a shader with a texture sampler (tells the graphics card how to pick/generate pixels from the texture). You then set the texture in the shader in your C++ program, and the sampler figures out how to color the pixels from the texture you fed it and your pixel shader code. I don't know if it's exactly the same for Direct3D 11, but something tells me the HLSL interaction part should be similar. Best, - Steve.
8. ## Rotating Camera For Different Views

My brain is fuzzy and I haven't messed with computers in a while, but I'll take a random stab. You are rotating the camera 40 degrees one way and 40 degrees another way to produce 3 different views, and the camera has the same projection matrix for each view (as I understand it). I think you need to take a step back and look at that projection matrix. The way I would do it is this: your total FOV angle should be whatever you want it to be (across the three monitors). Let's say this is 180 degrees (that would mean the edges of the left and right monitors are lined up with your ears, I guess). I'd take 180 degrees and divide it by 3. I use that FOV angle in my projection matrix for each camera. Then I rotate each of the end cameras by the FOV angle left or right and get their view matrices (I think you have that part down, but 40 degrees is not the right number for the FOV angle you're using). What is your FOV angle? Remember you don't want the views to overlap, so the larger the FOV angle, the more you have to rotate each camera so the views sync up. As for the other stuff: The math gods may correct me if I'm wrong, but aspect ratio and resolution shouldn't matter. It should be all in the projection matrix as far as I know. I don't know that I helped and you might have already tried all that, but let me know if you have any other thoughts. I'm curious about this problem. Best, - Steve.
9. ## Real-time lens blur

Hodgman, I'm sorry I haven't been on GD Net as religiously as I would have liked to be to follow this! This is truly excellent, and I don't think anyone minds you treating this thread like a dev-blog. At least I don't :) So the sub-offset was the way to go--good find for working on the downsampled map! I think my curiosity about the specular value of the pixels might have been too much work per-pixel, so I'm very happy to see the downsampled map work in some way (even if it worked "as fast," it would still bug me that it was per-pixel for some reason). Thanks for keeping us posted on the technique--one day I'll write a game and look back to this :). I think your DOF blur implementation will complete it and give you a very convincing effect once you've tweaked it as necessary. Nice job! ratings++; -- Steve.
10. ## Fastest way to render text?

Oh, I see; so each letter is in its own bitmap file? FillRect() is a GDI thing, not a DirectX-based function, am I right? I don't know where DirectX comes into this, but I have an idea for you if you're using Direct3D. I'd put all my letters in one bitmap, evenly spaced apart (or not--depends on what you want to do). Then I'd let 0 = A, 1 = B, 2 = C. Then I'd make a strip of vertices that's just a bunch of connected squares, with double vertices at each overlap. Then I'd put a letter on each square with texture coordinates. So, my bitmap file of the alphabet stores each letter as a 32x32 square let's say: A B C D E F G H I ... etc. I make a horizontal grid of vertices, with doubles on the overlapping edges of the individual squares I'm trying to form. 1 2/5 7/9 11 3 4/6 8/10 12 That's 3 square right there. Now I want to write "CAT"; I know C = 2, A = 0, T = 19. If I have 26 letters in my bitmap, I know that there is a texture coordinate of 1/26 between the letters (remember texture coordinates go from 0 to 1). Now I start setting some texture coordinates. C = 2. So I set the following texture coordinates (U, V) for each vertex for the letter C: 1: (2 * 1/26, 0) 2: (2 * 1/26, 1) 3: (3 * 1/26, 0) 4: (3 * 1/26, 1) A = 0. So for A: 5: (0 * 1/26, 0) 6: (0 * 1/26, 1) 7: (1/26, 0) 8: (1/26, 1) T = 19. 9: (19 * 1/26, 0) 10: (19 * 1/26, 1) 11: (20 * 1/26, 0) 12: (20 * 1/26, 1) And I'm done. Does that work for you, or do you need something in GDI?
11. ## Fastest way to render text?

Have you tried using fonts? http://msdn.microsoft.com/en-us/library/bb173961%28VS.85%29.aspx
12. ## Incorrect shader/normal issue in Directx

Excellent! I've never had to deal with a coordinate system mix-up, but now I know what one looks like. And I know what you mean about long works in progress... Anyway, glad I could help throw stuff out there. -- Steve.
13. ## Real-time lens blur

Awesome effect. I love bokeh, so much that spent millions of dollars on building a depth of field adapter for my video camera so I could make grainy movies full of bokeh. You have an interesting approach here--more thinking than I would have put into this at first, but now that you are describing your problem, I'm having ideas. I know you say that you're not doing DOF blurring just yet. One thing I would like to mention--the blurs don't pick out the specular highlights, although it does seem that way sometimes. The blurs happen to the whole image, and you _notice_ the specular highlights because they most obviously get blurred against a dark background. In fact, the entire image behind your subject is being blurred with what Photoshop would call a "lens blur" (just a convolving filter like you plan to apply for your DOF blur). The size of the blur is a function of your depth of field and your distance only, not the luminosity, if I remember right (correct me if I'm wrong though!). Lens blur is imperfect though; take a look at this page on bokeh at Wikipedia, particularly the faux-bokeh shown at the bottom. You don't really get a choice of apertures, which I think is why we need your effect. You might have already known all that though--in which case, sorry I digress! Ultimately I think we need a way of blurring the specular highlights using your aperture shape, which are getting slightly muddled in your downsampling (and so a new pixel gets the chance to be "brightest" each time). This sounds simple, and I am not a shader pro or familiar with GLSL, but is there a way you can operate on the specular value of your stuff (input to the pixel shader maybe? I'm not sure where that comes together, to be honest!) and apply your effect to things with a specular value >0.5? I'm also not sure that that would work for light sources, though, which are also a wonderful source of bokeh blurs. One other thing--I notice your blurs from the floor are getting drawn in front of your character. Just out of curiosity, how are you going to stop that from happening (I'm still learning shaders bit by bit here, there's probably an awesomely easy way to do it, so sorry for the dumb questions!)? I might be going down the wrong path with that; it's getting late for me. Let us know how this turns out though, I'm very interested in this effect! -- Steve.
14. ## Incorrect shader/normal issue in Directx

Okay, sorry for the late reply. The shader looks perfect--is this from Riemer's tutorial by any chance? :) A couple more questions I should have asked: 1. What's the orientation of the cube? (What's the camera and cube position? Or, the face on the top is in the X-Z plane, the face on the right is in the Y-Z plane, and the face on the left is in the X-Y plane, right?) 2. What's the other side of the cube look like? Can you move the camera there so we can see what that looks like? 3. You generated that corrected cube image outside your program, right? (Photoshop or something?) The answer to my second question is particularly important: I have a hunch that your two faces that you show rotating in your figure are actually correctly lit, and the one closest to us (on the left in your figure) is actually incorrect. If we get to the other side of the cube (rotate the camera 180 deg around the cube's Y axis) and find that the other face is dark, I would say both those faces have their normals pointing inwards. The light is on the other side of the face we see is lit, and the face you think is right actually has its normal pointing inwards toward the center of the cube (at the light) and is thus getting lit incorrectly. If the opposing face is dark, its normal is wrong too. Try flipping it and see what happens. (There's a chance that if one's flipped, they're all flipped, so stick a negative sign in front of them in your shader and see if things look right; if things look worse, undo that and try flipping them one by one in your code to find the bad one.) That was probably a bad explanation; if I had the art skills I would draw it. But does that make sense? You might have already done those things--sorry if I'm asking a lot of the same questions you've asked yourself! Just trying to get oriented. I'm interested in this kind of problem though, because it's the little gnat that bugs you when you're programming, maybe for a couple days, but when you realize your mistake (it can sometimes be a silly one, like a negative sign), you'll recognize the situation (or a similar one) later and know how to fix it immediately. In the meantime...let me try and come up with a picture to explain what I'm saying... Good luck! -- Steve.
15. ## Incorrect shader/normal issue in Directx

I'm curious to see your shader. I think your vertex shader may be flipping things around. You can post it using either ['source]['/source] (get rid of the '). -- Steve.
• Advertisement