2013-01-24 13:52:26 -08:00
//
// Shader.vsh
// KREngine
//
// Copyright 2012 Kearwood Gilbert. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The views and conclusions contained in the software and documentation are those of the
// authors and should not be interpreted as representing official policies, either expressed
// or implied, of Kearwood Gilbert.
//
2014-01-04 03:36:56 -08:00
attribute highp vec3 vertex_position , vertex_normal ;
#if HAS_NORMAL_MAP == 1
attribute highp vec3 vertex_tangent ;
#endif
2013-01-24 13:52:26 -08:00
attribute mediump vec2 vertex_uv ;
uniform highp mat4 mvp_matrix ; // mvp_matrix is the result of multiplying the model, view, and projection matrices
#if BONE_COUNT > 0
attribute highp vec4 bone_weights ;
2014-01-04 03:36:56 -08:00
attribute highp vec4 bone_indexes ;
2013-01-24 13:52:26 -08:00
uniform highp mat4 bone_transforms [ BONE_COUNT ] ;
#else
#define vertex_position_skinned vertex_position
#define vertex_normal_skinned vertex_normal
#define vertex_tangent_skinned vertex_tangent
#endif
#if ENABLE_PER_PIXEL == 1 || GBUFFER_PASS == 1
#if HAS_DIFFUSE_MAP == 1 || HAS_NORMAL_MAP == 1 || HAS_SPEC_MAP == 1 || HAS_REFLECTION_MAP == 1
varying highp vec2 texCoord ;
#endif
#if HAS_NORMAL_MAP == 1
#if HAS_NORMAL_MAP_SCALE == 1
uniform highp vec2 normalTexture_Scale ;
#endif
#if HAS_NORMAL_MAP_OFFSET == 1
uniform highp vec2 normalTexture_Offset ;
#endif
#if HAS_NORMAL_MAP_OFFSET == 1 || HAS_NORMAL_MAP_SCALE == 1
varying highp vec2 normal_uv ;
#endif
#else
varying mediump vec3 normal ;
#endif
#else
uniform mediump float material_shininess ;
#if HAS_DIFFUSE_MAP == 1
varying highp vec2 texCoord ;
#endif
#endif
#if GBUFFER_PASS == 1
#if HAS_NORMAL_MAP == 1
uniform highp mat4 model_view_inverse_transpose_matrix ;
varying highp mat3 tangent_to_view_matrix ;
#endif
#else
uniform highp vec3 light_direction_model_space ; // Must be normalized before entering shader
uniform highp vec3 camera_position_model_space ;
#if HAS_LIGHT_MAP == 1
attribute mediump vec2 vertex_lightmap_uv ;
varying mediump vec2 lightmap_uv ;
#endif
#if ENABLE_PER_PIXEL == 1
varying mediump vec3 lightVec ;
varying mediump vec3 halfVec ;
#if HAS_SPEC_MAP_OFFSET == 1 || HAS_SPEC_MAP_SCALE == 1
varying highp vec2 spec_uv ;
#endif
#if HAS_SPEC_MAP_SCALE == 1
uniform highp vec2 specularTexture_Scale ;
#endif
#if HAS_SPEC_MAP_OFFSET == 1
uniform highp vec2 specularTexture_Offset ;
#endif
#if HAS_REFLECTION_MAP_OFFSET == 1 || HAS_REFLECTION_MAP_SCALE == 1
varying highp vec2 reflection_uv ;
#endif
#if HAS_REFLECTION_MAP_SCALE == 1
2013-09-07 16:57:18 -07:00
uniform highp vec2 reflectionTexture_Scale ;
2013-01-24 13:52:26 -08:00
#endif
#if HAS_REFLECTION_MAP_OFFSET == 1
2013-09-07 16:57:18 -07:00
uniform highp vec2 reflectionTexture_Offset ;
2013-01-24 13:52:26 -08:00
#endif
#if SHADOW_QUALITY >= 1
uniform highp mat4 shadow_mvp1 ;
varying highp vec4 shadowMapCoord1 ;
#endif
#if SHADOW_QUALITY >= 2
uniform highp mat4 shadow_mvp2 ;
varying highp vec4 shadowMapCoord2 ;
#endif
#if SHADOW_QUALITY >= 3
uniform highp mat4 shadow_mvp3 ;
varying highp vec4 shadowMapCoord3 ;
#endif
#else
varying mediump float lamberFactor ;
varying mediump float specularFactor ;
#endif
2014-01-04 03:36:56 -08:00
#if ENABLE_RIM_COLOR == 1
#define NEED_EYEVEC
#endif
2013-01-24 13:52:26 -08:00
#if HAS_REFLECTION_CUBE_MAP == 1
#if HAS_NORMAL_MAP == 1
2014-01-04 03:36:56 -08:00
#define NEED_EYEVEC
2013-01-24 13:52:26 -08:00
uniform highp mat4 model_inverse_transpose_matrix ;
varying highp mat3 tangent_to_world_matrix ;
#else
uniform highp mat4 model_matrix ;
varying mediump vec3 reflectionVec ;
#endif
#endif
2014-01-04 03:36:56 -08:00
#ifdef NEED_EYEVEC
varying mediump vec3 eyeVec ;
#endif
2013-01-24 13:52:26 -08:00
#if HAS_DIFFUSE_MAP_SCALE == 1
uniform highp vec2 diffuseTexture_Scale ;
#endif
#if HAS_DIFFUSE_MAP_OFFSET == 1
uniform highp vec2 diffuseTexture_Offset ;
#endif
#if HAS_DIFFUSE_MAP_OFFSET == 1 || HAS_DIFFUSE_MAP_SCALE == 1
varying highp vec2 diffuse_uv ;
#endif
#endif
void main ( )
{
#if BONE_COUNT > 0
mediump vec4 scaled_bone_indexes = bone_indexes ;
mediump vec4 scaled_bone_weights = bone_weights ;
2014-01-04 03:36:56 -08:00
//scaled_bone_indexes = vec4(0.0, 0.0, 0.0, 0.0);
//scaled_bone_weights = vec4(1.0, 0.0, 0.0, 0.0);
highp mat4 skin_matrix =
bone_transforms [ int ( scaled_bone_indexes . x ) ] * scaled_bone_weights . x +
bone_transforms [ int ( scaled_bone_indexes . y ) ] * scaled_bone_weights . y +
bone_transforms [ int ( scaled_bone_indexes . z ) ] * scaled_bone_weights . z +
bone_transforms [ int ( scaled_bone_indexes . w ) ] * scaled_bone_weights . w ;
//skin_matrix = bone_transforms[0];
highp vec3 vertex_position_skinned = ( skin_matrix * vec4 ( vertex_position , 1 ) ) . xyz ;
highp vec3 vertex_normal_skinned = normalize ( mat3 ( skin_matrix ) * vertex_normal ) ;
#if HAS_NORMAL_MAP == 1
highp vec3 vertex_tangent_skinned = normalize ( mat3 ( skin_matrix ) * vertex_tangent ) ;
#endif
2013-01-24 13:52:26 -08:00
2014-01-04 03:36:56 -08:00
#endif
2013-01-24 13:52:26 -08:00
// Transform position
gl_Position = mvp_matrix * vec4 ( vertex_position_skinned , 1.0 ) ;
2014-01-04 03:36:56 -08:00
2013-01-24 13:52:26 -08:00
#if HAS_DIFFUSE_MAP == 1 || (HAS_NORMAL_MAP == 1 && ENABLE_PER_PIXEL == 1) || (HAS_SPEC_MAP == 1 && ENABLE_PER_PIXEL == 1) || (HAS_REFLECTION_MAP == 1 && ENABLE_PER_PIXEL == 1)
// Pass UV co-ordinates
texCoord = vertex_uv . st ;
#endif
// Scaled and translated normal map UV's
#if (HAS_NORMAL_MAP_OFFSET == 1 || HAS_NORMAL_MAP_SCALE == 1) && ENABLE_PER_PIXEL == 1
normal_uv = texCoord ;
#if HAS_NORMAL_MAP_OFFSET == 1
normal_uv += normalTexture_Offset ;
#endif
#if HAS_NORMAL_MAP_SCALE == 1
normal_uv *= normalTexture_Scale ;
#endif
#endif
#if GBUFFER_PASS != 1 || ALPHA_TEST == 1
// Scaled and translated diffuse map UV's
#if HAS_DIFFUSE_MAP_OFFSET == 1 || HAS_DIFFUSE_MAP_SCALE == 1
diffuse_uv = texCoord ;
#if HAS_DIFFUSE_MAP_OFFSET == 1
diffuse_uv += diffuseTexture_Offset ;
#endif
#if HAS_DIFFUSE_MAP_SCALE == 1
diffuse_uv *= diffuseTexture_Scale ;
#endif
#endif
#endif
#if GBUFFER_PASS == 1
#if HAS_NORMAL_MAP == 1
mediump vec3 a_bitangent = cross ( vertex_normal_skinned , vertex_tangent_skinned ) ;
tangent_to_view_matrix [ 0 ] = vec3 ( model_view_inverse_transpose_matrix * vec4 ( vertex_tangent_skinned , 1.0 ) ) ;
tangent_to_view_matrix [ 1 ] = vec3 ( model_view_inverse_transpose_matrix * vec4 ( a_bitangent , 1.0 ) ) ;
tangent_to_view_matrix [ 2 ] = vec3 ( model_view_inverse_transpose_matrix * vec4 ( vertex_normal_skinned , 1.0 ) ) ;
#else
normal = vertex_normal_skinned ;
#endif
#else
#if HAS_REFLECTION_CUBE_MAP == 1
#if HAS_NORMAL_MAP == 1
2014-01-04 03:36:56 -08:00
2013-01-24 13:52:26 -08:00
#else
// Calculate reflection vector as I - 2.0 * dot(N, I) * N
mediump vec3 eyeVec = normalize ( camera_position_model_space - vertex_position_skinned ) ;
mediump vec3 incidenceVec = - eyeVec ;
reflectionVec = mat3 ( model_matrix ) * ( incidenceVec - 2.0 * dot ( vertex_normal_skinned , incidenceVec ) * vertex_normal_skinned ) ;
#endif
#endif
2014-01-04 03:36:56 -08:00
#ifdef NEED_EYEVEC
eyeVec = normalize ( camera_position_model_space - vertex_position_skinned ) ;
#endif
2013-01-24 13:52:26 -08:00
#if HAS_LIGHT_MAP == 1
// Pass shadow UV co-ordinates
lightmap_uv = vertex_lightmap_uv . st ;
#endif
#if ENABLE_PER_PIXEL == 1
// Scaled and translated specular map UV's
#if HAS_SPEC_MAP_OFFSET == 1 || HAS_SPEC_MAP_SCALE == 1
spec_uv = texCoord ;
#if HAS_SPEC_MAP_OFFSET == 1
spec_uv += specularTexture_Offset ;
#endif
#if HAS_SPEC_MAP_SCALE == 1
spec_uv *= specularTexture_Scale ;
#endif
#endif
// Scaled and translated reflection map UV's
#if HAS_REFLECTION_MAP_OFFSET == 1 || HAS_REFLECTION_MAP_SCALE == 1
reflection_uv = texCoord ;
#if HAS_REFLECTION_MAP_OFFSET == 1
reflection_uv += reflectionTexture_Offset ;
#endif
#if HAS_REFLECTION_MAP_SCALE == 1
reflection_uv *= reflectionTexture_Scale ;
#endif
#endif
#if SHADOW_QUALITY >= 1
shadowMapCoord1 = shadow_mvp1 * vec4 ( vertex_position_skinned , 1.0 ) ;
#endif
#if SHADOW_QUALITY >= 2
shadowMapCoord2 = shadow_mvp2 * vec4 ( vertex_position_skinned , 1.0 ) ;
#endif
#if SHADOW_QUALITY >= 3
shadowMapCoord3 = shadow_mvp3 * vec4 ( vertex_position_skinned , 1.0 ) ;
#endif
// ----------- Directional Light (Sun) -----------
#if HAS_NORMAL_MAP == 1
// ----- Calculate per-pixel lighting in tangent space, for normal mapping ------
mediump vec3 a_bitangent = cross ( vertex_normal_skinned , vertex_tangent_skinned ) ;
#if HAS_REFLECTION_CUBE_MAP == 0
// The cube map reflections also require an eyeVec as a varying attribute when normal mapping, so only re-calculate here when needed
mediump vec3 eyeVec = normalize ( camera_position_model_space - vertex_position_skinned ) ;
#else
tangent_to_world_matrix [ 0 ] = vec3 ( model_inverse_transpose_matrix * vec4 ( vertex_tangent_skinned , 1.0 ) ) ;
tangent_to_world_matrix [ 1 ] = vec3 ( model_inverse_transpose_matrix * vec4 ( a_bitangent , 1.0 ) ) ;
tangent_to_world_matrix [ 2 ] = vec3 ( model_inverse_transpose_matrix * vec4 ( vertex_normal_skinned , 1.0 ) ) ;
#endif
lightVec = normalize ( vec3 ( dot ( light_direction_model_space , vertex_tangent_skinned ) , dot ( light_direction_model_space , a_bitangent ) , dot ( light_direction_model_space , vertex_normal_skinned ) ) ) ;
halfVec = normalize ( vec3 ( dot ( eyeVec , vertex_tangent_skinned ) , dot ( eyeVec , a_bitangent ) , dot ( eyeVec , vertex_normal_skinned ) ) ) ;
halfVec = normalize ( halfVec + lightVec ) ; // Normalizing anyways, no need to divide by 2
#else
// ------ Calculate per-pixel lighting without normal mapping ------
normal = vertex_normal_skinned ;
lightVec = light_direction_model_space ;
halfVec = normalize ( ( normalize ( camera_position_model_space - vertex_position_skinned ) + lightVec ) ) ; // Normalizing anyways, no need to divide by 2
#endif
#else
// ------ Calculate per-vertex lighting ------
mediump vec3 halfVec = normalize ( ( normalize ( camera_position_model_space - vertex_position_skinned ) + light_direction_model_space ) ) ; // Normalizing anyways, no need to divide by 2
lamberFactor = max ( 0.0 , dot ( light_direction_model_space , vertex_normal_skinned ) ) ;
specularFactor = max ( 0.0 , pow ( dot ( halfVec , vertex_normal_skinned ) , material_shininess ) ) ;
#endif
#endif
}