surface
aff (color ambientcolor = 0.1,
     color specularcolor = 0,
     float roughness = .1,
     float transmitted = 0.,
     float index = 1.0,
     string texturename = "",
	 float s = u, float t = v)
{
	if (raytype("shadow"))
	{
		C = 1.0;
		opacity = 1-transmitted;
	}
	else
	{
		normal Nn = faceforward (normalize(N),I);
		normal In = normalize( I );
		color reflected = 0, refracted = 0;

		if ((specularcolor[0] > .001) || (specularcolor[1] > .001) || (specularcolor[2] > .001)) 
		{
			reflected = specularcolor * trace (P, reflect (I, Nn));
		}
		if ( transmitted > .001 ) 
		{
			vector T = refract (In, Nn, dot (N, I) > 0 ? index : 1/index ); 
			if (length (T) != 0.0)
				refracted = transmitted * trace (P, T);
		}
	
		color Ct;
		if ( texturename != "" )
			Ct = texture (texturename, s, t, "wrap", "periodic");
		else
			Ct = 1.0;

		C = opacity * (Ct * (ambientcolor * ambient() +  C * diffuse(Nn) + reflected + refracted)
			+ specularcolor * phong (Nn, -In, roughness));
	}	
}