2024-09-22 19:20:45 -07:00
//
// object.vert
// Kraken Engine
//
// Copyright 2024 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.
//
#version 450
#extension GL_GOOGLE_include_directive : enable
2025-05-16 01:44:19 -07:00
// TODO - HACK! Need to dynamically set these defines...
#define ENABLE_DIFFUSE 1
#define ENABLE_PER_PIXEL 1
2024-09-22 19:20:45 -07:00
layout ( location = 0 ) in vec3 vertex_position ;
layout ( location = 1 ) in vec3 vertex_normal ;
#if HAS_NORMAL_MAP == 1
layout ( location = 2 ) in vec3 vertex_tangent ;
#endif
layout ( location = 3 ) in lowp vec3 vertex_uv ;
#if BONE_COUNT > 0
layout ( location = 4 ) in lowp vec3 vertex_uv ;
layout ( location = 5 ) in highp vec4 bone_weights ;
layout ( location = 6 ) in highp vec4 bone_indexes ;
#else
# define vertex_position_skinned vertex_position
# define vertex_normal_skinned vertex_normal
# define vertex_tangent_skinned vertex_tangent
#endif
#if GBUFFER_PASS == 1
# if HAS_NORMAL_MAP == 1
highp mat3 tangent_to_view_matrix ;
# endif
#else
# if HAS_LIGHT_MAP == 1
layout ( loction = 7 ) in mediump vec2 vertex_lightmap_uv ;
# endif //HAS_LIGHT_MAP
#endif // GBUFFER_PASS
layout ( push_constant ) uniform constants
{
highp mat4 mvp_matrix ; // mvp_matrix is the result of multiplying the model, view, and projection matrices
#if BONE_COUNT > 0
highp mat4 bone_transforms [ BONE_COUNT ] ;
#endif
#if ENABLE_PER_PIXEL == 1 || GBUFFER_PASS == 1
# if HAS_NORMAL_MAP == 1
# if HAS_NORMAL_MAP_SCALE == 1
highp vec2 normalTexture_Scale ;
# endif
# if HAS_NORMAL_MAP_OFFSET == 1
highp vec2 normalTexture_Offset ;
# endif
# endif
#else
mediump float material_shininess ;
#endif
#if GBUFFER_PASS == 1
# if HAS_NORMAL_MAP == 1
highp mat4 model_view_inverse_transpose_matrix ;
# endif
#else
highp vec3 light_direction_model_space ; // Must be normalized before entering shader
highp vec3 camera_position_model_space ;
# if ENABLE_PER_PIXEL == 1
# if HAS_SPEC_MAP_SCALE == 1
highp vec2 specularTexture_Scale ;
# endif
# if HAS_SPEC_MAP_OFFSET == 1
highp vec2 specularTexture_Offset ;
# endif
# if HAS_REFLECTION_MAP_SCALE == 1
highp vec2 reflectionTexture_Scale ;
# endif
# if HAS_REFLECTION_MAP_OFFSET == 1
highp vec2 reflectionTexture_Offset ;
# endif
# if SHADOW_QUALITY >= 1
highp mat4 shadow_mvp1 ;
# endif
# if SHADOW_QUALITY >= 2
highp mat4 shadow_mvp2 ;
# endif
# if SHADOW_QUALITY >= 3
highp mat4 shadow_mvp3 ;
# endif
# endif // ENABLE_PER_PIXEL
# if HAS_REFLECTION_CUBE_MAP == 1
# if HAS_NORMAL_MAP == 1
# define NEED_EYEVEC
highp mat4 model_inverse_transpose_matrix ;
# else
highp mat4 model_matrix ;
# endif
# endif
# if HAS_DIFFUSE_MAP_SCALE == 1
highp vec2 diffuseTexture_Scale ;
# endif
# if HAS_DIFFUSE_MAP_OFFSET == 1
highp vec2 diffuseTexture_Offset ;
# endif
#endif
#if ENABLE_RIM_COLOR == 1
lowp vec3 rim_color ;
mediump float rim_power ;
#endif
#if FOG_TYPE > 0
// FOG_TYPE 1 - Linear
// FOG_TYPE 2 - Exponential
// FOG_TYPE 3 - Exponential squared
lowp vec3 fog_color ;
mediump float fog_near ;
# if FOG_TYPE == 1
mediump float fog_far ;
mediump float fog_scale ;
# endif
# if FOG_TYPE > 1
mediump float fog_density ;
# endif
# if FOG_TYPE == 2
mediump float fog_density_premultiplied_exponential ;
# endif
# if FOG_TYPE == 3
mediump float fog_density_premultiplied_squared ;
# endif
#endif
#if ENABLE_PER_PIXEL == 1 || GBUFFER_PASS == 1
mediump float material_shininess ;
# if HAS_NORMAL_MAP == 1
sampler2D normalTexture ;
# endif
#endif
#if GBUFFER_PASS == 3
sampler2D gbuffer_frame ;
sampler2D gbuffer_depth ;
#endif
#if GBUFFER_PASS == 1
# if HAS_NORMAL_MAP == 1
# else
highp mat4 model_view_inverse_transpose_matrix ;
# endif
# if HAS_DIFFUSE_MAP == 1 && ALPHA_TEST == 1
sampler2D diffuseTexture ;
# endif
#else
lowp vec3 material_ambient ;
lowp vec3 material_diffuse ;
lowp vec3 material_specular ;
lowp float material_alpha ;
# if HAS_DIFFUSE_MAP == 1
sampler2D diffuseTexture ;
# endif
# if HAS_SPEC_MAP == 1
sampler2D specularTexture ;
# endif
# if HAS_REFLECTION_MAP == 1
sampler2D reflectionTexture ;
# endif
# if ENABLE_RIM_COLOR == 1
# define NEED_EYEVEC
# endif
# if HAS_REFLECTION_CUBE_MAP == 1
lowp vec3 material_reflection ;
samplerCube reflectionCubeTexture ;
# if HAS_NORMAL_MAP == 1
highp mat4 model_matrix ;
# endif
# endif
# if SHADOW_QUALITY >= 1
# ifdef GL_EXT_shadow_samplers
sampler2DShadow shadowTexture1 ;
# else
sampler2D shadowTexture1 ;
# endif
# endif
# if HAS_LIGHT_MAP == 1
sampler2D lightmapTexture ;
# endif
# if SHADOW_QUALITY >= 2
ampler2D shadowTexture2 ;
# endif
# if SHADOW_QUALITY >= 3
sampler2D shadowTexture3 ;
# endif
#endif
#if GBUFFER_PASS == 1 || GBUFFER_PASS == 3
mediump vec4 viewport ;
#endif
} PushConstants ;
#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
layout ( location = 0 ) out highp vec2 texCoord ;
# endif
# if HAS_NORMAL_MAP == 1
# if HAS_NORMAL_MAP_OFFSET == 1 || HAS_NORMAL_MAP_SCALE == 1
layout ( location = 1 ) out highp vec2 normal_uv ;
# endif
# else
layout ( location = 2 ) out mediump vec3 normal ;
# endif
#else
# if HAS_DIFFUSE_MAP == 1
layout ( location = 3 ) out highp vec2 texCoord ;
# endif
#endif
#if GBUFFER_PASS == 1
# if HAS_NORMAL_MAP == 1
layout ( location = 4 ) out highp mat3 tangent_to_view_matrix ;
# endif
#else
# if HAS_LIGHT_MAP == 1
layout ( location = 5 ) out mediump vec2 lightmap_uv ;
# endif
# if ENABLE_PER_PIXEL == 1
layout ( location = 6 ) out mediump vec3 lightVec ;
2025-05-16 01:44:19 -07:00
layout ( location = 7 ) out mediump vec3 halfVec ;
2024-09-22 19:20:45 -07:00
# if HAS_SPEC_MAP_OFFSET == 1 || HAS_SPEC_MAP_SCALE == 1
layout ( location = 8 ) out highp vec2 spec_uv ;
# endif
# if HAS_REFLECTION_MAP_OFFSET == 1 || HAS_REFLECTION_MAP_SCALE == 1
layout ( location = 9 ) out highp vec2 reflection_uv ;
# endif
# if SHADOW_QUALITY >= 1
layout ( location = 10 ) out highp vec4 shadowMapCoord1 ;
# endif
# if SHADOW_QUALITY >= 2
layout ( location = 11 ) out highp vec4 shadowMapCoord2 ;
# endif
# if SHADOW_QUALITY >= 3
layout ( location = 12 ) out highp vec4 shadowMapCoord3 ;
# endif
# else
layout ( location = 13 ) out mediump float lamberFactor ;
layout ( location = 14 ) out mediump float specularFactor ;
# endif
# if ENABLE_RIM_COLOR == 1
# define NEED_EYEVEC
# endif
# if HAS_REFLECTION_CUBE_MAP == 1
# if HAS_NORMAL_MAP == 1
# define NEED_EYEVEC
layout ( location = 15 ) out highp mat3 tangent_to_world_matrix ;
# else
layout ( location = 16 ) out mediump vec3 reflectionVec ;
# endif
# endif
# ifdef NEED_EYEVEC
layout ( location = 17 ) out mediump vec3 eyeVec ;
# endif
# if HAS_DIFFUSE_MAP_OFFSET == 1 || HAS_DIFFUSE_MAP_SCALE == 1
layout ( location = 18 ) out 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 ;
//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
#endif
// Transform position
gl_Position = PushConstants . mvp_matrix * vec4 ( vertex_position_skinned , 1.0 ) ;
# 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 + = PushConstants . diffuseTexture_Offset ;
# endif
# if HAS_DIFFUSE_MAP_SCALE == 1
diffuse_uv * = PushConstants . 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
# else
// Calculate reflection vector as I - 2.0 * dot(N, I) * N
mediump vec3 eyeVec = normalize ( PushConstants . camera_position_model_space - vertex_position_skinned ) ;
mediump vec3 incidenceVec = - eyeVec ;
reflectionVec = mat3 ( PushConstants . model_matrix ) * ( incidenceVec - 2.0 * dot ( vertex_normal_skinned , incidenceVec ) * vertex_normal_skinned ) ;
# endif
# endif
# ifdef NEED_EYEVEC
eyeVec = normalize ( PushConstants . camera_position_model_space - vertex_position_skinned ) ;
# endif
# 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 + = PushConstants . specularTexture_Offset ;
# endif
# if HAS_SPEC_MAP_SCALE == 1
spec_uv * = PushConstants . 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 + = PushConstants . reflectionTexture_Offset ;
# endif
# if HAS_REFLECTION_MAP_SCALE == 1
reflection_uv * = PushConstants . reflectionTexture_Scale ;
# endif
# endif
# if SHADOW_QUALITY >= 1
shadowMapCoord1 = PushConstants . shadow_mvp1 * vec4 ( vertex_position_skinned , 1.0 ) ;
# endif
# if SHADOW_QUALITY >= 2
shadowMapCoord2 = PushConstants . shadow_mvp2 * vec4 ( vertex_position_skinned , 1.0 ) ;
# endif
# if SHADOW_QUALITY >= 3
shadowMapCoord3 = PushConstants . 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 ( PushConstants . camera_position_model_space - vertex_position_skinned ) ;
# else
tangent_to_world_matrix [ 0 ] = vec3 ( PushConstants . model_inverse_transpose_matrix * vec4 ( vertex_tangent_skinned , 1.0 ) ) ;
tangent_to_world_matrix [ 1 ] = vec3 ( PushConstants . model_inverse_transpose_matrix * vec4 ( a_bitangent , 1.0 ) ) ;
tangent_to_world_matrix [ 2 ] = vec3 ( PushConstants . model_inverse_transpose_matrix * vec4 ( vertex_normal_skinned , 1.0 ) ) ;
# endif
lightVec = normalize ( vec3 ( dot ( PushConstants . light_direction_model_space , vertex_tangent_skinned ) , dot ( PushConstants . light_direction_model_space , a_bitangent ) , dot ( PushConstants . 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 = PushConstants . light_direction_model_space ;
halfVec = normalize ( ( normalize ( PushConstants . 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 ( PushConstants . camera_position_model_space - vertex_position_skinned ) + PushConstants . light_direction_model_space ) ) ; // Normalizing anyways, no need to divide by 2
lamberFactor = max ( 0.0 , dot ( PushConstants . light_direction_model_space , vertex_normal_skinned ) ) ;
specularFactor = max ( 0.0 , pow ( dot ( halfVec , vertex_normal_skinned ) , PushConstants . material_shininess ) ) ;
# endif
# endif
}