Dart Documentationthree

three library

Exports

Properties

const int AddEquation #

const int AddEquation = 100

const int AdditiveBlending #

const int AdditiveBlending = 2

const int AlphaFormat #

const int AlphaFormat = 16

const int BackSide #

const int BackSide = 1

const int BasicShadowMap #

const int BasicShadowMap = 0

const int ByteType #

const int ByteType = 9

const int ClampToEdgeWrapping #

const int ClampToEdgeWrapping = 1

const int CullFaceBack #

const int CullFaceBack = 1

const int CullFaceFront #

const int CullFaceFront = 2

const int CullFaceFrontBack #

const int CullFaceFrontBack = 3

const int CullFaceNone #

const int CullFaceNone = 0

const int CustomBlending #

const int CustomBlending = 5

const int DoubleSide #

const int DoubleSide = 2

const int DstAlphaFactor #

const int DstAlphaFactor = 206

const int DstColorFactor #

const int DstColorFactor = 208

const int FaceColors #

const int FaceColors = 1

const int FlatShading #

const int FlatShading = 1

const int FloatType #

const int FloatType = 15

const int FrontFaceDirectionCCW #

const int FrontFaceDirectionCCW = 1

const int FrontFaceDirectionCW #

const int FrontFaceDirectionCW = 0

const int FrontSide #

const int FrontSide = 0

int GeometryCount #

int GeometryCount = 0

const int IntType #

const int IntType = 13

const int LinearFilter #

const int LinearFilter = 6

const int LinearMipMapLinearFilter #

const int LinearMipMapLinearFilter = 8

const int LinearMipMapNearestFilter #

const int LinearMipMapNearestFilter = 7

const int LinePieces #

const int LinePieces = 1

const int LineStrip #

const int LineStrip = 0

const int LuminanceAlphaFormat #

const int LuminanceAlphaFormat = 20

const int LuminanceFormat #

const int LuminanceFormat = 19

int MaterialCount #

int MaterialCount = 0

const int MirroredRepeatWrapping #

const int MirroredRepeatWrapping = 2

const int MixOperation #

const int MixOperation = 1

const int MultiplyBlending #

const int MultiplyBlending = 4

const int MultiplyOperation #

const int MultiplyOperation = 0

const int NearestFilter #

const int NearestFilter = 3

const int NearestMipMapLinearFilter #

const int NearestMipMapLinearFilter = 5

const int NearestMipMapNearestFilter #

const int NearestMipMapNearestFilter = 4

const int NoBlending #

const int NoBlending = 0

const int NoColors #

const int NoColors = 0

const int NormalBlending #

const int NormalBlending = 1

const int NoShading #

const int NoShading = 0

int Object3DCount #

int Object3DCount = 0

const int OneFactor #

const int OneFactor = 201

const int OneMinusDstAlphaFactor #

const int OneMinusDstAlphaFactor = 207

const int OneMinusDstColorFactor #

const int OneMinusDstColorFactor = 209

const int OneMinusSrcAlphaFactor #

const int OneMinusSrcAlphaFactor = 205

const int OneMinusSrcColorFactor #

const int OneMinusSrcColorFactor = 203

const int PCFShadowMap #

const int PCFShadowMap = 1

const int PCFSoftShadowMap #

const int PCFSoftShadowMap = 2

const int RepeatWrapping #

const int RepeatWrapping = 0

const int ReverseSubtractEquation #

const int ReverseSubtractEquation = 102

const int RGB_S3TC_DXT1_Format #

const int RGB_S3TC_DXT1_Format = 2001

const int RGBA_S3TC_DXT1_Format #

const int RGBA_S3TC_DXT1_Format = 2002

const int RGBA_S3TC_DXT3_Format #

const int RGBA_S3TC_DXT3_Format = 2003

const int RGBA_S3TC_DXT5_Format #

const int RGBA_S3TC_DXT5_Format = 2004

const int RGBAFormat #

const int RGBAFormat = 18

const int RGBFormat #

const int RGBFormat = 17

final ShaderChunk #

get ShaderChunk  {
 if (__ShaderChunk == null) {
   __ShaderChunk = {
// FOG

 "fog_pars_fragment": [

   "#ifdef USE_FOG",

     "uniform vec3 fogColor;",

     "#ifdef FOG_EXP2",

       "uniform float fogDensity;",

     "#else",

       "uniform float fogNear;",
       "uniform float fogFar;",

     "#endif",

   "#endif"

 ].join("\n"),

 "fog_fragment": [

   "#ifdef USE_FOG",

     "float depth = gl_FragCoord.z / gl_FragCoord.w;",

     "#ifdef FOG_EXP2",

       "const float LOG2 = 1.442695;",
       "float fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );",
       "fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );",

     "#else",

       "float fogFactor = smoothstep( fogNear, fogFar, depth );",

     "#endif",

     "gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );",

   "#endif"

 ].join("\n"),

 // ENVIRONMENT MAP

 "envmap_pars_fragment": [

   "#ifdef USE_ENVMAP",

     "uniform float reflectivity;",
     "uniform samplerCube envMap;",
     "uniform float flipEnvMap;",
     "uniform int combine;",

     "#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )",

       "uniform bool useRefract;",
       "uniform float refractionRatio;",

     "#else",

       "varying vec3 vReflect;",

     "#endif",

   "#endif"

 ].join("\n"),

 "envmap_fragment": [

   "#ifdef USE_ENVMAP",

     "vec3 reflectVec;",

     "#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )",

       "vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );",

       "if ( useRefract ) {",

         "reflectVec = refract( cameraToVertex, normal, refractionRatio );",

       "} else { ",

         "reflectVec = reflect( cameraToVertex, normal );",

       "}",

     "#else",

       "reflectVec = vReflect;",

     "#endif",

     "#ifdef DOUBLE_SIDED",

       "float flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );",
       "vec4 cubeColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );",

     "#else",

       "vec4 cubeColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );",

     "#endif",

     "#ifdef GAMMA_INPUT",

       "cubeColor.xyz *= cubeColor.xyz;",

     "#endif",

     "if ( combine == 1 ) {",

       "gl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, specularStrength * reflectivity );",

     "} else if ( combine == 2 ) {",

       "gl_FragColor.xyz += cubeColor.xyz * specularStrength * reflectivity;",

     "} else {",

       "gl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * cubeColor.xyz, specularStrength * reflectivity );",

     "}",

   "#endif"

 ].join("\n"),

 "envmap_pars_vertex": [

   "#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP )",

     "varying vec3 vReflect;",

     "uniform float refractionRatio;",
     "uniform bool useRefract;",

   "#endif"

 ].join("\n"),

 "worldpos_vertex" : [

   "#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )",

     "#ifdef USE_SKINNING",

       "vec4 worldPosition = modelMatrix * skinned;",

     "#endif",

     "#if defined( USE_MORPHTARGETS ) && ! defined( USE_SKINNING )",

       "vec4 worldPosition = modelMatrix * vec4( morphed, 1.0 );",

     "#endif",

     "#if ! defined( USE_MORPHTARGETS ) && ! defined( USE_SKINNING )",

       "vec4 worldPosition = modelMatrix * vec4( position, 1.0 );",

     "#endif",

   "#endif"

 ].join("\n"),

 "envmap_vertex" : [

   "#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP )",

     "vec3 worldNormal = mat3( modelMatrix[ 0 ].xyz, modelMatrix[ 1 ].xyz, modelMatrix[ 2 ].xyz ) * objectNormal;",
     "worldNormal = normalize( worldNormal );",

     "vec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );",

     "if ( useRefract ) {",

       "vReflect = refract( cameraToVertex, worldNormal, refractionRatio );",

     "} else {",

       "vReflect = reflect( cameraToVertex, worldNormal );",

     "}",

   "#endif"

 ].join("\n"),

 // COLOR MAP (particles)

 "map_particle_pars_fragment": [

   "#ifdef USE_MAP",

     "uniform sampler2D map;",

   "#endif"

 ].join("\n"),


 "map_particle_fragment": [

   "#ifdef USE_MAP",

     "gl_FragColor = gl_FragColor * texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) );",

   "#endif"

 ].join("\n"),

 // COLOR MAP (triangles)

 "map_pars_vertex": [

   "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP )",

     "varying vec2 vUv;",
     "uniform vec4 offsetRepeat;",

   "#endif"

 ].join("\n"),

 "map_pars_fragment": [

   "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP )",

     "varying vec2 vUv;",

   "#endif",

   "#ifdef USE_MAP",

     "uniform sampler2D map;",

   "#endif"

 ].join("\n"),

 "map_vertex": [

   "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP )",

     "vUv = uv * offsetRepeat.zw + offsetRepeat.xy;",

   "#endif"

 ].join("\n"),

 "map_fragment": [

   "#ifdef USE_MAP",

     "vec4 texelColor = texture2D( map, vUv );",

     "#ifdef GAMMA_INPUT",

       "texelColor.xyz *= texelColor.xyz;",

     "#endif",

     "gl_FragColor = gl_FragColor * texelColor;",

   "#endif"

 ].join("\n"),

 // LIGHT MAP

 "lightmap_pars_fragment": [

   "#ifdef USE_LIGHTMAP",

     "varying vec2 vUv2;",
     "uniform sampler2D lightMap;",

   "#endif"

 ].join("\n"),

 "lightmap_pars_vertex": [

   "#ifdef USE_LIGHTMAP",

     "varying vec2 vUv2;",

   "#endif"

 ].join("\n"),

 "lightmap_fragment": [

   "#ifdef USE_LIGHTMAP",

     "gl_FragColor = gl_FragColor * texture2D( lightMap, vUv2 );",

   "#endif"

 ].join("\n"),

 "lightmap_vertex": [

   "#ifdef USE_LIGHTMAP",

     "vUv2 = uv2;",

   "#endif"

 ].join("\n"),

 // BUMP MAP

 "bumpmap_pars_fragment": [

   "#ifdef USE_BUMPMAP",

     "uniform sampler2D bumpMap;",
     "uniform float bumpScale;",

     // Derivative maps - bump mapping unparametrized surfaces by Morten Mikkelsen
     //  http://mmikkelsen3d.blogspot.sk/2011/07/derivative-maps.html

     // Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2)

     "vec2 dHdxy_fwd() {",

       "vec2 dSTdx = dFdx( vUv );",
       "vec2 dSTdy = dFdy( vUv );",

       "float Hll = bumpScale * texture2D( bumpMap, vUv ).x;",
       "float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;",
       "float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;",

       "return vec2( dBx, dBy );",

     "}",

     "vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {",

       "vec3 vSigmaX = dFdx( surf_pos );",
       "vec3 vSigmaY = dFdy( surf_pos );",
       "vec3 vN = surf_norm;",   // normalized

       "vec3 R1 = cross( vSigmaY, vN );",
       "vec3 R2 = cross( vN, vSigmaX );",

       "float fDet = dot( vSigmaX, R1 );",

       "vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );",
       "return normalize( abs( fDet ) * surf_norm - vGrad );",

     "}",

   "#endif"

 ].join("\n"),

 // NORMAL MAP

 "normalmap_pars_fragment": [

   "#ifdef USE_NORMALMAP",

     "uniform sampler2D normalMap;",
     "uniform vec2 normalScale;",

     // Per-Pixel Tangent Space Normal Mapping
     // http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html

     "vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {",

       "vec3 q0 = dFdx( eye_pos.xyz );",
       "vec3 q1 = dFdy( eye_pos.xyz );",
       "vec2 st0 = dFdx( vUv.st );",
       "vec2 st1 = dFdy( vUv.st );",

       "vec3 S = normalize(  q0 * st1.t - q1 * st0.t );",
       "vec3 T = normalize( -q0 * st1.s + q1 * st0.s );",
       "vec3 N = normalize( surf_norm );",

       "vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;",
       "mapN.xy = normalScale * mapN.xy;",
       "mat3 tsn = mat3( S, T, N );",
       "return normalize( tsn * mapN );",

     "}",

   "#endif"

 ].join("\n"),

 // SPECULAR MAP

 "specularmap_pars_fragment": [

   "#ifdef USE_SPECULARMAP",

     "uniform sampler2D specularMap;",

   "#endif"

 ].join("\n"),

 "specularmap_fragment": [

   "float specularStrength;",

   "#ifdef USE_SPECULARMAP",

     "vec4 texelSpecular = texture2D( specularMap, vUv );",
     "specularStrength = texelSpecular.r;",

   "#else",

     "specularStrength = 1.0;",

   "#endif"

 ].join("\n"),

 // LIGHTS LAMBERT

 "lights_lambert_pars_vertex": [

   "uniform vec3 ambient;",
   "uniform vec3 diffuse;",
   "uniform vec3 emissive;",

   "uniform vec3 ambientLightColor;",

   "#if MAX_DIR_LIGHTS > 0",

     "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
     "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",

   "#endif",

   "#if MAX_HEMI_LIGHTS > 0",

     "uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
     "uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
     "uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];",

   "#endif",

   "#if MAX_POINT_LIGHTS > 0",

     "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
     "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
     "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",

   "#endif",

   "#if MAX_SPOT_LIGHTS > 0",

     "uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];",
     "uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];",
     "uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];",
     "uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];",
     "uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];",
     "uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];",

   "#endif",

   "#ifdef WRAP_AROUND",

     "uniform vec3 wrapRGB;",

   "#endif"

 ].join("\n"),

 "lights_lambert_vertex": [

   "vLightFront = vec3( 0.0 );",

   "#ifdef DOUBLE_SIDED",

     "vLightBack = vec3( 0.0 );",

   "#endif",

   "transformedNormal = normalize( transformedNormal );",

   "#if MAX_DIR_LIGHTS > 0",

   "for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {",

     "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
     "vec3 dirVector = normalize( lDirection.xyz );",

     "float dotProduct = dot( transformedNormal, dirVector );",
     "vec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );",

     "#ifdef DOUBLE_SIDED",

       "vec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );",

       "#ifdef WRAP_AROUND",

         "vec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );",

       "#endif",

     "#endif",

     "#ifdef WRAP_AROUND",

       "vec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );",
       "directionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );",

       "#ifdef DOUBLE_SIDED",

         "directionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );",

       "#endif",

     "#endif",

     "vLightFront += directionalLightColor[ i ] * directionalLightWeighting;",

     "#ifdef DOUBLE_SIDED",

       "vLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;",

     "#endif",

   "}",

   "#endif",

   "#if MAX_POINT_LIGHTS > 0",

     "for( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",

       "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
       "vec3 lVector = lPosition.xyz - mvPosition.xyz;",

       "float lDistance = 1.0;",
       "if ( pointLightDistance[ i ] > 0.0 )",
         "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",

       "lVector = normalize( lVector );",
       "float dotProduct = dot( transformedNormal, lVector );",

       "vec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );",

       "#ifdef DOUBLE_SIDED",

         "vec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );",

         "#ifdef WRAP_AROUND",

           "vec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );",

         "#endif",

       "#endif",

       "#ifdef WRAP_AROUND",

         "vec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );",
         "pointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );",

         "#ifdef DOUBLE_SIDED",

           "pointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );",

         "#endif",

       "#endif",

       "vLightFront += pointLightColor[ i ] * pointLightWeighting * lDistance;",

       "#ifdef DOUBLE_SIDED",

         "vLightBack += pointLightColor[ i ] * pointLightWeightingBack * lDistance;",

       "#endif",

     "}",

   "#endif",

   "#if MAX_SPOT_LIGHTS > 0",

   "for( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",

   "vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
   "vec3 lVector = lPosition.xyz - mvPosition.xyz;",

   "float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - worldPosition.xyz ) );",

   "if ( spotEffect > spotLightAngleCos[ i ] ) {",

   "spotEffect = max( pow( spotEffect, spotLightExponent[ i ] ), 0.0 );",

   "float lDistance = 1.0;",
   "if ( spotLightDistance[ i ] > 0.0 )",
   "lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );",

   "lVector = normalize( lVector );",

   "float dotProduct = dot( transformedNormal, lVector );",
   "vec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );",

   "#ifdef DOUBLE_SIDED",

   "vec3 spotLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );",

   "#ifdef WRAP_AROUND",

   "vec3 spotLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );",

   "#endif",

   "#endif",

   "#ifdef WRAP_AROUND",

   "vec3 spotLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );",
   "spotLightWeighting = mix( spotLightWeighting, spotLightWeightingHalf, wrapRGB );",

   "#ifdef DOUBLE_SIDED",

   "spotLightWeightingBack = mix( spotLightWeightingBack, spotLightWeightingHalfBack, wrapRGB );",

   "#endif",

   "#endif",

   "vLightFront += spotLightColor[ i ] * spotLightWeighting * lDistance * spotEffect;",

   "#ifdef DOUBLE_SIDED",

   "vLightBack += spotLightColor[ i ] * spotLightWeightingBack * lDistance * spotEffect;",

   "#endif",

   "}",

   "}",

   "#endif",

   "#if MAX_HEMI_LIGHTS > 0",

     "for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",

       "vec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );",
       "vec3 lVector = normalize( lDirection.xyz );",

       "float dotProduct = dot( transformedNormal, lVector );",

       "float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
       "float hemiDiffuseWeightBack = -0.5 * dotProduct + 0.5;",

       "vLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",

       "#ifdef DOUBLE_SIDED",

         "vLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );",

       "#endif",

     "}",

   "#endif",

   "vLightFront = vLightFront * diffuse + ambient * ambientLightColor + emissive;",

   "#ifdef DOUBLE_SIDED",

     "vLightBack = vLightBack * diffuse + ambient * ambientLightColor + emissive;",

   "#endif"

 ].join("\n"),

 // LIGHTS PHONG

 "lights_phong_pars_vertex": [

   "#ifndef PHONG_PER_PIXEL",

   "#if MAX_POINT_LIGHTS > 0",

     "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
     "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",

     "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",

   "#endif",

   "#if MAX_SPOT_LIGHTS > 0",

     "uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];",
     "uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];",

     "varying vec4 vSpotLight[ MAX_SPOT_LIGHTS ];",

   "#endif",

   "#endif",

   "#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP )",

     "varying vec3 vWorldPosition;",

   "#endif"

 ].join("\n"),


 "lights_phong_vertex": [

   "#ifndef PHONG_PER_PIXEL",

   "#if MAX_POINT_LIGHTS > 0",

     "for( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",

       "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
       "vec3 lVector = lPosition.xyz - mvPosition.xyz;",

       "float lDistance = 1.0;",
       "if ( pointLightDistance[ i ] > 0.0 )",
         "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",

       "vPointLight[ i ] = vec4( lVector, lDistance );",

     "}",

   "#endif",

   "#if MAX_SPOT_LIGHTS > 0",

     "for( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",

       "vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
       "vec3 lVector = lPosition.xyz - mvPosition.xyz;",

       "float lDistance = 1.0;",
       "if ( spotLightDistance[ i ] > 0.0 )",
         "lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );",

       "vSpotLight[ i ] = vec4( lVector, lDistance );",

     "}",

   "#endif",

   "#endif",

   "#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP )",

     "vWorldPosition = worldPosition.xyz;",

   "#endif"

 ].join("\n"),

 "lights_phong_pars_fragment": [

   "uniform vec3 ambientLightColor;",

   "#if MAX_DIR_LIGHTS > 0",

     "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
     "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",

   "#endif",

   "#if MAX_HEMI_LIGHTS > 0",

     "uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
     "uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
     "uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];",

   "#endif",

   "#if MAX_POINT_LIGHTS > 0",

     "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",

     "#ifdef PHONG_PER_PIXEL",

       "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
       "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",

     "#else",

       "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",

     "#endif",

   "#endif",

   "#if MAX_SPOT_LIGHTS > 0",

     "uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];",
     "uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];",
     "uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];",
     "uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];",
     "uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];",

     "#ifdef PHONG_PER_PIXEL",

       "uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];",

     "#else",

       "varying vec4 vSpotLight[ MAX_SPOT_LIGHTS ];",

     "#endif",

   "#endif",

   "#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP )",

     "varying vec3 vWorldPosition;",

   "#endif",

   "#ifdef WRAP_AROUND",

     "uniform vec3 wrapRGB;",

   "#endif",

   "varying vec3 vViewPosition;",
   "varying vec3 vNormal;"

 ].join("\n"),

 "lights_phong_fragment": [

   "vec3 normal = normalize( vNormal );",
   "vec3 viewPosition = normalize( vViewPosition );",

   "#ifdef DOUBLE_SIDED",

     "normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );",

   "#endif",

   "#ifdef USE_NORMALMAP",

     "normal = perturbNormal2Arb( -viewPosition, normal );",

   "#elif defined( USE_BUMPMAP )",

     "normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );",

   "#endif",

   "#if MAX_POINT_LIGHTS > 0",

     "vec3 pointDiffuse  = vec3( 0.0 );",
     "vec3 pointSpecular = vec3( 0.0 );",

     "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",

       "#ifdef PHONG_PER_PIXEL",

         "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
         "vec3 lVector = lPosition.xyz + vViewPosition.xyz;",

         "float lDistance = 1.0;",
         "if ( pointLightDistance[ i ] > 0.0 )",
           "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",

         "lVector = normalize( lVector );",

       "#else",

         "vec3 lVector = normalize( vPointLight[ i ].xyz );",
         "float lDistance = vPointLight[ i ].w;",

       "#endif",

       // diffuse

       "float dotProduct = dot( normal, lVector );",

       "#ifdef WRAP_AROUND",

         "float pointDiffuseWeightFull = max( dotProduct, 0.0 );",
         "float pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );",

         "vec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );",

       "#else",

         "float pointDiffuseWeight = max( dotProduct, 0.0 );",

       "#endif",

       "pointDiffuse  += diffuse * pointLightColor[ i ] * pointDiffuseWeight * lDistance;",

       // specular

       "vec3 pointHalfVector = normalize( lVector + viewPosition );",
       "float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );",
       "float pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );",

       "#ifdef PHYSICALLY_BASED_SHADING",

         // 2.0 => 2.0001 is hack to work around ANGLE bug

         "float specularNormalization = ( shininess + 2.0001 ) / 8.0;",

         "vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, pointHalfVector ), 5.0 );",
         "pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance * specularNormalization;",

       "#else",

         "pointSpecular += specular * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance;",

       "#endif",

     "}",

   "#endif",

   "#if MAX_SPOT_LIGHTS > 0",

     "vec3 spotDiffuse  = vec3( 0.0 );",
     "vec3 spotSpecular = vec3( 0.0 );",

     "for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",

       "#ifdef PHONG_PER_PIXEL",

         "vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
         "vec3 lVector = lPosition.xyz + vViewPosition.xyz;",

         "float lDistance = 1.0;",
         "if ( spotLightDistance[ i ] > 0.0 )",
           "lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );",

         "lVector = normalize( lVector );",

       "#else",

         "vec3 lVector = normalize( vSpotLight[ i ].xyz );",
         "float lDistance = vSpotLight[ i ].w;",

       "#endif",

       "float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );",

       "if ( spotEffect > spotLightAngleCos[ i ] ) {",

         "spotEffect = max( pow( spotEffect, spotLightExponent[ i ] ), 0.0 );",

         // diffuse

         "float dotProduct = dot( normal, lVector );",

         "#ifdef WRAP_AROUND",

           "float spotDiffuseWeightFull = max( dotProduct, 0.0 );",
           "float spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );",

           "vec3 spotDiffuseWeight = mix( vec3 ( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );",

         "#else",

           "float spotDiffuseWeight = max( dotProduct, 0.0 );",

         "#endif",

         "spotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * lDistance * spotEffect;",

         // specular

         "vec3 spotHalfVector = normalize( lVector + viewPosition );",
         "float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );",
         "float spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );",

         "#ifdef PHYSICALLY_BASED_SHADING",

           // 2.0 => 2.0001 is hack to work around ANGLE bug

           "float specularNormalization = ( shininess + 2.0001 ) / 8.0;",

           "vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, spotHalfVector ), 5.0 );",
           "spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * specularNormalization * spotEffect;",

         "#else",

           "spotSpecular += specular * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * spotEffect;",

         "#endif",

       "}",

     "}",

   "#endif",

   "#if MAX_DIR_LIGHTS > 0",

     "vec3 dirDiffuse  = vec3( 0.0 );",
     "vec3 dirSpecular = vec3( 0.0 );" ,

     "for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {",

       "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
       "vec3 dirVector = normalize( lDirection.xyz );",

       // diffuse

       "float dotProduct = dot( normal, dirVector );",

       "#ifdef WRAP_AROUND",

         "float dirDiffuseWeightFull = max( dotProduct, 0.0 );",
         "float dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );",

         "vec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );",

       "#else",

         "float dirDiffuseWeight = max( dotProduct, 0.0 );",

       "#endif",

       "dirDiffuse  += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;",

       // specular

       "vec3 dirHalfVector = normalize( dirVector + viewPosition );",
       "float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );",
       "float dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );",

       "#ifdef PHYSICALLY_BASED_SHADING",

         /*
         // fresnel term from skin shader
         "const float F0 = 0.128;",

         "float base = 1.0 - dot( viewPosition, dirHalfVector );",
         "float exponential = pow( base, 5.0 );",

         "float fresnel = exponential + F0 * ( 1.0 - exponential );",
         */

         /*
         // fresnel term from fresnel shader
         "const float mFresnelBias = 0.08;",
         "const float mFresnelScale = 0.3;",
         "const float mFresnelPower = 5.0;",

         "float fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );",
         */

         // 2.0 => 2.0001 is hack to work around ANGLE bug

         "float specularNormalization = ( shininess + 2.0001 ) / 8.0;",

         //"dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;",

         "vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( dirVector, dirHalfVector ), 5.0 );",
         "dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;",

       "#else",

         "dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight;",

       "#endif",

     "}",

   "#endif",

   "#if MAX_HEMI_LIGHTS > 0",

     "vec3 hemiDiffuse  = vec3( 0.0 );",
     "vec3 hemiSpecular = vec3( 0.0 );" ,

     "for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",

       "vec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );",
       "vec3 lVector = normalize( lDirection.xyz );",

       // diffuse

       "float dotProduct = dot( normal, lVector );",
       "float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",

       "vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",

       "hemiDiffuse += diffuse * hemiColor;",

       // specular (sky light)

       "vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );",
       "float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;",
       "float hemiSpecularWeightSky = specularStrength * max( pow( hemiDotNormalHalfSky, shininess ), 0.0 );",

       // specular (ground light)

       "vec3 lVectorGround = -lVector;",

       "vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );",
       "float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;",
       "float hemiSpecularWeightGround = specularStrength * max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );",

       "#ifdef PHYSICALLY_BASED_SHADING",

         "float dotProductGround = dot( normal, lVectorGround );",

         // 2.0 => 2.0001 is hack to work around ANGLE bug

         "float specularNormalization = ( shininess + 2.0001 ) / 8.0;",

         "vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, hemiHalfVectorSky ), 5.0 );",
         "vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );",
         "hemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );",

       "#else",

         "hemiSpecular += specular * hemiColor * ( hemiSpecularWeightSky + hemiSpecularWeightGround ) * hemiDiffuseWeight;",

       "#endif",

     "}",

   "#endif",

   "vec3 totalDiffuse = vec3( 0.0 );",
   "vec3 totalSpecular = vec3( 0.0 );",

   "#if MAX_DIR_LIGHTS > 0",

     "totalDiffuse += dirDiffuse;",
     "totalSpecular += dirSpecular;",

   "#endif",

   "#if MAX_HEMI_LIGHTS > 0",

     "totalDiffuse += hemiDiffuse;",
     "totalSpecular += hemiSpecular;",

   "#endif",

   "#if MAX_POINT_LIGHTS > 0",

     "totalDiffuse += pointDiffuse;",
     "totalSpecular += pointSpecular;",

   "#endif",

   "#if MAX_SPOT_LIGHTS > 0",

     "totalDiffuse += spotDiffuse;",
     "totalSpecular += spotSpecular;",

   "#endif",

   "#ifdef METAL",

     "gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient + totalSpecular );",

   "#else",

     "gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient ) + totalSpecular;",

   "#endif"

 ].join("\n"),

 // VERTEX COLORS

 "color_pars_fragment": [

   "#ifdef USE_COLOR",

     "varying vec3 vColor;",

   "#endif"

 ].join("\n"),


 "color_fragment": [

   "#ifdef USE_COLOR",

     "gl_FragColor = gl_FragColor * vec4( vColor, opacity );",

   "#endif"

 ].join("\n"),

 "color_pars_vertex": [

   "#ifdef USE_COLOR",

     "varying vec3 vColor;",

   "#endif"

 ].join("\n"),


 "color_vertex": [

   "#ifdef USE_COLOR",

     "#ifdef GAMMA_INPUT",

       "vColor = color * color;",

     "#else",

       "vColor = color;",

     "#endif",

   "#endif"

 ].join("\n"),

 // SKINNING

 "skinning_pars_vertex": [

   "#ifdef USE_SKINNING",

     "#ifdef BONE_TEXTURE",

       "uniform sampler2D boneTexture;",

       "mat4 getBoneMatrix( const in float i ) {",

         "float j = i * 4.0;",
         "float x = mod( j, N_BONE_PIXEL_X );",
         "float y = floor( j / N_BONE_PIXEL_X );",

         "const float dx = 1.0 / N_BONE_PIXEL_X;",
         "const float dy = 1.0 / N_BONE_PIXEL_Y;",

         "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 boneGlobalMatrices[ MAX_BONES ];",

       "mat4 getBoneMatrix( const in float i ) {",

         "mat4 bone = boneGlobalMatrices[ int(i) ];",
         "return bone;",

       "}",

     "#endif",

   "#endif"

 ].join("\n"),

 "skinbase_vertex": [

   "#ifdef USE_SKINNING",

     "mat4 boneMatX = getBoneMatrix( skinIndex.x );",
     "mat4 boneMatY = getBoneMatrix( skinIndex.y );",

   "#endif"

 ].join("\n"),

 "skinning_vertex": [

   "#ifdef USE_SKINNING",

     "#ifdef USE_MORPHTARGETS",

       "vec4 skinVertex = vec4( morphed, 1.0 );",

     "#else",

       "vec4 skinVertex = vec4( position, 1.0 );",

     "#endif",

     "vec4 skinned  = boneMatX * skinVertex * skinWeight.x;",
     "skinned    += boneMatY * skinVertex * skinWeight.y;",

   "#endif"

 ].join("\n"),

 // MORPHING

 "morphtarget_pars_vertex": [

   "#ifdef USE_MORPHTARGETS",

     "#ifndef USE_MORPHNORMALS",

     "uniform float morphTargetInfluences[ 8 ];",

     "#else",

     "uniform float morphTargetInfluences[ 4 ];",

     "#endif",

   "#endif"

 ].join("\n"),

 "morphtarget_vertex": [

   "#ifdef USE_MORPHTARGETS",

     "vec3 morphed = vec3( 0.0 );",
     "morphed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];",
     "morphed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];",
     "morphed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];",
     "morphed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];",

     "#ifndef USE_MORPHNORMALS",

     "morphed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];",
     "morphed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];",
     "morphed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];",
     "morphed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];",

     "#endif",

     "morphed += position;",

   "#endif"

 ].join("\n"),

 "default_vertex" : [

     "vec4 mvPosition;",

     "#ifdef USE_SKINNING",

       "mvPosition = modelViewMatrix * skinned;",

     "#endif",

     "#if !defined( USE_SKINNING ) && defined( USE_MORPHTARGETS )",

       "mvPosition = modelViewMatrix * vec4( morphed, 1.0 );",

     "#endif",

     "#if !defined( USE_SKINNING ) && ! defined( USE_MORPHTARGETS )",

       "mvPosition = modelViewMatrix * vec4( position, 1.0 );",

     "#endif",

     "gl_Position = projectionMatrix * mvPosition;"

 ].join("\n"),

 "morphnormal_vertex": [

   "#ifdef USE_MORPHNORMALS",

     "vec3 morphedNormal = vec3( 0.0 );",

     "morphedNormal +=  ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];",
     "morphedNormal +=  ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];",
     "morphedNormal +=  ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];",
     "morphedNormal +=  ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];",

     "morphedNormal += normal;",

   "#endif"

 ].join("\n"),

 "skinnormal_vertex": [

   "#ifdef USE_SKINNING",

     "mat4 skinMatrix = skinWeight.x * boneMatX;",
     "skinMatrix   += skinWeight.y * boneMatY;",

     "#ifdef USE_MORPHNORMALS",

     "vec4 skinnedNormal = skinMatrix * vec4( morphedNormal, 0.0 );",

     "#else",

     "vec4 skinnedNormal = skinMatrix * vec4( normal, 0.0 );",

     "#endif",

   "#endif"

 ].join("\n"),

 "defaultnormal_vertex": [

    "vec3 objectNormal;",

    "#ifdef USE_SKINNING",

       "objectNormal = skinnedNormal.xyz;",

    "#endif",

    "#if !defined( USE_SKINNING ) && defined( USE_MORPHNORMALS )",

       "objectNormal = morphedNormal;",

    "#endif",

    "#if !defined( USE_SKINNING ) && ! defined( USE_MORPHNORMALS )",

       "objectNormal = normal;",

    "#endif",

    "#ifdef FLIP_SIDED",

       "objectNormal = -objectNormal;",

    "#endif",

    "vec3 transformedNormal = normalMatrix * objectNormal;"

 ].join("\n"),

 // SHADOW MAP

 // based on SpiderGL shadow map and Fabien Sanglard's GLSL shadow mapping examples
 //  http://spidergl.org/example.php?id=6
 //  http://fabiensanglard.net/shadowmapping

 "shadowmap_pars_fragment": [

   "#ifdef USE_SHADOWMAP",

     "uniform sampler2D shadowMap[ MAX_SHADOWS ];",
     "uniform vec2 shadowMapSize[ MAX_SHADOWS ];",

     "uniform float shadowDarkness[ MAX_SHADOWS ];",
     "uniform float shadowBias[ MAX_SHADOWS ];",

     "varying vec4 vShadowCoord[ MAX_SHADOWS ];",

     "float unpackDepth( const in vec4 rgba_depth ) {",

       "const vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );",
       "float depth = dot( rgba_depth, bit_shift );",
       "return depth;",

     "}",

   "#endif"

 ].join("\n"),

 "shadowmap_fragment": [

   "#ifdef USE_SHADOWMAP",

     "#ifdef SHADOWMAP_DEBUG",

       "vec3 frustumColors[3];",
       "frustumColors[0] = vec3( 1.0, 0.5, 0.0 );",
       "frustumColors[1] = vec3( 0.0, 1.0, 0.8 );",
       "frustumColors[2] = vec3( 0.0, 0.5, 1.0 );",

     "#endif",

     "#ifdef SHADOWMAP_CASCADE",

       "int inFrustumCount = 0;",

     "#endif",

     "float fDepth;",
     "vec3 shadowColor = vec3( 1.0 );",

     "for( int i = 0; i < MAX_SHADOWS; i ++ ) {",

       "vec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;",

       // "if ( something && something )"     breaks ATI OpenGL shader compiler
       // "if ( all( something, something ) )"  using this instead

       "bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );",
       "bool inFrustum = all( inFrustumVec );",

       // don't shadow pixels outside of light frustum
       // use just first frustum (for cascades)
       // don't shadow pixels behind far plane of light frustum

       "#ifdef SHADOWMAP_CASCADE",

         "inFrustumCount += int( inFrustum );",
         "bvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 );",

       "#else",

         "bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );",

       "#endif",

       "bool frustumTest = all( frustumTestVec );",

       "if ( frustumTest ) {",

         "shadowCoord.z += shadowBias[ i ];",

         "#if defined( SHADOWMAP_TYPE_PCF )",

           // Percentage-close filtering
           // (9 pixel kernel)
           // http://fabiensanglard.net/shadowmappingPCF/

           "float shadow = 0.0;",

           /*
           // nested loops breaks shader compiler / validator on some ATI cards when using OpenGL
           // must enroll loop manually

           "for ( float y = -1.25; y <= 1.25; y += 1.25 )",
             "for ( float x = -1.25; x <= 1.25; x += 1.25 ) {",

               "vec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );",

               // doesn't seem to produce any noticeable visual difference compared to simple "texture2D" lookup
               //"vec4 rgbaDepth = texture2DProj( shadowMap[ i ], vec4( vShadowCoord[ i ].w * ( vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ), 0.05, vShadowCoord[ i ].w ) );",

               "float fDepth = unpackDepth( rgbaDepth );",

               "if ( fDepth < shadowCoord.z )",
                 "shadow += 1.0;",

           "}",

           "shadow /= 9.0;",

           */

           "const float shadowDelta = 1.0 / 9.0;",

           "float xPixelOffset = 1.0 / shadowMapSize[ i ].x;",
           "float yPixelOffset = 1.0 / shadowMapSize[ i ].y;",

           "float dx0 = -1.25 * xPixelOffset;",
           "float dy0 = -1.25 * yPixelOffset;",
           "float dx1 = 1.25 * xPixelOffset;",
           "float dy1 = 1.25 * yPixelOffset;",

           "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );",
           "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",

           "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );",
           "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",

           "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );",
           "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",

           "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );",
           "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",

           "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );",
           "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",

           "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );",
           "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",

           "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );",
           "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",

           "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );",
           "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",

           "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );",
           "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",

           "shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );",

         "#elif defined( SHADOWMAP_TYPE_PCF_SOFT )",

           // Percentage-close filtering
           // (9 pixel kernel)
           // http://fabiensanglard.net/shadowmappingPCF/

           "float shadow = 0.0;",

           "float xPixelOffset = 1.0 / shadowMapSize[ i ].x;",
           "float yPixelOffset = 1.0 / shadowMapSize[ i ].y;",

           "float dx0 = -1.0 * xPixelOffset;",
           "float dy0 = -1.0 * yPixelOffset;",
           "float dx1 = 1.0 * xPixelOffset;",
           "float dy1 = 1.0 * yPixelOffset;",

           "mat3 shadowKernel;",
           "mat3 depthKernel;",

           "depthKernel[0][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );",
           "if ( depthKernel[0][0] < shadowCoord.z ) shadowKernel[0][0] = 0.25;",
           "else shadowKernel[0][0] = 0.0;",

           "depthKernel[0][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );",
           "if ( depthKernel[0][1] < shadowCoord.z ) shadowKernel[0][1] = 0.25;",
           "else shadowKernel[0][1] = 0.0;",

           "depthKernel[0][2] = unpackDepth( texture2D( shadowMap[ i], shadowCoord.xy + vec2( dx0, dy1 ) ) );",
           "if ( depthKernel[0][2] < shadowCoord.z ) shadowKernel[0][2] = 0.25;",
           "else shadowKernel[0][2] = 0.0;",

           "depthKernel[1][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );",
           "if ( depthKernel[1][0] < shadowCoord.z ) shadowKernel[1][0] = 0.25;",
           "else shadowKernel[1][0] = 0.0;",

           "depthKernel[1][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );",
           "if ( depthKernel[1][1] < shadowCoord.z ) shadowKernel[1][1] = 0.25;",
           "else shadowKernel[1][1] = 0.0;",

           "depthKernel[1][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );",
           "if ( depthKernel[1][2] < shadowCoord.z ) shadowKernel[1][2] = 0.25;",
           "else shadowKernel[1][2] = 0.0;",

           "depthKernel[2][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );",
           "if ( depthKernel[2][0] < shadowCoord.z ) shadowKernel[2][0] = 0.25;",
           "else shadowKernel[2][0] = 0.0;",

           "depthKernel[2][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );",
           "if ( depthKernel[2][1] < shadowCoord.z ) shadowKernel[2][1] = 0.25;",
           "else shadowKernel[2][1] = 0.0;",

           "depthKernel[2][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );",
           "if ( depthKernel[2][2] < shadowCoord.z ) shadowKernel[2][2] = 0.25;",
           "else shadowKernel[2][2] = 0.0;",

           "vec2 fractionalCoord = 1.0 - fract( shadowCoord.xy * shadowMapSize[i].xy );",

           "shadowKernel[0] = mix( shadowKernel[1], shadowKernel[0], fractionalCoord.x );",
           "shadowKernel[1] = mix( shadowKernel[2], shadowKernel[1], fractionalCoord.x );",

           "vec4 shadowValues;",
           "shadowValues.x = mix( shadowKernel[0][1], shadowKernel[0][0], fractionalCoord.y );",
           "shadowValues.y = mix( shadowKernel[0][2], shadowKernel[0][1], fractionalCoord.y );",
           "shadowValues.z = mix( shadowKernel[1][1], shadowKernel[1][0], fractionalCoord.y );",
           "shadowValues.w = mix( shadowKernel[1][2], shadowKernel[1][1], fractionalCoord.y );",

           "shadow = dot( shadowValues, vec4( 1.0 ) );",

           "shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );",

         "#else",

           "vec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );",
           "float fDepth = unpackDepth( rgbaDepth );",

           "if ( fDepth < shadowCoord.z )",

             // spot with multiple shadows is darker

             "shadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );",

             // spot with multiple shadows has the same color as single shadow spot

             //"shadowColor = min( shadowColor, vec3( shadowDarkness[ i ] ) );",

         "#endif",

       "}",


       "#ifdef SHADOWMAP_DEBUG",

         "#ifdef SHADOWMAP_CASCADE",

           "if ( inFrustum && inFrustumCount == 1 ) gl_FragColor.xyz *= frustumColors[ i ];",

         "#else",

           "if ( inFrustum ) gl_FragColor.xyz *= frustumColors[ i ];",

         "#endif",

       "#endif",

     "}",

     "#ifdef GAMMA_OUTPUT",

       "shadowColor *= shadowColor;",

     "#endif",

     "gl_FragColor.xyz = gl_FragColor.xyz * shadowColor;",

   "#endif"

 ].join("\n"),

 "shadowmap_pars_vertex": [

   "#ifdef USE_SHADOWMAP",

     "varying vec4 vShadowCoord[ MAX_SHADOWS ];",
     "uniform mat4 shadowMatrix[ MAX_SHADOWS ];",

   "#endif"

 ].join("\n"),

 "shadowmap_vertex": [

   "#ifdef USE_SHADOWMAP",

     "for( int i = 0; i < MAX_SHADOWS; i ++ ) {",

       "vShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;",

     "}",

   "#endif"

 ].join("\n"),

 // ALPHATEST

 "alphatest_fragment": [

   "#ifdef ALPHATEST",

     "if ( gl_FragColor.a < ALPHATEST ) discard;",

   "#endif"

 ].join("\n"),

 // LINEAR SPACE

 "linear_to_gamma_fragment": [

   "#ifdef GAMMA_OUTPUT",

     "gl_FragColor.xyz = sqrt( gl_FragColor.xyz );",

   "#endif"

 ].join("\n")
};
 }
 return __ShaderChunk;
}

final ShaderLib #

get ShaderLib  {
 if (__ShaderLib == null) {
   __ShaderLib = {

'depth': {

   'uniforms': {

     "mNear": new Uniform.float(1.0),
     "mFar" :  new Uniform.float(2000.0),
     "opacity" :  new Uniform.float(1.0)

   },

   'vertexShader': [

     "void main() {",

       "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",

     "}"

   ].join("\n"),

   'fragmentShader': [

     "uniform float mNear;",
     "uniform float mFar;",
     "uniform float opacity;",

     "void main() {",

       "float depth = gl_FragCoord.z / gl_FragCoord.w;",
       "float color = 1.0 - smoothstep( mNear, mFar, depth );",
       "gl_FragColor = vec4( vec3( color ), opacity );",

     "}"

   ].join("\n")

 },

'normal': {

   'uniforms': {

     "opacity" : new Uniform.float(1.0)

   },

   'vertexShader': [

     "varying vec3 vNormal;",

     "void main() {",

       "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
       "vNormal = normalize( normalMatrix * normal );",

       "gl_Position = projectionMatrix * mvPosition;",

     "}"

   ].join("\n"),

   'fragmentShader': [

     "uniform float opacity;",
     "varying vec3 vNormal;",

     "void main() {",

       "gl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );",

     "}"

   ].join("\n")

 },

'basic': {
 'uniforms': UniformsUtils.merge( [UniformsLib[ "common" ],
                                   UniformsLib[ "fog" ],
                                   UniformsLib[ "shadowmap" ]] ),

 'vertexShader': [

                ShaderChunk[ "map_pars_vertex" ],
                ShaderChunk[ "lightmap_pars_vertex" ],
                ShaderChunk[ "envmap_pars_vertex" ],
                ShaderChunk[ "color_pars_vertex" ],
                ShaderChunk[ "morphtarget_pars_vertex" ],
                ShaderChunk[ "skinning_pars_vertex" ],
                ShaderChunk[ "shadowmap_pars_vertex" ],

                "void main() {",

                  ShaderChunk[ "map_vertex" ],
                  ShaderChunk[ "lightmap_vertex" ],
                  ShaderChunk[ "color_vertex" ],
                  ShaderChunk[ "skinbase_vertex" ],

                  "#ifdef USE_ENVMAP",

                   ShaderChunk[ "morphnormal_vertex" ],
                   ShaderChunk[ "skinnormal_vertex" ],
                   ShaderChunk[ "defaultnormal_vertex" ],

                  "#endif",

                  ShaderChunk[ "morphtarget_vertex" ],
                  ShaderChunk[ "skinning_vertex" ],
                  ShaderChunk[ "default_vertex" ],

                  ShaderChunk[ "worldpos_vertex" ],
                  ShaderChunk[ "envmap_vertex" ],
                  ShaderChunk[ "shadowmap_vertex" ],

                "}"

                ].join("\n"),

  'fragmentShader': [

                   "uniform vec3 diffuse;",
                   "uniform float opacity;",

                   ShaderChunk[ "color_pars_fragment" ],
                   ShaderChunk[ "map_pars_fragment" ],
                   ShaderChunk[ "lightmap_pars_fragment" ],
                   ShaderChunk[ "envmap_pars_fragment" ],
                   ShaderChunk[ "fog_pars_fragment" ],
                   ShaderChunk[ "shadowmap_pars_fragment" ],
                   ShaderChunk[ "specularmap_pars_fragment" ],

                   "void main() {",

                   "gl_FragColor = vec4( diffuse, opacity );",

                   ShaderChunk[ "map_fragment" ],
                   ShaderChunk[ "alphatest_fragment" ],
                   ShaderChunk[ "specularmap_fragment" ],
                   ShaderChunk[ "lightmap_fragment" ],
                   ShaderChunk[ "color_fragment" ],
                   ShaderChunk[ "envmap_fragment" ],
                   ShaderChunk[ "shadowmap_fragment" ],

                   ShaderChunk[ "linear_to_gamma_fragment" ],

                   ShaderChunk[ "fog_fragment" ],

                   "}"

                   ].join("\n")

 },

 'lambert': {

   'uniforms': UniformsUtils.merge( [

     UniformsLib[ "common" ],
     UniformsLib[ "fog" ],
     UniformsLib[ "lights" ],
     UniformsLib[ "shadowmap" ],

     {
       "ambient"  : new Uniform.color(0xffffff),
       "emissive" : new Uniform.color(0x000000),
       "wrapRGB"  : new Uniform.vector3(1.0, 1.0, 1.0)
     }

   ] ),

   'vertexShader': [

     "#define LAMBERT",

     "varying vec3 vLightFront;",

     "#ifdef DOUBLE_SIDED",

       "varying vec3 vLightBack;",

     "#endif",

     ShaderChunk[ "map_pars_vertex" ],
     ShaderChunk[ "lightmap_pars_vertex" ],
     ShaderChunk[ "envmap_pars_vertex" ],
     ShaderChunk[ "lights_lambert_pars_vertex" ],
     ShaderChunk[ "color_pars_vertex" ],
     ShaderChunk[ "morphtarget_pars_vertex" ],
     ShaderChunk[ "skinning_pars_vertex" ],
     ShaderChunk[ "shadowmap_pars_vertex" ],

     "void main() {",

       ShaderChunk[ "map_vertex" ],
       ShaderChunk[ "lightmap_vertex" ],
       ShaderChunk[ "color_vertex" ],

       ShaderChunk[ "morphnormal_vertex" ],
       ShaderChunk[ "skinbase_vertex" ],
       ShaderChunk[ "skinnormal_vertex" ],
       ShaderChunk[ "defaultnormal_vertex" ],

       ShaderChunk[ "morphtarget_vertex" ],
       ShaderChunk[ "skinning_vertex" ],
       ShaderChunk[ "default_vertex" ],

       ShaderChunk[ "worldpos_vertex" ],
       ShaderChunk[ "envmap_vertex" ],
       ShaderChunk[ "lights_lambert_vertex" ],
       ShaderChunk[ "shadowmap_vertex" ],

     "}"

   ].join("\n"),

   'fragmentShader': [

     "uniform float opacity;",

     "varying vec3 vLightFront;",

     "#ifdef DOUBLE_SIDED",

       "varying vec3 vLightBack;",

     "#endif",

     ShaderChunk[ "color_pars_fragment" ],
     ShaderChunk[ "map_pars_fragment" ],
     ShaderChunk[ "lightmap_pars_fragment" ],
     ShaderChunk[ "envmap_pars_fragment" ],
     ShaderChunk[ "fog_pars_fragment" ],
     ShaderChunk[ "shadowmap_pars_fragment" ],
     ShaderChunk[ "specularmap_pars_fragment" ],

     "void main() {",

       "gl_FragColor = vec4( vec3 ( 1.0 ), opacity );",

       ShaderChunk[ "map_fragment" ],
       ShaderChunk[ "alphatest_fragment" ],
       ShaderChunk[ "specularmap_fragment" ],

       "#ifdef DOUBLE_SIDED",

         //"float isFront = float( gl_FrontFacing );",
         //"gl_FragColor.xyz *= isFront * vLightFront + ( 1.0 - isFront ) * vLightBack;",

         "if ( gl_FrontFacing )",
           "gl_FragColor.xyz *= vLightFront;",
         "else",
           "gl_FragColor.xyz *= vLightBack;",

       "#else",

         "gl_FragColor.xyz *= vLightFront;",

       "#endif",

       ShaderChunk[ "lightmap_fragment" ],
       ShaderChunk[ "color_fragment" ],
       ShaderChunk[ "envmap_fragment" ],
       ShaderChunk[ "shadowmap_fragment" ],

       ShaderChunk[ "linear_to_gamma_fragment" ],

       ShaderChunk[ "fog_fragment" ],

     "}"

   ].join("\n")

 },

 'phong': {

   'uniforms': UniformsUtils.merge( [

     UniformsLib[ "common" ],
     UniformsLib[ "bump" ],
     UniformsLib[ "normalmap" ],
     UniformsLib[ "fog" ],
     UniformsLib[ "lights" ],
     UniformsLib[ "shadowmap" ],

     {
       "ambient"  : new Uniform.color(0xffffff),
       "emissive" : new Uniform.color(0x000000),
       "specular" : new Uniform.color(0x111111),
       "shininess": new Uniform.float(30.0),
       "wrapRGB"  : new Uniform.vector3(1.0, 1.0, 1.0)
     }

   ] ),

   'vertexShader': [

     "#define PHONG",

     "varying vec3 vViewPosition;",
     "varying vec3 vNormal;",

     ShaderChunk[ "map_pars_vertex" ],
     ShaderChunk[ "lightmap_pars_vertex" ],
     ShaderChunk[ "envmap_pars_vertex" ],
     ShaderChunk[ "lights_phong_pars_vertex" ],
     ShaderChunk[ "color_pars_vertex" ],
     ShaderChunk[ "morphtarget_pars_vertex" ],
     ShaderChunk[ "skinning_pars_vertex" ],
     ShaderChunk[ "shadowmap_pars_vertex" ],

     "void main() {",

       ShaderChunk[ "map_vertex" ],
       ShaderChunk[ "lightmap_vertex" ],
       ShaderChunk[ "color_vertex" ],

       ShaderChunk[ "morphnormal_vertex" ],
       ShaderChunk[ "skinbase_vertex" ],
       ShaderChunk[ "skinnormal_vertex" ],
       ShaderChunk[ "defaultnormal_vertex" ],

       "vNormal = normalize( transformedNormal );",

       ShaderChunk[ "morphtarget_vertex" ],
       ShaderChunk[ "skinning_vertex" ],
       ShaderChunk[ "default_vertex" ],

       "vViewPosition = -mvPosition.xyz;",

       ShaderChunk[ "worldpos_vertex" ],
       ShaderChunk[ "envmap_vertex" ],
       ShaderChunk[ "lights_phong_vertex" ],
       ShaderChunk[ "shadowmap_vertex" ],

     "}"

   ].join("\n"),

   'fragmentShader': [

     "uniform vec3 diffuse;",
     "uniform float opacity;",

     "uniform vec3 ambient;",
     "uniform vec3 emissive;",
     "uniform vec3 specular;",
     "uniform float shininess;",

     ShaderChunk[ "color_pars_fragment" ],
     ShaderChunk[ "map_pars_fragment" ],
     ShaderChunk[ "lightmap_pars_fragment" ],
     ShaderChunk[ "envmap_pars_fragment" ],
     ShaderChunk[ "fog_pars_fragment" ],
     ShaderChunk[ "lights_phong_pars_fragment" ],
     ShaderChunk[ "shadowmap_pars_fragment" ],
     ShaderChunk[ "bumpmap_pars_fragment" ],
     ShaderChunk[ "normalmap_pars_fragment" ],
     ShaderChunk[ "specularmap_pars_fragment" ],

     "void main() {",

       "gl_FragColor = vec4( vec3 ( 1.0 ), opacity );",

       ShaderChunk[ "map_fragment" ],
       ShaderChunk[ "alphatest_fragment" ],
       ShaderChunk[ "specularmap_fragment" ],

       ShaderChunk[ "lights_phong_fragment" ],

       ShaderChunk[ "lightmap_fragment" ],
       ShaderChunk[ "color_fragment" ],
       ShaderChunk[ "envmap_fragment" ],
       ShaderChunk[ "shadowmap_fragment" ],

       ShaderChunk[ "linear_to_gamma_fragment" ],

       ShaderChunk[ "fog_fragment" ],

     "}"

   ].join("\n")

 },

 'particle_basic': {

   'uniforms':  UniformsUtils.merge( [

     UniformsLib[ "particle" ],
     UniformsLib[ "shadowmap" ]

   ] ),

   'vertexShader': [

     "uniform float size;",
     "uniform float scale;",

     ShaderChunk[ "color_pars_vertex" ],
     ShaderChunk[ "shadowmap_pars_vertex" ],

     "void main() {",

       ShaderChunk[ "color_vertex" ],

       "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",

       "#ifdef USE_SIZEATTENUATION",
         "gl_PointSize = size * ( scale / length( mvPosition.xyz ) );",
       "#else",
         "gl_PointSize = size;",
       "#endif",

       "gl_Position = projectionMatrix * mvPosition;",

       ShaderChunk[ "worldpos_vertex" ],
       ShaderChunk[ "shadowmap_vertex" ],

     "}"

   ].join("\n"),

   'fragmentShader': [

     "uniform vec3 psColor;",
     "uniform float opacity;",

     ShaderChunk[ "color_pars_fragment" ],
     ShaderChunk[ "map_particle_pars_fragment" ],
     ShaderChunk[ "fog_pars_fragment" ],
     ShaderChunk[ "shadowmap_pars_fragment" ],

     "void main() {",

       "gl_FragColor = vec4( psColor, opacity );",

       ShaderChunk[ "map_particle_fragment" ],
       ShaderChunk[ "alphatest_fragment" ],
       ShaderChunk[ "color_fragment" ],
       ShaderChunk[ "shadowmap_fragment" ],
       ShaderChunk[ "fog_fragment" ],

     "}"

   ].join("\n")

 },
 'dashed': {

   "uniforms": UniformsUtils.merge( [

     UniformsLib[ "common" ],
     UniformsLib[ "fog" ],

     {
       "scale": new Uniform.float(1.0),
       "dashSize": new Uniform.float(1.0),
       "totalSize": new Uniform.float(2.0)
     }

   ] ),

   "vertexShader": [

     "uniform float scale;",
     "attribute float lineDistance;",

     "varying float vLineDistance;",

     ShaderChunk[ "color_pars_vertex" ],

     "void main() {",

       ShaderChunk[ "color_vertex" ],

       "vLineDistance = scale * lineDistance;",

       "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
       "gl_Position = projectionMatrix * mvPosition;",

     "}"

   ].join("\n"),

   "fragmentShader": [

     "uniform vec3 diffuse;",
     "uniform float opacity;",

     "uniform float dashSize;",
     "uniform float totalSize;",

     "varying float vLineDistance;",

     ShaderChunk[ "color_pars_fragment" ],
     ShaderChunk[ "fog_pars_fragment" ],

     "void main() {",

       "if ( mod( vLineDistance, totalSize ) > dashSize ) {",

         "discard;",

       "}",

       "gl_FragColor = vec4( diffuse, opacity );",

       ShaderChunk[ "color_fragment" ],
       ShaderChunk[ "fog_fragment" ],

     "}"

   ].join("\n")

 },
 // Depth encoding into RGBA texture
 //  based on SpiderGL shadow map example
 //    http://spidergl.org/example.php?id=6
 //  originally from
 //    http://www.gamedev.net/topic/442138-packing-a-float-into-a-a8r8g8b8-texture-shader/page__whichpage__1%25EF%25BF%25BD
 //  see also here:
 //    http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/

 'depthRGBA': {

   'uniforms': {},

   'vertexShader': [

     ShaderChunk[ "morphtarget_pars_vertex" ],
     ShaderChunk[ "skinning_pars_vertex" ],

     "void main() {",

       ShaderChunk[ "skinbase_vertex" ],
       ShaderChunk[ "morphtarget_vertex" ],
       ShaderChunk[ "skinning_vertex" ],
       ShaderChunk[ "default_vertex" ],

     "}"

   ].join("\n"),

   'fragmentShader': [

     "vec4 pack_depth( const in float depth ) {",

       "const vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );",
       "const vec4 bit_mask  = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );",
       "vec4 res = fract( depth * bit_shift );",
       "res -= res.xxyz * bit_mask;",
       "return res;",

     "}",

     "void main() {",

       "gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );",

       //"gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z / gl_FragCoord.w );",
       //"float z = ( ( gl_FragCoord.z / gl_FragCoord.w ) - 3.0 ) / ( 4000.0 - 3.0 );",
       //"gl_FragData[ 0 ] = pack_depth( z );",
       //"gl_FragData[ 0 ] = vec4( z, z, z, 1.0 );",

     "}"

   ].join("\n")

 }

   };
 }
 return __ShaderLib;
}

const int ShortType #

const int ShortType = 11

const int SmoothShading #

const int SmoothShading = 2

const int SrcAlphaFactor #

const int SrcAlphaFactor = 204

const int SrcAlphaSaturateFactor #

const int SrcAlphaSaturateFactor = 210

const int SrcColorFactor #

const int SrcColorFactor = 202

const int SubtractEquation #

const int SubtractEquation = 101

const int SubtractiveBlending #

const int SubtractiveBlending = 3

int TextureCount #

int TextureCount = 0

final UniformsLib #

get UniformsLib {
 if (__UniformsLib == null) {
   __UniformsLib = {
 "common": {

   "diffuse" : new Uniform.color(0xeeeeee),
   "opacity" : new Uniform.float(1.0),

   "map" : new Uniform.texture(),
   "offsetRepeat" : new Uniform.vector4(0.0, 0.0, 1.0, 1.0),

   "lightMap" : new Uniform.texture(),
   "specularMap" : new Uniform.texture(),

   "envMap" : new Uniform.texture(),
   "flipEnvMap" : new Uniform.float(-1.0),
   "useRefract" : new Uniform.int(0),
   "reflectivity" : new Uniform.float(1.0),
   "refractionRatio" : new Uniform.float(0.98),
   "combine" : new Uniform.int(0),

   "morphTargetInfluences" : new Uniform.float(0.0)

 },

 "bump": {

   "bumpMap" : new Uniform.texture(),
   "bumpScale" : new Uniform.float(1.0)

 },

 "normalmap": {

   "normalMap" : new Uniform.texture(),
   "normalScale" : new Uniform.vector2(1.0, 1.0)

 },

 "fog" : {

   "fogDensity" : new Uniform.float(0.00025),
   "fogNear" : new Uniform.float(1.0),
   "fogFar" : new Uniform.float(2000.0),
   "fogColor" : new Uniform.color(0xffffff)

 },

 "lights": {

   "ambientLightColor" : new Uniform.floatv([]),

   "directionalLightDirection" : new Uniform.floatv([]),
   "directionalLightColor" : new Uniform.floatv([]),

   "hemisphereLightDirection" : new Uniform.floatv([]),
   "hemisphereLightSkyColor" : new Uniform.floatv([]),
   "hemisphereLightGroundColor" : new Uniform.floatv([]),

   "pointLightColor" : new Uniform.floatv([]),
   "pointLightPosition" : new Uniform.floatv([]),
   "pointLightDistance" : new Uniform.floatv1([]),

   "spotLightColor" : new Uniform.floatv([]),
   "spotLightPosition" : new Uniform.floatv([]),
   "spotLightDirection" : new Uniform.floatv([]),
   "spotLightDistance" : new Uniform.floatv1([]),
   "spotLightAngleCos" : new Uniform.floatv1([]),
   "spotLightExponent" : new Uniform.floatv1([])

 },

 "particle": {

   "psColor" : new Uniform.color(0xeeeeee),
   "opacity" : new Uniform.float(1.0),
   "size" : new Uniform.float(1.0),
   "scale" : new Uniform.float(1.0),
   "map" : new Uniform.texture(),

   "fogDensity" : new Uniform.float(0.00025),
   "fogNear" : new Uniform.float(1.0),
   "fogFar" : new Uniform.float(2000.0),
   "fogColor" : new Uniform.color(0xffffff)

 },

 "shadowmap": {

   "shadowMap": new Uniform.texturev([]),
   "shadowMapSize": new Uniform.vector2v([]),

   "shadowBias" : new Uniform.floatv1([]),
   "shadowDarkness": new Uniform.floatv1([]),

   "shadowMatrix" : new Uniform.matrix4v([]),

 }
};
}
return __UniformsLib;
}

const int UnsignedByteType #

const int UnsignedByteType = 10

const int UnsignedIntType #

const int UnsignedIntType = 14

const int UnsignedShort4444Type #

const int UnsignedShort4444Type = 1016

const int UnsignedShort5551Type #

const int UnsignedShort5551Type = 1017

const int UnsignedShort565Type #

const int UnsignedShort565Type = 1018

const int UnsignedShortType #

const int UnsignedShortType = 12

const int VertexColors #

const int VertexColors = 2

const int ZeroFactor #

const int ZeroFactor = 200

Functions

dynamic multiplyVector3Array(Matrix4 m, List<double> a) #

multiplyVector3Array(Matrix4 m, List<double> a) {

 var v1 = new Vector3.zero();
 var il = a.length;

 for ( var i = 0; i < il; i += 3 ) {

   v1.x = a[ i ];
   v1.y = a[ i + 1 ];
   v1.z = a[ i + 2 ];

   v1.applyProjection( m );

   a[ i ]     = v1.x;
   a[ i + 1 ] = v1.y;
   a[ i + 2 ] = v1.z;

 }

 return a;
}

Matrix4 makeRotationAxis(Matrix4 m, Vector3 axis, num angle) #

Matrix4 makeRotationAxis( Matrix4 m, Vector3 axis, num angle ) {
 // Based on http://www.gamedev.net/reference/articles/article1199.asp

 num c = Math.cos( angle ),
     s = Math.sin( angle ),
     t = 1.0 - c,
     x = axis.x, y = axis.y, z = axis.z,
     tx = t * x, ty = t * y;

 m.setValues(
     tx * x + c, tx * y - s * z, tx * z + s * y, 0.0,
     tx * y + s * z, ty * y + c, ty * z - s * x, 0.0,
     tx * z - s * y, ty * z + s * x, t * z * z + c, 0.0,
     0.0, 0.0, 0.0, 1.0
   );

  return m;
}

Matrix4 compose(Matrix4 matrix, Vector3 translation, Quaternion rotation, Vector3 s) #

Matrix4 compose( Matrix4 matrix, Vector3 translation, Quaternion rotation, Vector3 s ) {

 var te = matrix.storage;

 Matrix4 mRotation = new Matrix4.identity();
 setRotationFromQuaternion( mRotation, rotation );

 Matrix4 mScale = new Matrix4.diagonal3Values(s.x, s.y, s.z);

 mRotation.multiply(mScale);

 te[12] = translation.x;
 te[13] = translation.y;
 te[14] = translation.z;

 return matrix;
}

Quaternion setFromRotationMatrix(Quaternion quaternion, Matrix4 m) #

Quaternion setFromRotationMatrix(Quaternion quaternion, Matrix4 m ) {

 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm

 // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
 quaternion = new Quaternion.identity();

 var te = m.storage,
     m11 = te[0], m12 = te[4], m13 = te[8],
     m21 = te[1], m22 = te[5], m23 = te[9],
     m31 = te[2], m32 = te[6], m33 = te[10],
     trace = m11 + m22 + m33,
     s;

 if( trace > 0 ) {

   s = 0.5 / Math.sqrt( trace + 1.0 );

   quaternion.w = 0.25 / s;
   quaternion.x = ( m32 - m23 ) * s;
   quaternion.y = ( m13 - m31 ) * s;
   quaternion.z = ( m21 - m12 ) * s;

 } else if ( m11 > m22 && m11 > m33 ) {

   s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );

   quaternion.w = (m32 - m23 ) / s;
   quaternion.x = 0.25 * s;
   quaternion.y = (m12 + m21 ) / s;
   quaternion.z = (m13 + m31 ) / s;

 } else if (m22 > m33) {

   s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );

   quaternion.w = (m13 - m31 ) / s;
   quaternion.x = (m12 + m21 ) / s;
   quaternion.y = 0.25 * s;
   quaternion.z = (m23 + m32 ) / s;

 } else {

   s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );

   quaternion.w = ( m21 - m12 ) / s;
   quaternion.x = ( m13 + m31 ) / s;
   quaternion.y = ( m23 + m32 ) / s;
   quaternion.z = 0.25 * s;

 }

 return quaternion;
}

List decompose(Matrix4 m, Vector3 translation, Quaternion rotation, Vector3 scale) #

List decompose(Matrix4 m, Vector3 translation, Quaternion rotation, Vector3 scale ) {

 var te = m.storage;

 // grab the axis vectors
 Vector3 x = new Vector3( te[0], te[1], te[2] );
 Vector3 y = new Vector3( te[4], te[5], te[6] );
 Vector3 z = new Vector3( te[8], te[9], te[10] );

 translation = ( translation is Vector3 ) ? translation : new Vector3.zero();
 rotation = ( rotation is Quaternion ) ? rotation : new Quaternion.identity();
 scale = ( scale is Vector3 ) ? scale : new Vector3.zero();

 scale.x = x.length;
 scale.y = y.length;
 scale.z = z.length;

 translation.x = te[12];
 translation.y = te[13];
 translation.z = te[14];

 // scale the rotation part

 Matrix4 matrix = m.clone();

 matrix.storage[0] /= scale.x;
 matrix.storage[1] /= scale.x;
 matrix.storage[2] /= scale.x;

 matrix.storage[4] /= scale.y;
 matrix.storage[5] /= scale.y;
 matrix.storage[6] /= scale.y;

 matrix.storage[8] /= scale.z;
 matrix.storage[9] /= scale.z;
 matrix.storage[10] /= scale.z;

 setFromRotationMatrix( rotation, matrix );


 return [ translation, rotation, scale ];
}

Vector3 getScaleFromMatrix(Matrix4 m) #

Vector3 getScaleFromMatrix(Matrix4 m) {
 double sx = new Vector3(m.storage[0], m.storage[1], m.storage[2]).length;
 double sy = new Vector3(m.storage[4], m.storage[5], m.storage[6]).length;
 double sz = new Vector3(m.storage[8], m.storage[9], m.storage[10]).length;
 return new Vector3(sx, sy, sz);
}

Matrix4 extractRotation(Matrix4 te, Matrix4 m) #

Matrix4 extractRotation( Matrix4 te, Matrix4 m ) {

 Vector3 vector = new Vector3.zero();

 var scaleX = 1.0 / vector.setValues ( m[0], m[1], m[2] ).length;
 var scaleY = 1.0 / vector.setValues( m[4], m[5], m[6] ).length;
 var scaleZ = 1.0 / vector.setValues( m[8], m[9], m[10] ).length;

 te[0] = m[0] * scaleX;
 te[1] = m[1] * scaleX;
 te[2] = m[2] * scaleX;

 te[4] = m[4] * scaleY;
 te[5] = m[5] * scaleY;
 te[6] = m[6] * scaleY;

 te[8] = m[8] * scaleZ;
 te[9] = m[9] * scaleZ;
 te[10] = m[10] * scaleZ;

 return te;
}

Matrix3 calcInverse(Matrix4 m) #

Matrix3 calcInverse( Matrix4 m ) {

 // input: THREE.Matrix4
 // ( based on http://code.google.com/p/webgl-mjs/ )

 double a11 =   m[10] * m[5] - m[6] * m[9];
 double a21 = - m[10] * m[1] + m[2] * m[9];
 double a31 =   m[6]  * m[1] - m[2] * m[5];
 double a12 = - m[10] * m[4] + m[6] * m[8];
 double a22 =   m[10] * m[0] - m[2] * m[8];
 double a32 = - m[6]  * m[0] + m[2] * m[4];
 double a13 =   m[9]  * m[4] - m[5] * m[8];
 double a23 = - m[9]  * m[0] + m[1] * m[8];
 double a33 =   m[5]  * m[0] - m[1] * m[4];

 var det = m[0] * a11 + m[1] * a12 + m[2] * a13;

 // no inverse

 if ( det == 0 ) {

   print( "Matrix3.getInverse(): determinant == 0" );

 }

 var idet = 1.0 / det;

 return new Matrix3(idet * a11, idet * a21, idet * a31,
                    idet * a12, idet * a22, idet * a32,
                    idet * a13, idet * a23, idet * a33);
}

double calcMaxScaleOnAxis(Matrix4 te) #

double calcMaxScaleOnAxis(Matrix4 te) {

 var scaleXSq =  te[0] * te[0] + te[1] * te[1] + te[2] * te[2];
 var scaleYSq =  te[4] * te[4] + te[5] * te[5] + te[6] * te[6];
 var scaleZSq =  te[8] * te[8] + te[9] * te[9] + te[10] * te[10];

 return Math.sqrt( Math.max( scaleXSq, Math.max( scaleYSq, scaleZSq ) ) );

}

Matrix4 setRotationFromQuaternion(Matrix4 m, Quaternion q) #

Matrix4 setRotationFromQuaternion( Matrix4 m, Quaternion q ) {
 num x = q.x, y = q.y, z = q.z, w = q.w,
     x2 = x + x, y2 = y + y, z2 = z + z,
     xx = x * x2, xy = x * y2, xz = x * z2,
     yy = y * y2, yz = y * z2, zz = z * z2,
     wx = w * x2, wy = w * y2, wz = w * z2;

 m[0] = 1.0 - ( yy + zz );
 m[4] = xy - wz;
 m[8] = xz + wy;

 m[1] = xy + wz;
 m[5] = 1.0 - ( xx + zz );
 m[9] = yz - wx;

 m[2] = xz - wy;
 m[6] = yz + wx;
 m[10] = 1.0 - ( xx + yy );

 return m;
}

Matrix4 setRotationFromEuler(Matrix4 m, Vector3 v, [String order = 'XYZ']) #

Matrix4 setRotationFromEuler( Matrix4 m, Vector3 v, [String order = 'XYZ'] ) {
 num x = v.x, y = v.y, z = v.z,
     a = Math.cos( x ), b = Math.sin( x ),
     c = Math.cos( y ), d = Math.sin( y ),
     e = Math.cos( z ), f = Math.sin( z );

 switch ( order ) {
   case 'YXZ':

     num ce = c * e, cf = c * f, de = d * e, df = d * f;

     m[0] = ce + df * b;
     m[4] = de * b - cf;
     m[8] = a * d;

     m[1] = a * f;
     m[5] = a * e;
     m[9] = - b;

     m[2] = cf * b - de;
     m[6] = df + ce * b;
     m[10] = a * c;
     break;

   case 'ZXY':

     num ce = c * e, cf = c * f, de = d * e, df = d * f;

     m[0] = ce - df * b;
     m[4] = - a * f;
     m[8] = de + cf * b;

     m[1] = cf + de * b;
     m[5] = a * e;
     m[9] = df - ce * b;

     m[2] = - a * d;
     m[6] = b;
     m[10] = a * c;
     break;

   case 'ZYX':

     num ae = a * e, af = a * f, be = b * e, bf = b * f;

     m[0] = c * e;
     m[4] = be * d - af;
     m[8] = ae * d + bf;

     m[1] = c * f;
     m[5] = bf * d + ae;
     m[9] = af * d - be;

     m[2] = - d;
     m[6] = b * c;
     m[10] = a * c;
     break;

   case 'YZX':

     num ac = a * c, ad = a * d, bc = b * c, bd = b * d;

     m[0] = c * e;
     m[4] = bd - ac * f;
     m[8] = bc * f + ad;

     m[1] = f;
     m[5] = a * e;
     m[9] = - b * e;

     m[2] = - d * e;
     m[6] = ad * f + bc;
     m[10] = ac - bd * f;
     break;

   case 'XZY':

     num ac = a * c, ad = a * d, bc = b * c, bd = b * d;

     m[0] = c * e;
     m[4] = - f;
     m[8] = d * e;

     m[1] = ac * f + bd;
     m[5] = a * e;
     m[9] = ad * f - bc;

     m[2] = bc * f - ad;
     m[6] = b * e;
     m[10] = bd * f + ac;
     break;

   default: // 'XYZ'

     num ae = a * e, af = a * f, be = b * e, bf = b * f;

     m[0] = c * e;
     m[4] = - c * f;
     m[8] = d;

     m[1] = af + be * d;
     m[5] = ae - bf * d;
     m[9] = - b * c;

     m[2] = bf - ae * d;
     m[6] = be + af * d;
     m[10] = a * c;
     break;

 }

 return m;
}

Matrix4 makeLookAt(Matrix4 m, Vector3 eye, Vector3 center, Vector3 up) #

@author mr.doob / http://mrdoob.com/ @author supereggbert / http://www.paulbrunt.co.uk/ @author philogb / http://blog.thejit.org/ @author jordi_ros / http://plattsoft.com @author D1plo1d / http://github.com/D1plo1d @author alteredq / http://alteredqualia.com/ @author mikael emtinger / http://gomo.se/ @author timknip / http://www.floorplanner.com/

Ported to Dart from JS by: @author rob silverton / http://www.unwrong.com/ @author anders forsell / http://aforsell.blogspot.com/

Matrix4 makeLookAt(Matrix4 m, Vector3 eye, Vector3 center, Vector3 up ) {
 Vector3 z = (eye - center ).normalize();
 if ( z.length == 0.0 ) {
   z.z = 1.0;
 }

 Vector3 x = up.cross(z).normalize();
 if ( x.length == 0.0 ) {
   z.x = z.x + 0.0001;
   x = up.cross( z ).normalize();
 }

 Vector3 y = z.cross( x ).normalize();

 m.setValues(x.x, x.y, x.z, 0.0,
             y.x, y.y, y.z, 0.0,
             z.x, z.y, z.z, 0.0,
             0.0, 0.0, 0.0, 1.0);
 return m;
}

Vector4 lerp4(Vector4 start, Vector4 end, double percent) #

Vector4 lerp4(Vector4 start, Vector4 end, double percent) {
    return (start + (end - start).scale(percent));
}

Vector3 calcEulerFromQuaternion(Vector4 q, [String order = 'XYZ']) #

Vector3 calcEulerFromQuaternion(Vector4 q, [String order = 'XYZ'] ) {
 double x, y, z;
 // q is assumed to be normalized

 // clamp, to handle numerical problems

 var clamp = ( x ) => Math.min( Math.max( x, -1 ), 1 );

 // http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/content/SpinCalc.m

 var sqx = q.x * q.x;
 var sqy = q.y * q.y;
 var sqz = q.z * q.z;
 var sqw = q.w * q.w;

 if ( order == 'XYZ' ) {

   x = Math.atan2( 2 * ( q.x * q.w - q.y * q.z ), ( sqw - sqx - sqy + sqz ) );
   y = Math.asin(  clamp( 2 * ( q.x * q.z + q.y * q.w ) ) );
   z = Math.atan2( 2 * ( q.z * q.w - q.x * q.y ), ( sqw + sqx - sqy - sqz ) );

 } else if ( order ==  'YXZ' ) {

   x = Math.asin(  clamp( 2 * ( q.x * q.w - q.y * q.z ) ) );
   y = Math.atan2( 2 * ( q.x * q.z + q.y * q.w ), ( sqw - sqx - sqy + sqz ) );
   z = Math.atan2( 2 * ( q.x * q.y + q.z * q.w ), ( sqw - sqx + sqy - sqz ) );

 } else if ( order == 'ZXY' ) {

   x = Math.asin(  clamp( 2 * ( q.x * q.w + q.y * q.z ) ) );
   y = Math.atan2( 2 * ( q.y * q.w - q.z * q.x ), ( sqw - sqx - sqy + sqz ) );
   z = Math.atan2( 2 * ( q.z * q.w - q.x * q.y ), ( sqw - sqx + sqy - sqz ) );

 } else if ( order == 'ZYX' ) {

   x = Math.atan2( 2 * ( q.x * q.w + q.z * q.y ), ( sqw - sqx - sqy + sqz ) );
   y = Math.asin(  clamp( 2 * ( q.y * q.w - q.x * q.z ) ) );
   z = Math.atan2( 2 * ( q.x * q.y + q.z * q.w ), ( sqw + sqx - sqy - sqz ) );

 } else if ( order == 'YZX' ) {

   x = Math.atan2( 2 * ( q.x * q.w - q.z * q.y ), ( sqw - sqx + sqy - sqz ) );
   y = Math.atan2( 2 * ( q.y * q.w - q.x * q.z ), ( sqw + sqx - sqy - sqz ) );
   z = Math.asin(  clamp( 2 * ( q.x * q.y + q.z * q.w ) ) );

 } else if ( order == 'XZY' ) {

   x = Math.atan2( 2 * ( q.x * q.w + q.y * q.z ), ( sqw - sqx + sqy - sqz ) );
   y = Math.atan2( 2 * ( q.x * q.z + q.y * q.w ), ( sqw + sqx - sqy - sqz ) );
   z = Math.asin(  clamp( 2 * ( q.z * q.w - q.x * q.y ) ) );

 }

 return new Vector3(x, y, z);
}

Vector3 calcEulerFromRotationMatrix(Matrix4 m, [String order = 'XYZ']) #

@author mr.doob / http://mrdoob.com/ @author kile / http://kile.stravaganza.org/ @author philogb / http://blog.thejit.org/ @author mikael emtinger / http://gomo.se/ @author egraether / http://egraether.com/

Ported to Dart from JS by: @author rob silverton / http://www.unwrong.com/ @author anders forsell / http://aforsell.blogspot.com

(moved from three.js Vector3 to here since these are missing in vector_math's Vector3)

Vector3 calcEulerFromRotationMatrix( Matrix4 m, [String order = 'XYZ'] ) {
 double x, y, z;

 // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)

 // clamp, to handle numerical problems

 var clamp = ( x ) => Math.min( Math.max( x, -1 ), 1 );

 var m11 = m[0], m12 = m[4], m13 = m[8];
 var m21 = m[1], m22 = m[5], m23 = m[9];
 var m31 = m[2], m32 = m[6], m33 = m[10];

 if ( order == 'XYZ' ) {

   y = Math.asin( clamp( m13 ) );

   if (  m13.abs() < 0.99999 ) {

     x = Math.atan2( - m23, m33 );
     z = Math.atan2( - m12, m11 );

   } else {

     x = Math.atan2( m21, m22 );
     z = 0.0;

   }

 } else if ( order == 'YXZ' ) {

   x = Math.asin( - clamp( m23 ) );

   if ( m23.abs() < 0.99999 ) {

     y = Math.atan2( m13, m33 );
     z = Math.atan2( m21, m22 );

   } else {

     y = Math.atan2( - m31, m11 );
     z = 0.0;

   }

 } else if ( order == 'ZXY' ) {

   x = Math.asin( clamp( m32 ) );

   if ( m32.abs() < 0.99999 ) {

     y = Math.atan2( - m31, m33 );
     z = Math.atan2( - m12, m22 );

   } else {

     y = 0.0;
     z = Math.atan2( m13, m11 );

   }

 } else if ( order == 'ZYX' ) {

   y = Math.asin( - clamp( m31 ) );

   if (m31.abs() < 0.99999 ) {

     x = Math.atan2( m32, m33 );
     z = Math.atan2( m21, m11 );

   } else {

     x = 0.0;
     z = Math.atan2( - m12, m22 );

   }

 } else if ( order == 'YZX' ) {

   z = Math.asin( clamp( m21 ) );

   if ( m21.abs() < 0.99999 ) {

     x = Math.atan2( - m23, m22 );
     y = Math.atan2( - m31, m11 );

   } else {

     x = 0.0;
     y = Math.atan2( m31, m33 );

   }

 } else if ( order == 'XZY' ) {

   z = Math.asin( - clamp( m12 ) );

   if ( m12.abs() < 0.99999 ) {

     x = Math.atan2( m32, m22 );
     y = Math.atan2( m13, m11 );

   } else {

     x = Math.atan2( - m13, m33 );
     y = 0.0;

   }

 }

 return new Vector3(x, y, z);
}

Abstract Classes

Classes

Fog

LOD

Ray

UV

Typedefs