struct Vert { float4 pos : POSITION; float2 coefs : TEXCOORD0; float2 tc0 : TEXCOORD1; float3 norm : TEXCOORD2; float3 objpos : TEXCOORD3; float3 R : TEXCOORD4; }; struct Pix { float3 col : COLOR0; }; Pix main( Vert I, // textures const uniform sampler2D colorMap : register(s0), const uniform sampler2D wetMap : register(s2), const uniform samplerCUBE envMap : register(s3), const uniform sampler2D dropsMap : register(s5), // constant parameters const uniform float4 time : register(c0), const uniform float3 camPos : register(c8), const uniform float3 lightPos : register(c9), const uniform float4 phong : register(c10), // ka, kd, ks, exp const uniform float3 ambCol : register(c11), const uniform float4 param : register(c12) // ksWater, poreFillingTime ) { // Globals #define M_PI 3.14159265358979323846 float alphaPoro = 0.3; // [0..1[ float sp = 2.0; // [1..10] float m = 0.08; // [0..1] float ks = phong.z; float kd = phong.y; float kr = 1.0; float3 finalCol; // Porosity reflectance computation float3 cameraDirection = normalize( camPos - I.objpos ); float3 lightDirection = normalize( lightPos - I.objpos ); float k = sqrt( 2.0 * m * m / M_PI); float k1 = dot( I.norm, cameraDirection); float k2 = dot( I.norm, lightDirection ); // Check BDRF definition domain if( k1 <= 0.0 || k2 <= 0.0 ) { finalCol.rgb = 0.0; } else { // Shadowing/masking terms float Gp = ( k1 * k2 ) / ( (k1 - k * k1 + k) * ( k2 - k * k2 + k ) ); float ka = 1.0 - ks - kd ; float nb = sp * ( 3.7 - 2.0 * pow( ((acos(k2) + acos(k1))/2.0) - (2.0 * M_PI) / (sp + 6.0), 2.0 ) ); float Ap = ka * ( 1.0 - pow( 1.0 - ka, nb )) / (1.0 - ( 1.0 - ka )); // Porous surface float alphaGp = alphaPoro * Gp; float poroCoef = alphaGp * (1.0 - Ap ); float ksporo = ks * ( 1.0 - alphaGp ); float kdporo = kd * ( 1.0 - alphaGp * Ap ) + ks * alphaGp * (1.0 - Ap); // Diffuse color float3 diffColor = tex2D( colorMap, I.tc0 ).gbr; // Lightmap float3 waterExposure = tex2D( wetMap, I.tc0 ).rgb; #ifdef USE_DROPSMAP waterExposure *= tex2D( dropsMap, I.tc0 ).r; #endif float t0 = waterExposure.r; float t = 1.0 - time.x; // Interpolated diffuse and // specular Phong components #define diff I.coefs.x #define spec I.coefs.y #define ksWater param.x #define poreFillingTime param.y if( t0 > t ) { float poreFillingPercentage = ( t0 - t) / poreFillingTime; poreFillingPercentage = clamp( poreFillingPercentage, 0.0, 1.0 ); finalCol = diff * ( kd * ( 1.0 - alphaGp ) * diffColor + kd * alphaGp * ( 1.0 - Ap ) * diffColor * ( 1.0 - poreFillingPercentage ) + ks * alphaGp * ( 1.0 - Ap ) * diffColor * ( 1.0 - poreFillingPercentage ) ) + spec * ( ks * ( 1.0 - alphaGp ) + texCUBE( envMap, I.R ).rgb * ksWater * alphaGp * poreFillingPercentage ); } else { finalCol = diff * diffColor * kdporo + spec * ksporo ; } } Pix OUT; OUT.col = finalCol + ambCol; return OUT; }