mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-20 03:16:10 +00:00
Found a problem with sdf shader. A part of the shader has been disabled with comments.
This commit is contained in:
parent
0726ceaf3c
commit
6d905f85ff
@ -16,7 +16,6 @@ using namespace vcg;
|
||||
#define PI 3.14159265358979323846264;
|
||||
#define USEVBO_BY_DEFAULT false
|
||||
|
||||
#define MACOS
|
||||
|
||||
SdfGpuPlugin::SdfGpuPlugin()
|
||||
: mPeelingTextureSize(256)
|
||||
@ -194,7 +193,6 @@ bool SdfGpuPlugin::applyFilter(QAction *filter, MeshDocument &md, RichParameterS
|
||||
TraceRay(peel, (*vi), md.mm());
|
||||
cb(100*((float)tracedRays/(float)unifDirVec.size()), "Tracing rays...");
|
||||
++tracedRays;
|
||||
Log(0, "traced rays: %i ", tracedRays );
|
||||
}
|
||||
|
||||
//read back the result texture and store result in the mesh
|
||||
@ -223,7 +221,7 @@ bool SdfGpuPlugin::initGL(MeshModel& mm)
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glEnable(GL_NORMALIZE);
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
glClearColor(0,0,0,0);
|
||||
glClearColor(1,0,0,0);
|
||||
glClearDepth(1.0);
|
||||
|
||||
GLenum err = glewInit();
|
||||
@ -263,6 +261,13 @@ bool SdfGpuPlugin::initGL(MeshModel& mm)
|
||||
}
|
||||
|
||||
//INIT FBOs AND TEXs
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
mFboArray[i] = new FramebufferObject();
|
||||
}
|
||||
|
||||
mFboResult = new FramebufferObject();
|
||||
|
||||
unsigned int maxTexSize;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, reinterpret_cast<GLint*>(&maxTexSize) );
|
||||
Log(0, "QUERY HARDWARE FOR: MAX TEX SIZE: %i ", maxTexSize );
|
||||
@ -279,66 +284,38 @@ bool SdfGpuPlugin::initGL(MeshModel& mm)
|
||||
Log(0, "Mesh has %i vertices\n", numVertices );
|
||||
Log(0, "Result texture is %i X %i = %i", mResTextureDim, mResTextureDim, mResTextureDim*mResTextureDim);
|
||||
|
||||
mVertexCoordsTexture = new FloatTexture2D( TextureFormat( GL_TEXTURE_2D, mResTextureDim, mResTextureDim, GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT ), TextureParams( GL_LINEAR/*GL_NEAREST*/, /*GL_NEAREST*/GL_LINEAR ) );
|
||||
mVertexNormalsTexture = new FloatTexture2D( TextureFormat( GL_TEXTURE_2D, mResTextureDim, mResTextureDim, GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT ), TextureParams( /*GL_NEAREST*/GL_LINEAR, /*GL_NEAREST*/GL_LINEAR ) );
|
||||
mVertexCoordsTexture = new FloatTexture2D( TextureFormat( GL_TEXTURE_2D, mResTextureDim, mResTextureDim, GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT ), TextureParams( GL_NEAREST, GL_NEAREST ) );
|
||||
mVertexNormalsTexture = new FloatTexture2D( TextureFormat( GL_TEXTURE_2D, mResTextureDim, mResTextureDim, GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT ), TextureParams( GL_NEAREST, GL_NEAREST ) );
|
||||
|
||||
mResultTexture = new FloatTexture2D( TextureFormat( GL_TEXTURE_2D, mResTextureDim, mResTextureDim, GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT ), TextureParams( GL_NEAREST, GL_NEAREST ) );
|
||||
|
||||
// FloatTexture2D* df = new FloatTexture2D( TextureFormat( GL_TEXTURE_2D, mResTextureDim, mResTextureDim, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_FLOAT ),
|
||||
// TextureParams( GL_NEAREST, GL_NEAREST, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE ) );
|
||||
|
||||
mResultTexture = new FloatTexture2D( TextureFormat( GL_TEXTURE_2D, mResTextureDim, mResTextureDim, GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT ), TextureParams( GL_LINEAR/*GL_NEAREST*/, GL_LINEAR/*GL_NEAREST*/ ) );
|
||||
|
||||
#ifdef MACOS
|
||||
mResultTextureDepth = new FloatTexture2D(TextureFormat( GL_TEXTURE_2D, mResTextureDim, mResTextureDim, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_FLOAT ),
|
||||
TextureParams( /*GL_NEAREST*/GL_LINEAR, /*GL_NEAREST*/GL_LINEAR) );
|
||||
#endif
|
||||
mFboResult = new FramebufferObject();
|
||||
mFboResult->attachTexture( mResultTexture->format().target(), mResultTexture->id(), GL_COLOR_ATTACHMENT0_EXT );
|
||||
#ifdef MACOS
|
||||
mFboResult->attachTexture(mResultTextureDepth->format().target(),mResultTextureDepth->id(),GL_DEPTH_ATTACHMENT_EXT );
|
||||
#endif
|
||||
assert(mFboResult->isValid());
|
||||
|
||||
checkGLError::qDebug("Error during mFboResult ");
|
||||
|
||||
|
||||
//clear first time
|
||||
mFboResult->bind();
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
mFboResult->unbind();
|
||||
|
||||
//We use 3 FBOs to avoid z-fighting in sdf and obscurance calculation, see TraceRays function for details
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
mDepthTextureArray[i] = new FloatTexture2D( TextureFormat( GL_TEXTURE_2D, mPeelingTextureSize, mPeelingTextureSize, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_FLOAT ),
|
||||
TextureParams( GL_NEAREST, GL_NEAREST, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE ) );
|
||||
|
||||
mFboArray[i] = new FramebufferObject();
|
||||
mFboArray[i]->attachTexture( mDepthTextureArray[i]->format().target(), mDepthTextureArray[i]->id(), GL_DEPTH_ATTACHMENT );
|
||||
|
||||
mFboArray[i]->bind();
|
||||
|
||||
|
||||
mDepthTextureArray[i] = new FloatTexture2D(TextureFormat( GL_TEXTURE_2D, mPeelingTextureSize, mPeelingTextureSize, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_FLOAT ),
|
||||
TextureParams( /*GL_NEAREST*/GL_LINEAR, /*GL_NEAREST*/GL_LINEAR) );
|
||||
|
||||
#ifdef MACOS
|
||||
mColorTextureArray[i] = new FloatTexture2D( TextureFormat( GL_TEXTURE_2D, mPeelingTextureSize, mPeelingTextureSize, GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT ), TextureParams( GL_LINEAR/*GL_NEAREST*/, /*GL_NEAREST*/GL_LINEAR ) );
|
||||
|
||||
mColorTextureArray[i]->bind();
|
||||
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,
|
||||
GL_TEXTURE_2D, mColorTextureArray[i]->id(),0);
|
||||
|
||||
#endif
|
||||
mDepthTextureArray[i]->bind();
|
||||
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,
|
||||
GL_TEXTURE_2D, mDepthTextureArray[i]->id(),0);
|
||||
|
||||
|
||||
|
||||
#ifndef MACOS
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
#endif
|
||||
|
||||
assert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT && "mFboArray error");
|
||||
|
||||
mFboArray[i]->unbind();
|
||||
|
||||
#ifndef MACOS
|
||||
glDrawBuffer(GL_BACK);
|
||||
glReadBuffer(GL_BACK);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//Depth peeling shader used for both sdf and obscurance
|
||||
@ -386,10 +363,10 @@ bool SdfGpuPlugin::initGL(MeshModel& mm)
|
||||
mObscuranceProgram->addUniform("maxDist"); //mesh BB diagonal
|
||||
mObscuranceProgram->disable();
|
||||
|
||||
assert(mFboResult->isValid() && "Error during init");
|
||||
assert(mFboArray[0]->isValid() && "Error during init");
|
||||
assert(mFboArray[1]->isValid() && "Error during init");
|
||||
assert(mFboArray[2]->isValid() && "Error during init");
|
||||
assert(mFboResult->isValid());
|
||||
assert(mFboArray[0]->isValid());
|
||||
assert(mFboArray[1]->isValid());
|
||||
assert(mFboArray[2]->isValid());
|
||||
|
||||
|
||||
//If required from the user, we use VBO to speed up mesh rendering
|
||||
@ -472,33 +449,16 @@ void SdfGpuPlugin::releaseGL(MeshModel &m)
|
||||
|
||||
void SdfGpuPlugin::fillFrameBuffer(bool front, MeshModel* mm)
|
||||
{
|
||||
#ifndef MACOS
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
#else
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
#endif
|
||||
checkGLError::qDebug("Error during fillFrameBuffer 1");
|
||||
glEnable(GL_CULL_FACE);
|
||||
checkGLError::qDebug("Error during fillFrameBuffer 2");
|
||||
glCullFace((front)?GL_BACK:GL_FRONT);
|
||||
checkGLError::qDebug("Error during fillFrameBuffer 3");
|
||||
#ifndef MACOS
|
||||
//the most recent GPUs can do double speed Z-only rendering
|
||||
//(also alpha test must be turned off, depth replace and texkill must not be used in fragment shader)
|
||||
glColorMask(0, 0, 0, 0);
|
||||
|
||||
#endif
|
||||
checkGLError::qDebug("Error during fillFrameBuffer 4");
|
||||
mm->glw.DrawFill<GLW::NMNone, GLW::CMNone, GLW::TMNone>();
|
||||
checkGLError::qDebug("Error during fillFrameBuffer 5");
|
||||
#ifndef MACOS
|
||||
glColorMask(1, 1, 1, 1);
|
||||
#endif
|
||||
checkGLError::qDebug("Error during fillFrameBuffer 6");
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
checkGLError::qDebug("Error during fillFrameBuffer 7");
|
||||
|
||||
|
||||
}
|
||||
|
||||
void SdfGpuPlugin::setupMesh(MeshDocument& md, ONPRIMITIVE onPrimitive )
|
||||
@ -556,21 +516,17 @@ void SdfGpuPlugin::setCamera(Point3f camDir, Box3f &meshBBox)
|
||||
void SdfGpuPlugin::useDepthPeelingShader(FramebufferObject* fbo)
|
||||
{
|
||||
glUseProgram(mDeepthPeelingProgram->id());
|
||||
checkGLError::qDebug("Error during useDepthPeelingShader 1 ");
|
||||
mDeepthPeelingProgram->setUniform1f("tolerance", mTolerance);
|
||||
checkGLError::qDebug("Error during useDepthPeelingShader 2 ");
|
||||
mDeepthPeelingProgram->setUniform2f("oneOverBufSize", 1.0f/mPeelingTextureSize, 1.0f/mPeelingTextureSize);
|
||||
checkGLError::qDebug("Error during useDepthPeelingShader 3 ");
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
checkGLError::qDebug("Error during useDepthPeelingShader 4 ");
|
||||
glBindTexture(GL_TEXTURE_2D, fbo->getAttachedId(GL_DEPTH_ATTACHMENT));
|
||||
checkGLError::qDebug("Error during useDepthPeelingShader 5 ");
|
||||
mDeepthPeelingProgram->setUniform1i("textureLastDepth",0);
|
||||
checkGLError::qDebug("Error during useDepthPeelingShader 6 ");
|
||||
}
|
||||
|
||||
void SdfGpuPlugin::calculateSdfHW(FramebufferObject* fboFront, FramebufferObject* fboBack, FramebufferObject* fboPrevBack, const vcg::Point3f& cameraDir)
|
||||
{
|
||||
mFboResult->bind();
|
||||
glViewport(0, 0, mResTextureDim, mResTextureDim);
|
||||
GLfloat mv_pr_Matrix_f[16]; // modelview-projection matrix
|
||||
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, mv_pr_Matrix_f);
|
||||
@ -585,6 +541,14 @@ void SdfGpuPlugin::calculateSdfHW(FramebufferObject* fboFront, FramebufferObject
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
glEnable (GL_BLEND);
|
||||
glBlendFunc (GL_ONE, GL_ONE);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
|
||||
|
||||
glUseProgram(mSDFProgram->id());
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
@ -623,6 +587,7 @@ void SdfGpuPlugin::calculateSdfHW(FramebufferObject* fboFront, FramebufferObject
|
||||
vcg::Invert(mvprINV);
|
||||
mSDFProgram->setUniformMatrix4fv( "mvprMatrixINV", mvprINV.V(), 1, GL_TRUE );
|
||||
|
||||
|
||||
// Set texture Size
|
||||
mSDFProgram->setUniform1f("texSize", mPeelingTextureSize);
|
||||
|
||||
@ -650,21 +615,6 @@ void SdfGpuPlugin::calculateSdfHW(FramebufferObject* fboFront, FramebufferObject
|
||||
else
|
||||
mSDFProgram->setUniform1i("removeOutliers",0);
|
||||
|
||||
mFboResult->bind();
|
||||
glViewport(0, 0, mResTextureDim, mResTextureDim);
|
||||
#ifndef MACOS
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
#endif
|
||||
checkGLError::qDebug("error after glDrawBuffer");
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
#ifndef MACOS
|
||||
glDepthMask(GL_FALSE);
|
||||
#endif
|
||||
|
||||
glEnable (GL_BLEND);
|
||||
glBlendFunc (GL_ONE, GL_ONE);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
|
||||
// Screen-aligned Quad
|
||||
glBegin(GL_QUADS);
|
||||
glVertex3f(-1.0f, -1.0f, 0.0f); //L-L
|
||||
@ -673,14 +623,9 @@ void SdfGpuPlugin::calculateSdfHW(FramebufferObject* fboFront, FramebufferObject
|
||||
glVertex3f(-1.0f, 1.0f, 0.0f); //U-L
|
||||
glEnd();
|
||||
|
||||
|
||||
assert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT && "mFboResult error while drawing");
|
||||
|
||||
mFboResult->unbind();
|
||||
#ifndef MACOS
|
||||
glDepthMask(GL_TRUE);
|
||||
#endif
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
}
|
||||
@ -709,6 +654,9 @@ void SdfGpuPlugin::applySdfHW(MeshModel &m, float numberOfRays)
|
||||
|
||||
void SdfGpuPlugin::calculateObscurance(FramebufferObject* fboFront, FramebufferObject* fboBack, FramebufferObject* nextBack, const vcg::Point3f& cameraDir, float bbDiag)
|
||||
{
|
||||
mFboResult->bind();
|
||||
glViewport(0, 0, mResTextureDim, mResTextureDim);
|
||||
|
||||
GLfloat mv_pr_Matrix_f[16]; // modelview-projection matrix
|
||||
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, mv_pr_Matrix_f);
|
||||
@ -723,7 +671,17 @@ void SdfGpuPlugin::calculateObscurance(FramebufferObject* fboFront, FramebufferO
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glEnable (GL_BLEND);
|
||||
glBlendFunc (GL_ONE, GL_ONE);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
|
||||
|
||||
glUseProgram(mObscuranceProgram->id());
|
||||
assert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)==GL_FRAMEBUFFER_COMPLETE_EXT && "before draw");
|
||||
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, fboFront->getAttachedId(GL_DEPTH_ATTACHMENT));
|
||||
@ -771,22 +729,6 @@ void SdfGpuPlugin::calculateObscurance(FramebufferObject* fboFront, FramebufferO
|
||||
else
|
||||
mObscuranceProgram->setUniform1i("firstRendering",0);
|
||||
|
||||
mFboResult->bind();
|
||||
glViewport(0, 0, mResTextureDim, mResTextureDim);
|
||||
|
||||
|
||||
#ifndef MACOS
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
#endif
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
#ifndef MACOS
|
||||
glDepthMask(GL_FALSE);
|
||||
#endif
|
||||
glEnable (GL_BLEND);
|
||||
glBlendFunc (GL_ONE, GL_ONE);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
|
||||
// Screen-aligned Quad
|
||||
glBegin(GL_QUADS);
|
||||
glVertex3f(-1.0f, -1.0f, 0.0f); //L-L
|
||||
@ -795,13 +737,12 @@ void SdfGpuPlugin::calculateObscurance(FramebufferObject* fboFront, FramebufferO
|
||||
glVertex3f(-1.0f, 1.0f, 0.0f); //U-L
|
||||
glEnd();
|
||||
|
||||
assert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT && "mFboResult error while drawing");
|
||||
assert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)==GL_FRAMEBUFFER_COMPLETE_EXT && "after draw");
|
||||
|
||||
mFboResult->unbind();
|
||||
#ifndef MACOS
|
||||
glDepthMask(GL_TRUE);
|
||||
#endif
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
@ -879,13 +820,11 @@ void SdfGpuPlugin::TraceRay(int peelingIteration,const Point3f& dir, MeshModel*
|
||||
int prevBack = (j+1)%3;
|
||||
int prevFront = (j==0)? 2 : (j-1);
|
||||
calculateSdfHW( mFboArray[prevFront], mFboArray[j], mFboArray[prevBack],dir );// front back prevback
|
||||
checkGLError::qDebug("Error during calculateSdfHW 1 ");
|
||||
}
|
||||
else
|
||||
{ //we have first and second depth layers, so we can use "second-depth shadow mapping" to avoid z-fighting
|
||||
assert(j!=0);
|
||||
calculateSdfHW( mFboArray[j-1], mFboArray[j], NULL, dir );// front back prevback
|
||||
checkGLError::qDebug("Error during calculateSdfHW 2 ");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -894,10 +833,10 @@ void SdfGpuPlugin::TraceRay(int peelingIteration,const Point3f& dir, MeshModel*
|
||||
j = (j+1) % 3;
|
||||
}
|
||||
|
||||
assert(mFboResult->isValid()&& "Error during depth peeling" );
|
||||
assert(mFboArray[0]->isValid() && "Error during depth peeling");
|
||||
assert(mFboArray[1]->isValid() && "Error during depth peeling");
|
||||
assert(mFboArray[2]->isValid() && "Error during depth peeling");
|
||||
assert(mFboResult->isValid());
|
||||
assert(mFboArray[0]->isValid());
|
||||
assert(mFboArray[1]->isValid());
|
||||
assert(mFboArray[2]->isValid());
|
||||
|
||||
checkGLError::qDebug("Error during depth peeling");
|
||||
}
|
||||
|
||||
@ -1,293 +1,292 @@
|
||||
/****************************************************************************
|
||||
* 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. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
Author: Andrea Baldacci baldacci85@hotmail.it
|
||||
*/
|
||||
|
||||
#define EXTRA_RAYS 40
|
||||
|
||||
uniform sampler2D vTexture;
|
||||
uniform sampler2D nTexture;
|
||||
uniform sampler2D depthTextureFront;
|
||||
uniform sampler2D depthTextureBack;
|
||||
uniform sampler2D depthTexturePrevBack;
|
||||
uniform vec3 viewDirection;
|
||||
uniform mat4 mvprMatrix;
|
||||
uniform float viewpSize;
|
||||
uniform float texSize;
|
||||
uniform float minCos;
|
||||
uniform int firstRendering;
|
||||
uniform mat4 mvprMatrixINV;
|
||||
uniform int removeFalse;
|
||||
uniform int removeOutliers;
|
||||
uniform vec3 coneRays[EXTRA_RAYS];
|
||||
float _vals[EXTRA_RAYS];
|
||||
|
||||
|
||||
|
||||
vec4 project(vec4 coords)
|
||||
{
|
||||
coords = mvprMatrix * coords; // clip space [-1 .. 1]
|
||||
return vec4(coords.xyz * 0.5+0.5, coords.w);
|
||||
}
|
||||
|
||||
//Sort values
|
||||
void InsertionSort(int n)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
float app;
|
||||
|
||||
for (i = 1; i < n; i++)
|
||||
{
|
||||
app = _vals[i];
|
||||
|
||||
for (j = i - 1; (j >= 0) && (_vals[j] > app); j--)
|
||||
_vals[j+1] = _vals[j];
|
||||
|
||||
_vals[j + 1] = app;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Recostruct normal at the point of intersection and check for false intersection.
|
||||
For each ray we check the normal at the point of intersection,
|
||||
and ignore intersections where the normal at the intersection
|
||||
points is in the same direction as the point-of-origin
|
||||
(the same direction is defined as an angle difference lessthan 90)
|
||||
*/
|
||||
bool isFalseIntersection(vec3 P, vec3 objSpaceNormal)
|
||||
{
|
||||
|
||||
//Recostructing the normal at intersection point
|
||||
|
||||
vec2 coordX1 = vec2( P.x - 1.0/texSize, P.y );
|
||||
vec2 coordX2 = vec2( P.x + 1.0/texSize, P.y );
|
||||
vec2 coordY1 = vec2( P.x , P.y - 1.0/texSize);
|
||||
vec2 coordY2 = vec2( P.x , P.y + 1.0/texSize);
|
||||
|
||||
if(coordX1.x < 0.0 ) coordX1.x = 0.0;
|
||||
if(coordX2.x > 1.0 ) coordX2.x = 1.0;
|
||||
if(coordY1.y < 0.0 ) coordY1.y = 0.0;
|
||||
if(coordY2.y > 1.0 ) coordY2.y = 1.0;
|
||||
|
||||
float sampleX1 = texture2D(depthTextureBack, coordX1).r;
|
||||
float sampleX2 = texture2D(depthTextureBack, coordX2).r;
|
||||
float sampleY1 = texture2D(depthTextureBack, coordY1).r;
|
||||
float sampleY2 = texture2D(depthTextureBack, coordY2).r;
|
||||
|
||||
vec3 x1 = vec3( coordX1.x, coordX1.y, sampleX1 );
|
||||
vec3 x2 = vec3( coordX2.x, coordX2.y, sampleX2 );
|
||||
vec3 y1 = vec3( coordY1.x, coordY1.y, sampleY1 );
|
||||
vec3 y2 = vec3( coordY2.x, coordY2.y, sampleY2 );
|
||||
|
||||
//
|
||||
vec3 intersectionPointNormal = normalize(cross((x2-x1),(y2-y1)));// * 2.0 -0.5;
|
||||
|
||||
vec4 tmpNormal = vec4( intersectionPointNormal, 0.0 );
|
||||
|
||||
//from texture space to object space
|
||||
tmpNormal = mvprMatrixINV * tmpNormal ;
|
||||
|
||||
intersectionPointNormal = tmpNormal.xyz;
|
||||
|
||||
// intersectionPointNormal = normalize(intersectionPointNormal);
|
||||
|
||||
//if angles dont differ at least 90 degrees reject intersection
|
||||
if(dot(-intersectionPointNormal, objSpaceNormal) > 0.0) return true;
|
||||
|
||||
}
|
||||
|
||||
//Based on the paper "Dynamic Parallax Occlusion Mapping with Approximate Soft Shadows" Natalya Tatarchuk ATI Research, Inc.
|
||||
float TraceRay(vec2 P, vec3 dir, float sourceHeight)
|
||||
{
|
||||
|
||||
int LinearSearchSteps = 256;
|
||||
|
||||
float StepSize = 1.0/256.0;
|
||||
float Depth = sourceHeight; //Initial depth is that of front vertex
|
||||
int StepIndex = 0;
|
||||
|
||||
float CurrD = 0.0;
|
||||
float PrevD = sourceHeight;
|
||||
|
||||
vec2 p1 = vec2(0.0);
|
||||
vec2 p2 = vec2(0.0);
|
||||
|
||||
// Compute max displacement:
|
||||
vec2 V = dir.xy*1.41422;
|
||||
|
||||
//
|
||||
float cotan = sqrt(length(dir)*length(dir) - dir.z*dir.z) / (dir.z);
|
||||
|
||||
float coordStepSize = StepSize * cotan;
|
||||
|
||||
vec2 coordOffset = vec2(0.0,0.0);
|
||||
|
||||
|
||||
while(StepIndex < LinearSearchSteps)
|
||||
{
|
||||
Depth += StepSize;
|
||||
coordOffset += V.xy * coordStepSize;
|
||||
|
||||
vec2 tc = P + coordOffset;
|
||||
|
||||
CurrD = texture2D( depthTextureBack, tc).r;
|
||||
|
||||
if(CurrD < Depth)
|
||||
{
|
||||
p1 = vec2(Depth, CurrD);
|
||||
p2 = vec2(Depth - StepSize, PrevD);
|
||||
StepIndex = LinearSearchSteps;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//no intersections found, the height map values along the edges is below one.
|
||||
//In this case the parallax vector near the edges crosses the texture boundary without hitting any features
|
||||
if(tc.x < 0.0 || tc.x > 1.0 || tc.y < 0.0 || tc.y > 1.0) return 0.0;
|
||||
|
||||
StepIndex++;
|
||||
PrevD = CurrD;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Linear approximation using current and last step
|
||||
float d2 = p2.x - p2.y;
|
||||
float d1 = p1.x - p1.y;
|
||||
|
||||
float fDenominator = d2 - d1;
|
||||
|
||||
if(fDenominator == 0.0)
|
||||
{
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
//y=m0*x+b0 and y=m1*x+b1 intersection
|
||||
float destHeight = (p1.x * d2 - p2.x * d1) / fDenominator;
|
||||
|
||||
float sdf = sqrt((destHeight - sourceHeight)* (destHeight - sourceHeight) + length(coordOffset)*length(coordOffset));
|
||||
|
||||
return sdf;
|
||||
|
||||
}
|
||||
|
||||
float calculateSdf(vec3 P, vec3 objSpacePos, vec3 objSpaceNormal)
|
||||
{
|
||||
|
||||
float sdf = 0.0;
|
||||
|
||||
float zFront = texture2D(depthTextureFront, P.xy).r;
|
||||
float zBack = texture2D(depthTextureBack, P.xy).r;
|
||||
float zPrevBack = texture2D(depthTexturePrevBack, P.xy).r;
|
||||
|
||||
|
||||
|
||||
|
||||
//first hit of the ray on the mesh. We compare vertex's depth to the next depth layer (back faces),
|
||||
// this technique is called second-depth shadow mapping
|
||||
if(firstRendering==1)
|
||||
{
|
||||
if ( P.z <= zBack )
|
||||
{
|
||||
sdf = max(0.0,(zBack-zFront) ) ;
|
||||
|
||||
}
|
||||
}//We have are interested in vertices belonging to the "front" depth layer
|
||||
//, so we check vertex's depth against the previous layer and the next one
|
||||
else if ( zPrevBack <= P.z && P.z <= zBack )
|
||||
sdf = max(0.0,(zBack-zFront) ) ;
|
||||
|
||||
if(removeFalse==1)
|
||||
if( isFalseIntersection(P,objSpaceNormal) ) return 0.0;
|
||||
|
||||
if( sdf != 0.0 && removeOutliers == 1)
|
||||
{
|
||||
|
||||
|
||||
int i = 0;
|
||||
|
||||
for( ; i < EXTRA_RAYS ; i++ )
|
||||
{
|
||||
_vals[i] = TraceRay( P.xy, coneRays[i] , zFront );
|
||||
}
|
||||
|
||||
|
||||
|
||||
InsertionSort(EXTRA_RAYS);
|
||||
|
||||
|
||||
for( i = 0; i < EXTRA_RAYS; i++ )
|
||||
{
|
||||
if(_vals[i] != 0.0 ) break;
|
||||
|
||||
}
|
||||
|
||||
float valids = float(EXTRA_RAYS - i);
|
||||
int median = int(valids / 2.0);
|
||||
int percentile = int(valids / 10.0);
|
||||
|
||||
|
||||
if( sdf < _vals[i+median-4*percentile ] || sdf > _vals[i+median+4*percentile] ) return 0.0;
|
||||
|
||||
// sdf = _vals[i+median];
|
||||
|
||||
}
|
||||
|
||||
|
||||
return sdf;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
|
||||
float sdf = 0.0;
|
||||
|
||||
vec2 coords = vec2(gl_FragCoord.xy/viewpSize);
|
||||
|
||||
vec4 V = texture2D(vTexture, coords);
|
||||
vec4 N = texture2D(nTexture, coords);
|
||||
|
||||
N = normalize(N);
|
||||
|
||||
vec4 P = project(V); //* (viewpSize/texSize);
|
||||
|
||||
|
||||
float cosAngle = max(0.0,dot(N.xyz, viewDirection));
|
||||
|
||||
|
||||
if( cosAngle >= minCos )
|
||||
{
|
||||
|
||||
sdf = calculateSdf( P.xyz , V.xyz, N.xyz ) * cosAngle;
|
||||
}
|
||||
|
||||
|
||||
if(sdf == 0.0) cosAngle = 0.0;
|
||||
|
||||
|
||||
|
||||
gl_FragColor = vec4(sdf, cosAngle , 0.0, 1.0);
|
||||
}
|
||||
/****************************************************************************
|
||||
* 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. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
Author: Andrea Baldacci baldacci85@hotmail.it
|
||||
*/
|
||||
|
||||
#define EXTRA_RAYS 40
|
||||
|
||||
uniform sampler2D vTexture;
|
||||
uniform sampler2D nTexture;
|
||||
uniform sampler2D depthTextureFront;
|
||||
uniform sampler2D depthTextureBack;
|
||||
uniform sampler2D depthTexturePrevBack;
|
||||
uniform vec3 viewDirection;
|
||||
uniform mat4 mvprMatrix;
|
||||
uniform float viewpSize;
|
||||
uniform float texSize;
|
||||
uniform float minCos;
|
||||
uniform int firstRendering;
|
||||
uniform mat4 mvprMatrixINV;
|
||||
uniform int removeFalse;
|
||||
uniform int removeOutliers;
|
||||
uniform vec3 coneRays[EXTRA_RAYS];
|
||||
float _vals[EXTRA_RAYS];
|
||||
|
||||
|
||||
|
||||
vec4 project(vec4 coords)
|
||||
{
|
||||
coords = mvprMatrix * coords; // clip space [-1 .. 1]
|
||||
return vec4(coords.xyz * 0.5+0.5, coords.w);
|
||||
}
|
||||
|
||||
//Sort values
|
||||
void InsertionSort(int n)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
float app;
|
||||
|
||||
for (i = 1; i < n; i++)
|
||||
{
|
||||
app = _vals[i];
|
||||
|
||||
for (j = i - 1; (j >= 0) && (_vals[j] > app); j--)
|
||||
_vals[j+1] = _vals[j];
|
||||
|
||||
_vals[j + 1] = app;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Recostruct normal at the point of intersection and check for false intersection.
|
||||
For each ray we check the normal at the point of intersection,
|
||||
and ignore intersections where the normal at the intersection
|
||||
points is in the same direction as the point-of-origin
|
||||
(the same direction is defined as an angle difference lessthan 90)
|
||||
*/
|
||||
bool isFalseIntersection(vec3 P, vec3 objSpaceNormal)
|
||||
{
|
||||
|
||||
//Recostructing the normal at intersection point
|
||||
|
||||
vec2 coordX1 = vec2( P.x - 1.0/texSize, P.y );
|
||||
vec2 coordX2 = vec2( P.x + 1.0/texSize, P.y );
|
||||
vec2 coordY1 = vec2( P.x , P.y - 1.0/texSize);
|
||||
vec2 coordY2 = vec2( P.x , P.y + 1.0/texSize);
|
||||
|
||||
if(coordX1.x < 0.0 ) coordX1.x = 0.0;
|
||||
if(coordX2.x > 1.0 ) coordX2.x = 1.0;
|
||||
if(coordY1.y < 0.0 ) coordY1.y = 0.0;
|
||||
if(coordY2.y > 1.0 ) coordY2.y = 1.0;
|
||||
|
||||
float sampleX1 = texture2D(depthTextureBack, coordX1).r;
|
||||
float sampleX2 = texture2D(depthTextureBack, coordX2).r;
|
||||
float sampleY1 = texture2D(depthTextureBack, coordY1).r;
|
||||
float sampleY2 = texture2D(depthTextureBack, coordY2).r;
|
||||
|
||||
vec3 x1 = vec3( coordX1.x, coordX1.y, sampleX1 );
|
||||
vec3 x2 = vec3( coordX2.x, coordX2.y, sampleX2 );
|
||||
vec3 y1 = vec3( coordY1.x, coordY1.y, sampleY1 );
|
||||
vec3 y2 = vec3( coordY2.x, coordY2.y, sampleY2 );
|
||||
|
||||
//
|
||||
vec3 intersectionPointNormal = normalize(cross((x2-x1),(y2-y1)));// * 2.0 -0.5;
|
||||
|
||||
vec4 tmpNormal = vec4( intersectionPointNormal, 0.0 );
|
||||
|
||||
//from texture space to object space
|
||||
tmpNormal = mvprMatrixINV * tmpNormal ;
|
||||
|
||||
intersectionPointNormal = tmpNormal.xyz;
|
||||
|
||||
// intersectionPointNormal = normalize(intersectionPointNormal);
|
||||
|
||||
//if angles dont differ at least 90 degrees reject intersection
|
||||
if(dot(intersectionPointNormal, objSpaceNormal) > 0.0) return true;
|
||||
|
||||
}
|
||||
|
||||
//Based on the paper "Dynamic Parallax Occlusion Mapping with Approximate Soft Shadows" Natalya Tatarchuk ATI Research, Inc.
|
||||
float TraceRay(vec2 P, vec3 dir, float sourceHeight)
|
||||
{
|
||||
|
||||
int LinearSearchSteps = 256;
|
||||
|
||||
float StepSize = 1.0/256.0;
|
||||
float Depth = sourceHeight; //Initial depth is that of front vertex
|
||||
int StepIndex = 0;
|
||||
|
||||
float CurrD = 0.0;
|
||||
float PrevD = sourceHeight;
|
||||
|
||||
vec2 p1 = vec2(0.0);
|
||||
vec2 p2 = vec2(0.0);
|
||||
|
||||
// Compute max displacement:
|
||||
vec2 V = dir.xy*1.41422;
|
||||
|
||||
//
|
||||
float cotan = sqrt(length(dir)*length(dir) - dir.z*dir.z) / (dir.z);
|
||||
|
||||
float coordStepSize = StepSize * cotan;
|
||||
|
||||
vec2 coordOffset = vec2(0.0,0.0);
|
||||
|
||||
|
||||
while(StepIndex < LinearSearchSteps)
|
||||
{
|
||||
Depth += StepSize;
|
||||
coordOffset += V.xy * coordStepSize;
|
||||
|
||||
vec2 tc = P + coordOffset;
|
||||
|
||||
CurrD = texture2D( depthTextureBack, tc).r;
|
||||
|
||||
if(CurrD < Depth)
|
||||
{
|
||||
p1 = vec2(Depth, CurrD);
|
||||
p2 = vec2(Depth - StepSize, PrevD);
|
||||
StepIndex = LinearSearchSteps;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//no intersections found, the height map values along the edges is below one.
|
||||
//In this case the parallax vector near the edges crosses the texture boundary without hitting any features
|
||||
if(tc.x < 0.0 || tc.x > 1.0 || tc.y < 0.0 || tc.y > 1.0) return 0.0;
|
||||
|
||||
StepIndex++;
|
||||
PrevD = CurrD;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Linear approximation using current and last step
|
||||
float d2 = p2.x - p2.y;
|
||||
float d1 = p1.x - p1.y;
|
||||
|
||||
float fDenominator = d2 - d1;
|
||||
|
||||
if(fDenominator == 0.0)
|
||||
{
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
//y=m0*x+b0 and y=m1*x+b1 intersection
|
||||
float destHeight = (p1.x * d2 - p2.x * d1) / fDenominator;
|
||||
|
||||
float sdf = sqrt((destHeight - sourceHeight)* (destHeight - sourceHeight) + length(coordOffset)*length(coordOffset));
|
||||
|
||||
return sdf;
|
||||
|
||||
}
|
||||
|
||||
float calculateSdf(vec3 P, vec3 objSpacePos, vec3 objSpaceNormal)
|
||||
{
|
||||
|
||||
float sdf = 0.0;
|
||||
|
||||
float zFront = texture2D(depthTextureFront, P.xy).r;
|
||||
float zBack = texture2D(depthTextureBack, P.xy).r;
|
||||
float zPrevBack = texture2D(depthTexturePrevBack, P.xy).r;
|
||||
|
||||
|
||||
//first hit of the ray on the mesh. We compare vertex's depth to the next depth layer (back faces),
|
||||
// this technique is called second-depth shadow mapping
|
||||
if(firstRendering==1)
|
||||
{
|
||||
if ( P.z <= zBack )
|
||||
{
|
||||
sdf = max(0.0,(zBack-zFront) ) ;
|
||||
|
||||
}
|
||||
}//We have are interested in vertices belonging to the "front" depth layer
|
||||
//, so we check vertex's depth against the previous layer and the next one
|
||||
else if ( zPrevBack <= P.z && P.z <= zBack )
|
||||
sdf = max(0.0,(zBack-zFront) ) ;
|
||||
|
||||
// if(removeFalse==1)
|
||||
// if( isFalseIntersection(P,objSpaceNormal) ) return 0.0;
|
||||
|
||||
/* if( sdf != 0.0 && removeOutliers == 1)
|
||||
{
|
||||
|
||||
|
||||
int i = 0;
|
||||
|
||||
for( ; i < EXTRA_RAYS ; i++ )
|
||||
{
|
||||
_vals[i] = TraceRay( P.xy, coneRays[i] , zFront );
|
||||
}
|
||||
|
||||
|
||||
|
||||
InsertionSort(EXTRA_RAYS);
|
||||
|
||||
|
||||
for( i = 0; i < EXTRA_RAYS; i++ )
|
||||
{
|
||||
if(_vals[i] != 0.0 ) break;
|
||||
|
||||
}
|
||||
|
||||
float valids = float(EXTRA_RAYS - i);
|
||||
int median = int(valids / 2.0);
|
||||
int percentile = int(valids / 10.0);
|
||||
|
||||
|
||||
if( sdf < _vals[i+median-4*percentile ] || sdf > _vals[i+median+4*percentile] ) return 0.0;
|
||||
|
||||
// sdf = _vals[i+median];
|
||||
|
||||
|
||||
}*/
|
||||
|
||||
|
||||
return sdf;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
|
||||
float sdf = 0.0;
|
||||
|
||||
vec2 coords = vec2(gl_FragCoord.xy/viewpSize);
|
||||
|
||||
vec4 V = texture2D(vTexture, coords);
|
||||
vec4 N = texture2D(nTexture, coords);
|
||||
|
||||
N = normalize(N);
|
||||
|
||||
vec4 P = project(V); //* (viewpSize/texSize);
|
||||
|
||||
|
||||
float cosAngle = max(0.0,dot(N.xyz, viewDirection));
|
||||
|
||||
|
||||
if( cosAngle >= minCos )
|
||||
{
|
||||
|
||||
sdf = calculateSdf( P.xyz , V.xyz, N.xyz ) * cosAngle;
|
||||
}
|
||||
|
||||
|
||||
if(sdf == 0.0) cosAngle = 0.0;
|
||||
|
||||
|
||||
|
||||
gl_FragColor = vec4(sdf, cosAngle , 0.0, 1.0);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user