GLSL gl_LightSource.halfVector problem

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

GLSL gl_LightSource.halfVector problem

Post by arras »

I am having some problems with GLSL parameter gl_LightSource.halfVector. It should store a vector with a direction half-way between the eye vector and the light vector. It is used to compute specular color.

Using Irrlicht it however use some strange values with resulting specular lighting messed up.

I made test shader which renders halfVector as color using x,y,z as r,g,b. For comparison I made another shader which compute half vector directly from camera and light direction and applied both on two spheres. Results show totally different colors indicating different half vectors. Moreover gl_LightSource.halfVector seems to be the same for every vertex on sphere which is of course wrong.

It seems that halfVector is somehow set but probably not to correct value. It btw. causes this shader code to fail.

Does anybody have idea what might be wrong?

Shader using gl_LightSource.halfVector on the right (blue), shader with computed half vector on the left (green -notice slight shade):
Image

Code: Select all

//fragment shader

void main()
{
	gl_FragColor = gl_Color;
}

Code: Select all

// vertex shader 1

void main()
{
	vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
   vec3 lightVector = normalize(gl_LightSource[0].position.xyz - position);
   vec3 cameraVector = normalize(-position);
   vec3 halfVector = normalize(lightVector + cameraVector);

   gl_FrontColor = vec4(halfVector.x,halfVector.y,halfVector.z,1);

	gl_Position = ftransform();
}

Code: Select all

// vertex shader 2

void main()
{
   vec3 halfVector = normalize(gl_LightSource[0].halfVector.xyz);

   gl_FrontColor = vec4(halfVector.x,halfVector.y,halfVector.z,1);

	gl_Position = ftransform();
}

Code: Select all

#include <irrlicht.h>
using namespace irr;

int main()
{
   IrrlichtDevice *device = createDevice(video::EDT_OPENGL,
      core::dimension2d<u32>(640, 480), 16, false, false, false, 0);

   video::IVideoDriver* driver = device->getVideoDriver();
   scene::ISceneManager* smgr = device->getSceneManager();
   gui::IGUIEnvironment* guienv = device->getGUIEnvironment();

   video::IGPUProgrammingServices *services = driver->getGPUProgrammingServices();

   s32 customMaterial1 = services->addHighLevelShaderMaterialFromFiles(
      "shaders/vertex1.glsl", "main", video::EVST_VS_1_1,
      "shaders/fragment.glsl", "main", video::EPST_PS_1_1,
      0, video::EMT_SOLID);

   s32 customMaterial2 = services->addHighLevelShaderMaterialFromFiles(
      "shaders/vertex2.glsl", "main", video::EVST_VS_1_1,
      "shaders/fragment.glsl", "main", video::EPST_PS_1_1,
      0, video::EMT_SOLID);

   scene::ISceneNode *sphere1 = smgr->addSphereSceneNode(5,64);
   sphere1->setPosition(core::vector3df(-6,0,0));
   sphere1->setMaterialType((video::E_MATERIAL_TYPE)customMaterial1);

   scene::ISceneNode *sphere2 = smgr->addSphereSceneNode(5,64);
   sphere2->setPosition(core::vector3df(6,0,0));
   sphere2->setMaterialType((video::E_MATERIAL_TYPE)customMaterial2);

   scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 50, 0.1f);
   camera->setPosition(core::vector3df(0,0,-20));
   camera->setTarget(core::vector3df(0,0,0));

   scene::ILightSceneNode *light = smgr->addLightSceneNode(0, core::vector3df(-30,30,0));

   smgr->addBillboardTextSceneNode(guienv->getSkin()->getFont() ,
      L"SHADER1", sphere1, core::dimension2df(2.0f, 0.5f), core::vector3df(0,6,0));

   smgr->addBillboardTextSceneNode(guienv->getSkin()->getFont() ,
      L"SHADER2", sphere2, core::dimension2df(2.5f, 0.5f), core::vector3df(0,6,0));

   while(device->run())
   {
      driver->beginScene(true, true, video::SColor(0,200,200,255));
      smgr->drawAll();
      driver->endScene();
   }

   device->drop();

   return 0;
}
Post Reply