Complex glass

From GameStudio Wiki

Jump to: navigation, search
//--------------------------------------------------------------//
// ComplexGlass
//--------------------------------------------------------------//

float4x4 matWorldViewProj;
float4x4 matWorldView;
float4x4 matWorld;
float4 vecViewPos;
float4 vecFog;
texture mtlSkin1;
texture mtlSkin2;

float refractionScale = 1.0;
float rainbowScale = 0.20;
float rainbowSpread = 0.18;
float4 baseColor = ( 0.72, 0.70, 0.76, 1.00 );
float ambient = 0.05;
float indexOfRefractionRatio = 1.14;
float reflectionScale = 1.0;

sampler Environment = sampler_state
{
   Texture = (mtlSkin1);
   ADDRESSU = CLAMP;
   ADDRESSV = CLAMP;
   MAGFILTER = LINEAR;
   MINFILTER = LINEAR;
   MIPFILTER = LINEAR;
};

sampler Rainbow = sampler_state
{
   Texture = (mtlSkin2);
   ADDRESSU = CLAMP;
   ADDRESSV = CLAMP;
   MAGFILTER = LINEAR;
   MINFILTER = LINEAR;
   MIPFILTER = LINEAR;
};

struct ComplexGlass_VS_OUTPUT {
   float4 Pos:     POSITION;
   float3 normal:  TEXCOORD0;
   float3 viewVec: TEXCOORD1;
    float Fog : FOG;
};

ComplexGlass_VS_OUTPUT ComplexGlass_Object_VS_main(float4 vPos: POSITION, float3 normal: NORMAL){
   ComplexGlass_VS_OUTPUT Out;

   Out.Pos = mul(vPos,matWorldViewProj);
   Out.normal = mul(normal,matWorld);
   Out.viewVec = vecViewPos - mul(vPos,matWorld);
   float3 PosWorld = mul(vPos, matWorld);
   Out.Fog = 1- (distance(PosWorld, vecViewPos) - vecFog.x) * (vecFog.z);

   return Out;
}

float4 ComplexGlass_Object_PS_main(float3 normal: TEXCOORD0, float3 viewVec: TEXCOORD1) : COLOR {
   normal = normalize(normal);
   viewVec = normalize(viewVec);

   // Look up the reflection
   half3 reflVec = reflect(-viewVec, normal);
   half4 reflection = texCUBE(Environment, reflVec.xyz);

   // We'll use Snell's refraction law:
   // n  * sin(theta ) = n  * sin(theta )
   //  i            i     r            r

   // sin(theta )
   //          i
   half cosine = dot(viewVec, normal);
   half sine = sqrt(1 - cosine * cosine);

   // sin(theta )
   //          r
   half sine2 = saturate(indexOfRefractionRatio * sine);
   half cosine2 = sqrt(1 - sine2 * sine2);

   // Out of the sine and cosine of the angle between the
   // refraction vector and the normal we can construct the
   // refraction vector itself given two base vectors.
   // These two base vectors are the negative normal and
   // a tangent vector along the path of the incoming vector
   // relative to the surface.
   half3 x = -normal;
   half3 y = normalize(cross(cross(viewVec, normal), normal));

   // Refraction
   half3 refrVec = x * cosine2 + y * sine2;
   half4 refraction = texCUBE(Environment, refrVec.xyz);

   // Colors refract differently and the difference is more
   // visible the stronger the refraction. We'll fake this
   // effect by adding some rainbowish colors accordingly.
   half4 rainbow = tex1D(Rainbow, pow(cosine, rainbowSpread));

   half4 rain = rainbowScale * rainbow * baseColor;
   half4 refl = reflectionScale * reflection;
   half4 refr = refractionScale * refraction * baseColor;

   // There is more light reflected at sharp angles and less
   // light refracted. There is more color separation of refracted
   // light at sharper angles
   half4 color = sine * refl + (1 - sine2) * refr + sine2 * rain + ambient;
   return color;
}
technique ComplexGlass{
	pass Object {
		AlphaBlendEnable=True;
		Zenable = True;
		AlphaTestEnable=True;
		ZwriteEnable = False;
//		ZwriteEnable = True;
		CULLMODE = CCW;
		BlendOp=5;
		VertexShader = compile vs_1_1 ComplexGlass_Object_VS_main();
		PixelShader = compile ps_2_0 ComplexGlass_Object_PS_main();
   }
}
Personal tools