I'm using THREE.Raycaster to do THREE.Line picking. When my THREE.Line contains more points, the precision becomes very low. Changing the THREE.Raycaster.linePrecision doesn't work.
Is that caused by the super big bounding sphere? But in this official example, the lines contain 50 points and work well.
So what's the problem?
Related
When setting the OpenGLES draw distance using Matrix.frustumM I notice that you can’t set the near draw distance to zero and any value less than 1 gives really weird distortion. Setting the near distance to 1 works fine most of the time but when the camera moves closer to objects than this distance it looks horrible because they are not drawn (or a portion of them is not drawn). Is there anything that can be done about this?
Many thanks for your time.
Not much can be done actually. The near and far clipping planes clip the pixels closer to near or further then far. Beside this the near is a bit special as it defines your field of view with the combination of the border parameters (left, right, up and down). So if you had a quad with same coordinates as those border if would be full-screen when exactly near away. Because of this the near plane can not be zero or even negative as for instance an object that would be at zero units away using a frustum would appear to be scaled infinitely.
Still you can use values smaller then 1 without having some strange artifacts. What you should do is look at some examples on how to define the frustum by setting a field of view. Generally you define your angle (a field of view) for one of the dimensions like 45 degrees in width, then you define your near and far as you please but both should be positive. Now use the trigonometry to compute the left and right using the angle and near and use the same values for up and down but scaled by screen (view) ratio. By doing so you will have no difference as in distortion when changing the near parameter.
I'm new to three.js and WebGL in general.
The sample at http://css.dzone.com/articles/threejs-render-real-world shows how to use raster GIS terrain data in three.js
Is it possible to use vector GIS data in a scene? For example, I have a series of points representing locations (including height) stored in real-world coordinates (meters). How would I go about displaying those in three.js?
The basic sample at http://threejs.org/docs/59/#Manual/Introduction/Creating_a_scene shows how to create a geometry using coordinates - could I use a similar approach with real-world coordinates such as
"x" : 339494.5,
"y" : 1294953.7,
"z": 0.75
or do I need to convert these into page units? Could I use my points to create a surface on which to drape an aerial image?
I tried modifying the simple sample but I'm not seeing anything (or any error messages): http://jsfiddle.net/slead/KpCfW/
Thanks for any suggestions on what I'm doing wrong, or whether this is indeed possible.
I did a number of things to get the JSFiddle show something.. here: http://jsfiddle.net/HxnnA/
You did not specify any faces in your geometry. In this case I just hard-coded a face with all three of your data points acting as corner. Alternatively you can look into using particles to display your data as points instead of faces.
Set material to THREE.DoubleSide. This is not usually needed or recommended, but helps debugging in early phases, when you can see both sides of a face.
Your camera was probably looking in a wrong direction. Added a lookAt() to point it to the center and made the field of view wider (this just makes it easier to find things while coding).
Your camera near and far planes were likely off-range for the camera position and terrain dimensions. So I increased the far plane distance.
Your coordinate values were quite huge, so I just modified them by hand a bit to make sense in relation to the camera, and to make sure they form a big enough triangle for it to be seen in camera. You could consider dividing your coordinates with something like 100 to make the units smaller. But adjusting the camera to account for the huge scale should be enough too.
Nothing wrong with your approach, just make sure you feed the data so that it makes sense considering the camera location, direction and near + far planes. Pay attention to how you make the faces. The parameters to Face3 is the index of each point in your vertices array. Later on you might need to take winding order, normals and uvs into account. You can study the geometry classes included in Three.js for reference.
Three.js does not specify any meaning to units. Its just floating point numbers, and you can decide yourself what a unit (1.0) represents. Whether it's 1mm, 1 inch or 1km, depends on what makes the most sense considering the application and the scale of it. Floating point numbers can bring precision problems when the actual numbers are extremely small or extremely big. My own applications typically deal with stuff in the range from a couple of centimeters to couple hundred meters, and use units in such a way that 1.0 = 1 meter, that has been working fine.
I understand that by setting the depth function in OpenGL ES one can control how overlapping geometries are rendered in a 3D scene. I use gl.depthFunc(gl.LEQUAL) (webgl) in my code.
However when two sets of polygons are coincident and are of different color, the resulting surface turns out to be an arbitrary mixed pattern of the two colors (which changes as the camera location changes, hence leads to flickering). Take a look at this image:
How can I fix this? I have tried different depthFunc values, but none of them solves this problem. I would like the coincident polygons to have single color, it doesn't matter which one.
This is called z-fighting, and is related to two objects being rendered at the same depth, but rounding errors (and depth buffer precision) occasionally popping one in front of the other. One solution available to you is to use the glPolygonOffset function:
http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPolygonOffset.xml
You can see an example of it in use at the bottom of this page:
http://www.glprogramming.com/red/chapter06.html
What you experience is called Z fighting and unfortunately there's not definitive solution against it. What happens is, that due to the limited precision of the depth buffer, rounding errors occur and either one of the primitives "win" the depth test operation. Changing the depth function will just toggle the colours in the fighting pattern, but not remove it.
One method to get rid of the Z fighting is using polygon offset http://www.opengl.org/wiki/Basics_Of_Polygon_Offset
Unfortunately polygon offset introduces its own share of problems.
Try changing your z-near to be farther from zero in your call to gluPerspective:
void gluPerspective(
GLdouble fovy,
GLdouble aspect,
GLdouble zNear,
GLdouble zFar);
From this website:
http://www.opengl.org/resources/faq/technical/depthbuffer.htm
Depth buffering seems to work, but polygons seem to bleed through polygons that are in front of them. What's going on?
You may have configured your zNear and zFar clipping planes in a way
that severely limits your depth buffer precision. Generally, this is
caused by a zNear clipping plane value that's too close to 0.0. As the
zNear clipping plane is set increasingly closer to 0.0, the effective
precision of the depth buffer decreases dramatically. Moving the zFar
clipping plane further away from the eye always has a negative impact
on depth buffer precision, but it's not one as dramatic as moving the
zNear clipping plane.
Try messing with glPolygonOffset(factor, units). This page might help.
I have an application that draws 3-d map view marked up lines that show various features.
I am porting the map over to an OpenGL-ES architecture, but am having a bit of trouble working out how to display dashed lines.
Doing a lot of googling, I've found many references to the idea that drawing dashed lines and polygons were removed from OpenGL-ES as they can be easily emulated using textures triangles. That's great, but I can't find anyone that actually does this emulation and/or has a description of the steps involved.
An example, of one problem I have encountered trying to prototype out this concept is perspective squeezes my lines to invisible as they go towards the horizon. Using LINE_STRIP, this doesn't happen, and the lines remain a constant width in the map.
Any advice on how to achieve dashed constant width lines in a perspective view would be much appreciated.
I believe you can apply a texture to a line, not just a triangle. You'll need to set texture coordinates for each end of the line; the texture will be interpolated linearly along the line.
The effectiveness of this solution should be invariant of whether you use lines or line strips - line strips are just a way to create lines with fewer vertices.
There is one other problem: the tendency of the texture pattern to become compact as a line goes away from the camera. This happens because texture coordinate interpolation is perspective-correct even for lines (see section 3.5 of the GL spec).
There are two ways to get around this:
If you can calculate a "q" coordinate for your texture that undoes the perspective, you can restore screen-space texturing. This technique is probably too performance-expensive.
You can project the texture in eye space (e.g. glTexGen).
Texture coordinate generation is of course not available in GLES 1.1, but if you are using vertices by array, you can fake it by:
Setting your texture coordinate array to be your vertex coordinate array and
Using the texture matrix to "transform" the vertices.
The disadvantage of this technique is that the texture pattern will be in fixed screen space - that is, the texture won't run across the lines.
If all you want is to draw dashed lines, just change from GL_LINE_STRIP to GL_LINES. That way, open GL will connect vertices 1&2, 3&4, 5&6, but not 3&4, or 4&5 leaving spaces there. It will in essence be a half/half ratio dotted line-- the rough equivalent of glLineStipple(1, 0101);
IE: in the vertex array
[0,0,1,1,2,2,3,3,4,4,5,5,6,6]
OpenGL will connect (0,0) to (1,1), but will not connect (1,1) to (2,2) [whereas it would with GL_LINE_STRIP]. It will then connect (3,3) to (4,4), but NOT (4,4) to (5,5). The final connection will be (5,5) to (6,6).
This is what it looks like when I did it:
Dotted Lines on Android
The line is not 50/50 dotted/empty because in my case, it represents the position of a game entity each game frame-- and game frames are not necessarily all of equal length, thus the inconsistent line:space ratio.
The code looks like this to draw it:
public void draw(GL10 gl)
{
gl.glDisable(GL10.GL_TEXTURE_2D);
gl.glColor4f(color[0], color[1], color[2], color[3] / fade);
//pointsBuffer holds the points on the line
gl.glVertexPointer(2, GL10.GL_FLOAT, 0, pointsBuffer);
gl.glDrawArrays(GL10.GL_LINES, 0, points.length/2);
gl.glEnable(GL10.GL_TEXTURE_2D);
}
An alternative idea to create a more intentionally patterned stipple would be to skip certain vertices by instead drawing with an indices array (glDrawElements). However, I don't have an example of that to show you. :/
I was wondering if anyone knew of any algorithm to draw a line with specific thickness, based on Bresenham's line algorithm or any similar.
On a second thought, I've been wondering about for each setPixel(x,y) I'd just draw a circle, e.g.:
filledCircle(x,y,thickness); for every x,y but that would of course be very slow. I also tried to use dictionary but that would fill the memory in no time. Check the pixels I'm about to draw on if they have the same color, but that's also not efficient enough for large brushes.
Perhaps I could somehow draw half circles depending on the angle?
Any input would be appreciated.
Thanks.
duplicate: how do I create a line of arbitrary thickness using Bresenham?
You cannot actually draw circles along the line. This approach is patented. :)
You can still read patent for inspiration.
I don't know what is commonly used, but it seems to me that you could use Bresenham for the 1-pixel-wide line, but extend it a set number of pixels vertically or horizonally. For instance, suppose your line is roughly 30 degrees away from the horizontal, and you want it to be four pixels wide. You calculate that the vertical thickness of the line should be five pixels. You run Bresenham, but for each pixel (x,y), you actually draw (x,y), (x,y+1), ... (x,y+4). And if you want the ends of the line to be rounded, draw a circle at each end.
For overkill, make a pixel map of the stylus (a circle or diagonal nib, or whatever), then draw a set of parallel Bresenham lines, one for each pixel in the stylus.
There are variations on Bresenhams which calculate pixel coverage, such as those used in the anti-grain geometry libraries; whether you want something that quality - you don't say what the output medium is, and most systems more capable than on-off LCDS support pens with thickness anyway.