You can get Voxel Farm now. For more information click here.

Sunday, April 28, 2013

Video Update for April 2013

An update about clouds and a surprise topic for the second part.

Making these recordings feels a bit weird. I love talking to real audiences, but this feels more like leaving a message in someone's answering machine.


  1. How you are testing it? Some kind of prerender to determine what octree is visible?

    1. No pre-rendering of the actual geometry. I compute simple occluders from the geometry clipmap. Then each clipmap cell boundary box is tested against these occluders.

  2. I've been following your blog for some weeks now, and I like what you've done.

    But you never give any technical details beyond just some pictures/videos and a vague explanation. I understand you may want to keep secrets on how you do things but I've realized over the years that telling people how you do things doesn't make them implement it right away and steal your "ideas".

    So maybe you could give a lot more technical details on how you're doing things in your engine. I'm interested to know how you integrated it with Unity for example, the technical bits, not the Unity money shot :)

    Sorry for the small rant, good luck with your engine !

    1. It is fine.

      Note I did not integrate it with Unity. This is not for me to share.

      In general there are no ideas to steal. I you have been following the blog from the beginning you would see there are no secrets here. I have not invented anything new. I have put together a series of existing pieces. All the key links are there.

      I would love to do a better job at explaining all the details, but I rather spend that time coding new stuff. Even then, whenever I find a technique that I think it is key for anyone in this line of work, I share it openly.

      I remember a real story about this teacher. During an exam if you did not know an answer you could stand up and walk to him, and he would explain the solution to you. That was not cheating to him. His rationale was, if you really knew the matter you only needed a few pointers. If you did not know it, everything he revealed would be forgotten by the time you were back to your desk.

    2. I agree with you both on this, but clearly Miguel you have some serious talent for getting shaders to agree with you, I'd love to see more on how you go about putting shaders together to get this type of look and feel as aguably this is unlike anything in the indie market at the moment.

    3. Miguel's revealed ... well, almost everything if you're a dev familiar with procedural gen and graphics. He's revealed more than pretty much any other dev I've ever seen (outside of opening the code entirely).

      His session was also extremely revealing. He's told in sufficient detail almost every single part of his engine.

      Take for instance his comment here "I compute simple occluders from the geometry clipmap. Then each clipmap cell boundary box is tested against these occluders."

      I could be 100% completely wrong, but these are the kinds of things I infer from Miguel's comment. To work out the finer detail I'd need to implement it and play with it.

      Since we're on the CPU and depth buffer based techniques on the CPU are too slow (last time I checked). We're going to want a simple/fast/conservative approach with as few occluders as possible (since performance is occluders * occludees somewhat).

      I'd start with using the completely covered/opaque faces (axis aligned Quads) of the clip map cells as the occluders.

      Since we have a clip map, we already know the relative depth of cells, so it's just a matter of testing AABBs against axis aligned quads.

      Draw lines from the 8 points of the occludee AABB to the viewing point, and check where they intercept the axis of the quad. If all points are inside the quad, it's occluded, otherwise you need to draw it.

    4. Small clarification since I can't edit.

      In order it for it to be occluded the 8 points can be occluded by any occluder (not just a single quad). So we'd test each of the 8 points in turn (against each of the occluders) until we find one point that isn't occluded.

      We'd likely test near occluders first, and due to the regularity of the clipmap, we can further cull down occluders (at least by half) e.g. don't test northern occludees against occluders that are south of you.

    5. Regarding the occluders, it is pretty much like you said. But I am still testing different approaches to see which one performs better.

      Like you say testing the projected volumes analytically is the fastest approach, but does not include the case where one cell is occluded by two or more conjoint occluders. Joining occluders in real time becomes expensive, either you have to test non-convex volumes or you need to make everything convex, which results in a lot of false negatives.

      Then you have CPU rasterization techniques. I am seeing encouraging results in this direction. Maybe it is the one I will end up using.

    6. A reply to you clarification. Testing only the 8 corner points can fail in some cases. All corners may be occluded, but the middle of the cell could still be in full sight.

      You really need to test the whole thing. It sucks!

    7. This comment has been removed by the author.

    8. Of course ... and attempting to staple together occluders (so we can do one test) is going to get mighty painful as well.

      I'm kind amazed how CPU rasterization is promising, I've read about it in Frostbite (occlusion) and Killzone (cover detection), but I didn't think it would be practical, even when you're offseting such a huge cost as mesh generation.

    9. I just discovered this project via a techcrunch article. It looks awesome! I'll confess that I'm not a developer in any sense (poking around with VB doesn't count) but I love this program! Is there a plan to make the project open source?

    10. I definitely agree that the amount of content in this blog has been enough for me to throw together similar things and experiment with the trade-offs (although this blog has saved me some convincing wrong turns! thank you!). It's also not *too* detailed in the sense that many posts are fairly short and get the necessary points across - brevity is a powerful skill.

      As somebody said above, the place where I find detail most lacking is in the shaders; you do seem to have a sort of magic touch, but I'm also not very experienced with writing them, so maybe it will seem less magical as I become more comfortable with them. I'd be interested to know how careful you are about compatibility across platforms and OpenGL versions. If you wanted to add more detail somewhere, I'm throwing my vote in for shaders!

  3. This comment has been removed by the author.

  4. I love the fact that you made a volumetric filtering, It really speeds things up.
    Sorry if this seems a bit out of topic but i've been thinking of some kind of way to do volumetric textures without doing it in with tesseltation. << is what i meant by tesseltation.
    But i was thinking of doing a "approximate" approach, which changes indexbuffer for each chunk.
    There is something called Range Tree, where you try to access objects with a number, and you get the object from with a certain range, If that was stacked to 3 dimensions, you could create an Angle storage.
    So if you stack this with hardware instancing, you could sort of render each chunk as a static billboard facing towards you.
    The furthest chunks would look quite decent.
    But the close ones would have to be calculated in realtime due to the large amount of angles you can see.

    Sort of:
    RangeTree>> A
    A[anglex][angley][anglez].LOD << returns an indexbuffer of the triangles to be drawn at that angle.
    And the close by vegetation would probobally be needed to use something simular as the video.

    I'm just curious if this would be any method that would sound reasonable for preformance? Or would it not be any of worth to implement?

    1. God, what happend to the line, after "Sort of:"
      RangeTree>> A
      where RangeTree

    2. Seems to be a buff in the comment software. I cant write "<" and ">" in masses without messing with the HTML

  5. There's a moment near the start of this video where you glance down off the cliff and it looks like there's a stream in the valley below.

    I had to go back and pause the video to make sure it wasn't water (we can hope!), but it was just white rock with the light playing tricks. :(

    On the bright side, even the fact that my eyes were tricked like this lends a sense of realism that I've never got from other 3d engines.

  6. Thank you for the progress update. This is a great addition. It always bothered me how in games (like minecraft) you would occasionally clip the surface and see just how much of your world was being needlessly computed.

    How does this system work for geometry that you are about to see? Is there a buffering zone as the geometry nears visibility?

  7. I just found your engine recently, and I have to say, AMAZING job :) I'm a one-man development team myself, but I wouldn't say I'm near this level :P Keep up the great work! And who knows, maybe you'll be the next Minecraft :P

    Looking at the wire frame in your video, are you using vertex colors for the sky? Or is that an actual texture? Also, I'm sure there's probably a very logical and obvious explanation, but why are the chunks low detail in the center, and high detail at the edges?

    P.S: Impressive occlusion system you have going for you!

    1. Yes, you are correct, this is using vertex colors for the sky. The scattering functions run per vertex, not per fragment.

      Also, this higher vertex density allows with the clouds. I did not mention it in the video, but since the cloud texture tiles there is another layer of noise used to hide some areas so you won't see the repeating patterns. This noise function also runs in the vertex shader.

      The edges need higher detail because each chunk is produced in parallel. That means that two neighbor chunks could be in the pipeline at the same time. The mesh simplification logic produces different results based on the context, if it was too aggressive near the edges they would not match at all. For this reason simplification becomes less greedy as it approaches an edge.

  8. Hey Miguel,
    I've discovered your blog a couple weeks ago and only now I've been able to conclude the archive trawl :D

    I just wanted to show my appreciation, I am simply AMAZED at the level of polishing and profesional grade your project as reached. All of this in the comfofor of your pijamas....while typing on an iPad (!)...well I honestly can say I'd have already crushed the damn thing under a steamroller for how much is a pain typing in there (not counting usign logMeIn or Teamviewer touch-to-mouse input translation!).

    I had a serious jaw-drop in two distinct occasions:

    - when you switched to a realtime client-side generated terrain

    - right NOW that you found out a way to cull the unnecessary geometry.

    So...props for a job EXTREMELY well done so far and keep throwing at us these golden posts.


  9. Wow, got to say this is one epic blog. I have been following it for a good number of months now and I got to say, you are doing way better then me at keeping people updated on your work :D (and way better work as well).

    One question I have though is, would your terrain generation be able to generate planets? While I liked minecraft a lot, the thing that always bothered me was the infinite flat world. I think generating in a spherical manner would enable all sorts of cool things.
    Just my thoughts on this :D

    Keep up on the awesome project!
    -Patrick Martin

  10. hey can i have a download for this texture for a video on youtube it looks great and i want to show it off ill make sure to give you some props and just by the way it looks great keep up the good work!
    Thanks :)
    -Dylan Carney

  11. How did you render the wireframes so beautifully? OpenGL seems to have a terrible time using lines (depth-fighting is a big problem for me), and polygon occlusion has prevented me from getting good results by just rendering triangles and discarding internal fragments. Did you use OpenCL to do it, and then just render through OpenGL?

    And side note: thank you so much for making this blog - it's been an absolute godsend time after time. It's some of the most consistently interesting reading material I have!