/**************************************************************************** * MeshLab o o * * An extendible mesh processor o o * * _ O _ * * Copyright(C) 2005, 2009 \/)\/ * * Visual Computing Lab /\/| * * ISTI - Italian National Research Council | * * \ * * All rights reserved. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * * for more details. * * * ****************************************************************************/ // #version 110 // #extension all : enable #pragma optimize(on) #ifndef EXPE_EWA_HINT #define EXPE_EWA_HINT 0 #endif #ifndef EXPE_DEPTH_INTERPOLATION #define EXPE_DEPTH_INTERPOLATION 0 #endif //-------------------------------------------------------------------------------- // shared variables //-------------------------------------------------------------------------------- // custom vertex attributes //attribute float radius; #ifdef CLIPPED_SPLAT attribute vec3 secondNormal; varying vec4 clipLine; #endif // standard uniforms uniform float expeRadiusScale; uniform float expePreComputeRadius; uniform float expeDepthOffset; // varying varying vec4 covmat; varying vec3 fragNormal; varying vec3 fragNoverCdotN; varying vec3 fragCenter; varying float scaleSquaredDistance; #ifdef EXPE_ATI_WORKAROUND varying vec4 fragCenterAndRadius; #endif #ifdef EXPE_DEPTH_CORRECTION varying float depthOffset; #endif uniform vec2 halfVp; uniform float oneOverEwaRadius; #ifdef EXPE_BACKFACE_SHADING #undef EXPE_EARLY_BACK_FACE_CULLING //#define EXPE_EWA_HINT 2 #endif //-------------------------------------------------------------------------------- // Visibility Splatting // Vertex Shader //-------------------------------------------------------------------------------- #ifdef __VisibilityVP__ varying vec2 scaledFragCenter2d; void VisibilityVP(void) { vec3 normal = normalize(gl_NormalMatrix * gl_Normal); // Point in eye space vec4 ePos = gl_ModelViewMatrix * gl_Vertex; float dotpn = dot(normal.xyz,ePos.xyz); vec4 oPos; #ifdef EXPE_EARLY_BACK_FACE_CULLING // back_face culling oPos = vec4(0,0,1,0); if(dotpn<0.) { #endif float radius = gl_MultiTexCoord2.x * expeRadiusScale; vec4 pointSize; pointSize.x = radius * expePreComputeRadius / ePos.z; gl_PointSize = max(1.0, pointSize.x); scaleSquaredDistance = 1.0 / (radius * radius); //fragNormal = normal; fragCenter = ePos.xyz; fragNoverCdotN = normal/dot(ePos.xyz,normal); #ifndef EXPE_DEPTH_CORRECTION ePos.xyz += normalize(ePos.xyz) * expeDepthOffset * radius; #else //ePos.xyz += normalize(ePos.xyz) * expeDepthOffset * radius; depthOffset = expeDepthOffset * radius; #endif oPos = gl_ProjectionMatrix * ePos; #if (EXPE_EWA_HINT>0) scaledFragCenter2d = 0.5*((oPos.xy/oPos.w)+1.0)*halfVp*oneOverEwaRadius; #endif #ifdef EXPE_ATI_WORKAROUND fragCenterAndRadius.xyz = (oPos.xyz/oPos.w) + 1.0; fragCenterAndRadius.xy = fragCenterAndRadius.xy*halfVp; fragCenterAndRadius.z = fragCenterAndRadius.z*0.5; fragCenterAndRadius.w = pointSize.x; #endif #ifndef EXPE_EARLY_BACK_FACE_CULLING oPos.w = oPos.w * ( (dotpn<0.0) ? 1.0 : 0.0); #else } #endif gl_Position = oPos; } #endif //-------------------------------------------------------------------------------- // Visibility Splatting // Fragment Shader //-------------------------------------------------------------------------------- #ifdef __VisibilityFP__ varying vec2 scaledFragCenter2d; uniform vec3 rayCastParameter1; uniform vec3 rayCastParameter2; uniform vec2 depthParameterCast; void VisibilityFP(void) { #ifdef EXPE_ATI_WORKAROUND vec3 fragCoord; fragCoord.xy = fragCenterAndRadius.xy + (gl_TexCoord[0].st-0.5) * fragCenterAndRadius.w; fragCoord.z = fragCenterAndRadius.z; #else vec3 fragCoord = gl_FragCoord.xyz; #endif // compute q in object space vec3 qOne = rayCastParameter1 * fragCoord + rayCastParameter2; // MAD float oneOverDepth = dot(qOne,-fragNoverCdotN); // DP3 float depth = (1.0/oneOverDepth); // RCP vec3 diff = fragCenter + qOne * depth; // MAD float r2 = dot(diff,diff); // DP3 #if (EXPE_EWA_HINT>0) vec2 d2 = oneOverEwaRadius*gl_FragCoord.xy - scaledFragCenter2d; // MAD float r2d = dot(d2,d2); // DP3 gl_FragColor = vec4(min(r2d,r2*scaleSquaredDistance)); #else gl_FragColor = vec4(r2*scaleSquaredDistance); #endif #ifdef EXPE_DEPTH_CORRECTION oneOverDepth = 1.0/(-depth+depthOffset); gl_FragDepth = depthParameterCast.x * oneOverDepth + depthParameterCast.y; // MAD #endif } #endif #ifdef __AttributeVP__ varying vec2 scaledFragCenter2d; void AttributeVP(void) { // transform normal vec3 normal = normalize(gl_NormalMatrix * gl_Normal); // Point in eye space vec4 ePos = gl_ModelViewMatrix * gl_Vertex; float dotpn = dot(normal.xyz,ePos.xyz); vec4 oPos; #ifdef EXPE_EARLY_BACK_FACE_CULLING // back_face culling oPos = vec4(0,0,1,0); if(dotpn<0.) { #endif #ifdef EXPE_BACKFACE_SHADING if(dotpn>0.) { dotpn = -dotpn; normal = -normal; } #endif float radius = gl_MultiTexCoord2.x * expeRadiusScale * 1.05; vec4 pointSize; pointSize.x = radius * expePreComputeRadius / ePos.z; #if (EXPE_EWA_HINT>0) gl_PointSize = max(2.0, pointSize.x); #else gl_PointSize = max(1.0, pointSize.x); #endif scaleSquaredDistance = 1. / (radius * radius); ///********* uncommented fragNormal.... //fragNormal = normal; fragCenter = ePos.xyz; fragNoverCdotN = normal/dot(ePos.xyz,normal); // Output color #ifdef EXPE_DEFERRED_SHADING fragNormal.xyz = normal.xyz; gl_FrontColor = gl_Color; #else // Output color #ifdef EXPE_LIGHTING gl_FrontColor = expeLighting(gl_Color, ePos.xyz, normal.xyz, 1.); #else gl_FrontColor = meshlabLighting(gl_Color, ePos.xyz, normal.xyz); #endif #endif oPos = gl_ModelViewProjectionMatrix * gl_Vertex; #ifdef EXPE_ATI_WORKAROUND fragCenterAndRadius.xyz = (oPos.xyz/oPos.w) + 1.0; fragCenterAndRadius.xy = fragCenterAndRadius.xy*halfVp; fragCenterAndRadius.z = fragCenterAndRadius.z*0.5; fragCenterAndRadius.w = pointSize.x; #endif #if (EXPE_EWA_HINT>0) scaledFragCenter2d = ((oPos.xy/oPos.w)+1.0)*halfVp*oneOverEwaRadius; #endif #ifndef EXPE_EARLY_BACK_FACE_CULLING oPos.w = oPos.w * (dotpn<0. ? 1.0 : 0.0); #else } #endif gl_Position = oPos; } #endif //-------------------------------------------------------------------------------- // EWA Splatting // Fragment Shader //-------------------------------------------------------------------------------- #ifdef __AttributeFP__ // this sampler is only used by this fragment shader varying vec2 scaledFragCenter2d; uniform vec3 rayCastParameter1; uniform vec3 rayCastParameter2; uniform vec2 depthParameterCast; // uniform sampler1D Kernel1dMap; void AttributeFP(void) { #ifdef EXPE_ATI_WORKAROUND vec3 fragCoord; fragCoord.xy = fragCenterAndRadius.xy + (gl_TexCoord[0].st-0.5) * fragCenterAndRadius.w; fragCoord.z = fragCenterAndRadius.z; #else vec3 fragCoord = gl_FragCoord.xyz; #endif #if 1 vec3 qOne = rayCastParameter1 * fragCoord + rayCastParameter2; // MAD float oneOverDepth = dot(qOne,fragNoverCdotN); // DP3 float depth = (1.0/oneOverDepth); // RCP vec3 diff = fragCenter - qOne * depth; // MAD float r2 = dot(diff,diff); // DP3 #if (EXPE_EWA_HINT>0) vec2 d2 = oneOverEwaRadius*gl_FragCoord.xy - scaledFragCenter2d; // MAD float r2d = dot(d2,d2); // DP3 // float weight = texture1D(Kernel1dMap, min(r2d,r2*scaleSquaredDistance)).a; // MUL + MIN + TEX float weight = min(r2d,r2*scaleSquaredDistance); weight = clamp(1.-weight,0,1); weight = weight*weight; #else //float weight = texture1D(Kernel1dMap, r2*scaleSquaredDistance).a; // MUL + TEX float weight = clamp(1.-r2*scaleSquaredDistance,0.0,1.0); weight = weight*weight; #endif weight *= 0.1; // limits overflow #ifdef EXPE_DEPTH_CORRECTION gl_FragDepth = depthParameterCast.x * oneOverDepth + depthParameterCast.y; // MAD #endif #ifdef EXPE_DEFERRED_SHADING gl_FragData[0].rgb = gl_Color.rgb; // MOV gl_FragData[1].xyz = fragNormal.xyz; // MOV gl_FragData[1].w = weight; // MOV gl_FragData[0].w = weight; #if EXPE_DEPTH_INTERPOLATION==2 // linear space gl_FragData[1].z = -depth; // MOV #elif EXPE_DEPTH_INTERPOLATION==1 // window space #ifdef EXPE_DEPTH_CORRECTION gl_FragData[1].z = gl_FragDepth; #else gl_FragData[1].z = fragCoord.z; #endif #endif #else gl_FragColor.rgb = gl_Color.rgb; // MOV gl_FragColor.w = weight; #endif #endif } #endif