9 Replies Latest reply on Jul 11, 2018 2:14 PM by mirh

    floating point precision

    spectral

      Hi,

      In my current kernel I use floating point values, but I think I got precision problems...

      by example, I use an 'epsilon' defined as

      #define EPSILON 1e-4 and play with values like 500.f etc....

      I'm not sure how I can improve this ? Do you have any council ? ideas ?

        • floating point precision
          himanshu.gautam

          hi viewon01,

          I would myself be interested to find some new ideas here. Anyhow some  thought which I would like to share are:

          Try using some iterations of numerical methods( like Newton raphson to improve accuracy)

          Try to avoid division operation, it has the least precision among other operations.

          You can also think of resorting to double if possible in your case.

            • floating point precision
              spectral

              A concrete example. I have to compute the intersection between a ray (Point,Direction) and a set of faces in 3D space.

              Because it is raytracing, the "Point" is often located on a face, so, to avoid self-intersection I do the following :

              P += N * epsilon;

              Where P is the point, N is the normal direction and epsilon is a very small value (I use 1e-4 for now).

              When I'm playing with big model, ie. coordinates like (500,500,500) I got some strange effects, playing with a smaller epsilon give me better results.

              So, I decrease epsilon, but when playing with small models, (1,1,1) I have errors.

              I think that I don't have this kind of problem when working in C++ on the CPU !

                • floating point precision
                  spectral

                  I have try to play with double, but the SDK doesn't support "double3" (as float3) ... the SDK give me compilation errors !

                  • floating point precision
                    himanshu.gautam

                    CPUs are capable of having higher precision than GPUs, so it can most certainly be true.

                    I think you might get better help if you post some kernel code snippet which is facing precision issues.

                      • floating point precision
                        spectral

                        Here are some code, the problem is that epsilon is to "big" for some scenes. Smaller it is, better it is (in theory). The problem is the floating point precision !

                        Does the SDK has a lower precision than normal C++ ? Or there is a way (a pragma by example) to use the best precision ?

                        Thanks

                        void TriangleIntersect( clVector3 rayOrig, clVector3 rayDir, float minT, float *maxT, unsigned int *hitIndex, unsigned int currentIndex, __global Vertex *vertices, __global Triangle *tris) { // Load triangle vertices Point p0 = (vertices[tris[currentIndex].v[0]].P); Point p1 = (vertices[tris[currentIndex].v[1]].P); Point p2 = (vertices[tris[currentIndex].v[2]].P); clVector3 v0 = (clVector3) (p0.x, p0.y, p0.z); clVector3 v1 = (clVector3) (p1.x, p1.y, p1.z); clVector3 v2 = (clVector3) (p2.x, p2.y, p2.z); // Calculate intersection clVector3 e1 = v1 - v0; clVector3 e2 = v2 - v0; clVector3 s1 = cross(rayDir, e2); float divisor = dot(s1, e1); if (divisor == 0.f) return; float invDivisor = 1.f / divisor; // Compute first barycentric coordinate clVector3 d = rayOrig - v0; float b1 = dot(d, s1) * invDivisor; if (b1 < 0.f) return; // Compute second barycentric coordinate clVector3 s2 = cross(d, e1); float b2 = dot(rayDir, s2) * invDivisor; if (b2 < 0.f) return; float b0 = 1.f - b1 - b2; if (b0 < 0.f) return; // Compute _t_ to intersection point float t = dot(e2, s2) * invDivisor; if (t <= minT || t >= *maxT) return; // We have a hit *maxT = t; *hitIndex = currentIndex; } orig += EPSILON * normal; TriangleIntersect(orig, direction, minT, &maxT, &hitIndex, currentIndex, vertices, indices);