Dear all,

I am an employee of dGB Earth Sciences, and we are still porting
the 3D visualization of our open-source seismic interpretation
package OpendTect to OpenSceneGraph.

I want to report a numerical bug in ALL fragment shaders coming with
OpenSceneGraph, i.e. those in the src/osgVolume/Shaders directory.

The line:  "    while(num_iterations>0.0)\n"
should be: "    while(num_iterations>0.5)\n"

The loop variable num_iterations is probably made "float" instead
of "int" for a good reason, but depending on its start value, now
very small numerical errors may sometimes lead to the execution
of one iteration more than intended. This can be solved easily
by having the stop criterion test halfway two consecutive
iteration values.

This bug manifested itself when extending the RayTracedTechnique
with an option to use the NEAREST texture filters instead of the
default LINEAR texture filters. Serious artifacts were "walking"
over the surface of the volume when rotating the scene. After
discovering and fixing this bug, these artifacts disappeared.

I have attached one modified fragment shader file from the
latest trunk: src/osgVolume/Shaders/volume_frag.cpp, but
the fix should apply to all.


Best regards,

Jaap Glas

--
-- dr. Jaap C. Glas
-- Software Engineer
-- dGB Earth Sciences
-- Nijverheidstraat 11-2
-- 7511 JM Enschede, The Netherlands
-- [email protected]
-- http://www.dgbes.com
-- Tel: +31 534315155, Fax: +31 534315104
char volume_frag[] = "uniform sampler3D baseTexture;\n"
                     "uniform float SampleDensityValue;\n"
                     "uniform float TransparencyValue;\n"
                     "uniform float AlphaFuncValue;\n"
                     "\n"
                     "varying vec4 cameraPos;\n"
                     "varying vec4 vertexPos;\n"
                     "varying mat4 texgen;\n"
                     "varying vec4 baseColor;\n"
                     "\n"
                     "void main(void)\n"
                     "{ \n"
                     "    vec4 t0 = vertexPos;\n"
                     "    vec4 te = cameraPos;\n"
                     "\n"
                     "    if (te.x>=0.0 && te.x<=1.0 &&\n"
                     "        te.y>=0.0 && te.y<=1.0 &&\n"
                     "        te.z>=0.0 && te.z<=1.0)\n"
                     "    {\n"
                     "        // do nothing... te inside volume\n"
                     "    }\n"
                     "    else\n"
                     "    {\n"
                     "        if (te.x<0.0)\n"
                     "        {\n"
                     "            float r = -te.x / (t0.x-te.x);\n"
                     "            te = te + (t0-te)*r;\n"
                     "        }\n"
                     "\n"
                     "        if (te.x>1.0)\n"
                     "        {\n"
                     "            float r = (1.0-te.x) / (t0.x-te.x);\n"
                     "            te = te + (t0-te)*r;\n"
                     "        }\n"
                     "\n"
                     "        if (te.y<0.0)\n"
                     "        {\n"
                     "            float r = -te.y / (t0.y-te.y);\n"
                     "            te = te + (t0-te)*r;\n"
                     "        }\n"
                     "\n"
                     "        if (te.y>1.0)\n"
                     "        {\n"
                     "            float r = (1.0-te.y) / (t0.y-te.y);\n"
                     "            te = te + (t0-te)*r;\n"
                     "        }\n"
                     "\n"
                     "        if (te.z<0.0)\n"
                     "        {\n"
                     "            float r = -te.z / (t0.z-te.z);\n"
                     "            te = te + (t0-te)*r;\n"
                     "        }\n"
                     "\n"
                     "        if (te.z>1.0)\n"
                     "        {\n"
                     "            float r = (1.0-te.z) / (t0.z-te.z);\n"
                     "            te = te + (t0-te)*r;\n"
                     "        }\n"
                     "    }\n"
                     "\n"
                     "    t0 = t0 * texgen;\n"
                     "    te = te * texgen;\n"
                     "\n"
                     "    const float max_iteratrions = 2048.0;\n"
                     "    float num_iterations = ceil(length((te-t0).xyz)/SampleDensityValue);\n"
                     "    if (num_iterations<2.0) num_iterations = 2.0;\n"
                     "\n"
                     "    if (num_iterations>max_iteratrions) \n"
                     "    {\n"
                     "        num_iterations = max_iteratrions;\n"
                     "    }\n"
                     "\n"
                     "    vec3 deltaTexCoord=(te-t0).xyz/float(num_iterations-1.0);\n"
                     "    vec3 texcoord = t0.xyz;\n"
                     "\n"
                     "    vec4 fragColor = vec4(0.0, 0.0, 0.0, 0.0); \n"
                     "    while(num_iterations>0.5)\n"
                     "    {\n"
                     "        vec4 color = texture3D( baseTexture, texcoord);\n"
                     "        float r = color[3]*TransparencyValue;\n"
                     "        if (r>AlphaFuncValue)\n"
                     "        {\n"
                     "            fragColor.xyz = fragColor.xyz*(1.0-r)+color.xyz*r;\n"
                     "            fragColor.w += r;\n"
                     "        }\n"
                     "\n"
                     "        if (fragColor.w<color.w)\n"
                     "        {\n"
                     "            fragColor = color;\n"
                     "        }\n"
                     "        texcoord += deltaTexCoord; \n"
                     "\n"
                     "        --num_iterations;\n"
                     "    }\n"
                     "\n"
                     "    fragColor.w *= TransparencyValue;\n"
                     "    if (fragColor.w>1.0) fragColor.w = 1.0;\n"
                     "\n"
                     "    fragColor *= baseColor;\n"
                     "\n"
                     "    if (fragColor.w<AlphaFuncValue) discard;\n"
                     "    \n"
                     "    gl_FragColor = fragColor;\n"
                     "}\n"
                     "\n";
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org

Reply via email to