custom vertex shader

moagames

28-05-2008 08:53:36

Hi everybody,

I just could't get my vertex shader to work with pagedgeometry.

So can you please tell me, what i have to add/modify in my 3 files (material+vs+ps) ?

here are my files:

material

material tree
{
technique
{
pass
{
specular 0.639216 0.639216 0.639216 1 10

vertex_program_ref tutorial_BumpMap_vs
{
param_named_auto view_proj_matrix worldviewproj_matrix
param_named_auto light_position light_position_object_space 0
param_named_auto eye_position camera_position_object_space
param_named_auto inv_view_matrix inverse_worldview_matrix
}

fragment_program_ref tutorial_BumpMap_ps
{
param_named_auto specular light_specular_colour 0
param_named Ka float 0.7
param_named Kd float 1
param_named Ks float 0
param_named specular_power float 200
param_named bumpiness float 2
param_named_auto ambient ambient_light_colour
param_named_auto diffuse light_diffuse_colour 0
}

texture_unit
{
texture_alias Map #7
texture carolinabuckthornbark.tga
colour_op_ex source1 src_current src_current
colour_op_multipass_fallback dest_colour zero
alpha_op_ex source1 src_current src_current
}

texture_unit
{
texture_alias Map #8
texture carolinabuckthornbark_normal.tga
colour_op_ex blend_texture_alpha src_current src_current
colour_op_multipass_fallback dest_colour zero
alpha_op_ex source1 src_current src_current
}
}

}

}

vs
//float4x4 view_proj_matrix: register(c0);
//float4 light_position: register(c8);
//float4 eye_position: register(c9);
//float4x4 inv_view_matrix;
struct VS_INPUT_STRUCT
{
float4 position: POSITION;
float3 normal: NORMAL;
float2 texcoord0: TEXCOORD0;
float3 tangent: TEXCOORD1;
};

struct VS_OUTPUT_STRUCT
{
float4 position: POSITION;
float2 bump_map: TEXCOORD0;
float3 light_vector: TEXCOORD1;
float3 half_angle: TEXCOORD2;
};

//**---------------------------------------------------------
//** Function: main
//** Description: Declare the main entry point for the shader
//** Input: VS_INPUT_STRUCT, derived from the stream
//** mapping parameters defined in the workspace
//** Returns: VS_OUTPUT_STRUCT
//**---------------------------------------------------------
VS_OUTPUT_STRUCT main( VS_INPUT_STRUCT vsInStruct,
uniform float4x4 view_proj_matrix,
uniform float4 light_position,
uniform float4 eye_position,
uniform float4x4 inv_view_matrix )
{
VS_OUTPUT_STRUCT vsOutStruct; //** Declare the output struct

//**-----------------------------------------------------------
//** Calculate the pixel position using the perspective matrix.
//**-----------------------------------------------------------
vsOutStruct.position = mul( view_proj_matrix, vsInStruct.position );

//**----------------------------------------------
//** Pass the bump and base texture coords through
//**----------------------------------------------
vsOutStruct.bump_map = vsInStruct.texcoord0;

//**----------------------------------------------
//** Calculate the Binormal vector
//**----------------------------------------------
float3 binormal = cross(vsInStruct.tangent, vsInStruct.normal);

//**--------------------------------------------
//** Calculate the light vector in object space,
//** and then transform it into texture space.
//**--------------------------------------------
float3 temp_light_position = mul( inv_view_matrix, light_position );
float3 temp_light_vector = temp_light_position - vsInStruct.position;
vsOutStruct.light_vector.x = dot( temp_light_vector, vsInStruct.tangent );
vsOutStruct.light_vector.y = dot( temp_light_vector, binormal );
vsOutStruct.light_vector.z = dot( temp_light_vector, vsInStruct.normal );

//**-------------------------------------------
//** Calculate the view vector in object space,
//** and then transform it into texture space.
//**-------------------------------------------
float3 temp_eye_position = mul( inv_view_matrix, eye_position );
float3 temp_view_vector = temp_eye_position - vsInStruct.position;
float3 temp_view_vector2;
temp_view_vector2.x = dot( temp_view_vector, vsInStruct.tangent );
temp_view_vector2.y = dot( temp_view_vector, binormal );
temp_view_vector2.z = dot( temp_view_vector, vsInStruct.normal );

//**-------------------------
//** Calculate the half angle
//**-------------------------
vsOutStruct.half_angle = vsOutStruct.light_vector + temp_view_vector2;

return vsOutStruct; //** Return the resulting output struct
}


ps:
//float4 specular: register(c2);
//float Ka: register(c3);
//float Kd: register(c4);
//float Ks: register(c5);
//float specular_power: register(c6);
//float bumpiness: register(c7);
//float4 ambient: register(c0);
//float4 diffuse: register(c1);
//sampler base_map: register(s0);
//sampler bump_map: register(s1);
struct PS_INPUT_STRUCT
{
float2 bump_map: TEXCOORD0;
float3 light_vector: TEXCOORD1;
float3 half_angle: TEXCOORD2;
};

struct PS_OUTPUT_STRUCT
{
float4 color0: COLOR0;
};

//**---------------------------------------------------------
//** Function: main
//** Description: Declare the main entry point for the shader
//** Input: PS_INPUT_STRUCT, derived from the output of
//** the associated vertex shader
//** Returns: PS_OUTPUT_STRUCT
//**---------------------------------------------------------
PS_OUTPUT_STRUCT main( PS_INPUT_STRUCT psInStruct,
uniform float4 specular,
uniform float Ka,
uniform float Kd,
uniform float Ks,
uniform float specular_power,
uniform float bumpiness,
uniform float4 ambient,
uniform float4 diffuse,
uniform sampler base_map,
uniform sampler bump_map)
{
PS_OUTPUT_STRUCT psOutStruct; //** Declare the output struct

//**------------------------------------------------------
//** Retreive the base color and bump components from the
//** respective textures, based on the passed bump coords.
//**------------------------------------------------------
float3 base = tex2D( base_map, psInStruct.bump_map );
float3 bump = tex2D( bump_map, psInStruct.bump_map );

//**----------------------------------------------------
//** Normalize the passed vectors from the vertex shader
//**----------------------------------------------------
float3 normalized_light_vector = normalize( psInStruct.light_vector );
float3 normalized_half_angle = normalize( psInStruct.half_angle );

//**--------------------------------------------------------
//** "Smooth out" the bump based on the bumpiness parameter.
//** This is simply a linear interpolation between a "flat"
//** normal and a "bumped" normal. Note that this "flat"
//** normal is based on the texture space coordinate basis.
//**--------------------------------------------------------
float3 smooth = { 0.5f, 0.5f, 1.0f };
bump = lerp( smooth, bump, bumpiness );
bump = normalize( ( bump * 2.0f ) - 1.0f );

//**---------------------------------------------------------
//** These dot products are used for the lighting model
//** equations. The surface normal dotted with the light
//** vector is denoted by n_dot_l. The normal vector
//** dotted with the half angle vector is denoted by n_dot_h.
//**---------------------------------------------------------
float4 n_dot_l = dot( bump, normalized_light_vector );
float4 n_dot_h = dot( bump, normalized_half_angle );

//**--------------------------------------
//** Calculate the resulting pixel color,
//** based on our lighting model.
//** Ambient + Diffuse + Specular
//**--------------------------------------
psOutStruct.color0.rgb =
( base * ambient * Ka ) +
( base * diffuse * Kd * max( 0.0f, n_dot_l ) ) +
( specular * Ks * pow( max( 0.0f, n_dot_h ), specular_power ) );
psOutStruct.color0.a = 1.0f; //** Set the alpha component manually

return psOutStruct; //** Return the resulting output struct
}


thanks

JohnJ

28-05-2008 16:47:29

Custom shaders is a somewhat advanced and undocumented area of PagedGeometry (which I really should provide more info on I guess). Basically what you need to do to get your own shaders working is add some code to your vertex shader so PagedGeometry's fade values are applied properly.

Starting at line 172 of "BatchPage.cpp" you should see some code that builds a big string containing a CG vertex shader. Your shaders will override this code, but they will still need to do the same fade work, so you'll need to copy the appropriate fade code from this shader into your vertex shader. Lines 256 - 273 shows which shader parameters are configured by PagedGeometry automatically, and will be available to your vertex shader. Assume "fadeEnabled" is true, and "lightingEnabled" will be true unless you disable lighting in your material script (which you don't).

I wish there was an easier way to integrate custom shaders into PagedGeometry, but a big limitation with shaders in general is you can't combine them automatically - it has to be done by the programmer. Unfortunately this means that this is left up to the users of PagedGeometry, rather than me, and there's nothing I can do about it (although I should document this issue better).