Commit 101f9eeb authored by David C. Lonie's avatar David C. Lonie

Add Depth stage to polydata fragment shaders.

The depth peelers currently assume gl_FragCoord.z is always the depth,
but the imposter shaders in Domains/Chemistry modify the depth.

This patch adds a //VTK::Depth::Impl hook into the fragment shader
template, before any depth peeling processing is applied. The depth
is stored into gl_FragDepth, and all depth processing now uses this
variable instead of gl_FragCoord.z.
parent 3f597823
......@@ -86,7 +86,7 @@ void vtkOpenGLSphereMapper::ReplaceShaderValues(
"uniform mat4 VCDCMatrix;\n";
vtkShaderProgram::Substitute(FSSource,"//VTK::Normal::Dec",replacement);
vtkShaderProgram::Substitute(FSSource,"//VTK::Normal::Impl",
vtkShaderProgram::Substitute(FSSource,"//VTK::Depth::Impl",
// compute the eye position and unit direction
" vec3 EyePos;\n"
" vec3 EyeDir;\n"
......@@ -129,16 +129,8 @@ void vtkOpenGLSphereMapper::ReplaceShaderValues(
" gl_FragDepth = (pos.z / pos.w + 1.0) / 2.0;\n"
);
if (ren->GetLastRenderingUsedDepthPeeling())
{
vtkShaderProgram::Substitute(FSSource,
"//VTK::DepthPeeling::Impl",
"float odepth = texture2D(opaqueZTexture, gl_FragCoord.xy/screenSize).r;\n"
" if (gl_FragDepth >= odepth) { discard; }\n"
" float tdepth = texture2D(translucentZTexture, gl_FragCoord.xy/screenSize).r;\n"
" if (gl_FragDepth <= tdepth) { discard; }\n"
);
}
// Strip out the normal line -- the normal is computed as part of the depth
vtkShaderProgram::Substitute(FSSource,"//VTK::Normal::Impl", "");
shaders[vtkShader::Vertex]->SetSource(VSSource);
shaders[vtkShader::Fragment]->SetSource(FSSource);
......
......@@ -90,9 +90,8 @@ void vtkOpenGLStickMapper::ReplaceShaderValues(
"uniform mat4 VCDCMatrix;\n";
vtkShaderProgram::Substitute(FSSource,"//VTK::Normal::Dec",replacement);
// see https://www.cl.cam.ac.uk/teaching/1999/AGraphHCI/SMAG/node2.html
vtkShaderProgram::Substitute(FSSource,"//VTK::Normal::Impl",
vtkShaderProgram::Substitute(FSSource,"//VTK::Depth::Impl",
// compute the eye position and unit direction
" vec3 EyePos;\n"
" vec3 EyeDir;\n"
......@@ -164,6 +163,9 @@ void vtkOpenGLStickMapper::ReplaceShaderValues(
" gl_FragDepth = (pos.z / pos.w + 1.0) / 2.0;\n"
);
// Strip out the normal line -- the normal is computed as part of the depth
vtkShaderProgram::Substitute(FSSource,"//VTK::Normal::Impl", "");
vtkHardwareSelector* selector = ren->GetSelector();
bool picking = (ren->GetRenderWindow()->GetIsPicking() || selector != NULL);
if (picking)
......@@ -198,17 +200,6 @@ void vtkOpenGLStickMapper::ReplaceShaderValues(
}
}
if (ren->GetLastRenderingUsedDepthPeeling())
{
vtkShaderProgram::Substitute(FSSource,
"//VTK::DepthPeeling::Impl",
"float odepth = texture2D(opaqueZTexture, gl_FragCoord.xy/screenSize).r;\n"
" if (gl_FragDepth >= odepth) { discard; }\n"
" float tdepth = texture2D(translucentZTexture, gl_FragCoord.xy/screenSize).r;\n"
" if (gl_FragDepth <= tdepth) { discard; }\n"
);
}
shaders[vtkShader::Vertex]->SetSource(VSSource);
shaders[vtkShader::Fragment]->SetSource(FSSource);
......
......@@ -59,6 +59,9 @@ void main()
// Place any calls that require uniform flow (e.g. dFdx) here.
//VTK::UniformFlow::Impl
// Set gl_FragDepth here (gl_FragCoord.z by default)
//VTK::Depth::Impl
// Early depth peeling abort:
//VTK::DepthPeeling::PreColor
......
......@@ -578,9 +578,9 @@ bool vtkDepthPeelingPass::ReplaceShaderValues(std::string &,
vtkShaderProgram::Substitute(
fragmentShader, "//VTK::DepthPeeling::Impl",
"float odepth = texture2D(opaqueZTexture, gl_FragCoord.xy/screenSize).r;\n"
" if (gl_FragCoord.z >= odepth) { discard; }\n"
" if (gl_FragDepth >= odepth) { discard; }\n"
" float tdepth = texture2D(translucentZTexture, gl_FragCoord.xy/screenSize).r;\n"
" if (gl_FragCoord.z <= tdepth + .0000001) { discard; }\n"
" if (gl_FragDepth <= tdepth + .0000001) { discard; }\n"
);
return true;
......
......@@ -111,14 +111,14 @@ bool vtkDualDepthPeelingPass::ReplaceShaderValues(std::string &,
fragmentShader, "//VTK::DepthPeeling::PreColor",
"ivec2 pixel = ivec2(gl_FragCoord.xy);\n"
" float oDepth = texelFetch(opaqueDepth, pixel, 0).y;\n"
" if (oDepth != -1. && gl_FragCoord.z > oDepth)\n"
" if (oDepth != -1. && gl_FragDepth > oDepth)\n"
" { // Ignore fragments that are occluded by opaque geometry:\n"
" gl_FragData[1].xy = vec2(-1., oDepth);\n"
" return;\n"
" }\n"
" else\n"
" {\n"
" gl_FragData[1].xy = vec2(-gl_FragCoord.z, gl_FragCoord.z);\n"
" gl_FragData[1].xy = vec2(-gl_FragDepth, gl_FragDepth);\n"
" return;\n"
" }\n"
);
......@@ -131,7 +131,6 @@ bool vtkDualDepthPeelingPass::ReplaceShaderValues(std::string &,
"uniform sampler2D lastDepthPeel;\n");
vtkShaderProgram::Substitute(
fragmentShader, "//VTK::DepthPeeling::PreColor",
"float depth = gl_FragCoord.z;\n"
" ivec2 pixelCoord = ivec2(gl_FragCoord.xy);\n"
" vec4 front = texelFetch(lastFrontPeel, pixelCoord, 0);\n"
" vec2 minMaxDepth = texelFetch(lastDepthPeel, pixelCoord, 0).xy;\n"
......@@ -151,16 +150,18 @@ bool vtkDualDepthPeelingPass::ReplaceShaderValues(std::string &,
" gl_FragData[2].xy = vec2(-1.);\n"
"\n"
" // Is this fragment outside the current peels?\n"
" if (depth < minDepth - epsilon || depth > maxDepth + epsilon)\n"
" if (gl_FragDepth < minDepth - epsilon ||\n"
" gl_FragDepth > maxDepth + epsilon)\n"
" {\n"
" return;\n"
" }\n"
"\n"
" // Is this fragment inside the current peels?\n"
" if (depth > minDepth + epsilon && depth < maxDepth - epsilon)\n"
" if (gl_FragDepth > minDepth + epsilon &&\n"
" gl_FragDepth < maxDepth - epsilon)\n"
" {\n"
" // Write out depth so this frag will be peeled later:\n"
" gl_FragData[2].xy = vec2(-depth, depth);\n"
" gl_FragData[2].xy = vec2(-gl_FragDepth, gl_FragDepth);\n"
" return;\n"
" }\n"
"\n"
......@@ -172,8 +173,8 @@ bool vtkDualDepthPeelingPass::ReplaceShaderValues(std::string &,
" // Default outputs (no data/change):\n"
"\n"
" // This fragment is on a current peel:\n"
" if (depth >= minDepth - epsilon &&\n"
" depth <= minDepth + epsilon)\n"
" if (gl_FragDepth >= minDepth - epsilon &&\n"
" gl_FragDepth <= minDepth + epsilon)\n"
" { // Front peel:\n"
" // Clear the back color:\n"
" gl_FragData[0] = vec4(0.);\n"
......@@ -187,14 +188,12 @@ bool vtkDualDepthPeelingPass::ReplaceShaderValues(std::string &,
" gl_FragData[1].rgb = front.a * frag.a * frag.rgb + front.rgb;\n"
" // Write out (1-alpha):\n"
" gl_FragData[1].a = 1. - (front.a * (1. - frag.a));\n"
" return;\n"
" }\n"
" else // (depth == maxDepth)\n"
" else // (gl_FragDepth == maxDepth)\n"
" { // Back peel:\n"
" // Dump premultiplied fragment, it will be blended later:\n"
" frag.rgb *= frag.a;\n"
" gl_FragData[0] = frag;\n"
" return;\n"
" }\n"
);
break;
......@@ -205,14 +204,13 @@ bool vtkDualDepthPeelingPass::ReplaceShaderValues(std::string &,
"uniform sampler2D lastDepthPeel;\n");
vtkShaderProgram::Substitute(
fragmentShader, "//VTK::DepthPeeling::PreColor",
"float depth = gl_FragCoord.z;\n"
" ivec2 pixelCoord = ivec2(gl_FragCoord.xy);\n"
" vec2 minMaxDepth = texelFetch(lastDepthPeel, pixelCoord, 0).xy;\n"
" float minDepth = -minMaxDepth.x;\n"
" float maxDepth = minMaxDepth.y;\n"
"\n"
" // Discard all fragments outside of the last set of peels:\n"
" if (depth < minDepth || depth > maxDepth)\n"
" if (gl_FragDepth < minDepth || gl_FragDepth > maxDepth)\n"
" {\n"
" discard;\n"
" }\n"
......
......@@ -1335,14 +1335,15 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderCoincidentOffset(
vtkShaderProgram::Substitute(FSSource,
"//VTK::UniformFlow::Impl",
"float cscale = length(vec2(dFdx(gl_FragCoord.z),dFdy(gl_FragCoord.z)));\n"
" gl_FragDepth = gl_FragCoord.z + cfactor*cscale + 0.000016*coffset;\n"
" //VTK::UniformFlow::Impl\n" // for other replacements
);
vtkShaderProgram::Substitute(FSSource, "//VTK::Depth::Impl",
"gl_FragDepth = gl_FragCoord.z + cfactor*cscale + 0.000016*coffset;\n");
}
else
{
vtkShaderProgram::Substitute(FSSource,
"//VTK::Coincident::Impl",
"//VTK::Depth::Impl",
"gl_FragDepth = gl_FragCoord.z + 0.000016*coffset;\n"
);
}
......@@ -1350,6 +1351,16 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderCoincidentOffset(
}
}
void vtkOpenGLPolyDataMapper::ReplaceShaderDepth(
std::map<vtkShader::Type, vtkShader *> shaders,
vtkRenderer *, vtkActor *)
{
std::string FSSource = shaders[vtkShader::Fragment]->GetSource();
vtkShaderProgram::Substitute(FSSource,"//VTK::Depth::Impl",
"gl_FragDepth = gl_FragCoord.z;");
shaders[vtkShader::Fragment]->SetSource(FSSource);
}
void vtkOpenGLPolyDataMapper::ReplaceShaderValues(
std::map<vtkShader::Type, vtkShader *> shaders,
vtkRenderer *ren, vtkActor *actor)
......@@ -1364,6 +1375,7 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderValues(
this->ReplaceShaderPrimID(shaders, ren, actor);
this->ReplaceShaderPositionVC(shaders, ren, actor);
this->ReplaceShaderCoincidentOffset(shaders, ren, actor);
this->ReplaceShaderDepth(shaders, ren, actor);
//cout << "VS: " << shaders[vtkShader::Vertex]->GetSource() << endl;
//cout << "GS: " << shaders[vtkShader::Geometry]->GetSource() << endl;
......
......@@ -266,6 +266,9 @@ protected:
virtual void ReplaceShaderCoincidentOffset(
std::map<vtkShader::Type, vtkShader *> shaders,
vtkRenderer *ren, vtkActor *act);
virtual void ReplaceShaderDepth(
std::map<vtkShader::Type, vtkShader *> shaders,
vtkRenderer *ren, vtkActor *act);
// Description:
// Set the shader parameters related to the mapper/input data, called by UpdateShader
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment