Fur Shader New
From GameStudio Wiki
FIXME!!
Fur Shader for Directx9 (vs 1.1 ,ps 1.4) - tested on terrains
As discussed in this thread, URL, the old fur shader on this Wiki doesn't work with DirectX9, with great help from ello and others, here's a new fur shader. It extrudes the model vertices 5 times along the normal and renders the pixels using an alpha-mapped texture. Requires two textures that get multiplied together and one red channel texture that specifies the alpha value.
In my case I wanted to use a fur shader for a terrain, so I will explain it using a terrain. To make sure everyone will be able to implement it, i've written it in a more tutorial way, I hope it's not chaotic, anyways just follow the steps below;
1)Add this to your project's MAIN function
include <terrainshdrFUR.wdl>; // in this wdl, which we are going to make next, are all the functions for the shader load_fur_fx(); // put this in your game's MAIN function, it'll call a function in the wdl mentioned earlier, and loads the shader
Ok, I like to keep things organised so I've put those shaderrelated code in a new wdl; Put this in a new wdl file, and save as for example terrainshdrFUR.wdl ;) terrainshdrFUR.wdl Code:
// terrainshdrFUR.wdl
// the next three textures are a bit mixed-up name-wise, maybe I'll change this later
bmap bmp_fur=<fur.tga>; //the furmap, choose a name you like
bmap bmp_base=<tropical_tex.tga>; // your terrain's basic skin
bmap bmp_color=<fur2.tga>; //
// Next are the functions for the basic setup, define the materials
function mtl_fur_init
{
// first_shell_brightness, you may want to experiment with these value a lot
mtl.skill1=float(0.00006);
mtl.skill2=float(0.000005); // brightness_increment
bmap_to_mipmap(mtl.skin1);
}
//Define the skins's material this way;
material mtl_fur
{
event=mtl_fur_init;
skin1=bmp_fur; // skin1 is the fur texture
skin2=bmp_base; //skin2 is the noise texture
skin3=bmp_color;//skin3 is the actual skin of in my case the terrain
effect = <terrainshdrFUR.fx>; //this points to another file, but I'll come to that later
}
//this is the actual function that starts loading the shader,
// don't forget to call it in your MAIN function
function load_fur_fx()
{
//checks if your system is at least capable of handling
//vertex shader (vs) 1.1 and pixel shader (ps) 1.1 or higher versions
if (d3d_shaderversion >= 1111)
{
effect_load(mtl_fur,"terrainshdrFUR.fx");
return;
} else {
exit;
}
}
//attach this action to your model or terrain for the fur effect
action fur
{
my.skill41=float(0.6); // shell_distance
my.skill43=float(10); // fur_u_scale
my.skill44=float(10); // fur_v_scale
my.material=mtl_fur;
}
Next thing to do is put the next lines of code in a new file and save it as 'terrainshdrFUR.fx'
TerrainshdrFUR.fx Code:
float4x4 matWorldViewProj;
// This is the Vertex shader, most info comes from GameStudio and DirectX
// except for the (shell) offset value which is specified in the various
// passes later on
// All it does is move the vertex position along the triangle normal
void mainVS(in float4 position:POSITION,
in float4 normal:NORMAL,
in float2 texCoord:TEXCOORD0,
out float4 pos:POSITION,
out float4 nrm:COLOR0,
out float2 oT0:TEXCOORD0,
uniform float offset )
{
//scale vertexposition in normals direction
position.xyz+=normal.xyz*offset/100;
// from world pos to screen pos
pos=mul(position,matWorldViewProj);
nrm=normal;
oT0=texCoord*1; //this is the amount of tiling of the fur texture
}
//Define the material skins which we use;
texture mtlSkin1;
sampler basemap = sampler_state
{
texture=(mtlSkin1);
};
texture mtlSkin2;
sampler noiseMap=sampler_state
{
texture=(mtlSkin2);
};
texture mtlSkin3;
sampler furmap = sampler_state
{
texture=(mtlSkin3);
};
// Next the main pixel shader. nrm & texcoord come from the Vertex Shader,
// alpha is set in the function calls later on
float4 mainPS(
in float4 nrm:COLOR0,
in float2 texCoord:TEXCOORD0,
uniform float alpha) : COLOR
{
float4 base=tex2D(basemap,texCoord); //mtlskin1 sampler
float4 fur=tex2D(furmap,texCoord); //mtlskin2 sampler
float4 result=fur*base; //this is for color fur
// use Red channel in noisemap texture to modulate transparency
float4 noise=tex2D(noiseMap,texCoord);
result.a=alpha*noise.r;
return noise;
}
// Through these passes, the amount of fur-layers are determined,
// the more passes, the less fps (and even a changing effect, too much contrast)
technique test1
{
pass p0
{
VertexShader=compile vs_1_1 mainVS(1); // 1% offset
PixelShader=compile ps_1_4 mainPS(1); // 1% transparency
}
//fur part:
pass p0
{
CullMode=0;
AlphaBlendEnable=1;
BlendOp=1;
srcBlend=3; // '1/2/3' play with these values to see what it does
destBlend=7; // '3/5/7/9/11' just play with these numbers a bitrenderstates
VertexShader=compile vs_1_1 mainVS(301.9); // 300 % offset
PixelShader=compile ps_1_4 mainPS(300.9); // 300 % alpha
}
pass p0
{
AlphaBlendEnable=1;
destBlend=13;
VertexShader=compile vs_1_1 mainVS(101);
PixelShader=compile ps_1_4 mainPS(100.9);
}
pass p0
{
AlphaBlendEnable=1;
destBlend=11; //7/9
srcBlend=3;
VertexShader=compile vs_1_1 mainVS(91);
PixelShader=compile ps_1_4 mainPS(80.9);
}
pass p0
{
AlphaBlendEnable=1;
destBlend=7;
VertexShader=compile vs_1_1 mainVS(200);
PixelShader=compile ps_1_4 mainPS(99.9);
}
}
Written by: Erik Franken aka PHeMoX 5/8/05 ---I guess someone couldn't stand the chaos ;) Thanks for making it more organised!---
