#168 Fixed shader based light in parallel projection

Added the light position as a uniform in the standard light model shader snippet in the effect generator.
Set the uniform default value on the shader program where ever it is used.
Added an override global uniform set on the viewer to control the light position, and to set it far behind camera when in parallel projection.
This commit is contained in:
Jacob Støren 2016-08-16 10:58:07 +02:00
parent a3499152a5
commit 0eace5579a
5 changed files with 58 additions and 7 deletions

View File

@ -35,6 +35,7 @@
#include <QFile>
#include <QTextStream>
#include "cvfUniform.h"
//--------------------------------------------------------------------------------------------------
@ -196,6 +197,8 @@ void CellEdgeEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect)
cvf::ref<cvf::ShaderProgram> prog = shaderGen.generate();
eff->setShaderProgram(prog.p());
if(!m_disableLighting) prog->setDefaultUniform(new cvf::UniformFloat("u_ecLightPosition", cvf::Vec3f(0.5, 5.0, 7.0)));
// Set up textures
m_edgeTextureImage = new cvf::TextureImage;

View File

@ -32,6 +32,7 @@
#include "cvfShaderSourceProvider.h"
#include "cvfTexture.h"
#include "cvfTexture2D_FF.h"
#include "cvfUniform.h"
@ -81,6 +82,8 @@ void RivTernaryScalarMapperEffectGenerator::updateForShaderBasedRendering(cvf::E
cvf::ref<cvf::ShaderProgram> prog = gen.generate();
eff->setShaderProgram(prog.p());
if(!m_disableLighting) prog->setDefaultUniform(new cvf::UniformFloat("u_ecLightPosition", cvf::Vec3f(0.5, 5.0, 7.0)));
// Result mapping texture
m_textureImage = new cvf::TextureImage();

View File

@ -67,18 +67,18 @@ static const char light_AmbientDiffuse_inl[] =
" \n"
"varying vec3 v_ecPosition; \n"
"varying vec3 v_ecNormal; \n"
"uniform vec3 u_ecLightPosition; \n"
" \n"
"//-------------------------------------------------------------------------------------------------- \n"
"/// lightFragment() - Simple Headlight without Phong/specular component \n"
"/// lightFragment() - Simple Positional Headlight without Phong/specular component \n"
"/// \n"
"//-------------------------------------------------------------------------------------------------- \n"
"vec4 lightFragment(vec4 srcFragColor, float not_in_use_shadowFactor) \n"
"{ \n"
" const vec3 ecLightPosition = vec3(0.5, 5.0, 7.0); \n"
" const float ambientIntensity = 0.2; \n"
" \n"
" // Light vector (from point to light source) \n"
" vec3 L = normalize(ecLightPosition - v_ecPosition); \n"
" vec3 L = normalize(u_ecLightPosition - v_ecPosition); \n"
" \n"
" // Viewing vector (from point to eye) \n"
" // Since we are in eye space, the eye pos is at (0, 0, 0) \n"
@ -101,7 +101,6 @@ cvf::String CommonShaderSources::light_AmbientDiffuse()
return cvf::String(light_AmbientDiffuse_inl);
}
//--------------------------------------------------------------------------------------------------
/// Static helper to configure polygon offset render state from enum
//--------------------------------------------------------------------------------------------------
@ -283,11 +282,12 @@ void SurfaceEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect)
}
cvf::ref<cvf::ShaderProgram> shaderProg = gen.generate();
if (m_enableLighting) shaderProg->setDefaultUniform(new cvf::UniformFloat("u_ecLightPosition", cvf::Vec3f(0.5, 5.0, 7.0)));
cvf::ref<cvf::Effect> eff = effect;
eff->setShaderProgram(shaderProg.p());
eff->setUniform(new cvf::UniformFloat("u_color", m_color));
this->updateCommonEffect(effect);
}
@ -443,6 +443,8 @@ void ScalarMapperEffectGenerator::updateForShaderBasedRendering(cvf::Effect* eff
cvf::ref<cvf::ShaderProgram> prog = gen.generate();
eff->setShaderProgram(prog.p());
if(!m_disableLighting) prog->setDefaultUniform(new cvf::UniformFloat("u_ecLightPosition", cvf::Vec3f(0.5, 5.0, 7.0)));
// Result mapping texture
m_textureImage = new cvf::TextureImage();

View File

@ -45,6 +45,7 @@
#include "cvfDebugTimer.h"
#include "cvfDrawable.h"
#include "cvfDrawableGeo.h"
#include "cvfDynamicUniformSet.h"
#include "cvfHitItemCollection.h"
#include "cvfManipulatorTrackball.h"
#include "cvfModel.h"
@ -59,6 +60,8 @@
#include "cvfScene.h"
#include "cvfTextureImage.h"
#include "cvfTransform.h"
#include "cvfUniform.h"
#include "cvfUniformSet.h"
#include "cvfqtOpenGLContext.h"
#include "cvfqtPerformanceInfoHud.h"
@ -68,6 +71,34 @@
#include <QHBoxLayout>
#include <QInputEvent>
namespace caf
{
class GlobalViewerDynUniformSet: public cvf::DynamicUniformSet
{
public:
GlobalViewerDynUniformSet()
{
m_headlightPosition = new cvf::UniformFloat("u_ecLightPosition", cvf::Vec3f(0.5, 5.0, 7.0));
m_uniformSet = new cvf::UniformSet();
m_uniformSet->setUniform(m_headlightPosition.p());
}
virtual ~GlobalViewerDynUniformSet() {}
void setHeadLightPosition(const cvf::Vec3f posRelativeToCamera) { m_headlightPosition->set(posRelativeToCamera);}
virtual cvf::UniformSet* uniformSet() { return m_uniformSet.p(); }
virtual void update(cvf::Rendering* rendering){};
private:
cvf::ref<cvf::UniformSet> m_uniformSet;
cvf::ref<cvf::UniformFloat> m_headlightPosition;
};
}
std::list<caf::Viewer*> caf::Viewer::sm_viewers;
cvf::ref<cvf::OpenGLContextGroup> caf::Viewer::sm_openGLContextGroup;
@ -98,6 +129,8 @@ caf::Viewer::Viewer(const QGLFormat& format, QWidget* parent)
// Needed to get keystrokes
setFocusPolicy(Qt::ClickFocus);
m_globalUniformSet = new GlobalViewerDynUniformSet();
m_mainCamera = new cvf::Camera;
m_mainCamera->setFromLookAt(cvf::Vec3d(0,0,-1), cvf::Vec3d(0,0,0), cvf::Vec3d(0,1,0));
m_renderingSequence = new cvf::RenderSequence();
@ -143,6 +176,7 @@ void caf::Viewer::setupMainRendering()
{
m_mainRendering->setCamera(m_mainCamera.p());
m_mainRendering->setRenderQueueSorter(new cvf::RenderQueueSorterBasic(cvf::RenderQueueSorterBasic::EFFECT_ONLY));
m_mainRendering->addGlobalDynamicUniformSet(m_globalUniformSet.p());
// Set fixed function rendering if QGLFormat does not support directRendering
if (!this->format().directRendering())
@ -1002,8 +1036,11 @@ void caf::Viewer::enableParallelProjection(bool enableOrtho)
}
m_mainCamera->setProjectionAsOrtho(1.0, m_mainCamera->nearPlane(), m_mainCamera->farPlane());
this->updateParallelProjectionHeightFromMoveZoom(pointOfInterest);
this->m_renderingSequence->setDefaultFFLightDirectional(cvf::Vec3f(0,0,-1));
// Set the light position behind us, far away from the scene
float sceneDepth = m_mainCamera->farPlane() - m_mainCamera->nearPlane();
this->m_renderingSequence->setDefaultFFLightPositional(cvf::Vec3f(0,0, 2 * sceneDepth));
m_globalUniformSet->setHeadLightPosition(cvf::Vec3f(0,0, 2 * sceneDepth));
this->update();
}
@ -1018,6 +1055,7 @@ void caf::Viewer::enableParallelProjection(bool enableOrtho)
m_mainCamera->setProjectionAsPerspective(m_cameraFieldOfViewYDeg, dummyNearPlane, m_mainCamera->farPlane());
this->m_renderingSequence->setDefaultFFLightPositional(cvf::Vec3f(0.5, 5.0, 7.0));
m_globalUniformSet->setHeadLightPosition(cvf::Vec3f(0.5, 5.0, 7.0));
this->update();
}

View File

@ -73,6 +73,7 @@ class QInputEvent;
namespace caf
{
class GlobalViewerDynUniformSet;
class Viewer : public caf::OpenGLWidget
{
@ -219,6 +220,10 @@ private:
caf::FrameAnimationControl* m_animationControl;
cvf::Collection<cvf::Scene> m_frameScenes;
cvf::Collection<cvf::Model> m_staticModels;
// Parallel projection light modification
cvf::ref<GlobalViewerDynUniformSet> m_globalUniformSet;
};
} // End namespace caf