//Godrays(timely) v3.4 for Scanti's OGE(20.02.2010)
//by vtastek
/*TWEAKABLES START*/
//Number of passes for sunshafts
#define NUM_SAMPLES 64
//decrease to gain performance
//but keep in mind effect will start to break
//revealing the squarish nature of the lightshafts
//FOV
#define fov 75
//setting this correctly is very important
//or lights will move around as you look around
//creating a searchlight effect
//Exposure(intensity) values for sunshafts
float morningshaftex = 0.04f;
float eveningshaftex = 0.20f;
float goldendecay = 0.99;
float noonshaftex = 0.49f;
float noondecay = 0.63;
float moonshaftex = 0.09f;
float moondecay = 0.88;
//Mornings are more powerful already
//so I decreased it
//noon is for noon and moon is for nights
//you may get shafts for lightnings and moon maybe
//goldendecay is for sunrise and sunset rays lengths
//noondecay is noon rays length
//Morning start-end hours
float startsunrise = 4.0f;
float endsunrise = 10.0f;
//start early for sunrise
//Evening start-end hours
float startevening = 17.0f;
float endevening = 21.0f;
//end late for sunset
//edit for remaining sunshaft properties
float Density=0.9;
float Weight=0.44;
//edit for light colorness, lower the value for desaturated colors...
static const float saturate = 0.540f;
//decreasing may fix blue lights
//Bright Pass values
static const float Luminance = 0.44;
static const float fMiddleGray = 0.99f;
static const float fWhiteCutoff = 0.99f;
//This shader is image based
//this step(pass) determines how much of the sky will produce godrays
//different skies may need different brightpass values
/*TWEAKABLES END*/
//shader codes begin here
matrix m44view;
float3 f3EyeForward;
float4 f4SunDir;
float2 rcpres;
static const float3 eyef = f3EyeForward;
float4 f4Time;
static const float3 sd = -f4SunDir.xyz;
float t = tan(radians(fov * 0.5));
/*
static const float3 t1 = normalize(cross(eyef ,float3(0,0,1)));
static const float3 t2 = normalize(cross(eyef ,t1));
static const float2 proj = float2(dot(sd,t1),dot(sd,t2));
static const float d = sqrt(1-(proj.x*proj.x)-(proj.y*proj.y));
static const float2 sunview = float2(0.5,0.5) - 0.5f * float2( proj.x/d , proj.y/d * rcpres.y / rcpres.x )/t;
*/
static const float2 texproj = 0.5*float2(1,-rcpres.y/rcpres.x)/t;
static const float d=dot(f3EyeForward,sd);
static const float3 sunview_v=mul(sd/d,m44view);
static const float2 sunview=float2(0.5,0.5)+sunview_v.xy*texproj;
//float2 sunview = (0.3,0.3);
texture thisframe;
texture lastpass;
texture lastframe;
texture Depth;
sampler s0 = sampler_state { texture=<thisframe>; minfilter = linear; magfilter = linear; mipfilter = linear; addressu=clamp; addressv = clamp;};
sampler s1 = sampler_state
{
texture = <Depth>;
AddressU = CLAMP;
AddressV = CLAMP;
MINFILTER = linear;
MAGFILTER = linear;
};
sampler s2 = sampler_state { texture=<lastpass>; minfilter = linear; magfilter = linear; mipfilter = linear; addressu=clamp; addressv = clamp; };
sampler s3 = sampler_state { texture=<lastframe>; minfilter = linear; magfilter = linear; mipfilter = linear; addressu=clamp; addressv = clamp; };
struct VSOUT
{
float4 vertPos : POSITION;
float2 UVCoord : TEXCOORD0;
};
struct VSIN
{
float4 vertPos : POSITION0;
float2 UVCoord : TEXCOORD0;
};
VSOUT FrameVS(VSIN IN)
{
VSOUT OUT = (VSOUT)0.0f; // initialize to zero, avoid complaints.
OUT.vertPos = IN.vertPos;
OUT.UVCoord = IN.UVCoord;
return OUT;
}
/*float4 depthskymask( float2 Tex : TEXCOORD0 ) : COLOR0
{
float4 ce = smoothstep(-100,100, tex2D(s1, Tex).r);
return ce;
//ce.a = 0.0f;
//float4 sky = tex2D(s0,Tex);
//sky = sky * ce.r;
//return sky;
}*/
float4 SunPosDebug(float2 TexCoord : TEXCOORD0) : COLOR0
{
float4 black = float4(0.0, 0.0, 0.0, 1.0);
float4 sample=tex2D(s0,TexCoord);
float2 diff=TexCoord-sunview;
diff.x=diff.x*diff.x;
diff.y=diff.y*diff.y;
float dist=diff.x+diff.y;
if (dist>0.1)
dist=0;
else
dist=0.5;
return(lerp(sample,black,dist));
}
float4 depthskymask(VSOUT IN) : COLOR0
{
float4 black = float4(1.0, 0.0, 0.0, 0.0);
float4 purple = float4(1.0, 0.0, 1.0, 0.0);
float4 sample=tex2D(s1,IN.UVCoord);
//sample=1-sample;
sample=sample*sample;
sample=sample*sample;
sample=sample*sample;
sample=sample*sample;
sample=sample*sample;
//sample=1-sample;
sample=dot(sample,black);
sample = smoothstep(0.999,1, sample);
sample.a = 0.0f;
float4 sky = tex2D(s0,IN.UVCoord);
sky = sky * sample.r;
return(sky);
}
float4 lightshaft(float2 TexCoord : TEXCOORD0 ) : COLOR0
{
float Decay = 0.99;
float saat = f4Time[1];
float dakika = f4Time[2];
float Exposure = 0.001;
if (saat > endevening - 1 && saat < 24 )
{
Exposure = moonshaftex;
Decay = moondecay;
}
if (saat > 0 && saat < startsunrise + 1)
{
Exposure = moonshaftex;
Decay = moondecay;
}
if (saat > startsunrise - 1 && saat < endsunrise-1 )
{
Exposure = morningshaftex;
Decay = goldendecay;
}
if ( saat > (endsunrise - 2) && saat < endsunrise + 1 )
{
//float trans1 = clamp(dakika, 0,1);
Exposure = lerp (morningshaftex, noonshaftex, float(dakika / 59));
Decay = lerp (goldendecay, noondecay, float(dakika / 59));
}
if ( saat > endsunrise -1 && saat < startevening )
{
Exposure = noonshaftex;
Decay = noondecay;
}
if (saat > startevening - 1 && saat < (startevening + 1))
{
//float trans2 = clamp(dakika, 0,1);
Exposure = lerp (noonshaftex, eveningshaftex, float(dakika/59));
Decay = lerp (noondecay, goldendecay, float(dakika/59));
}
if (saat > startevening && saat < endevening )
{
Exposure = eveningshaftex;
Decay = goldendecay;
}
float2 DeltaTexCoord= (TexCoord - sunview.xy);
//float2 DeltaTexCoord = (TexCoord - ScreenLightPos.xy);
DeltaTexCoord *= 1.0 / NUM_SAMPLES * Density;
float3 Color = tex2D( s2, TexCoord );
float IlluminationDecay = 1.0;
for( int i = 0; i < NUM_SAMPLES; ++i )
{
TexCoord -= DeltaTexCoord;
float3 Sample = tex2D( s2, TexCoord );
Sample *= IlluminationDecay * Weight;
Color += Sample;
IlluminationDecay *= Decay;
}
/*if (saat > 20 && saat < 24 )
{
Exposure = 0;
}
if (saat > 0 && saat < 6 )
{
Exposure = 0;
}
if (saat > 6 && saat < 11 )
{
Exposure = 0.11;
}
if ( saat>11 && saat<16)
{
Exposure = 0.001;
}
if (saat > 16 && saat < 20 )
{
Exposure = 0.11;
}*/
/*if (saat == 7)
{
Exposure = morningshaft * dakika / 60;
}
if (saat == 10)
{
Exposure = morningshaft * 1 / (dakika+0.1);
}
if (saat == 11)
{
Exposure = 0;
}
if (saat == 16)
{
Exposure = eveningshaft * dakika / 60;
}
if (saat == 19)
{
Exposure = eveningshaft * 1 / (dakika+0.1);
}
if (saat == 20)
{
Exposure = 0;
}*/
Color = Color * Exposure;
return float4( Color , 1.0 );
}
float gScaleFactor = 1.5;
float gWeights3x3[3][3] = {
{ 0.0625, 0.1250, 0.0625 },
{ 0.1250, 0.2500, 0.1250 },
{ 0.0625, 0.1250, 0.0625 }
};
// -----------------------------------------------------------------
float4 sunblur(
float2 UV: TEXCOORD0,
uniform float ScaleFactor,
uniform float Weights[ 3 ][ 3 ]) : COLOR0
{
float gScreenWidth=(1.0f/rcpres[1]);;
float gScreenHeight=(1.0f/rcpres[0]);;
float OffX = ( gScreenWidth ) * ScaleFactor;
float OffY = ( gScreenHeight ) * ScaleFactor;
float4 Color = ( float4 )0;
float2 Pos;
for( int y = 0; y < 3; ++y )
{
for( int x = 0; x < 3; ++x )
{
Pos.x = UV.x + ( x - 1 ) * OffX;
Pos.y = UV.y + ( y - 1 ) * OffY;
Color += tex2D( s2, Pos ) * Weights[ x ][ y ];
}
}
return float4( Color.rgb, 1.0 );
}
float4 SunCombine( float2 Tex : TEXCOORD0 ) : COLOR0
{
float4 orgi = tex2D(s0,Tex);
//float4 shaft = tex2D(s2,Tex/2);
float4 shaft = tex2D(s2,Tex);
orgi = shaft + orgi;
return orgi;
}
/*float4 scale2( float2 Tex : TEXCOORD0 ) : COLOR0
{
return tex2D( s2, Tex*2);
}*/
float4 brightpass( in float2 Tex : TEXCOORD0 ) : COLOR0
{
float3 ColorOut = tex2D( s2, Tex );
ColorOut *= fMiddleGray / ( Luminance + 0.001f );
ColorOut *= ( 1.0f + ( ColorOut / ( fWhiteCutoff * fWhiteCutoff ) ) );
ColorOut -= 5.0f;
ColorOut = max( ColorOut, 0.0f );
ColorOut /= ( 10.0f + ColorOut );
return float4( ColorOut, 1.0f );
}
float4 desaturatees( in float2 Tex : TEXCOORD0 ) : COLOR0
{
float4 color = tex2D(s2,Tex);
float grey_s = ((color.r * 0.3) + (color.g * 0.59)) + (color.b * 0.11);
return(lerp(grey_s, color, saturate));
}
technique t0
{
/*
pass debug {
//VertexShader = compile vs_1_1 FrameVS();
PixelShader = compile ps_2_0 SunPosDebug();
}
*/
pass p0 {
VertexShader = compile vs_1_1 FrameVS();
PixelShader = compile ps_2_0 depthskymask();
}
pass p1 {
//VertexShader = compile vs_1_1 FrameVS();
PixelShader = compile ps_2_0 brightpass();
}
pass p2 {
//VertexShader = compile vs_1_1 FrameVS();
Pixelshader = compile ps_2_0 desaturatees(); }
pass p3 {
VertexShader = compile vs_1_1 FrameVS();
Pixelshader = compile ps_3_0 lightshaft(); }
/*
pass p4 {
//VertexShader = compile vs_1_1 FrameVS();
Pixelshader = compile ps_2_0 sunblur(gScaleFactor, gWeights3x3 );}
*/
pass p5 {
//VertexShader = compile vs_1_1 FrameVS();
Pixelshader = compile ps_2_0 SunCombine(); }
}
/*eof*/