Directx 11 spheres - geometry

I'm looking for an efficient way to display lots of spheres using directx 11. The spheres are defined by (x,y,z,r) where (x,y,z) are coordinates in space and r is the radius. I want to display only the spheres that can be seen, meaning that spheres that are not in the field of view and spheres that are too small to be seen wouldn't be drawn. However, if a group of spheres smaller than one pixel is at least as big as one pixel, then I want to display the most predominant color. Spheres have only one color and different levels of transparency. Any help would be appreciated and incomplete answers are acceptable.

You need several things. First an indexed unit sphere geometry, second a buffer to store the sphere instance properties ( position, radius and color ) and third a small buffer for the API parameters yet to come. The three combines in a single 'ID3D11DeviceContext::DrawIndexedInstancedIndirect'
The remaining question is "how to feed the instance buffer ?". cpu is easy, just apply frustum culling, sort back to front because of the transparency and apply a merge based on the screen projection, update the buffer and use 'ID3D11DeviceContext::DrawIndexedInstanced'.
gpu version will do the same thing with compute shaders but will be harder to implement. The advantage, zero cpu/gpu synchronization and should support far more instance.

Related

Are triangles rendered in order in a single draw call/command in Vulkan? [duplicate]

This question already has an answer here:
Is synchronization needed between multiple draw calls with transparency in Vulkan?
(1 answer)
Closed 1 year ago.
Related to this question about ordering or triangles in OpenGL , I'm wondering what the situation is in Vulkan. To illustrate:
Example. A GUI batches a whole bunch of vertices for many windows/widgets and embeds the zvalue/depth in each vertex. In many cases you use one draw call to render a lot. For this to work then the order of each triangle/vertex in the primitive being rendered must be preserved. I've seen IMGUI do this.
If the ordering is preserved, then is it also for blending? Or just the depth buffer writing/reading? For example, consider the following example:
I have 100 meshes, and they are all solid (no transparency). I push the vertices all into a buffer, and submit ONE draw call to draw TRIANGLES. If the depth buffer is written for triangle 1 before triangle 2, then the correct ordering will happen.
My 100 meshes have transparency. None of them overlap in space. And I order them by depth. Will triangle 1 be blended onto triangle 2 correctly (triangle 1 comes before triangle 2)?
If it works for the depth but not the blending then is it a case that the depth buffer reads/writes are ordered corresponding with the triangle input order but not the color buffer reads/writes? If so, why is this?
Edit: The question marked as duplicate asks about rendering order "between draw calls". This question is about order WITHIN a draw call, and I've learned is referred to as "rasterisation order".
Vulkan rasterises triangles as if in order, unless you specify that it is fine otherwise with an AMD out-of-order rasterisation extension. However, the gpu will process the triangles and vertices in parallel, but it only affects you in certain circumstances. The reason graphics APIs preserve triangle order is mostly for possability of transparency sorting: for blending.
If gui embeds depth information, then the order doesn't matter, unless some elements have same depth and draw on top of each other. The depth buffer makes it so no matter the order of triangles, only the closest(topmost, whatever) pixels are rasterised; For every pixel that appears, if depth tests are enabled, it compares(comparison operator can be chosen) the value that is already stored with the new pixel, and only if comparison returns true will it write the pixel and depth(if depth writes are enabled).
Depth generally doesn't care about triangle ordering, but they are ordered correctly anyway.
Transparency cares about triangle ordering, and so will only work if you sort triangles beforehand(unless you have commutative blend operator and disabled depth testing). Depth testing makes sure your transparent objects don't appear in front of your opaque geometry.

In computer graphics, faces of a polygon

In computer graphics, why do we need to know that backward face and forward face of a polygon are different?
There are several reasons why a triangle's face might be important.
Face Culling
If you draw a cube, you can only ever see at most 3 sides of it. The front three sides will block your view of the back 3 sides. And while depth testing will prevent drawing the fragments corresponding to the back sides... why bother? In order to do depth testing, you have to rasterize those triangles. That's a lot of work for triangles that won't be seen.
Therefore, we have a way to cull triangles based on their facing, before performing rasterization on them. While vertex processing will still be done on those triangles, they will be discarded before doing heavy-weight operations like rasterization.
Through face culling, you can eliminate approximately half of the triangles in a closed mesh. That's a pretty decent performance savings.
Two-Sided Rendering
A leaf is a thin object, so you might render it as one flat polygon, without face culling. However, a leaf does not look the same on both sides. The top side is usually quite a bit darker than the bottom side.
You can achieve this effect by sending two colors when rendering the leaf; one meant for the top side and one for the bottom. In your fragment shader, you can detect which side of the polygon that fragment was generated from, by looking at the built-in variable gl_FrontFacing. That boolean can be used to select which color to use.
It could even be used to select which texture to sample from, if you want to do more complex two-sided rendering.

How heavy is hardware tessellation?

If tessellation gives a bonus over just using high-poly models,then why do modern 2012 games still use gigantic models that take a lot of hard disk space instead of tessellating it all and just adjusting the tessellation factor to depend on distance from camera,creating a nice level of detail.
You can't get back detail by tessellation that was not there in the first place. It just means those models would be even bigger without it being available.
In its most basic form, tessellation is a method of breaking down polygons into finer pieces. For example, if you take a square and cut it across its diagonal, you’ve “tessellated” this square into two triangles. By itself, tessellation does little to improve realism. For example, in a game, it doesn’t really matter if a square is rendered as two triangles or two thousand triangles—tessellation only improves realism if the new triangles are put to use in depicting new information.
When a displacement map (left) is applied to a flat surface, the
resulting surface (right) expresses the height information encoded in
the displacement map. The simplest and most popular way of putting the
new triangles to use is a technique called displacement mapping. A
displacement map is a texture that stores height information. When
applied to a surface, it allows vertices on the surface to be shifted
up or down based on the height information. For example, the graphics
artist can take a slab of marble and shift the vertices to form a
carving. Another popular technique is to apply displacement maps over
terrain to carve out craters, canyons, and peaks
http://www.nvidia.com/object/tessellation.html
I think the reason why nobody uses hardware tessellation in games is, that ca. 60% of all game player are console player and aslong the console doesnt support shadermodel5, there is no reason to do games that uses hardware tessellation. Even if they do, they may be have to do a game in dx9 and dx11 because it is not really good downward compatible... but maybe there is an other reason to!
With the new consoles comming out this year, maybe HW Tessellation gets an other change ;)

Antialiased composition by coverage?

Does anyone know of a graphics system which handles composition of multiple anti-aliased lines well?
I'm showing a dependency diagram and have a bunch of curves emanating from a point. These are drawn anti-aliased in the usual way, of blending partially covered pixels. So if two lines would occupy the same half of a pixel, the antialiasing blends it to 75% filled rather than 50% filled. With enough lines drawn on top of each other, the pixel blend clamps and you end up with aliased lines.
I know anti-grain geometry has algorithms for calculating blends which cater for lines which abut, and that oversampling might work, but are there any other approaches?
Handling this form of line composition well is going to be slow (you have to consider all the lines that impinge upon each pixel using a deferred rendering approach). I doubt that there are many (if any) libraries out there that will do it for you.
The quickest and easiest method (and possibly the only realistic and cost effective solution for your case), which will work with virtually any drawing library would be to supersample it - draw to an offscreen bitmap at much higher resolution (e.g. 4 times wider and higher, with lines of 4 pixels width. Disable antialiasing when drawing this as it'll only slow it down) and then scale the result down with bilinear filtering. The main down-side is that it uses a lot of memory for the offscreen bitmap.
If you need an existing system that gets antialiased lines "visually correct", you might try using one of several existing RenderMan-compliant 3D renderers. The REYES algorithm, which many of these renderers use, works by breaking up primitives into micropolygons, then sampling them at several random point locations within each pixel. So even if you have a million lines collectively obscuring 50% of a pixel, the resulting image value will show roughly 50% coverage. (This is, for example, how the millions of antialiased hairs are drawn on characters in many animated movies.)
Of course, using a full-blown 3D renderer to draw 2D lines is like driving nails with a sledgehammer. You'd need a fairly pathological scenario for the 3D renderer to be any more efficient than simply supersampling with a traditional 2D renderer.
It sounds like you want a premade drawing library, which I do not know of.
However, to answer your question of knowing any approach that would work, you can consider a pixel to be a square. You can then approximate any shape that you draw as a polygon that intersects the pixel box. By clipping these polygons against the box of the pixel and against each other, you can get a very good estimate of the areas associated with each color that intersects the pixel for accurate antialiasing. This is, of course, very slow to calculate and is not suitable for interactive drawing.

What does 'Polygon' mean in terms of 3D Graphics?

An old Direct3D book says
"...you can achieve an acceptable frame
rate with hardware acceleration while
displaying between 2000 and 4000
polygons per frame..."
What is one polygon in Direct3D? Do they mean one primitive (indexed or otherwise) or one triangle?
That book means triangles. Otherwise, what if I wanted 1000-sided polygons? Could I still achieve 2000-4000 such shapes per frame?
In practice, the only thing you'll want it to be is a triangle because if a polygon is not a triangle it's generally tessellated to be one anyway. (Eg, a quad consists of two triangles, et cetera). A basic triangulation (tessellation) algorithm for that is really simple; you just loop though the vertices and turn every three vertices into a triangle.
Here, a "polygon" refers to a triangle. All . However, as you point out, there are many more variables than just the number of triangles which determine performance.
Key issues that matter are:
The format of storage (indexed or not; list, fan, or strip)
The location of storage (host-memory vertex arrays, host-memory vertex buffers, or GPU-memory vertex buffers)
The mode of rendering (is the draw primitive command issued fully from the host, or via instancing)
Triangle size
Together, those variables can create much greater than a 2x variation in performance.
Similarly, the hardware on which the application is running may vary 10x or more in performance in the real world: a GPU (or integrated graphics processor) that was low-end in 2005 will perform 10-100x slower in any meaningful metric than a current top-of-the-line GPU.
All told, any recommendation that you use 2-4000 triangles is so ridiculously outdated that it should be entirely ignored today. Even low-end hardware today can easily push 100,000 triangles in a frame under reasonable conditions. Further, most visually interesting applications today are dominated by pixel shading performance, not triangle count.
General rules of thumb for achieving good triangle throughput today:
Use [indexed] triangle (or quad) lists
Store data in GPU-memory vertex buffers
Draw large batches with each draw primitives call (thousands of primitives)
Use triangles mostly >= 16 pixels on screen
Don't use the Geometry Shader (especially for geometry amplification)
Do all of those things, and any machine today should be able to render tens or hundreds of thousands of triangles with ease.
According to this page, a polygon is n-sided in Direct3d.
In C#:
public static Mesh Polygon(
Device device,
float length,
int sides
)
As others already said, polygons here means triangles.
Main advantage of triangles is that, since 3 points define a plane, triangles are coplanar by definition. This means that every point within the triangle is exactly defined as a linear combination of polygon points. More vertices aren't necessarily coplanar, and they don't define a unique curved plane.
An advantage more in mechanical modeling than in graphics is that triangles are also undeformable.

Resources