Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- uniform lowp sampler2D uTexture0; // decal
- uniform lowp sampler2D uTexture1; // normal
- uniform lowp sampler2D uTexture2; // specular
- uniform lowp sampler2D uTexture3; // gloss
- uniform lowp sampler2D uTexture4; // height
- uniform lowp sampler2D uTexture5; // ao
- uniform lowp samplerCube uTexture6; // cube
- uniform lowp vec4 uMaterialGloss; // { x = uGlossBias, y = uGlossHorizonSmooth }
- uniform lowp vec4 uMaterialPhong; // { x = uPhongBrightness, y = uPhongHorizonFade }
- uniform lowp vec4 uMaterialSpecularColor; // uSpecularColor
- uniform lowp vec4 uMaterialSpecularFrensel; // uSpecularFresnel
- uniform lowp vec4 uMaterialAO; //{ x = uAmbientOcclusionStrength }
- uniform lowp vec4 uMaterialParallax; // { xy = uParallaxDepthOffset
- uniform lowp vec4 uMaterialAnisotropic; // { x = uAnisoBrightness, y = uAnisoHorizonFade, z = uAnisoSpread
- uniform lowp vec4 uMaterialMicrofiber; //x = uAnisoBrightness, y = uMicrofiberScatter, z = uAnisoSpread
- varying mediump vec3 outUV0;
- varying mediump vec3 outNormal;
- varying mediump vec3 outTangent;
- varying mediump vec3 outPosition;
- varying mediump vec3 outWorldNormal;
- uniform highp vec3 uLightPos;
- uniform highp vec3 uLightColor;
- uniform highp vec3 uLightAtten;
- uniform highp vec3 uEyePos;
- uniform highp vec3 uLightDiffuseSphere[9];
- #define SPECULAR_IMPORTANCE_SAMPLES 32
- uniform highp vec4 uPhongRands[SPECULAR_IMPORTANCE_SAMPLES];
- #if USE_MATERIAL_PARAM
- #define uGlossBias uMaterialGloss.x
- #define uGlossHorizonSmooth uMaterialGloss.y
- #define uPhongBrightness uMaterialPhong.x
- #define uPhongHorizonFade uMaterialPhong.y
- #define uSpecularColor uMaterialSpecularColor.xyz
- #define uSpecularFresnel uMaterialSpecularFrensel.xyz
- #define uAmbientOcclusionStrength uMaterialAO.x
- #define uParallaxDepthOffset uMaterialParallax
- #define uAnisoBrightness uMaterialAnisotropic.x
- #define uAnisoHorizonFade uMaterialAnisotropic.y
- #define uAnisoSpread uMaterialAnisotropic.z
- #define uMicrofiberColor uMaterialMicrofiber.x
- #define uMicrofiberScatter uMaterialMicrofiber.y
- #define uMicrofiberOcc uMaterialMicrofiber.z
- #else
- const mediump float uPhongBrightness = 1.0;
- const mediump float uPhongHorizonFade = 1.0;
- const mediump float uGlossHorizonSmooth = 0.5;
- const mediump float uGlossBias = 1.0;//0.7
- const mediump vec3 uSpecularColor = vec3(1.0, 1.0, 1.0);
- const mediump vec3 uSpecularFresnel = vec3(1.0, 1.0, 1.0);
- //const vec2 uParallaxDepthOffset = vec2(0.037, 0.5);
- const mediump vec2 uParallaxDepthOffset = vec2(0.1, 1.0);
- const mediump float uAmbientOcclusionStrength = 1.0;
- const mediump float uAnisoBrightness = 1.0;
- const mediump float uAnisoHorizonFade = 1.0;
- const mediump float uAnisoSpread = 1.0;
- const mediump float uMicrofiberScatter = 0.777;
- const mediump float uMicrofiberOcc = 0.5;
- const mediump float uMicrofiberColor = 1.0;
- #endif
- const mediump float uMaskWithGloss = 0.0;
- const mediump vec3 uAnisoDirectionMapScale = vec3(2.0,2.0,2.0);
- const mediump vec3 uAnisoDirectionMapBias = vec3(-1.0,-1.0,-1.0);
- const mediump float uAnisoDirectionMapSwizzle = 0.0;
- const mediump vec3 uAnisoDirectionConst = vec3(1.0, 0.0, 0.0);
- //
- //
- #define uAnisoRands uPhongRands
- mediump float saturate(mediump float x)
- {
- return clamp(x, 0.0, 1.0);
- }
- mediump vec3 saturate(mediump vec3 x)
- {
- return clamp(x, 0.0, 1.0);
- }
- const lowp vec3 fvLightColor = vec3(255.0/255.0, 165.0/255.0, 79.0/255.0);
- //const lowp vec3 fvLightColor = vec3(1.0, 1.0, 1.0);
- const lowp vec3 fvLightShadow = vec3(1.0, 1.0, 1.0);
- //const lowp vec3 fvReflectivity = vec3(0.5, 0.5, 0.5);
- const lowp vec3 fvReflectivity = vec3(1.0, 1.0, 1.0);
- const lowp vec3 fvFresnel = vec3(1.0, 1.0, 1.0);
- mediump float wrapLight(mediump float DP, mediump float scatter)
- {
- mediump float res = saturate( DP*(1.0-scatter) + scatter );
- return res;
- }
- mediump vec3 wrapLight3(mediump float DP, mediump vec3 scatter)
- {
- mediump vec3 res = saturate( DP*(vec3(1.0,1.0,1.0)-scatter) + scatter );
- return res;
- }
- mediump float wrapLightIntegral(mediump float scatter)
- {
- return (1.0 / 3.14159) * (1.0 - scatter);
- }
- mediump vec3 wrapLightIntegral3(mediump vec3 scatter)
- {
- return (1.0 / 3.14159) * (vec3(1.0,1.0,1.0)-scatter);
- }
- mediump float diffuseFresnel(mediump float eyeDP, mediump float scatter, mediump float occ, mediump float occWeight)
- {
- eyeDP = 1.0 - eyeDP;
- mediump float dp4 = eyeDP * eyeDP; dp4 *= dp4;
- eyeDP = mix(dp4, eyeDP*0.4, scatter); //0.4 is energy conserving integral
- return mix(eyeDP, eyeDP*occ, occWeight); //occlude with occ term
- }
- mediump vec3 diffuseFresnel3(mediump float eyeDP, mediump float scatter, mediump vec3 occ, mediump float occWeight)
- {
- eyeDP = 1.0 - eyeDP;
- mediump float dp4 = eyeDP * eyeDP; dp4 *= dp4;
- eyeDP = mix(dp4, eyeDP*0.4, scatter); //0.4 is energy conserving integral
- return mix(vec3(eyeDP,eyeDP,eyeDP), eyeDP*occ, occWeight); //occlude with occ term
- }
- #if 0
- vec3 DirectLightingFuncGGX(float gloss, vec3 N, vec3 V, vec3 L, vec3 H, float LAtten)
- {
- //roughness
- float roughness = 1.0 - gloss;
- float a = max( roughness * roughness, 2e-3 );
- float a2 = a * a;
- //light params
- //LightParams l = getLight( s.vertexPosition );
- //adjustAreaLightSpecular( l, reflect( -s.vertexEye, s.normal ), rcp(3.141592 * a2) );
- //various dot products
- //vec3 H = normalize(L + V);
- float NdotH = saturate(dot(N,H));
- float VdotN = saturate(dot(V,N));
- float LdotN = saturate(dot(L,N));
- float VdotH = saturate(dot(V,H));
- //horizon
- float atten = LAtten;
- float horizon = 1.0 - LdotN;
- horizon *= horizon; horizon *= horizon;
- atten = atten - atten * horizon;
- //incident light
- vec3 spec = fvLightColor * fvLightShadow * (atten * LdotN);
- //microfacet distribution
- float d = ( NdotH * a2 - NdotH ) * NdotH + 1.0;
- d *= d;
- float D = a2 / (3.141593 * d);
- //geometric / visibility
- float k = a * 0.5;
- float G_SmithL = LdotN * (1.0 - k) + k;
- float G_SmithV = VdotN * (1.0 - k) + k;
- float G = 0.25 / ( G_SmithL * G_SmithV );
- //fresnel
- vec3 reflectivity = fvReflectivity;
- vec3 fresn = fvFresnel;
- vec3 F = reflectivity + (fresn - fresn*reflectivity) * exp2( (-5.55473 * VdotH - 6.98316) * VdotH );
- return (D * G) * (F * spec);
- //return vec3(LAtten);
- //return vec3((G) * (F * spec));
- //return vec3((D * G) * (F));
- //return vec3(F);
- }
- float sRGB_gamma_correct(float c)
- {
- const float a = 0.055;
- if(c < 0.0031308)
- return 12.92*c;
- else
- return (1.0+a)*pow(c, 1.0/2.4) - a;
- }
- #endif
- mediump float rcp(mediump float x)
- {
- return 1.0 / x;
- }
- // constant that are used to adjust lighting
- const mediump float C1 = 0.429043;
- const mediump float C2 = 0.511664;
- const mediump float C3 = 0.743125;
- const mediump float C4 = 0.886227;
- const mediump float C5 = 0.247708;
- mediump vec3 toRGBM(mediump vec3 srgb)
- {
- return pow(srgb, vec3(1.0/1.2));
- }
- mediump vec3 toRGB(mediump vec3 srgb)
- {
- return pow(srgb, vec3(1.0/2.2));
- }
- mediump float tosRGBFloat(mediump float rgba)
- {
- mediump float srgb = (rgba*rgba)*(rgba*0.2848 + 0.7152);
- return srgb;
- }
- mediump vec4 tosRGB(mediump vec4 rgba)
- {
- mediump vec3 srgb = (rgba.xyz*rgba.xyz)*(rgba.xyz*vec3(0.2848,0.2848,0.2848) + vec3(0.7152,0.7152,0.7152));
- return vec4(srgb, rgba.a);
- }
- mediump vec3 tosRGB(mediump vec3 rgb)
- {
- mediump vec3 srgb = (rgb.xyz*rgb.xyz)*(rgb.xyz*vec3(0.2848,0.2848,0.2848) + vec3(0.7152,0.7152,0.7152));
- return srgb;
- }
- mediump float MicrosurfaceGlossMap(mediump vec2 uv, mediump vec3 N, mediump vec3 V)
- {
- //float g = dot( texture2D( uTexture3, uv ), uGlossSwizzle );
- mediump float g = texture2D( uTexture3, uv ).r;
- mediump float gloss = g * uGlossBias;
- mediump float h = saturate( dot( N, V ) );
- h = uGlossHorizonSmooth - h * uGlossHorizonSmooth;
- gloss = mix( gloss, 1.0, h*h );
- //return dot( N, V );
- return gloss;
- }
- #define SPECULAR_IMPORTANCE_SAMPLES 32
- mediump vec3 phongImportanceSample( mediump vec4 r, mediump float specExp )
- {
- mediump float cos_theta = pow( r.x, 1.0 / (specExp + 1.0) );
- mediump float sin_theta = sqrt( 1.0 - cos_theta*cos_theta );
- mediump float cos_phi = r.z;
- mediump float sin_phi = r.w;
- return vec3( cos_phi*sin_theta, sin_phi*sin_theta, cos_theta );
- }
- mediump vec3 fix_cube_lookup(mediump vec3 v)
- {
- mediump float cube_size = 512.0;
- mediump float M = max(max(abs(v.x), abs(v.y)), abs(v.z));
- mediump float scale = (cube_size - 1.0) / cube_size;
- if (abs(v.x) != M) v.x *= scale;
- if (abs(v.y) != M) v.y *= scale;
- if (abs(v.z) != M) v.z *= scale;
- return v;
- }
- mediump vec3 fresnel( mediump float cosTheta,
- mediump vec3 reflectivity,
- mediump vec3 fresnelStrength )
- {
- //schlick's fresnel approximation
- mediump float f = saturate( 1.0 - cosTheta );
- mediump float f2 = f*f; f *= f2 * f2;
- return mix( reflectivity, vec3(1.0,1.0,1.0), f*fresnelStrength );
- }
- #if 1
- #define ANISO_IMPORTANCE_SAMPLES 32
- void SampleAnisoTangent(mediump vec3 N, out mediump vec3 tangent, out mediump vec3 bitangent, mediump vec3 vertexTangent, mediump vec3 vertexBitangent, mediump vec3 vertexNormal)
- {
- //Direction
- tangent = vec3(0.5, 0.5, 0.5); //texture2D( tAnisoDirectionMap, s.vertexTexCoord ).xyz;
- tangent = tangent * 2.0 - 1.0;
- //zero if a tangent map is present
- tangent += uAnisoDirectionConst;
- //swizzle tangent and binormal directions
- tangent.xy = mix(tangent.xy, tangent.yx, uAnisoDirectionMapSwizzle);
- //transform into render space
- tangent = tangent.x * vertexTangent + tangent.y * vertexBitangent + tangent.z * vertexNormal;
- //project tangent onto normal plane
- tangent = tangent - N*dot( tangent, N );
- tangent = normalize( tangent );
- bitangent = normalize( cross( N, tangent ) );
- }
- //returns a random hemisphere vector, with probabilty weighted to a pow() lobe of 'specExp'
- mediump vec3 anisoImportanceSampleDirection(mediump vec4 r,mediump float specExp )
- {
- mediump float cos_theta = pow( r.x, 1.0 / (specExp + 1.0) );
- mediump float sin_theta = sqrt( 1.0 - cos_theta*cos_theta );
- mediump float cos_phi = r.z;
- mediump float sin_phi = r.w;
- return vec3( cos_phi*sin_theta, sin_phi*sin_theta, cos_theta );
- }
- mediump float computeAnisoLOD( mediump float specExp, mediump vec3 H, mediump vec3 N )
- {
- mediump float pdf = (specExp + 4.0)/(8.0*3.14159) * pow( saturate( dot( H, N ) ), specExp );
- return 0.5 * log2( (256.0*256.0)/float(ANISO_IMPORTANCE_SAMPLES) ) - 0.5 * log2( pdf ) + 0.5;
- }
- //@TODO:!!!
- //#extension GL_EXT_gpu_shader4 : enable
- mediump vec3 Anisotropic(mediump float gloss, mediump vec3 V, mediump vec3 N, mediump vec3 vertexTangent, mediump vec3 vertexBitangent, mediump vec3 vertexNormal, mediump vec3 reflectivity, mediump vec3 fresn)
- {
- mediump float anisoSpread = uAnisoSpread;
- //determine specular exponent from gloss map & settings
- mediump float specExp = -10.0 / log2( gloss*0.968 + 0.03 );
- specExp *= specExp;
- //something happens to the importance samples at exp=16 and there's a noticeable jump --Andres
- specExp = max(16.1,specExp);
- //aniso
- mediump vec3 T, B; SampleAnisoTangent( N, T, B, vertexTangent, vertexBitangent, vertexNormal );
- mediump vec3 E = -V;
- mediump vec3 R = reflect(E,N);
- //sample the reflection map repeatedly, with an importance-based sample distribution
- mediump vec3 basisX = normalize( cross( N, vec3(0.0, 1.0, saturate(N.y*10000.0 - 9999.0) ) ) );
- mediump vec3 basisY = cross( basisX, N );
- mediump vec3 basisZ = N;
- mediump vec3 spec = vec3(0.0, 0.0, 0.0);
- mediump float anisoExp = 16.0;
- anisoSpread = max(0.01, anisoSpread);
- mediump float invSampleCount = 1.0/float(ANISO_IMPORTANCE_SAMPLES-1);
- mediump vec3 dB = B;
- mediump vec3 dT = T;
- //HINT_LOOP
- for(mediump int i=0; i<ANISO_IMPORTANCE_SAMPLES; ++i )
- {
- mediump vec4 r = uAnisoRands[i];
- mediump float ct = 1.0;
- mediump float st = 0.0;
- mediump float cp = 0.0;
- mediump float sp = 1.0;
- mediump vec3 zero = vec3(cp*st, sp*st, ct);
- mediump vec3 dirSpec = anisoImportanceSampleDirection(r, specExp);
- mediump vec3 dirAniso = anisoImportanceSampleDirection(r, anisoExp);
- //dir into world-space
- dirSpec = dirSpec.x*basisX + dirSpec.y*basisY + dirSpec.z*basisZ;
- dirAniso = dirAniso.x*basisX + dirAniso.y*basisY + dirAniso.z*basisZ;
- mediump vec3 iT = vec3(T.x,B.x,N.x);
- mediump vec3 iB = vec3(T.y,B.y,N.y);
- mediump vec3 iN = vec3(T.z,B.z,N.z);
- //dir into tangent space
- mediump vec3 dirCombined;
- dirCombined = iT*dirSpec.x + iB*dirSpec.y + iN*dirSpec.z;
- dirAniso = iT*dirAniso.x + iB*dirAniso.y + iN*dirAniso.z;
- //bias the binormal components of dir by anisoSpread
- mediump float lodMix = abs(dirAniso.y - dirCombined.y) * anisoSpread;
- dirCombined.y = mix(dirCombined.y, dirAniso.y, anisoSpread);
- //combined dir out of tangent space
- mediump vec3 hAniso = normalize(T*dirCombined.x + B*dirCombined.y + N*dirCombined.z);
- mediump vec3 hSpec = dirSpec;
- //compute aniso filtering scale, cannot exceed 0.5 or cubemap borders bleed nonsense into the lookups
- mediump float lodSpec = computeAnisoLOD(specExp, hSpec, N);
- lodSpec = min(saturate(lodSpec / 16.0), 0.4);
- mediump float lodAniso = min(0.15*anisoSpread + lodSpec, 0.4);
- dirSpec = reflect(E, hSpec);
- dirAniso = reflect(E, hAniso);
- mediump vec3 lookup = dirAniso;
- //aniso filtering must happen along axes perpendicular to reflection, which is different every sample
- //TODO: 64x normalize? This is gross >_<!
- dB = normalize(dirAniso-dirSpec);
- dT = normalize(cross(dB,R));
- //spec += vec3(lodSpec);
- spec += textureCubeGrad(uTexture6, lookup, dT*lodSpec, dB*lodAniso ).xyz;
- //spec += textureGrad(uTexture6, lookup, dT*lodSpec, dB*lodAniso ).xyz;
- }
- spec *= invSampleCount;
- spec *= uAnisoBrightness;
- //fresnel
- mediump float glossAdjust = gloss*gloss;
- spec *= fresnel( dot(V, N),
- reflectivity,
- fresn * glossAdjust );
- //mask for local reflections
- //spec *= texture2D( tLocalReflectionMap, s.screenTexCoord ).x;
- //horizon test, reflection vector should quickly fade once it points under the surface
- mediump vec3 r = reflect( -V, N );
- mediump float horiz = dot( r, vertexNormal );
- horiz = saturate( 1.0 + uAnisoHorizonFade*horiz );
- horiz *= horiz;
- spec *= horiz;
- //add our contribution
- //spec = vec3(anisoSpread, 0.0, 0.0);
- return spec;
- }
- #endif
- #ifdef USE_PHONG
- mediump vec3 BlinnPhong(mediump float gloss, mediump vec3 V, mediump vec3 N, mediump vec3 vertexNormal, mediump vec3 reflectivity, mediump vec3 fresn )
- {
- mediump float specExp = -10.0 / log2( gloss*0.968 + 0.03 );
- specExp *= specExp;
- //sample the reflection map repeatedly, with an importance-based sample distribution
- mediump vec3 basisX = normalize( cross( N, vec3(0.0, 1.0, saturate(N.y*10000.0 - 9999.0) ) ) );
- mediump vec3 basisY = cross( basisX, N );
- mediump vec3 basisZ = N;
- mediump vec3 spec = vec3(0.0, 0.0, 0.0);
- for(mediump int i=0; i<SPECULAR_IMPORTANCE_SAMPLES; ++i )
- {
- mediump vec4 r = uPhongRands[i];
- mediump vec3 dir = phongImportanceSample(r, specExp);
- mediump vec3 h = dir.x*basisX + dir.y*basisY + dir.z*basisZ;
- mediump float pdf = (specExp + 4.0)/(8.0*3.14159) * pow( saturate( dot( h, N ) ), specExp );
- mediump float lod = (0.5 * log2( (256.0*256.0)/float(SPECULAR_IMPORTANCE_SAMPLES) ) + 0.5) - 0.5*log2( pdf );
- //vec3 lookup = reflect( -V, N );
- mediump vec3 lookup = reflect( -V, h );
- mediump vec3 tcube = textureCubeLod( uTexture6, lookup, lod ).xyz;
- spec += (1.0/float(SPECULAR_IMPORTANCE_SAMPLES)) * tcube;
- }
- //return tosRGB(textureCubeLod( uTexture6, vec3(0.5, 0.5, -0.5), 0.0 )).xyz;
- spec *= uPhongBrightness;
- //fresnel
- mediump float glossAdjust = gloss*gloss;
- spec *= fresnel( dot( V, N ),
- reflectivity,
- fresn * glossAdjust );
- mediump vec3 r = reflect( -V, N );
- mediump float horiz = dot( r, vertexNormal );
- horiz = saturate( 1.0 + uPhongHorizonFade*horiz );
- horiz *= horiz;
- //mask for local reflections
- //spec *= texture2D( tLocalReflectionMap, s.screenTexCoord ).x;
- spec *= horiz;
- //return vec3(horiz);
- return spec;
- }
- #endif
- #ifdef USE_PARALLAX
- mediump float ParallaxSample( mediump vec2 c )
- {
- c.y = 1.0 - c.y;
- return 1.0 - texture2DLod( uTexture4, c, 0.0 ).r;
- }
- void SurfaceParallaxMap(inout mediump vec2 uv0, mediump vec3 V, mediump vec3 vertexTangent, mediump vec3 vertexBitangent, mediump vec3 vertexNormal)
- {
- mediump vec3 dir = vec3( dot( -V, vertexTangent ),
- dot( -V, vertexBitangent ),
- dot( -V, vertexNormal ) );
- mediump vec2 maxOffset = dir.xy * (uParallaxDepthOffset.x / (abs(dir.z) + 0.001));
- mediump float minSamples = 16.0;
- mediump float maxSamples = 128.0;
- mediump float samples = saturate( 3.0*length(maxOffset) );
- mediump float incr = rcp( mix( minSamples, maxSamples, samples ) );
- mediump vec2 tc0 = uv0 - (1.0-uParallaxDepthOffset.y)*maxOffset;
- mediump float h0 = ParallaxSample( tc0 );
- //HINT_LOOP
- for(mediump float i=incr; i<=1.0; i+=incr )
- {
- mediump vec2 tc = tc0 + maxOffset * i;
- mediump float h1 = ParallaxSample( tc );
- if( i >= h1 )
- {
- //hit! now interpolate
- mediump float r1 = i, r0 = i-incr;
- mediump float t = (h0-r0)/((h0-r0)+(-h1+r1));
- mediump float r = (r0-t*r0) + t*r1;
- uv0 = tc0 + r*maxOffset;
- break;
- }
- h0 = h1;
- }
- //uv0.x = h0;
- //standard normal mapping
- //SurfaceNormalMap(s);
- }
- #endif
- mediump vec3 GetNormal(mediump vec2 uv, inout mediump vec3 vertexTangent, inout mediump vec3 vertexBitangent, inout mediump vec3 vertexNormal)
- {
- #if 0
- return normalize(vertexNormal);
- #else
- //sample and scale/bias the normal map
- //vec3 n = vec3(0.0, 1.0, 0.0);
- mediump vec3 n = texture2D(uTexture1, uv).xyz * 2.0 - 1.0;
- //TODO: invert normals
- //n.xy = -n.xy;
- //n.y = -n.y;
- mediump vec3 T = vertexTangent;
- mediump vec3 N = vertexNormal;
- mediump vec3 B = vertexBitangent;
- //ortho-normalization
- mediump float renormalize = 1.0;
- mediump float orthogonalize = 1.0;
- mediump float regenBitangent = 1.0;
- N = mix( N, normalize(N), renormalize );
- T -= (orthogonalize * dot(T,N)) * N;
- T = mix( T, normalize(T), renormalize );
- B -= orthogonalize * (dot(B,N)*N + dot(B,T)*T);
- B = mix( B, normalize(B), renormalize );
- //regenerate bitangent
- mediump vec3 B2 = cross( N, T );
- B2 = dot(B2,B) < 0.0 ? -B2 : B2;
- B = mix( B, B2, regenBitangent );
- vertexTangent = T;
- vertexBitangent = B;
- vertexNormal = N;
- //store our results
- return normalize( n.x*T + n.y*B + n.z*N );
- #endif
- }
- mediump vec3 GetSHLight(mediump vec3 N)
- {
- return (C1 * uLightDiffuseSphere[8] * (N.x*N.x - N.y*N.y)
- + C3 * uLightDiffuseSphere[6] * N.z*N.z
- + C4 * uLightDiffuseSphere[0]
- - C5 * uLightDiffuseSphere[6]
- + 2.0 * C1 * (uLightDiffuseSphere[4]*N.x*N.y + uLightDiffuseSphere[7]*N.x*N.z + uLightDiffuseSphere[5]*N.y*N.z)
- + 2.0 * C2 * (uLightDiffuseSphere[3]*N.x + uLightDiffuseSphere[1]*N.y + uLightDiffuseSphere[2]*N.z ));
- }
- mediump vec3 ImageLambert(mediump vec3 N,mediump vec3 V,mediump vec3 albedo)
- {
- return GetSHLight(N) * albedo;
- }
- #ifdef USE_MICROFIBER
- mediump vec3 ImageMicrofiber(mediump vec3 N,mediump vec3 V,mediump vec3 albedo,mediump float gloss)
- {
- mediump vec3 shLight = GetSHLight(N);
- mediump vec3 diffuseLight = shLight * albedo;
- //ambient occlusion
- mediump float AO = 1.0;
- //float AO = sampleOcclusion( s );
- //s.diffuseLight *= AO;
- //PEACH-FUZZ
- mediump vec3 fuzzMap = albedo;// texture2D( uTexture0, s.vertexTexCoord );
- mediump float eyeDP = dot( V, N );
- mediump vec3 fuzzLight = shLight;
- fuzzLight *= diffuseFresnel( eyeDP, uMicrofiberScatter, AO, uMicrofiberOcc );
- mediump float wet = saturate(1.0 - gloss*uMaskWithGloss);
- fuzzLight *= wet*wet;
- diffuseLight += fuzzLight * uMicrofiberColor * fuzzMap.rgb;
- return diffuseLight;
- }
- #endif
- #if 1
- struct LightParams
- {
- mediump vec3 color; // "colour"
- mediump vec3 toSource; // vector from shaded point to light
- mediump vec3 direction; // normalized vector to light
- mediump float invDistance; // 1/distance to light
- mediump float distance; // distance to light
- mediump float attenuation; // dimming (distance and other factors)
- };
- const mediump vec3 uDirectLightColor = vec3(255.0/255.0, 165.0/255.0, 79.0/255.0);
- mediump vec3 rsqrt(mediump vec3 a)
- {
- return pow(a, vec3(-0.5));
- }
- LightParams getLight(mediump vec3 shadedPosition )
- {
- LightParams p;
- //color
- p.color = uDirectLightColor;
- //light vectors
- p.toSource = uLightPos.xyz - shadedPosition * 1.0; //uLightPos.w;
- p.invDistance = 1.0 / sqrt( dot(p.toSource, p.toSource) );
- p.distance = rcp( p.invDistance );
- p.direction = p.toSource * p.invDistance;
- //distance attenuation
- mediump float a = saturate( p.distance * uLightAtten.z );
- p.attenuation = 1.0 + uLightAtten.x*a + uLightAtten.y*a*a;
- return p;
- }
- void adjustAreaLightSpecular( inout LightParams p, mediump vec3 dir, mediump float nrm )
- {
- mediump vec3 L = p.toSource;
- //energy conservation estimate
- mediump float sizeGuess = 0.0;
- mediump float solidAngleGuess = saturate( sizeGuess * p.invDistance );
- p.attenuation *= rcp( 1.0 + nrm * solidAngleGuess );
- //export
- p.toSource = L;
- p.direction = normalize( p.toSource );
- }
- mediump vec3 DirectLightingPhong(mediump float gloss, mediump vec3 P, mediump vec3 V, mediump vec3 N, mediump vec3 reflectivity, mediump vec3 fresn)
- {
- //determine specular exponent from gloss map & settings
- gloss = min( gloss, 0.995 );
- mediump float specExp = -10.0 / log2( gloss*0.968 + 0.03 );
- specExp *= specExp;
- //light params
- LightParams l = getLight( P );
- mediump float phongNormalize = (specExp + 4.0)/(8.0*3.141592);
- adjustAreaLightSpecular( l, reflect( -V, N ), phongNormalize );
- //blinn-phong term
- mediump vec3 H = normalize( V + l.direction );
- mediump float phong = phongNormalize * pow( saturate( dot(H, N) ), specExp );
- //horizon occlusion
- mediump float horizon = 1.0 - saturate( dot( l.direction, N ) );
- horizon *= horizon; horizon *= horizon;
- phong = phong - phong*horizon;
- //spec color
- mediump float s_shadow = 1.0;
- mediump vec3 spec = (s_shadow * l.attenuation) *
- saturate( dot( l.direction, N ) ) *
- l.color;
- //fresnel
- mediump float glossAdjust = gloss*gloss;
- spec *= fresnel( dot( V, N ),
- reflectivity,
- fresn * glossAdjust );
- //add it on
- return spec * phong;
- }
- mediump vec3 DirectDiffusionLambert(mediump vec3 P, mediump vec3 V, mediump vec3 N, mediump vec3 albedo)
- {
- LightParams l = getLight( P );
- //adjustAreaLightDiffuse( l, P );
- mediump float lambert = (1.0/3.1415926) * saturate( dot(N, l.direction) );
- mediump float s_shadow = 1.0;
- return (lambert * l.attenuation) * (l.color * s_shadow) * albedo;
- }
- mediump vec3 DirectLightingAnisotropic(mediump float gloss, mediump vec3 P, mediump vec3 V, mediump vec3 N, mediump vec3 vertexTangent, mediump vec3 vertexBitangent, mediump vec3 vertexNormal, mediump vec3 reflectivity, mediump vec3 fresn)
- {
- LightParams l = getLight( P );
- adjustAreaLightSpecular( l, reflect( -V, N ), 1.0-gloss );
- //gloss
- //determine specular exponent from gloss map & settings
- mediump float specExp = -10.0 / log2( gloss*0.968 + 0.03 );
- specExp *= specExp;
- mediump float anisoExp = mix( specExp, 16.0, uAnisoSpread );
- //blinn-phong
- mediump vec3 h = normalize( V + l.direction );
- //anisotropic projection
- //h is projected onto the B-plane (shared by strand dir and N) to max out the dot-product along the B axis.
- mediump vec3 T, B;
- SampleAnisoTangent( N, T, B, vertexTangent, vertexBitangent, vertexNormal );
- h = normalize(h - B*dot(h,B) * sqrt(uAnisoSpread));
- mediump float HdotN = saturate( dot( h, N ) );
- mediump float illum = pow( HdotN, specExp );
- illum *= (specExp + 4.0)/(8.0*3.141592);
- illum *= 1.0 - uAnisoSpread * 0.5;
- //horizon
- mediump float horizon = 1.0 - saturate( dot( l.direction, N ) );
- horizon *= horizon; horizon *= horizon;
- illum = illum - illum*horizon;
- //spec color
- mediump vec3 spec = (l.attenuation * illum) * l.color;
- //fresnel
- mediump float glossAdjust = gloss*gloss;
- spec *= fresnel( dot( V, N ),
- reflectivity,
- fresn * glossAdjust );
- //add it on
- return spec;// * s.shadow;
- }
- #endif
- void main (void)
- {
- mediump vec3 toLightSource = (uLightPos - outPosition);
- mediump float toSourceInvLen = inversesqrt(dot(toLightSource, toLightSource));
- mediump float toLightDist = rcp(toSourceInvLen);
- mediump float a = saturate(toLightDist * uLightAtten.z);
- mediump float toLightAtten = 1.0 + uLightAtten.x*a + uLightAtten.y*a*a;
- mediump vec3 L = toLightSource * toSourceInvLen;
- mediump vec3 V = normalize(uEyePos - outPosition);
- mediump vec3 vertexNormal = outNormal;// vec3(0.0);
- //vertexNormal.y = -vertexNormal.y;
- mediump vec3 vertexTangent = outTangent;
- //note fix outUV0.z: mirror uv
- mediump vec3 vertexBitangent = cross(vertexTangent, vertexNormal)*(-outUV0.z);
- mediump vec2 uv0 = outUV0.xy;
- #ifdef USE_PARALLAX
- SurfaceParallaxMap(uv0, V, vertexTangent, vertexBitangent, vertexNormal);
- #endif
- uv0.y = 1.0 - uv0.y;
- mediump vec3 N = GetNormal(uv0, vertexTangent, vertexBitangent, vertexNormal);
- mediump vec3 H = normalize(L + V);
- mediump float gloss = MicrosurfaceGlossMap(uv0, N, V);
- gl_FragColor.rgb = vec3(0.0);
- mediump vec3 reflectivity = uSpecularColor * tosRGB(texture2D( uTexture2, uv0 ).xyz);
- mediump vec3 fresnel = uSpecularFresnel;
- mediump vec3 albedo = tosRGB(texture2D(uTexture0, uv0)).xyz;
- albedo = albedo - albedo * reflectivity;
- mediump vec3 diffuseLight = vec3(0.0);
- mediump vec3 specularLight = vec3(0.0);
- #ifdef USE_MICROFIBER
- //vec3 N, vec3 V, vec3 albedo, float gloss)
- diffuseLight = ImageMicrofiber(N, V, albedo, gloss);
- #else
- diffuseLight = ImageLambert(N, V, albedo);
- #endif
- #ifdef USE_PHONG
- specularLight = BlinnPhong(gloss, V, N, vertexNormal, reflectivity, fresnel);
- #endif
- #ifdef USE_ANISOTROPIC
- specularLight = Anisotropic(gloss, V, N, vertexTangent, vertexBitangent, vertexNormal, reflectivity, fresnel);
- #endif
- mediump float diff = 1.0;
- mediump float spec = 1.0;
- #ifdef USE_AO
- //vec2 tc = mix( s.vertexTexCoord, s.vertexTexCoordSecondary, uAmbientOcclusionUseSecondaryUV );
- mediump vec2 tc = uv0;
- mediump float ao = tosRGBFloat(texture2D( uTexture5, tc ).r);
- ao = ao * uAmbientOcclusionStrength + (1.0 - uAmbientOcclusionStrength);
- diff = ao;
- #endif
- #if 1
- diffuseLight *= diff;
- specularLight *= spec;
- #endif
- #if 1
- diffuseLight += DirectDiffusionLambert(outPosition, V, N, albedo)*diff;
- #ifdef USE_ANISOTROPIC
- specularLight += DirectLightingAnisotropic(gloss, outPosition, V, N, vertexTangent, vertexBitangent, vertexNormal, reflectivity, fresnel)*spec;
- #else
- specularLight += DirectLightingPhong(gloss, outPosition, V, N, reflectivity, fresnel)*spec;
- #endif
- #endif
- gl_FragColor = vec4(diffuseLight*diff + specularLight*spec, 1.0);
- gl_FragColor.xyz = toRGB(gl_FragColor.xyz);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement