/* Cg functions to decode and filter textures in Radiance (RGBE) high dynamic range format sgg 2/15/02 http://www.graphics.cornell.edu/~bjw/rgbe.html */ #if 0 typedef float4 vec4; typedef float3 vec3; typedef float2 vec2; typedef float real; #define texRECT f4texRECT #define texCUBE f4texCUBE #else typedef half4 vec4; typedef half3 vec3; typedef half2 vec2; typedef half real; #define texRECT h4texRECT #define texCUBE h4texCUBE #endif struct fragin { float4 wpos : WPOS; float3 tex0 : TEXCOORD0; float3 tex1 : TEXCOORD1; float4 col0 : COLOR0; }; // Lookup in RGBE-encoded rectangle texture vec3 texRECT_RGBE(uniform samplerRECT tex, float2 t) { vec4 rgbe = texRECT(tex, t); real e = (rgbe[3] * 255) - 128; return rgbe.xyz * exp2(e); } // Lookup in RGBE-encoded cube map texture vec3 texCUBE_RGBE(uniform samplerCUBE tex, float3 t) { vec4 rgbe = texCUBE(tex, t); real e = (rgbe[3] * 255) - 128; return rgbe.xyz * exp2(e); } // Lookup in RGBE-encoded rectangle texture with filtering vec3 texRECT_RGBE_Bilinear(uniform samplerRECT tex, half2 t) { float2 f = frac(t); vec3 t0 = texRECT_RGBE(tex, t); vec3 t1 = texRECT_RGBE(tex, t + half2(1,0) ); vec3 t2 = lerp(t0, t1, f[0]); t0 = texRECT_RGBE(tex, t + half2(0,1) ); t1 = texRECT_RGBE(tex, t + half2(1,1) ); t0 = lerp(t0, t1, f[0]); t0 = lerp(t2, t0, f[1]); return t0; } // Lookup in cubemap encoded as two HILO cube maps vec3 texCUBE_hilo(uniform samplerCUBE rg_tex : TEXUNIT0, uniform samplerCUBE b_tex : TEXUNIT1, float3 t) { vec3 c; c.xy = texCUBE(rg_tex, t).xy; c.z = texCUBE(b_tex, t).x; // c = c * c; return c; } // Lookup in rectangle texture encoded as two HILO cube maps vec3 texRECT_hilo(uniform samplerRECT rg_tex : TEXUNIT0, uniform samplerRECT b_tex : TEXUNIT1, float2 t) { vec3 c; c.xy = texRECT(rg_tex, t).xy; c.z = texRECT(b_tex, t).x; return c; } // bilinear lookup in float texture vec4 texRECT_bilinear(uniform samplerRECT tex, half2 t) { float2 f = frac(t); vec4 t0 = texRECT(tex, t); vec4 t1 = texRECT(tex, t + half2(1,0) ); vec4 t2 = lerp(t0, t1, f[0]); t0 = texRECT(tex, t + half2(0,1) ); t1 = texRECT(tex, t + half2(1,1) ); t0 = lerp(t0, t1, f[0]); t0 = lerp(t2, t0, f[1]); return t0; } // applying vignetting based on window coordinates void vignette(inout float3 c, float4 wpos, const float2 win_bias, const float2 win_scale) { // convert window coord to [-1, 1] range wpos.xy = (wpos.xy - win_bias) * win_scale; // calculate distance from origin float r = length(wpos.xy); r = 1.0 - smoothstep(0.8, 1.5, r); c = c * r; } // refraction function from Renderman spec // I = incident direction, N = normal, eta = relative index of refraction half3 my_refract(half3 I, half3 N, half eta) { half IdotN = dot(I,N); half k = 1 - eta*eta*(1 - IdotN*IdotN); return eta*I - (eta*IdotN + sqrt(k))*N; } // fresnel approximation half my_fresnel(half3 I, half3 N, half power, half scale, half bias) { return bias + (pow(max(0.0, 1.0 - dot(I, N)), power) * scale); } // transform a direction vector by a 4x4 matrix float3 transform_dir(float4x4 m, float3 v) { float3 o; o.x = dot(v, m._11_12_13); o.y = dot(v, m._21_22_23); o.z = dot(v, m._31_32_33); return o; }