Original Post
Hi, I have recently started to move from system that was using Cg shaders to new one using GLSL. I translated my main lighting shader (blinn phong with custom attenuation function), but i turns out that it runs somewhat slower than the Cg version which compiled to ARB assembly (I have ATI GPU). Vertex shader is quite simple think I can safely rule it out. That brings me to the fragment shader: I placed /*plus*/ where a plus operator should be :) I really don't know what else I could do... I used vec3 a lot instead vec4 for colors and stuff, could that effect it? Does anyone know of a good GLSL profiler/debugger? (ATI one doesn't work for GLSL, despite it's listed)
#define LIGHT_COUNT 4
struct PointLight
{
vec3 gPosition;
vec3 gColor;
vec3 gAttenuation;
};
struct Material
{
vec3 gEmissive;
vec3 gAmbient;
vec3 gDiffuse;
vec3 gSpecular;
float gPower;
sampler2D gTexAlbedo;
sampler2D gTexNormal;
};
/*--------------------------------------------------------------*/
/*-------------------------- UNIFORMS --------------------------*/
/*--------------------------------------------------------------*/
uniform Material gMaterial;
uniform PointLight gLight[LIGHT_COUNT];
/*--------------------------------------------------------------*/
/*-------------------------- VARYINGS --------------------------*/
/*--------------------------------------------------------------*/
varying vec3 gColor;
varying vec2 gTexCoord;
varying vec3 gPosition;
varying vec3 gViewDirection;
varying vec3 gLightDirection[LIGHT_COUNT];
/*--------------------------------------------------------------*/
/*-------------------------- FUNCTIONS -------------------------*/
/*--------------------------------------------------------------*/
float calcualtePointAttenuation(in PointLight aLight)
{
float d = distance(gPosition, aLight.gPosition);
float v1 = aLight.gAttenuation.z * d +/*plus*/ aLight.gAttenuation.y;
float v2 = v1 * d +/*plus*/ aLight.gAttenuation.x;
return max(0, v2);
}
vec3 calculatePointLight(in PointLight aLight, in vec3 aNormal, in vec3 aAlbedo, in vec3 aViewDirection, in vec3 aLightDirection)
{
float diffuse_term = max(dot(aNormal, aLightDirection), 0.0);
vec3 final_ambient_diffuse = gMaterial.gDiffuse * diffuse_term +/*plus*/ gMaterial.gAmbient;
vec3 half_vector = normalize(aLightDirection +/*plus*/ aViewDirection);
float HdotN = max(dot(half_vector, aNormal), 0.0);
float specular_term = pow(HdotN, gMaterial.gPower);
vec3 final_specular = gMaterial.gSpecular * specular_term;
vec3 mat_final = final_ambient_diffuse * aAlbedo +/*plus*/ final_specular;
return mat_final * aLight.gColor * calcualtePointAttenuation(aLight);
}
void main( void )
{
vec3 final = vec3(0.0);
vec3 albedo = texture2D(gMaterial.gTexAlbedo, gTexCoord).rgb;
vec3 viewdir = normalize(gViewDirection);
vec3 normal_dir = normalize(texture2D(gMaterial.gTexNormal, gTexCoord).xyz * 2.0 - 1.0);
for (int i = 0; i < LIGHT_COUNT; i++)
final += calculatePointLight(gLight, normal_dir, albedo, viewdir, normalize(gLightDirection));
final += albedo * gMaterial.gEmissive;
gl_FragColor = vec4(gColor * final, 1.0);
}