#ifndef NUM_LIGHTS | |
#define NUM_LIGHTS 4 | |
#endif | |
uniform mat4 g_ViewMatrix; | |
uniform vec4 g_LightPosition[NUM_LIGHTS]; | |
uniform vec4 g_g_LightColor[NUM_LIGHTS]; | |
uniform float m_Shininess; | |
float Lighting_Diffuse(vec3 norm, vec3 lightdir){ | |
return max(0.0, dot(norm, lightdir)); | |
} | |
float Lighting_Specular(vec3 norm, vec3 viewdir, vec3 lightdir, float shiny){ | |
vec3 refdir = reflect(-lightdir, norm); | |
return pow(max(dot(refdir, viewdir), 0.0), shiny); | |
} | |
void Lighting_Direction(vec3 worldPos, vec4 color, vec4 position, out vec4 lightDir){ | |
float posLight = step(0.5, color.w); | |
vec3 tempVec = position.xyz * sign(posLight - 0.5) - (worldPos * posLight); | |
float dist = length(tempVec); | |
lightDir.w = clamp(1.0 - position.w * dist * posLight, 0.0, 1.0); | |
lightDir.xyz = tempVec / dist; | |
} | |
void Lighting_ComputePS(vec3 tanNormal, mat3 tbnMat, | |
int lightCount, out vec3 outDiffuse, out vec3 outSpecular){ | |
// find tangent view dir & vert pos | |
vec3 tanViewDir = viewDir * tbnMat; | |
for (int i = 0; i < lightCount; i++){ | |
// find light dir in tangent space, works for point & directional lights | |
vec4 wvLightPos = (g_ViewMatrix * vec4(g_LightPosition[i].xyz, g_LightColor[i].w)); | |
wvLightPos.w = g_LightPosition[i].w; | |
vec4 tanLightDir; | |
Lighting_Direction(wvPosition, g_LightColor[i], wvLightPos, tanLightDir); | |
tanLightDir.xyz = tanLightDir.xyz * tbnMat; | |
vec3 lightScale = g_LightColor[i].rgb * tanLightDir.w; | |
float specular = Lighting_Specular(tanNormal, tanViewDir, tanLightDir.xyz, m_Shininess); | |
float diffuse = Lighting_Diffuse(tanNormal, tanLightDir.xyz); | |
outSpecular += specular * lightScale * step(0.01, diffuse) * g_LightColor[i].rgb; | |
outDiffuse += diffuse * lightScale * g_LightColor[i].rgb; | |
} | |
} |