#define WORLD

in vec4 inPosition;
in vec4 inColor;
in vec2 inTexCoord;
in float inFogCoord;
in vec3 inNormal;

out vec4 varColor;
out vec2 varTexCoord;
#ifdef USE_FOG
out float varFog;
#endif  // USE_FOG
#ifdef USE_ENV
out vec2 varEnvCoord;
#endif  // USE_ENV

// projection matrix
uniform mat4 matViewProj;
uniform vec3 cameraPos;
uniform vec3 cameraUpVec;

#ifdef USE_FOG
// fog vars
uniform bool inFog;
uniform vec2 fogParams;
#endif  // USE_FOG

#ifdef USE_ENV
// env vars
uniform bool setEnv;
#endif  // USE_ENV

#ifdef USE_LIGHTS
void ProcessLights(void);
#endif  // USE_LIGHTS
#ifdef USE_EFFECTS
void ProcessEffects(inout vec4 pos);
#endif  // USE_EFFECTS

void main(void)
{
  vec4 pos = inPosition;

  varColor = inColor;
  varTexCoord = inTexCoord;

  #ifdef USE_EFFECTS
  // process effects
  ProcessEffects(pos);
  #endif  // USE_EFFECTS

  // calc position
  gl_Position = pos * matViewProj;

  #ifdef USE_FOG
  // is it in fog?
  if (inFog) {
    float fogEnd = fogParams.x;
    float fogMul = fogParams.y;
    float vertFog = inFogCoord;
    varFog = (fogEnd - gl_Position.w) * fogMul;
    varFog = clamp(varFog, 0.0, 1.0);
    varFog -= vertFog;
    varFog = clamp(varFog, 0.0, 1.0);
  }
  #endif  // USE_FOG

  #ifdef USE_ENV
  // calc env tex coords
  if (setEnv) {
    vec3 vecz = normalize(pos.xyz - cameraPos);
    vec3 vecx = cross(cameraUpVec, vecz);
    vec3 vecy = cross(vecz, vecx);
    varEnvCoord.s = dot(inNormal, vecx) * 0.5 + 0.5;
    varEnvCoord.t = dot(inNormal, vecy) * 0.5 + 0.5;
  }
  #endif  // USE_ENV

  #ifdef USE_LIGHTS
  // process lights
  ProcessLights();
  #endif  // USE_LIGHTS

  // clamp the color
  varColor = clamp(varColor, 0.0, 1.0);
}
