[Solved] Relief Mapping CG shader in Ogre material.

Problems building or running the engine, queries about how to use features etc.
Post Reply
gk
Halfling
Posts: 40
Joined: Tue Jan 31, 2006 3:19 pm

[Solved] Relief Mapping CG shader in Ogre material.

Post by gk » Wed Jan 23, 2008 2:58 pm

Hi,

I am trying to use a relief map cg script that I found here, but cannot get it to work in OGRE.

Its effect is shown in the pictures below, it appears similar to parallax occlusion mapping, others may be interested in this effect too?
ImageImage
Read about it here.

The problem is that I do not know how to include it into a material.

Below is my first attempt which definitely isn't right, currently I get an error 'cannot be used - compile error.' even though the script compiles fine in FX composer.

If you have any ideas, please let me know.

Thanks.

Code: Select all

// CG shader definition
vertex_program cg_relief_vp cg			
{
	source cg_relief.cg
	entry_point main_relief
	profiles ps_1_1 arbfp1	
}

material materialTest
{
	technique					
	{
		pass					
		{
			vertex_program_ref cg_relief_vp
			{
			}
			texture_unit
			{
				texture relief.tga 2d		
			}
		}
	}
}
Last edited by gk on Sat Jan 26, 2008 10:04 pm, edited 3 times in total.
0 x

Lord LoriK
Goblin
Posts: 254
Joined: Tue Feb 13, 2007 5:33 am

Post by Lord LoriK » Wed Jan 23, 2008 6:06 pm

The problem seems to be that your program definition includes no profiles for vertex programs. Both ps_1_1 and arbfp1 are fragment program profiles. I suggest arbvp1 and vs_2_0.
0 x

gk
Halfling
Posts: 40
Joined: Tue Jan 31, 2006 3:19 pm

thanks

Post by gk » Wed Jan 23, 2008 9:18 pm

thanks,

I think i have to arrange a number of passes in an ogre material that each use functions from the cg file.

I will see if I can work this out from the bump map example.
0 x

gk
Halfling
Posts: 40
Joined: Tue Jan 31, 2006 3:19 pm

um, still not working

Post by gk » Thu Jan 24, 2008 4:02 pm

I have no errors now but the material makes the meshes appear invisible.

The tangents vectors are being built and the normal mapping examples work fine.

I must have the incorrect parameters set up, but the code works fine in FX Composer 1.8 and there are no errors from Ogre.

Any ideas on what could be wrong or on how I could test it better?

Thanks

Update:
Code removed, I got it working so posted the working code below.
Last edited by gk on Sat Jan 26, 2008 10:01 pm, edited 1 time in total.
0 x

gk
Halfling
Posts: 40
Joined: Tue Jan 31, 2006 3:19 pm

Working :)

Post by gk » Sat Jan 26, 2008 10:00 pm

I have the shader working now. Its effect is similar to parallax occlusion mapping and much better than the standard parallax or normal mapping in the samples.

The only changes I have made were to use 3 component tangent vectors instead of 4 and to generate the binormals in the vertex shader rather than require them as input.

Hopefully, this will be of use to someone else too. Remember the shader came from here here, and there is also a demo there so you can see what it looks like first.

Also there is a 'howto' create relief maps here.

material:

Code: Select all

vertex_program relief_view_space_vp cg			
{
	source relief_map.cg
	entry_point view_space
	profiles arbvp1 vs_1_1
}

fragment_program relief_main_fp cg			
{
	source relief_map.cg	
	entry_point main_relief
	profiles ps_2_x arbfp1 fp30
}

material reliefMaterial
{
	technique
	{		
		pass
		{
			vertex_program_ref relief_view_space_vp
			{
				param_named_auto lightpos light_position_object_space 0
				param_named depth float 0.1
				param_named tile float 1
			}
			fragment_program_ref relief_main_fp
			{
				param_named_auto ambient ambient_light_colour 0
				param_named_auto diffuse light_diffuse_colour 0 
				param_named_auto specular light_specular_colour 0
				param_named planes float2 1 3000
			}
			texture_unit NormalMap
			{
				texture stone.tga
			}
			texture_unit DiffuseMap
			{
				texture stone.jpg
			}
		}
	}
}
relief_map.cg

Code: Select all

struct a2v 
{
    float4 pos		: POSITION;
    float3 normal		: NORMAL;
    float2 texcoord	: TEXCOORD0;
    float3 tangent	: TANGENT0;
};

struct v2f
{
    float4 hpos		: POSITION;
    float3 vpos		: TEXCOORD0;
    float2 texcoord	: TEXCOORD1;
    float3 view		: TEXCOORD2;
    float3 light		: TEXCOORD3;
    float4 scale	 : TEXCOORD4;
    float2 curvature : TEXCOORD5;
};

struct f2s
{	
	float4 color : COLOR;
#ifdef RM_DEPTHCORRECT
	float depth : DEPTH; 
#endif
};

v2f view_space(a2v IN,
	uniform float4 lightpos,
	uniform float depth,
	uniform float tile)
{
	v2f OUT;

	// vertex position in object space
	float4 pos=float4(IN.pos.x,IN.pos.y,IN.pos.z,1.0);

	// vertex position in clip space
	OUT.hpos=mul(glstate.matrix.mvp,pos);

	// copy texture coordinates
	OUT.texcoord=IN.texcoord*tile;

	// compute modelview rotation only part
	float3x3 modelviewrot=float3x3(glstate.matrix.modelview[0]);

	// vertex position in view space (with model transformations)
	OUT.vpos=mul(glstate.matrix.modelview[0],pos).xyz;

	// tangent vectors in view space
	float3 tangent=mul(modelviewrot,IN.tangent);
	float3 binormal=cross(IN.tangent, IN.normal);
	binormal=mul(modelviewrot,binormal);
	float3 normal=mul(modelviewrot,IN.normal);
	float3x3 tangentspace=float3x3(tangent,binormal,normal);

	// scale and curvature
	//OUT.scale=float4(IN.tangent.w,IN.binormal.w,depth,tile*tile)/tile;
	OUT.scale=float4(1,1,depth,tile*tile)/tile;
	//OUT.curvature=IN.curvature;

	// view and light in tangent space
	OUT.view=mul(tangentspace,OUT.vpos);
	OUT.light=mul(tangentspace,lightpos.xyz-OUT.vpos);

	return OUT;
}

void ray_intersect_rm_linear(
      in sampler2D reliefmap,
      inout float3 p, 
      inout float3 v)
{
#ifdef RM_DOUBLEPRECISION
	const int linear_search_steps=20;
#else
	const int linear_search_steps=10;
#endif

	v/=linear_search_steps;

	for( int i=0;i<linear_search_steps-1;i++ )
	{
		float4 t=tex2D(reliefmap,p.xy);
		if (p.z<t.w)
			p+=v;
	}
}

void ray_intersect_rm_binary(
      in sampler2D reliefmap,
      inout float3 p, 
      inout float3 v)
{
	const int binary_search_steps=6;
   
	for( int i=0;i<binary_search_steps;i++ )
	{
		v*=0.5;
		float4 t=tex2D(reliefmap,p.xy);
		if (p.z<t.w)
			p+=2*v;
		p-=v;
	}
}

f2s main_relief(
	v2f IN,
	uniform sampler2D rmtex:TEXUNIT0,		// rm texture map 
	uniform sampler2D colortex:TEXUNIT1,	// color texture map 
	uniform float4 ambient,			// ambient color
	uniform float4 diffuse,			// diffuse color
	uniform float4 specular,		// specular color
	uniform float2 planes)			// near and far plane information

{
	f2s OUT;

	// view vector in eye space
	float3 view=normalize(IN.view);
	view.z=-view.z;

	// scale view vector to texture space using depth factor
#ifdef RM_DEPTHBIAS
	float depth_bias=(2*view.z-view.z*view.z);
	view.xy*=depth_bias;
#endif
	view*=IN.scale.z/(IN.scale.xyz*view.z);

	// ray intersect depth map 
	float3 p=float3(IN.texcoord,0);
	ray_intersect_rm_linear(rmtex,p,view);
	ray_intersect_rm_binary(rmtex,p,view);

	float alpha=1;
#ifdef RM_BORDERCLAMP
	if (p.x<0) alpha=0;
	if (p.y<0) alpha=0;
	if (p.x>IN.scale.w) alpha=0;
	if (p.y>IN.scale.w) alpha=0;
#endif

#ifdef RM_VIEWDEPTH
	OUT.color=float4(p.zzz,1.0);
	return OUT;
#endif

	// get normal and color
	float4 n=tex2D(rmtex,p.xy);
	float4 c=tex2D(colortex,p.xy);

#ifdef RM_VIEWNORMAL
	OUT.color=float4(n.xyz,1.0);
	return OUT;
#endif

	// expand normal from normal map
	n.xyz=normalize(n.xyz-0.5);

	// restore view vector
	view=normalize(IN.view);

#ifdef RM_DEPTHCORRECT
	// a=-far/(far-near)
	// b=-far*near/(far-near)
	// Z=(a*z+b)/-z
	float3 pos=IN.vpos-normalize(IN.vpos)*p.z*IN.scale.z/view.z;
	OUT.depth=((planes.x*pos.z+planes.y)/-pos.z);
#endif

	float3 light=normalize(IN.light);

	// compute diffuse and specular terms
	float diff=saturate(dot(light,n.xyz));
	float spec=saturate(dot(normalize(light-view),n.xyz));

	// attenuation factor
	float att=1.0-max(0,light.z); att=1.0-att*att;

	// ambient term
	float4 finalcolor=ambient*c;

#ifdef RM_SHADOWS
	// compute light ray vector in texture space
	float light_depth_bias=(2*light.z-light.z*light.z);
	light.xy*=light_depth_bias;
	light.z=-light.z;
	light*=IN.scale.z/(IN.scale*light.z);

	// compute light ray entry point in texture space
	float3 lp=p-light*p.z;
	ray_intersect_rm_linear(rmtex,lp,light);

	if (lp.z<p.z-0.05) // if pixel in shadow
	{
	  diff*=0.25;
	  spec=0;
	}
#endif

	// compute final color
	finalcolor.xyz += att*(c.xyz*diffuse.xyz*diff + 
		specular.xyz*pow(spec,specular.w));
	finalcolor.w=alpha;

	OUT.color=finalcolor;
	return OUT;
}

0 x

User avatar
Jabberwocky
OGRE Moderator
OGRE Moderator
Posts: 2819
Joined: Mon Mar 05, 2007 11:17 pm
Location: Canada
Contact:

Post by Jabberwocky » Sun Jan 27, 2008 2:45 am

Cool, thanks for sharing. :)
0 x
Image

ShadeOgre
Gremlin
Posts: 158
Joined: Mon Mar 10, 2008 10:55 pm
Location: Budapest, Hungary
x 1

Post by ShadeOgre » Thu Jul 17, 2008 1:56 pm

First, a great thank you for posting the shader and the material. I've tried it, but I just cant make it to work.

I used the textures from the original rar (you linked), and the modell is MeshManager::getSingleton().createPlane. I call buildTangentVectors and with the basic normal-mapping it seems to work. But with your material, I get this (regardless of which texture(s) I use, I tried em all)

Image
0 x

gk
Halfling
Posts: 40
Joined: Tue Jan 31, 2006 3:19 pm

Post by gk » Fri Jul 18, 2008 12:24 pm

That pattern normally appears when a texture is missing. I'm not sure which rar you are talking about, but I guess you may have downloaded the samples from Manuel's Relief Texture Mapping page?

Here are some suggestions:

Check the cg plugin is loaded.

Use the OpenGL render system.

If this doesn't work I'll see if I make a minimal example for you.
0 x

ShadeOgre
Gremlin
Posts: 158
Joined: Mon Mar 10, 2008 10:55 pm
Location: Budapest, Hungary
x 1

Post by ShadeOgre » Fri Jul 18, 2008 12:43 pm

Yes, I missed a resource-path; I changed my directory-structure and I forget to add this path.

It works now, but the log yield for an exception: "Error in material reliefMaterial at line 339 of MyMaterials.material: Invalid param_named attribute - Parameter called planes does not exist."

And another problem: why is it working only with OGL, why not with DX? I tried vs/ps up to 3_0, and I get only a white screen... Weird.

Thank you, anyway!
0 x

lukeneorm
Halfling
Posts: 61
Joined: Wed Apr 01, 2009 12:03 am

Re: Working :)

Post by lukeneorm » Wed Apr 29, 2009 8:03 pm

gk wrote:I have the shader working now. Its effect is similar to parallax occlusion mapping and much better than the standard parallax or normal mapping in the samples.
The only changes I have made were to use 3 component tangent vectors instead of 4 and to generate the binormals in the vertex shader rather than require them as input.
Hopefully, this will be of use to someone else too. Remember the shader came from here, and there is also a demo there so you can see what it looks like first.
Hi,
I tried to use your cg shader usign your images, but the Ogre loader report this error when the application stars:
WARNING: material reliefMaterial has no supportable Techniques and will be blank. Explanation:
Pass 0: Vertex program ReliefMapping_VP cannot be used - not supported.

..leaving the model in the scene completely white without any texture.
Any idea of what kind of problem it could be?
I use nVida Quadro 750 card.

Thank you.
0 x

User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1869
Joined: Sun Mar 08, 2009 5:25 am
x 20

Re: [Solved] Relief Mapping CG shader in Ogre material.

Post by mkultra333 » Thu Apr 30, 2009 4:21 pm

This looks like a great shader. Unfortunately it also appears to be copyrighted. The code in the demo reads

Code: Select all

//    Relief Mapping for FX Composer
// 
//    Original code written by Fabio Policarpo.
//    Manuel M. Oliveira fixed and documented the vertex shader, 
//    and added refraction, chromatic dispersion, Fresnel effect,
//    and self-shadowing with Chromatic Dispersion and Fresnel. 
//    
//    Last modified on October 2, 2005. 
//
//    Copyright (c) 2005, Fabio Policarpo and Manuel M. Oliveira
//
Doesn't that make it, and the derivative code above, unusable?

Edit: I found a relief mapping shader on the nvidia page, also based on the above code, that should be free to use.
http://developer.download.nvidia.com/sh ... brary.html
Just thought I'd mention that.
0 x
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.

User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
Contact:

Re: [Solved] Relief Mapping CG shader in Ogre material.

Post by jacmoe » Fri May 29, 2009 12:17 am

That it's copyrighted doesn't say anything about what license it's under. :wink:
0 x
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.

User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1869
Joined: Sun Mar 08, 2009 5:25 am
x 20

Re: [Solved] Relief Mapping CG shader in Ogre material.

Post by mkultra333 » Fri May 29, 2009 2:19 am

True. But it does mean, in the absence of any other license info, that you can't copy it. :)

I'm pretty sure you can copy the nvidia one though, which is based on the same code. I'm working on a version now, I'll post it over here,http://www.ogre3d.org/forums/viewtopic. ... 05#p342205, later today.
0 x
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.

Post Reply