three.js standard shaders r122
#version 300 es | |
#define varying in | |
out highp vec4 pc_fragColor; | |
#define gl_FragColor pc_fragColor | |
#define gl_FragDepthEXT gl_FragDepth | |
#define texture2D texture | |
#define textureCube texture | |
#define texture2DProj textureProj | |
#define texture2DLodEXT textureLod | |
#define texture2DProjLodEXT textureProjLod | |
#define textureCubeLodEXT textureLod | |
#define texture2DGradEXT textureGrad | |
#define texture2DProjGradEXT textureProjGrad | |
#define textureCubeGradEXT textureGrad | |
precision highp float; | |
precision highp int; | |
#define HIGH_PRECISION | |
#define SHADER_NAME MeshPhongMaterial | |
#define GAMMA_FACTOR 2 | |
uniform mat4 viewMatrix; | |
uniform vec3 cameraPosition; | |
uniform bool isOrthographic; | |
vec4 LinearToLinear( in vec4 value ) { | |
return value; | |
} | |
vec4 GammaToLinear( in vec4 value, in float gammaFactor ) { | |
return vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a ); | |
} | |
vec4 LinearToGamma( in vec4 value, in float gammaFactor ) { | |
return vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a ); | |
} | |
vec4 sRGBToLinear( in vec4 value ) { | |
return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a ); | |
} | |
vec4 LinearTosRGB( in vec4 value ) { | |
return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a ); | |
} | |
vec4 RGBEToLinear( in vec4 value ) { | |
return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 ); | |
} | |
vec4 LinearToRGBE( in vec4 value ) { | |
float maxComponent = max( max( value.r, value.g ), value.b ); | |
float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 ); | |
return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 ); | |
} | |
vec4 RGBMToLinear( in vec4 value, in float maxRange ) { | |
return vec4( value.rgb * value.a * maxRange, 1.0 ); | |
} | |
vec4 LinearToRGBM( in vec4 value, in float maxRange ) { | |
float maxRGB = max( value.r, max( value.g, value.b ) ); | |
float M = clamp( maxRGB / maxRange, 0.0, 1.0 ); | |
M = ceil( M * 255.0 ) / 255.0; | |
return vec4( value.rgb / ( M * maxRange ), M ); | |
} | |
vec4 RGBDToLinear( in vec4 value, in float maxRange ) { | |
return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 ); | |
} | |
vec4 LinearToRGBD( in vec4 value, in float maxRange ) { | |
float maxRGB = max( value.r, max( value.g, value.b ) ); | |
float D = max( maxRange / maxRGB, 1.0 ); | |
D = clamp( floor( D ) / 255.0, 0.0, 1.0 ); | |
return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D ); | |
} | |
const mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 ); | |
vec4 LinearToLogLuv( in vec4 value ) { | |
vec3 Xp_Y_XYZp = cLogLuvM * value.rgb; | |
Xp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) ); | |
vec4 vResult; | |
vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z; | |
float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0; | |
vResult.w = fract( Le ); | |
vResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0; | |
return vResult; | |
} | |
const mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 ); | |
vec4 LogLuvToLinear( in vec4 value ) { | |
float Le = value.z * 255.0 + value.w; | |
vec3 Xp_Y_XYZp; | |
Xp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 ); | |
Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y; | |
Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z; | |
vec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb; | |
return vec4( max( vRGB, 0.0 ), 1.0 ); | |
} | |
vec4 linearToOutputTexel( vec4 value ) { return LinearToLinear( value ); } | |
#define PHONG | |
uniform vec3 diffuse; | |
uniform vec3 emissive; | |
uniform vec3 specular; | |
uniform float shininess; | |
uniform float opacity; | |
#define PI 3.141592653589793 | |
#define PI2 6.283185307179586 | |
#define PI_HALF 1.5707963267948966 | |
#define RECIPROCAL_PI 0.3183098861837907 | |
#define RECIPROCAL_PI2 0.15915494309189535 | |
#define EPSILON 1e-6 | |
#ifndef saturate | |
#define saturate(a) clamp( a, 0.0, 1.0 ) | |
#endif | |
#define whiteComplement(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); | |
} | |
#ifdef HIGH_PRECISION | |
float precisionSafeLength( vec3 v ) { return length( v ); } | |
#else | |
float max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); } | |
float precisionSafeLength( vec3 v ) { | |
float maxComponent = max3( abs( v ) ); | |
return length( v / maxComponent ) * maxComponent; | |
} | |
#endif | |
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; | |
#ifdef CLEARCOAT | |
vec3 clearcoatNormal; | |
#endif | |
}; | |
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 ); | |
} | |
bool isPerspectiveMatrix( mat4 m ) { | |
return m[ 2 ][ 3 ] == - 1.0; | |
} | |
vec2 equirectUv( in vec3 dir ) { | |
float u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5; | |
float v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5; | |
return vec2( u, v ); | |
} | |
vec3 packNormalToRGB( const in vec3 normal ) { | |
return normalize( normal ) * 0.5 + 0.5; | |
} | |
vec3 unpackRGBToNormal( const in vec3 rgb ) { | |
return 2.0 * rgb.xyz - 1.0; | |
} | |
const float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.; | |
const vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. ); | |
const vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. ); | |
const float ShiftRight8 = 1. / 256.; | |
vec4 packDepthToRGBA( const in float v ) { | |
vec4 r = vec4( fract( v * PackFactors ), v ); | |
r.yzw -= r.xyz * ShiftRight8; return r * PackUpscale; | |
} | |
float unpackRGBAToDepth( const in vec4 v ) { | |
return dot( v, UnpackFactors ); | |
} | |
vec4 pack2HalfToRGBA( vec2 v ) { | |
vec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 )); | |
return vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w); | |
} | |
vec2 unpackRGBATo2Half( vec4 v ) { | |
return vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) ); | |
} | |
float viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) { | |
return ( viewZ + near ) / ( near - far ); | |
} | |
float orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) { | |
return linearClipZ * ( near - far ) - near; | |
} | |
float viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) { | |
return (( near + viewZ ) * far ) / (( far - near ) * viewZ ); | |
} | |
float perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) { | |
return ( near * far ) / ( ( far - near ) * invClipZ - far ); | |
} | |
#ifdef DITHERING | |
vec3 dithering( vec3 color ) { | |
float grid_position = rand( gl_FragCoord.xy ); | |
vec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 ); | |
dither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position ); | |
return color + dither_shift_RGB; | |
} | |
#endif | |
#ifdef USE_COLOR | |
varying vec3 vColor; | |
#endif | |
#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) ) | |
varying vec2 vUv; | |
#endif | |
#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP ) | |
varying vec2 vUv2; | |
#endif | |
#ifdef USE_MAP | |
uniform sampler2D map; | |
#endif | |
#ifdef USE_ALPHAMAP | |
uniform sampler2D alphaMap; | |
#endif | |
#ifdef USE_AOMAP | |
uniform sampler2D aoMap; | |
uniform float aoMapIntensity; | |
#endif | |
#ifdef USE_LIGHTMAP | |
uniform sampler2D lightMap; | |
uniform float lightMapIntensity; | |
#endif | |
#ifdef USE_EMISSIVEMAP | |
uniform sampler2D emissiveMap; | |
#endif | |
#ifdef USE_ENVMAP | |
uniform float envMapIntensity; | |
uniform float flipEnvMap; | |
uniform int maxMipLevel; | |
#ifdef ENVMAP_TYPE_CUBE | |
uniform samplerCube envMap; | |
#else | |
uniform sampler2D envMap; | |
#endif | |
#endif | |
#ifdef USE_ENVMAP | |
uniform float reflectivity; | |
#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) | |
#define ENV_WORLDPOS | |
#endif | |
#ifdef ENV_WORLDPOS | |
varying vec3 vWorldPosition; | |
uniform float refractionRatio; | |
#else | |
varying vec3 vReflect; | |
#endif | |
#endif | |
#ifdef ENVMAP_TYPE_CUBE_UV | |
#define cubeUV_maxMipLevel 8.0 | |
#define cubeUV_minMipLevel 4.0 | |
#define cubeUV_maxTileSize 256.0 | |
#define cubeUV_minTileSize 16.0 | |
float getFace( vec3 direction ) { | |
vec3 absDirection = abs( direction ); | |
float face = - 1.0; | |
if ( absDirection.x > absDirection.z ) { | |
if ( absDirection.x > absDirection.y ) | |
face = direction.x > 0.0 ? 0.0 : 3.0; | |
else | |
face = direction.y > 0.0 ? 1.0 : 4.0; | |
} else { | |
if ( absDirection.z > absDirection.y ) | |
face = direction.z > 0.0 ? 2.0 : 5.0; | |
else | |
face = direction.y > 0.0 ? 1.0 : 4.0; | |
} | |
return face; | |
} | |
vec2 getUV( vec3 direction, float face ) { | |
vec2 uv; | |
if ( face == 0.0 ) { | |
uv = vec2( direction.z, direction.y ) / abs( direction.x ); | |
} else if ( face == 1.0 ) { | |
uv = vec2( - direction.x, - direction.z ) / abs( direction.y ); | |
} else if ( face == 2.0 ) { | |
uv = vec2( - direction.x, direction.y ) / abs( direction.z ); | |
} else if ( face == 3.0 ) { | |
uv = vec2( - direction.z, direction.y ) / abs( direction.x ); | |
} else if ( face == 4.0 ) { | |
uv = vec2( - direction.x, direction.z ) / abs( direction.y ); | |
} else { | |
uv = vec2( direction.x, direction.y ) / abs( direction.z ); | |
} | |
return 0.5 * ( uv + 1.0 ); | |
} | |
vec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) { | |
float face = getFace( direction ); | |
float filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 ); | |
mipInt = max( mipInt, cubeUV_minMipLevel ); | |
float faceSize = exp2( mipInt ); | |
float texelSize = 1.0 / ( 3.0 * cubeUV_maxTileSize ); | |
vec2 uv = getUV( direction, face ) * ( faceSize - 1.0 ); | |
vec2 f = fract( uv ); | |
uv += 0.5 - f; | |
if ( face > 2.0 ) { | |
uv.y += faceSize; | |
face -= 3.0; | |
} | |
uv.x += face * faceSize; | |
if ( mipInt < cubeUV_maxMipLevel ) { | |
uv.y += 2.0 * cubeUV_maxTileSize; | |
} | |
uv.y += filterInt * 2.0 * cubeUV_minTileSize; | |
uv.x += 3.0 * max( 0.0, cubeUV_maxTileSize - 2.0 * faceSize ); | |
uv *= texelSize; | |
vec3 tl = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb; | |
uv.x += texelSize; | |
vec3 tr = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb; | |
uv.y += texelSize; | |
vec3 br = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb; | |
uv.x -= texelSize; | |
vec3 bl = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb; | |
vec3 tm = mix( tl, tr, f.x ); | |
vec3 bm = mix( bl, br, f.x ); | |
return mix( tm, bm, f.y ); | |
} | |
#define r0 1.0 | |
#define v0 0.339 | |
#define m0 - 2.0 | |
#define r1 0.8 | |
#define v1 0.276 | |
#define m1 - 1.0 | |
#define r4 0.4 | |
#define v4 0.046 | |
#define m4 2.0 | |
#define r5 0.305 | |
#define v5 0.016 | |
#define m5 3.0 | |
#define r6 0.21 | |
#define v6 0.0038 | |
#define m6 4.0 | |
float roughnessToMip( float roughness ) { | |
float mip = 0.0; | |
if ( roughness >= r1 ) { | |
mip = ( r0 - roughness ) * ( m1 - m0 ) / ( r0 - r1 ) + m0; | |
} else if ( roughness >= r4 ) { | |
mip = ( r1 - roughness ) * ( m4 - m1 ) / ( r1 - r4 ) + m1; | |
} else if ( roughness >= r5 ) { | |
mip = ( r4 - roughness ) * ( m5 - m4 ) / ( r4 - r5 ) + m4; | |
} else if ( roughness >= r6 ) { | |
mip = ( r5 - roughness ) * ( m6 - m5 ) / ( r5 - r6 ) + m5; | |
} else { | |
mip = - 2.0 * log2( 1.16 * roughness ); } | |
return mip; | |
} | |
vec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) { | |
float mip = clamp( roughnessToMip( roughness ), m0, cubeUV_maxMipLevel ); | |
float mipF = fract( mip ); | |
float mipInt = floor( mip ); | |
vec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt ); | |
if ( mipF == 0.0 ) { | |
return vec4( color0, 1.0 ); | |
} else { | |
vec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 ); | |
return vec4( mix( color0, color1, mipF ), 1.0 ); | |
} | |
} | |
#endif | |
#ifdef USE_FOG | |
uniform vec3 fogColor; | |
varying float fogDepth; | |
#ifdef FOG_EXP2 | |
uniform float fogDensity; | |
#else | |
uniform float fogNear; | |
uniform float fogFar; | |
#endif | |
#endif | |
vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) { | |
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; | |
return vec2( -1.04, 1.04 ) * a004 + r.zw; | |
} | |
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 && decayExponent > 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; | |
} | |
vec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) { | |
float fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV ); | |
vec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0; | |
return Fr * fresnel + F0; | |
} | |
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 vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) { | |
float alpha = pow2( roughness ); | |
vec3 halfDir = normalize( incidentLight.direction + viewDir ); | |
float dotNL = saturate( dot( normal, incidentLight.direction ) ); | |
float dotNV = saturate( dot( normal, viewDir ) ); | |
float dotNH = saturate( dot( 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 vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) { | |
float dotNV = saturate( dot( normal, viewDir ) ); | |
vec2 brdf = integrateSpecularBRDF( dotNV, roughness ); | |
return specularColor * brdf.x + brdf.y; | |
} | |
void BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) { | |
float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); | |
vec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness ); | |
vec2 brdf = integrateSpecularBRDF( dotNV, roughness ); | |
vec3 FssEss = F * brdf.x + brdf.y; | |
float Ess = brdf.x + brdf.y; | |
float Ems = 1.0 - Ess; | |
vec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619; vec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg ); | |
singleScatter += FssEss; | |
multiScatter += Fms * Ems; | |
} | |
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 ) ); | |
} | |
#if defined( USE_SHEEN ) | |
float D_Charlie(float roughness, float NoH) { | |
float invAlpha = 1.0 / roughness; | |
float cos2h = NoH * NoH; | |
float sin2h = max(1.0 - cos2h, 0.0078125); return (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI); | |
} | |
float V_Neubelt(float NoV, float NoL) { | |
return saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV))); | |
} | |
vec3 BRDF_Specular_Sheen( const in float roughness, const in vec3 L, const in GeometricContext geometry, vec3 specularColor ) { | |
vec3 N = geometry.normal; | |
vec3 V = geometry.viewDir; | |
vec3 H = normalize( V + L ); | |
float dotNH = saturate( dot( N, H ) ); | |
return specularColor * D_Charlie( roughness, dotNH ) * V_Neubelt( dot(N, V), dot(N, L) ); | |
} | |
#endif | |
uniform bool receiveShadow; | |
uniform vec3 ambientLightColor; | |
uniform vec3 lightProbe[ 9 ]; | |
vec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) { | |
float x = normal.x, y = normal.y, z = normal.z; | |
vec3 result = shCoefficients[ 0 ] * 0.886227; | |
result += shCoefficients[ 1 ] * 2.0 * 0.511664 * y; | |
result += shCoefficients[ 2 ] * 2.0 * 0.511664 * z; | |
result += shCoefficients[ 3 ] * 2.0 * 0.511664 * x; | |
result += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y; | |
result += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z; | |
result += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 ); | |
result += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z; | |
result += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y ); | |
return result; | |
} | |
vec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) { | |
vec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix ); | |
vec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe ); | |
return irradiance; | |
} | |
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; | |
}; | |
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; | |
}; | |
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; | |
}; | |
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 | |
varying vec3 vViewPosition; | |
#ifndef FLAT_SHADED | |
varying vec3 vNormal; | |
#endif | |
struct BlinnPhongMaterial { | |
vec3 diffuseColor; | |
vec3 specularColor; | |
float specularShininess; | |
float specularStrength; | |
}; | |
void RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) { | |
float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); | |
vec3 irradiance = dotNL * directLight.color; | |
#ifndef PHYSICALLY_CORRECT_LIGHTS | |
irradiance *= PI; | |
#endif | |
reflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); | |
reflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength; | |
} | |
void RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) { | |
reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); | |
} | |
#define RE_Direct RE_Direct_BlinnPhong | |
#define RE_IndirectDiffuse RE_IndirectDiffuse_BlinnPhong | |
#define Material_LightProbeLOD( material ) (0) | |
#ifdef USE_SHADOWMAP | |
#if 0 > 0 | |
uniform sampler2D directionalShadowMap[ 0 ]; | |
varying vec4 vDirectionalShadowCoord[ 0 ]; | |
struct DirectionalLightShadow { | |
float shadowBias; | |
float shadowNormalBias; | |
float shadowRadius; | |
vec2 shadowMapSize; | |
}; | |
uniform DirectionalLightShadow directionalLightShadows[ 0 ]; | |
#endif | |
#if 0 > 0 | |
uniform sampler2D spotShadowMap[ 0 ]; | |
varying vec4 vSpotShadowCoord[ 0 ]; | |
struct SpotLightShadow { | |
float shadowBias; | |
float shadowNormalBias; | |
float shadowRadius; | |
vec2 shadowMapSize; | |
}; | |
uniform SpotLightShadow spotLightShadows[ 0 ]; | |
#endif | |
#if 0 > 0 | |
uniform sampler2D pointShadowMap[ 0 ]; | |
varying vec4 vPointShadowCoord[ 0 ]; | |
struct PointLightShadow { | |
float shadowBias; | |
float shadowNormalBias; | |
float shadowRadius; | |
vec2 shadowMapSize; | |
float shadowCameraNear; | |
float shadowCameraFar; | |
}; | |
uniform PointLightShadow pointLightShadows[ 0 ]; | |
#endif | |
float texture2DCompare( sampler2D depths, vec2 uv, float compare ) { | |
return step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) ); | |
} | |
vec2 texture2DDistribution( sampler2D shadow, vec2 uv ) { | |
return unpackRGBATo2Half( texture2D( shadow, uv ) ); | |
} | |
float VSMShadow (sampler2D shadow, vec2 uv, float compare ){ | |
float occlusion = 1.0; | |
vec2 distribution = texture2DDistribution( shadow, uv ); | |
float hard_shadow = step( compare , distribution.x ); | |
if (hard_shadow != 1.0 ) { | |
float distance = compare - distribution.x ; | |
float variance = max( 0.00000, distribution.y * distribution.y ); | |
float softness_probability = variance / (variance + distance * distance ); softness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 ); occlusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 ); | |
} | |
return occlusion; | |
} | |
float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) { | |
float shadow = 1.0; | |
shadowCoord.xyz /= shadowCoord.w; | |
shadowCoord.z += shadowBias; | |
bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 ); | |
bool inFrustum = all( inFrustumVec ); | |
bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 ); | |
bool frustumTest = all( frustumTestVec ); | |
if ( frustumTest ) { | |
#if defined( SHADOWMAP_TYPE_PCF ) | |
vec2 texelSize = vec2( 1.0 ) / shadowMapSize; | |
float dx0 = - texelSize.x * shadowRadius; | |
float dy0 = - texelSize.y * shadowRadius; | |
float dx1 = + texelSize.x * shadowRadius; | |
float dy1 = + texelSize.y * shadowRadius; | |
float dx2 = dx0 / 2.0; | |
float dy2 = dy0 / 2.0; | |
float dx3 = dx1 / 2.0; | |
float dy3 = dy1 / 2.0; | |
shadow = ( | |
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) + | |
texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) + | |
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) + | |
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) + | |
texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) + | |
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) + | |
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) + | |
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) + | |
texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) + | |
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) + | |
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) + | |
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) + | |
texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) + | |
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) + | |
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) + | |
texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) + | |
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z ) | |
) * ( 1.0 / 17.0 ); | |
#elif defined( SHADOWMAP_TYPE_PCF_SOFT ) | |
vec2 texelSize = vec2( 1.0 ) / shadowMapSize; | |
float dx = texelSize.x; | |
float dy = texelSize.y; | |
vec2 uv = shadowCoord.xy; | |
vec2 f = fract( uv * shadowMapSize + 0.5 ); | |
uv -= f * texelSize; | |
shadow = ( | |
texture2DCompare( shadowMap, uv, shadowCoord.z ) + | |
texture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) + | |
texture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) + | |
texture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) + | |
mix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), | |
texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ), | |
f.x ) + | |
mix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), | |
texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ), | |
f.x ) + | |
mix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), | |
texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ), | |
f.y ) + | |
mix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), | |
texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ), | |
f.y ) + | |
mix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), | |
texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ), | |
f.x ), | |
mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), | |
texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ), | |
f.x ), | |
f.y ) | |
) * ( 1.0 / 9.0 ); | |
#elif defined( SHADOWMAP_TYPE_VSM ) | |
shadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z ); | |
#else | |
shadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ); | |
#endif | |
} | |
return shadow; | |
} | |
vec2 cubeToUV( vec3 v, float texelSizeY ) { | |
vec3 absV = abs( v ); | |
float scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) ); | |
absV *= scaleToCube; | |
v *= scaleToCube * ( 1.0 - 2.0 * texelSizeY ); | |
vec2 planar = v.xy; | |
float almostATexel = 1.5 * texelSizeY; | |
float almostOne = 1.0 - almostATexel; | |
if ( absV.z >= almostOne ) { | |
if ( v.z > 0.0 ) | |
planar.x = 4.0 - v.x; | |
} else if ( absV.x >= almostOne ) { | |
float signX = sign( v.x ); | |
planar.x = v.z * signX + 2.0 * signX; | |
} else if ( absV.y >= almostOne ) { | |
float signY = sign( v.y ); | |
planar.x = v.x + 2.0 * signY + 2.0; | |
planar.y = v.z * signY - 2.0; | |
} | |
return vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 ); | |
} | |
float getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) { | |
vec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) ); | |
vec3 lightToPosition = shadowCoord.xyz; | |
float dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear ); dp += shadowBias; | |
vec3 bd3D = normalize( lightToPosition ); | |
#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM ) | |
vec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y; | |
return ( | |
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) + | |
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) + | |
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) + | |
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) + | |
texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) + | |
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) + | |
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) + | |
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) + | |
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp ) | |
) * ( 1.0 / 9.0 ); | |
#else | |
return texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ); | |
#endif | |
} | |
#endif | |
#ifdef USE_BUMPMAP | |
uniform sampler2D bumpMap; | |
uniform float bumpScale; | |
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 = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) ); | |
vec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) ); | |
vec3 vN = surf_norm; | |
vec3 R1 = cross( vSigmaY, vN ); | |
vec3 R2 = cross( vN, vSigmaX ); | |
float fDet = dot( vSigmaX, R1 ); | |
fDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 ); | |
vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 ); | |
return normalize( abs( fDet ) * surf_norm - vGrad ); | |
} | |
#endif | |
#ifdef USE_NORMALMAP | |
uniform sampler2D normalMap; | |
uniform vec2 normalScale; | |
#endif | |
#ifdef OBJECTSPACE_NORMALMAP | |
uniform mat3 normalMatrix; | |
#endif | |
#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) ) | |
vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN ) { | |
vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) ); | |
vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) ); | |
vec2 st0 = dFdx( vUv.st ); | |
vec2 st1 = dFdy( vUv.st ); | |
float scale = sign( st1.t * st0.s - st0.t * st1.s ); | |
vec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale ); | |
vec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale ); | |
vec3 N = normalize( surf_norm ); | |
mat3 tsn = mat3( S, T, N ); | |
mapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 ); | |
return normalize( tsn * mapN ); | |
} | |
#endif | |
#ifdef USE_SPECULARMAP | |
uniform sampler2D specularMap; | |
#endif | |
#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT ) | |
uniform float logDepthBufFC; | |
varying float vFragDepth; | |
varying float vIsPerspective; | |
#endif | |
#if 0 > 0 | |
varying vec3 vClipPosition; | |
uniform vec4 clippingPlanes[ 0 ]; | |
#endif | |
void main() { | |
#if 0 > 0 | |
vec4 plane; | |
#if 0 < 0 | |
bool clipped = true; | |
if ( clipped ) discard; | |
#endif | |
#endif | |
vec4 diffuseColor = vec4( diffuse, opacity ); | |
ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); | |
vec3 totalEmissiveRadiance = emissive; | |
#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT ) | |
gl_FragDepthEXT = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5; | |
#endif | |
#ifdef USE_MAP | |
vec4 texelColor = texture2D( map, vUv ); | |
texelColor = mapTexelToLinear( texelColor ); | |
diffuseColor *= texelColor; | |
#endif | |
#ifdef USE_COLOR | |
diffuseColor.rgb *= vColor; | |
#endif | |
#ifdef USE_ALPHAMAP | |
diffuseColor.a *= texture2D( alphaMap, vUv ).g; | |
#endif | |
#ifdef ALPHATEST | |
if ( diffuseColor.a < ALPHATEST ) discard; | |
#endif | |
float specularStrength; | |
#ifdef USE_SPECULARMAP | |
vec4 texelSpecular = texture2D( specularMap, vUv ); | |
specularStrength = texelSpecular.r; | |
#else | |
specularStrength = 1.0; | |
#endif | |
#ifdef FLAT_SHADED | |
vec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) ); | |
vec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) ); | |
vec3 normal = normalize( cross( fdx, fdy ) ); | |
#else | |
vec3 normal = normalize( vNormal ); | |
#ifdef DOUBLE_SIDED | |
normal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 ); | |
#endif | |
#ifdef USE_TANGENT | |
vec3 tangent = normalize( vTangent ); | |
vec3 bitangent = normalize( vBitangent ); | |
#ifdef DOUBLE_SIDED | |
tangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 ); | |
bitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 ); | |
#endif | |
#if defined( TANGENTSPACE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP ) | |
mat3 vTBN = mat3( tangent, bitangent, normal ); | |
#endif | |
#endif | |
#endif | |
vec3 geometryNormal = normal; | |
#ifdef OBJECTSPACE_NORMALMAP | |
normal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0; | |
#ifdef FLIP_SIDED | |
normal = - normal; | |
#endif | |
#ifdef DOUBLE_SIDED | |
normal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 ); | |
#endif | |
normal = normalize( normalMatrix * normal ); | |
#elif defined( TANGENTSPACE_NORMALMAP ) | |
vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0; | |
mapN.xy *= normalScale; | |
#ifdef USE_TANGENT | |
normal = normalize( vTBN * mapN ); | |
#else | |
normal = perturbNormal2Arb( -vViewPosition, normal, mapN ); | |
#endif | |
#elif defined( USE_BUMPMAP ) | |
normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() ); | |
#endif | |
#ifdef USE_EMISSIVEMAP | |
vec4 emissiveColor = texture2D( emissiveMap, vUv ); | |
emissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb; | |
totalEmissiveRadiance *= emissiveColor.rgb; | |
#endif | |
BlinnPhongMaterial material; | |
material.diffuseColor = diffuseColor.rgb; | |
material.specularColor = specular; | |
material.specularShininess = shininess; | |
material.specularStrength = specularStrength; | |
GeometricContext geometry; | |
geometry.position = - vViewPosition; | |
geometry.normal = normal; | |
geometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition ); | |
#ifdef CLEARCOAT | |
geometry.clearcoatNormal = clearcoatNormal; | |
#endif | |
IncidentLight directLight; | |
#if ( 0 > 0 ) && defined( RE_Direct ) | |
PointLight pointLight; | |
#if defined( USE_SHADOWMAP ) && 0 > 0 | |
PointLightShadow pointLightShadow; | |
#endif | |
#endif | |
#if ( 0 > 0 ) && defined( RE_Direct ) | |
SpotLight spotLight; | |
#if defined( USE_SHADOWMAP ) && 0 > 0 | |
SpotLightShadow spotLightShadow; | |
#endif | |
#endif | |
#if ( 1 > 0 ) && defined( RE_Direct ) | |
DirectionalLight directionalLight; | |
#if defined( USE_SHADOWMAP ) && 0 > 0 | |
DirectionalLightShadow directionalLightShadow; | |
#endif | |
directionalLight = directionalLights[ 0 ]; | |
getDirectionalDirectLightIrradiance( directionalLight, geometry, directLight ); | |
#if defined( USE_SHADOWMAP ) && ( 0 < 0 ) | |
directionalLightShadow = directionalLightShadows[ 0 ]; | |
directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ 0 ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ 0 ] ) : 1.0; | |
#endif | |
RE_Direct( directLight, geometry, material, reflectedLight ); | |
#endif | |
#if ( 0 > 0 ) && defined( RE_Direct_RectArea ) | |
RectAreaLight rectAreaLight; | |
#endif | |
#if defined( RE_IndirectDiffuse ) | |
vec3 iblIrradiance = vec3( 0.0 ); | |
vec3 irradiance = getAmbientLightIrradiance( ambientLightColor ); | |
irradiance += getLightProbeIrradiance( lightProbe, geometry ); | |
#if ( 0 > 0 ) | |
#endif | |
#endif | |
#if defined( RE_IndirectSpecular ) | |
vec3 radiance = vec3( 0.0 ); | |
vec3 clearcoatRadiance = vec3( 0.0 ); | |
#endif | |
#if defined( RE_IndirectDiffuse ) | |
#ifdef USE_LIGHTMAP | |
vec4 lightMapTexel= texture2D( lightMap, vUv2 ); | |
vec3 lightMapIrradiance = lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity; | |
#ifndef PHYSICALLY_CORRECT_LIGHTS | |
lightMapIrradiance *= PI; | |
#endif | |
irradiance += lightMapIrradiance; | |
#endif | |
#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV ) | |
iblIrradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel ); | |
#endif | |
#endif | |
#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular ) | |
radiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.normal, material.specularRoughness, maxMipLevel ); | |
#ifdef CLEARCOAT | |
clearcoatRadiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, maxMipLevel ); | |
#endif | |
#endif | |
#if defined( RE_IndirectDiffuse ) | |
RE_IndirectDiffuse( irradiance, geometry, material, reflectedLight ); | |
#endif | |
#if defined( RE_IndirectSpecular ) | |
RE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight ); | |
#endif | |
#ifdef USE_AOMAP | |
float ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0; | |
reflectedLight.indirectDiffuse *= ambientOcclusion; | |
#if defined( USE_ENVMAP ) && defined( STANDARD ) | |
float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); | |
reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness ); | |
#endif | |
#endif | |
vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance; | |
#ifdef USE_ENVMAP | |
#ifdef ENV_WORLDPOS | |
vec3 cameraToFrag; | |
if ( isOrthographic ) { | |
cameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) ); | |
} else { | |
cameraToFrag = normalize( vWorldPosition - cameraPosition ); | |
} | |
vec3 worldNormal = inverseTransformDirection( normal, viewMatrix ); | |
#ifdef ENVMAP_MODE_REFLECTION | |
vec3 reflectVec = reflect( cameraToFrag, worldNormal ); | |
#else | |
vec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio ); | |
#endif | |
#else | |
vec3 reflectVec = vReflect; | |
#endif | |
#ifdef ENVMAP_TYPE_CUBE | |
vec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) ); | |
#elif defined( ENVMAP_TYPE_CUBE_UV ) | |
vec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 ); | |
#else | |
vec4 envColor = vec4( 0.0 ); | |
#endif | |
#ifndef ENVMAP_TYPE_CUBE_UV | |
envColor = envMapTexelToLinear( envColor ); | |
#endif | |
#ifdef ENVMAP_BLENDING_MULTIPLY | |
outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity ); | |
#elif defined( ENVMAP_BLENDING_MIX ) | |
outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity ); | |
#elif defined( ENVMAP_BLENDING_ADD ) | |
outgoingLight += envColor.xyz * specularStrength * reflectivity; | |
#endif | |
#endif | |
gl_FragColor = vec4( outgoingLight, diffuseColor.a ); | |
#if defined( TONE_MAPPING ) | |
gl_FragColor.rgb = toneMapping( gl_FragColor.rgb ); | |
#endif | |
gl_FragColor = linearToOutputTexel( gl_FragColor ); | |
#ifdef USE_FOG | |
#ifdef FOG_EXP2 | |
float fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth ); | |
#else | |
float fogFactor = smoothstep( fogNear, fogFar, fogDepth ); | |
#endif | |
gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor ); | |
#endif | |
#ifdef PREMULTIPLIED_ALPHA | |
gl_FragColor.rgb *= gl_FragColor.a; | |
#endif | |
#ifdef DITHERING | |
gl_FragColor.rgb = dithering( gl_FragColor.rgb ); | |
#endif | |
} |
#version 300 es | |
#define attribute in | |
#define varying out | |
#define texture2D texture | |
precision highp float; | |
precision highp int; | |
#define HIGH_PRECISION | |
#define SHADER_NAME MeshPhongMaterial | |
#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; | |
uniform bool isOrthographic; | |
#ifdef USE_INSTANCING | |
attribute mat4 instanceMatrix; | |
#endif | |
#ifdef USE_INSTANCING_COLOR | |
attribute vec3 instanceColor; | |
#endif | |
attribute vec3 position; | |
attribute vec3 normal; | |
attribute vec2 uv; | |
#ifdef USE_TANGENT | |
attribute vec4 tangent; | |
#endif | |
#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 | |
#define PHONG | |
varying vec3 vViewPosition; | |
#ifndef FLAT_SHADED | |
varying vec3 vNormal; | |
#endif | |
#define PI 3.141592653589793 | |
#define PI2 6.283185307179586 | |
#define PI_HALF 1.5707963267948966 | |
#define RECIPROCAL_PI 0.3183098861837907 | |
#define RECIPROCAL_PI2 0.15915494309189535 | |
#define EPSILON 1e-6 | |
#ifndef saturate | |
#define saturate(a) clamp( a, 0.0, 1.0 ) | |
#endif | |
#define whiteComplement(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); | |
} | |
#ifdef HIGH_PRECISION | |
float precisionSafeLength( vec3 v ) { return length( v ); } | |
#else | |
float max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); } | |
float precisionSafeLength( vec3 v ) { | |
float maxComponent = max3( abs( v ) ); | |
return length( v / maxComponent ) * maxComponent; | |
} | |
#endif | |
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; | |
#ifdef CLEARCOAT | |
vec3 clearcoatNormal; | |
#endif | |
}; | |
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 ); | |
} | |
bool isPerspectiveMatrix( mat4 m ) { | |
return m[ 2 ][ 3 ] == - 1.0; | |
} | |
vec2 equirectUv( in vec3 dir ) { | |
float u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5; | |
float v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5; | |
return vec2( u, v ); | |
} | |
#ifdef USE_UV | |
#ifdef UVS_VERTEX_ONLY | |
vec2 vUv; | |
#else | |
varying vec2 vUv; | |
#endif | |
uniform mat3 uvTransform; | |
#endif | |
#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP ) | |
attribute vec2 uv2; | |
varying vec2 vUv2; | |
uniform mat3 uv2Transform; | |
#endif | |
#ifdef USE_DISPLACEMENTMAP | |
uniform sampler2D displacementMap; | |
uniform float displacementScale; | |
uniform float displacementBias; | |
#endif | |
#ifdef USE_ENVMAP | |
#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG ) | |
#define ENV_WORLDPOS | |
#endif | |
#ifdef ENV_WORLDPOS | |
varying vec3 vWorldPosition; | |
#else | |
varying vec3 vReflect; | |
uniform float refractionRatio; | |
#endif | |
#endif | |
#if defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR ) | |
varying vec3 vColor; | |
#endif | |
#ifdef USE_FOG | |
varying float fogDepth; | |
#endif | |
#ifdef USE_MORPHTARGETS | |
uniform float morphTargetBaseInfluence; | |
#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 highp 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 0 > 0 | |
uniform mat4 directionalShadowMatrix[ 0 ]; | |
varying vec4 vDirectionalShadowCoord[ 0 ]; | |
struct DirectionalLightShadow { | |
float shadowBias; | |
float shadowNormalBias; | |
float shadowRadius; | |
vec2 shadowMapSize; | |
}; | |
uniform DirectionalLightShadow directionalLightShadows[ 0 ]; | |
#endif | |
#if 0 > 0 | |
uniform mat4 spotShadowMatrix[ 0 ]; | |
varying vec4 vSpotShadowCoord[ 0 ]; | |
struct SpotLightShadow { | |
float shadowBias; | |
float shadowNormalBias; | |
float shadowRadius; | |
vec2 shadowMapSize; | |
}; | |
uniform SpotLightShadow spotLightShadows[ 0 ]; | |
#endif | |
#if 0 > 0 | |
uniform mat4 pointShadowMatrix[ 0 ]; | |
varying vec4 vPointShadowCoord[ 0 ]; | |
struct PointLightShadow { | |
float shadowBias; | |
float shadowNormalBias; | |
float shadowRadius; | |
vec2 shadowMapSize; | |
float shadowCameraNear; | |
float shadowCameraFar; | |
}; | |
uniform PointLightShadow pointLightShadows[ 0 ]; | |
#endif | |
#endif | |
#ifdef USE_LOGDEPTHBUF | |
#ifdef USE_LOGDEPTHBUF_EXT | |
varying float vFragDepth; | |
varying float vIsPerspective; | |
#else | |
uniform float logDepthBufFC; | |
#endif | |
#endif | |
#if 0 > 0 | |
varying vec3 vClipPosition; | |
#endif | |
void main() { | |
#ifdef USE_UV | |
vUv = ( uvTransform * vec3( uv, 1 ) ).xy; | |
#endif | |
#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP ) | |
vUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy; | |
#endif | |
#if defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR ) | |
vColor = vec3( 1.0 ); | |
#endif | |
#ifdef USE_COLOR | |
vColor.xyz *= color.xyz; | |
#endif | |
#ifdef USE_INSTANCING_COLOR | |
vColor.xyz *= instanceColor.xyz; | |
#endif | |
vec3 objectNormal = vec3( normal ); | |
#ifdef USE_TANGENT | |
vec3 objectTangent = vec3( tangent.xyz ); | |
#endif | |
#ifdef USE_MORPHNORMALS | |
objectNormal *= morphTargetBaseInfluence; | |
objectNormal += morphNormal0 * morphTargetInfluences[ 0 ]; | |
objectNormal += morphNormal1 * morphTargetInfluences[ 1 ]; | |
objectNormal += morphNormal2 * morphTargetInfluences[ 2 ]; | |
objectNormal += morphNormal3 * 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; | |
#ifdef USE_TANGENT | |
objectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz; | |
#endif | |
#endif | |
vec3 transformedNormal = objectNormal; | |
#ifdef USE_INSTANCING | |
mat3 m = mat3( instanceMatrix ); | |
transformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) ); | |
transformedNormal = m * transformedNormal; | |
#endif | |
transformedNormal = normalMatrix * transformedNormal; | |
#ifdef FLIP_SIDED | |
transformedNormal = - transformedNormal; | |
#endif | |
#ifdef USE_TANGENT | |
vec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz; | |
#ifdef FLIP_SIDED | |
transformedTangent = - transformedTangent; | |
#endif | |
#endif | |
#ifndef FLAT_SHADED | |
vNormal = normalize( transformedNormal ); | |
#endif | |
vec3 transformed = vec3( position ); | |
#ifdef USE_MORPHTARGETS | |
transformed *= morphTargetBaseInfluence; | |
transformed += morphTarget0 * morphTargetInfluences[ 0 ]; | |
transformed += morphTarget1 * morphTargetInfluences[ 1 ]; | |
transformed += morphTarget2 * morphTargetInfluences[ 2 ]; | |
transformed += morphTarget3 * morphTargetInfluences[ 3 ]; | |
#ifndef USE_MORPHNORMALS | |
transformed += morphTarget4 * morphTargetInfluences[ 4 ]; | |
transformed += morphTarget5 * morphTargetInfluences[ 5 ]; | |
transformed += morphTarget6 * morphTargetInfluences[ 6 ]; | |
transformed += morphTarget7 * 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 | |
#ifdef USE_DISPLACEMENTMAP | |
transformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias ); | |
#endif | |
vec4 mvPosition = vec4( transformed, 1.0 ); | |
#ifdef USE_INSTANCING | |
mvPosition = instanceMatrix * mvPosition; | |
#endif | |
mvPosition = modelViewMatrix * mvPosition; | |
gl_Position = projectionMatrix * mvPosition; | |
#ifdef USE_LOGDEPTHBUF | |
#ifdef USE_LOGDEPTHBUF_EXT | |
vFragDepth = 1.0 + gl_Position.w; | |
vIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) ); | |
#else | |
if ( isPerspectiveMatrix( projectionMatrix ) ) { | |
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 | |
vClipPosition = - mvPosition.xyz; | |
#endif | |
vViewPosition = - mvPosition.xyz; | |
#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) | |
vec4 worldPosition = vec4( transformed, 1.0 ); | |
#ifdef USE_INSTANCING | |
worldPosition = instanceMatrix * worldPosition; | |
#endif | |
worldPosition = modelMatrix * worldPosition; | |
#endif | |
#ifdef USE_ENVMAP | |
#ifdef ENV_WORLDPOS | |
vWorldPosition = worldPosition.xyz; | |
#else | |
vec3 cameraToVertex; | |
if ( isOrthographic ) { | |
cameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) ); | |
} else { | |
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 | |
#ifdef USE_SHADOWMAP | |
#if 0 > 0 || 0 > 0 || 0 > 0 | |
vec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix ); | |
vec4 shadowWorldPosition; | |
#endif | |
#if 0 > 0 | |
#endif | |
#if 0 > 0 | |
#endif | |
#if 0 > 0 | |
#endif | |
#endif | |
#ifdef USE_FOG | |
fogDepth = - mvPosition.z; | |
#endif | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment