Show
Ignore:
Timestamp:
09/24/08 12:45:15 (6 years ago)
Author:
robert
Message:

Added shader based transfer function, enabled via --gpu-tf

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgvolume/osgvolume.cpp

    r8930 r8931  
    2121#include <osg/Notify> 
    2222#include <osg/Texture3D> 
     23#include <osg/Texture1D> 
    2324#include <osg/TexGen> 
    2425#include <osg/Geode> 
     
    688689}; 
    689690 
    690 osg::Node* createShaderModel(osg::ref_ptr<osg::Image>& image_3d, osg::ref_ptr<osg::Image>& /*normalmap_3d*/, 
     691osg::Node* createShaderModel(osg::ref_ptr<osg::Image>& image_3d,  
     692                       osg::ref_ptr<osg::Image>& /*normalmap_3d*/, 
     693                       osg::TransferFunction1D* tf, 
    691694                       osg::Texture::InternalFormatMode internalFormatMode, 
    692695                       float xSize, float ySize, float zSize, 
     
    731734 
    732735    stateset->setTextureAttributeAndModes(0,texture3D,osg::StateAttribute::ON); 
     736     
     737    if (tf) 
     738    { 
     739        osg::Texture1D* texture1D = new osg::Texture1D; 
     740        texture1D->setImage(tf->getImage());     
     741        stateset->setTextureAttributeAndModes(1,texture1D,osg::StateAttribute::ON); 
     742    } 
    733743 
    734744    osg::Program* program = new osg::Program; 
     
    767777    } 
    768778     
    769     std::string fragmentShaderFile = osgDB::findDataFile("volume.frag"); 
    770     if (!fragmentShaderFile.empty()) 
    771     { 
    772         program->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT, fragmentShaderFile)); 
     779    if (tf) 
     780    { 
     781        std::string fragmentShaderFile = osgDB::findDataFile("volume-tf.frag"); 
     782        if (!fragmentShaderFile.empty()) 
     783        { 
     784            program->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT, fragmentShaderFile)); 
     785        } 
     786        else 
     787        { 
     788            ////////////////////////////////////////////////////////////////// 
     789            // fragment shader 
     790            // 
     791            char fragmentShaderSource[] =  
     792                "uniform sampler3D baseTexture;\n" 
     793                "uniform sampler1D tfTexture;\n" 
     794                "uniform float sampleDensity;\n" 
     795                "uniform float transparency;\n" 
     796                "uniform float alphaCutOff;\n" 
     797                "\n" 
     798                "varying vec4 cameraPos;\n" 
     799                "varying vec4 vertexPos;\n" 
     800                "varying mat4 texgen;\n" 
     801                "\n" 
     802                "void main(void)\n" 
     803                "{ \n" 
     804                "    vec3 t0 = (texgen * vertexPos).xyz;\n" 
     805                "    vec3 te = (texgen * cameraPos).xyz;\n" 
     806                "\n" 
     807                "    if (te.x>=0.0 && te.x<=1.0 &&\n" 
     808                "        te.y>=0.0 && te.y<=1.0 &&\n" 
     809                "        te.z>=0.0 && te.z<=1.0)\n" 
     810                "    {\n" 
     811                "        // do nothing... te inside volume\n" 
     812                "    }\n" 
     813                "    else\n" 
     814                "    {\n" 
     815                "        if (te.x<0.0)\n" 
     816                "        {\n" 
     817                "            float r = -te.x / (t0.x-te.x);\n" 
     818                "            te = te + (t0-te)*r;\n" 
     819                "        }\n" 
     820                "\n" 
     821                "        if (te.x>1.0)\n" 
     822                "        {\n" 
     823                "            float r = (1.0-te.x) / (t0.x-te.x);\n" 
     824                "            te = te + (t0-te)*r;\n" 
     825                "        }\n" 
     826                "\n" 
     827                "        if (te.y<0.0)\n" 
     828                "        {\n" 
     829                "            float r = -te.y / (t0.y-te.y);\n" 
     830                "            te = te + (t0-te)*r;\n" 
     831                "        }\n" 
     832                "\n" 
     833                "        if (te.y>1.0)\n" 
     834                "        {\n" 
     835                "            float r = (1.0-te.y) / (t0.y-te.y);\n" 
     836                "            te = te + (t0-te)*r;\n" 
     837                "        }\n" 
     838                "\n" 
     839                "        if (te.z<0.0)\n" 
     840                "        {\n" 
     841                "            float r = -te.z / (t0.z-te.z);\n" 
     842                "            te = te + (t0-te)*r;\n" 
     843                "        }\n" 
     844                "\n" 
     845                "        if (te.z>1.0)\n" 
     846                "        {\n" 
     847                "            float r = (1.0-te.z) / (t0.z-te.z);\n" 
     848                "            te = te + (t0-te)*r;\n" 
     849                "        }\n" 
     850                "    }\n" 
     851                "\n" 
     852                "    const float max_iteratrions = 2048.0;\n" 
     853                "    float num_iterations = length(te-t0)/sampleDensity;\n" 
     854                "    if (num_iterations>max_iteratrions) \n" 
     855                "    {\n" 
     856                "        num_iterations = max_iteratrions;\n" 
     857                "    }\n" 
     858                "\n" 
     859                "    vec3 deltaTexCoord=(te-t0)/float(num_iterations-1.0);\n" 
     860                "    vec3 texcoord = t0;\n" 
     861                "\n" 
     862                "    vec4 fragColor = vec4(0.0, 0.0, 0.0, 0.0); \n" 
     863                "    while(num_iterations>0.0)\n" 
     864                "    {\n" 
     865                "        float v = texture3D( baseTexture, texcoord).s;\n" 
     866                "        vec4 color = texture1D( tfTexture, v);\n" 
     867                "        float r = color[3]*transparency;\n" 
     868                "        if (r>alphaCutOff)\n" 
     869                "        {\n" 
     870                "            fragColor.xyz = fragColor.xyz*(1.0-r)+color.xyz*r;\n" 
     871                "            fragColor.w += r;\n" 
     872                "        }\n" 
     873                "        texcoord += deltaTexCoord; \n" 
     874                "\n" 
     875                "        --num_iterations;\n" 
     876                "    }\n" 
     877                "\n" 
     878                "    if (fragColor.w>1.0) fragColor.w = 1.0; \n" 
     879                "    if (fragColor.w==0.0) discard;\n" 
     880                "    gl_FragColor = fragColor;\n" 
     881                "}\n"; 
     882 
     883            osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource); 
     884            program->addShader(fragment_shader); 
     885        } 
     886 
     887        osg::Uniform* tfTextureSampler = new osg::Uniform("tfTexture",1); 
     888        stateset->addUniform(tfTextureSampler); 
     889 
    773890    } 
    774891    else 
    775     { 
    776         ////////////////////////////////////////////////////////////////// 
    777         // fragment shader 
    778         // 
    779         char fragmentShaderSource[] =  
    780             "uniform sampler3D baseTexture;\n" 
    781             "uniform float sampleDensity;\n" 
    782             "uniform float transparency;\n" 
    783             "uniform float alphaCutOff;\n" 
    784             "\n" 
    785             "varying vec4 cameraPos;\n" 
    786             "varying vec4 vertexPos;\n" 
    787             "varying mat4 texgen;\n" 
    788             "\n" 
    789             "void main(void)\n" 
    790             "{ \n" 
    791             "    vec3 t0 = (texgen * vertexPos).xyz;\n" 
    792             "    vec3 te = (texgen * cameraPos).xyz;\n" 
    793             "\n" 
    794             "    if (te.x>=0.0 && te.x<=1.0 &&\n" 
    795             "        te.y>=0.0 && te.y<=1.0 &&\n" 
    796             "        te.z>=0.0 && te.z<=1.0)\n" 
    797             "    {\n" 
    798             "        // do nothing... te inside volume\n" 
    799             "    }\n" 
    800             "    else\n" 
    801             "    {\n" 
    802             "        if (te.x<0.0)\n" 
    803             "        {\n" 
    804             "            float r = -te.x / (t0.x-te.x);\n" 
    805             "            te = te + (t0-te)*r;\n" 
    806             "        }\n" 
    807             "\n" 
    808             "        if (te.x>1.0)\n" 
    809             "        {\n" 
    810             "            float r = (1.0-te.x) / (t0.x-te.x);\n" 
    811             "            te = te + (t0-te)*r;\n" 
    812             "        }\n" 
    813             "\n" 
    814             "        if (te.y<0.0)\n" 
    815             "        {\n" 
    816             "            float r = -te.y / (t0.y-te.y);\n" 
    817             "            te = te + (t0-te)*r;\n" 
    818             "        }\n" 
    819             "\n" 
    820             "        if (te.y>1.0)\n" 
    821             "        {\n" 
    822             "            float r = (1.0-te.y) / (t0.y-te.y);\n" 
    823             "            te = te + (t0-te)*r;\n" 
    824             "        }\n" 
    825             "\n" 
    826             "        if (te.z<0.0)\n" 
    827             "        {\n" 
    828             "            float r = -te.z / (t0.z-te.z);\n" 
    829             "            te = te + (t0-te)*r;\n" 
    830             "        }\n" 
    831             "\n" 
    832             "        if (te.z>1.0)\n" 
    833             "        {\n" 
    834             "            float r = (1.0-te.z) / (t0.z-te.z);\n" 
    835             "            te = te + (t0-te)*r;\n" 
    836             "        }\n" 
    837             "    }\n" 
    838             "\n" 
    839             "    const float max_iteratrions = 2048.0;\n" 
    840             "    float num_iterations = length(te-t0)/sampleDensity;\n" 
    841             "    if (num_iterations>max_iteratrions) \n" 
    842             "    {\n" 
    843             "        num_iterations = max_iteratrions;\n" 
    844             "    }\n" 
    845             "\n" 
    846             "    vec3 deltaTexCoord=(te-t0)/float(num_iterations-1.0);\n" 
    847             "    vec3 texcoord = t0;\n" 
    848             "\n" 
    849             "    vec4 fragColor = vec4(0.0, 0.0, 0.0, 0.0); \n" 
    850             "    while(num_iterations>0.0)\n" 
    851             "    {\n" 
    852             "        vec4 color = texture3D( baseTexture, texcoord);\n" 
    853             "        float r = color[3]*transparency;\n" 
    854             "        if (r>alphaCutOff)\n" 
    855             "        {\n" 
    856             "            fragColor.xyz = fragColor.xyz*(1.0-r)+color.xyz*r;\n" 
    857             "            fragColor.w += r;\n" 
    858             "        }\n" 
    859             "        texcoord += deltaTexCoord; \n" 
    860             "\n" 
    861             "        --num_iterations;\n" 
    862             "    }\n" 
    863             "\n" 
    864             "    if (fragColor.w>1.0) fragColor.w = 1.0; \n" 
    865             "    if (fragColor.w==0.0) discard;\n" 
    866             "    gl_FragColor = fragColor;\n" 
    867             "}\n"; 
    868  
    869         osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource); 
    870         program->addShader(fragment_shader); 
    871     } 
    872  
     892    {     
     893        std::string fragmentShaderFile = osgDB::findDataFile("volume.frag"); 
     894        if (!fragmentShaderFile.empty()) 
     895        { 
     896            program->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT, fragmentShaderFile)); 
     897        } 
     898        else 
     899        { 
     900            ////////////////////////////////////////////////////////////////// 
     901            // fragment shader 
     902            // 
     903            char fragmentShaderSource[] =  
     904                "uniform sampler3D baseTexture;\n" 
     905                "uniform float sampleDensity;\n" 
     906                "uniform float transparency;\n" 
     907                "uniform float alphaCutOff;\n" 
     908                "\n" 
     909                "varying vec4 cameraPos;\n" 
     910                "varying vec4 vertexPos;\n" 
     911                "varying mat4 texgen;\n" 
     912                "\n" 
     913                "void main(void)\n" 
     914                "{ \n" 
     915                "    vec3 t0 = (texgen * vertexPos).xyz;\n" 
     916                "    vec3 te = (texgen * cameraPos).xyz;\n" 
     917                "\n" 
     918                "    if (te.x>=0.0 && te.x<=1.0 &&\n" 
     919                "        te.y>=0.0 && te.y<=1.0 &&\n" 
     920                "        te.z>=0.0 && te.z<=1.0)\n" 
     921                "    {\n" 
     922                "        // do nothing... te inside volume\n" 
     923                "    }\n" 
     924                "    else\n" 
     925                "    {\n" 
     926                "        if (te.x<0.0)\n" 
     927                "        {\n" 
     928                "            float r = -te.x / (t0.x-te.x);\n" 
     929                "            te = te + (t0-te)*r;\n" 
     930                "        }\n" 
     931                "\n" 
     932                "        if (te.x>1.0)\n" 
     933                "        {\n" 
     934                "            float r = (1.0-te.x) / (t0.x-te.x);\n" 
     935                "            te = te + (t0-te)*r;\n" 
     936                "        }\n" 
     937                "\n" 
     938                "        if (te.y<0.0)\n" 
     939                "        {\n" 
     940                "            float r = -te.y / (t0.y-te.y);\n" 
     941                "            te = te + (t0-te)*r;\n" 
     942                "        }\n" 
     943                "\n" 
     944                "        if (te.y>1.0)\n" 
     945                "        {\n" 
     946                "            float r = (1.0-te.y) / (t0.y-te.y);\n" 
     947                "            te = te + (t0-te)*r;\n" 
     948                "        }\n" 
     949                "\n" 
     950                "        if (te.z<0.0)\n" 
     951                "        {\n" 
     952                "            float r = -te.z / (t0.z-te.z);\n" 
     953                "            te = te + (t0-te)*r;\n" 
     954                "        }\n" 
     955                "\n" 
     956                "        if (te.z>1.0)\n" 
     957                "        {\n" 
     958                "            float r = (1.0-te.z) / (t0.z-te.z);\n" 
     959                "            te = te + (t0-te)*r;\n" 
     960                "        }\n" 
     961                "    }\n" 
     962                "\n" 
     963                "    const float max_iteratrions = 2048.0;\n" 
     964                "    float num_iterations = length(te-t0)/sampleDensity;\n" 
     965                "    if (num_iterations>max_iteratrions) \n" 
     966                "    {\n" 
     967                "        num_iterations = max_iteratrions;\n" 
     968                "    }\n" 
     969                "\n" 
     970                "    vec3 deltaTexCoord=(te-t0)/float(num_iterations-1.0);\n" 
     971                "    vec3 texcoord = t0;\n" 
     972                "\n" 
     973                "    vec4 fragColor = vec4(0.0, 0.0, 0.0, 0.0); \n" 
     974                "    while(num_iterations>0.0)\n" 
     975                "    {\n" 
     976                "        vec4 color = texture3D( baseTexture, texcoord);\n" 
     977                "        float r = color[3]*transparency;\n" 
     978                "        if (r>alphaCutOff)\n" 
     979                "        {\n" 
     980                "            fragColor.xyz = fragColor.xyz*(1.0-r)+color.xyz*r;\n" 
     981                "            fragColor.w += r;\n" 
     982                "        }\n" 
     983                "        texcoord += deltaTexCoord; \n" 
     984                "\n" 
     985                "        --num_iterations;\n" 
     986                "    }\n" 
     987                "\n" 
     988                "    if (fragColor.w>1.0) fragColor.w = 1.0; \n" 
     989                "    if (fragColor.w==0.0) discard;\n" 
     990                "    gl_FragColor = fragColor;\n" 
     991                "}\n"; 
     992 
     993            osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource); 
     994            program->addShader(fragment_shader); 
     995        } 
     996    } 
    873997    osg::Uniform* baseTextureSampler = new osg::Uniform("baseTexture",0); 
    874998    stateset->addUniform(baseTextureSampler); 
     
    16891813    while(arguments.read("--shader")) { useShader = true; } 
    16901814 
     1815    bool gpuTransferFunction = false;  
     1816    while(arguments.read("--gpu-tf")) { gpuTransferFunction = true; } 
     1817 
    16911818    osg::ref_ptr<osg::Image> image_3d; 
    16921819     
     
    19032030    } 
    19042031     
    1905     if (transferFunction.valid()) 
     2032    if (!gpuTransferFunction && transferFunction.valid()) 
    19062033    { 
    19072034        image_3d = applyTransferFunction(image_3d.get(), transferFunction.get()); 
     
    19182045    { 
    19192046        rootNode = createShaderModel(image_3d, normalmap_3d,  
     2047                               (gpuTransferFunction ? transferFunction.get() : 0), 
    19202048                               internalFormatMode, 
    19212049                               xSize, ySize, zSize,