precision highp float; precision highp int; #define SHADER_NAME MeshLambertMaterial #define VERTEX_TEXTURES #define GAMMA_FACTOR 2 #define MAX_BONES 0 #define BONE_TEXTURE uniform mat4 modelMatrix; uniform mat4 modelViewMatrix; uniform mat4 projectionMatrix; uniform mat4 viewMatrix; uniform mat3 normalMatrix; uniform vec3 cameraPosition; attribute vec3 position; attribute vec3 normal; attribute vec2 uv; #ifdef USE_COLOR attribute vec3 color; #endif #ifdef USE_MORPHTARGETS attribute vec3 morphTarget0; attribute vec3 morphTarget1; attribute vec3 morphTarget2; attribute vec3 morphTarget3; #ifdef USE_MORPHNORMALS attribute vec3 morphNormal0; attribute vec3 morphNormal1; attribute vec3 morphNormal2; attribute vec3 morphNormal3; #else attribute vec3 morphTarget4; attribute vec3 morphTarget5; attribute vec3 morphTarget6; attribute vec3 morphTarget7; #endif #endif #ifdef USE_SKINNING attribute vec4 skinIndex; attribute vec4 skinWeight; #endif uniform float time; #define LAMBERT varying vec3 vLightFront; #ifdef DOUBLE_SIDED varying vec3 vLightBack; #endif #define PI 3.14159265359 #define PI2 6.28318530718 #define PI_HALF 1.5707963267949 #define RECIPROCAL_PI 0.31830988618 #define RECIPROCAL_PI2 0.15915494 #define LOG2 1.442695 #define EPSILON 1e-6 #define saturate(a) clamp( a, 0.0, 1.0 ) #define whiteCompliment(a) ( 1.0 - saturate( a ) ) float pow2( const in float x ) { return x*x; } float pow3( const in float x ) { return x*x*x; } float pow4( const in float x ) { float x2 = x*x; return x2*x2; } float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); } highp float rand( const in vec2 uv ) { const highp float a = 12.9898, b = 78.233, c = 43758.5453; highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI ); return fract(sin(sn) * c); } struct IncidentLight { vec3 color; vec3 direction; bool visible; }; struct ReflectedLight { vec3 directDiffuse; vec3 directSpecular; vec3 indirectDiffuse; vec3 indirectSpecular; }; struct GeometricContext { vec3 position; vec3 normal; vec3 viewDir; }; vec3 transformDirection( in vec3 dir, in mat4 matrix ) { return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); } vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) { return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz ); } vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { float distance = dot( planeNormal, point - pointOnPlane ); return - distance * planeNormal + point; } float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { return sign( dot( point - pointOnPlane, planeNormal ) ); } vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) { return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine; } mat3 transposeMat3( const in mat3 m ) { mat3 tmp; tmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x ); tmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y ); tmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z ); return tmp; } float linearToRelativeLuminance( const in vec3 color ) { vec3 weights = vec3( 0.2126, 0.7152, 0.0722 ); return dot( weights, color.rgb ); } #if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP ) varying vec2 vUv; uniform mat3 uvTransform; #endif #if defined( USE_LIGHTMAP ) || defined( USE_AOMAP ) attribute vec2 uv2; varying vec2 vUv2; #endif #ifdef USE_ENVMAP #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) varying vec3 vWorldPosition; #else varying vec3 vReflect; uniform float refractionRatio; #endif #endif float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) { #if defined ( PHYSICALLY_CORRECT_LIGHTS ) float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 ); if( cutoffDistance > 0.0 ) { distanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) ); } return distanceFalloff; #else if( cutoffDistance > 0.0 ) { return pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent ); } return 1.0; #endif } vec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) { return RECIPROCAL_PI * diffuseColor; } vec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) { float fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH ); return ( 1.0 - specularColor ) * fresnel + specularColor; } float G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) { float a2 = pow2( alpha ); float gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) ); float gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) ); return 1.0 / ( gl * gv ); } float G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) { float a2 = pow2( alpha ); float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) ); float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) ); return 0.5 / max( gv + gl, EPSILON ); } float D_GGX( const in float alpha, const in float dotNH ) { float a2 = pow2( alpha ); float denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0; return RECIPROCAL_PI * a2 / pow2( denom ); } vec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) { float alpha = pow2( roughness ); vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); float dotNL = saturate( dot( geometry.normal, incidentLight.direction ) ); float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); float dotNH = saturate( dot( geometry.normal, halfDir ) ); float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); vec3 F = F_Schlick( specularColor, dotLH ); float G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV ); float D = D_GGX( alpha, dotNH ); return F * ( G * D ); } vec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) { const float LUT_SIZE = 64.0; const float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE; const float LUT_BIAS = 0.5 / LUT_SIZE; float dotNV = saturate( dot( N, V ) ); vec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) ); uv = uv * LUT_SCALE + LUT_BIAS; return uv; } float LTC_ClippedSphereFormFactor( const in vec3 f ) { float l = length( f ); return max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 ); } vec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) { float x = dot( v1, v2 ); float y = abs( x ); float a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y; float b = 3.4175940 + ( 4.1616724 + y ) * y; float v = a / b; float theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v; return cross( v1, v2 ) * theta_sintheta; } vec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) { vec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ]; vec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ]; vec3 lightNormal = cross( v1, v2 ); if( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 ); vec3 T1, T2; T1 = normalize( V - N * dot( V, N ) ); T2 = - cross( N, T1 ); mat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) ); vec3 coords[ 4 ]; coords[ 0 ] = mat * ( rectCoords[ 0 ] - P ); coords[ 1 ] = mat * ( rectCoords[ 1 ] - P ); coords[ 2 ] = mat * ( rectCoords[ 2 ] - P ); coords[ 3 ] = mat * ( rectCoords[ 3 ] - P ); coords[ 0 ] = normalize( coords[ 0 ] ); coords[ 1 ] = normalize( coords[ 1 ] ); coords[ 2 ] = normalize( coords[ 2 ] ); coords[ 3 ] = normalize( coords[ 3 ] ); vec3 vectorFormFactor = vec3( 0.0 ); vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] ); vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] ); vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] ); vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] ); float result = LTC_ClippedSphereFormFactor( vectorFormFactor ); return vec3( result ); } vec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) { float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 ); const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 ); vec4 r = roughness * c0 + c1; float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y; vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw; return specularColor * AB.x + AB.y; } float G_BlinnPhong_Implicit( ) { return 0.25; } float D_BlinnPhong( const in float shininess, const in float dotNH ) { return RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess ); } vec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) { vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); float dotNH = saturate( dot( geometry.normal, halfDir ) ); float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); vec3 F = F_Schlick( specularColor, dotLH ); float G = G_BlinnPhong_Implicit( ); float D = D_BlinnPhong( shininess, dotNH ); return F * ( G * D ); } float GGXRoughnessToBlinnExponent( const in float ggxRoughness ) { return ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 ); } float BlinnExponentToGGXRoughness( const in float blinnExponent ) { return sqrt( 2.0 / ( blinnExponent + 2.0 ) ); } uniform vec3 ambientLightColor; vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) { vec3 irradiance = ambientLightColor; #ifndef PHYSICALLY_CORRECT_LIGHTS irradiance *= PI; #endif return irradiance; } #if 1 > 0 struct DirectionalLight { vec3 direction; vec3 color; int shadow; float shadowBias; float shadowRadius; vec2 shadowMapSize; }; uniform DirectionalLight directionalLights[ 1 ]; void getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) { directLight.color = directionalLight.color; directLight.direction = directionalLight.direction; directLight.visible = true; } #endif #if 0 > 0 struct PointLight { vec3 position; vec3 color; float distance; float decay; int shadow; float shadowBias; float shadowRadius; vec2 shadowMapSize; float shadowCameraNear; float shadowCameraFar; }; uniform PointLight pointLights[ 0 ]; void getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) { vec3 lVector = pointLight.position - geometry.position; directLight.direction = normalize( lVector ); float lightDistance = length( lVector ); directLight.color = pointLight.color; directLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay ); directLight.visible = ( directLight.color != vec3( 0.0 ) ); } #endif #if 0 > 0 struct SpotLight { vec3 position; vec3 direction; vec3 color; float distance; float decay; float coneCos; float penumbraCos; int shadow; float shadowBias; float shadowRadius; vec2 shadowMapSize; }; uniform SpotLight spotLights[ 0 ]; void getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) { vec3 lVector = spotLight.position - geometry.position; directLight.direction = normalize( lVector ); float lightDistance = length( lVector ); float angleCos = dot( directLight.direction, spotLight.direction ); if ( angleCos > spotLight.coneCos ) { float spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos ); directLight.color = spotLight.color; directLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay ); directLight.visible = true; } else { directLight.color = vec3( 0.0 ); directLight.visible = false; } } #endif #if 0 > 0 struct RectAreaLight { vec3 color; vec3 position; vec3 halfWidth; vec3 halfHeight; }; uniform sampler2D ltc_1; uniform sampler2D ltc_2; uniform RectAreaLight rectAreaLights[ 0 ]; #endif #if 0 > 0 struct HemisphereLight { vec3 direction; vec3 skyColor; vec3 groundColor; }; uniform HemisphereLight hemisphereLights[ 0 ]; vec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) { float dotNL = dot( geometry.normal, hemiLight.direction ); float hemiDiffuseWeight = 0.5 * dotNL + 0.5; vec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); #ifndef PHYSICALLY_CORRECT_LIGHTS irradiance *= PI; #endif return irradiance; } #endif #ifdef USE_COLOR varying vec3 vColor; #endif #ifdef USE_FOG varying float fogDepth; #endif #ifdef USE_MORPHTARGETS #ifndef USE_MORPHNORMALS uniform float morphTargetInfluences[ 8 ]; #else uniform float morphTargetInfluences[ 4 ]; #endif #endif #ifdef USE_SKINNING uniform mat4 bindMatrix; uniform mat4 bindMatrixInverse; #ifdef BONE_TEXTURE uniform sampler2D boneTexture; uniform int boneTextureSize; mat4 getBoneMatrix( const in float i ) { float j = i * 4.0; float x = mod( j, float( boneTextureSize ) ); float y = floor( j / float( boneTextureSize ) ); float dx = 1.0 / float( boneTextureSize ); float dy = 1.0 / float( boneTextureSize ); y = dy * ( y + 0.5 ); vec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) ); vec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) ); vec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) ); vec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) ); mat4 bone = mat4( v1, v2, v3, v4 ); return bone; } #else uniform mat4 boneMatrices[ MAX_BONES ]; mat4 getBoneMatrix( const in float i ) { mat4 bone = boneMatrices[ int(i) ]; return bone; } #endif #endif #ifdef USE_SHADOWMAP #if 1 > 0 uniform mat4 directionalShadowMatrix[ 1 ]; varying vec4 vDirectionalShadowCoord[ 1 ]; #endif #if 0 > 0 uniform mat4 spotShadowMatrix[ 0 ]; varying vec4 vSpotShadowCoord[ 0 ]; #endif #if 0 > 0 uniform mat4 pointShadowMatrix[ 0 ]; varying vec4 vPointShadowCoord[ 0 ]; #endif #endif #ifdef USE_LOGDEPTHBUF #ifdef USE_LOGDEPTHBUF_EXT varying float vFragDepth; #else uniform float logDepthBufFC; #endif #endif #if 0 > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP ) varying vec3 vViewPosition; #endif void main() { #if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP ) vUv = ( uvTransform * vec3( uv, 1 ) ).xy; #endif #if defined( USE_LIGHTMAP ) || defined( USE_AOMAP ) vUv2 = uv2; #endif #ifdef USE_COLOR vColor.xyz = color.xyz; #endif vec3 objectNormal = vec3( normal ); #ifdef USE_MORPHNORMALS objectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ]; objectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ]; objectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ]; objectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ]; #endif #ifdef USE_SKINNING mat4 boneMatX = getBoneMatrix( skinIndex.x ); mat4 boneMatY = getBoneMatrix( skinIndex.y ); mat4 boneMatZ = getBoneMatrix( skinIndex.z ); mat4 boneMatW = getBoneMatrix( skinIndex.w ); #endif #ifdef USE_SKINNING mat4 skinMatrix = mat4( 0.0 ); skinMatrix += skinWeight.x * boneMatX; skinMatrix += skinWeight.y * boneMatY; skinMatrix += skinWeight.z * boneMatZ; skinMatrix += skinWeight.w * boneMatW; skinMatrix = bindMatrixInverse * skinMatrix * bindMatrix; objectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz; #endif vec3 transformedNormal = normalMatrix * objectNormal; #ifdef FLIP_SIDED transformedNormal = - transformedNormal; #endif float theta = sin(time+position.y)/2.0 #ifdef USE_MORPHTARGETS transformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ]; transformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ]; transformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ]; transformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ]; #ifndef USE_MORPHNORMALS transformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ]; transformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ]; transformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ]; transformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ]; #endif #endif #ifdef USE_SKINNING vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 ); vec4 skinned = vec4( 0.0 ); skinned += boneMatX * skinVertex * skinWeight.x; skinned += boneMatY * skinVertex * skinWeight.y; skinned += boneMatZ * skinVertex * skinWeight.z; skinned += boneMatW * skinVertex * skinWeight.w; transformed = ( bindMatrixInverse * skinned ).xyz; #endif vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 ); gl_Position = projectionMatrix * mvPosition; #ifdef USE_LOGDEPTHBUF #ifdef USE_LOGDEPTHBUF_EXT vFragDepth = 1.0 + gl_Position.w; #else gl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0; gl_Position.z *= gl_Position.w; #endif #endif #if 0 > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP ) vViewPosition = - mvPosition.xyz; #endif #if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 ); #endif #ifdef USE_ENVMAP #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) vWorldPosition = worldPosition.xyz; #else vec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition ); vec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix ); #ifdef ENVMAP_MODE_REFLECTION vReflect = reflect( cameraToVertex, worldNormal ); #else vReflect = refract( cameraToVertex, worldNormal, refractionRatio ); #endif #endif #endif vec3 diffuse = vec3( 1.0 ); GeometricContext geometry; geometry.position = mvPosition.xyz; geometry.normal = normalize( transformedNormal ); geometry.viewDir = normalize( -mvPosition.xyz ); GeometricContext backGeometry; backGeometry.position = geometry.position; backGeometry.normal = -geometry.normal; backGeometry.viewDir = geometry.viewDir; vLightFront = vec3( 0.0 ); #ifdef DOUBLE_SIDED vLightBack = vec3( 0.0 ); #endif IncidentLight directLight; float dotNL; vec3 directLightColor_Diffuse; #if 0 > 0 #endif #if 0 > 0 #endif #if 1 > 0 getDirectionalDirectLightIrradiance( directionalLights[ 0 ], geometry, directLight ); dotNL = dot( geometry.normal, directLight.direction ); directLightColor_Diffuse = PI * directLight.color; vLightFront += saturate( dotNL ) * directLightColor_Diffuse; #ifdef DOUBLE_SIDED vLightBack += saturate( -dotNL ) * directLightColor_Diffuse; #endif #endif #if 0 > 0 #endif #ifdef USE_SHADOWMAP #if 1 > 0 vDirectionalShadowCoord[ 0 ] = directionalShadowMatrix[ 0 ] * worldPosition; #endif #if 0 > 0 #endif #if 0 > 0 #endif #endif #ifdef USE_FOG fogDepth = -mvPosition.z; #endif }