//============================================================================= // // Project: SharpImage // Module: shader-vmt-phong.frag // Language: OpenGL Shading Language (GLSL) // Author: Dan Mueller // Date: $Date: 2007-10-01 06:48:46 +1000 (Mon, 01 Oct 2007) $ // Revision: $Revision: 27 $ // // Copyright (c) Queensland University of Technology (QUT) 2007. // All rights reserved. // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the copyright notices for more information. // //============================================================================= uniform sampler3D sam3Tex0; // Sampler for transfer function uniform sampler3D sam3Tex1; // Sampler for value image uniform sampler3D sam3Tex2; // Sampler for gradient image uniform sampler3D sam3Tex3; // Sampler for tags image uniform float fSamplingRate; // Current sampling rate uniform float fNormalOffset; // Offset for normal calculataions uniform float fFactor1; // Enhancement factor uniform float fFactor2; // Enhancement factor uniform float fFactor3; // Enhancement factor // Adjust the alpha value for the current sampling rate float adjustAlphaForSamplingRate( float a ) { return 1.0 - pow( 1.0 - a, 1.0 / fSamplingRate ); } // Compute the gradient using central differences vec4 gradientFromCentralDifferences( ) { vec4 gradient = vec4( 0.0 ); for ( int i=0; i<3; i++ ) { vec3 pos3L = vec3( gl_TexCoord[1] ); pos3L[i] -= fNormalOffset; vec3 pos3R = vec3( gl_TexCoord[1] ); pos3R[i] += fNormalOffset; float valL = texture3D( sam3Tex1, pos3L ).a; float valR = texture3D( sam3Tex1, pos3R ).a; gradient[i] = (valL - valR) / 2.0; } return gradient; } // Compute the normal dot viewing vector float computeNdotV( vec4 vec4N ) { vec4 vec4V = vec4( 0.0, 0.0, -1.0, 0.0 ); vec4V = vec4V * gl_ModelViewMatrix; vec4V = vec4( vec4V.x, vec4V.y, -vec4V.z, 0.0 ); return dot( vec4N, normalize(vec4V) ); } // Compute the silhouette enhancement float enhanceSilhouette( vec4 vec4N ) { if (fFactor1 <= 0.0) return 0.0; return pow( 1.0 - abs( computeNdotV(vec4N) ), fFactor1 ); } // Compute the boundary enhancement float enhanceBoundary( float value ) { if (fFactor1 <= 0.0) return 1.0; return pow( value, fFactor1 ); } // Apply the Phong lighting model vec4 phong( vec4 vec4N, gl_LightSourceParameters light ) { // Compute light/view vector vec4 vec4L = vec4( 0.0, 0.0, -1.0, 0.0 ); vec4L *= gl_ModelViewMatrix; vec4L = normalize( vec4(vec4L.x, vec4L.y, -vec4L.z, 0.0) ); // Compute terms float fLdotN = dot( vec4L, vec4N ); vec4 vec4R = normalize( (2.0 * fLdotN * vec4N) - vec4L ); float fRdotL = abs( dot(vec4R, vec4L) ); // Compute contributions vec4 vec4A = light.ambient; vec4 vec4D = light.diffuse * abs( fLdotN ); vec4 vec4S = light.specular * pow( fRdotL, light.spotExponent ); // Add and return return (vec4A + vec4D + vec4S); } void main() { // Interpolate images float value = vec4( texture3D(sam3Tex1, gl_TexCoord[1]) ).a; float grad = vec4( texture3D(sam3Tex2, gl_TexCoord[2]) ).a; float tags = vec4( texture3D(sam3Tex3, gl_TexCoord[3]) ).a; // Interpolate transfer function const float fNumLayers = 4.0; vec3 pos3TfAll = vec3( value, 1.0-grad, 0.0 ); vec3 pos3TfTag1 = vec3( value, 1.0-grad, 1.0/(fNumLayers-1.0) ); vec3 pos3TfTag2 = vec3( value, 1.0-grad, 2.0/(fNumLayers-1.0) ); //vec3 pos3TfTag3 = vec3( value, 1.0-grad, 3.0/(fNumLayers-1.0) ); //vec3 pos3TfTag4 = vec3( value, 1.0-grad, 4.0/(fNumLayers-1.0) ); vec4 val4TfAll = texture3D( sam3Tex0, pos3TfAll ); vec4 val4TfTag1 = texture3D( sam3Tex0, pos3TfTag1 ); vec4 val4TfTag2 = texture3D( sam3Tex0, pos3TfTag2 ); //vec4 val4TfTag3 = texture3D( sam3Tex0, pos3TfTag3 ); //vec4 val4TfTag4 = texture3D( sam3Tex0, pos3TfTag4 ); // Adjust alpha for sampling rate val4TfAll.a = adjustAlphaForSamplingRate( val4TfAll.a ); val4TfTag1.a = adjustAlphaForSamplingRate( val4TfTag1.a ); val4TfTag2.a = adjustAlphaForSamplingRate( val4TfTag2.a ); //val4TfTag3.a = adjustAlphaForSamplingRate( val4TfTag3.a ); //val4TfTag4.a = adjustAlphaForSamplingRate( val4TfTag4.a ); // Mix tags bool light; bool enhance; vec4 val4Mix; if (val4TfAll.a == 0 && tags > 0.5) { // Tag 2 val4Mix = val4TfTag2; enhance=true; light=true; if (val4TfTag2.a <= 0.0) discard; } else if (val4TfAll.a == 0 && tags > 0.25) { // Tag 1 val4Mix = val4TfTag1; enhance=true; light=true; if (val4TfTag1.a <= 0.0) discard; } else { // All val4Mix = val4TfAll; enhance=true; light=true; if (val4TfAll.a <= 0.0) discard; } // Compute the normal vec4 vec4G = gradientFromCentralDifferences( ); vec4 vec4N = normalize( vec4G ); // Apply enhancements vec4 black = vec4( 0.0, 0.0, 0.0, 1.0 ); float silhouette = enhanceSilhouette( vec4N ); if ( enhance && silhouette > fFactor3 ) { val4Mix = mix( black, val4Mix, fFactor2 ); val4Mix.a *= silhouette; } // Apply lighting if (light) gl_FragColor = val4Mix * phong( vec4N, gl_LightSource[0] ); else gl_FragColor = val4Mix; }