I'm currently learning how to use Metal and having some difficulty using the stencil buffer – possibly because its the wrong solution for the problem I have.
The problem: I have a tree of 2D render nodes, quads, that I'm rendering with metal. For some quads, I'd like to enable a 'clipping mask', that clips the rendering of all its sub-nodes to within its bounds.
I imagined that this might be a good use-case for the stencil attachment (Metal is my first foray into low-level graphics APIs) but am not 100% sure.
Having set-up the depth attachment however, I've got no idea of what to actually do with it. Is it even possible to implement this idea of nested clipping masks with this method?
My rough idea for how it might work would be:
Set-up a pipeline state for each quad as usual
Set-up a couple of depth stencil states, one for tree elements that will clip, and one for nodes that won't. (Write masks of 0xFF and 0x00 respectively.)
Begin a render pass as usual and begin traversing the tree.
If a node should clip, use the clipping depth stencil state otherwise the non-clipping.
Any idea if this is the right approach?
Any thoughts as to the specifics of tackling this problem. i.e configuration of the MTLStencilDescriptor and its read/write masks and various comparison operations and functions. How I would set the stencilReferenceValue on the render command encoder? Increment it at each level of the tree?
EDIT: A Similar question attempts to tackle this problem in Open GL (although the solution comes with its own compromises), so it appears that the above problem can be tackled using a stencil attachment.
The solution in the linked question notes "by giving each level in your scene graph a higher number than the last, you can assign each level its own stencil mask," but comes with the caveat: "Of course, if two siblings at the same depth level overlap, or simply are too close, then you've got a problem."
Is there a better way of achieving this with the capabilities that Metal provides? An idea of/pointers to a recommended algorithm/method to do this within the capabilities of Metal's API would be appreciated!
Related
For SCNFloor, if the reflective is set to 1 and reflectionFallOffEnd is big enough, it will be like a mirror.
My question is how to apply this to other geometries (say plane or box)? As I want to have a mirror in my game.
I have done quite a bit of research on how to make reflections using Scenekit.
Here are the different leads I found (sadly, they will all need a serious amount of code and research):
Screen-Space reflections
Pros :
Cheap
Easy to make
Cons
Doesn't always look great
I'm not sure how to output a normal pass with SCNTechnique
Parallax-mapped cubemaps
Pros :
Cheap
Looks amazing
Cons
No real time objects unless using an image proxy
No good code sample online, will need research
Not quite sure how to use it with SCNProgram
Two cameras + Stencil
Pros :
Realistic
Real time
Almost built in
Cons
No documentation of the pointOfView of SCNTechnique
No documentation on Stencils
Needs to render the scene twice
OpenGL mirror
Pros :
Actually duplicates the geometry, so very accurate
This is the technique used by SCNFloor (I think)
Cons
Geometry can clip with the mirror plane (happens with SCNFloor)
Unusable on anything other than a plane
Needs OpenGL Code
4 Cameras linked to a Cubemap
Pros :
Easy to set up
Real time
Works on any object
Very popular technique in modern Video Games
Cons
I have no idea if this would work
Will need to render the scene 5 times for a single mirror
Not very accurate depending on object
My conclusion is that we need more help on using SCNTechnique. We could build amazing things with it but the lack of documentation and examples is a big problem.
If you could specify what kind of mirror you have in mind, I'll be happy to help you choose the best way to go.
I know this is an old question, but I wanted to share what I have done. I created a gist on GitHub that contains the code and explains how it works.
It basically attaches six cameras to a node and automatically creates a cubemap that is then used as the reflective property of the object. The main downside is that it won't work with physically based materials, but in order to simulate roughness, it blurs the cubemap to whatever you set the roughness property to. It works well in real time and you can set how quickly the cubemaps update so that you are not affecting the framerate of your game too much. It can also handle many different reflective objects and automatically stops updating nodes that you can't see.
This is currently not supported on other geometry types. Please file a request to Apple.
I have this huge model(helix) created with 2 million vertices at once and some million more indices for which vertices to use.
I am pretty sure this is a very bad way to draw so many vertices.
I need some hints to where I should start to optimize this?
I thought about copying 1 round of my helix (vertices) and moving the z of that. But in the end, I would be drawing a lot of triangles at once again...
How naive are you currently being? As per rickster's comment, there's a serious case of potential premature optimisation here: the correct way to optimise is to find the actual bottlenecks and to widen those.
Knee-jerk thoughts:
Minimise memory bandwidth. Pack your vertices into the smallest space they can fit into (i.e. limit precision where it is acceptable to do so) and make sure all the attributes that describe a single vertex are contiguously stored (i.e. the individual arrays themselves will be interleaved).
Consider breaking your model up to achieve that aim. Instanced drawing as rickster suggests is a good idea if it's sufficiently repetitive. You might also consider what you can do with 65536-vertex segments, since that'll cut your index size.
Use triangle strips if it allows you to specify the geometry in substantially fewer indices, even if you have to add degenerate triangles.
Consider where the camera will be. Do you really need that level of detail all the way around? Will the whole thing even ever be on screen? If not then consider level-of-detail solutions and subdivision for culling (both outside the viewport and within via the occlusion query).
I'm making an iOS app and I want to be able to render with individual "layers" so that I can do blending between them and use shaders on each individually before blending them all together and rendering to the screen.
I understand that I will be rendering to Textures and then rendering these textures on top of each other in the framebuffer, but I am not understanding clearly what code needs to be written to follow this procedure. In another answer I found what I want to do, but I don't know what code accomplishes this task: How to achieve multi-layered drawing with OpenGL ES on iOS? (For example how do I "Bind texture 1, then draw it"? What does it mean to "Attach texture 1"?)
I've also looked at Apple's documentation regarding this technique but it isn't very clear about the steps or code for the actual rendering part of the process.
How would I go about doing this? (hopefully with code examples of each step because I haven't understood spotty instructions that expect me to just know what is needed for each step)
Here is an example of what I want to do with this. The spheres would be rendered into a "layer" or Texture2D which I would then pass through the shader, then render on top of a already partially rendered scene. I don't know exactly what kind of openGL code could do that.
You're looking at wrong place. To use OpenGL, you need to study OpenGL, not anything else. Apple doesn't provide any OpenGL documentation because it's an open standard, so the specs are freely published. Apple assumes you're already familiar with it.
OpenGL ES 2.0 spec
manual pages
I think you are having trouble because you don't have understanding of GL specific terms. The spec describes them very well and clearly. So, please read the spec. That will save your time A LOT. Or you will keep the trouble.
Also, I like to introduce a site which has very nice conceptual description of OpenGL pipeline.
http://www.songho.ca/opengl/
This site is targeting desktop GL, and some API may be different a little. Please focus on conceptual understanding. For example, here's an illustration from the site.
For more tutorials, google with proper keyword like OpenGL ES 2.0 tutorials (or how-tos). Here's an example link, and would be helpful. There're also many more tutorials. If spec is too boring, it's also good to have some fun with tutors.
Update
I like to say one more. IMO, the OpenGL is all about drawing triangles. Everything is ultimately converted into triangles in 3D space to represent some shape. Anything else all exists only for optimization. And in most cases, GL chooses batch processing for major optimization strategy. Because overhead of each drawing call is not affordable for most games.
It's hard to start OpenGL ES because it's an optimized version of desktop GL, so all convenient or easy drawing features are stripped off. This is same even on recent version of desktop GL.
So there's no such drawOneTriangle function. Instead GL has something like
make a buffer,
put list of many triangles there
select the buffer for next drawing.
draw all triangles in current buffer at once
delete the buffer.
By using buffer, you don't need to dispatch duplicated data to GPU from CPU. And GL uses this approach everywhere. For example, you don't have such drawOneTriangleWithTexture function to use textures. Instead, you have to
make a buffer
put list of many pixels there (bitmap)
select the buffer for next drawing.
draw all triangles with the texture pixel data in current buffers.
delete the buffer.
Everything overly complex stuffs on GL are all exists for optimization. This may look weird at first, but there're usually very good reasons for the design.
Update 2
Now I think you're looking for render to texture feature. (well actually you already mentioned this…)
You can use a rendered image as a texture source. To do this,
you need to bind a frame-buffer with texture object rather then render-buffer object using some functions like glFramebufferTexture.
Once you render to a texture, and switch frame-buffer to final buffer, and bind the texture you drawn and others, and perform the final drawing. You need two frame buffers: one for render-to-texture, and one for final output.
In Threejs, what is the most performant way to display a large number of cubes on an xyz grid for the WebGL renderer, in terms of which rendering methods/ lights/ settings/ material to use? The cubes should support receiving and casting shadows based on a directionLight -- or I can precalculate the side colors if that helps and is possible -- but they don't have any texture or special rotation. Thanks!
Be sure to merge your geometry. It helps a LOT. up to 60times more code. here is a post explaining why. It contains a demo actually showing the difference
http://learningthreejs.com/blog/2011/10/05/performance-merging-geometry/
Another things is to remove the duplicated faces when applicable. For example three.js minecraft demo remove the faces from the geometry. http://mrdoob.github.com/three.js/examples/webgl_geometry_minecraft.html for the demo and https://github.com/mrdoob/three.js/blob/master/examples/webgl_geometry_minecraft.html#L106 for the source
In 3d terrain that consists of thousands of cubes (i.e. Minecraft ), what is a way to handle each block in terms of location and rendering? More specifically, I know that drawing a primitive of a cube and world transforming it everywhere in directX 9 is probably a ridiculous way to accomplish this since there are so many performance issues, so I was wondering what a more reasonable method would be.
Should each cube be a mesh that's copied many times, or is their a way to create the appropriate meshes from the data in your vertex buffer?
I found this article that walks through some of the theory behind implementing what I want to implement, but I've never used octrees before so I wasn't able to take too much from the source code. If octrees are indeed the way to go, where is a good starting point to learn about them? Most of my google searches only turned up blog posts about theory with little or no implementation examples.
It seems like using voxels would be useful in doing this, but like with octrees, I'm coming from no experience here, so I don't really know what to study first.
Anyway, thanks for any advice\resources\book names you can spare. I'm sure it's obvious, but I'm still very new to 3d programming, so I appreciate your help.
First off if you're using Minecraft as your reference, think of their use of chunks and relate it to Oct-trees. Minecraft divides up their world into smaller chunks to handle the massive amount information that is needed to be stored so use Oct-trees to organize this data that will be stored. Goz has a very accurate description of how Oct-trees and Quad-trees work, so use his information as a reference.
Another thing to consider is that you don't actually want to draw every cube to the screen as this will eat up your framerate. Use Object Culling to only draw visible cubes to the screen. Again if you think Minecraft; have you ever encountered a glitch where you can see through the blocks and under the world? This is because Minecraft only draws the top layer of blocks. With this many objects on screen, it would be a worthwhile investment to look into Object Culling using both the camera frustum and occlusion query.
For information on using DirectX I would recommend any book by Frank Luna. I own this book myself and it never leaves my side when programming in DirectX. http://www.amazon.com/Introduction-Game-Programming-Direct-9-0c/dp/1598220160/ref=sr_1_3?ie=UTF8&qid=1332478780&sr=8-3
I highly recommend this book as I've learned almost everything I know about DirectX from it.
Upon a Google search I found this link that discusses Occlusion Culling, because Luna doesn't cover occlusion culling, only frustum culling. I hear the Programming Gems series mentioned a lot, but I can't attest to its name personally. http://http.developer.nvidia.com/GPUGems/gpugems_ch29.html
Hope this helps.
Oct-trees are fairly simple, especially axis aligned ones like those in mine craft.
It is basically just a 3D extension of the quad-tree. You may find it easier to learn about Quad-trees first.
To give you a quick overview of a quad-tree; basically you start off with a square. Now imagine placing a much smaller square in that square. If you wish to build a quad tree representing it you first divide the original square into 4 equal sized squares.
Next you check each quadrant and if the smaller square is in that quadrant you split that quadrant into 4 smaller sized squares. Then you check those 4 quadrants choose the quadrant and subdivide. Eventually your smaller square will be wholly contained in one or more quadrants inside quadrants inside quadrants (etc). You have now built your quad tree.
Now if you imagine you are searching for a specific square inside the larger square you can quickly see the bonus of a quad-tree. Instead of searching every possible square in the quad tree (equivalent to searching every pixel in a texture) you can now check the first 4 quadrants to see if they contain it. If one does you can check its 4 sub quadrants and so on until you find the smallest quadrant wholly containing your square (or pixel). This way you end up doing many fewer tests to find your object.
Now an oct-tree is basically the same thing but instead of encoding squares in squares you now encode cubes in cubes. Every cube can be split into 8 smaller octants (and hence the name oct-tree).
Oct-trees have the advantage that by knowing which octant you are starting in you can easily cast rays through the oct-tree to find collisions (as an octant is either full, partially full or it is empty). If an octant is empty then you pass right through it and then check the octant on the other side. If it is partially full you check its sub-octants and so on until you either find a full octant (ie you've hit a solid cube and you render it) or you pass through the octant entirely and hence there is no cube to render. This is how minecraft works (I'm guessing anyway ;)). This is also a good way of quickly rendering voxel data which more people are looking into these days as a possible future rendering mechanism.
Hope thats some help! :)
Oct-trees and quad-trees are useful for culling sections of your geometry to render. Minecraft uses 16x16x16 render blocks to break up the terrain into manageable pieces.
Another technique to consider is instancing. Instancing is where you tell the GPU to render an object multiple times in different locations. It's used for crowd rendering, trees, anything where the geometry is the same, but you have lots of them.
http://msdn.microsoft.com/en-us/library/windows/desktop/bb173349(v=vs.85).aspx
http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter03.html
Here is an article where the writer duplicates the minecraft renderer in OpenGL 4. While the code won't apply to your case the techniques (culling cubes that are surrounded, etc) can be applied to a directx renderer.
http://codeflow.org/entries/2010/dec/09/minecraft-like-rendering-experiments-in-opengl-4/
Don't be fooled by the blocky graphics and the low quality textures. Minecraft is an extremely complex renderer and you'll need to come up with ways to handle the sheer number of items involved. For example even a "small" part of the world, say 100x100x100 blocks is 1 million blocks. To push each block to the GPU as a separate mesh would kill your GPU. The Minecraft renderer is far more complex than most first person shooters when you get down to the technology.