Discussion:
[Opensg-users] QuadTreeTerrain rendering problem
Christian Bar
2014-07-16 13:06:33 UTC
Permalink
Hello! I am experiencing a problem with the QuadTreeTerrain rendering.
With the test project everything works, but when I tried to implement it
inside my project the terrain shows just some little parts of it (also with
wrong triangles, this one seems like an indexing problem).
After lot of trials, it seems to me that the quadtree algorithm does not
work properly when the terrain is not in the origin of the world
coordinates. In my project, the camera is fixed in the origin and the world
moves by the inverse of the camera "virtual" position (there is a transform
with the camera inverse position on top of the scene geometries).
To demonstrate the problem I created a small program by mixing the
"testQuadTreeTerrain" and the "11withoutSSM_complete" tests.
By pressing '1' the camera will be put in the origin and the terrain in a
convenient position to be shown; by pressing '2' the terrain will be in the
origin and the camera in the inverse of the case '1' camera position.
As you can see, in case '2' the terrain is correctly rendered, in case '1'
not.
You can use the button 'q,w,e,a,s,d' to change the position the and
'r,t,y,f,g,h' for rotations, in order to see how the terrain rendering
changes.
I also tried to use the 'terrain->setEyePoint()' and
'terrain->setEyePointValid()', but it works (again) only if the terrain is
in the origin.

What can I do to solve my problem? Thank you!
Christian Bar

Now the test code:
"
#include <OSGGLUT.h>
#include <OSGConfig.h>
#include <OSGSimpleGeometry.h>
#include <OSGGLUTWindow.h>
#include <OSGSolidBackground.h>
#include <OSGDirectionalLight.h>
#include <OSGPerspectiveCamera.h>
#include <OSGTransform.h>
#include <OSGRenderAction.h>
#include <OSGViewport.h>
#include <OSGGradientBackground.h>
#include <OSGTextureBackground.h>
#include <OSGTextureObjChunk.h>
#include <OSGImage.h>
#include <OSGImageForeground.h>
#include <OSGFileGrabForeground.h>
#include "OSGQuadTreeTerrain.h"
#include "OSGImageFileHandler.h"
#include "OSGChunkMaterial.h"
#include "OSGMaterialChunk.h"
#include "OSGTextureObjChunk.h"
#include "OSGTextureEnvChunk.h"

#define ROT 0.1f;
#define TRASL 1.f;

bool updateCameraPos=false;
float tx=-15.f;
float ty=15.f;
float tz=-30.f;
float rx=3.1415f/2.f;
float ry=0.f;
float rz=0.f;
OSG::TransformRecPtr terrainTransCore;
OSG::NodeRecPtr scene;
OSG::QuadTreeTerrainUnrecPtr terrain;
OSG::PerspectiveCameraRecPtr camera;
OSG::TransformRecPtr camTrans;
OSG::ViewportRecPtr viewport;
OSG::WindowRecPtr window;
OSG::NodeRecPtr camBeacon, lightBeacon, lightNode;
OSG::RenderActionRefPtr renderAction;

int setupGLUT(int *argc, char *argv[]);

OSG::MaterialTransitPtr makeTexture (const char* texname)
{
OSG::ImageUnrecPtr image = OSG::ImageFileHandler::the()->read(texname);

SLOG << "Create ChunkMaterial" << std::endl;

OSG::ChunkMaterialUnrecPtr texMatPtr = OSG::ChunkMaterial
::create();
OSG::TextureObjChunkUnrecPtr texChunkPtr =
OSG::TextureObjChunk::create();
OSG::TextureEnvChunkUnrecPtr texEnvChunkPtr =
OSG::TextureEnvChunk::create();
OSG::MaterialChunkUnrecPtr phongChunk = OSG::MaterialChunk
::create();

phongChunk->setDiffuse (OSG::Color4f(1.0f, 1.0f, 1.0f, 1.0f));
phongChunk->setAmbient (OSG::Color4f(0.1f, 0.1f, 0.1f, 1.0f));
phongChunk->setSpecular(OSG::Color4f(0.2f, 0.2f, 0.2f, 1.0f));
phongChunk->setShininess(6);

texChunkPtr->setImage ( image);
texChunkPtr->setWrapS ( GL_CLAMP );
texChunkPtr->setWrapT ( GL_CLAMP );
texChunkPtr->setWrapR ( GL_CLAMP );

texChunkPtr->setMinFilter ( GL_LINEAR );
texChunkPtr->setMagFilter ( GL_LINEAR );

texEnvChunkPtr->setEnvMode(GL_MODULATE);

texMatPtr->addChunk(texChunkPtr, 0);
texMatPtr->addChunk(texEnvChunkPtr, 0);
texMatPtr->addChunk(phongChunk);

return OSG::MaterialTransitPtr(texMatPtr);
}

OSG::NodeTransitPtr createScenegraph(void)
{
OSG::NodeRecPtr torus = OSG::makeTorus(1,5,8,16);

// create the terrain
OSG::ImageUnrecPtr height;
OSG::MaterialUnrecPtr mat;
mat = makeTexture("Default_TexMap.png");
height = OSG::ImageFileHandler::the()->read("Default_HeightMap.png");
terrain = OSG::QuadTreeTerrain::create();
terrain->setHeightData(height);
terrain->setMaterial(mat);
terrain->setVertexSpacing(30.0f/256.0f);
terrain->setHeightScale (5.0f);
terrain->setGeoMorphing(true);
terrain->setDetail (25.0f);
OSG::NodeRecPtr scenet = OSG::Node::create();
scenet->setCore(terrain);

terrainTransCore = OSG::Transform::create();
OSG::NodeRecPtr terrTrans = OSG::makeNodeFor(terrainTransCore);
torus->addChild(terrTrans);
OSG::Matrix terrainMat;
terrainMat.setTransform(OSG::Vec3f( 0, 0, 0),
OSG::Quaternion(OSG::Vec3f(0,1,0),0));
terrainTransCore->setMatrix(terrainMat);
terrTrans->addChild(scenet);

//create transformations & beacons for cameras & light
camBeacon = OSG::Node::create();
lightBeacon = OSG::Node::create();

OSG::TransformRecPtr lightTrans;
camTrans = OSG::Transform::create();
lightTrans = OSG::Transform::create();
OSG::Matrix camMat, lightM;
camMat.setIdentity();
lightM.setIdentity();
camTrans->setMatrix(camMat);
lightTrans->setMatrix(lightM);

camBeacon->setCore(camTrans);
lightBeacon->setCore(lightTrans );

//create the light source
OSG::DirectionalLightRecPtr dLight = OSG::DirectionalLight::create();
dLight->setDirection(OSG::Vec3f(0,1,2));
dLight->setDiffuse(OSG::Color4f(1,1,1,1));
dLight->setAmbient(OSG::Color4f(0.2f,0.2f,0.2f,1.f));
dLight->setSpecular(OSG::Color4f(1,1,1,1));
dLight->setBeacon(lightBeacon);

lightNode = OSG::Node::create();
lightNode->setCore(dLight);
lightNode->addChild(torus);

// now create the root and add all children
OSG::NodeRecPtr root = OSG::Node::create();
root->setCore(OSG::Group::create());
root->addChild(lightNode);
root->addChild(camBeacon);
root->addChild(lightBeacon);

return OSG::NodeTransitPtr(root);
}

int main(int argc, char **argv)
{
OSG::preloadSharedObject("OSGFileIO");
OSG::preloadSharedObject("OSGImageFileIO");
OSG::osgInit(argc,argv);

int winid = setupGLUT(&argc, argv);
scene = createScenegraph();

//create camera, background, viewport, render action, window
camera = OSG::PerspectiveCamera::create();
camera->setBeacon(camBeacon);
camera->setFov(OSG::osgDegree2Rad(90.0f));
camera->setNear(0.1f);
camera->setFar(100.f);

OSG::GradientBackgroundRecPtr bkg = OSG::GradientBackground::create();
bkg->addLine(OSG::Color3f(0.5f,0.5f,0.5f),0);
bkg->addLine(OSG::Color3f(1,1,1),1);

viewport = OSG::Viewport::create();
viewport->setCamera(camera);
viewport->setBackground(bkg);
viewport->setRoot(scene);
viewport->setSize(0,0,1,1);

renderAction = OSG::RenderAction::create();
OSG::GLUTWindowRecPtr gwin = OSG::GLUTWindow::create();
gwin->setGlutId(winid);
gwin->setSize(300,300);
window = gwin;
window->addPort(viewport);
window->init();

printf_s("Now moving terrain, camera is in 0,0,0\n");

OSG::commitChanges();

glutMainLoop();
return 0;
}

void reshape(int w, int h)
{
window->resize(w, h);
glutPostRedisplay();
}

void display(void)
{
OSG::commitChanges();

OSG::Matrix mat;
OSG::Quaternion q;
q.setValue(rx,ry,rz);
mat.setTransform(OSG::Vec3f(tx,ty,tz),q);

if(updateCameraPos)
camTrans->setMatrix(mat); // 15 30 15 -1.57
else
terrainTransCore->setMatrix(mat); // -15 15 -30 1.57

window->render(renderAction);
}

void mouse(int button, int state, int x, int y)
{
glutPostRedisplay();
}

void motion(int x, int y)
{
glutPostRedisplay();
}

void keyboard(unsigned char k, int x, int y)
{
switch(k)
{
case 27:
{
terrain = NULL;
terrainTransCore=NULL;
scene = NULL;
window = NULL;
camera = NULL;
viewport = NULL;
camBeacon = NULL;
lightBeacon = NULL;
lightNode = NULL;
renderAction= NULL;
camTrans = NULL;
OSG::osgExit();
exit(1);
}
break;
case 'a':
tx-=TRASL;
break;
case 'd':
tx+=TRASL;
break;
case 'w':
ty+=TRASL;
break;
case 's':
ty-=TRASL;
break;
case 'q':
tz+=TRASL;
break;
case 'e':
tz-=TRASL;
break;

case 'f':
rx-=ROT;
break;
case 'h':
rx+=ROT;
break;
case 't':
ry+=ROT;
break;
case 'g':
ry-=ROT;
break;
case 'r':
rz+=ROT;
break;
case 'y':
rz-=ROT;
break;

case '1': // move the terrain and put the camera in 0,0,0
{
tx=-15.f;
ty=15.f;
tz=-30.f;
rx=3.1415f/2.f;
ry=0.f;
rz=0.f;
updateCameraPos=false;
OSG::Matrix mat; mat.setIdentity();
camTrans->setMatrix(mat);
terrainTransCore->setMatrix(mat);
printf_s("Now moving terrain, camera is in 0,0,0\n");
}
break;

case '2': // move the camera and put the terrain in 0,0,0
{
tx=15.f;
ty=30.f;
tz=15.f;
rx=-3.1415f/2.f;
ry=0.f;
rz=0.f;
updateCameraPos=true;
OSG::Matrix mat; mat.setIdentity();
camTrans->setMatrix(mat);
terrainTransCore->setMatrix(mat);
printf_s("Now moving camera, terrain is in 0,0,0\n");
}
break;

case '0': // reset camera and terrain transformations
{
rx=ry=rz=tx=ty=tz=0.f;
OSG::Matrix mat; mat.setIdentity();
camTrans->setMatrix(mat);
terrainTransCore->setMatrix(mat);
}
break;
}
printf_s("%.1f %.1f %.1f %.1f %.1f %.1f\n", tx,ty,tz,rx,ry,rz);
}

int setupGLUT(int *argc, char *argv[])
{
glutInit(argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);

int winid = glutCreateWindow("QuadTreeTerrain without SSM problem");

glutDisplayFunc(display);
glutMotionFunc(motion);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutIdleFunc(display);

return winid;
}

"
Carsten Neumann
2014-07-17 15:08:23 UTC
Permalink
Hello Christian,
Post by Christian Bar
Hello! I am experiencing a problem with the QuadTreeTerrain rendering.
With the test project everything works, but when I tried to implement it
inside my project the terrain shows just some little parts of it (also
with wrong triangles, this one seems like an indexing problem).
After lot of trials, it seems to me that the quadtree algorithm does not
work properly when the terrain is not in the origin of the world
coordinates.
hmm, possible, it may never have been located anywhere but at the origin.

[snip]
Post by Christian Bar
I also tried to use the 'terrain->setEyePoint()' and
'terrain->setEyePointValid()', but it works (again) only if the terrain
is in the origin.
In which coordinate system did you specify the eye point? For example
was the eye point you set in the terrain's local coordinate system or in
world coordinates?
Post by Christian Bar
What can I do to solve my problem? Thank you!
My guess would be that the camera position (either the one derived from
the active camera or the one set explicitly) are not transformed to
local coordinates. I don't have the code in front of me right now (can
take a look tomorrow), but my hope would be that the eye position is
calculate only in one (or very few) places and only needs to be
multiplied with the inverse transform of the current node.

Cheers,
Carsten
Christian Bar
2014-07-18 14:02:15 UTC
Permalink
Thank you Carsten!

I tried to specify the eye point in local coordinates, in global, or
in random positions, but the result is never the correct one...

I made an update to my little test program, now you can also use and
move the eye point.

You can see what I mean if you:

- start the test program,

- press '1' to set the camera in the origin and the terrain in
(-15,15-30) in order to be seen by the camera

- press '3' to start using the eye point for the terrain

- play with 'j,l,i,k,u,o' to move the eye point and see how the
terrain rendering changes.

The weirdest thing (to me) is that the terrain starts to show all its
patches when the sum of the absolute x,y,z of the eye point exceed
2000~2100...

Best regards,

Christian Bar


Below the code:

"


#include <OSGGLUT.h>
#include <OSGConfig.h>
#include <OSGSimpleGeometry.h>
#include <OSGGLUTWindow.h>
#include <OSGSolidBackground.h>
#include <OSGDirectionalLight.h>
#include <OSGPerspectiveCamera.h>
#include <OSGTransform.h>
#include <OSGRenderAction.h>
#include <OSGViewport.h>
#include <OSGGradientBackground.h>
#include <OSGTextureBackground.h>
#include <OSGTextureObjChunk.h>
#include <OSGImage.h>
#include <OSGImageForeground.h>
#include <OSGFileGrabForeground.h>
#include "OSGQuadTreeTerrain.h"
#include "OSGImageFileHandler.h"
#include "OSGChunkMaterial.h"
#include "OSGMaterialChunk.h"
#include "OSGTextureObjChunk.h"
#include "OSGTextureEnvChunk.h"

#define ROT 0.1f;
#define TRASL 1.f;

bool updateCameraPos=false;
bool eye=false;
float tx=-15.f;
float ty=15.f;
float tz=-30.f;
float rx=3.1415f/2.f;
float ry=0.f;
float rz=0.f;
float tex=0.f,tey=0.f,tez=0.f;
OSG::TransformRecPtr terrainTransCore;
OSG::NodeRecPtr scene;
OSG::QuadTreeTerrainUnrecPtr terrain;
OSG::PerspectiveCameraRecPtr camera;
OSG::TransformRecPtr camTrans;
OSG::ViewportRecPtr viewport;
OSG::WindowRecPtr window;
OSG::NodeRecPtr camBeacon, lightBeacon, lightNode;
OSG::RenderActionRefPtr renderAction;

int setupGLUT(int *argc, char *argv[]);

OSG::MaterialTransitPtr makeTexture (const char* texname)
{
OSG::ImageUnrecPtr image = OSG::ImageFileHandler::the()->read(texname);

SLOG << "Create ChunkMaterial" << std::endl;

OSG::ChunkMaterialUnrecPtr texMatPtr = OSG::ChunkMaterial ::create();
OSG::TextureObjChunkUnrecPtr texChunkPtr = OSG::TextureObjChunk::create();
OSG::TextureEnvChunkUnrecPtr texEnvChunkPtr = OSG::TextureEnvChunk::create();
OSG::MaterialChunkUnrecPtr phongChunk = OSG::MaterialChunk ::create();

phongChunk->setDiffuse (OSG::Color4f(1.0f, 1.0f, 1.0f, 1.0f));
phongChunk->setAmbient (OSG::Color4f(0.1f, 0.1f, 0.1f, 1.0f));
phongChunk->setSpecular(OSG::Color4f(0.2f, 0.2f, 0.2f, 1.0f));
phongChunk->setShininess(6);

texChunkPtr->setImage ( image);
texChunkPtr->setWrapS ( GL_CLAMP );
texChunkPtr->setWrapT ( GL_CLAMP );
texChunkPtr->setWrapR ( GL_CLAMP );

texChunkPtr->setMinFilter ( GL_LINEAR );
texChunkPtr->setMagFilter ( GL_LINEAR );

texEnvChunkPtr->setEnvMode(GL_MODULATE);

texMatPtr->addChunk(texChunkPtr, 0);
texMatPtr->addChunk(texEnvChunkPtr, 0);
texMatPtr->addChunk(phongChunk);

return OSG::MaterialTransitPtr(texMatPtr);
}

OSG::NodeTransitPtr createScenegraph(void)
{
OSG::NodeRecPtr torus = OSG::makeTorus(1,5,8,16);

// create the terrain
OSG::ImageUnrecPtr height;
OSG::MaterialUnrecPtr mat;
mat = makeTexture("Default_TexMap.png");
height = OSG::ImageFileHandler::the()->read("Default_HeightMap.png");
terrain = OSG::QuadTreeTerrain::create();
terrain->setHeightData(height);
terrain->setMaterial(mat);
terrain->setVertexSpacing(30.0f/256.0f);
terrain->setHeightScale (5.0f);
terrain->setGeoMorphing(true);
terrain->setDetail (25.0f);
OSG::NodeRecPtr scenet = OSG::Node::create();
scenet->setCore(terrain);

terrainTransCore = OSG::Transform::create();
OSG::NodeRecPtr terrTrans = OSG::makeNodeFor(terrainTransCore);
torus->addChild(terrTrans);
OSG::Matrix terrainMat;
terrainMat.setTransform(OSG::Vec3f( 0, 0, 0),
OSG::Quaternion(OSG::Vec3f(0,1,0),0));
terrainTransCore->setMatrix(terrainMat);
terrTrans->addChild(scenet);

//create transformations & beacons for cameras & light
camBeacon = OSG::Node::create();
lightBeacon = OSG::Node::create();

OSG::TransformRecPtr lightTrans;
camTrans = OSG::Transform::create();
lightTrans = OSG::Transform::create();
OSG::Matrix camMat, lightM;
camMat.setIdentity();
lightM.setIdentity();
camTrans->setMatrix(camMat);
lightTrans->setMatrix(lightM);

camBeacon->setCore(camTrans);
lightBeacon->setCore(lightTrans );

//create the light source
OSG::DirectionalLightRecPtr dLight = OSG::DirectionalLight::create();
dLight->setDirection(OSG::Vec3f(0,1,2));
dLight->setDiffuse(OSG::Color4f(1,1,1,1));
dLight->setAmbient(OSG::Color4f(0.2f,0.2f,0.2f,1.f));
dLight->setSpecular(OSG::Color4f(1,1,1,1));
dLight->setBeacon(lightBeacon);

lightNode = OSG::Node::create();
lightNode->setCore(dLight);
lightNode->addChild(torus);

// now create the root and add all children
OSG::NodeRecPtr root = OSG::Node::create();
root->setCore(OSG::Group::create());
root->addChild(lightNode);
root->addChild(camBeacon);
root->addChild(lightBeacon);

return OSG::NodeTransitPtr(root);
}

int main(int argc, char **argv)
{
OSG::preloadSharedObject("OSGFileIO");
OSG::preloadSharedObject("OSGImageFileIO");
OSG::osgInit(argc,argv);

int winid = setupGLUT(&argc, argv);
scene = createScenegraph();

//create camera, background, viewport, render action, window
camera = OSG::PerspectiveCamera::create();
camera->setBeacon(camBeacon);
camera->setFov(OSG::osgDegree2Rad(90.0f));
camera->setNear(0.1f);
camera->setFar(100.f);

OSG::GradientBackgroundRecPtr bkg = OSG::GradientBackground::create();
bkg->addLine(OSG::Color3f(0.5f,0.5f,0.5f),0);
bkg->addLine(OSG::Color3f(1,1,1),1);

viewport = OSG::Viewport::create();
viewport->setCamera(camera);
viewport->setBackground(bkg);
viewport->setRoot(scene);
viewport->setSize(0,0,1,1);

renderAction = OSG::RenderAction::create();
OSG::GLUTWindowRecPtr gwin = OSG::GLUTWindow::create();
gwin->setGlutId(winid);
gwin->setSize(300,300);
window = gwin;
window->addPort(viewport);
window->init();

printf_s("Now moving terrain, camera is in 0,0,0\n");

OSG::commitChanges();

glutMainLoop();
return 0;
}

void reshape(int w, int h)
{
window->resize(w, h);
glutPostRedisplay();
}

void display(void)
{
OSG::commitChanges();

OSG::Matrix mat;
OSG::Quaternion q;
q.setValue(rx,ry,rz);
mat.setTransform(OSG::Vec3f(tx,ty,tz),q);

if(updateCameraPos)
camTrans->setMatrix(mat); // 15 30 15 -1.57
else
terrainTransCore->setMatrix(mat); // -15 15 -30 1.57

if(eye)
terrain->setEyePoint(OSG::Pnt3f(tex,tey,tez));
//float e = 100.f;
//terrain->setEyePoint(OSG::Pnt3f(OSG::osgRand()*e-e/2.f,
OSG::osgRand()*e-e/2.f, OSG::osgRand()*e-e/2.f));

window->render(renderAction);
}

void mouse(int button, int state, int x, int y)
{
glutPostRedisplay();
}

void motion(int x, int y)
{
glutPostRedisplay();
}

void keyboard(unsigned char k, int x, int y)
{
switch(k)
{
case 27:
{
terrain = NULL;
terrainTransCore=NULL;
scene = NULL;
window = NULL;
camera = NULL;
viewport = NULL;
camBeacon = NULL;
lightBeacon = NULL;
lightNode = NULL;
renderAction= NULL;
camTrans = NULL;
OSG::osgExit();
exit(1);
}
break;
case 'a':
tx-=TRASL;
break;
case 'd':
tx+=TRASL;
break;
case 'w':
ty+=TRASL;
break;
case 's':
ty-=TRASL;
break;
case 'q':
tz+=TRASL;
break;
case 'e':
tz-=TRASL;
break;

case 'f':
rx-=ROT;
break;
case 'h':
rx+=ROT;
break;
case 't':
ry+=ROT;
break;
case 'g':
ry-=ROT;
break;
case 'r':
rz+=ROT;
break;
case 'y':
rz-=ROT;
break;

case 'j':
tex-=10.f*TRASL;
break;
case 'l':
tex+=10.f*TRASL;
break;
case 'i':
tey+=10.f*TRASL;
break;
case 'k':
tey-=10.f*TRASL;
break;
case 'u':
tez+=10.f*TRASL;
break;
case 'o':
tez-=10.f*TRASL;
break;

case '1': // move the terrain and put the camera in 0,0,0
{
tx=-15.f;
ty=15.f;
tz=-30.f;
rx=3.1415f/2.f;
ry=0.f;
rz=0.f;
updateCameraPos=false;
OSG::Matrix mat; mat.setIdentity();
camTrans->setMatrix(mat);
terrainTransCore->setMatrix(mat);
printf_s("Now moving terrain, camera is in 0,0,0\n");
}
break;

case '2': // move the camera and put the terrain in 0,0,0
{
tx=15.f;
ty=30.f;
tz=15.f;
rx=-3.1415f/2.f;
ry=0.f;
rz=0.f;
updateCameraPos=true;
OSG::Matrix mat; mat.setIdentity();
camTrans->setMatrix(mat);
terrainTransCore->setMatrix(mat);
printf_s("Now moving camera, terrain is in 0,0,0\n");
}
break;

case '3': // use the terrain->setEyePoint() to update the terrain
{
eye=!eye;
if(eye)
{
terrain->setEyePointValid(true);
printf_s("Now moving eye...\n");
}
else
{
terrain->setEyePointValid(false);
printf_s("Now NOT moving eye...\n");
}
tex=0.f;
tey=0.f;
tez=0.f;
}
break;

case '0': // reset camera and terrain transformations
{
rx=ry=rz=tx=ty=tz=0.f;
OSG::Matrix mat; mat.setIdentity();
camTrans->setMatrix(mat);
terrainTransCore->setMatrix(mat);
}
break;
}
printf_s("%.1f %.1f %.1f, %.1f %.1f %.1f, %.1f %.1f %.1f\n",
tx,ty,tz,rx,ry,rz,tex,tey,tez);
}

int setupGLUT(int *argc, char *argv[])
{
glutInit(argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);

int winid = glutCreateWindow("QuadTreeTerrain without SSM problem");

glutDisplayFunc(display);
glutMotionFunc(motion);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutIdleFunc(display);

return winid;
}


"



--------------------------------------------------------------
Post by Christian Bar
Hello! I am experiencing a problem with the QuadTreeTerrain rendering.
With the test project everything works, but when I tried to implement it
inside my project the terrain shows just some little parts of it (also
with wrong triangles, this one seems like an indexing problem).
After lot of trials, it seems to me that the quadtree algorithm does not
work properly when the terrain is not in the origin of the world
coordinates.
hmm, possible, it may never have been located anywhere but at the origin.

[snip]
Post by Christian Bar
I also tried to use the 'terrain->setEyePoint()' and
'terrain->setEyePointValid()', but it works (again) only if the terrain
is in the origin.
In which coordinate system did you specify the eye point? For example
was the eye point you set in the terrain's local coordinate system or in
world coordinates?
Post by Christian Bar
What can I do to solve my problem? Thank you!
My guess would be that the camera position (either the one derived from
the active camera or the one set explicitly) are not transformed to
local coordinates. I don't have the code in front of me right now (can
take a look tomorrow), but my hope would be that the eye position is
calculate only in one (or very few) places and only needs to be
multiplied with the inverse transform of the current node.

Cheers,
Carsten
Carsten Neumann
2014-07-21 12:39:07 UTC
Permalink
Hello Christian,
I tried to specify the eye point in local coordinates, in global, or in random positions, but the result is never the correct one...
I made an update to my little test program, now you can also use and move the eye point.
thanks for the updated program!
The weirdest thing (to me) is that the terrain starts to show all its patches when the sum of the absolute x,y,z of the eye point exceed 2000~2100...
I think/hope that was just a (really weird) coincidence ;)
AFAICS the problem was that the camera frustum was not transformed to
local coordinates, so the culling of terrain parts used the wrong
frustum to test against.
There also was something quite fishy in our Plane::transform()
implementation, the whole thing only started to work after I replaced
that with a text book implementation [1].
I'm attaching a patch that makes your example work for me, could you
give it a try with your real application and let me know if that is
fixed as well? Thanks!

Cheers,
Carsten

[1] I'm not quite sure what the previous code was trying to do and if it
perhaps attempted to be more efficient, but mainly it did not seem to
produce correct results... ;)
Christian Bar
2014-07-22 15:21:37 UTC
Permalink
Thank you Carsten!
The example now also works for me!
BUT... going on with the implementation in my software, I noticed two more
problems:

1) Terrain lighting (and/or normals) is not right, because the terrain
lighting changes as I move the camera (the camera is in the origin and the
world moves by its inverse transform, indeed).

2) The terrain is not correctly rendered in a cluster environment.
In the program I have a WIN32Window (local viewport) and
a MultiDisplayWindow (for cluster visualization).

2a)
In my render loop I usually did things in this order:

MasterApplication::update()
{
changeTheScenegraph();
Thread::getCurrentChangeList()->commitChanges();
MultiDisplayWindow->render();
WIN32Window->render();
Thread::getCurrentChangeList()->clear();
}

If I do this, the result is a wrong rendered terrain: the geometry and the
triangles are not correct. You can see the result by looking at one of the
screenshot I made:
Loading Image...
Loading Image...
Loading Image...


2b)
In the case I change the loop to:

MasterApplication::update()
{
changeTheScenegraph();
MultiDisplayWindow->render();
WIN32Window->render();
Thread::getCurrentChangeList()->commitChangesAndClear();
}

, the terrain is correctly rendered (except for lighting) on the WIN32Window,
but on the MultiDisplayWindow the terrain still looks like in the
screenshots.

Any help would really, really be appreciated :)
Thanks again in advance,
Christian Bar


-------------------------------------------------------------------------------------------------------------------------------------------

Hello Christian,
I tried to specify the eye point in local coordinates, in global, or in
random positions, but the result is never the correct one...
I made an update to my little test program, now you can also use and move
the eye point.

thanks for the updated program!
The weirdest thing (to me) is that the terrain starts to show all its
patches when the sum of the absolute x,y,z of the eye point exceed
2000~2100...

I think/hope that was just a (really weird) coincidence ;)
AFAICS the problem was that the camera frustum was not transformed to
local coordinates, so the culling of terrain parts used the wrong
frustum to test against.
There also was something quite fishy in our Plane::transform()
implementation, the whole thing only started to work after I replaced
that with a text book implementation [1].
I'm attaching a patch that makes your example work for me, could you
give it a try with your real application and let me know if that is
fixed as well? Thanks!

Cheers,
Carsten

[1] I'm not quite sure what the previous code was trying to do and if it
perhaps attempted to be more efficient, but mainly it did not seem to
produce correct results... ;)
Thank you Carsten!
I tried to specify the eye point in local coordinates, in global, or in random positions, but the result is never the correct one...
I made an update to my little test program, now you can also use and move the eye point.
- start the test program,
- press '1' to set the camera in the origin and the terrain in (-15,15-30) in order to be seen by the camera
- press '3' to start using the eye point for the terrain
- play with 'j,l,i,k,u,o' to move the eye point and see how the terrain rendering changes.
The weirdest thing (to me) is that the terrain starts to show all its patches when the sum of the absolute x,y,z of the eye point exceed 2000~2100...
Best regards,
Christian Bar
"
#include <OSGGLUT.h>
#include <OSGConfig.h>
#include <OSGSimpleGeometry.h>
#include <OSGGLUTWindow.h>
#include <OSGSolidBackground.h>
#include <OSGDirectionalLight.h>
#include <OSGPerspectiveCamera.h>
#include <OSGTransform.h>
#include <OSGRenderAction.h>
#include <OSGViewport.h>
#include <OSGGradientBackground.h>
#include <OSGTextureBackground.h>
#include <OSGTextureObjChunk.h>
#include <OSGImage.h>
#include <OSGImageForeground.h>
#include <OSGFileGrabForeground.h>
#include "OSGQuadTreeTerrain.h"
#include "OSGImageFileHandler.h"
#include "OSGChunkMaterial.h"
#include "OSGMaterialChunk.h"
#include "OSGTextureObjChunk.h"
#include "OSGTextureEnvChunk.h"
#define ROT 0.1f;
#define TRASL 1.f;
bool updateCameraPos=false;
bool eye=false;
float tx=-15.f;
float ty=15.f;
float tz=-30.f;
float rx=3.1415f/2.f;
float ry=0.f;
float rz=0.f;
float tex=0.f,tey=0.f,tez=0.f;
OSG::TransformRecPtr terrainTransCore;
OSG::NodeRecPtr scene;
OSG::QuadTreeTerrainUnrecPtr terrain;
OSG::PerspectiveCameraRecPtr camera;
OSG::TransformRecPtr camTrans;
OSG::ViewportRecPtr viewport;
OSG::WindowRecPtr window;
OSG::NodeRecPtr camBeacon, lightBeacon, lightNode;
OSG::RenderActionRefPtr renderAction;
int setupGLUT(int *argc, char *argv[]);
OSG::MaterialTransitPtr makeTexture (const char* texname)
{
OSG::ImageUnrecPtr image = OSG::ImageFileHandler::the()->read(texname);
SLOG << "Create ChunkMaterial" << std::endl;
OSG::ChunkMaterialUnrecPtr texMatPtr = OSG::ChunkMaterial ::create();
OSG::TextureObjChunkUnrecPtr texChunkPtr = OSG::TextureObjChunk::create();
OSG::TextureEnvChunkUnrecPtr texEnvChunkPtr = OSG::TextureEnvChunk::create();
OSG::MaterialChunkUnrecPtr phongChunk = OSG::MaterialChunk ::create();
phongChunk->setDiffuse (OSG::Color4f(1.0f, 1.0f, 1.0f, 1.0f));
phongChunk->setAmbient (OSG::Color4f(0.1f, 0.1f, 0.1f, 1.0f));
phongChunk->setSpecular(OSG::Color4f(0.2f, 0.2f, 0.2f, 1.0f));
phongChunk->setShininess(6);
texChunkPtr->setImage ( image);
texChunkPtr->setWrapS ( GL_CLAMP );
texChunkPtr->setWrapT ( GL_CLAMP );
texChunkPtr->setWrapR ( GL_CLAMP );
texChunkPtr->setMinFilter ( GL_LINEAR );
texChunkPtr->setMagFilter ( GL_LINEAR );
texEnvChunkPtr->setEnvMode(GL_MODULATE);
texMatPtr->addChunk(texChunkPtr, 0);
texMatPtr->addChunk(texEnvChunkPtr, 0);
texMatPtr->addChunk(phongChunk);
return OSG::MaterialTransitPtr(texMatPtr);
}
OSG::NodeTransitPtr createScenegraph(void)
{
OSG::NodeRecPtr torus = OSG::makeTorus(1,5,8,16);
// create the terrain
OSG::ImageUnrecPtr height;
OSG::MaterialUnrecPtr mat;
mat = makeTexture("Default_TexMap.png");
height = OSG::ImageFileHandler::the()->read("Default_HeightMap.png");
terrain = OSG::QuadTreeTerrain::create();
terrain->setHeightData(height);
terrain->setMaterial(mat);
terrain->setVertexSpacing(30.0f/256.0f);
terrain->setHeightScale (5.0f);
terrain->setGeoMorphing(true);
terrain->setDetail (25.0f);
OSG::NodeRecPtr scenet = OSG::Node::create();
scenet->setCore(terrain);
terrainTransCore = OSG::Transform::create();
OSG::NodeRecPtr terrTrans = OSG::makeNodeFor(terrainTransCore);
torus->addChild(terrTrans);
OSG::Matrix terrainMat;
terrainMat.setTransform(OSG::Vec3f( 0, 0, 0), OSG::Quaternion(OSG::Vec3f(0,1,0),0));
terrainTransCore->setMatrix(terrainMat);
terrTrans->addChild(scenet);
//create transformations & beacons for cameras & light
camBeacon = OSG::Node::create();
lightBeacon = OSG::Node::create();
OSG::TransformRecPtr lightTrans;
camTrans = OSG::Transform::create();
lightTrans = OSG::Transform::create();
OSG::Matrix camMat, lightM;
camMat.setIdentity();
lightM.setIdentity();
camTrans->setMatrix(camMat);
lightTrans->setMatrix(lightM);
camBeacon->setCore(camTrans);
lightBeacon->setCore(lightTrans );
//create the light source
OSG::DirectionalLightRecPtr dLight = OSG::DirectionalLight::create();
dLight->setDirection(OSG::Vec3f(0,1,2));
dLight->setDiffuse(OSG::Color4f(1,1,1,1));
dLight->setAmbient(OSG::Color4f(0.2f,0.2f,0.2f,1.f));
dLight->setSpecular(OSG::Color4f(1,1,1,1));
dLight->setBeacon(lightBeacon);
lightNode = OSG::Node::create();
lightNode->setCore(dLight);
lightNode->addChild(torus);
// now create the root and add all children
OSG::NodeRecPtr root = OSG::Node::create();
root->setCore(OSG::Group::create());
root->addChild(lightNode);
root->addChild(camBeacon);
root->addChild(lightBeacon);
return OSG::NodeTransitPtr(root);
}
int main(int argc, char **argv)
{
OSG::preloadSharedObject("OSGFileIO");
OSG::preloadSharedObject("OSGImageFileIO");
OSG::osgInit(argc,argv);
int winid = setupGLUT(&argc, argv);
scene = createScenegraph();
//create camera, background, viewport, render action, window
camera = OSG::PerspectiveCamera::create();
camera->setBeacon(camBeacon);
camera->setFov(OSG::osgDegree2Rad(90.0f));
camera->setNear(0.1f);
camera->setFar(100.f);
OSG::GradientBackgroundRecPtr bkg = OSG::GradientBackground::create();
bkg->addLine(OSG::Color3f(0.5f,0.5f,0.5f),0);
bkg->addLine(OSG::Color3f(1,1,1),1);
viewport = OSG::Viewport::create();
viewport->setCamera(camera);
viewport->setBackground(bkg);
viewport->setRoot(scene);
viewport->setSize(0,0,1,1);
renderAction = OSG::RenderAction::create();
OSG::GLUTWindowRecPtr gwin = OSG::GLUTWindow::create();
gwin->setGlutId(winid);
gwin->setSize(300,300);
window = gwin;
window->addPort(viewport);
window->init();
printf_s("Now moving terrain, camera is in 0,0,0\n");
OSG::commitChanges();
glutMainLoop();
return 0;
}
void reshape(int w, int h)
{
window->resize(w, h);
glutPostRedisplay();
}
void display(void)
{
OSG::commitChanges();
OSG::Matrix mat;
OSG::Quaternion q;
q.setValue(rx,ry,rz);
mat.setTransform(OSG::Vec3f(tx,ty,tz),q);
if(updateCameraPos)
camTrans->setMatrix(mat); // 15 30 15 -1.57
else
terrainTransCore->setMatrix(mat); // -15 15 -30 1.57
if(eye)
terrain->setEyePoint(OSG::Pnt3f(tex,tey,tez));
//float e = 100.f;
//terrain->setEyePoint(OSG::Pnt3f(OSG::osgRand()*e-e/2.f, OSG::osgRand()*e-e/2.f, OSG::osgRand()*e-e/2.f));
window->render(renderAction);
}
void mouse(int button, int state, int x, int y)
{
glutPostRedisplay();
}
void motion(int x, int y)
{
glutPostRedisplay();
}
void keyboard(unsigned char k, int x, int y)
{
switch(k)
{
{
terrain = NULL;
terrainTransCore=NULL;
scene = NULL;
window = NULL;
camera = NULL;
viewport = NULL;
camBeacon = NULL;
lightBeacon = NULL;
lightNode = NULL;
renderAction= NULL;
camTrans = NULL;
OSG::osgExit();
exit(1);
}
break;
tx-=TRASL;
break;
tx+=TRASL;
break;
ty+=TRASL;
break;
ty-=TRASL;
break;
tz+=TRASL;
break;
tz-=TRASL;
break;
rx-=ROT;
break;
rx+=ROT;
break;
ry+=ROT;
break;
ry-=ROT;
break;
rz+=ROT;
break;
rz-=ROT;
break;
tex-=10.f*TRASL;
break;
tex+=10.f*TRASL;
break;
tey+=10.f*TRASL;
break;
tey-=10.f*TRASL;
break;
tez+=10.f*TRASL;
break;
tez-=10.f*TRASL;
break;
case '1': // move the terrain and put the camera in 0,0,0
{
tx=-15.f;
ty=15.f;
tz=-30.f;
rx=3.1415f/2.f;
ry=0.f;
rz=0.f;
updateCameraPos=false;
OSG::Matrix mat; mat.setIdentity();
camTrans->setMatrix(mat);
terrainTransCore->setMatrix(mat);
printf_s("Now moving terrain, camera is in 0,0,0\n");
}
break;
case '2': // move the camera and put the terrain in 0,0,0
{
tx=15.f;
ty=30.f;
tz=15.f;
rx=-3.1415f/2.f;
ry=0.f;
rz=0.f;
updateCameraPos=true;
OSG::Matrix mat; mat.setIdentity();
camTrans->setMatrix(mat);
terrainTransCore->setMatrix(mat);
printf_s("Now moving camera, terrain is in 0,0,0\n");
}
break;
case '3': // use the terrain->setEyePoint() to update the terrain
{
eye=!eye;
if(eye)
{
terrain->setEyePointValid(true);
printf_s("Now moving eye...\n");
}
else
{
terrain->setEyePointValid(false);
printf_s("Now NOT moving eye...\n");
}
tex=0.f;
tey=0.f;
tez=0.f;
}
break;
case '0': // reset camera and terrain transformations
{
rx=ry=rz=tx=ty=tz=0.f;
OSG::Matrix mat; mat.setIdentity();
camTrans->setMatrix(mat);
terrainTransCore->setMatrix(mat);
}
break;
}
printf_s("%.1f %.1f %.1f, %.1f %.1f %.1f, %.1f %.1f %.1f\n", tx,ty,tz,rx,ry,rz,tex,tey,tez);
}
int setupGLUT(int *argc, char *argv[])
{
glutInit(argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
int winid = glutCreateWindow("QuadTreeTerrain without SSM problem");
glutDisplayFunc(display);
glutMotionFunc(motion);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutIdleFunc(display);
return winid;
}
"
--------------------------------------------------------------
Post by Christian Bar
Hello! I am experiencing a problem with the QuadTreeTerrain rendering.
With the test project everything works, but when I tried to implement it
inside my project the terrain shows just some little parts of it (also
with wrong triangles, this one seems like an indexing problem).
After lot of trials, it seems to me that the quadtree algorithm does not
work properly when the terrain is not in the origin of the world
coordinates.
hmm, possible, it may never have been located anywhere but at the origin.
[snip]
Post by Christian Bar
I also tried to use the 'terrain->setEyePoint()' and
'terrain->setEyePointValid()', but it works (again) only if the terrain
is in the origin.
In which coordinate system did you specify the eye point? For example
was the eye point you set in the terrain's local coordinate system or in
world coordinates?
Post by Christian Bar
What can I do to solve my problem? Thank you!
My guess would be that the camera position (either the one derived from
the active camera or the one set explicitly) are not transformed to
local coordinates. I don't have the code in front of me right now (can
take a look tomorrow), but my hope would be that the eye position is
calculate only in one (or very few) places and only needs to be
multiplied with the inverse transform of the current node.
Cheers,
Carsten
Carsten Neumann
2014-07-24 12:59:15 UTC
Permalink
Hello Christian,
Post by Christian Bar
Thank you Carsten!
The example now also works for me!
ok, thanks for testing!
Post by Christian Bar
BUT... going on with the implementation in my software, I noticed two
1) Terrain lighting (and/or normals) is not right, because the terrain
lighting changes as I move the camera (the camera is in the origin and
the world moves by its inverse transform, indeed).
Hmm, does this reproduce with your test program? Note that there the
terrTrans node is below the lightBeacon, so lighting should in fact
change when moving the terrain - because the terrain changes position
relative to the light source.
Anyway, I think the shader was missing a transformation of the light
position from eye space to model space (i.e. multiply with
gl_ModelViewMatrixInverse). Attaching a new patch (contains the changes
from the previous one), and a .zip with the individual commits from my tree.
With that patch the lighting with shaders (setPerPixelLighting(true)) is
practically the same as without, so that seems an improvement to me ;)
Post by Christian Bar
2) The terrain is not correctly rendered in a cluster environment.
In the program I have a WIN32Window (local viewport) and
a MultiDisplayWindow (for cluster visualization).
2a)
MasterApplication::update()
{
changeTheScenegraph();
Thread::getCurrentChangeList()->commitChanges();
MultiDisplayWindow->render();
WIN32Window->render();
Thread::getCurrentChangeList()->clear();
}
Hmm, not sure if that makes any difference, but you can set your local
window as: mdw->setClientWindow(win32win); and it will be rendered
without the explicit call.
Post by Christian Bar
If I do this, the result is a wrong rendered terrain: the geometry and
the triangles are not correct. You can see the result by looking at one
https://www.dropbox.com/s/49sgu7ywf2oqwkt/screenshot000.jpg
https://www.dropbox.com/s/4h681pqcpo9lc29/screenshot002.jpg
https://www.dropbox.com/s/q8kio1cquyzdsea/screenshot007.jpg
2b)
MasterApplication::update()
{
changeTheScenegraph();
MultiDisplayWindow->render();
WIN32Window->render();
Thread::getCurrentChangeList()->commitChangesAndClear();
}
, the terrain is correctly rendered (except for lighting) on the
WIN32Window, but on the MultiDisplayWindow the terrain still looks like
in the screenshots.
Well, the latter is 'better' anyway. Since rendering can in fact cause
things to be modified (cache data mostly) you could loose (i.e. not
commit) those changes when just calling CL->clear() after rendering.
For the actual meat of the problem, I'll have to hack up a cluster
example to use the QuadTreeTerrain, which will take a day or two.

Cheers,
Carsten
Christian Bar
2014-07-25 15:21:35 UTC
Permalink
Hello Carsten!
Thank you again for your support.
Regarding the clustering problem, I solved it by using the
commitChangesAndClear().
The lost changes that were made during the render() were probably used by
the new render iteration; committing changes before clearing was sufficient
:)
Regarding the lighting problem, it does not reproduce in the test program...
IMHO it seemed better before, even if it was wrong (the terrain went
progressively darker as the camera moved away from the terrain)...
As you desumed, the problem regards the applied shader, but I do not know
if the problem lies in the shader code or in the generated normal map (IMHO
the shader code, probably...)

Christian Bar


--------------------------------------------------------------------------------------------------------------------------------------

Hello Christian,
Post by Christian Bar
Thank you Carsten!
The example now also works for me!
ok, thanks for testing!


BUT... going on with the implementation in my software, I noticed two
Post by Christian Bar
1) Terrain lighting (and/or normals) is not right, because the terrain
lighting changes as I move the camera (the camera is in the origin and
the world moves by its inverse transform, indeed).
Hmm, does this reproduce with your test program? Note that there the
terrTrans node is below the lightBeacon, so lighting should in fact change
when moving the terrain - because the terrain changes position relative to
the light source.
Anyway, I think the shader was missing a transformation of the light
position from eye space to model space (i.e. multiply with
gl_ModelViewMatrixInverse). Attaching a new patch (contains the changes
from the previous one), and a .zip with the individual commits from my tree.
With that patch the lighting with shaders (setPerPixelLighting(true)) is
practically the same as without, so that seems an improvement to me ;)


2) The terrain is not correctly rendered in a cluster environment.
Post by Christian Bar
In the program I have a WIN32Window (local viewport) and
a MultiDisplayWindow (for cluster visualization).
2a)
MasterApplication::update()
{
changeTheScenegraph();
Thread::getCurrentChangeList()->commitChanges();
MultiDisplayWindow->render();
WIN32Window->render();
Thread::getCurrentChangeList()->clear();
}
Hmm, not sure if that makes any difference, but you can set your local
window as: mdw->setClientWindow(win32win); and it will be rendered without
the explicit call.


If I do this, the result is a wrong rendered terrain: the geometry and
Post by Christian Bar
the triangles are not correct. You can see the result by looking at one
https://www.dropbox.com/s/49sgu7ywf2oqwkt/screenshot000.jpg
https://www.dropbox.com/s/4h681pqcpo9lc29/screenshot002.jpg
https://www.dropbox.com/s/q8kio1cquyzdsea/screenshot007.jpg
2b)
MasterApplication::update()
{
changeTheScenegraph();
MultiDisplayWindow->render();
WIN32Window->render();
Thread::getCurrentChangeList()->commitChangesAndClear();
}
, the terrain is correctly rendered (except for lighting) on the
WIN32Window, but on the MultiDisplayWindow the terrain still looks like
in the screenshots.
Well, the latter is 'better' anyway. Since rendering can in fact cause
things to be modified (cache data mostly) you could loose (i.e. not commit)
those changes when just calling CL->clear() after rendering.
For the actual meat of the problem, I'll have to hack up a cluster example
to use the QuadTreeTerrain, which will take a day or two.

Cheers,
Carsten
Christian Bar
2014-07-28 13:04:13 UTC
Permalink
Hello Carsten and All,
Sorry for spamming the OpenSG mailing list :)
I managed to make the QuadTreeTerrain rendering work inside my application.
I changed the light position calculation inside the vertex shader. Now it
is:

" vec3 LightPosition = gl_LightSource[0].position.xyz -
vec3(gl_ModelViewMatrix * gl_Vertex);\n"

I'm not a shader expert, but to me now it seems to work...
If it's ok for you, can you commit this line, along with the modification
you did in the other patch?

Thank you again,
Christian Bar
Post by Christian Bar
Hello Carsten!
Thank you again for your support.
Regarding the clustering problem, I solved it by using the
commitChangesAndClear().
The lost changes that were made during the render() were probably used by
the new render iteration; committing changes before clearing was sufficient
:)
Regarding the lighting problem, it does not reproduce in the test
program...
IMHO it seemed better before, even if it was wrong (the terrain went
progressively darker as the camera moved away from the terrain)...
As you desumed, the problem regards the applied shader, but I do not know
if the problem lies in the shader code or in the generated normal map (IMHO
the shader code, probably...)
Christian Bar
Carsten Neumann
2014-07-29 07:57:29 UTC
Permalink
Hello Christian,
Post by Christian Bar
I managed to make the QuadTreeTerrain rendering work inside my application.
I changed the light position calculation inside the vertex shader. Now
" vec3 LightPosition = gl_LightSource[0].position.xyz -
vec3(gl_ModelViewMatrix * gl_Vertex);\n"
I'm not a shader expert, but to me now it seems to work...
hmm, that changes the lighting from a directional to a (sort of) point
light.
In the meantime I've noticed that my last change to the shader using
gl_ModelViewMatrixInverse was wrong; the tangent space vectors are first
transformed to eye-space, so the light direction can be left in
eye-space as well.
Post by Christian Bar
If it's ok for you, can you commit this line, along with the
modification you did in the other patch?
I've committed the other changes, but left the shader in its original
form. I feel uneasy changing it without some understanding why that is
the correct change.

Cheers,
Carsten
Christian Bar
2014-07-29 14:21:31 UTC
Permalink
Thanks!

In the meanwhile, I've discovered that the original shader actually
works with a directional light, but not with a point light. Otherwise,
with my modification it works with the point light, but not with the
directional one.

To make both lights work, I added after the line


" vec3 LightPosition = gl_LightSource[0].position.xyz;\n"


of the original shader the following lines:


" if(gl_LightSource[0].position.w != 0.0)\n"
" LightPosition -= vec3(gl_ModelViewMatrix * gl_Vertex);\n"


Also, in the fragment shader I added the light color to the fragment
final color calculation:


" color = clamp(gl_LightSource[0].diffuse.rgb * texcolor *
basecolor * intensity, 0.0, 1.0);\n"


Hope this makes sense to you :)


Christian




---------------------------------------------------------------------


Hello Christian,
Post by Christian Bar
I managed to make the QuadTreeTerrain rendering work inside my application.
I changed the light position calculation inside the vertex shader. Now
" vec3 LightPosition = gl_LightSource[0].position.xyz -
vec3(gl_ModelViewMatrix * gl_Vertex);\n"
I'm not a shader expert, but to me now it seems to work...
hmm, that changes the lighting from a directional to a (sort of) point
light.
In the meantime I've noticed that my last change to the shader using
gl_ModelViewMatrixInverse was wrong; the tangent space vectors are first
transformed to eye-space, so the light direction can be left in
eye-space as well.
Post by Christian Bar
If it's ok for you, can you commit this line, along with the
modification you did in the other patch?
I've committed the other changes, but left the shader in its original
form. I feel uneasy changing it without some understanding why that is
the correct change.

Cheers,
Carsten
Carsten Neumann
2014-08-01 07:25:39 UTC
Permalink
Hello Christian,
In the meanwhile, I've discovered that the original shader actually works with a directional light, but not with a point light. Otherwise, with my modification it works with the point light, but not with the directional one.
To make both lights work, I added after the line
" vec3 LightPosition = gl_LightSource[0].position.xyz;\n"
" if(gl_LightSource[0].position.w != 0.0)\n"
" LightPosition -= vec3(gl_ModelViewMatrix * gl_Vertex);\n"
" color = clamp(gl_LightSource[0].diffuse.rgb * texcolor * basecolor * intensity, 0.0, 1.0);\n"
Hope this makes sense to you :)
sorry for the delay. Those are nice improvements, thanks for sending
them! Committed.

Cheers,
Carsten

Loading...