No problem, It did confuse me too at first.that was it, my bad.
a typo!
GLSL and Irrlicht Ambient color lighting.
looks like you've figured out lighting in glsl.
what's next? my guess is probably setting up a texture then move on to multi-texture.
anyway, here's the whole she-bang...
Vertex:
Fragment:
what's next? my guess is probably setting up a texture then move on to multi-texture.
anyway, here's the whole she-bang...
Code: Select all
#include <irrlicht.h>
#include <iostream>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif
int main()
{
video::E_DRIVER_TYPE driverType;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char i = 'c';
//std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_SOFTWARE; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
// create device and exit if creation failed
core::dimension2di videoDim ( 800,600 );
IrrlichtDevice *device = createDevice(driverType, videoDim, 32, false );
if (device == 0)
return 1; // could not create selected driver.
//IrrlichtDevice* device = createDevice(
// video::EDT_OPENGL,
// core::dimension2d<s32>(640, 480), 32, false, false, false, 0);
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
video::IGPUProgrammingServices *services = driver->getGPUProgrammingServices();
s32 customMaterial = services->addHighLevelShaderMaterialFromFiles(
"shaders/shader_v.glsl", "main", video::EVST_VS_1_1,
"shaders/shader_f.glsl", "main", video::EPST_PS_1_1,
0,
video::EMT_SOLID);
scene::ISceneNode *sphere = smgr->addSphereSceneNode(7);
sphere->setPosition(core::vector3df(0,0,0));
sphere->setMaterialType((video::E_MATERIAL_TYPE)customMaterial);
sphere->getMaterial(0).AmbientColor = video::SColor(0, 0, 255, 255);
sphere->getMaterial(0).Shininess = 200;
sphere = smgr->addSphereSceneNode(5);
sphere->setPosition(core::vector3df(12,0,0));
sphere->getMaterial(0).AmbientColor = video::SColor(255, 255, 0, 0);
sphere->getMaterial(0).Shininess = 128;
scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 50, 10);
camera->setPosition(core::vector3df(0,10,-10));
camera->setTarget(core::vector3df(6,0,0));
scene::ILightSceneNode *light = smgr->addLightSceneNode(0, core::vector3df(50,50,-50),
video::SColorf(1.0f, 1.0f, 1.0f), 10.0f, -1);
video::SLight *ldata = &light->getLightData();
ldata->AmbientColor = video::SColorf(0.5f, 0.5f, 0.5f, 1.0f);
smgr->setAmbientLight( video::SColorf(0.0f, 0.0f, 1.0f) ); // not influencing shader material sphere!!!
scene::ISceneNodeAnimator *anim2 = smgr->createFlyCircleAnimator(core::vector3df(0,0,0), 50.0f, 0.001f);
light->addAnimator(anim2);
while(device->run())
{
driver->beginScene(true, true, video::SColor(255,100,101,140));
smgr->drawAll();
driver->endScene();
}
device->drop();
return 0;
}
Code: Select all
varying vec3 N;
varying vec3 v;
void main(void)
{
v = vec3(gl_ModelViewMatrix * gl_Vertex);
N = normalize(gl_NormalMatrix * gl_Normal);
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
Code: Select all
varying vec3 N;
varying vec3 v;
void main (void)
{
vec3 L = normalize(gl_LightSource[0].position.xyz - v);
vec3 E = normalize(-v);
// we are in Eye Coordinates, so EyePos is (0,0,0)
vec3 R = normalize(-reflect(L,N));
//calculate Ambient Term:
vec4 Iamb = gl_FrontLightProduct[0].ambient;
//calculate Diffuse Term:
vec4 Idiff = gl_FrontLightProduct[0].diffuse * max(dot(N,L), 0.0);
// calculate Specular Term:
vec4 Ispec = gl_FrontLightProduct[0].specular * pow(max(dot(R,E),0.0),0.3*gl_FrontMaterial.shininess);
// write Total Color:
gl_FragColor = gl_FrontLightModelProduct.sceneColor + Iamb + Idiff + Ispec;
//gl_FragColor = Iamb + Idiff + Ispec;
}

Not yet!looks like you've figured out lighting in glsl.
Until now we have just one point light in the scene. Shader should be able to handle any number of lights (maximum 8 ) of any type.
So first I would code shader for directional light, which will be probably easy then spot light, which will be more difficult. Then add things like radius and attenuation in to the mix. And last made it in to one shader capable of handling several lights.
I would say, number of lights and their type have to be passed in to shader from Irrlicht. I see no other way of how to determine number of lights in scene nor their type.
ok, i've looked in several places, including gpugems 2 & 3 books and it turns out this one is new to me. i have no experience setting up multiple lights.
maybe we could set up test cases, very specific moment-in-time render could work, though.
for example, we could try to render a hallway lighted from flickering candles. well, we could try even easier than that, maybe an alley lighted by a neon sign that turns on and off, cars passing by, headlights dimly lighting up the alley.
anyway, those are just examples, i'll leave it up to you how would you like them tested.
maybe we could set up test cases, very specific moment-in-time render could work, though.
for example, we could try to render a hallway lighted from flickering candles. well, we could try even easier than that, maybe an alley lighted by a neon sign that turns on and off, cars passing by, headlights dimly lighting up the alley.
anyway, those are just examples, i'll leave it up to you how would you like them tested.

Well setting up multiple lights will not be such a problem. Its just matter of doing for loop and calculate each light. There is even code floating somewhere on net. Number of lights must be probably handed in to shader manually. But thats not problem.
Problem is spot light. If you can find some code somewhere, let me know. So we don't have to reinvent the wheel again
Here is shader code for directional light (again, per vertex lighting without specular):
vertex shader:
Fragment shader is the same as for point light.
Problem is spot light. If you can find some code somewhere, let me know. So we don't have to reinvent the wheel again
Here is shader code for directional light (again, per vertex lighting without specular):
vertex shader:
Code: Select all
varying vec4 color;
void main()
{
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
vec3 lightVector = normalize(gl_LightSource[0].position.xyz);
vec4 diffuse = gl_FrontLightProduct[0].diffuse * max(0.0, dot(normal,lightVector));
color = gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + diffuse;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}And here is spot light (again only ambient and diffuse, per vertex):
vertex shader:
Fragment shader is same as before.
Now some code to test it:
vertex shader:
Code: Select all
varying vec4 color;
void main()
{
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
vec3 lightVector = normalize(gl_LightSource[0].position.xyz - position);
color = gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient;
float NdotL = max(dot(normal, lightVector), 0.0);
if (NdotL > 0.0)
{
float spotEffect = dot( normalize(gl_LightSource[0].spotDirection), -lightVector );
if (spotEffect > gl_LightSource[0].spotCosCutoff)
{
vec4 diffuse = gl_FrontLightProduct[0].diffuse * NdotL;
spotEffect = pow(spotEffect, gl_LightSource[0].spotExponent);
color += diffuse * spotEffect;
}
}
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}Now some code to test it:
Code: Select all
#include <irrlicht.h>
using namespace irr;
int main()
{
IrrlichtDevice* device = createDevice(
video::EDT_OPENGL,
core::dimension2d<s32>(640, 480), 32, false, false, false, 0);
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
video::IGPUProgrammingServices *services = driver->getGPUProgrammingServices();
s32 customMaterial = services->addHighLevelShaderMaterialFromFiles(
"shaders/shader_spot_v.glsl", "main", video::EVST_VS_1_1,
"shaders/shader_spot_f.glsl", "main", video::EPST_PS_1_1,
0,
video::EMT_SOLID);
scene::ISceneNode *sphere = smgr->addSphereSceneNode(5,256);
sphere->setPosition(core::vector3df(0,0,0));
sphere->setMaterialType((video::E_MATERIAL_TYPE)customMaterial);
sphere->getMaterial(0).AmbientColor = video::SColor(255, 255, 255, 255);
sphere = smgr->addSphereSceneNode(5,256);
sphere->setPosition(core::vector3df(12,0,0));
sphere->getMaterial(0).AmbientColor = video::SColor(255, 255, 255, 255);
scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 50, 10);
camera->setPosition(core::vector3df(0,10,-10));
camera->setTarget(core::vector3df(6,0,0));
scene::ILightSceneNode *light = smgr->addLightSceneNode(0, core::vector3df(0,0,-20),
video::SColorf(1.0f, 1.0f, 1.0f), 10.0f, -1);
video::SLight *ldata = &light->getLightData();
ldata->Type = video::ELT_SPOT;
ldata->InnerCone = 5.0f;
ldata->OuterCone = 10.0f;
ldata->Falloff = 100.0f;
smgr->setAmbientLight( video::SColorf(0.0f, 0.0f, 0.3f) );
scene::ISceneNodeAnimator *anim2 = smgr->createFlyCircleAnimator(core::vector3df(0,0,0), 50.0f, 0.001f);
f32 x = 0.06f;
while(device->run())
{
driver->beginScene(true, true, video::SColor(255,100,101,140));
light->setPosition(core::vector3df(x,0,0)+light->getPosition());
if(light->getPosition().X > 17.0f) x = -0.06f;
if(light->getPosition().X < -5.0f) x = 0.06f;
smgr->drawAll();
driver->endScene();
}
device->drop();
return 0;
}Hmm, it turns out this guy (living in dubai uae) who volunteered to write the parser/interpreter written in lex/yacc for the procedural building submitted his first code submission. I need to review this code and write a reply to him and that will take days. after that, i'll be writing more specs for him to code for.
please pardon the delay, i don't want to lose this great guy, he's pretty good in c/c++ writing yacc parsers.
i'll catch up with you later.
please pardon the delay, i don't want to lose this great guy, he's pretty good in c/c++ writing yacc parsers.
i'll catch up with you later.

Ok, I'm back.
I'll be working on this sometime late night later, I have to meet a study-buddy and continue on the OpenGL project we're working on, he's setting-up the transform matrix without the matrix lib, which is really bordering on insanity. I've pulled a lot of hair on this already.
Anyway, I'm hoping this book ( http://www.amazon.com/Physics-Developme ... 012369471X ) will be a lot of help.
I'll be working on this sometime late night later, I have to meet a study-buddy and continue on the OpenGL project we're working on, he's setting-up the transform matrix without the matrix lib, which is really bordering on insanity. I've pulled a lot of hair on this already.
Anyway, I'm hoping this book ( http://www.amazon.com/Physics-Developme ... 012369471X ) will be a lot of help.

Hey thats a great discovery, nice work arras 
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
just got home, at 3:00AM. six hours of matrix math coding. that was a huge debate about 4x4 matrices and vectors that have four elements. anyway, we settled on using 4 instead of 3. 32 bit floats for textures.
i did some test on the code you posted above, i'll add more code it and see if you have any comments.
see ya later.
i did some test on the code you posted above, i'll add more code it and see if you have any comments.
see ya later.

Thanks Blindside 
dlangdev >> I did some research meanwhile about attenuation and fog. I also did some optimizations to my code. Here are results so far:
Per vertex point light model with ambient, diffuse, specular and attenuation:
Per vertex directional light complete with ambient, diffuse, specular and attenuation:
Per vertex spot light with ambient, diffuse, specular and attenuation:
Linear fog:
Exponential fog (this one is not working exactly the same as Irrlicht fog ...if somebody can find the better formula, please let me know):
Does somebody know what gl_fog.scale is?
dlangdev >> I did some research meanwhile about attenuation and fog. I also did some optimizations to my code. Here are results so far:
Code: Select all
// fragment shader common for all vertex shaders belove
void main()
{
gl_FragColor = gl_Color;
}Code: Select all
// point light vertex shader
void main()
{
vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
vec3 lightVector = gl_LightSource[0].position.xyz - position;
float distance = length(lightVector);
lightVector = normalize(lightVector);
// ambient color
gl_FrontColor = gl_FrontLightProduct[0].ambient;
float difusePower = max(0.0, dot(normal, lightVector));
if(difusePower != 0)
{
// diffuse color
gl_FrontColor += gl_FrontLightProduct[0].diffuse * difusePower;
// specular color
vec3 cameraVector = normalize(-position);
vec3 halfVector = normalize(lightVector + cameraVector);
float specularPower = max( 0.0, dot(normal, halfVector) );
if(specularPower != 0)
{
specularPower = pow( specularPower, gl_FrontMaterial.shininess );
gl_FrontColor += gl_FrontLightProduct[0].specular * specularPower;
}
}
// attentuation
float attentuation = 1.0 / (gl_LightSource[0].constantAttenuation +
gl_LightSource[0].linearAttenuation * distance +
gl_LightSource[0].quadraticAttenuation * distance * distance);
// final color
gl_FrontColor = gl_FrontColor * attentuation + gl_FrontLightModelProduct.sceneColor;
gl_Position = ftransform();
}Code: Select all
// directional light vertex shader
void main()
{
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
vec3 lightVector = gl_LightSource[0].position.xyz;
float distance = length(lightVector);
lightVector = normalize(lightVector);
// ambient color
gl_FrontColor = gl_FrontLightProduct[0].ambient;
// diffuse color
float difusePower = max(0.0, dot(normal, lightVector));
if(difusePower != 0)
{
gl_FrontColor += gl_FrontLightProduct[0].diffuse * difusePower;
// specular color
vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
vec3 cameraVector = normalize(-position);
vec3 halfVector = normalize(lightVector + cameraVector);
float specularPower = max( 0.0, dot(normal, halfVector) );
if(specularPower != 0)
{
specularPower = pow( specularPower, gl_FrontMaterial.shininess );
gl_FrontColor += gl_FrontLightProduct[0].specular * specularPower;
}
}
// attentuation
float attentuation = 1.0 / (gl_LightSource[0].constantAttenuation +
gl_LightSource[0].linearAttenuation * distance +
gl_LightSource[0].quadraticAttenuation * distance * distance);
// final color
gl_FrontColor = gl_FrontColor * attentuation + gl_FrontLightModelProduct.sceneColor;
gl_Position = ftransform();
}Code: Select all
// spot light vertex shader
void main()
{
vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
vec3 lightVector = gl_LightSource[0].position.xyz - position;
float distance = length(lightVector);
lightVector = normalize(lightVector);
// ambient color
gl_FrontColor = gl_FrontLightProduct[0].ambient;
// diffuse color
float difusePower = max(0.0, dot(normal, lightVector));
if(difusePower != 0.0)
{
float spotEffect = dot( normalize(gl_LightSource[0].spotDirection), -lightVector );
if (spotEffect > gl_LightSource[0].spotCosCutoff)
{
spotEffect = pow(spotEffect, gl_LightSource[0].spotExponent);
gl_FrontColor += gl_FrontLightProduct[0].diffuse * difusePower * spotEffect;
// specular color
vec3 cameraVector = normalize(-position);
vec3 halfVector = normalize(lightVector + cameraVector);
float specularPower = max( 0.0, dot(normal, halfVector) );
if(specularPower != 0)
{
specularPower = pow( specularPower, gl_FrontMaterial.shininess );
gl_FrontColor += gl_FrontLightProduct[0].specular * specularPower * spotEffect;
}
}
}
// attentuation
float attentuation = 1.0 / (gl_LightSource[0].constantAttenuation +
gl_LightSource[0].linearAttenuation * distance +
gl_LightSource[0].quadraticAttenuation * distance * distance);
// final color
gl_FrontColor = gl_FrontColor * attentuation + gl_FrontLightModelProduct.sceneColor;
gl_Position = ftransform();
}Code: Select all
// linear fog vertex shader
void main()
{
gl_Position = ftransform();
vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
//float distance = length(position); // distance based
float distance = position.z; // standard Irrlicht
float fogFactor = (gl_Fog.end - distance) / (gl_Fog.end - gl_Fog.start);
fogFactor = clamp(fogFactor, 0.0, 1.0);
gl_FrontColor = gl_Color;
gl_FrontColor = mix(gl_Fog.color, gl_FrontColor, fogFactor );
}Code: Select all
// exponential fog vertex shader
void main()
{
gl_Position = ftransform();
vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
float distance = length(position);
const float LOG2 = 1.442695;
float fogFactor = exp2(-gl_Fog.density * gl_Fog.density * distance * distance * LOG2);
fogFactor = clamp(fogFactor, 0.0, 1.0);
gl_FrontColor = gl_Color;
gl_FrontColor = mix(gl_Fog.color, gl_FrontColor, fogFactor );
}Currently I am working on multi lighting. I am trying to pass lights number and type in to shader.
BlindSide, you did mention some problems ATI cards have with arrays. I have ATI card myself and was unable to pass array in to shader, which complicate things a bit. Do you know more about that problem?
Here is code:
vertex shader:
pixel shader:
ShaderCallBack code:
It does slow things down a little bit. I have found different approach somewhere on net. One which determined light type on its attributes (cone angle, possition ect...). I must test it if it would not be more efficient.
Any ideas are welcome.
BlindSide, you did mention some problems ATI cards have with arrays. I have ATI card myself and was unable to pass array in to shader, which complicate things a bit. Do you know more about that problem?
Here is code:
vertex shader:
Code: Select all
uniform int LightsCount;
uniform int LightType0, LightType1, LightType2, LightType3, LightType4,
LightType5, LightType6, LightType7;
void main()
{
int LightType[8] = int[](LightType0, LightType1, LightType2, LightType3,
LightType4, LightType5, LightType6, LightType7);
gl_FrontColor = gl_Color;
gl_Position = ftransform();
}Code: Select all
void main()
{
gl_FragColor = gl_Color;
}Code: Select all
class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver* driver = Device->getVideoDriver();
u32 LightsCount = (u32)driver->getDynamicLightCount();
services->setVertexShaderConstant("LightsCount", (f32*)&LightsCount, 1);
u32 LightType;
for(u32 i=0; i<LightsCount; i++)
{
LightType = (u32)Device->getVideoDriver()->getDynamicLight(i).Type;
core::stringc str("LightType");
str += i;
services->setVertexShaderConstant(str.c_str(), (f32*)&LightType, 1);
}
}
};Any ideas are welcome.
Just have found that gl_Fog.scale = 1.0 / (gl_Fog.end - gl_Fog.start) and is precomputed.
So here is code for both linear and exponential fog in per vertex and per pixel versions:
So here is code for both linear and exponential fog in per vertex and per pixel versions:
Code: Select all
// linear fog vertex shader
// per vertex linear fog
void main()
{
gl_Position = ftransform();
vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
float fogPower = max(0.0, (gl_Fog.end - position.z) * gl_Fog.scale);
gl_FrontColor = mix(gl_Fog.color,gl_Color, fogPower);
}
// per pixel linear fog
void main()
{
gl_Position = ftransform();
vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
gl_FogFragCoord = position.z;
gl_FrontColor = gl_Color;
}Code: Select all
// linear fog fragment shader
// per vertex linear fog
void main()
{
gl_FragColor = gl_Color;
}
// per pixel linear fog
void main()
{
float fogPower = max(0.0, (gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale);
gl_FragColor = mix(gl_Fog.color,gl_Color, fogPower);
}Code: Select all
// exponential fog vertex shader
// per vertex exponential fog
void main()
{
gl_Position = ftransform();
vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
const float LOG2E = 1.442695;
float fogPower = exp2(-gl_Fog.density * position.z * LOG2E);
gl_FrontColor = mix(gl_Fog.color,gl_Color, fogPower);
}
// per pixel exponential fog
varying float FDxLOG2E;
void main()
{
gl_Position = ftransform();
const float LOG2E = 1.442695;
FDxLOG2E = -gl_Fog.density * LOG2E; // precompuing it for fragment shader
vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
gl_FogFragCoord = position.z;
gl_FrontColor = gl_Color;
}Code: Select all
// exponential fog fragment shader
// per vertex exponential fog
void main()
{
gl_FragColor = gl_Color;
}
// per pixel exponential fog
varying float FDxLOG2E;
void main()
{
float fogPower = exp2(FDxLOG2E * gl_FogFragCoord);
gl_FragColor = mix(gl_Fog.color,gl_Color, fogPower);
}Is it defined what this variable returns if fog is disabled?
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net