Planet shader
From GameStudio Wiki
Contents |
[edit]
Planet shader with atmosphere
The planet_atmosphere.fx file:
float4x4 matView;
float4x4 matProj;
float4x4 matWorld;
float4x4 matWorldViewProj;
float3 vecSunDir;
float4 vecLightPos[8];
float4 vecLightColor[8];
float4 vecViewPos;
float4 vecSkill1;
float4 vecSkill5;
float4 vecSkill9;
float4 vecFog;
float4 vecDiffuse;
float4 vecAmbient;
float4 vecSpecular;
float fPower;
texture entSkin1;
sampler ColorSampler =sampler_state
{
Texture=<entSkin1>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = wrap;
AddressV = wrap;
};
struct VS_OUTPUT
{
float4 Pos: POSITION;
float2 Tex: TEXCOORD0;
float3 Normal:TEXCOORD1;
float3 Diffuse:COLOR0;
float3 Specular:COLOR1;
float3 View:TEXCOORD2;
float Fog:FOG;
};
VS_OUTPUT VS(float4 inPos:POSITION, float3 inNormal:NORMAL, float2 inTex:TEXCOORD0)
{
VS_OUTPUT Out=(VS_OUTPUT)0;
Out.Pos=mul(inPos,matWorldViewProj);
float4 wpos=mul(inPos,matWorld);
Out.Normal=normalize(mul(inNormal,matWorld));
float3 Viewer = wpos.xyz - vecViewPos.xyz;
float3 LightDir=normalize(wpos.xyz-vecLightPos[0].xyz);
float3 litLights=lit(dot(Out.Normal.xyz,-LightDir),dot(Out.Normal.xyz,normalize(-Viewer.xyz-LightDir)), fPower);
Out.Diffuse=litLights.y;
Out.View=Viewer;
Out.Specular=litLights.z;
Out.Tex=inTex; return Out;
Out.Fog = 1 - (distance(wpos, vecViewPos) - vecFog.x) * vecFog.z;
}
float4 PS(VS_OUTPUT In):COLOR0
{
float4 color=tex2D(ColorSampler,In.Tex);
float3 atmo=pow(1-saturate(dot(In.Normal,normalize(-In.View))),vecSkill5.z)*In.Diffuse;
atmo*=float3(0.1,0.4,1.0)*vecSkill9.z;
color.rgb*=vecAmbient.rgb+In.Diffuse*vecDiffuse.rgb*vecSkill5.w*vecLightColor[0].rgb+atmo+In.Specular*vecSpecular.rgb*In.Diffuse*vecSkill9.x;
color.a=1;
return color;
}
VS_OUTPUT VS_atmo(float4 inPos:POSITION, float3 inNormal:NORMAL, float2 inTex:TEXCOORD0)
{
VS_OUTPUT Out=(VS_OUTPUT)0;
Out.Normal=normalize(mul(inNormal,matWorld));
float4 wpos=mul(inPos,matWorld);
wpos.xyz+=Out.Normal*vecSkill1.x*5;
Out.Pos=mul(mul(wpos,matView),matProj);
float3 LightDir=normalize(wpos.xyz-vecLightPos[0].xyz);
Out.Diffuse=max(0,dot(Out.Normal,normalize(-LightDir)));
float3 Viewer = wpos.xyz - vecViewPos.xyz;
Out.View=Viewer;
float specular=max(0,dot(lerp(Out.Normal,-LightDir,vecSkill5.y),-LightDir));
Out.Specular=specular;
Out.Tex=inTex;
Out.Fog = 1 - (distance(wpos, vecViewPos) - vecFog.x) * vecFog.z;
return Out;
}
float4 PS_atmo(VS_OUTPUT In):COLOR0
{
float4 color;
In.Normal=normalize(In.Normal);
float3 atmo=pow(saturate(dot(In.Normal,normalize(In.View))),vecSkill1.y);
color.rgb=float3(0.5,0.6,1.0)*In.Specular*vecSkill1.z;
color.a=atmo*10*(In.Diffuse+vecSkill5.x)*vecSkill1.w;
return color;
}
technique renderTerrain
{
pass P0
{
VertexShader = compile vs_2_0 VS();
PixelShader = compile ps_2_0 PS();
ZEnable = true;
ZWriteEnable=true;
AlphaBlendEnable = false;
CullMode=CCW;
}
pass P2
{
VertexShader = compile vs_2_0 VS_atmo();
PixelShader = compile ps_2_0 PS_atmo();
ZEnable = true;
ZWriteEnable=false;
AlphaBlendEnable = true;
CullMode=CW;
}
}
[edit]
C-Script example:
//predefined effect parameters
var planet_atmoSize=25;
var planet_atmoFalloff=5;
var planet_atmoBrightness=1;
var planet_atmoDensity=1;
var planet_atmoThreshold=0.5;
var planet_atmoDiffuse=0.5;
var planet_planetFalloff=1;
var planet_planetDiffuse=0.5;
var planet_planetSpecular=1;
var planet_planetPower=20;
var planet_planetAtmo=2;
material mat_planet
{
effect="planet_atmosphere.fx";
flags=TRANSLUCENT;
ambient_red=0;
ambient_green=0;
ambient_blue=0;
diffuse_red=255;
diffuse_green=255;
diffuse_blue=255;
specular_red=255;
specular_green=255;
specular_blue=255;
}
action planet
{
my.material=mat_planet;
mat_planet.skill1=float(planet_atmoSize);
mat_planet.skill2=float(planet_atmoFalloff);
mat_planet.skill3=float(planet_atmoBrightness);
mat_planet.skill4=float(planet_atmoDensity);
mat_planet.skill5=float(planet_atmoThreshold);
mat_planet.skill6=float(planet_atmoDiffuse);
mat_planet.skill7=float(planet_planetFalloff);
mat_planet.skill8=float(planet_planetDiffuse);
mat_planet.skill9=float(planet_planetSpecular);
mat_planet.power=planet_planetPower;
mat_planet.skill11=float(planet_planetAtmo);
while(1)
{
my.pan+=2*time;
my.tilt+=0.5*time;
wait(1);
}
}
[edit]
Adjustable through:
| material parameter | meaning |
|---|---|
| mtl.skill1 | size of the atmosphere |
| mtl.skill2 | density falloff of the atmosphere |
| mtl.skill3 | brightness of the atmosphere |
| mtl.skill4 | density of the atmosphere |
| mtl.skill5 | density threshold of the atmosphere |
| mtl.skill6 | lighting factor for the atmosphere |
| mtl.skill7 | lighting falloff for the planet |
| mtl.skill8 | diffuse lighting factor for the planet |
| mtl.skill9 | specular lighting factor for the planet |
| mtl.skill11 | atmosphere lighting factor for the planet |
| mtl.ambient_xxx | ambient lighting color |
| mtl.diffuse_xxx | diffuse lighting color |
| mtl.specular_xxx | specular lighting color |
| mtl.power | power factor for specular lighting |
[edit]
Remarks
The shader uses the nearest dynamic light for shading. Make sure you created one in your level. Also you must set all material skills mentioned above, otherwise you may only see a black sphere.
| Uses ShaderModel: | 2 |
| Has fallback techniques: | no |
| Uses fog: | yes |
--ChrisB 00:44, 23 June 2008 (CEST)
