I am a beginner making a simple game and I modeled a robot and gave it controls. You basically walk around but there's gravity. It was working great until I let it fall for a long time, when I noticed something odd.
Here is how it looked before the problem:
Then after I fell off the platform, at about -2000 on the y-axis, deformations became present:
It became particularly extreme at about -20,000 on the y-axis:
Is this simply a compression issue? I tried it both compressed and uncompressed and it happened both ways. Perhaps an issue in the Engine?
Based on the numbers you've provided, it's clear you're experiencing floating point precision issues. The precise effect would depend on your platform, but the OpenGL ES Shading Language specifications have some minimum requirements for hardware manufacturers:
https://www.khronos.org/files/opengles_shading_language.pdf (Section 4.5.2)
While The Khronos Group seem to have increased the minimum precision requirement for highp in a newer edition of the specification, which seems to be the version required by OpenGL ES 3.0, I don't know what you're using exactly and how well your hardware conforms to it, so I'll go with the first specification I've linked. Based on that, GLSL floating point numbers have the following minimum precision:
highp : 2^-16 = 0.0000153
mediump: 2^-10 = 0.000977
lowp : 2^-8 = 0.00391
Assuming your hardware doesn't go beyond the minimum requirements, you'll have precision issues of about .3 units even with highp when you're 20,000 units from origin. Considering your vertices are within a 1x1x1 unit box, this equates to about a 30% error relative to the size of your object, which is in line with the images you've shared.
As a solution, try and keep your objects closer to the origin; shift your origin if/when needed.
Related
I'm trying to figure out how to correct drift errors introduced by a SLAM method using GPS measurements, I have two point sets in euclidian 3d space taken at fixed moments in time:
The red dataset is introduced by GPS and contains no drift errors, while blue dataset is based on SLAM algorithm, it drifts over time.
The idea is that SLAM is accurate on short distances but eventually drifts, while GPS is accurate on long distances and inaccurate on short ones. So I would like to figure out how to fuse SLAM data with GPS in such way that will take best accuracy of both measurements. At least how to approach this problem?
Since your GPS looks like it is very locally biased, I'm assuming it is low-cost and doesn't use any correction techniques, e.g. that it is not differential. As you probably are aware, GPS errors are not Gaussian. The guys in this paper show that a good way to model GPS noise is as v+eps where v is a locally constant "bias" vector (it is usually constant for a few metters, and then changes more or less smoothly or abruptly) and eps is Gaussian noise.
Given this information, one option would be to use Kalman-based fusion, e.g. you add the GPS noise and bias to the state vector, and define your transition equations appropriately and proceed as you would with an ordinary EKF. Note that if we ignore the prediction step of the Kalman, this is roughly equivalent to minimizing an error function of the form
measurement_constraints + some_weight * GPS_constraints
and that gives you a more straigh-forward, second option. For example, if your SLAM is visual, you can just use the sum of squared reprojection errors (i.e. the bundle adjustment error) as the measurment constraints, and define your GPS constraints as ||x- x_{gps}|| where the x are 2d or 3d GPS positions (you might want to ignore the altitude with low-cost GPS).
If your SLAM is visual and feature-point based (you didn't really say what type of SLAM you were using so I assume the most widespread type), then fusion with any of the methods above can lead to "inlier loss". You make a sudden, violent correction, and augment the reprojection errors. This means that you lose inliers in SLAM's tracking. So you have to re-triangulate points, and so on. Plus, note that even though the paper I linked to above presents a model of the GPS errors, it is not a very accurate model, and assuming that the distribution of GPS errors is unimodal (necessary for the EKF) seems a bit adventurous to me.
So, I think a good option is to use barrier-term optimization. Basically, the idea is this: since you don't really know how to model GPS errors, assume that you have more confidance in SLAM locally, and minimize a function S(x) that captures the quality of your SLAM reconstruction. Note x_opt the minimizer of S. Then, fuse with GPS data as long as it does not deteriorate S(x_opt) more than a given threshold. Mathematically, you'd want to minimize
some_coef/(thresh - S(X)) + ||x-x_{gps}||
and you'd initialize the minimization with x_opt. A good choice for S is the bundle adjustment error, since by not degrading it, you prevent inlier loss. There are other choices of S in the litterature, but they are usually meant to reduce computational time and add little in terms of accuracy.
This, unlike the EKF, does not have a nice probabilistic interpretation, but produces very nice results in practice (I have used it for fusion with other things than GPS too, and it works well). You can for example see this excellent paper that explains how to implement this thoroughly, how to set the threshold, etc.
Hope this helps. Please don't hesitate to tell me if you find inaccuracies/errors in my answer.
I'm currently writing an SPH Solver using CUDA on https://github.com/Mathiasb17/sph_opengl.
I have pretty good results and performances but in my mind they still seem pretty weird for some reason :
https://www.youtube.com/watch?v=_DdHN8qApns
https://www.youtube.com/watch?v=Afgn0iWeDoc
In some implementations, i saw that a particle does not contribute to its own internal forces (which would be 0 anyways due to the formulas), but it does contribute to its own density.
My simulations work "pretty fine" (i don't like "pretty fine", i want it perfect) and in my implementation a particle does not contribute to its own density.
Besides when i change the code so it does contribute to its own density, the resulting simulation becomes way too unstable (particles explode).
I asked this to a lecturer in physics based animation, he told me a particle should not contribute to its density, but did not give me specific details about this assertion.
Any idea of how it should be ?
As long as you calculate the density with the summation formula instead of the continuity equation, yes you need to do it with self-contribution.
Here is why:
SPH is an interpolation scheme, which allows you to interpolate a specific value in any position in space over a particle cloud. Any position means you are not restricted to evaluate it on a particle, but anywhere in space. If you do so, obviously you need to consider all particles within the influence radius. From this point of view, it is easy to see that interpolating a quantity at a particle's position does not influence its contribution.
For other quantities like forces, where the derivative of some quantity is approximated, you don't need to apply self-contribution (that would lead to the evaluation of 0/0).
To discover the source of the instability:
check if the kernel is normalised
are the stiffness of the liquid and the time step size compatible (for the weakly compressible case)?
In the stereo camera system, two cameras are needed and should be mounted side by side. I see someone just glues two cameras to a wooden board. However One mobile phone manufacture claimed that the two lens of dual camera modules on their phone are parallel within 0.3 degree. Why do two lens on mobile phones need such high precise assembly? Does this will bring any benefit?
I have not worked on stereo setup, but would like to answer from what I have studied during my course. Camera setup which are not parallel are usually called converged/toe-in setup.
Stereo camera setup which are parallel does provide some advantages over toe-in setup. But the advantage is not absolute and dependent on what is required.
In toe-in setup there is a problem of keystoning. Keystoning is when two images(Left and Right) are kept side by side, the images are aligned at the meeting point but they tilt as you go further towards the edge. This leads to depth plane curvature and it shows as though farther objects are curved. This can be corrected in post processing and its called keystone correction. There is no keystone problem in parallel setup. Below image shows image distortion towards edges. If your requirement is not to have keystone effect, then it is an advantage ;)
In parallel setup you can decide the image convergence in post processing by slightly shifting the images horizontally(Horizontal image translation HIT). In toe-in you need to decide the convergence area during the shoot. Convergence is the region of the image which is same in both Left and Right. As you can imagine, in parallel setup, there is no convergence and you get stereo effect for the whole image. This is good right ? Depends. Because, in stereo, we have zero place, near plane and far place. Zero plane is when the image is perceived as to be formed on the screen(screen on which image is projected in the theatre).Near field is near the viewer(imagine popping out of the screen towards the viewer). Far field is farther from the viewer. Therefore, since there is no convergence in parallel setup the whole screen has stereo effect(that is near or far field, see figure below) and convergence is at infinity. Now imagine sky which is very deep in real, i.e the sky which is at infinity. But since in parallel setup sky converges as it is at infinity and appears to be formed on the screen. But a person who is near to the viewer seems to be floating in stereo space, which messes up the brain. Therefore usually people prefer slight convergence angle to avoid this or use HIT such that the convergence point appears on the zero field. Hope this helps :) I will try to rephrase this tomorrow as I wrote this in one go.
in my fragment shader there are two lines as below:
float depthExp=max(0.5,pow(depth,100.0));
gl_FragColor=vec4(depthExp*vec3(color),1);
i "optimize" it into:
if(depth<0.99309249543703590153321021688807){//0.5^(1/100.0)
gl_FragColor=vec4(0.5*vec3(color),1);
}else{
float depthExp=pow(depth,100.0);
gl_FragColor=vec4(depthExp*vec3(color),1);
}
can i get performance rise by this? or i just do the thing against my will?
i give the complete fragment shader here, see if there is chance to optimize it:
varying vec2 TexCoord;
uniform sampler2D Texture_color;
uniform sampler2D Texture_depth;
uniform sampler2D Texture_stencil;
void main()
{
float depth=texture2D(Texture_depth,TexCoord).r;
float stencil=texture2D(Texture_stencil,TexCoord).r;
vec4 color=texture2D(Texture_color,TexCoord);
if(stencil==0.0){
gl_FragColor=color;
}else{
float depthExp=max(0.5,pow(depth,100.0));
gl_FragColor=vec4(depthExp*vec3(color),1);
}
}
First of all excessive branching in the shader is usually not a good idea. On modern hardware it won't be too bad as long as nearby fragments all take the same branch. But once two fragments of a local packet of fragments (whose size is implementation dependent, probably a small square, say 4x4-8x8) take different branches, the GPU will actually have to execute both branches for each fragment of the packet.
So if nearby fragments are likely to take the same branch it may give some improvement. Since the condition is based on the depth (though from a previous rendering, I guess) and the depth buffer is usually comprised of larger regions with mononotous depth distribution, it is indeed likely for nearby fragments to enter the same branch. And since the optimized branch is executed for most of the fragments (since most will be smaller than 0.993, even more so due to the depth buffer's non-linear nauture and the higher precision at the smaller values) it may be profitable. But like Apeforce suggests, the best idea would be to measure it.
But this brings me to another question. Given that virtually all fragments in a usual scene will have a depth smaller than 0.993, except for the background and most of the values will result in incredibly small numbers after exponentiating with 100 (man, 0.95^100 = 0.005 and 0.9^100 = 0,00002), scaling a color (whose precision and impact on perception is not that high in the first place, anyway) by this amount will most probably just zero it out. So if you indeed have a standard depth buffer with values from [0,1] (and maybe even non-linear as usual), then I doubt what the actual purpose of this pow is anyway and if there is probably a different solution to your problem.
Usually, you will want to avoid branching inside shaders at all cost, you are probably better off leaving it as it was from the beginning.
I have heard that modern GPU's are better at this though (branching statements), what are you writing for, OpenGL ES 2.0 or OpenGL 3.2+?
Your use of varying suggest that you are writing for OpenGL ES?
I suggest you just write out your fps to either your console (which is going to affect performance, but since it will for both cases it's no problem) or your screen, using first the original shader, and then the "optimized" shader, and see which one gets the higher frames.
In general though, you can't optimize a shader program using branching conditions, which feels really backwards, but it is because of how the hardware acts.
I'm considering exploiting ray coherence in my software per-pixel realtime raycaster.
AFAICT, using a uniform grid, if I assign ray coherence to patches of say 4x4 pixels (where at present I have one raycast per pixel), given 16 parallel rays with different start (and end) point, how does this work out to a coherent scene? What I foresee is:
There is a distance within which the ray march would be exactly the same for adjacent/similar rays. Within that distance, I am saving on processing. (How do I know what that distance is?)
I will end up with a slightly to seriously incorrect image, due to the fact that some rays didn't diverge at the right times.
Given that my rays are cast from a single point rather than a plane, I guess I will need some sort of splitting function according to distance traversed, such that the set of all rays forms a tree as it move outward. My concern here is that finer detail will be lost when closer to the viewer.
I guess I'm just not grasping how this is meant to be used.
If done correctly, ray coherence shouldn't affect the final image. Because the rays are very close together, there's a good change that they'll all take similar paths when traversing the acceleration structure (kd-tree, aabb tree, etc). You have to go down each branch that any of the rays could hit, but hopefully this doesn't increase the number of branches much, and it saves on memory access.
The other advantage is that you can use SIMD (e.g. SSE) to accelerate some of your tests, both in the acceleration structure and against the triangles.