float GetPuddles(vec3 pos){
	pos=(pos+cameraPosition)*.005;
	
	float noise=texture2D(noisetex,pos.xz).r;
	noise+=texture2D(noisetex,pos.xz*.5).r*2.;
	noise+=texture2D(noisetex,pos.xz*.25).r*4.;
	noise+=texture2D(noisetex,pos.xz*.125).r*8.;
	noise+=texture2D(noisetex,pos.xz*.0625).r*16.;
	noise=max(abs(noise-15.5)*.8-1.2,0.)*wetness;
	noise/=sqrt(noise*noise+1.);
	
	return clamp(noise,0.,.95);
}

//Bicubic sampling from http://www.java-gaming.org/index.php?topic=35123.0
vec4 cubic(float v){
	vec4 n=vec4(1.,2.,3.,4.)-v;
	vec4 s=n*n*n;
	float x=s.x;
	float y=s.y-4.*s.x;
	float z=s.z-4.*s.y+6.*s.x;
	float w=6.-x-y-z;
	return vec4(x,y,z,w)*(1./6.);
}

vec4 textureBicubic(sampler2D sampler,vec2 coord){
	float texSize=1024.;
	
	coord=coord*texSize-.5;
	
	vec2 fxy=fract(coord);
	coord-=fxy;
	
	vec4 xcubic=cubic(fxy.x);
	vec4 ycubic=cubic(fxy.y);
	
	vec4 c=coord.xxyy+vec2(-.5,1.5).xyxy;
	
	vec4 s=vec4(xcubic.xz+xcubic.yw,ycubic.xz+ycubic.yw);
	vec4 offset=c+vec4(xcubic.yw,ycubic.yw)/s;
	
	offset/=texSize;
	
	vec4 sample0=texture2D(sampler,offset.xz);
	vec4 sample1=texture2D(sampler,offset.yz);
	vec4 sample2=texture2D(sampler,offset.xw);
	vec4 sample3=texture2D(sampler,offset.yw);
	
	float sx=s.x/(s.x+s.y);
	float sy=s.z/(s.z+s.w);
	
	return mix(mix(sample3,sample2,sx),mix(sample1,sample0,sx),sy);
}

float puddleH(vec3 pos,vec3 fpos){
	float noise=0;
	pos=pos+cameraPosition;
	
	float mult=sqrt(-dot(normalize(normal),normalize(fpos)))/
	sqrt(sqrt(max(length(pos),4.)));
	
	if(mult>.01){
		noise=textureBicubic(noisetex,pos.xz/32.).r;
	}
	
	noise=sin((noise+frametime)*16.)*.15+.5;
	noise*=mult;
	
	return noise;
}

vec3 GetPuddleNormal(vec3 pos,vec3 fpos,mat3 tbn){
	float deltaPos=.05;
	float h0=puddleH(pos,fpos.xyz);
	float h1=puddleH(pos+vec3(deltaPos,0.,0.),fpos.xyz);
	float h2=puddleH(pos+vec3(-deltaPos,0.,0.),fpos.xyz);
	float h3=puddleH(pos+vec3(0.,0.,deltaPos),fpos.xyz);
	float h4=puddleH(pos+vec3(0.,0.,-deltaPos),fpos.xyz);
	
	float xDelta=((h1-h0)+(h0-h2))/deltaPos;
	float yDelta=((h3-h0)+(h0-h4))/deltaPos;
	
	vec3 pnormalMap=vec3(xDelta,yDelta,1.-(xDelta*xDelta+yDelta*yDelta));
	float bumpmult=.03;
	pnormalMap=pnormalMap*vec3(bumpmult,bumpmult,bumpmult)+vec3(0.,0.,1.-bumpmult);
	
	return clamp(normalize(pnormalMap*tbn),vec3(-1.),vec3(1.));
}