Commit c97d617e authored by Ken Martin's avatar Ken Martin

Fix lighting to use Blinn-Phong specular model

A few fixes and cleanups. Use the Blinn-Phong specular lighting
model in the LightKit and Positional shaders. Old OpenGL uses this
model and it is a decent model. Remind myself that the camera is
positioned at 0,0,0 in view coordinates, had to fix a couple places
that were making different assumptions.

Minor changes to TestVBOPLYMapper to make it easier to use
when testing out changes.

Minor warning and documentation fixes as well.

Change-Id: I8bf108ec18fef2f0a2f83ada8cdf7663086036be
parent 22f9267c
......@@ -52,7 +52,6 @@ varying float radiusVC;
varying vec3 centerVC;
uniform int cameraParallel;
uniform float cameraDistance;
void main()
{
......@@ -72,7 +71,7 @@ void main()
// make the triangle face the camera
if (cameraParallel == 0)
{
vec3 dir = normalize(vec3(0.0,0.0,cameraDistance) - vertexVCClose.xyz);
vec3 dir = normalize(-vertexVCClose.xyz);
vec3 base2 = normalize(cross(dir,vec3(1.0,0.0,0.0)));
vec3 base1 = cross(base2,dir);
vertexVCClose.xyz = vertexVCClose.xyz + offsetMC.x*base1 + offsetMC.y*base2;
......
......@@ -57,7 +57,6 @@ varying vec3 centerVC;
varying vec3 orientVC;
uniform int cameraParallel;
uniform float cameraDistance;
void main()
{
......@@ -89,7 +88,7 @@ void main()
vec3 dir = vec3(0.0,0.0,1.0);
if (cameraParallel == 0)
{
dir = normalize(vec3(0.0,0.0,cameraDistance) - vertexVCClose.xyz);
dir = normalize(-vertexVCClose.xyz);
}
if (abs(dot(dir,orientVC)) == 1.0)
{
......
......@@ -66,7 +66,6 @@ void vtkOpenGLSphereMapper::ReplaceShaderValues(std::string &VSSource,
std::string replacement =
"uniform float invertedDepth;\n"
"uniform int cameraParallel;\n"
"uniform float cameraDistance;\n"
"varying float radiusVC;\n"
"varying vec3 centerVC;\n";
......@@ -79,8 +78,8 @@ void vtkOpenGLSphereMapper::ReplaceShaderValues(std::string &VSSource,
FSSource = replace(FSSource,"//VTK::Normal::Impl",
// compute the eye position and unit direction
"vec4 vertexVC = vertexVCClose;\n"
" vec3 EyePos = vec3(0.0,0.0,cameraDistance);\n"
" if (cameraParallel != 0) { EyePos = EyePos + vertexVC.xyz;}\n"
" vec3 EyePos = vec3(0.0,0.0,0.0);\n"
" if (cameraParallel != 0) { EyePos = vertexVC.xyz;}\n"
" vec3 EyeDir = vertexVC.xyz - EyePos;\n"
// we adjust the EyePos to be closer if it is too far away
// to prevent floating point precision noise
......@@ -133,15 +132,6 @@ void vtkOpenGLSphereMapper::SetCameraShaderParameters(vtkgl::CellBO &cellBO,
// add in uniforms for parallel and distance
vtkCamera *cam = ren->GetActiveCamera();
cellBO.Program->SetUniformi("cameraParallel", cam->GetParallelProjection());
cellBO.Program->SetUniformf("cameraDistanceVC", cam->GetDistance());
}
//-----------------------------------------------------------------------------
void vtkOpenGLSphereMapper::SetPropertyShaderParameters(vtkgl::CellBO &cellBO,
vtkRenderer *ren, vtkActor *actor)
{
// do the superclass and then reset a couple values
this->Superclass::SetPropertyShaderParameters(cellBO,ren,actor);
}
//-----------------------------------------------------------------------------
......@@ -178,8 +168,10 @@ void vtkOpenGLSphereMapper::PrintSelf(ostream& os, vtkIndent indent)
this->Superclass::PrintSelf(os, indent);
}
namespace
{
// internal function called by CreateVBO
static vtkgl::VBOLayout vtkOpenGLSphereMapperCreateVBO(float * points, vtkIdType numPts,
vtkgl::VBOLayout vtkOpenGLSphereMapperCreateVBO(float * points, vtkIdType numPts,
unsigned char *colors, int colorComponents,
float *sizes,
vtkgl::BufferObject &vertexBuffer)
......@@ -244,6 +236,7 @@ static vtkgl::VBOLayout vtkOpenGLSphereMapperCreateVBO(float * points, vtkIdType
layout.VertexCount = numPts*3;
return layout;
}
}
size_t vtkOpenGLSphereMapperCreateTriangleIndexBuffer(
vtkgl::BufferObject &indexBuffer,
......
......@@ -58,15 +58,11 @@ protected:
vtkRenderer *ren, vtkActor *act);
// Description:
// Set the shader parameteres related to the Camera
// Set the shader parameters related to the Camera
virtual void SetCameraShaderParameters(vtkgl::CellBO &cellBO, vtkRenderer *ren, vtkActor *act);
// Description:
// Set the shader parameteres related to the property
virtual void SetPropertyShaderParameters(vtkgl::CellBO &cellBO, vtkRenderer *ren, vtkActor *act);
// Description:
// Set the shader parameteres related to the actor/mapper
// Set the shader parameters related to the actor/mapper
virtual void SetMapperShaderParameters(vtkgl::CellBO &cellBO, vtkRenderer *ren, vtkActor *act);
const char *ScaleArray;
......
......@@ -65,7 +65,6 @@ void vtkOpenGLStickMapper::ReplaceShaderValues(std::string &VSSource,
// so don't redefine it
std::string replacement =
"uniform int cameraParallel;\n"
"uniform float cameraDistance;\n"
"varying float radiusVC;\n"
"varying vec3 orientVC;\n"
"varying float lengthVC;\n"
......@@ -82,8 +81,8 @@ void vtkOpenGLStickMapper::ReplaceShaderValues(std::string &VSSource,
FSSource = replace(FSSource,"//VTK::Normal::Impl",
// compute the eye position and unit direction
" vec4 vertexVC = vertexVCClose;\n"
" vec3 EyePos = vec3(0.0,0.0,cameraDistance);\n"
" if (cameraParallel != 0) { EyePos = EyePos + vertexVC.xyz;}\n"
" vec3 EyePos = vec3(0.0,0.0,0.0);\n"
" if (cameraParallel != 0) { EyePos = vertexVC.xyz;}\n"
// we adjust the EyePos to be closer if it is too far away
// to prevent floating point precision noise
" vec3 EyeDir = vertexVC.xyz - EyePos;\n"
......@@ -195,15 +194,6 @@ void vtkOpenGLStickMapper::SetCameraShaderParameters(vtkgl::CellBO &cellBO,
// add in uniforms for parallel and distance
vtkCamera *cam = ren->GetActiveCamera();
cellBO.Program->SetUniformi("cameraParallel", cam->GetParallelProjection());
cellBO.Program->SetUniformf("cameraDistanceVC", cam->GetDistance());
}
//-----------------------------------------------------------------------------
void vtkOpenGLStickMapper::SetPropertyShaderParameters(vtkgl::CellBO &cellBO,
vtkRenderer *ren, vtkActor *actor)
{
// do the superclass and then reset a couple values
this->Superclass::SetPropertyShaderParameters(cellBO,ren,actor);
}
//-----------------------------------------------------------------------------
......@@ -261,8 +251,10 @@ void vtkOpenGLStickMapper::PrintSelf(ostream& os, vtkIndent indent)
this->Superclass::PrintSelf(os, indent);
}
namespace
{
// internal function called by CreateVBO
static vtkgl::VBOLayout vtkOpenGLStickMapperCreateVBO(float * points, vtkIdType numPts,
vtkgl::VBOLayout vtkOpenGLStickMapperCreateVBO(float * points, vtkIdType numPts,
unsigned char *colors, int colorComponents,
float *orients,
float *sizes,
......@@ -420,6 +412,7 @@ static vtkgl::VBOLayout vtkOpenGLStickMapperCreateVBO(float * points, vtkIdType
layout.VertexCount = numPts*6;
return layout;
}
}
size_t vtkOpenGLStickMapperCreateTriangleIndexBuffer(
vtkgl::BufferObject &indexBuffer,
......
......@@ -11,9 +11,10 @@
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME vtkOpenGLStickMapper - PolyDataMapper using OpenGL to render.
// .NAME vtkOpenGLStickMapper - use imposters to draw cylinders
// .SECTION Description
// PolyDataMapper that uses a OpenGL to do the actual rendering.
// PolyDataMapper that uses imposters to draw cylinders/sticks
// for ball/stick style molecular rendering. Supports picking.
#ifndef __vtkOpenGLStickMapper_h
#define __vtkOpenGLStickMapper_h
......@@ -61,15 +62,11 @@ protected:
vtkRenderer *ren, vtkActor *act);
// Description:
// Set the shader parameteres related to the Camera
// Set the shader parameters related to the Camera
virtual void SetCameraShaderParameters(vtkgl::CellBO &cellBO, vtkRenderer *ren, vtkActor *act);
// Description:
// Set the shader parameteres related to the property
virtual void SetPropertyShaderParameters(vtkgl::CellBO &cellBO, vtkRenderer *ren, vtkActor *act);
// Description:
// Set the shader parameteres related to the actor/mapper
// Set the shader parameters related to the actor/mapper
virtual void SetMapperShaderParameters(vtkgl::CellBO &cellBO, vtkRenderer *ren, vtkActor *act);
const char *ScaleArray;
......
......@@ -29,6 +29,8 @@
#include "vtkRegressionTestImage.h"
#include "vtkTestUtilities.h"
#include "vtkRenderWindowInteractor.h"
//----------------------------------------------------------------------------
int TestVBOPLYMapper(int argc, char *argv[])
{
......@@ -40,6 +42,8 @@ int TestVBOPLYMapper(int argc, char *argv[])
renderWindow->SetSize(900, 900);
renderWindow->AddRenderer(renderer.Get());
renderer->AddActor(actor.Get());
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renderWindow.Get());
vtkNew<vtkLightKit> lightKit;
lightKit->AddLightsToRenderer(renderer.Get());
......@@ -99,5 +103,11 @@ int TestVBOPLYMapper(int argc, char *argv[])
renderWindow->SetSize(300, 300);
renderWindow->Render();
int retVal = vtkRegressionTestImage( renderWindow.Get() );
if ( retVal == vtkRegressionTester::DO_INTERACTOR)
{
iren->Start();
}
return EXIT_SUCCESS;
}
......@@ -34,6 +34,7 @@ uniform mat3 normalMatrix; // transform model coordinate directions to view coor
uniform int numberOfLights; // only allow for up to 6 active lights
uniform vec3 lightColor[6]; // intensity weighted color
uniform vec3 lightDirectionVC[6]; // normalized
uniform vec3 lightHalfAngleVC[6]; // normalized
// VC positon of this fragment
//VTK::PositionVC::Dec
......@@ -67,8 +68,6 @@ void main()
//VTK::Normal::Impl
// now compute the vertex color
vec3 viewDirectionVC = normalize(vec3(0.0, 0.0, 1.0) - vertexVC.xyz);
vec3 diffuse = vec3(0,0,0);
vec3 specular = vec3(0,0,0);
for (int lightNum = 0; lightNum < numberOfLights; lightNum++)
......@@ -77,10 +76,9 @@ void main()
float df = max(0.0, dot(normalVC, -lightDirectionVC[lightNum]));
diffuse += (df * lightColor[lightNum]);
if (dot(normalVC, -lightDirectionVC[lightNum]) > 0.0)
if (dot(normalVC, lightDirectionVC[lightNum]) < 0.0)
{
float sf = pow( max(0.0, dot(
reflect(lightDirectionVC[lightNum], normalVC), viewDirectionVC)), specularPower);
float sf = pow( max(0.0, dot(lightHalfAngleVC[lightNum],normalVC)), specularPower);
specular += (sf * lightColor[lightNum]);
}
}
......
......@@ -35,6 +35,7 @@ uniform mat3 normalMatrix; // transform model coordinate directions to view coor
uniform int numberOfLights; // only allow for up to 6 active lights
uniform vec3 lightColor[6]; // intensity weighted color
uniform vec3 lightDirectionVC[6]; // normalized
uniform vec3 lightHalfAngleVC[6]; // normalized
uniform vec3 lightPositionVC[6];
uniform vec3 lightAttenuation[6];
uniform float lightConeAngle[6];
......@@ -72,8 +73,6 @@ void main()
// Generate the normal if we are not passed in one
//VTK::Normal::Impl
vec3 viewDirectionVC = normalize(vec3(0.0, 0.0, 1.0) - vertexVC.xyz);
vec3 diffuse = vec3(0,0,0);
vec3 specular = vec3(0,0,0);
vec3 vertLightDirectionVC;
......@@ -116,10 +115,9 @@ void main()
float df = max(0.0, attenuation*dot(normalVC, -vertLightDirectionVC));
diffuse += (df * lightColor[lightNum]);
if (dot(normalVC, -vertLightDirectionVC) > 0.0)
if (dot(normalVC, vertLightDirectionVC) < 0.0)
{
float sf = attenuation*pow( max(0.0, dot(
reflect(vertLightDirectionVC, normalVC), viewDirectionVC)), specularPower);
float sf = attenuation*pow( max(0.0, dot(lightHalfAngleVC[lightNum],normalVC)), specularPower);
specular += (sf * lightColor[lightNum]);
}
}
......
......@@ -85,7 +85,7 @@ private:
vtkStandardNewMacro(vtkCompositeMapperHelper);
vtkUnsignedCharArray *vtkCompositeMapperHelper::MapScalars(double alpha)
vtkUnsignedCharArray *vtkCompositeMapperHelper::MapScalars(double vtkNotUsed(alpha))
{
return this->Superclass::MapScalars(this->Parent->BlockState.Opacity.top());
}
......
......@@ -823,6 +823,7 @@ void vtkOpenGLPolyDataMapper::SetLightingShaderParameters(vtkgl::CellBO &cellBO,
vtkCollectionSimpleIterator sit;
float lightColor[6][3];
float lightDirection[6][3];
float lightHalfAngle[6][3];
for(lc->InitTraversal(sit);
(light = lc->GetNextLight(sit)); )
{
......@@ -844,12 +845,20 @@ void vtkOpenGLPolyDataMapper::SetLightingShaderParameters(vtkgl::CellBO &cellBO,
lightDirection[numberOfLights][0] = tDir[0];
lightDirection[numberOfLights][1] = tDir[1];
lightDirection[numberOfLights][2] = tDir[2];
lightDir[0] = -tDir[0];
lightDir[1] = -tDir[1];
lightDir[2] = -tDir[2]+1.0;
vtkMath::Normalize(lightDir);
lightHalfAngle[numberOfLights][0] = lightDir[0];
lightHalfAngle[numberOfLights][1] = lightDir[1];
lightHalfAngle[numberOfLights][2] = lightDir[2];
numberOfLights++;
}
}
program->SetUniform3fv("lightColor", numberOfLights, lightColor);
program->SetUniform3fv("lightDirectionVC", numberOfLights, lightDirection);
program->SetUniform3fv("lightHalfAngleVC", numberOfLights, lightHalfAngle);
program->SetUniformi("numberOfLights", numberOfLights);
// we are done unless we have positional lights
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment