Game Development Community

Help: quick material setup script...

by Giorgio Zanetti ( JoZ ) · in Torque Game Engine Advanced · 01/27/2008 (3:43 pm) · 20 replies

Hi guys...
I was trying to modify the script for the materials that ship with TGEA in order to have different functions for quickly generating materials for quick textures test purpose...

Here is the default script that ship with TGEA (for easy reference...)

//*****************************************************************************
// Cottage and Tower materials
//*****************************************************************************
function demoMaterial( %name, %dir )
{
   %com = "new Material(Demo_"@%name@") {"@
      "baseTex[0] = " @ %name @ ";" @
      "mapTo = " @ %name @ ";" @
   "};";
//   echo(%com);
   eval(%com);
}
demoMaterial("MtlPilrFront" );


here is my materials.cs that isn't working...
//*****************************************************************************
//
// call the function, passing to it... :
//	- the texture file name (must be the same for diffuse and normal, use .jpg/.png and .dds respectively
//
// and for functions other than "_simple" also:
//	- the diffuse texture extension (DFext)
//	- the normal texture extension (NMext)
//    
//*****************************************************************************

//*************************   FUNCTIONS DEFINITIONS   *************************


function _simple( %name, %dir )
{
   %com = "new Material(_"@%name@") {"@
      "baseTex[0] = " @ %name @ ";" @
      "mapTo = " @ %name @ ";" @
   "};";
//   echo(%com);
   eval(%com);
}


function _bump( %name, %DFext, %NMext, %dir )
{
   %com = "new Material(_"@%name@") {"@
      "baseTex[0] = " @ %name @ %DFext @ ";" @
      "bumpTex[0] = " @ %name @ %NMext @ ";" @
      "pixelSpecular[0] = true;" @
      "specular[0]      = \"0.75 0.75 0.75\";" @
      "specularPower[0] = 128.0;" @
      "mapTo = " @ %name @ ";" @
   "};";
//   echo(%com);
   eval(%com);
}


function _normal( %name, %DFext, %NMext, %dir )
{
   %com = "new CustomMaterial(_"@%name@") {"@
      "texture[0] = " @ %name @ %DFext @ ";" @
      "texture[1] = " @ %name @ %NMext @ ";" @
      "texture[2] = \"$lightmap\";" @
      "shader = NormalShader;" @
      "pixVersion = 2.0;" @
      "specular = \"0.75 0.75 0.75\";" @
      "specularPower = 128.0;" @
      "mapTo = " @ %name @ ";" @
   "};";
//   echo(%com);
   eval(%com);
}

function _parallax( %name, %DFext, %NMext, %dir )
{
   %com = "new CustomMaterial(_"@%name@") {"@
      "texture[0] = " @ %name @ %DFext @ ";" @
      "texture[1] = " @ %name @ %NMext @ ";" @
      "texture[2] = \"$lightmap\";" @
      "shader = ParallaxShader;" @
      "pixVersion = 2.0;" @
      "specular = \"0.75 0.75 0.75\";" @
      "specularPower = 128.0;" @
      "mapTo = " @ %name @ ";" @
   "};";
//   echo(%com);
   eval(%com);
}

function _relief( %name, %DFext, %NMext, %dir )
{
   %com = "new CustomMaterial(_"@%name@") {"@
      "texture[0] = " @ %name @ %DFext @ ";" @
      "texture[1] = " @ %name @ %NMext @ ";" @
      "texture[2] = \"$lightmap\";" @
      "shader = ReliefShader;" @
      "pixVersion = 3.0;" @
      "specular = \"0.75 0.75 0.75\";" @
      "specularPower = 128.0;" @
      "mapTo = " @ %name @ ";" @
   "};";
//   echo(%com);
   eval(%com);
}



//*****   MATERIALS DEFINITIONS   *****

// <function name>("<texture name>", "<diffuse extension>", "<normal extension>" 

_parallax("plate_ground", ".jpg", ".dds" );
_normal("gear_5", ".jpg", ".dds" );

Any idea why it isn't working?

When loading the game on that interior instead of the textures definited here I see it swapping between:
- black
- a texture of another interior (name it A)
- a texture of another interior (name it B)

Cannot figure out where is the problem...

#1
01/27/2008 (6:10 pm)
Look at the ork materails.cs file and you'll see that this isn't the way TGEA does material...well this isn't the way my scripts look. unless Im missing something;)
#2
01/28/2008 (7:43 am)
Ok, maybe I wasn't to much clear... the first piece of code is the material setup that you can find in "example\demo\data\interiors" that ships with the demo...

The function in it do a really simple material mapping so you don't have to write so much lines of code but only call the function passing the texture file name...

What I'm trying to do it is to extend this script in order to have different functions that will do a more complex material setup...
The reason I'm trying to do this is because I'm simply doing a lot of tests with materials to find the best shader to apply to each texture and changing the materials definition every 2 minutes I'm a bit bored to write everytime the material code and I was trying to find a way to do a material setup in just one line of code as the original script from GG do but with a bit more complexity... :)

Tnx anyway for the reply ;)
#3
01/28/2008 (10:21 am)
@ %name @ %DFext @ ";" @

?????

name and DFext(diffuse name) are the same thing
#4
01/28/2008 (2:50 pm)
DFext is supposed to be the extension of your diffuse texture (IE .jpg or .png) and NMext the extension of the normal texture (IE .dds)... this because I'm used to have the same name for the diffuse and normal textures.. for the diffuse I always use .jpg or .png, for the normal always .dds ...

Obviously I can just change the script and when calling the function pass to it the diffuse texture name and the normal texture file name (using for them different names) ... Yes probably this would have more sense...

i'll try this , I yet had a though that the problem may reside in the concatenation of texture name and extension...

:)
#5
01/28/2008 (4:37 pm)
Ok trying this way but similar (not working) result...

The not working code is:
function matnormal( %DFtex, %NMtex, %dir )
{
   %com = "new CustomMaterial("@%DFtex@") {" @
      "texture[0] = " @ %DFtex @ ";" @
      "texture[1] = " @ %NMtex @ ";" @
      "texture[2] = \"$lightmap\";" @
      "shader = NormalShader;" @
      "mapTo = " @ %DFtex @ ";" @      
      "pixVersion = 2.0;" @
      "specular = \"0.75 0.75 0.75\";" @
      "specularPower = 128.0;" @
   "};";
//   echo(%com);
   eval(%com);
}

matnormal("plate_ground", "plate_ground_NM.dds" );

This way i was trying to setup the material as per this (tested and working) code:
new CustomMaterial(myplate)
{
   texture[0] = "plate_ground.jpg";
   texture[1] = "plate_ground_NM.dds";
   texture[2] = "$lightmap";

   shader = NormalShader;
   mapTo = "plate_ground";
   pixVersion = 2.0;

   specular = "0.75 0.75 0.75";
   specularPower = 128.0;
}
#6
01/28/2008 (4:39 pm)
Uhm... trying again the last piece of code in the previous post I found out it isn't working... but was working just 5 minutes ago...

Ok it's too late, I'll try again tomorrow ...
#7
01/29/2008 (10:27 am)
Ok, after some test and then trying again the "not working" code above it magically do its work...
Maybe something weird in... ok no idea there ! (confused...)

The only reason I use this, as stated above, is to quick test when I'm working on textures... I was bored of write and rewrite the same code for everymaterial I was testing...

EDIT : IT DOESN'T WORK... For some reason it was working for more then 10 times and now doesn't work anymore...

Here is the code:

//************************    INSTRUCTIONS    *************************
//
// Call the function, passing to it parameters in this order :
//
//	  - the diffuse texture filename (without extension!)
//   - the normal texture filename + extension
//
// NOTE! : to use matNormal, matParallax and matRelief functions
// you have to setup the right shaders, take a look at
// http://www.garagegames.com/mg/forums/result.thread.php?qt=36211
//
//*********************************************************************
 
//**********************   FUNCTIONS DEFINITIONS   ********************
 
function matSimple( %DFtex, %NMtex, %dir )
{
   %com = "new Material("@%DFtex@") {" @
      "baseTex[0] = " @ %DFtex @ ";" @
      "mapTo = " @ %DFtex @ ";" @
   "};";
//   echo(%com);
   eval(%com);
}
 
function matBump( %DFtex, %NMtex, %dir )
{
   %com = "new Material("@%DFtex@") {" @
      "baseTex[0] = " @ %DFtex @ ";" @
      "bumpTex[0] = " @ %NMtex @ ";" @
      "pixelSpecular[0] = true;" @
      "specular[0]      = \"0.75 0.75 0.75\";" @
      "specularPower[0] = 128.0;" @
      "mapTo = " @ %DFtex @ ";" @
   "};";
//   echo(%com);
   eval(%com);
}
 
function matNormal( %DFtex, %NMtex, %dir )
{
   %com = "new CustomMaterial("@%DFtex@") {" @
      "texture[0] = " @ %DFtex @ ";" @
      "texture[1] = " @ %NMtex @ ";" @
      "texture[2] = \"$lightmap\";" @
      "shader = NormalShader;" @
      "mapTo = " @ %DFtex @ ";" @      
      "pixVersion = 2.0;" @
      "specular = \"0.75 0.75 0.75\";" @
      "specularPower = 128.0;" @
   "};";
//   echo(%com);
   eval(%com);
}
 
function matParallax( %DFtex, %NMtex, %dir )
{
   %com = "new CustomMaterial("@%DFtex@") {" @
      "texture[0] = " @ %DFtex @ ";" @
      "texture[1] = " @ %NMtex @ ";" @
      "texture[2] = \"$lightmap\";" @
      "shader = ParallaxShader;" @
      "mapTo = " @ %DFtex @ ";" @
      "pixVersion = 2.0;" @
      "specular = \"0.75 0.75 0.75\";" @
      "specularPower = 128.0;" @
   "};";
//   echo(%com);
   eval(%com);
}
 
function matRelief( %DFtex, %NMtex, %dir )
{
   %com = "new CustomMaterial("@%DFtex@") {"@
      "texture[0] = " @ %DFtex @ ";" @
      "texture[1] = " @ %NMtex @ ";" @
      "texture[2] = \"$lightmap\";" @
      "shader = ReliefShader;" @
      "mapTo = " @ %DFtex @ ";" @
      "pixVersion = 3.0;" @
      "specular = \"0.75 0.75 0.75\";" @
      "specularPower = 128.0;" @
   "};";
//   echo(%com);
   eval(%com);
}

//*****   MATERIALS DEFINITIONS   *****
 
// <function name>("<diffuse texture name>", "<normal texture name+extension>"  );
 
matNormal("plate_ground", "plate_ground_NM.dds" );
matParallax("gear_5", "gear_5_NM.dds" );

Bye ;)
#8
01/29/2008 (12:06 pm)
Lavora, lavora :-)
#9
01/29/2008 (12:41 pm)
Ohi ciao!!! Come va? ;)

(sorry guys, a bit of italian there... eheheh)

;P
#10
01/29/2008 (1:10 pm)
Hei Raga !!

Bentornati online ;-)

:-P
#11
01/31/2008 (6:44 am)
Well, this is a bit off from your current code, but why bother sorting through string/parse issues? You don't really need to use the eval command, you could just write a function like this:

function matNormal( %DFtex, %NMtex, %dir )
{

%mat = new CustomMaterial(%DFtex)
{
texture[0] = "" @ %DFtex @ "";
texture[1] = "" @ %NMtex @ "";
texture[2] = "$lightmap";
shader = NormalShader;
mapTo = "" @ %DFtex @ "";
pixVersion = 2.0;
specular = "0.75 0.75 0.75 0.75";
specularPower = 128.0;
};

}
#12
01/31/2008 (7:43 am)
Uhm, I'm really not a programmer as you can see... :P
I tryed this way starting from the script that ship with TGEA in data/interiors folder...
Tested and function well! :)
Eheheh I think you and many other guys on the GG forum should have a paypal account allowing people to donate something when you guys act as a "healtkit" for our headache !!! :D

By the way I really wasn't understand why it wasn't working since putting an echo command before the eval command I ended up having in the console the right statements for the materials definition...

www.spongedpics.com/upload/resized-WZ1201792658W47a1e692784b0-console.gif

Anyway now it works and really you had solved my headache ! :D

Tnx so much ;)

JoZ
#13
01/31/2008 (3:57 pm)
Aha. Looks like it wasn't including the "s after the texture[x] = code. Either way, I like to think the working function is easier to read/modify.
#14
02/01/2008 (5:45 am)
Ehy you're right, I noticed that but I was supposing that's was right and I dunno why... !

Ehehe, yes the function is now much more clear and simple to modify, I yet implemented you ParallaxDL shader... And about that one more question (sorry!) ...

Is it (your ParallaxDL shader) capable of specular and if yes how it takes as specular map, the alpha channel of diffuse or normal texture?
I suppose it is but it seems I can't get it working...

Here is how I setup the material to use ParallaxDL shader...
function matParallaxDL( %DFtex, %NMtex, %dir )
{
   %mat = new CustomMaterial(DynLght)
   {
      texture[0] = "" @ %DFtex @ "";
      texture[1] = "" @ %NMtex @ "";
      texture[2] = "$dynamiclight";
      shader = ParallaxDynamic;
      version = 2.0;
   };
   %mat = new CustomMaterial(%DFtex)
   {
      mapTo = "" @ %DFtex @ "";
      texture[0] = "" @ %DFtex @ "";
      texture[1] = "" @ %NMtex @ "";
      shader = ParallaxDL;
      version = 2.0;
      specular = "0.75 0.75 0.75 0.75";
      specularPower = 128.0;

      dynamicLightingMaterial = DynLght;
   };
}

and another question is, I have to set up the function so that the name of the first material (the one using ParallaxDynamic shader) is unique or it doesn't hurt if it will be overwritten after the material creation (what I suppose will happen when I call 2 times the function for generating 2 materials and the name of the first material in the function is static..)

I hope I'm not wasting to much of your time Matt... ;)
#15
02/01/2008 (7:01 am)
It uses the dot product of the normal map and the view vector. (Technically it's the light vector minus the view vector, but it creates a new vector in the process.)

My ParallaxDL shader set doesn't use specular. You could use the original parallax shader and I believe the lighting shader would work there too.

To answer your other question, maybe setup something like:

function matParallaxDL( %DFtex, %NMtex, %dir )
{
%name = "" @ %DFtex @ "DynLight";
   %mat = new CustomMaterial(%name)
   {
      texture[0] = "" @ %DFtex @ "";
      texture[1] = "" @ %NMtex @ "";
      texture[2] = "$dynamiclight";
      shader = ParallaxDynamic;
      version = 2.0;
   };
   %mat = new CustomMaterial(%DFtex)
   {
      mapTo = "" @ %DFtex @ "";
      texture[0] = "" @ %DFtex @ "";
      texture[1] = "" @ %NMtex @ "";
      shader = ParallaxDL;
      version = 2.0;
      specular = "0.75 0.75 0.75 0.75";
      specularPower = 128.0;

      dynamicLightingMaterial = %name;
   };
}

I think that might work.
#16
02/04/2008 (7:37 am)
Uhm... Ok it doesn't use specular, so I can't understand "It uses the dot product of the normal map and the view vector. (Technically it's the light vector minus the view vector, but it creates a new vector in the process.)
". What it's referred to?

Then with "You could use the original parallax shader and I believe the lighting shader would work there too" do you mean you believe I can use the ParallaxDynamic shader with the Noolness' parallax shader?

Sorry I didn't understood ! :-|

;-)


Tnx ;)
#17
02/04/2008 (4:28 pm)
Quote:
It uses the dot product of the normal map and the view vector. (Technically it's the light vector minus the view vector, but it creates a new vector in the process.)

That's referring to both Nool's shaders and the dynamic lighting one.

Quote:
You could use the original parallax shader and I believe the lighting shader would work there too.

Yes, that's referring to the original parallax shader by Noolness.
#18
02/05/2008 (8:49 am)
Ok, I suppose I can't input the ParallaxDynamic in Nool's parallax with

dynamicLightingMaterial = %name;

so I setup the script in this way, supposing I have to input Texture[2] with ParallaxDynamic...

function matParallaxDLnool( %DFtex, %NMtex, %dir )
{
   %DynLight = "" @ %DFtex @ "DynLight";
      echo(%DynLightName);
      echo("+++++++++++++ NOOL ParallaxDL STAGE 001 +++++++++++++") 
   
   %mat = new CustomMaterial(%DynLightName)   
   {   
      texture[0] = "" @ %DFtex @ "";      
      texture[1] = "" @ %NMtex @ "";      
      texture[2] = "$dynamiclight";      
      shader = ParallaxDynamic;      
      version = 2.0;   
   };   
      echo("+++++++++++++ NoolParallax + DL STAGE 002 +++++++++++++") 
   %mat = new CustomMaterial(%DFtex)   
   {      
      mapTo = "" @ %DFtex @ "";      
      texture[0] = "" @ %DFtex @ "";      
      texture[1] = "" @ %NMtex @ "";  
      // texture[2] = "$lightmap";
      texture[2] = %DynLightName;
      shader = ParallaxShader;      
      pixVersion = 2.0;      
      specular = "0.75 0.75 0.75 0.75";      
      specularPower = 128.0;      
      // dynamicLightingMaterial = %DynLightName;   
   };
      echo("+++++++++++++ NoolParallax + DL STAGE 003 +++++++++++++") 
}

But it seems something is not right... I'll post some screenshot...
#19
02/06/2008 (1:09 pm)
Ok, in the end I tryed to do some cleaning of all and I try to merge your parallax with the Noolness' one...
I really know anything about shaders, but I gave it a try since I saw the differences being minimal...

So I end up with this parallax shaders...

ParallaxP.hlsl :
#define IN_HLSL
#include "../shdrConsts.h"
#include "../lightingSystem/shdrLib.h"
 
struct v2f
{
	float4 hpos     : POSITION;
	float3 eye      : TEXCOORD0;
	float3 light    : TEXCOORD1;
	float2 texcoord : TEXCOORD2;
	float2 lmcoord  : TEXCOORD3;
};
 
float4 main(
	v2f IN,
	uniform sampler2D texmap    : register(S0),
	uniform sampler2D reliefmap : register(S1),
	uniform sampler2D lightmap  : register(S2),
	uniform float4    ambient   : register(PC_AMBIENT_COLOR),
	uniform float4    specular  : register(PC_MAT_SPECCOLOR),
	uniform float     shine     : register(PC_MAT_SPECPOWER)
	) : COLOR
{
	const float3 diffuse  = {1,1,1};
 
   	// view and light directions
	float3 v = normalize(IN.eye);
	float3 l = normalize(IN.light);
 
	float2 uv = IN.texcoord;
 
	// parallax code
	float height = tex2D(reliefmap,uv).w * 0.06 - 0.03;
	uv += height * v.xy;
 
	// normal map
	float4 normal=tex2D(reliefmap,uv);
	normal.xyz=normalize(normal.xyz-0.5);
	normal.y=-normal.y;
	
	// color map
	float4 color=tex2D(texmap,uv);
	
	// light map
	float4 lm = tex2D(lightmap, IN.lmcoord);
 
	// compute diffuse and specular terms
	float diff=saturate(dot(l,normal.xyz));
	float spec=saturate(dot(normalize(l-v),normal.xyz));
	
	// attenuation factor
	float att=1.0-max(0,l.z); att=1.0-att*att;
 
	// compute final color
	float4 finalcolor;
	finalcolor.xyz = ambient*color.xyz +
		att*(color.xyz*diffuse*diff + 
		specular*pow(spec,shine)) *
		lm;
	finalcolor.w=1.0;
 
	return finalcolor;
}

ParallaxV.hlsl :
The only difference is the include of /lightingSystem/shdrLib.h so I added it...

Then for the material setup :
function matParallaxDL( %DFtex, %NMtex, %dir )
{
   %DynLight = "" @ %DFtex @ "PrlxDynLight";
      echo(%DynLight);
      echo("+++++++++++++ ParallaxDL STAGE 001 +++++++++++++"); 
   
   %mat = new CustomMaterial(%DynLight)   
   {   
      texture[0] = "" @ %DFtex @ "";      
      texture[1] = "" @ %NMtex @ "";      
      texture[2] = "$dynamiclight";      
      shader = ParallaxDynLight;      
      version = 2.0;   
   };   
      echo("+++++++++++++ ParallaxDL STAGE 002 +++++++++++++"); 
   %mat = new CustomMaterial(%DFtex)   
   {      
      mapTo = "" @ %DFtex @ "";      
      texture[0] = "" @ %DFtex @ "";      
      texture[1] = "" @ %NMtex @ "";  
      texture[2] = "$lightmap";
      shader = ParallaxShader;      
      pixVersion = 2.0;      
      specular = "0.75 0.75 0.75 0.75";      
      specularPower = 128.0;      
      dynamicLightingMaterial = %DynLight;   
   };
      echo("+++++++++++++ ParallaxDL STAGE 003 +++++++++++++"); 
}

But it seems I can't get the material get the lighting of a light...
(in this case you can see I'm using the simple GreenLight that ships with the TGEA SDK...)

SCREENSHOT :
www.spongedpics.com/upload/resized-WR1202331901W47aa20fd9f992-screenshot_00200001.jpg

I hope I'm not boring you too much Matt, in case at least let me know if I can compensate... (maybe a book about shaders on Amazon? ;) )

TnX ;)
#20
02/06/2008 (1:26 pm)
Ok it seems I made a mistake and I didn't save the material setup with the last changes...
So correcting this it seems that the above code works!

Give me a minute for a screenshot :)

Edit: Here it is...

www.spongedpics.com/upload/resized-WM1202334023W47aa294760c6a-screenshot_00300001.jpg

Another one: you can see both greenlight affecting this .dif and the specular reflections on it...

www.spongedpics.com/upload/resized-WM1202334259W47aa2a334a483-screenshot_00300002.jpg

:)

So to me now it seems ok... if someone note something strange let me know...

@Matt: I think it's quiete ok, really tnx for the help... and my proposal for a little gift is still valid if you wanna profit of it :)


The only think I would see added to this is using the alpha channel of the diffuse (or maybe another texture file?) as a mask for moduling specular like in some parallax shader from Nvidia...

But as said I really know nothing about shaders implementation, so I hope someone would take care about it... Unfortunately for now I'm too busy doing a lot of other stuff (gamedev related and not) and I cannot plan to learn about shaders for now...

If someone would like to see this as a resource let me know, obviously the most of the credit should go to Matt and Noolness for their shader implementation as i just done a very little work to mix them...
I Just put in it a bit of time because of my no-knowledge of many things... :)