Jump to content
  • Advertisement

Darg

Member
  • Content count

    293
  • Joined

  • Last visited

Community Reputation

213 Neutral

About Darg

  • Rank
    Member
  1. Darg

    GPU ray tracing in real time

    About 4 years ago I wrote a GPU based raytracer written in directx 9 and XNA. This was used to evaluate the possibility of using raytracing for secondary rays in a deferred renderer where the GBuffer was used to determine the primary rays. For the thesis I used it for just shadow rays from one directional light. The result was this:   https://www.youtube.com/watch?list=UUEKKcDZ4qxf4rXDOKTD3Ktg&feature=player_detailpage&v=vqrg0yxZtvM#t=67   The video has three passes, the first without shadows the second using a shadow buffer and the third with raytraced shadows, I've linked to the third pass.   As you can see the result was quite slow, down to around 5fps, not exactly realtime. Modern hardware should be able to cope with this better, I tested this on an nVidia 470x GPU.   I used a simple dynamically updated fixed grid size octree where each cell contained object references which held the transform and an offset which pointed into a large texture containing the vertex position of all the object types in the scene, for this test I used polygonal spheres and a tree model. As the spheres are polygonal they are equivalent to an object with around 1,000 triangles if I remember correctly. I deliberately avoided parametric spheres as I wanted the results to equate to using real game assets. Using a 2k texture you could store up to 4 million vertices. Most games at the time limited their vertex count to under 10k for hero assets.   The octree as well was passed through in texture form, I can't remember the exact implementation I used to assure multiple objects could inhabit the same cell. With modern GPGPU programming languages you should definitely use better data transfer formats but as I was limited at the time to directX 9 HLSL I worked with what I had.   Long story short it is possible, but it's not fast. You're essentially duplicating your scene description, one for rasterisation and one for raytracing. I really like the idea of using the GBuffer to feed into secondary rays but it just doesn't make much sense at the moment as the "fake" methods look better (I had to downsample before raytracing) and perform much much better.
  2. Darg

    Atmospheric scattering

    I don't know how we can help without you explaining the problems you're having when trying to merge the two together? Perhaps have a look at other world renderers that have implemented atmospheric scattering ( there are plenty ) Before you post a question to the forums you really should have a look over it and make sure you've given enough information so that someone can answer it. Your question is so vague it's impossible.
  3. Darg

    [XNA] Picking

    You can have a look at my XNA code that does this. You start off with having a GetHeightAtLoc(float x, float y) method like this: public float GetHeightAtLoc(float x, float y) { if (x >= 0 && x < size && y >= 0 && y < size) { if (x >= size - 1) { if (y >= size - 1) { return heights[(int)x + ((int)y * size)]; } float modY = y % 1; int cX = (int)x; int cY = (int)y; return MathHelper.Lerp(heights[cX + (cY * size)], heights[cX + ((cY + 1) * size)], modY); } else if (y >= size - 1) { float modX = x % 1; int cX = (int)x; int cY = (int)y; return MathHelper.Lerp(heights[cX + (cY * size)], heights[(cX + 1) + (cY * size)], modX); } else { float modX = x % 1; float modY = y % 1; int cX = (int)x; int cY = (int)y; float TopLin = MathHelper.Lerp(heights[cX + (cY * size)], heights[(cX + 1) + (cY * size)], modX); float BotLin = MathHelper.Lerp(heights[cX + ((cY + 1) * size)], heights[(cX + 1) + ((cY + 1) * size)], modX); return MathHelper.Lerp(TopLin, BotLin, modY); } } else { return 0; } } Then you have a method that takes a ray and intersects it with the terrain return a Vector3 point: public Vector3 GetRayCollisionPoint(Ray ray) { ray = ClipRay(ray, boundingBox.Max.Y, boundingBox.Min.Y); ray = LinearSearch(ray); Vector3 collisionPoint = BinarySearch(ray); if (Calc.Contains(collisionPoint, boundingBox)) { return collisionPoint; } else { Calc.MapBounds(ref collisionPoint, boundingBox); collisionPoint.Y = GetHeightAtLoc(collisionPoint.X, collisionPoint.Z); return collisionPoint; } } That method uses a Linear search along the ray until the ray goes under the terrain, it then performs a Binary search backwards until it reaches a close enough approximation, in this instance within 0.01f of the terrain height. This results in fast accurate results that are hard to break. A Linear only approach would not be accurate enough due to the large stepping size, decreasing the stepping size would drastically increase computation time. A Binary only approach is prone to breaking if for instance you are looking through one hill, out the other side of it above the terrain again and then into another hill, you might well get the intersection point with the second hill. If no intersection point is found then an intersection with the map bounds is performed and the height at that point used, so if you're looking at the map wall or roof it will give you the point just below it on the terrain. Here are the Linear and Binary search methods: private Ray LinearSearch(Ray ray) { ray.Direction /= 50.0f; Vector3 nextPoint = ray.Position + ray.Direction; float heightAtNextPoint = GetHeightAtLoc(nextPoint.X, nextPoint.Z); while (heightAtNextPoint < nextPoint.Y) { ray.Position = nextPoint; nextPoint = ray.Position + ray.Direction; heightAtNextPoint = GetHeightAtLoc(nextPoint.X, nextPoint.Z); } return ray; } private Vector3 BinarySearch(Ray ray) { float accuracy = 0.01f; float heightAtStartingPoint = GetHeightAtLoc(ray.Position.X, ray.Position.Z); float currentError = ray.Position.Y - heightAtStartingPoint; int counter = 0; while (currentError > accuracy) { ray.Direction /= 2.0f; Vector3 nextPoint = ray.Position + ray.Direction; float heightAtNextPoint = GetHeightAtLoc(nextPoint.X, nextPoint.Z); if (nextPoint.Y > heightAtNextPoint) { ray.Position = nextPoint; currentError = ray.Position.Y - heightAtNextPoint; } if (counter++ == 1000) break; } return ray.Position; } Let me know if you have any questions!
  4. It looks like your camera might be underneath the terrain?
  5. Darg

    Strange Lock Up Problem

    I'd be surprised if this were the case but have you tried checking your memory usage? If each chunk is quite large then it might just be at 256 it is too big to handle.
  6. I'm not really understanding the issue you're having either. It's identical functionality to the standard spotlight style shadow mapping just with a cube depth map. You're not calculating distances for the same points in space you're calculating them for two points that lie along an identical vector from the light source. Imagine this basic ASCII diagram: (Light Source) ---------light--------->(point a)- - - - - - - - - ->(point b) So in your depth map rendering point a will be rendered to your depth map with the distance of the solid line. Then when rendering point b with your camera you will multiple the world position of b by first the camera view matrix to get the correct screen position of the point then you multiply it by the light view matrix to get the position of the point in the cube map. You will sample the cube map at that point and read the depth of the solid line. You will compare that to the depth of b from the light source (solid line + dotted line) and realise it's longer therefore it must be in shadow.
  7. When drawing hud elements there is no need for any matrix transformations. You just need to create the polygon for the item in screen space, ie between 0 and 1 for both the x and y axes. What you're doing in your example is treating it as an in-world element thus rotating it is probably moving it away from where your camera is pointing just as if it was any other object in the world. In your case you just have to set up your vertices with x/y positions something like X = screenPos.X / screenWidth; Y = screenPos.Y / screenHeight; where screenPos is the desired position of the vertex. After that just pass it through to an effect written to handle 2D objects so it doesn't take in any matrices it just takes the input position and passes it directly to the pixel shader. I think you can actually just avoid having a vertex shader at all if you don't need one and anything that would normally get sent to the vertex shader will get sent straight to the pixel shader but I can't remember if I just made that up or not If you do need a vertex shader then it can be as simple as: Data screenVertexShader( Data in ) { return in; }
  8. Darg

    Terrain Textures

    Cropping down to a square image then scaling it to the nearest power of 2 size should work but will not be tileable. You could use mirror texcoords on your terrain but these tend to look pretty bad when viewed from afar. If you can get your hands on photoshop it's got a very nice method to make textures tileable, it works pretty well with low contrast textures like grass.
  9. As other people in here have said, it is in your best interests to take a few days and read up on 3D maths, in particular vector based maths until you're reasonably confident that you know the basic operations and what they do and give you as a result. Time spent now will be more than made up for later by saving you time with trivial problems like these. It will also help ensure that you framework is robust enough to handle such mathematics, for instance even the most basic camera should have some way of calculating its forward vector.
  10. Darg

    Persistant Planet

    Blink you have a good idea and it's somewhere along the lines of what I've always wanted to see more of in MMOs but I fear you're falling into the beginners trap of underestimating the amount of work involved in making such a game. That's not to say you shouldn't strive towards completing your goals, it's always good to have something to work towards, I do too but time has been lacking a lot lately so it hasn't seen a whole lot of progress and I tend to rewrite from scratch everytime I restart it! Anyway if I were you I would think about working on smaller projects that give you the knowledge, experience and potentially reusable code so that you can not only understand what's involved in such an undertaking but actually have a decent skill set to put towards its development along with a good start on what the engine would need. If I were in your shoes I would start looking at procedural terrain generation based on given seeds. Technically, if done right then a randomly generated planet on computer A should be identical to the one on computer B if they start from the same seed. Random number generators are just predictable pieces of code, same input goes in, same output comes out. They're not actually random at all, they just pretend to be Getting a planet created procedurally like that will probably take you the best part of a year to do on your own if you want to include vegetation and resource placement. To keep yourself motivated I'd try to think of ways of using it in a much simpler game, some sort of Moon Lander game or something springs to mind and shouldn't be hard to code once you have the basic terrain generation done. Once you have an actual game with a start, a fun part and an ending you'll find the motivation to improve upon it grows and grows.
  11. I can't delve deeply into the maths you're working with as it's far too late for me to try to understand but I do have one suggestion on getting the orientation of the track. You've probably thought of this already but simply get the location of the previous (or next) point and then create a vector between it and the current point. Perhaps get the vector from the previous point to the current point and average it with the vector of the current point to the next point. As for roll around the direction of the track that might have to be defined by the track designer or by some method that takes into account the current yaw around the vertical axes so when it goes around corners it rolls in that direction and such.
  12. I don't see the need to nest the switch statement here, surely you're just adding several more lines to a piece of code that's already too long? What you could do is have an array of levels 1-30. Then when you want to load a specific level you would just do: levelArray.load() or whatever your code looks like.
  13. Darg

    SpriteBatch BlendMode

    My first idea would be to group the sprites according to their desired blend mode in the spritebatch manager class. So you'd have a dictionary with a key for each different blend mode, then when a sprite is added you simply put it into the right array in the dictionary based on its blend mode. When drawing it would be a simple matter of iterating through the keys of the dictionary, if their arrays aren't empty then call the Begin method with the key then iterate through its array.
  14. I wrote my own python console window that appears in game before, it'd serve your requirements nicely allowing output as well as the power of python scripting which works excellently with XNA. Have a look here: http://xnaconsole.codeplex.com/ The code used is, I found a bit overkill in parts. I made a simplified version in a couple hundred lines of code it's that easy and quick to implement
  15. Darg

    Opposite of If statement

    I was just about to mention, before I saw Owls latest post that you're passing exactly the same variables through to World twice asking for two separate results. It would be far more readable if you simply introduced a third function in World that takes the variables once and does the two tests then passes back False if both of the values are true. You'll learn as you go on, especially with larger projects that if you come back to that code in a couple of months you'll have to spend half an hour just deciphering what it was you were doing with it all. In my opinion readable code is more important even than super efficient code. I know a lot of people will say that when programming for realtime calculations like games efficiency is paramount but readable code will make development easier and quicker which should give you plenty of time at the end for efficiency changes if they're even needed at that point
  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!