OpenGl triangle interpolation issue [duplicate] - opengl

This question already has answers here:
OpenGL Colour Interpolation
(3 answers)
Closed 6 years ago.
I need to interpolate the red triangle on the left from white to black as depicted in the figure. I've extended it to a parallelogram to better understand the kind of interpolation that i'm trying to achieve.
By assigning 1 to the white extremes of the triangle and zero to the bottom i'm not getting the expected results, I thought that this specific case wouldn't cause perspective coordinates issues due to the fact that triangle values are still mapped to a parallelogram and not a trapezoid, but I guess I was wrong.
One solution would be as drawn in the right figure to find p1 by computing a vector intersection, compute the lenght of frag - p1 and compare it to length(v3 - v1) which would be too overkill for the fragment shader i'm using.
Another also expensive solution would be to store the angle formed from the dots of the vertices vectors, and use a bit of trigonometry with p2 and frag to get a point in v1 - v3 to interpolate with the full segment, which is also crazy inefficient
The end goal would be to draw a convex hull made of triangles from it's center to it's edges in a black to white fashion
Edit: this question was marked as 'exact duplicate' of another one that as far as my understanding goes, has little to with what I asked. None of the provided responses helps my case and I'd like to at least know where exactly it could be defined as 'exact duplicate'

I think you should try the barycentric coordinate system, this is the way OpenGL interpolates the colors between different corners.
(called barycentric interpolation)
In you specific case you should take a single value of this three values for setting the color.
But just read it yourself...
This is the Wikipedia link : https://en.wikipedia.org/wiki/Barycentric_coordinate_system

Related

Cubemap PCF: Get the plane perpendicular to a vector at a given point

I'm trying to implement PCF for a shadow cube map in OpenGL 2.0. I thought I'd found a solution here (search for Percentage closer filtering (PCF) algorithm to find the start of the section on cube map PCF), but the code is relying on the samplerCubeShadow that is unavailable in OpenGL 2.0 so I can't use the call to texture(samplerCubeShadow(), vec4()) shown on that page.
The first part of this question is: Is there a way to retrieve the same results from a samplerCube in OpenGL 2.0/GLSL 1.10? By using a textureCube or something else?
The second part relates to an idea I have to solve this problem. The image below illustrates what I'd like to do.
The solid blue line and the dotted red lines are all vectors coming from one face of the samplerCube that stores my depth values. The blue line's intersection with the dark grey square in the center of the black squares represents the sampled point from the cube. I'd like to create a plane (represented by the light grey rectangle) that is perpendicular to the blue vector. Then I'd like to sample the 4 black points from the camera by casting Z vectors from the light position (these are the dotted red lines) to their x,Y values on that plane. Afterwards, I would use those values combined with the original sample's values to calculate the PCF shadow value.
Is this a viable and efficient way of calculating PCF for a pointlight/cubemap? And how would I create the parallel plane and then retrieve the X and Y coordinates I need from it?
I can't say whether it is efficient or good (or even correct), but it is absolutely doable.
Given the vector v from the light to the fragment, choose any vector u that is not parallel to v. The cross product w = cross(u, v) will be perpendicular to v. Take w as a axis and cross(v, w) as the second axis.

Aliased rasterization: why sampling pixel at center?

Both OpenGL and Direct3D use pixel's center as a sample point during rasterization (without antialiasing).
For example here is the quote from D3D11 rasterization rules:
Any pixel center which falls inside a triangle is drawn
I tried to find out what is the reason to use (0.5, 0.5) instead of, say, (0.0, 0.0) or whatever else in range of 0.0 - 1.0f for both x and y.
The result might be translated a little, but does it really matter? Does it produce some visible artifacts? May be, it makes some algorithms harder to implement? Or it's just a convention?
Again, I don't talk about multisampling here.
So what is the reason?
Maybe this is not the answer to your problem, but I try to answer your question from ray tracing perspective.
In ray tracing, you can get color of every single points in the scene. But since we have a limited amount of pixel, you need to downsample to your image to your screen pixels.
In ray tracing, if you use 1 ray per pixel, we generally choose center point to create our ray which gives the most correct render results. In the image below, I try to show the difference when you choose a corner of pixel or center. The distance will get bigger when your object is far from the rendering screen.
If you use more than one ray for each pixel, lets say 5 rays (4 corners + 1 center) and average the result, you will of course get more realistic image ( Will handle aliasing problems much better) However it will be slower as you guess.
So, it is probably the same idea that opengl and directX take one sample for each pixel instead of multisampling and taking average (Performance issues) and center point is probably giving the best result.
EDIT :
For area rasterization, center of pixel is used because if center of pixel remains inside Area, it is guaranteed that at least 50% of pixel is inside the shape.(Except shape corners) That's why since the proportion is greater than half that pixel is colored.
For other corner selections there is no general rule. Lets look at example image below. The black point (bottom left) is outside of area and should not be drawn (And when you look at it more than half of pixel is outside. However if you look at blue point %80 of pixel is inside area but since bottom left corner is outside area it shouldn't be drawn
This answer mainly focuses on the OP's comment on
Cagkan Toptas answer:
Thanx for the answer, but my question is: why does it give better
results? Does it at all? If yes, what is the explanation?"
It depends on how you define "better" results. From an image qualioty perspective, it does not change much, as long as the primitves are not specifically aligned (after the projection).
Using just one sample at (0,0) instead (0.5, 0.5) will just shift the scene by half a pixel (in both axis, of course). In the general case of aribitrary placed primitves, the average error should be the same.
However, if you want "pixel-exact" drawing (i.e. for text, and UI, and also full-screen post-processing effects), you just would have to take the convention of the underlying implementation into account, and both conventions would work.
One advantage of the "center at half integers" rule is that you can get the integer pixel coordinates (with respect to the sample locations) of the nearest pixel by a simple floor(floating_point_coords) operation, which is simpler than rounding to the nearest integer.

Marching Cubes, voxels, need a bit of suggestions

I'm trying to construct a proper destructible terrain, just for research purposes.
Well, everything went fine, but resolution is not satisfying me enough.
I have seen a lot of examples how people implement MC algorithm, but most of them,
as far as I understand, uses functions to triangulate final mesh, which is not
appropriate for me.
I will try briefly to explain how I'm constructing my terrain, and maybe someone
of you will give me suggestion how to improve, or to increase resolution of final terrain.
1) Precalculating MC triangles.
I'm running simple loop through MC lookup tables for each case(0-255) and calculating triangles
in rage: [0,0,0] - [1,1,1].
No problems here.
2) Terrain
I have terrain class, which stores my voxels.
In general, it looks like this:
int size = 32;//Size of each axis.
unsigned char *voxels = new unsigned char[(size * size * size)/8];
So, each axis is 32 units of size long, but, I store voxel information per bit.
Meaning if bit is turned on (1), there is something, and there should be draw something.
I have couple of functions:
TurnOn(x,y,z);
TurnOff(x,y,z);
to turn location of voxel on or off. (Helps to work with bits).
Once terrain is allocated, I'm running perlin noise, and turning bits on or off.
My terrain class has one more function, to extract Marching Cubes case number (0-255) from x,y,z location:
unsigned char GetCaseNumber(x,y,z);
by determining if neighbours of that voxel is turned on or off.
No problems here.
3) Rendering part
I'm looping for each axis, extracting case number, then getting precalculated triangles by case,
translating to x,y,z coordinates, and drawing those triangles.
no problems here.
So result looks like this:
But as you can see, in any single location, resolution is not comparable to for example this:
(source: angelfire.com)
I have seen in MC examples that people are using something called "iso values", which I don't understand.
Any suggestions how to improve my work, or what is iso values, and how to implement it in uniform grid would be truly lovely.
The problem is that your voxels are a binary mask (just on or off).
This is great for the "default" marching cubes algorithm, but it it does mean you get sharp edges in your mesh.
The smooth example is probably generated from smooth scalar data.
Imagine that if your data varies smoothly between 0 and 1.0, and you set your threshold to 0.5. Now, after you detect which configuration a given cube is, you look at the all the vertices generated.
Say, that you have a vertex on an edge between two voxels, one with value 0.4 and the other 0.7. Then you move the vertex to the position where you would get exactly 0.5 (the threshold) when interpolating between 0.4 and 0.7. So it will be closer to the 0.4 vertex.
This way, each vertex is exactly on the interpolated iso surface and you will generate much smoother triangles.
But it does require that your input voxels are scalar (and vary smoothly). If your voxels are bi-level (all either 0 or 1), this will produce the same triangles as you got earlier.
Another idea (not the answer to your question but perhaps useful):
To just get smoother rendering, without mathematical correctness, it could be worthwile to compute an average normal vector for each vertex, and use that normal for each triangle connecting to it. This will hide the sharp edges.

How to create an even sphere with triangles in OpenGL?

Is there a formula that generates a set of coordinates of triangles whose vertices are located on a sphere?
I am probably looking for something that does something similar to gluSphere. Yet, I need to color the different triangles in specfic colors so that it seems I can't use gluSphere.
Also: I do understand that gluSphere draws edges along lines with equal longitudes and lattitudes which entails the triangles being small at the poles compared to their size at the equator. Now, if such a formula would generate the triangles such that their difference in size is minimized, that would be great.
To calculate the normals and the uv map.
Fortunately there is an amazing trick for calculating the normals, on a sphere. If you think about it, the normals on a sphere are indeed nothing more than the direction from the centre of the sphere, to that point!! Furthermore, if you think it through, that means the normals literally equal the point! i.e., it's the same vector! - just don't forget to normalise the length, for the normal.
You can win bar bets on that one: "is there a shape where all the normals happen to be exactly ... equal to the vertices?" At first glance you'd think, that's impossible, no such coincidental shape could exist. But of course the answer is simply "a sphere with radius one!" Heh!
Regarding the UVs. It is relatively easy on a sphere, assuming you're projecting to 2D in the "obvious" manner, a "rectangle-style" map projection. In that case the u and v is basically just the longitude / latitude of any point, normalised to 0,1.
Hope it helps!
Here's the all-time-classic web page that beautifully explains how to build an icosphere .. http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html
Start with a unit icosahedron. Then apply muliple homogenous subdivisions of the triangles, normalizing the resulting vertices distance to the origin.

OpenGL lighting question?

Greetings all,
As seen in the image , I draw lots of contours using GL_LINE_STRIP.
But the contours look like a mess and I wondering how I can make this look good.(to see the depth..etc )
I must render contours so , i have to stick with GL_LINE_STRIP.I am wondering how I can enable lighting for this?
Thanks in advance
Original image
http://oi53.tinypic.com/287je40.jpg
Lighting contours isn't going to do much good, but you could use fog or manually set the line colors based on distance (or even altitude) to give a depth effect.
Updated:
umanga, at first I thought lighting wouldn't work because lighting is based on surface normal vectors - and you have no surfaces. However #roe pointed out that normal vectors are actually per vertex in OpenGL, and as such, any POLYLINE can have normals. So that would be an option.
It's not entirely clear what the normal should be for a 3D line, as #Julien said. The question is how to define normals for the contour lines such that the resulting lighting makes visual sense and helps clarify the depth?
If all the vertices in each contour are coplanar (e.g. in the XY plane), you could set the 3D normal to be the 2D normal, with 0 as the Z coordinate. The resulting lighting would give a visual sense of shape, though maybe not of depth.
If you know the slope of the surface (assuming there is a surface) at each point along the line, you could use the surface normal and do a better job of showing depth; this is essentially like a hill-shading applied only to the contour lines. The question then is why not display the whole surface?
End of update
+1 to Ben's suggestion of setting the line colors based on altitude (is it topographic contours?) or based on distance from viewer. You could also fill the polygon surrounded by each contour with a similar color, as in http://en.wikipedia.org/wiki/File:IsraelCVFRtopography.jpg
Another way to make the lines clearer would be to have fewer of them... can you adjust the density of the contours? E.g. one contour line per 5ft height difference instead of per 1ft, or whatever the units are. Depending on what it is you're drawing contours of.
Other techniques for elucidating depth include stereoscopy, and rotating the image in 3D while the viewer is watching.
If your looking for shading then you would normally convert the contours to a solid. The usual way to do that is to build a mesh by setting up 4 corner points at zero height at the bounds or beyond then dropping the contours into the mesh and getting the mesh to triangulate the coords in. Once done you then have a triangulated solid hull for which you can find the normals and smooth them over adjacent faces to create smooth terrain.
To triangulate the mesh one normally uses the Delaunay algorithm which is a bit of a beast but there does exist libraries for doing it. The best of which I know of is the ones based on Guibas as Stolfi papers since its pretty optimal.
To generate the normals you do a simple cross product and ensure the facing is correct and manually renormalize them before feeding into the glNormal.
The in the old days you used to make a glList out of the result but the newer way is to make a vertex array. If you want to be extra flash then you can look for coincident planar faces and optimize the mesh down for faster redraw but thats a bit of a black art - good for games, not so good for CAD.
(thx for bonus last time)