Planet shader

From GameStudio Wiki

Jump to: navigation, search

Contents

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;
	}
}


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);
	}
}


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


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)

Personal tools