From 752d40b118e777607258c4b3d8c1755d70e7f700 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 20 Jan 2014 17:23:11 +0000 Subject: [PATCH] Integrated multipass volume rendering shaders from OpenSceneGraph-Data --- src/osgVolume/MultipassTechnique.cpp | 67 +++------ .../volume_accumulateSamples_iso_frag.cpp | 70 +++++++++ .../volume_accumulateSamples_iso_tf_frag.cpp | 68 +++++++++ .../volume_accumulateSamples_lit_frag.cpp | 58 ++++++++ .../volume_accumulateSamples_lit_tf_frag.cpp | 65 +++++++++ .../volume_accumulateSamples_mip_frag.cpp | 26 ++++ .../volume_accumulateSamples_mip_tf_frag.cpp | 33 +++++ ...volume_accumulateSamples_standard_frag.cpp | 32 +++++ ...ume_accumulateSamples_standard_tf_frag.cpp | 38 +++++ .../Shaders/volume_compute_ray_color_frag.cpp | 134 ++++++++++++++++++ .../Shaders/volume_multipass_frag.cpp | 93 ++++++++++++ .../Shaders/volume_multipass_vert.cpp | 45 ++++++ 12 files changed, 684 insertions(+), 45 deletions(-) create mode 100644 src/osgVolume/Shaders/volume_accumulateSamples_iso_frag.cpp create mode 100644 src/osgVolume/Shaders/volume_accumulateSamples_iso_tf_frag.cpp create mode 100644 src/osgVolume/Shaders/volume_accumulateSamples_lit_frag.cpp create mode 100644 src/osgVolume/Shaders/volume_accumulateSamples_lit_tf_frag.cpp create mode 100644 src/osgVolume/Shaders/volume_accumulateSamples_mip_frag.cpp create mode 100644 src/osgVolume/Shaders/volume_accumulateSamples_mip_tf_frag.cpp create mode 100644 src/osgVolume/Shaders/volume_accumulateSamples_standard_frag.cpp create mode 100644 src/osgVolume/Shaders/volume_accumulateSamples_standard_tf_frag.cpp create mode 100644 src/osgVolume/Shaders/volume_compute_ray_color_frag.cpp create mode 100644 src/osgVolume/Shaders/volume_multipass_frag.cpp create mode 100644 src/osgVolume/Shaders/volume_multipass_vert.cpp diff --git a/src/osgVolume/MultipassTechnique.cpp b/src/osgVolume/MultipassTechnique.cpp index 577c06f72..72a90afa2 100644 --- a/src/osgVolume/MultipassTechnique.cpp +++ b/src/osgVolume/MultipassTechnique.cpp @@ -444,34 +444,27 @@ void MultipassTechnique::init() - osg::ref_ptr computeRayColorShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_compute_ray_color.frag"); -#if 0 - if (!computeRayColorShader) - { - #include "Shaders/volume_compute_ray_color_frag.cpp"; - computeRayColorShader = new osg::Shader(osg::Shader::FRAGMENT, volume_compute_ray_color_frag); - } -#endif - osg::ref_ptr main_vertexShader = osgDB::readRefShaderFile(osg::Shader::VERTEX, "shaders/volume_multipass.vert"); -#if 0 if (!main_vertexShader) { #include "Shaders/volume_multipass_vert.cpp" - main_vertexShader = new osg::Shader(osg::Shader::VERTEX, volume_multipass_vert)); + main_vertexShader = new osg::Shader(osg::Shader::VERTEX, volume_multipass_vert); } -#endif - osg::ref_ptr back_main_fragmentShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_multipass_back_with_front_depthtexture.frag");; - //osg::ref_ptr back_main_fragmentShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_multipass_back.frag"); -#if 0 + osg::ref_ptr back_main_fragmentShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_multipass.frag");; if (!back_main_fragmentShader) { - #include "Shaders/shaders/volume_multipass_back_with_front_depthtexture_frag.cpp" - back_main_fragmentShader = new osg::Shader(osg::Shader::VERTEX, volume_multipass_back_with_front_depthtexture_frag)); + #include "Shaders/volume_multipass_frag.cpp" + back_main_fragmentShader = new osg::Shader(osg::Shader::FRAGMENT, volume_multipass_frag); + } + + osg::ref_ptr computeRayColorShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_compute_ray_color.frag"); + if (!computeRayColorShader) + { + #include "Shaders/volume_compute_ray_color_frag.cpp" + computeRayColorShader = new osg::Shader(osg::Shader::FRAGMENT, volume_compute_ray_color_frag); } -#endif // clear any previous settings _stateSetMap.clear(); @@ -506,13 +499,11 @@ void MultipassTechnique::init() // STANDARD_SHADERS without TransferFunction { osg::ref_ptr accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_standard.frag"); - #if 0 if (!accumulateSamplesShader) { - #include "Shaders/volume_accumulateSamples_standard_frag.cpp"; + #include "Shaders/volume_accumulateSamples_standard_frag.cpp" accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_standard_frag); } - #endif // back _stateSetMap[STANDARD_SHADERS|BACK_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get()); @@ -522,13 +513,11 @@ void MultipassTechnique::init() if (tf) { osg::ref_ptr accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_standard_tf.frag"); - #if 0 if (!accumulateSamplesShader) { - #include "Shaders/volume_accumulateSamples_standard_tf_frag.cpp"; + #include "Shaders/volume_accumulateSamples_standard_tf_frag.cpp" accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_standard_tf_frag); } - #endif // back _stateSetMap[STANDARD_SHADERS|BACK_SHADERS|TF_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get()); @@ -541,13 +530,11 @@ void MultipassTechnique::init() // ISO_SHADERS without TransferFunction { osg::ref_ptr accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_iso.frag"); - #if 0 if (!accumulateSamplesShader) { - #include "Shaders/volume_accumulateSamples_iso_frag.cpp"; + #include "Shaders/volume_accumulateSamples_iso_frag.cpp" accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_iso_frag); } - #endif // back _stateSetMap[ISO_SHADERS|BACK_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get()); @@ -557,13 +544,11 @@ void MultipassTechnique::init() if (tf) { osg::ref_ptr accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_iso_tf.frag"); - #if 0 if (!accumulateSamplesShader) { - #include "Shaders/volume_accumulateSamples_standard_iso_tf_frag.cpp"; - accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_standard_iso_tf_frag); + #include "Shaders/volume_accumulateSamples_iso_tf_frag.cpp" + accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_iso_tf_frag); } - #endif // back _stateSetMap[ISO_SHADERS|BACK_SHADERS|TF_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get()); @@ -576,13 +561,11 @@ void MultipassTechnique::init() // MIP_SHADERS without TransferFunction { osg::ref_ptr accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_mip.frag"); - #if 0 if (!accumulateSamplesShader) { - #include "Shaders/volume_accumulateSamples_mip_frag.cpp"; + #include "Shaders/volume_accumulateSamples_mip_frag.cpp" accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_mip_frag); } - #endif // back _stateSetMap[MIP_SHADERS|BACK_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get()); @@ -592,13 +575,11 @@ void MultipassTechnique::init() if (tf) { osg::ref_ptr accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_mip_tf.frag"); - #if 0 if (!accumulateSamplesShader) { - #include "Shaders/volume_accumulateSamples_standard_mip_tf_frag.cpp"; - accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_standard_mip_tf_frag); + #include "Shaders/volume_accumulateSamples_mip_tf_frag.cpp" + accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_mip_tf_frag); } - #endif // back _stateSetMap[MIP_SHADERS|BACK_SHADERS|TF_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get()); @@ -611,13 +592,11 @@ void MultipassTechnique::init() // LIT_SHADERS without TransferFunction { osg::ref_ptr accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_lit.frag"); - #if 0 if (!accumulateSamplesShader) { - #include "Shaders/volume_accumulateSamples_lit_frag.cpp"; + #include "Shaders/volume_accumulateSamples_lit_frag.cpp" accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_lit_frag); } - #endif // back _stateSetMap[LIT_SHADERS|BACK_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get()); @@ -627,13 +606,11 @@ void MultipassTechnique::init() if (tf) { osg::ref_ptr accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_lit_tf.frag"); - #if 0 if (!accumulateSamplesShader) { - #include "Shaders/volume_accumulateSamples_standard_lit_tf_frag.cpp"; - accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_standard_lit_tf_frag); + #include "Shaders/volume_accumulateSamples_lit_tf_frag.cpp" + accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_lit_tf_frag); } - #endif // back _stateSetMap[LIT_SHADERS|BACK_SHADERS|TF_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get()); diff --git a/src/osgVolume/Shaders/volume_accumulateSamples_iso_frag.cpp b/src/osgVolume/Shaders/volume_accumulateSamples_iso_frag.cpp new file mode 100644 index 000000000..aba2dd92d --- /dev/null +++ b/src/osgVolume/Shaders/volume_accumulateSamples_iso_frag.cpp @@ -0,0 +1,70 @@ +char volume_accumulateSamples_iso_frag[] = "#version 110\n" + "\n" + "uniform sampler3D volumeTexture;\n" + "\n" + "uniform float IsoSurfaceValue;\n" + "\n" + "varying vec3 lightDirection;\n" + "\n" + "vec4 accumulateSamples(vec3 ts, vec3 te, vec3 dt, float scale, float cutoff, int num_iterations)\n" + "{\n" + " vec3 texcoord = te.xyz;\n" + "\n" + " float normalSampleDistance = length(dt);\n" + " vec3 deltaX = vec3(normalSampleDistance, 0.0, 0.0);\n" + " vec3 deltaY = vec3(0.0, normalSampleDistance, 0.0);\n" + " vec3 deltaZ = vec3(0.0, 0.0, normalSampleDistance);\n" + "\n" + " vec4 previousColor = texture3D( volumeTexture, texcoord);\n" + "\n" + " float targetValue = IsoSurfaceValue;\n" + "\n" + " while(num_iterations>0)\n" + " {\n" + " vec4 color = texture3D( volumeTexture, texcoord);\n" + "\n" + " float m = (previousColor.a-targetValue) * (color.a-targetValue);\n" + " if (m <= 0.0)\n" + " {\n" + " float r = (targetValue-color.a)/(previousColor.a-color.a);\n" + " texcoord = texcoord - r*dt;\n" + "\n" + "#if 0\n" + " color = texture3D( volumeTexture, texcoord);\n" + "#else\n" + " color.r = 1.0;\n" + " color.g = 1.0;\n" + " color.b = 1.0;\n" + " color.a = 1.0;\n" + "#endif\n" + " float px = texture3D( volumeTexture, texcoord + deltaX).a;\n" + " float py = texture3D( volumeTexture, texcoord + deltaY).a;\n" + " float pz = texture3D( volumeTexture, texcoord + deltaZ).a;\n" + "\n" + " float nx = texture3D( volumeTexture, texcoord - deltaX).a;\n" + " float ny = texture3D( volumeTexture, texcoord - deltaY).a;\n" + " float nz = texture3D( volumeTexture, texcoord - deltaZ).a;\n" + "\n" + " vec3 grad = vec3(px-nx, py-ny, pz-nz);\n" + " if (grad.x!=0.0 || grad.y!=0.0 || grad.z!=0.0)\n" + " {\n" + " vec3 normal = normalize(grad);\n" + " float lightScale = 0.1 + max(0.0, dot(normal.xyz, lightDirection))*0.9;\n" + "\n" + " color.r *= lightScale;\n" + " color.g *= lightScale;\n" + " color.b *= lightScale;\n" + " }\n" + " return color;\n" + " }\n" + "\n" + " previousColor = color;\n" + "\n" + " texcoord += dt;\n" + "\n" + " --num_iterations;\n" + " }\n" + "\n" + " return vec4(0.0, 0.0, 0.0, 0.0);\n" + "}\n" + "\n"; diff --git a/src/osgVolume/Shaders/volume_accumulateSamples_iso_tf_frag.cpp b/src/osgVolume/Shaders/volume_accumulateSamples_iso_tf_frag.cpp new file mode 100644 index 000000000..5a19f6837 --- /dev/null +++ b/src/osgVolume/Shaders/volume_accumulateSamples_iso_tf_frag.cpp @@ -0,0 +1,68 @@ +char volume_accumulateSamples_iso_tf_frag[] = "#version 110\n" + "\n" + "uniform sampler3D volumeTexture;\n" + "\n" + "uniform sampler1D tfTexture;\n" + "uniform float tfScale;\n" + "uniform float tfOffset;\n" + "\n" + "uniform float IsoSurfaceValue;\n" + "\n" + "varying vec3 lightDirection;\n" + "\n" + "vec4 accumulateSamples(vec3 ts, vec3 te, vec3 dt, float scale, float cutoff, int num_iterations)\n" + "{\n" + " vec3 texcoord = te.xyz;\n" + "\n" + " float normalSampleDistance = length(dt);\n" + " vec3 deltaX = vec3(normalSampleDistance, 0.0, 0.0);\n" + " vec3 deltaY = vec3(0.0, normalSampleDistance, 0.0);\n" + " vec3 deltaZ = vec3(0.0, 0.0, normalSampleDistance);\n" + "\n" + " float previous_a = texture3D( volumeTexture, texcoord).a;\n" + "\n" + " float targetValue = IsoSurfaceValue;\n" + "\n" + " while(num_iterations>0)\n" + " {\n" + " float a = texture3D( volumeTexture, texcoord).a;\n" + " float m = (previous_a-targetValue) * (a-targetValue);\n" + " if (m <= 0.0)\n" + " {\n" + " float r = (targetValue-a)/(previous_a-a);\n" + " texcoord = texcoord - r*dt;\n" + "\n" + " float v = targetValue * tfScale + tfOffset;\n" + " vec4 color = texture1D( tfTexture, v);\n" + "\n" + " float px = texture3D( volumeTexture, texcoord + deltaX).a;\n" + " float py = texture3D( volumeTexture, texcoord + deltaY).a;\n" + " float pz = texture3D( volumeTexture, texcoord + deltaZ).a;\n" + "\n" + " float nx = texture3D( volumeTexture, texcoord - deltaX).a;\n" + " float ny = texture3D( volumeTexture, texcoord - deltaY).a;\n" + " float nz = texture3D( volumeTexture, texcoord - deltaZ).a;\n" + "\n" + " vec3 grad = vec3(px-nx, py-ny, pz-nz);\n" + " if (grad.x!=0.0 || grad.y!=0.0 || grad.z!=0.0)\n" + " {\n" + " vec3 normal = normalize(grad);\n" + " float lightScale = 0.1 + max(0.0, dot(normal.xyz, lightDirection))*0.9;\n" + "\n" + " color.r *= lightScale;\n" + " color.g *= lightScale;\n" + " color.b *= lightScale;\n" + " }\n" + " return color;\n" + " }\n" + "\n" + " previous_a = a;\n" + "\n" + " texcoord += dt;\n" + "\n" + " --num_iterations;\n" + " }\n" + "\n" + " return vec4(0.0, 0.0, 0.0, 0.0);\n" + "}\n" + "\n"; diff --git a/src/osgVolume/Shaders/volume_accumulateSamples_lit_frag.cpp b/src/osgVolume/Shaders/volume_accumulateSamples_lit_frag.cpp new file mode 100644 index 000000000..0737c5da5 --- /dev/null +++ b/src/osgVolume/Shaders/volume_accumulateSamples_lit_frag.cpp @@ -0,0 +1,58 @@ +char volume_accumulateSamples_lit_frag[] = "#version 110\n" + "\n" + "uniform sampler3D volumeTexture;\n" + "uniform float AlphaFuncValue;\n" + "\n" + "varying vec3 lightDirection;\n" + "\n" + "vec4 accumulateSamples(vec3 ts, vec3 te, vec3 dt, float scale, float cutoff, int num_iterations)\n" + "{\n" + " vec3 texcoord = te.xyz;\n" + " vec4 fragColor = vec4(0.0, 0.0, 0.0, 0.0);\n" + "\n" + " float normalSampleDistance = length(dt);\n" + " vec3 deltaX = vec3(normalSampleDistance, 0.0, 0.0);\n" + " vec3 deltaY = vec3(0.0, normalSampleDistance, 0.0);\n" + " vec3 deltaZ = vec3(0.0, 0.0, normalSampleDistance);\n" + "\n" + " while(num_iterations>0 && fragColor.aAlphaFuncValue)\n" + " {\n" + "\n" + " float px = texture3D( volumeTexture, texcoord + deltaX).a;\n" + " float py = texture3D( volumeTexture, texcoord + deltaY).a;\n" + " float pz = texture3D( volumeTexture, texcoord + deltaZ).a;\n" + "\n" + " float nx = texture3D( volumeTexture, texcoord - deltaX).a;\n" + " float ny = texture3D( volumeTexture, texcoord - deltaY).a;\n" + " float nz = texture3D( volumeTexture, texcoord - deltaZ).a;\n" + "\n" + " vec3 grad = vec3(px-nx, py-ny, pz-nz);\n" + " if (grad.x!=0.0 || grad.y!=0.0 || grad.z!=0.0)\n" + " {\n" + " vec3 normal = normalize(grad);\n" + " float lightScale = 0.1 + max(0.0, dot(normal.xyz, lightDirection))*0.9;\n" + "\n" + " color.r *= lightScale;\n" + " color.g *= lightScale;\n" + " color.b *= lightScale;\n" + " }\n" + "\n" + " float r = color.a * ((1.0-fragColor.a)*scale);\n" + " fragColor.rgb += color.rgb*r;\n" + " fragColor.a += r;\n" + " }\n" + "\n" + " texcoord += dt;\n" + "\n" + " --num_iterations;\n" + " }\n" + "\n" + " if (num_iterations>0) fragColor.a = 1.0;\n" + "\n" + " return fragColor;\n" + "}\n" + "\n"; diff --git a/src/osgVolume/Shaders/volume_accumulateSamples_lit_tf_frag.cpp b/src/osgVolume/Shaders/volume_accumulateSamples_lit_tf_frag.cpp new file mode 100644 index 000000000..0367ba5e9 --- /dev/null +++ b/src/osgVolume/Shaders/volume_accumulateSamples_lit_tf_frag.cpp @@ -0,0 +1,65 @@ +char volume_accumulateSamples_lit_tf_frag[] = "#version 110\n" + "\n" + "uniform sampler3D volumeTexture;\n" + "\n" + "uniform sampler1D tfTexture;\n" + "uniform float tfScale;\n" + "uniform float tfOffset;\n" + "\n" + "uniform float AlphaFuncValue;\n" + "\n" + "varying vec3 lightDirection;\n" + "\n" + "vec4 accumulateSamples(vec3 ts, vec3 te, vec3 dt, float scale, float cutoff, int num_iterations)\n" + "{\n" + " vec3 texcoord = te.xyz;\n" + " vec4 fragColor = vec4(0.0, 0.0, 0.0, 0.0);\n" + "\n" + " float normalSampleDistance = length(dt);\n" + " vec3 deltaX = vec3(normalSampleDistance, 0.0, 0.0);\n" + " vec3 deltaY = vec3(0.0, normalSampleDistance, 0.0);\n" + " vec3 deltaZ = vec3(0.0, 0.0, normalSampleDistance);\n" + "\n" + " while(num_iterations>0 && fragColor.aAlphaFuncValue)\n" + " {\n" + "\n" + " float px = texture3D( volumeTexture, texcoord + deltaX).a;\n" + " float py = texture3D( volumeTexture, texcoord + deltaY).a;\n" + " float pz = texture3D( volumeTexture, texcoord + deltaZ).a;\n" + "\n" + " float nx = texture3D( volumeTexture, texcoord - deltaX).a;\n" + " float ny = texture3D( volumeTexture, texcoord - deltaY).a;\n" + " float nz = texture3D( volumeTexture, texcoord - deltaZ).a;\n" + "\n" + " vec3 grad = vec3(px-nx, py-ny, pz-nz);\n" + " if (grad.x!=0.0 || grad.y!=0.0 || grad.z!=0.0)\n" + " {\n" + " vec3 normal = normalize(grad);\n" + " float lightScale = 0.1 + max(0.0, dot(normal.xyz, lightDirection))*0.9;\n" + "\n" + " color.r *= lightScale;\n" + " color.g *= lightScale;\n" + " color.b *= lightScale;\n" + " }\n" + "\n" + " float r = color.a * ((1.0-fragColor.a)*scale);\n" + " fragColor.rgb += color.rgb*r;\n" + " fragColor.a += r;\n" + " }\n" + "\n" + " texcoord += dt;\n" + "\n" + " --num_iterations;\n" + " }\n" + "\n" + " if (num_iterations>0) fragColor.a = 1.0;\n" + "\n" + " return fragColor;\n" + "}\n" + "\n"; diff --git a/src/osgVolume/Shaders/volume_accumulateSamples_mip_frag.cpp b/src/osgVolume/Shaders/volume_accumulateSamples_mip_frag.cpp new file mode 100644 index 000000000..1af49e9bb --- /dev/null +++ b/src/osgVolume/Shaders/volume_accumulateSamples_mip_frag.cpp @@ -0,0 +1,26 @@ +char volume_accumulateSamples_mip_frag[] = "#version 110\n" + "\n" + "uniform sampler3D volumeTexture;\n" + "\n" + "vec4 accumulateSamples(vec3 ts, vec3 te, vec3 dt, float scale, float cutoff, int num_iterations)\n" + "{\n" + " vec3 texcoord = te.xyz;\n" + " vec4 fragColor = vec4(0.0, 0.0, 0.0, 0.0);\n" + "\n" + " while(num_iterations>0)\n" + " {\n" + " vec4 color = texture3D( volumeTexture, texcoord);\n" + "\n" + " if (color.a>fragColor.a)\n" + " {\n" + " fragColor = color;\n" + " }\n" + "\n" + " texcoord += dt;\n" + "\n" + " --num_iterations;\n" + " }\n" + "\n" + " return fragColor;\n" + "}\n" + "\n"; diff --git a/src/osgVolume/Shaders/volume_accumulateSamples_mip_tf_frag.cpp b/src/osgVolume/Shaders/volume_accumulateSamples_mip_tf_frag.cpp new file mode 100644 index 000000000..9f092a33a --- /dev/null +++ b/src/osgVolume/Shaders/volume_accumulateSamples_mip_tf_frag.cpp @@ -0,0 +1,33 @@ +char volume_accumulateSamples_mip_tf_frag[] = "#version 110\n" + "\n" + "uniform sampler3D volumeTexture;\n" + "\n" + "uniform sampler1D tfTexture;\n" + "uniform float tfScale;\n" + "uniform float tfOffset;\n" + "\n" + "vec4 accumulateSamples(vec3 ts, vec3 te, vec3 dt, float scale, float cutoff, int num_iterations)\n" + "{\n" + " vec3 texcoord = te.xyz;\n" + " vec4 fragColor = vec4(0.0, 0.0, 0.0, 0.0);\n" + "\n" + " float max_a = 0.0;\n" + " while(num_iterations>0)\n" + " {\n" + " float a = texture3D( volumeTexture, texcoord).a;\n" + "\n" + " if (a>max_a)\n" + " {\n" + " float v = a * tfScale + tfOffset;\n" + " fragColor = texture1D( tfTexture, v);\n" + " max_a = a;\n" + " }\n" + "\n" + " texcoord += dt;\n" + "\n" + " --num_iterations;\n" + " }\n" + "\n" + " return fragColor;\n" + "}\n" + "\n"; diff --git a/src/osgVolume/Shaders/volume_accumulateSamples_standard_frag.cpp b/src/osgVolume/Shaders/volume_accumulateSamples_standard_frag.cpp new file mode 100644 index 000000000..ab448e23c --- /dev/null +++ b/src/osgVolume/Shaders/volume_accumulateSamples_standard_frag.cpp @@ -0,0 +1,32 @@ +char volume_accumulateSamples_standard_frag[] = "#version 110\n" + "\n" + "uniform sampler3D volumeTexture;\n" + "\n" + "uniform float AlphaFuncValue;\n" + "\n" + "vec4 accumulateSamples(vec3 ts, vec3 te, vec3 dt, float scale, float cutoff, int num_iterations)\n" + "{\n" + " vec3 texcoord = te.xyz;\n" + " vec4 fragColor = vec4(0.0, 0.0, 0.0, 0.0);\n" + "\n" + " while(num_iterations>0 && fragColor.aAlphaFuncValue)\n" + " {\n" + " float r = color.a * ((1.0-fragColor.a)*scale);\n" + " fragColor.rgb += color.rgb*r;\n" + " fragColor.a += r;\n" + " }\n" + "\n" + " texcoord += dt;\n" + "\n" + " --num_iterations;\n" + " }\n" + "\n" + " if (num_iterations>0) fragColor.a = 1.0;\n" + "\n" + " return fragColor;\n" + "}\n" + "\n"; diff --git a/src/osgVolume/Shaders/volume_accumulateSamples_standard_tf_frag.cpp b/src/osgVolume/Shaders/volume_accumulateSamples_standard_tf_frag.cpp new file mode 100644 index 000000000..c32a6dcc0 --- /dev/null +++ b/src/osgVolume/Shaders/volume_accumulateSamples_standard_tf_frag.cpp @@ -0,0 +1,38 @@ +char volume_accumulateSamples_standard_tf_frag[] = "#version 110\n" + "\n" + "uniform sampler3D volumeTexture;\n" + "\n" + "uniform sampler1D tfTexture;\n" + "uniform float tfScale;\n" + "uniform float tfOffset;\n" + "\n" + "uniform float AlphaFuncValue;\n" + "\n" + "vec4 accumulateSamples(vec3 ts, vec3 te, vec3 dt, float scale, float cutoff, int num_iterations)\n" + "{\n" + " vec3 texcoord = te.xyz;\n" + " vec4 fragColor = vec4(0.0, 0.0, 0.0, 0.0);\n" + "\n" + " while(num_iterations>0 && fragColor.aAlphaFuncValue)\n" + " {\n" + " float r = color.a * ((1.0-fragColor.a)*scale);\n" + " fragColor.rgb += color.rgb*r;\n" + " fragColor.a += r;\n" + " }\n" + "\n" + " texcoord += dt;\n" + "\n" + " --num_iterations;\n" + " }\n" + "\n" + " if (num_iterations>0) fragColor.a = 1.0;\n" + "\n" + " return fragColor;\n" + "}\n" + "\n"; diff --git a/src/osgVolume/Shaders/volume_compute_ray_color_frag.cpp b/src/osgVolume/Shaders/volume_compute_ray_color_frag.cpp new file mode 100644 index 000000000..5c102a4db --- /dev/null +++ b/src/osgVolume/Shaders/volume_compute_ray_color_frag.cpp @@ -0,0 +1,134 @@ +char volume_compute_ray_color_frag[] = "#version 110\n" + "\n" + "uniform vec4 viewportDimensions;\n" + "uniform sampler3D volumeTexture;\n" + "uniform vec3 volumeCellSize;\n" + "\n" + "uniform float SampleRatioValue;\n" + "uniform float TransparencyValue;\n" + "varying mat4 texgen_withProjectionMatrixInverse;\n" + "\n" + "// forward declare, probided by volume_accumulateSamples*.frag shaders\n" + "vec4 accumulateSamples(vec3 ts, vec3 te, vec3 dt, float scale, float cutoff, int num_iterations);\n" + "\n" + "vec4 accumulateSegment(vec3 ts, vec3 te)\n" + "{\n" + " const int max_iterations = 8192;\n" + "\n" + " float density = volumeCellSize.x;\n" + " if (volumeCellSize.ymax_iterations)\n" + " {\n" + " num_iterations = max_iterations;\n" + " baseColor.r = 0.0;\n" + " }\n" + "\n" + " // traverse from front to back\n" + " vec3 deltaTexCoord=(ts-te).xyz/float(num_iterations-1);\n" + " float stepLength = length(deltaTexCoord);\n" + "\n" + " //float scale = 0.5/sampleRatio;\n" + " float scale = stepLength/length(volumeCellSize);\n" + " if (scale>1.0) scale = 1.0;\n" + "\n" + " scale *= TransparencyValue;\n" + "\n" + " float cutoff = 1.0-1.0/256.0;\n" + "\n" + " vec4 fragColor;\n" + "\n" + " fragColor = accumulateSamples(ts, te, deltaTexCoord, scale, cutoff, num_iterations);\n" + "\n" + " fragColor *= baseColor;\n" + "\n" + " return fragColor;\n" + "}\n" + "\n" + "vec3 clampToUnitCube(vec3 ts, vec3 te)\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" + " return te;\n" + " }\n" + " else\n" + " {\n" + " if (te.x<0.0)\n" + " {\n" + " float r = -te.x / (ts.x-te.x);\n" + " te = te + (ts-te)*r;\n" + " }\n" + "\n" + " if (te.x>1.0)\n" + " {\n" + " float r = (1.0-te.x) / (ts.x-te.x);\n" + " te = te + (ts-te)*r;\n" + " }\n" + "\n" + " if (te.y<0.0)\n" + " {\n" + " float r = -te.y / (ts.y-te.y);\n" + " te = te + (ts-te)*r;\n" + " }\n" + "\n" + " if (te.y>1.0)\n" + " {\n" + " float r = (1.0-te.y) / (ts.y-te.y);\n" + " te = te + (ts-te)*r;\n" + " }\n" + "\n" + " if (te.z<0.0)\n" + " {\n" + " float r = -te.z / (ts.z-te.z);\n" + " te = te + (ts-te)*r;\n" + " }\n" + "\n" + " if (te.z>1.0)\n" + " {\n" + " float r = (1.0-te.z) / (ts.z-te.z);\n" + " te = te + (ts-te)*r;\n" + " }\n" + " }\n" + " return te;\n" + "}\n" + "\n" + "\n" + "vec4 computeRayColor(float px, float py, float depth_start, float depth_end)\n" + "{\n" + " float viewportWidth = viewportDimensions[2];\n" + " float viewportHeight = viewportDimensions[3];\n" + "\n" + " px -= viewportDimensions.x;\n" + " py -= viewportDimensions.y;\n" + "\n" + " // start and end clip space coords\n" + " vec4 start_clip = vec4((px/viewportWidth)*2.0-1.0, (py/viewportHeight)*2.0-1.0, (depth_start)*2.0-1.0, 1.0);\n" + " vec4 end_clip = vec4((px/viewportWidth)*2.0-1.0, (py/viewportHeight)*2.0-1.0, (depth_end)*2.0-1.0, 1.0);\n" + "\n" + " vec4 start_texcoord = texgen_withProjectionMatrixInverse * start_clip;\n" + " vec4 end_texcoord = texgen_withProjectionMatrixInverse * end_clip;\n" + "\n" + " start_texcoord.xyz = start_texcoord.xyz / start_texcoord.w;\n" + " start_texcoord.w = 1.0;\n" + "\n" + " end_texcoord.xyz = end_texcoord.xyz / end_texcoord.w;\n" + " end_texcoord.w = 1.0;\n" + "\n" + " vec3 clamped_start_texcoord = clampToUnitCube(end_texcoord.xyz, start_texcoord.xyz);\n" + " vec3 clamped_end_texcoord = clampToUnitCube(start_texcoord.xyz, end_texcoord.xyz);\n" + "\n" + " return accumulateSegment(clamped_start_texcoord, clamped_end_texcoord);\n" + "}\n" + "\n"; diff --git a/src/osgVolume/Shaders/volume_multipass_frag.cpp b/src/osgVolume/Shaders/volume_multipass_frag.cpp new file mode 100644 index 000000000..0cd1d76fa --- /dev/null +++ b/src/osgVolume/Shaders/volume_multipass_frag.cpp @@ -0,0 +1,93 @@ +char volume_multipass_frag[] = "#version 110\n" + "\n" + "uniform sampler2D colorTexture;\n" + "uniform sampler2D depthTexture;\n" + "uniform sampler2D frontFaceDepthTexture;\n" + "uniform vec4 viewportDimensions;\n" + "\n" + "// declare function defined in volume_compute_ray_color.frag\n" + "vec4 computeRayColor(float px, float py, float depth_start, float depth_end);\n" + "\n" + "void main(void)\n" + "{\n" + " vec2 texcoord = vec2((gl_FragCoord.x-viewportDimensions[0])/viewportDimensions[2], (gl_FragCoord.y-viewportDimensions[1])/viewportDimensions[3]);\n" + " vec4 color = texture2D( colorTexture, texcoord);\n" + " float texture_depth = texture2D( depthTexture, texcoord).s;\n" + " float front_depth = texture2D( frontFaceDepthTexture, texcoord).s;\n" + "\n" + " // if front_depth is set to the far plane then front\n" + " // face has been clipped out by the near plane, so assume\n" + " // front_depth is near plane and reset depth to 0.0\n" + " if (front_depth==1.0) front_depth = 0.0;\n" + "\n" + " if (gl_FragCoord.ztexture_depth) discard;\n" + "\n" + " // gl_FragDepth = texture_depth;\n" + "\n" + " // need to blend the object color with the ray from the object depth to the eye point\n" + " vec4 ray_color = computeRayColor(gl_FragCoord.x, gl_FragCoord.y, texture_depth, front_depth);\n" + " // ray_color *= vec4(1.0,1.0,0.0,1.0);\n" + " gl_FragColor = mix(color, ray_color, ray_color.a);\n" + " }\n" + " }\n" + "\n" + "}\n" + "\n"; diff --git a/src/osgVolume/Shaders/volume_multipass_vert.cpp b/src/osgVolume/Shaders/volume_multipass_vert.cpp new file mode 100644 index 000000000..5a71e0f1e --- /dev/null +++ b/src/osgVolume/Shaders/volume_multipass_vert.cpp @@ -0,0 +1,45 @@ +char volume_multipass_vert[] = "#version 110\n" + "\n" + "uniform mat4 texgen;\n" + "\n" + "varying vec4 cameraPos;\n" + "varying vec4 vertexPos;\n" + "varying vec3 lightDirection;\n" + "varying mat4 texgen_withProjectionMatrixInverse;\n" + "varying vec4 baseColor;\n" + "\n" + "varying float near;\n" + "varying float far;\n" + "varying float near_mult_far;\n" + "varying float far_sub_near;\n" + "\n" + "void main(void)\n" + "{\n" + " // compute near and far values from projection matrix.\n" + " near = gl_ProjectionMatrix[2][3] / (gl_ProjectionMatrix[2][2]-1.0);\n" + " far = gl_ProjectionMatrix[2][3] / (1.0+gl_ProjectionMatrix[2][2]);\n" + "\n" + " near_mult_far = near*far;\n" + " far_sub_near = far-near;\n" + "\n" + " gl_Position = ftransform();\n" + "\n" + " cameraPos = gl_ModelViewMatrixInverse * vec4(0,0,0,1);\n" + " vertexPos = gl_Vertex;\n" + " baseColor = gl_FrontMaterial.diffuse;\n" + "\n" + " vec4 lightPosition = gl_ModelViewMatrixInverse * gl_LightSource[0].position;\n" + " if (lightPosition[3]==0.0)\n" + " {\n" + " // directional light source\n" + " lightDirection = -normalize(lightPosition.xyz);\n" + " }\n" + " else\n" + " {\n" + " // positional light source\n" + " lightDirection = normalize((lightPosition-vertexPos).xyz);\n" + " }\n" + "\n" + " texgen_withProjectionMatrixInverse = texgen * gl_ProjectionMatrixInverse;\n" + "}\n" + "\n";