//in COGLES2FixedPipelineRenderer.cpp
//modify this function
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");
LightFallOffID = services->getVertexShaderConstantID("uLightFallOff");
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;
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);
break;
case ELT_SPOT:
LightType = 1;
Matrix_V.transformVect(CurrentLight.Position);
Matrix_V.rotateVect(CurrentLight.Direction);
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;
LightFallOff[i] = CurrentLight.Falloff;
}
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);
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);
}
}
////////////////////////////
//in COGLES2Solid.vsh
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);
}
}
}
}