//Godrays(timely) v4.2 for Scanti's OGE(07.04.2010)
//by vtastek
/*TWEAKABLES START*/
//Number of passes for sunshafts
#define NUM_SAMPLES 48
//decrease to gain performance
//but keep in mind effect will start to break
//revealing the squarish nature of the lightshafts
//so increasing would be a better idea
//but at the exchange of performance
//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
extern float globalmul = 6.0f;
extern float morningshaftex = 2.3f; //morning ray intensity
extern float eveningshaftex = 3.5f; //evening ray intensity
extern float goldendecay = 0.99; //ray length for golden hours ie. sunrises and sunsets
extern float noonshaftex = 1.0f; //afternoon ray intensity
extern float noondecay = 0.99; //afternoon ray length
extern float moonshaftex = 0.09f; //night ray intensity experimental
extern float moondecay = 0.88; //night ray length experimental
//for advancing tweaking shows the rays
extern float showraypass = 0;
//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
extern float startsunrise = 4.0f;
extern float endsunrise = 10.0f;
//start early for sunrise
//Evening start-end hours
extern float startevening = 17.0f;
extern float endevening = 21.0f;
//end late for sunset
//ray density
extern float Density=0.99;
//actual ray visibility
extern float Weight=0.1;
//edit for light colorness, lower the value for desaturated colors...
extern float goldensaturate = 0.540f; //ray colors for golden hours
extern float noonsaturate = 0.010f; //ray colors for afternoon
//decreasing may fix blue lights
//Bright Pass values
extern float Luminance = 0.44;
extern float fMiddleGray = 0.99f;
extern float fWhiteCutoff = 0.40f;
//This shader is image based
//this step(pass) determines how much of the sky will produce godrays
//different skies may need different brightpass values
//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;
//float3 eyepos = float3(m44world[3][0],m44world[3][1],m44world[3][2]);
/*matrix mview;
matrix mproj;
static const float raspect = rcpres.x / rcpres.y;
static const float3 sundir = -normalize(sunpos);
static const float forward = dot(sundir,eyevec);
static const float2 texproj = 0.5f * float2( 1 , - rcpres.y / rcpres.x ) / tan(radians(fov * 0.5));
static const float2 invtexproj = 2 * float2( 1 , - rcpres.x / rcpres.y ) * tan(radians(fov * 0.5));
static const float d = dot(eyevec,sunpos);
static const float3 sunview_v = mul(sunpos/d, mview);
static const float2 sunview = (0.5).xx + sunview_v.xy * texproj;*/
float t = tan(radians(fov * 0.5));
static const float3 sp = float3(0,0,0) + (f4SunDir.xyz * 999999);
static const float2 texproj = 0.5*float2(1,-rcpres.y/rcpres.x)/t;
static const float d=dot(f3EyeForward,sp);
static const float3 sunview_v=mul(sp/d,m44view);
static const float2 sunview=float2(0.5,0.5)+sunview_v.xy*texproj;
static const float raspect = rcpres.x / rcpres.y;
//float2 sunview = (0.3,0.3);
//the golden code
static const float forward = dot(sd,eyef);
//photoshop blend modes softlight
#define BlendSoftLightf(base, blend) ((blend < 0.5) ? (2.0 * base * blend + base * base * (1.0 - 2.0 * blend)) : (sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend)))
texture thisframe;
texture lastpass;
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; };
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 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
{
float saat = f4Time[1];
float dakika = f4Time[2];
float gece = 0;
if (saat > endevening - 1 && saat < 24 )
{
gece = 1;
}
if (saat > 0 && saat < startsunrise + 1)
{
gece = 1;
}
float4 black = float4(1.0, 0.0, 0.0, 0.0);
float4 sky = 0;
if(forward<0 && gece<0.6)
{
/*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;
sky = tex2D(s0,IN.UVCoord);
sky = sky * sample.r;*/
float4 depthMask = dot(pow(tex2D(s1, IN.UVCoord),11), float4(1.0f, 0.f, 0.f, 0.f));
depthMask = depthMask * 10000;
depthMask = 1 - 10000/(depthMask+10000);
depthMask = step(0.5, depthMask);
//depthMask = pow(depthMask, 256);
sky = tex2D(s0, IN.UVCoord) * depthMask.x;
}
return(sky);
}
float4 lightshaft(float2 TexCoord : TEXCOORD0 ) : COLOR0
{
clip(-forward);
float Decay = 0.99;
float saat = f4Time[1];
float dakika = f4Time[2];
float Exposure = 0.001;
float saturatex = 0.550;
float gece = 0;
if (saat > endevening - 1 && saat < 24 )
{
gece = 1;
}
if (saat > 0 && saat < startsunrise + 1)
{
gece = 1;
}
if (gece>0.5)
{
clip(forward);
}
if (saat > endevening - 1 && saat < 24 )
{
clip(forward);
Exposure = moonshaftex;
Decay = moondecay;
}
if (saat > 0 && saat < startsunrise + 1)
{
clip(forward);
Exposure = moonshaftex;
Decay = moondecay;
}
if (saat > startsunrise - 1 && saat < endsunrise-1 )
{
Exposure = morningshaftex;
Decay = goldendecay;
saturatex = goldensaturate;
}
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));
saturatex = lerp (goldensaturate, noonsaturate, float(dakika / 59));
}
if ( saat > endsunrise -1 && saat < startevening )
{
Exposure = noonshaftex;
Decay = noondecay;
saturatex = noonsaturate;
}
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));
saturatex = lerp (noonsaturate, goldensaturate, float(dakika/59));
}
if (saat > startevening && saat < endevening )
{
Exposure = eveningshaftex;
Decay = goldendecay;
saturatex = goldensaturate;
}
//this is a vector!!!
float2 DeltaTexCoord= (TexCoord - sunview.xy);
//vertically, we need to adjust it according to Aspect Ratio
float screendist = length(DeltaTexCoord * float2(1,raspect));
DeltaTexCoord /=screendist;
//sun is not a point
float sunr = min(0.3,screendist);
//float2 DeltaTexCoord = (TexCoord - ScreenLightPos.xy);
DeltaTexCoord = DeltaTexCoord * 0.5 * sunr * (1.0 / NUM_SAMPLES) * Density;
float3 Color = tex2D( s2, TexCoord );
float IlluminationDecay = 1.0;
float2 samplepos = TexCoord;
for( int i = 0; i < NUM_SAMPLES; ++i )
{
samplepos -= DeltaTexCoord;
float3 Sample = tex2D( s2, samplepos );
Sample *= IlluminationDecay * Weight;
Color += Sample;
IlluminationDecay *= Decay;
}
Color /= float(NUM_SAMPLES);
Color = Color * Exposure * globalmul;
Color = saturate(Color);
float grey_s = ((Color.r * 0.3) + (Color.g * 0.59)) + (Color.b * 0.11);
Color = lerp(grey_s, Color, saturatex);
return float4( Color , 1.0 );
}
float4 SunCombine( float2 Tex : TEXCOORD0 ) : COLOR0
{
float4 graypass = {0.5, 0.5, 0.5, 1};
float4 orgi = tex2D(s0,Tex);
//float4 shaft = tex2D(s2,Tex/2);
float4 shaft = tex2D(s2,Tex);
if (showraypass<0.88){
//shaft = orgi + shaft;
shaft *= -forward;
shaft = graypass + shaft;
shaft = BlendSoftLightf(orgi,shaft);
}
return float4(shaft.rgb,1);
}
float4 brightpass( in float2 Tex : TEXCOORD0 ) : COLOR0
{
clip(-forward);
float saat = f4Time[1];
float dakika = f4Time[2];
float gece = 0;
if (saat > endevening - 1 && saat < 24 )
{
gece = 1;
}
if (saat > 0 && saat < startsunrise + 1)
{
gece = 1;
}
if (gece>0.5)
{
clip(forward);
}
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 );
}
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_3_0 FrameVS();
Pixelshader = compile ps_3_0 lightshaft(); }
pass p3 {
VertexShader = compile vs_1_1 FrameVS();
Pixelshader = compile ps_2_0 SunCombine(); }
}
/*eof*/