add spot light and correct the direct light

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
Post Reply
feelthat
Posts: 194
Joined: Sat Feb 02, 2013 5:27 am

add spot light and correct the direct light

Post by feelthat »

///in COGLES2Solid.vsh, COGLES2Solid2.vsh, COGLES2SphereMap.vsh
...
...
...
uniform float uLightOuterCone[MAX_LIGHTS]; //add this var
uniform float uLightFallOff[MAX_LIGHTS]; //add this var

varying vec2 vTextureCoord0;
varying vec4 vVertexColor;
varying float vFogCoord;

void dirLight(in int index, in vec3 position, in vec3 normal, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular)
{
//vec3 L = normalize(-uLightDirection[index]);
vec3 L = normalize(uLightPosition[index]); //direction same as assignHardwareLight(u32 lightIndex)

ambient += uLightAmbient[index];

float NdotL = dot(normal, L);

if (NdotL > 0.0)
{
diffuse += uLightDiffuse[index] * NdotL;

//Blinn shading, in camera space which the camera position is (0,0,0)
vec3 E = normalize(-position);
vec3 HalfVector = normalize(L + E);
float NdotH = dot(normal, HalfVector);

if (NdotH > 0.0)
{
float SpecularFactor = pow(NdotH, uMaterialShininess);
specular += uLightSpecular[index] * SpecularFactor;
}
}
}

////////////
void spotLight(in int index, in vec3 position, in vec3 normal, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular)
{
vec3 L = uLightPosition[index] - position;
float D = length(L);
L = normalize(L);

//LDirection must do view transform in OnSetConstants or spotlight follow camera
vec3 NSpotDir = normalize(uLightDirection[index]);

//dot(NSpotDir and lightvector) = cos(theta)
float spotEffect = dot(NSpotDir, -L);

if (spotEffect >= uLightOuterCone[index])
{
float Attenuation = 1.0 / (uLightAttenuation[index].x + uLightAttenuation[index].y * D +
uLightAttenuation[index].z * D * D);

Attenuation *= pow(spotEffect, uLightFallOff[index]);

ambient += uLightAmbient[index] * Attenuation;

float NdotL = dot(normal, L);

if (NdotL > 0.0)
{
diffuse += uLightDiffuse[index] * (NdotL * Attenuation);

vec3 E = normalize(-position);
vec3 HalfVector = normalize(L + E);
float NdotH = dot(normal, HalfVector);

if (NdotH > 0.0)
{
float SpecularFactor = pow(NdotH, uMaterialShininess);
specular += uLightSpecular[index] * (SpecularFactor * Attenuation);
}
}
}
}
Last edited by feelthat on Sat Jan 02, 2016 2:37 pm, edited 3 times in total.
feelthat
Posts: 194
Joined: Sat Feb 02, 2013 5:27 am

Re: add spot light and correct the direct light

Post by feelthat »

//in COGLES2FixedPipelineRenderer.cpp

void COGLES2MaterialBaseCB::OnSetConstants(IMaterialRendererServices* services, s32 userData)
{
int MAX_SHADER_LIGHTS;
IVideoDriver* driver = services->getVideoDriver();

if (FirstUpdateBase)
{
WVPMatrixID = services->getVertexShaderConstantID("uWVPMatrix");
WVMatrixID = services->getVertexShaderConstantID("uWVMatrix");
NMatrixID = services->getVertexShaderConstantID("uNMatrix");
MaterialAmbientID = services->getVertexShaderConstantID("uMaterialAmbient");
MaterialDiffuseID = services->getVertexShaderConstantID("uMaterialDiffuse");
MaterialEmissiveID = services->getVertexShaderConstantID("uMaterialEmissive");
MaterialSpecularID = services->getVertexShaderConstantID("uMaterialSpecular");
MaterialShininessID = services->getVertexShaderConstantID("uMaterialShininess");
LightCountID = services->getVertexShaderConstantID("uLightCount");
LightTypeID = services->getVertexShaderConstantID("uLightType");
LightPositionID = services->getVertexShaderConstantID("uLightPosition");
LightDirectionID = services->getVertexShaderConstantID("uLightDirection");
LightAttenuationID = services->getVertexShaderConstantID("uLightAttenuation");
LightAmbientID = services->getVertexShaderConstantID("uLightAmbient");
LightDiffuseID = services->getVertexShaderConstantID("uLightDiffuse");
LightSpecularID = services->getVertexShaderConstantID("uLightSpecular");
FogEnableID = services->getVertexShaderConstantID("uFogEnable");
FogTypeID = services->getVertexShaderConstantID("uFogType");
FogColorID = services->getVertexShaderConstantID("uFogColor");
FogStartID = services->getVertexShaderConstantID("uFogStart");
FogEndID = services->getVertexShaderConstantID("uFogEnd");
FogDensityID = services->getVertexShaderConstantID("uFogDensity");
LightOuterConeID = services->getVertexShaderConstantID("uLightOuterCone"); //add code here
LightFallOffID = services->getVertexShaderConstantID("uLightFallOff"); //add code here

FirstUpdateBase = false;
}

const core::matrix4 W = driver->getTransform(ETS_WORLD);
const core::matrix4 V = driver->getTransform(ETS_VIEW);
const core::matrix4 P = driver->getTransform(ETS_PROJECTION);

/*core::matrix4 Matrix = P * V * W;
services->setPixelShaderConstant(WVPMatrixID, Matrix.pointer(), 16);

Matrix = V * W;
services->setPixelShaderConstant(WVMatrixID, Matrix.pointer(), 16);

Matrix.makeInverse();
services->setPixelShaderConstant(NMatrixID, Matrix.getTransposed().pointer(), 16);*/

core::matrix4 Matrix_V;
core::matrix4 Matrix_V_W = V * W;
core::matrix4 Matrix_P_V_W = P * Matrix_V_W; //for less matrix multiply on V * W

services->setPixelShaderConstant(WVPMatrixID, Matrix_P_V_W.pointer(), 16);
services->setPixelShaderConstant(WVMatrixID, Matrix_V_W.pointer(), 16);

Matrix_V_W.makeInverse();
services->setPixelShaderConstant(NMatrixID, Matrix_V_W.getTransposed().pointer(), 16);

s32 LightCount = LightEnable ? driver->getDynamicLightCount() : 0;
services->setPixelShaderConstant(LightCountID, &LightCount, 1);

if (LightCount > 0)
{
services->setPixelShaderConstant(MaterialAmbientID, reinterpret_cast<f32*>(&MaterialAmbient), 4);
services->setPixelShaderConstant(MaterialDiffuseID, reinterpret_cast<f32*>(&MaterialDiffuse), 4);
services->setPixelShaderConstant(MaterialEmissiveID, reinterpret_cast<f32*>(&MaterialEmissive), 4);
services->setPixelShaderConstant(MaterialSpecularID, reinterpret_cast<f32*>(&MaterialSpecular), 4);
services->setPixelShaderConstant(MaterialShininessID, &MaterialShininess, 1);

//Matrix = V;
Matrix_V = V;

for (s32 i = 0; i < LightCount; ++i)
{
SLight CurrentLight = driver->getDynamicLight(i);
//Matrix.transformVect(CurrentLight.Position);

//.transformVect-> vec3(Vmatrix*vec4(Position, 1))
//.rotateVect -> vec3(Vmatrix*vec4(Direction,0))
switch (CurrentLight.Type)
{
case ELT_DIRECTIONAL:
LightType = 2;
//put on Position, same as assignHardwareLight(u32 lightIndex)
Matrix_V.rotateVect(CurrentLight.Position, -CurrentLight.Direction); //add code here
break;
case ELT_SPOT:
LightType = 1; //add code here
Matrix_V.transformVect(CurrentLight.Position); //add code here
Matrix_V.rotateVect(CurrentLight.Direction); //add code here
break;
default: // ELT_POINT
LightType = 0;
Matrix_V.transformVect(CurrentLight.Position);
break;
}

LightPosition = CurrentLight.Position;
LightDirection = CurrentLight.Direction;
LightAttenuation = CurrentLight.Attenuation;
LightAmbient = CurrentLight.AmbientColor;
LightDiffuse = CurrentLight.DiffuseColor;
LightSpecular = CurrentLight.SpecularColor;
LightOuterCone = CurrentLight.OuterCone; //add code here
LightFallOff[i] = CurrentLight.Falloff; //add code here
}

MAX_SHADER_LIGHTS = 8;
services->setPixelShaderConstant(LightTypeID, reinterpret_cast<s32*>(LightType), MAX_SHADER_LIGHTS);
services->setPixelShaderConstant(LightPositionID, reinterpret_cast<f32*>(LightPosition), 3*MAX_SHADER_LIGHTS);
services->setPixelShaderConstant(LightDirectionID, reinterpret_cast<f32*>(LightDirection), 3*MAX_SHADER_LIGHTS);
services->setPixelShaderConstant(LightAttenuationID,reinterpret_cast<f32*>(LightAttenuation), 3*MAX_SHADER_LIGHTS);
services->setPixelShaderConstant(LightAmbientID, reinterpret_cast<f32*>(LightAmbient), 4*MAX_SHADER_LIGHTS);
services->setPixelShaderConstant(LightDiffuseID, reinterpret_cast<f32*>(LightDiffuse), 4*MAX_SHADER_LIGHTS);
services->setPixelShaderConstant(LightSpecularID, reinterpret_cast<f32*>(LightSpecular), 4*MAX_SHADER_LIGHTS);
services->setPixelShaderConstant(LightOuterConeID, reinterpret_cast<f32*>(LightOuterCone), MAX_SHADER_LIGHTS); //add code here
services->setPixelShaderConstant(LightFallOffID, reinterpret_cast<f32*>(LightFallOff), MAX_SHADER_LIGHTS);
}

services->setPixelShaderConstant(FogEnableID, &FogEnable, 1);

if (FogEnable)
{
SColor TempColor(0);
E_FOG_TYPE TempType = EFT_FOG_LINEAR;
bool TempPerFragment = false;
bool TempRange = false;

driver->getFog(TempColor, TempType, FogStart, FogEnd, FogDensity, TempPerFragment, TempRange);

FogType = (s32)TempType;
FogColor = SColorf(TempColor);

services->setPixelShaderConstant(FogTypeID, &FogType, 1);
services->setPixelShaderConstant(FogColorID, reinterpret_cast<f32*>(&FogColor), 4);
services->setPixelShaderConstant(FogStartID, &FogStart, 1);
services->setPixelShaderConstant(FogEndID, &FogEnd, 1);
services->setPixelShaderConstant(FogDensityID, &FogDensity, 1);
}
}
Last edited by feelthat on Sat Jan 02, 2016 2:30 pm, edited 2 times in total.
feelthat
Posts: 194
Joined: Sat Feb 02, 2013 5:27 am

Re: add spot light and correct the direct light

Post by feelthat »

//in CLightSceneNode.cpp

//! sets the light data
void CLightSceneNode::setLightData(const video::SLight& light)
{
LightData = light;

switch(SceneManager->getVideoDriver()->getDriverType())
{
//radians
case video::EDT_OGLES2:
LightData.OuterCone = (float)cos(LightData.OuterCone*3.141615926f/180.0f);
LightData.InnerCone = (float)cos(LightData.InnerCone*3.141615926f/180.0f);
break;

//degrees
default:
break;
}

LightData.Direction.normalize();
}
chronologicaldot
Competition winner
Posts: 684
Joined: Mon Sep 10, 2012 8:51 am

Re: add spot light and correct the direct light

Post by chronologicaldot »

Deja vu
http://irrlicht.sourceforge.net/forum/v ... =2&t=50934
Although I see you've added a comment here and there. As CuteAlien said last time, you need to explain what's going on and what your code is doing. English probably isn't your first language, though, is it?
Also, to use the code tags, just select your text and press the "Code" button on the top of your post's edit box before you submit your post.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: add spot light and correct the direct light

Post by Vectrotek »

Very cool Spot Lights! Thanks! will definitely try to implement this!
feelthat
Posts: 194
Joined: Sat Feb 02, 2013 5:27 am

Re: add spot light and correct the direct light

Post by feelthat »

Vectrotek wrote:Very cool Spot Lights! Thanks! will definitely try to implement this!
file is here if u need
https://github.com/fatalfeel/proton_sdk ... 2Solid.vsh
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: add spot light and correct the direct light

Post by Vectrotek »

@ feelthat: Thanks!
Post Reply