346 lines
10 KiB
GLSL
346 lines
10 KiB
GLSL
/****************************************************************************
|
|
* 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
|