You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
345 lines
10 KiB
345 lines
10 KiB
/**************************************************************************** |
|
* 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
|
|
|