After some help, i want to texture onto a circle as you can see below.
I want to do it in such a way that the centre of the circle starts on the shared point of the triangles.
the triangles can change in size and number and will range over varying degrees ie 45, 68, 250 so only the part of the texture visible in the triangle can be seen.
its basically a one to one mapping shift the image to the left and you see only the part where there are triangles.
not sure what this is called or what to google for, can any one makes some suggestions or point me to relevant information.
i was thinking i would have to generate the texture coordinates on the fly to select the relevant part, but it feels like i should be able to do a one to one mapping which would be simpler than calculating triangles on the texture to map to the opengl triangles.
Generating texture coordinates for this isn't difficult. Each point of polygon corresponds to certain angle, so i'th point angle will be i*2*pi/N, where N is the order of regular polygon (number of sides). Then you can use the following to evaluate each point texture coordinates:
texX = (cos(i*2*pi/N)+1)/2
texY = (sin(i*2*pi/N)+1)/2
Well, and the center point has (0.5, 0.5).
It may be even simpler to generate coordinates in the shader, if you have one specially for this:
I assume, you get pos vertex position. It depends on how you store the polygon vertexes, but let the center be (0,0) and other points ranging from (-1;-1) to (1;1). Then the pos should be simply used as texture coordinates with offset:
vec2 texCoords = (pos + vec2(1,1))*0.5;
and the pos itself then should be passed to vector-matrix multiplication as usual.
Related
Im making an editor in which I want to build a terrain map. I want to use the mouse to increase/decrease terrain altitude to create mountains and lakes.
Technically I have a heightmap I want to modify at a certain texcoord that I pick out with my mouse. To do this I first go from screen coordinates to world position - I have done that. The next step, going from world position to picking the right texture coordinate puzzles me though. How do I do that?
If you are using a simple hightmap, that you use as a displacement map in lets say the y direction. The base mesh lays in the xz plain (y=0).
You can discard the y coordinate from world coordinate that you have calculated and you get the point on the base mesh. From there you can map it to texture space the way, you map your texture.
I would not implement it that way.
I would render the scene to a framebuffer and instead of rendering a texture the the mesh, colorcode the texture coordinate onto the mesh.
If i click somewhere in screen space, i can simple read the pixel value from the framebuffer and get the texture coordinate directly.
The rendering to the framebuffer should be very inexpensive anyway.
Assuming your terrain is a simple rectangle you first calculate the vector between the mouse world position and the origin of your terrain. (The vertex of your terrain quad where the top left corner of your height map is mapped to). E.g. mouse (50,25) - origin(-100,-100) = (150,125).
Now divide the x and y coordinates by the world space width and height of your terrain quad.
150 / 200 = 0.75 and 125 / 200 = 0.625. This gives you the texture coordinates, if you need them as pixel coordinates instead simply multiply with the size of your texture.
I assume the following:
The world coordinates you computed are those of the mouse pointer within the view frustrum. I name them mouseCoord
We also have the camera coordinates, camCoord
The world consists of triangles
Each triangle point has texture coordiantes, those are interpolated by barycentric coordinates
If so, the solution goes like this:
use camCoord as origin. Compute the direction of a ray as mouseCoord - camCoord.
Compute the point of intersection with a triangle. Naive variant is to check for every triangle if it is intersected, more sophisticated would be to rule out several triangles first by some other algorithm, like parting the world in cubes, trace the ray along the cubes and only look at the triangles that have overlappings with the cube. Intersection with a triangle can be computed like on this website: http://www.lighthouse3d.com/tutorials/maths/ray-triangle-intersection/
Compute the intersection points barycentric coordinates with respect to that triangle, like that: https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/barycentric-coordinates
Use the barycentric coordinates as weights for the texture coordinates of the corresponding triangle points. The result are the texture coordinates of the intersection point, aka what you want.
If I misunderstood what you wanted, please edit your question with additional information.
Another variant specific for a height map:
Assumed that the assumptions are changed like that:
The world has ground tiles over x and y
The ground tiles have height values in their corners
For a point within the tile, the height value is interpolated somehow, like by bilinear interpolation.
The texture is interpolated in the same way, again with given texture coordinates for the corners
A feasible algorithm for that (approximative):
Again, compute origin and direction.
Wlog, we assume that the direction has a higher change in x-direction. If not, exchange x and y in the algorithm.
Trace the ray in a given step length for x, that is, in each step, the x-coordinate changes by that step length. (take the direction, multiply it with step size divided by it's x value, add that new direction to the current position starting at the origin)
For your current coordinate, check whether it's z value is below the current height (aka has just collided with the ground)
If so, either finish or decrease step size and do a finer search in that vicinity, going backwards until you are above the height again, then maybe go forwards in even finer steps again et cetera. The result are the current x and y coordinates
Compute the relative position of your x and y coordinates within the current tile. Use that for weights for the corner texture coordinates.
This algorithm can theoretically jump over very thin tops. Choose a small enough step size to counter that. I cannot give an exact algorithm without knowing what type of interpolation the height map uses. Might be not the worst idea to create triangles anyway, out of bilinear interpolated coordinates maybe? In any case, the algorithm is good to find the tile in which it collides.
Another variant would be to trace the ray over the points at which it's x-y-coordinates cross the tile grid and then look if the z coordinate went below the height map. Then we know that it collides in this tile. This could produce a false negative if the height can be bigger inside the tile than at it's edges, as certain forms of interpolation can produce, especially those that consider the neighbour tiles. Works just fine with bilinear interpolation, though.
In bilinear interpolation, the exact intersection can be found like that: Take the two (x,y) coordinates at which the grid is crossed by the ray. Compute the height of those to retrieve two (x,y,z) coordinates. Create a line out of them. Compute the intersection of that line with the ray. The intersection of those is that of the intersection with the tile's height map.
Simplest way is to render the mesh as a pre-pass with the uvs as the colour. No screen to world needed. The uv is the value at the mouse position. Just be careful though with mips/filtering etv
How can I calculate texture coordinates of such geometry?
The angle shown in the image (89.90 degree) may vary, therefore the geometry figure is changing and is not always such uniform.(maybe like geometry in the bottom of image) and red dots are generated procedurally depends on degree of smoothness given.
I would solve it by basic trigonometry.
For simplicity and convenience lets assume:
coordinates [0,0] are in the middle of the geometry (where all the lines there intersect) and in the middle of the texture (and they map to each other - [0,0] in geometry is [0,0] in the texture).
the texture coordinates span from -1 to 1 (and also assume the geometry coordinates do too in the case of 90 degrees - in other cases it may get wider and shorter)
possitive values for x span right and y up. And assume that x geometry axis is aligned with the u texture axis no matter the angle (which is 89.90 in your figures).
Something like this:
Then to transform from texture [u,v] to geometry [x,y] coordinates:
x = u + v*cos(angle)
y = v*sin(angle)
To illustrate, it is basically a shear transformation and scale transformation to preserve length of y (or alternatively - similar to rotation transform, but rotating only one axis - y - not both). If I reverse that transformation (to get the texture coordinates we want):
u = x - y*cotg(angle)
v = y/sin(angle)
With those equations I should be able to transform any geometry coordinates (a point) in the described situation into texture coordinates. For any angle in a (0, 180) range anyway
(Hopefully I didn't make too many embarrassing errors in there)
I would take the easy way out and use either solid texturing or tri-planar [http://gamedevelopment.tutsplus.com/articles/use-tri-planar-texture-mapping-for-better-terrain--gamedev-13821] mapping.
If you really need uv, one option is to start with primitives that have a mapping and carry that over for every operation.
Creating uv after the fact will not get good results.
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.
As far as I understand, location of a point/pixel cannot be a fraction, at least on a raster graphics system where hardwares use pixels to display images.
Then, why and how does OpenGL use fractional values for plotting pixels?
For example, how is it possible: glVertex2f(0.15f, 0.51f); ?
This command does not plot any pixels. It merely defines the location of a point in 3D space (you'll notice that there are 3 coordinates, while for a pixel on the screen you'd only need 2). This is the starting point for the OpenGL pipeline. This point then goes through a lot of transformations before it ends up on the screen.
Also, the coordinates are unitless. For example, you can say that your viewport is between 0.0f and 1.0f, then these coordinates make a lot of sense. Basically you have to think of these point in terms of mathematics, not pixels.
I would suggest some reading on how OpenGL transformations work, for example here, here or the tutorial here.
The vectors you pass into OpenGL are not viewport positions but arbitrary numbers in some vector space. Only after a chain of transformations these numbers are mapped into viewport pixel positions. With the old fixed function pipeline this could be anything that can be represented by a vector–matrix multiplication.
These days, where everything is programmable (shaders) the mapping can very well be any kind of function you can think of. For example the values you pass into glVertex (immediate mode call, but available to shaders with OpenGL-2.1) may be interpreted as polar coordinates in the vertex shader:
This is a perfectly valid OpenGL-2.1 vertex shader that interprets the vertex position to be in polar coordinates. Note that due to triangles and lines being straight edges and polar coordinates being curvilinear this gives good visual results only for points or highly tesselated primitives.
#version 110
void main() {
gl_Position =
gl_ModelViewProjectionMatrix
* vec4( gl_Vertex.y*vec2(sin(gl_Vertex.x),cos(gl_Vertex.x)) , 0, 1);
}
As you can see here the valus passed to glVertex are actually arbitrary, unitless components of vectors in some vector space. Only by applying some transformation to the viewport space these vectors gain meaning. Hence it makes no way to impose a certain value range onto the values that go into the vertex attribute.
Vertex and pixel are very different things.
It's quite possible to have all your vertices within one pixel (although in this case you probably need help with LODing).
You might want to start here...
http://www.glprogramming.com/blue/ch01.html
Specifically...
Primitives are defined by a group of one or more vertices. A vertex defines a point, an endpoint of a line, or a corner of a polygon where two edges meet. Data (consisting of vertex coordinates, colors, normals, texture coordinates, and edge flags) is associated with a vertex, and each vertex and its associated data are processed independently, in order, and in the same way.
And...
Rasterization produces a series of frame buffer addresses and associated values using a two-dimensional description of a point, line segment, or polygon. Each fragment so produced is fed into the last stage, per-fragment operations, which performs the final operations on the data before it's stored as pixels in the frame buffer.
For your example, before glVertex2f(0.15f, 0.51f) is on the screen, there are many transforms to be done. Making complex thing crudely simpler, after moving your vertex to view space (applying camera position and direction), the magic here is (1) projection matrix, and (2) viewport setting.
Internally, OpenGL "screen coordinates" are in a cube (-1, -1, -1) - (1, 1, 1), :
http://www.matrix44.net/cms/wp-content/uploads/2011/03/ogl_coord_object_space_cube.png
Projection matrix 'squeezes' the frustum in this cube (which you do in vertex shader), assuming you have perspective transform - if projection is orthogonal, the projection is just a tube, limited by near and far values (and like in both cases, scaling factors):
http://www.songho.ca/opengl/files/gl_projectionmatrix01.png
EDIT: Maybe better example here:
http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/#The_Projection_matrix
(EDIT: The Z-coordinate is used as depth value) When fragments are finally transferred to pixels on texture/framebuffer/screen, these are multiplied with viewport settings:
https://www3.ntu.edu.sg/home/ehchua/programming/opengl/images/GL_2DViewportAspectRatio.png
Hope this helps!
I've got a very specific problem. I have an OpenGL application that is used to render video onto 3D meshes. As it turns out, I can make my video sources send me rectangular portions of the image, reducing memory usage. These portions are specified as a Rectangle2D(int x, int y, int width, int height) with 0 <= x <= w <= sourceVideoWidth and 0 <= y <= h <= sourceVideoHeight.
With that said, I want to find out, for each frame, and for each mesh the following:
Whether the mesh is visible
If so, what portion of image should I request
The benefit is reducint the texture upload to GPU, this operation is often the bottleneck in my application.
In order to simplify the problem let's make the assumption that all meshes are 3D rectangles arbitrarily positioned. A 3D rectangle is defined by four points:
class Rectangle3D
{
public:
Vec3 topLeft;
Vec3 topRight;
Vec3 botLeft;
Vec3 botRight;
}
Possible solutions:
A) Split the mesh into a point grid of points with known texture coordinates, and run frustum culling for each point, then, from the visible points find the top left and bottom right texture coordinates that we must request. This is rather inefficient, and the number of points to test multiplies when we add another mesh to the scene. Solutions that use just the four corners of the rectangle might be preferable.
B) Using the frustum defining planes (see frustum culling). For further simplicity, using only the four planes that correspond to the screen sides. Finding out whether the mesh is visible is rather simple. Finding the visible texture coordinates would need several cases:
- One or more frustum sides intersect with the mesh
- No frustum sides intersect with the mesh
- Either the mesh is fully visible
- Or the mesh is surrounding the screen sides
In any case I need several plane-plane and plane-line segment intersections. Which are not necessarily efficient.
C) Make a 2D projection of the Rectangle3D lines, resulting into a four side polygon, then using line segment intersection between the screen sides and the polygon sides. Also accounting for cases where we have no intersection and the mesh is still visible.
D) Using OpenGL occlusion query objects, this way a render pass could generate information about the visible mesh portion.
Is there any other solution that best solves this problem? If not which one would you use and why?
Just one more thought on to your solutions,
Why don't you incorporate one rendering pass for occlusion queries. Split your mesh into imaginary rectangles which tells you about the visible parts of the mesh. Like
Left part of the image is with imaginary sub-rectangles, right part of the image shows sub-rectangles visible within the screen area (red rectangle in this case). Based on this pass result, you will get the co-ordinates of mesh which are visible.
UPDATE:
This is a sample view that explains my point. This can be done by using opengl query objects.
r is result of GL_SAMPLES_PASSED
Since you will know which rectangles are visible through the result of the query objects , you will come to know which co-ordinates are visible.Google for opengl occlusion queries you will get detailed info. Hope this helps.