Optimizations and changes in OpenGL 2.1 device.

* Limited number of lights to 4
* Only directional lights
* Per-pixel lighting
* Improved dynamic shadows a bit
dev-buzzingcars
Tomasz Kapuściński 2017-01-02 16:35:40 +01:00
parent 7b3b257580
commit 9bdd83771e
5 changed files with 164 additions and 173 deletions

View File

@ -242,7 +242,7 @@ bool CGL21Device::Create()
glViewport(0, 0, m_config.size.x, m_config.size.y); glViewport(0, 0, m_config.size.x, m_config.size.y);
// this is set in shader // this is set in shader
int numLights = 8; int numLights = 4;
m_lights = std::vector<Light>(numLights, Light()); m_lights = std::vector<Light>(numLights, Light());
m_lightsEnabled = std::vector<bool> (numLights, false); m_lightsEnabled = std::vector<bool> (numLights, false);
@ -408,7 +408,7 @@ bool CGL21Device::Create()
uni.fogColor = glGetUniformLocation(m_normalProgram, "uni_FogColor"); uni.fogColor = glGetUniformLocation(m_normalProgram, "uni_FogColor");
uni.shadowColor = glGetUniformLocation(m_normalProgram, "uni_ShadowColor"); uni.shadowColor = glGetUniformLocation(m_normalProgram, "uni_ShadowColor");
uni.lightingEnabled = glGetUniformLocation(m_normalProgram, "uni_LightingEnabled"); uni.lightCount = glGetUniformLocation(m_normalProgram, "uni_LightCount");
uni.ambientColor = glGetUniformLocation(m_normalProgram, "uni_Material.ambient"); uni.ambientColor = glGetUniformLocation(m_normalProgram, "uni_Material.ambient");
uni.diffuseColor = glGetUniformLocation(m_normalProgram, "uni_Material.diffuse"); uni.diffuseColor = glGetUniformLocation(m_normalProgram, "uni_Material.diffuse");
@ -417,12 +417,6 @@ bool CGL21Device::Create()
GLchar name[64]; GLchar name[64];
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
sprintf(name, "uni_Light[%d].Enabled", i);
uni.lights[i].enabled = glGetUniformLocation(m_normalProgram, name);
sprintf(name, "uni_Light[%d].Type", i);
uni.lights[i].type = glGetUniformLocation(m_normalProgram, name);
sprintf(name, "uni_Light[%d].Position", i); sprintf(name, "uni_Light[%d].Position", i);
uni.lights[i].position = glGetUniformLocation(m_normalProgram, name); uni.lights[i].position = glGetUniformLocation(m_normalProgram, name);
@ -434,18 +428,6 @@ bool CGL21Device::Create()
sprintf(name, "uni_Light[%d].Specular", i); sprintf(name, "uni_Light[%d].Specular", i);
uni.lights[i].specular = glGetUniformLocation(m_normalProgram, name); uni.lights[i].specular = glGetUniformLocation(m_normalProgram, name);
sprintf(name, "uni_Light[%d].Attenuation", i);
uni.lights[i].attenuation = glGetUniformLocation(m_normalProgram, name);
sprintf(name, "uni_Light[%d].SpotDirection", i);
uni.lights[i].spotDirection = glGetUniformLocation(m_normalProgram, name);
sprintf(name, "uni_Light[%d].Exponent", i);
uni.lights[i].spotExponent = glGetUniformLocation(m_normalProgram, name);
sprintf(name, "uni_Light[%d].SpotCutoff", i);
uni.lights[i].spotCutoff = glGetUniformLocation(m_normalProgram, name);
} }
// Set default uniform values // Set default uniform values
@ -476,10 +458,7 @@ bool CGL21Device::Create()
glUniform1f(uni.shadowColor, 0.5f); glUniform1f(uni.shadowColor, 0.5f);
glUniform1i(uni.lightingEnabled, 0); glUniform1i(uni.lightCount, 0);
for (int i = 0; i < 8; i++)
glUniform1i(uni.lights[i].enabled, 0);
} }
// Obtain uniform locations from interface rendering program and initialize them // Obtain uniform locations from interface rendering program and initialize them
@ -594,6 +573,7 @@ void CGL21Device::ConfigChanged(const DeviceConfig& newConfig)
// Reset state // Reset state
m_lighting = false; m_lighting = false;
m_updateLights = true;
glViewport(0, 0, m_config.size.x, m_config.size.y); glViewport(0, 0, m_config.size.x, m_config.size.y);
@ -721,36 +701,7 @@ void CGL21Device::SetLight(int index, const Light &light)
m_lights[index] = light; m_lights[index] = light;
LightLocations &loc = m_uniforms[m_mode].lights[index]; m_updateLights = true;
glUniform4fv(loc.ambient, 1, light.ambient.Array());
glUniform4fv(loc.diffuse, 1, light.diffuse.Array());
glUniform4fv(loc.specular, 1, light.specular.Array());
glUniform3f(loc.attenuation, light.attenuation0, light.attenuation1, light.attenuation2);
if (light.type == LIGHT_DIRECTIONAL)
{
glUniform1i(loc.type, 1);
glUniform4f(loc.position, -light.direction.x, -light.direction.y, -light.direction.z, 0.0f);
}
else if (light.type == LIGHT_POINT)
{
glUniform1i(loc.type, 2);
glUniform4f(loc.position, light.position.x, light.position.y, light.position.z, 1.0f);
glUniform3f(loc.spotDirection, 0.0f, 1.0f, 0.0f);
glUniform1f(loc.spotCutoff, -1.0f);
glUniform1f(loc.spotExponent, 1.0f);
}
else if (light.type == LIGHT_SPOT)
{
glUniform1i(loc.type, 3);
glUniform4f(loc.position, light.position.x, light.position.y, light.position.z, 1.0f);
glUniform3f(loc.spotDirection, -light.direction.x, -light.direction.y, -light.direction.z);
glUniform1f(loc.spotCutoff, std::cos(light.spotAngle));
glUniform1f(loc.spotExponent, light.spotIntensity);
}
} }
void CGL21Device::SetLightEnabled(int index, bool enabled) void CGL21Device::SetLightEnabled(int index, bool enabled)
@ -760,7 +711,7 @@ void CGL21Device::SetLightEnabled(int index, bool enabled)
m_lightsEnabled[index] = enabled; m_lightsEnabled[index] = enabled;
glUniform1i(m_uniforms[m_mode].lights[index].enabled, enabled ? 1 : 0); m_updateLights = true;
} }
/** If image is invalid, returns invalid texture. /** If image is invalid, returns invalid texture.
@ -798,12 +749,13 @@ Texture CGL21Device::CreateTexture(ImageData *data, const TextureCreateParams &p
result.originalSize = result.size; result.originalSize = result.size;
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &result.id); glGenTextures(1, &result.id);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, result.id); glBindTexture(GL_TEXTURE_2D, result.id);
glEnable(GL_TEXTURE_2D);
// Set texture parameters // Set texture parameters
GLint minF = GL_NEAREST, magF = GL_NEAREST; GLint minF = GL_NEAREST, magF = GL_NEAREST;
int mipmapLevel = 1; int mipmapLevel = 1;
@ -991,7 +943,7 @@ void CGL21Device::SetTexture(int index, const Texture &texture)
glBindTexture(GL_TEXTURE_2D, texture.id); glBindTexture(GL_TEXTURE_2D, texture.id);
// Params need to be updated for the new bound texture // Params need to be updated for the new bound texture
UpdateTextureStatus(); UpdateTextureState(index);
UpdateTextureParams(index); UpdateTextureParams(index);
} }
@ -1009,7 +961,7 @@ void CGL21Device::SetTexture(int index, unsigned int textureId)
glBindTexture(GL_TEXTURE_2D, textureId); glBindTexture(GL_TEXTURE_2D, textureId);
// Params need to be updated for the new bound texture // Params need to be updated for the new bound texture
UpdateTextureStatus(); UpdateTextureState(index);
UpdateTextureParams(index); UpdateTextureParams(index);
} }
@ -1024,15 +976,54 @@ void CGL21Device::SetTextureEnabled(int index, bool enabled)
if (same) if (same)
return; // nothing to do return; // nothing to do
UpdateTextureStatus(); UpdateTextureState(index);
} }
void CGL21Device::UpdateTextureStatus() void CGL21Device::UpdateTextureState(int index)
{ {
for (int i = 0; i < 3; i++) bool enabled = m_texturesEnabled[index] && (m_currentTextures[index].id != 0);
glUniform1i(m_uniforms[m_mode].textureEnabled[index], enabled ? 1 : 0);
}
void CGL21Device::UpdateLights()
{
m_updateLights = false;
// If not in normal rendering mode, return immediately
if (m_mode != 0) return;
// Lighting enabled
if (m_lighting)
{ {
bool enabled = m_texturesEnabled[i] && (m_currentTextures[i].id != 0); int index = 0;
glUniform1i(m_uniforms[m_mode].textureEnabled[i], enabled ? 1 : 0);
// Iterate all lights
for (unsigned int i = 0; i < m_lights.size(); i++)
{
// If disabled, ignore and continue
if (!m_lightsEnabled[i]) continue;
// If not directional, ignore and continue
if (m_lights[i].type != LIGHT_DIRECTIONAL) continue;
Light &light = m_lights[i];
LightLocations &uni = m_uniforms[m_mode].lights[index];
glUniform4fv(uni.ambient, 1, light.ambient.Array());
glUniform4fv(uni.diffuse, 1, light.diffuse.Array());
glUniform4fv(uni.specular, 1, light.specular.Array());
glUniform4f(uni.position, -light.direction.x, -light.direction.y, -light.direction.z, 0.0f);
index++;
}
glUniform1i(m_uniforms[m_mode].lightCount, index);
}
// Lighting disabled
else
{
glUniform1i(m_uniforms[m_mode].lightCount, 0);
} }
} }
@ -1044,6 +1035,12 @@ inline void CGL21Device::BindVBO(GLuint vbo)
m_currentVBO = vbo; m_currentVBO = vbo;
} }
inline void CGL21Device::BindTexture(int index, GLuint texture)
{
glActiveTexture(GL_TEXTURE0 + index);
glBindTexture(GL_TEXTURE_2D, texture);
}
/** /**
Sets the texture parameters for the given texture stage. Sets the texture parameters for the given texture stage.
If the given texture was not set (bound) yet, nothing happens. If the given texture was not set (bound) yet, nothing happens.
@ -1121,6 +1118,8 @@ void CGL21Device::SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode
void CGL21Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int vertexCount, void CGL21Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int vertexCount,
Color color) Color color)
{ {
if (m_updateLights) UpdateLights();
BindVBO(0); BindVBO(0);
Vertex* vs = const_cast<Vertex*>(vertices); Vertex* vs = const_cast<Vertex*>(vertices);
@ -1148,6 +1147,8 @@ void CGL21Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int
void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount,
Color color) Color color)
{ {
if (m_updateLights) UpdateLights();
BindVBO(0); BindVBO(0);
VertexTex2* vs = const_cast<VertexTex2*>(vertices); VertexTex2* vs = const_cast<VertexTex2*>(vertices);
@ -1180,6 +1181,8 @@ void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices,
void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount) void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount)
{ {
if (m_updateLights) UpdateLights();
BindVBO(0); BindVBO(0);
VertexCol* vs = const_cast<VertexCol*>(vertices); VertexCol* vs = const_cast<VertexCol*>(vertices);
@ -1199,6 +1202,8 @@ void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i
void CGL21Device::DrawPrimitive(PrimitiveType type, const void *vertices, void CGL21Device::DrawPrimitive(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int vertexCount) int size, const VertexFormat &format, int vertexCount)
{ {
if (m_updateLights) UpdateLights();
BindVBO(0); BindVBO(0);
const char *ptr = reinterpret_cast<const char*>(vertices); const char *ptr = reinterpret_cast<const char*>(vertices);
@ -1277,6 +1282,8 @@ void CGL21Device::DrawPrimitive(PrimitiveType type, const void *vertices,
void CGL21Device::DrawPrimitives(PrimitiveType type, const void *vertices, void CGL21Device::DrawPrimitives(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int first[], int count[], int drawCount) int size, const VertexFormat &format, int first[], int count[], int drawCount)
{ {
if (m_updateLights) UpdateLights();
BindVBO(0); BindVBO(0);
const char *ptr = reinterpret_cast<const char*>(vertices); const char *ptr = reinterpret_cast<const char*>(vertices);
@ -1355,6 +1362,8 @@ void CGL21Device::DrawPrimitives(PrimitiveType type, const void *vertices,
void CGL21Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices, void CGL21Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
int first[], int count[], int drawCount, Color color) int first[], int count[], int drawCount, Color color)
{ {
if (m_updateLights) UpdateLights();
BindVBO(0); BindVBO(0);
Vertex* vs = const_cast<Vertex*>(vertices); Vertex* vs = const_cast<Vertex*>(vertices);
@ -1381,6 +1390,8 @@ void CGL21Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices, void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
int first[], int count[], int drawCount, Color color) int first[], int count[], int drawCount, Color color)
{ {
if (m_updateLights) UpdateLights();
BindVBO(0); BindVBO(0);
VertexTex2* vs = const_cast<VertexTex2*>(vertices); VertexTex2* vs = const_cast<VertexTex2*>(vertices);
@ -1414,6 +1425,8 @@ void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices, void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
int first[], int count[], int drawCount) int first[], int count[], int drawCount)
{ {
if (m_updateLights) UpdateLights();
BindVBO(0); BindVBO(0);
VertexCol* vs = const_cast<VertexCol*>(vertices); VertexCol* vs = const_cast<VertexCol*>(vertices);
@ -1574,6 +1587,8 @@ void CGL21Device::DrawStaticBuffer(unsigned int bufferId)
if (it == m_vboObjects.end()) if (it == m_vboObjects.end())
return; return;
if (m_updateLights) UpdateLights();
BindVBO((*it).second.bufferId); BindVBO((*it).second.bufferId);
if ((*it).second.vertexType == VERTEX_TYPE_NORMAL) if ((*it).second.vertexType == VERTEX_TYPE_NORMAL)
@ -1741,9 +1756,11 @@ void CGL21Device::SetRenderState(RenderState state, bool enabled)
} }
else if (state == RENDER_STATE_LIGHTING) else if (state == RENDER_STATE_LIGHTING)
{ {
if (m_lighting == enabled) return;
m_lighting = enabled; m_lighting = enabled;
glUniform1i(m_uniforms[m_mode].lightingEnabled, enabled ? 1 : 0); m_updateLights = true;
return; return;
} }

View File

@ -183,10 +183,14 @@ public:
private: private:
//! Updates the texture params for given texture stage //! Updates the texture params for given texture stage
void UpdateTextureParams(int index); void UpdateTextureParams(int index);
//! Updates texture status //! Updates texture state
void UpdateTextureStatus(); void UpdateTextureState(int index);
//! Update light parameters
void UpdateLights();
//! Binds VBO //! Binds VBO
inline void BindVBO(GLuint vbo); inline void BindVBO(GLuint vbo);
//! Binds texture
inline void BindTexture(int index, GLuint texture);
private: private:
//! Current config //! Current config
@ -208,6 +212,8 @@ private:
//! Whether lighting is enabled //! Whether lighting is enabled
bool m_lighting = false; bool m_lighting = false;
//! true means that lights need to be updated
bool m_updateLights = false;
//! Current lights //! Current lights
std::vector<Light> m_lights; std::vector<Light> m_lights;
//! Current lights enable status //! Current lights enable status

View File

@ -194,8 +194,6 @@ struct UniformLocations
//! Shadow color //! Shadow color
GLint shadowColor = -1; GLint shadowColor = -1;
//! true enables lighting
GLint lightingEnabled = -1;
// Number of enabled lights // Number of enabled lights
GLint lightCount = -1; GLint lightCount = -1;
//! Ambient color //! Ambient color

View File

@ -19,6 +19,8 @@
// FRAGMENT SHADER - NORMAL MODE // FRAGMENT SHADER - NORMAL MODE
#version 120 #version 120
#define CONFIG_QUALITY_SHADOWS 1
uniform sampler2D uni_PrimaryTexture; uniform sampler2D uni_PrimaryTexture;
uniform sampler2D uni_SecondaryTexture; uniform sampler2D uni_SecondaryTexture;
uniform sampler2DShadow uni_ShadowTexture; uniform sampler2DShadow uni_ShadowTexture;
@ -34,6 +36,26 @@ uniform vec4 uni_FogColor;
uniform float uni_ShadowColor; uniform float uni_ShadowColor;
struct LightParams
{
vec4 Position;
vec4 Ambient;
vec4 Diffuse;
vec4 Specular;
};
struct Material
{
vec4 ambient;
vec4 diffuse;
vec4 specular;
};
uniform Material uni_Material;
uniform int uni_LightCount;
uniform LightParams uni_Light[4];
varying float pass_Distance; varying float pass_Distance;
varying vec4 pass_Color; varying vec4 pass_Color;
varying vec3 pass_Normal; varying vec3 pass_Normal;
@ -47,6 +69,55 @@ void main()
{ {
vec4 color = pass_Color; vec4 color = pass_Color;
if (uni_LightCount > 0)
{
vec4 ambient = vec4(0.0f);
vec4 diffuse = vec4(0.0f);
vec4 specular = vec4(0.0f);
vec3 normal = normalize(pass_Normal);
for (int i = 0; i < uni_LightCount; i++)
{
LightParams light = uni_Light[i];
vec3 lightDirection = light.Position.xyz;
vec3 reflectDirection = -reflect(lightDirection, normal);
float diffuseComponent = clamp(dot(normal, lightDirection), 0.0f, 1.0f);
float specularComponent = clamp(pow(dot(normal, lightDirection + reflectDirection), 10.0f), 0.0f, 1.0f);
ambient += light.Ambient;
diffuse += diffuseComponent * light.Diffuse;
specular += specularComponent * light.Specular;
}
float shadow = 1.0f;
if (uni_TextureEnabled[2])
{
#ifdef CONFIG_QUALITY_SHADOWS
float offset = 0.00025f;
float value = (1.0f / 5.0f) * (shadow2D(uni_ShadowTexture, pass_TexCoord2).x
+ shadow2D(uni_ShadowTexture, pass_TexCoord2 + vec3( offset, 0.0f, 0.0f)).x
+ shadow2D(uni_ShadowTexture, pass_TexCoord2 + vec3(-offset, 0.0f, 0.0f)).x
+ shadow2D(uni_ShadowTexture, pass_TexCoord2 + vec3( 0.0f, offset, 0.0f)).x
+ shadow2D(uni_ShadowTexture, pass_TexCoord2 + vec3( 0.0f, -offset, 0.0f)).x);
shadow = mix(uni_ShadowColor, 1.0f, value);
#else
shadow = mix(uni_ShadowColor, 1.0f, shadow2D(uni_ShadowTexture, pass_TexCoord2).x);
#endif
}
vec4 result = ambient * uni_Material.ambient
+ diffuse * uni_Material.diffuse * shadow
+ specular * uni_Material.specular * shadow;
color = clamp(vec4(result.rgb, 1.0f), 0.0f, 1.0f);
}
if (uni_TextureEnabled[0]) if (uni_TextureEnabled[0])
{ {
color = color * texture2D(uni_PrimaryTexture, pass_TexCoord0); color = color * texture2D(uni_PrimaryTexture, pass_TexCoord0);
@ -57,16 +128,6 @@ void main()
color = color * texture2D(uni_SecondaryTexture, pass_TexCoord1); color = color * texture2D(uni_SecondaryTexture, pass_TexCoord1);
} }
if (uni_TextureEnabled[2])
{
vec3 normal = pass_Normal * (2.0f * gl_Color.x - 1.0f);
if (dot(normal, const_LightDirection) < 0.0f)
color.rgb *= uni_ShadowColor;
else
color.rgb *= mix(uni_ShadowColor, 1.0f, shadow2D(uni_ShadowTexture, pass_TexCoord2).x);
}
if (uni_FogEnabled) if (uni_FogEnabled)
{ {
float interpolate = (pass_Distance - uni_FogRange.x) / (uni_FogRange.y - uni_FogRange.x); float interpolate = (pass_Distance - uni_FogRange.x) / (uni_FogRange.y - uni_FogRange.x);

View File

@ -25,33 +25,6 @@ uniform mat4 uni_ModelMatrix;
uniform mat4 uni_ShadowMatrix; uniform mat4 uni_ShadowMatrix;
uniform mat4 uni_NormalMatrix; uniform mat4 uni_NormalMatrix;
struct LightParams
{
bool Enabled;
int Type;
vec4 Position;
vec4 Ambient;
vec4 Diffuse;
vec4 Specular;
float Shininess;
vec3 Attenuation;
vec3 SpotDirection;
float SpotCutoff;
float SpotExponent;
};
struct Material
{
vec4 ambient;
vec4 diffuse;
vec4 specular;
};
uniform Material uni_Material;
uniform bool uni_LightingEnabled;
uniform LightParams uni_Light[8];
varying float pass_Distance; varying float pass_Distance;
varying vec4 pass_Color; varying vec4 pass_Color;
varying vec3 pass_Normal; varying vec3 pass_Normal;
@ -65,75 +38,11 @@ void main()
vec4 eyeSpace = uni_ViewMatrix * position; vec4 eyeSpace = uni_ViewMatrix * position;
vec4 shadowCoord = uni_ShadowMatrix * position; vec4 shadowCoord = uni_ShadowMatrix * position;
vec4 color = gl_Color;
vec3 normal = normalize((uni_NormalMatrix * vec4(gl_Normal, 0.0f)).xyz);
if (uni_LightingEnabled)
{
vec4 ambient = vec4(0.0f);
vec4 diffuse = vec4(0.0f);
vec4 specular = vec4(0.0f);
for (int i = 0; i < 8; i++)
{
if (uni_Light[i].Enabled)
{
LightParams light = uni_Light[i];
vec3 lightDirection = light.Position.xyz;
float atten = 1.0f;
if (light.Position.w > 0.5f)
{
float dist = distance(light.Position.xyz, position.xyz);
float atten = 1.0f / dot(light.Attenuation,
vec3(1.0f, dist, dist * dist));
lightDirection = normalize(light.Position.xyz - position.xyz);
}
float spot = 1.0f;
if (light.SpotCutoff > 0.0f)
{
float cone = dot(light.SpotDirection, lightDirection);
if (cone > light.SpotCutoff)
{
spot = pow(cone, light.SpotExponent);
}
else
{
continue;
}
}
vec3 reflectDirection = -reflect(lightDirection, normal);
float component = atten * spot;
float diffuseComponent = clamp(dot(normal, lightDirection), 0.0f, 1.0f);
float specularComponent = clamp(pow(dot(normal, lightDirection + reflectDirection), light.Shininess), 0.0f, 1.0f);
ambient += component * light.Ambient * uni_Material.ambient;
diffuse += component * diffuseComponent * light.Diffuse * uni_Material.diffuse;
specular += component * specularComponent * light.Specular * uni_Material.specular;
}
}
vec4 result = ambient + diffuse + specular;
color = clamp(vec4(result.rgb, uni_Material.diffuse), 0.0f, 1.0f);
}
gl_Position = uni_ProjectionMatrix * eyeSpace; gl_Position = uni_ProjectionMatrix * eyeSpace;
gl_FrontColor = vec4(1.0f);
gl_BackColor = vec4(0.0f);
pass_Color = gl_Color;
pass_Normal = normalize((uni_NormalMatrix * vec4(gl_Normal, 0.0f)).xyz);
pass_Distance = abs(eyeSpace.z / eyeSpace.w); pass_Distance = abs(eyeSpace.z / eyeSpace.w);
pass_Color = color;
pass_Normal = normal;
pass_TexCoord0 = gl_MultiTexCoord0.st; pass_TexCoord0 = gl_MultiTexCoord0.st;
pass_TexCoord1 = gl_MultiTexCoord1.st; pass_TexCoord1 = gl_MultiTexCoord1.st;
pass_TexCoord2 = shadowCoord.xyz / shadowCoord.w; pass_TexCoord2 = shadowCoord.xyz / shadowCoord.w;