i want to have per fragment lighting for a point light. Problem is that it seems lighting is applied per object and not for the whole scene.
This is what i have:
http://imgur.com/a/ylTcc
This is what i want:
https://i.stack.imgur.com/zcCFD.png
Is it even possible to apply per-fragment-lighting for the whole scene globally with this setup? Or do i need a post processing shader?
main.cpp
Code: Select all
#include <irrlicht.h>
class MyShaderCallBack: public irr::video::IShaderConstantSetCallBack
{
public:
MyShaderCallBack() :
TextureID(-1), FirstUpdate(true)
{
}
virtual void OnSetConstants(irr::video::IMaterialRendererServices* services,
irr::s32 userData)
{
//get shader constant id.
if (this->FirstUpdate)
{
this->TextureID = services->getPixelShaderConstantID("Texture");
this->FirstUpdate = false;
}
//set texture
const irr::s32 TextureLayerID = 0;
services->setPixelShaderConstant(this->TextureID, &TextureLayerID, 1);
}
private:
irr::s32 TextureID; //sampler2D
bool FirstUpdate;
};
int main()
{
irr::IrrlichtDevice* const device = irr::createDevice(
irr::video::EDT_OPENGL, irr::core::dimension2du(800, 600));
if (!device)
return 1;
irr::video::IVideoDriver* const driver = device->getVideoDriver();
irr::scene::ISceneManager* const smgr = device->getSceneManager();
//a camera
irr::scene::ICameraSceneNode* camera = smgr->addCameraSceneNode(0,
irr::core::vector3df(1.0f, 5.0, -5.0f));
camera->setTarget(irr::core::vector3df(1.0f, 0.0f, 0.0f));
//moving light
{
irr::scene::ILightSceneNode* light = smgr->addLightSceneNode(0,
irr::core::vector3df(), irr::video::SColorf(1, 1, 1, 1), 6);
irr::scene::ISceneNodeAnimator* anim = smgr->createFlyCircleAnimator(
irr::core::vector3df(1.0f, 3.0f, 1.0f), 3.0f, 0.001f);
light->addAnimator(anim);
anim->drop();
// attach billboard to light
irr::scene::IBillboardSceneNode* node = smgr->addBillboardSceneNode(
light, irr::core::dimension2d<irr::f32>(0.5f, 0.5f));
node->setMaterialFlag(irr::video::EMF_LIGHTING, false);
node->setMaterialType(irr::video::EMT_TRANSPARENT_ADD_COLOR);
node->setMaterialTexture(0,
driver->getTexture(
"./media/particlewhite.bmp"));
}
//shader
irr::video::IGPUProgrammingServices* gpu =
driver->getGPUProgrammingServices();
MyShaderCallBack* mc = new MyShaderCallBack;
irr::s32 shaderMaterialType = gpu->addHighLevelShaderMaterialFromFiles(
"./shader/ppl.vert", "main", irr::video::EVST_VS_1_1,
"./shader/ppl.frag", "main", irr::video::EPST_PS_1_1, mc);
if (shaderMaterialType == -1)
{
device->getLogger()->log("Shader error");
}
mc->drop();
//test cube
irr::scene::IMeshSceneNode* cube = 0;
for (unsigned int y = 0; y < 3; ++y)
{
for (unsigned int x = 0; x < 3; ++x)
{
cube = smgr->addCubeSceneNode(1.0f, 0, -1,
irr::core::vector3df(x, 0, y));
cube->setMaterialType(
(irr::video::E_MATERIAL_TYPE) shaderMaterialType);
cube->setMaterialFlag(irr::video::EMF_LIGHTING, false);
cube->setMaterialTexture(0,
driver->getTexture(
"./media/wall.bmp"));
}
}
while (device->run())
{
driver->beginScene();
smgr->drawAll();
driver->endScene();
}
device->drop();
return 0;
}
Code: Select all
varying vec4 eposition;
varying vec3 normal;
varying vec3 diffuseColor;
varying vec3 specularColor;
varying vec3 emissiveColor;
varying vec3 ambientColor;
varying float shininess;
varying vec2 Tex2DCoord;
void main()
{
// Position in clip space
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// Position in eye space
eposition = gl_ModelViewMatrix * gl_Vertex;
// Normal in eye space
normal = mat3(gl_ModelViewMatrix) * gl_Normal;
// Retrieves diffuse, specular emissive, and ambient color from the OpenGL state.
diffuseColor = vec3(gl_FrontMaterial.diffuse);
specularColor = vec3(gl_FrontMaterial.specular);
emissiveColor = vec3(gl_FrontMaterial.emission);
ambientColor = vec3(gl_FrontMaterial.ambient);
shininess = gl_FrontMaterial.shininess;
Tex2DCoord = vec2(gl_MultiTexCoord0);
}
Code: Select all
varying vec4 eposition;
varying vec3 normal;
varying vec3 diffuseColor;
varying vec3 specularColor;
varying vec3 emissiveColor;
varying vec3 ambientColor;
varying float shininess;
uniform sampler2D Texture;
varying vec2 Tex2DCoord;
void main()
{
const vec3 lightColor = vec3(1, 1, 1);
const vec3 globalAmbient = vec3(0.2, 0.2, 0.2);
// Position in eye space
vec3 P = vec3(eposition);
// Normalize normal in eye space
vec3 N = normalize(normal);
// Compute the emissive term
vec3 emissive = emissiveColor;
// Compute the ambient term
vec3 ambient = ambientColor * globalAmbient;
// Compute the diffuse term
// Normalized vector toward the light source
vec3 L = normalize(vec3(gl_LightSource[0].position) - P);
float diffuseLight = max(dot(N, L), 0);
vec3 diffuse = diffuseColor * lightColor * diffuseLight;
// Compute the specular term
vec3 V = normalize(-P); // Normalized vector toward the viewpoint
vec3 H = normalize(L + V); // Normalized vector that is halfway between V and L
float specularLight = pow(max(dot(N, H), 0), shininess);
if (diffuseLight <= 0)
specularLight = 0;
vec3 specular = specularColor * lightColor * specularLight;
// Define the final vertex color
gl_FragColor.xyz = emissive + ambient + diffuse + specular;
gl_FragColor.w = 1.0;
gl_FragColor *= texture2D(Texture, Tex2DCoord);
}