Is there a way to specify attributes per element index in WebGL? Here's what I mean.
I want to draw shapes with lines at the edges and fat dots at vertices. So, here's the data structure I would have for a triangle:
Vertices: [0,0,0, 1,0,0, 0,1,0]
Edges: [0,1, 1,2, 2,0]
The vertices are an ARRAY_BUFFER and edges are an ELEMENT_ARRAY_BUFFER. So when I call drawElements on the edges using LINES, I get an outline of a triangle. Now, I can also bind color attributes to the vertices. Suppose I make them all red:
Colors: [1,0,0, 1,0,0, 1,0,0]
If I want to highlight a particular vertex, I just write the bufferSubData over the colors before I draw the fat dots for vertices and change it back before drawing the edges. But what if I want to highlight an edge? I change the colors to [1,1,1, 1,1,1, 1,0,0] and wish for the best. The edge (0,1) will be white, but the other two edges will be colored with a gradient: red at vertex 2 and white at the other (0 or 1).
So, can I specify that I want to use a particular color for the elements at indices 0 and 1 and a different color for elements at indices 2, 3, 4, and 5? And all that without doubling up on every vertex (e.g. making each vertex data look like [x,y,z, r,g,b] and having two of them side by side in the buffer so that an edge can point to a regular or a highlighted version of the same vertex).
Sorry, but no, it doesn't work like that—you'll have to duplicate data somewhere. A vertex isn't just a position, it's the collection of all attributes associated with that position, and so in WebGL/OpenGL's view, they're different vertices.
The simplest solution is to just duplicate the vertices with the updated colors. You could do more elaborate things like having an array of colors, passing in an attribute that enumerates the vertices (e.g., vertex 0 gets '0', vertex 1 gets '1', etc.), and then having logic in your vertex shader to compensate. That's a lot of work and complexity, and may not be simpler or faster.
Related
I am drawing many different triangles with one draw call glDrawElements.
I am storing the vertices inside a buffer with glBufferData.
I can now give each triangle a different color by storing the color data inside the same buffer i store the vertices. I can then use glVertexAttribPointer to tell opengl where the colors are. Inside the vertex shader i define an attribute and then copy it to a varying in order to pass it to the fragment shader.
This means that I have to define a color for each vertex of the triangle. So i have to define 3 colors, but I only need 1 color for each triangle.
Is there a way to do this more efficient? Does it even matter? Can I store 1 color for each triangle inside a server side buffer?
I am trying to draw two triangles in a single drawcall. The two triangles are parallel. And the forward direction of camera is along the normal of those triangles which is perpendicular to both triangles. From camera view, the two triangles are perfectly overlapped.
Alpha blend is enabled with blendop being srcAlpha and invSrcAlpha. The color of triangle in back is (0, 1, 0, 0.5), the color of triangle in front is (1, 0, 0, 0.5). And the RT is cleared as black. The pixel shader simply output the triangle color.
Here is an image to show the scene, the vertices of triangles are indexed as in the image.
What could be the final color in RT, could be all (0.5, 0.25, 0). In graphics pipeline, is it guaranteed the pixel of green triangle output before red triangle?
You do not any guarantee on the pixel evaluation order, here the red and green pxel can be evaluated in any order. Precisely be executed in the order the triangles are ordered in the vertex/index buffer.
It exists a feature named Rasterizer Order Views, documentation here. But, first, it depends on an optional feature, and second, it can only turns on when you are using a unordered access view, it is not the case here when you simply use the output merger to write the samples.
It looks like DirectX pipeline guarantees the order.
"DirectX rendering follows a strict set of rule that ensure triangles are always rendered in the order they are submitted: if two triangles are overlapping on the screen, the hardware guarantees that Triangle 1 will have its color result blended to the screen before Triangle 2 is processed and blended."
Here is the link https://software.intel.com/en-us/gamedev/articles/rasterizer-order-views-101-a-primer, and at the section "DirectX Pipeline and the limitations of UAVs".
I am trying my hand at writing a 3d graphics engine, but I am having some trouble with drawing the shapes in the correct order.
When I translate the points of triangles into window space, i.e. the 2-dimensional space that directly correlates to position on the screen, in addition to an x and y position of each point, I also assign them a depth variable that stores how far away from the viewer that point was in 3d space.
At the moment, the only shapes I am rendering are triangles. My current render order algorithm sorts the triangles by the average depth of their 3 points. I knew when I started it that it would not be perfect, but I wanted a placeholder for testing.
For testing purposes, I constructed a square box with an open top, each side being a different color and made from 2 triangles, as shown below:
As you can see from the image above, the algorithm I am using works most of the time. However, at certain angles and positions, the triangles will be rendered in the wrong order, as show below:
As you can see, one of the cyan triangles on the bottom of the box is being drawn before one of the yellow triangles on the side. Clearly, sorting the triangles by the average depth of their points is not satisfactory.
Is there a better method of ordering shapes so that they are rendered in the correct order?
The standard method to draw 3D in correct depth order is to use a Z-buffer.
Basically, the idea is that for each pixel you set in the color buffer, you also set it's interpolated depth in the z (depth..) buffer. Whenever you're about to paint the next pixel, you first check that z-buffer to validate the new pixel if in front of the already painted pixel.
On top of that you can add various sorts of optimizations, such as sorting triangles in order to minimize the number of times you actually paint the color buffer.
On the other hand, it's sometimes required to do the exact opposite in order to properly handle transparency or other "advanced" effects.
When you draw triangle with 3 different colors for 3 vertices, XNA automatically interpolates pixel colors in between these vertices. I would like to disable this behavior and supply my own algorithm that determines color of in-between pixels (for example, use average of 3 colors). How this should be done in XNA?
The interpolation is the basic behaviour of a shader, you can not avoid that.
if you send vertex data to a pixel shader, the data of the three vertex that form a triangle will be interpolated.
So if you want to use the average of the three colors, one option maybe precalculate them in the cpu... and send it to gpu through a differet vertex buffer, this way you can change it when you want without change the vertex buffer that contain the vertex positions....
Of course if a vertex is shared with two triangles, and it has different colors, you have to duplicate it.
I'm learning XNA by doing and, as the title states, I'm trying to see if there's a way to fill a 2D area that is defined by a collection of vertices on a plane. I want to fill with a color, not a file-based texture.
For an example, take a rounded rectangle whose vertices are defined by four quarter-circle triangle fans. The vertices are defined by building a collection of triangles, but the triangles may not be adjacent.
Additionally, I would like to fill it with more than a single color -- i.e. divide the bound area into four vertical bands and have each a different color. You don't have to provide me the code, pointing me towards resources will help a great deal. I can be handy with Google (which I did try first, but have failed miserably).
This is as much an exploration into "what's appropriate for XNA" as it is the implementation of it. Being pretty new to XNA, I'm wanting to also learn what should and shouldn't be done on top of what can and can't be done.
Not too much but here's a start:
The color fill is accomplished by using a shader. Reimer's XNA Tutorials on pixel shaders is a great resource on the topic.
You need to calculate the geometry and build up vertex buffers to hold it. Note that all vector geometry in XNA is in 3D, but using a camera fixed to a plane will simulate 2D.
To add different colors to different triangles you basically need to group geometry into separate vertex buffers. Then, using a shader with a color parameter, for each buffer,
set the appropriate color before passing the buffer to the graphics device. Alternatively, you can use a vertex format containing color information, which basically let you assign a color to each vertex.