Shaders - having one hell-uv-a-time wit em

The place for artists, modellers, level designers et al to discuss their approaches for creating content for OGRE.
Post Reply
Van
Hobgoblin
Posts: 512
Joined: Fri Nov 19, 2004 3:56 am
Contact:

Shaders - having one hell-uv-a-time wit em

Post by Van »

We are having a problem with shader programming and its pulling our hair out. We really could use some expert help here please.

Please view this AVI (DivX Codec, 1.1MB - reduced quality to reduce the size):

http://www.EvilMasterMindsInc.com/Image ... roblem.avi

Note the spinning roid and the shadow and lighting. The light source is behind the station (the sun , the yellow spot, is just peaking over the station) in the background. The static roids on either side of the spinning roid are casting a shadow correctly (i.e we are seeing the backside - the darkside - of the roid).

The light seems to be following only one side of the roid. There is only ONE light source (the sun).

Ogre.log is not reporting any problems. It parses all files with no errors (we have TRIVIAL logging turned on).

So, we could use some help with this:

roid3.material script file

Code: Select all

material roid3/SOLID/roid3.bmp
{
	receive_shadows off
	technique
	{
	   pass
	      {
		
   		vertex_program_ref Shaders/sbvs
		{
			param_named_auto view_proj_matrix worldviewproj_matrix  
			param_named_auto light_position light_position 0
			param_named_auto eye_position camera_position_object_space     
			param_named_auto inv_view_matrix inverse_worldview_matrix 
		}

		fragment_program_ref Shaders/sbps
		
		{	
			
			param_indexed_auto 2 light_specular_colour 0
			param_indexed 3 float 0
			param_indexed 4 float 1
			param_indexed 5 float 1
			param_indexed 6 float 100
			param_indexed 7 float 1
			param_indexed_auto 0 ambient_light_colour
			param_indexed_auto 1 light_diffuse_colour 0
			
		}
   		
		texture_unit
		{

		 texture roid3f.png
		}

		texture_unit
		{
		  texture roid3_nor.png		  
		}

	     }
	}
      }

shaders.program file

Code: Select all

vertex_program Shaders/sbvs hlsl
{
	source sbvs.txt
	entry_point main	
	target vs_2_0
	
}

fragment_program Shaders/sbps asm
{	
	source sbps.asm
	syntax ps_2_0
}

sbps.asm file

Code: Select all

//
// Generated by Microsoft (R) D3DX9 Shader Compiler 9.04.91.0000
//
// Parameters:
//
//   float Ka;
//   float Kd;
//   float Ks;
//   float4 ambient;
//   sampler2D base_map;
//   sampler2D bump_map;
//   float bumpiness;
//   float4 diffuse;
//   float4 specular;
//   float specular_power;
//
//
// Registers:
//
//   Name           Reg   Size
//   -------------- ----- ----
//   ambient        c0       1
//   diffuse        c1       1
//   specular       c2       1
//   Ka             c3       1
//   Kd             c4       1
//   Ks             c5       1
//   specular_power c6       1
//   bumpiness      c7       1
//   base_map       s0       1
//   bump_map       s1       1
//

    ps_2_0
    def c8, 0.5, 0.5, 1, 0
    def c9, -0.5, -0.5, -1, 2
    dcl t0.xy
    dcl t1.xyz
    dcl t2.xyz
    dcl_2d s0
    dcl_2d s1
    texld r1, t0, s1
    texld r0, t0, s0
    add r1.xyz, r1, c9
    mov r0.w, c7.x
    mad r1.xyz, r0.w, r1, c8
    mad r1.xyz, c9.w, r1, c9.z
    nrm r2.xyz, r1
    nrm r1.xyz, t1
    dp3 r3.x, r2, r1
    mul r1.xyz, r0, c1
    mul r0.xyz, r0, c0
    max r0.w, r3.x, c8.w
    mul r1.xyz, r1, c4.x
    mul r1.xyz, r0.w, r1
    nrm r3.xyz, t2
    dp3 r2.x, r2, r3
    mad r1.xyz, r0, c3.x, r1
    max r1.w, r2.x, c8.w
    pow r0.w, r1.w, c6.x
    mov r1.w, c5.x
    mul r0.xyz, r1.w, c2
    mad r0.xyz, r0, r0.w, r1
    mov r0.w, c8.z
    mov oC0, r0

// approximately 32 instruction slots used (2 texture, 30 arithmetic)


sbvs.txt file

Code: Select all

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 binormal:     BINORMAL0;
   float3 tangent:      TANGENT0;
};

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 )
{
   VS_OUTPUT_STRUCT vsOutStruct; //** Declare the output struct

   vsOutStruct.position = mul( view_proj_matrix, vsInStruct.position );
   vsOutStruct.bump_map = vsInStruct.texcoord0;
   
   //float3 binormal=cross(vsInStruct.tangent,vsInStruct.normal);

   //float3 binormal=cross(vsInStruct.normal,vsInStruct.tangent);
    
   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.normal );
   vsOutStruct.light_vector.y = dot( temp_light_vector, vsInStruct.binormal);
   vsOutStruct.light_vector.z = dot( temp_light_vector, vsInStruct.tangent );

   float3 temp_eye_position = 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, vsInStruct.binormal );
   temp_view_vector2.z = dot( temp_view_vector, vsInStruct.normal );

   vsOutStruct.half_angle = vsOutStruct.light_vector + temp_view_vector2;

   return vsOutStruct; //** Return the resulting output struct
}
Rixeh
Greenskin
Posts: 135
Joined: Sat Nov 20, 2004 8:36 am

Post by Rixeh »

NFZ YOU ARE THE SHADER GOD. COMMAND US, SHADER GOD! :shock:
User avatar
tuan kuranes
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 2653
Joined: Wed Sep 24, 2003 8:07 am
Location: Haute Garonne, France
x 4
Contact:

Post by tuan kuranes »

Please comment the shaders source to let people help you wihtout too much time.
it will help you one day too, if you want to update your shaders.
(very likely to happen, believe me)

Don't you have the source of the PS ?
much more easier to read than uncommented raw asm.
nfz
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 1263
Joined: Wed Sep 24, 2003 4:00 pm
Location: Halifax, Nova Scotia, Canada

Post by nfz »

Sorry about the delay, ISP went down just after we were talking on irc. OK, here is the fixed vertex shader we talked about:

Code: Select all

float4x4 view_proj_matrix;
float3 light_position;
float3 eye_position; 

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 ) 
{ 
   VS_OUTPUT_STRUCT vsOutStruct = (VS_OUTPUT_STRUCT)0; //** Declare the output struct 

   vsOutStruct.position = mul( view_proj_matrix, vsInStruct.position ); 
   vsOutStruct.bump_map = vsInStruct.texcoord0; 

   // light and eye position are in object space so just calc direction to vertex
   float3 temp_light_vector = light_position - vsInStruct.position.xyz;
   float3 temp_view_vector  = eye_position - vsInStruct.position.xyz; 

   float3x3 rotation;

   // build tangent space rotation matrix
   rotation[0] = vsInStruct.tangent;
   // calc the binormal
   rotation[1] = cross(vsInStruct.tangent, vsInStruct.normal);
   rotation[2] = vsInStruct.normal;

   temp_light_vector = mul(rotation, temp_light_vector); 
   temp_view_vector = mul(rotation, temp_view_vector); 

   vsOutStruct.light_vector = temp_light_vector; 
   vsOutStruct.half_angle = temp_view_vector + temp_light_vector; 


   return vsOutStruct; //** Return the resulting output struct 
} 
and the changed material script:

Code: Select all

material roid3/SOLID/roid3.bmp 
{ 
  receive_shadows off 
  technique 
  { 
    pass 
   { 

     vertex_program_ref Shaders/sbvs 
     { 
       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 
     } 

     fragment_program_ref Shaders/sbps 
     { 

        param_indexed_auto 0 ambient_light_colour 
        param_indexed_auto 1 light_diffuse_colour 0 
        param_indexed_auto 2 light_specular_colour 0 
        param_indexed 3 float 0 
        param_indexed 4 float 1 
        param_indexed 5 float 1 
        param_indexed 6 float 100 
        param_indexed 7 float 1 

     } 

     texture_unit 
     { 
        texture fxTestDiff.png
        tex_coord_set 0
     } 

     texture_unit 
     { 
         texture fxTestNMap.png
         tex_coord_set 1
     } 

   } 
 } 
} 
I didn't find any problems with the pixel shader. The problem was just with the way you were setting up the tangent space rotation matrix, assuming Ogre would pass the binormal, and the declaration for the tangent vector as an input.

Using the light position in object space saves a matrix mul for every vertex in the vertex shader.

I changed your code from using dot product to using matrix mul, I find it cleaner and easier to understand.
biteme
Halfling
Posts: 70
Joined: Fri Mar 11, 2005 12:49 am

Post by biteme »

hello nfs the problem remains it dose exactly the same, thing BTW the shader is from render monkey 1.6 "specular bump" is the name..

this is driving us nuts im ready to give up.... almost


it almost seems like the light position is not getting updated, but im not a programer so who knows
biteme
Halfling
Posts: 70
Joined: Fri Mar 11, 2005 12:49 am

Post by biteme »

Ok i fixed it sort of.


I used the normal map from the ogre demos and it works.

I assume there are more then one normal map format could i get a run down on the differences?
Yokom
Halfling
Posts: 88
Joined: Tue Nov 30, 2004 2:34 am

Post by Yokom »

I noticed that in nfz's shader he used a normal map from the ogre test, the normal map biteme is using is from zbrush2 im pretty sure.

Is there a problem with the normals from the zbrush exporter?
biteme
Halfling
Posts: 70
Joined: Fri Mar 11, 2005 12:49 am

Post by biteme »

no yoks i just need to push the tanget option in in the normal map menu forz brush :oops:
biteme
Halfling
Posts: 70
Joined: Fri Mar 11, 2005 12:49 am

Post by biteme »

Well i seemed to have spoken to soon It works better now but not perfect.

the specular highlights work good as long as the object moves if its a static object the highlights stay frozen no matter the camera poaition.


btw thanks bunch for the help nfz
nfz
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 1263
Joined: Wed Sep 24, 2003 4:00 pm
Location: Halifax, Nova Scotia, Canada

Post by nfz »

oh boy, your right, I should have checked that. I just moved the light around in the scene and never moved the camera, silly me. I'll have another look, must be something to do with the half angle.
biteme
Halfling
Posts: 70
Joined: Fri Mar 11, 2005 12:49 am

Post by biteme »

thanks ahhh one more question, I know I've bothered you enough allready but...


i was using the nvidia normal map plug in to make normaps from textures wich aperantly doesn't work for this shader is there a such a program that will do the same thing with this format?
nfz
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 1263
Joined: Wed Sep 24, 2003 4:00 pm
Location: Halifax, Nova Scotia, Canada

Post by nfz »

Ok, really sorry about that, I removed to many normalize() in the vertex shader. This one here does work properly:

Code: Select all

float4x4 view_proj_matrix;
float3 light_position;
float3 eye_position; 

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 ) 
{ 
   VS_OUTPUT_STRUCT vsOutStruct = (VS_OUTPUT_STRUCT)0; //** Declare the output struct 

   vsOutStruct.position = mul( view_proj_matrix, vsInStruct.position ); 
   vsOutStruct.bump_map = vsInStruct.texcoord0; 


   float3 temp_light_vector = light_position - vsInStruct.position.xyz;
   float3 temp_view_vector  = eye_position - vsInStruct.position.xyz; 

   float3x3 rotation;

   rotation[0] = vsInStruct.tangent;
   rotation[1] = cross(vsInStruct.tangent, vsInStruct.normal);
   rotation[2] = vsInStruct.normal;

   temp_light_vector = normalize(mul(rotation, temp_light_vector)); 
   temp_view_vector = normalize( mul(rotation, temp_view_vector) ); 

   vsOutStruct.light_vector = temp_light_vector; 
   vsOutStruct.half_angle = normalize(temp_view_vector + temp_light_vector); 


   return vsOutStruct; //** Return the resulting output struct 
} 
nfz
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 1263
Joined: Wed Sep 24, 2003 4:00 pm
Location: Halifax, Nova Scotia, Canada

Post by nfz »

There are several formats for Normal Maps and its just how the normal vector is stored. 3 of the formats have to do with which transform space the normal vector is in. The normal could be in world space, object space, or tangent space. For the shader you are using, the normal map must be in tangent space. But then there are different formats for tangent space. There several different methods for placing the normal vector in the RGB channels and of course your pixel shader must know what format the normal vector is stored in the texture.

Nvidia and ATI formats are different but easy to switch between the two. Usually the difference is in the green channel and its just a matter of inverting the green channel to switch between the two. But there is also some packages that use a different mapping for the up vector. You can use your favorite image manipulation program to modify the RGB channels if the tangent space vector is not in the format you use in your shader.

Hmm...this would make a good tutorial where all the different formats could be explained and how to convert them since there are a lot of different formats floating around out there.
biteme
Halfling
Posts: 70
Joined: Fri Mar 11, 2005 12:49 am

Post by biteme »

You know I love you nfz I want to have like 10,000 of your babies thanks a ton.


BTW if any one uses this shader and uses the nvidia ps normal map plug in, use "colorspace" in the alternate conversions box and you'l be in shinny bumpy heaven!!


thanks again, learned more about shaders then i ever wanted to :P
User avatar
Jerky
Orc Shaman
Posts: 791
Joined: Wed Mar 02, 2005 4:13 am
Location: Springville, Utah
Contact:

Post by Jerky »

btw, I got my normal maps from ZBrush working and I did not press the tangent button on export. That is not a make-or-break option for this. For me though, I had to NOT use the normals from the demo to get mine to work. So, it all depends on what you are trying to do.
Erik Briggs (Jerky)
My Blog
Project Wish
Image
Rixeh
Greenskin
Posts: 135
Joined: Sat Nov 20, 2004 8:36 am

Post by Rixeh »

Gonna echo biteme for all of us nfz, OOOHHMMMMM WE BOW TO YOU SHADER GOD. 8)
Post Reply