Quote: "Congratulations. Sounds like high-level stuff."
Thanks.
My PhD was mostly experimental physics, but the grounding in maths and science and stuff does help out when i'm coding.
Quote: "Dr Tank your shader looks AMAZING in my opinion great work!"
Thanks very much.
With the directional shadow shader I overlooked an obvious optimisation in the shadow map vertex shader. Basically I calculate the exact same thing twice. No big deal because it's only the vertex shader, but i'll update it when I get around to it.
Quote: "I just wrote my first shader today and it works. Yeah! "
Well done dude! I was in that boat a few weeks ago, and assure you that fun times are ahead. Shaders are totally sweet.
Been toying with volumetric fog particles. Basically got it working, but it's kind of slow and looks a bit balls, and have been a bit confused about in what order DBP renders transparent things and that. So i've binned that.
Today i did this atmosphere/fog skybox thingy.
A cool thing about this is that the ground is on the shader too. Lots of ideas and stuff to play around with this. It may be highly inefficient/rubbish/physically incorrect. For example, would be better to have separate shaders for up and down halves of skybox. A work in progress but I attach it as is so you can have a play around.
I'm chuffed with this because back in the day when i was trying to make a flight sim in DBP, making a skybox work with fogging was a big problem. Maybe i'd like to throw together a little flight sim thingy.
After improving this, i'll look to writing a shader that does the same thing (but without the infinite ground tiling), but for regular objects in the world. Also i'll try out advanced terrain and see if i can get it to work seamlessly with this infinite tiled ground skybox.
Quick reference:
DBP code:
Rem Project: atmosphere and groundbox shader
Rem Created: 29/04/2010 22:14:41
Rem ***** Main Source File *****
`want to make an atmospheric fogging shader.
`because atmosphere tapers off exponentially with altitude, can stick this in too!
`equations come out quite nicely
`will have cool gradual darkening of sky as increase altitude, glow around horizon etc.
`also, hopefully can have infinite tiling of ground plane projected onto skybox lower half.
`may run into problems with /0 error. see how it goes!
`next up? put same shader for other objects, terrain etc.
`allow scaling of sunlight, so sky not blue at night etc
`think about angular distribution of scattering
`add skybox, or sun object.
`terrain.
`can i get skybox drawn before all other objects?
`use of multiple texture levels to reduce tiled effect
set display mode 1280,720,32,1
sync on
sync rate 0
set camera fov 70
autocam off
make object cube 1,100
scale object 1,100,-100,100
`load image "Marble_107_seamless_sample.jpg",1
load image "baked04.JPG",1
texture object 1,1
`load effect "FX/myfx.fx",1,0 `OMFG! it totally works!
`load effect "FX/myfx1.fx",1,0 `with black above horizon. totally works too!
`load effect "FX/myfx2.fx",1,0 `with cam height sent to it
`load effect "FX/myfx3.fx",1,0 `was doing it totally wrong! exp(exp) is not exp(x)exp(y), it's (exp(x))^y (duh)
`load effect "FX/myfx4.fx",1,0 `works!
`load effect "FX/myfx5.fx",1,0 `add colour
`load effect "FX/myfx6.fx",1,0 `use vector for cam pos and pass to shader
load effect "FX/myfx7.fx",1,0 `try to swap co-ords around to get behaviour right
set object effect 1,1
position camera 0,1,0
point camera 0,1,1
set camera range 0.1,1000
camheight#=1.0
`dim campos(3) as float
campos_vec=1
null=make vector4(campos_vec)
`test obj
`make object sphere 2,20
make object box 2,5,0.2,5
position object 2,0,0.1,0 `so bottom is at 0
disable object zdepth 2
timenow as dword
timelast as dword
timediff as dword
timenow=timer()
`Start loop
do
timelast=timenow
timenow=timer()
timediff=timenow-timelast
text 0,0,str$(screen fps())
mx#=wrapvalue(mx#+0.1*mousemovey())
my#=wrapvalue(my#+0.1*mousemovex())
rotate camera mx#,my#,0.0
mc=mouseclick()
move camera (((mc&&1)<<1)-(mc&&2))*0.01*timediff
camheight#=camera position y()
camheight#=camheight#*(1.0+(upkey()-downkey())*0.01)
if camheight#<1.0 then camheight#=1.0
position camera camera position x(),camheight#,camera position z()
position object 1,camera position x(),camheight#,camera position z()
set vector4 campos_vec,camera position x(),camera position y(),camera position z(),0.0
`pass in this info to shader.
`require - cam h , transmittance straight up, transmittance straight down to ground. pos for different colours.
`shader can work out the rest
`set effect constant float 1,"Camheight",camheight# `send camera height to shader.
set effect constant vector 1,"CamPos",campos_vec
`fogging goes as exp(-h) where h is height. take ground as 0
decayconst#=80.0 `length over which atmos decays with altitude
temp#=(2.71^-(camheight#/decayconst#))
up_part#=2.71^-temp# `transmittance to space (straight up)
`down_part#=2.71^(temp#-1.0)
down_part#=0.36788/up_part# `1/e `transmittance to ground. (straight down)
`NB that should scale this somehow to taste.
`is finite amount of atmosphere. currently, transmittance to ground goes to 1/e at infinity. in reality
`will want probably less than this, but values not too wacky!
up_part#=up_part#^0.6 `universal scaling factor.
down_part#=down_part#^0.6 `larger means thicker atmos
`ink 0,0
`text 1,11,str$(camheight#)
`text 1,21,str$(up_part#)
`text 1,31,str$(down_part#)
ink rgb(100,255,100),0
text 0,10,"ALTITUDE="+str$(camheight#)
text 0,20,"(BLUE) TRANSMITTANCE SPACE TO CAM ="+str$(up_part#)
text 0,30,"(BLUE) TRANSMITTANCE GROUND TO CAM="+str$(down_part#)
set effect constant float 1,"up_part",up_part#
set effect constant float 1,"down_part",down_part#
sync
loop
Shader code:
matrix wvp : WorldViewProjection;
matrix world : World;
float4 CamPos=0.0; //only want 3vec, but DBP doesn't like passing those to shaders. may as well use 4
float up_part=0.0;
float down_part=0.0;
struct VSInput {
float4 Pos : Position;
float2 UV : TEXCOORD0;
};
struct VSOutput {
float4 Pos : Position;
float2 UV : TEXCOORD0;
float4 wPos : TEXCOORD1;
};
// The pixel shader does not need an input structure for this example.
struct PSOutput { float4 Col : Color; };
// The vertex shader code:
VSOutput VShader (VSInput In, VSOutput Out)
{ // Transforms the objects model coordinates to
// screen space coordinates
Out.Pos = mul(In.Pos, wvp);
// Out.wPos = mul(In.Pos, world);
Out.wPos = In.Pos; //it's that simple
Out.UV = In.UV; //not using currently
return Out;
};
texture BaseTX
<
string Name="";
>;
sampler2D Base = sampler_state
{
texture = <BaseTX>;
};
// The pixel shader code:
PSOutput PShader (VSOutput In,PSOutput Out)
{ // Just outputs the chosen colour without additional processing.
//Out.Col = lightColour;
//Out.Col = tex2D(Base,In.UV);
//Out.Col = tex2Dproj(Base,In.wPos); //cool effect but not what we want
float2 newuv=In.wPos.zx; //this stuff can go in vert shader, with scaling by campos y. also campos xz 2vec?
newuv=-CamPos.y*newuv/In.wPos.y;
newuv[0]=newuv[0]-CamPos.z;
newuv[1]=newuv[1]-CamPos.x;
//Out.Col = In.wPos.y > 0? 0:tex2D(Base,newuv);
float invsintheta=pow(dot(In.wPos.xyz,In.wPos.xyz),0.5) / abs(In.wPos.y); //hyp/opp =sumsq / y
//should put as texture. can also use dither on texture.
float spacetrans=pow(up_part,invsintheta);
float groundtrans=pow(down_part,invsintheta);
float spacetransrg=pow(spacetrans,0.5);
float groundtransrg=pow(groundtrans,0.5);
//scale things arbitrarily.. - actually do it in DBP.
//groundtrans=pow(groundtrans,2.0);
//spacetrans=pow(spacetrans,2.0);
//float4 spacetransrgb = float4(spacetrans,spacetransrg,spacetransrg,1.0f); //mars!
//float4 groundtransrgb = float4(groundtrans,groundtransrg,groundtransrg,1.0f);
float4 spacetransrgb = float4(spacetransrg,spacetransrg,spacetrans,1.0f);
float4 groundtransrgb = float4(groundtransrg,groundtransrg,groundtrans,1.0f);
//float4 spacecol=(1.0-spacetrans); //scalar version (greyscale sky)
//float4 groundcol=(1.0-groundtrans)+groundtrans*tex2D(Base,newuv);
float4 spacecol=(1.0-spacetransrgb);
float4 groundcol=(1.0-groundtransrgb)+groundtransrgb*tex2D(Base,newuv);
Out.Col = In.wPos.y < 0? spacecol:groundcol;
return Out;
};
// The following lines just put this together as a single technique
// with a single pass.
technique simplyOneColour
{ pass p1
{ VertexShader = compile vs_2_0 VShader();
PixelShader = compile ps_2_0 PShader();
}
}