Basic Custom Material Not Mapping Correctly
by Ben McIntosh · in Torque Game Engine Advanced · 04/26/2009 (10:45 am) · 5 replies
I'm quite new to TGEA and HLSL, but could someone take a quick look at this code and let me know if there is something blatantly obvious that I'm doing wrong?
I'm just trying to add a basic custom material to the default "Elf" model in order to make a custom shader later. Here is what I have:
client/scripts/shaders.cs
shaders/testV.hlsl
shaders/testP.hlsl
data/shapes/players/Elf/materials.cs
And here is the result I get:

The texture is being loaded in but the mapping coordinates get all messed up somehow. What is also strange is that it does not matter what index I use for texture[x] or TEXCOORDX. I always get the same result. Any help would be appreciated.
I'm just trying to add a basic custom material to the default "Elf" model in order to make a custom shader later. Here is what I have:
client/scripts/shaders.cs
new ShaderData( TestShader )
{
DXVertexShaderFile = "shaders/testV.hlsl";
DXPixelShaderFile = "shaders/testP.hlsl";
pixVersion = 2.0;
};shaders/testV.hlsl
#define IN_HLSL
#include "shdrConsts.h"
float4x4 view_proj_matrix : register(VC_WORLD_PROJ);
struct VS_INPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
};
VS_OUTPUT main( VS_INPUT Input )
{
VS_OUTPUT Output;
Output.Position = mul( Input.Position, view_proj_matrix );
Output.Texcoord = Input.Texcoord;
return( Output );
}shaders/testP.hlsl
sampler2D baseMap: register(s0);
struct PS_INPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
};
float4 main( PS_INPUT Input ) : COLOR0
{
return tex2D( baseMap, Input.Texcoord );
}data/shapes/players/Elf/materials.cs
new CustomMaterial(ElfSorceress)
{
mapTo = "ElfSorceress";
texture[0] = "~/data/shapes/players/Elf/ElfSorceress.dds";
shader = TestShader;
version = 2.0;
};And here is the result I get:

The texture is being loaded in but the mapping coordinates get all messed up somehow. What is also strange is that it does not matter what index I use for texture[x] or TEXCOORDX. I always get the same result. Any help would be appreciated.
About the author
Ben is the co-founder of Urban Brain Studios; a new independent developer of games and game development tools.
#2
1) You need to make your matrix a parameter to your vertex shader, and you need to name it modelview.
2) You need to reverse your modelview transform, matrix first and position second.
i.e.:
The first issue is because with TGEA 1.8.1, constant buffers are used to set the constants by name rather than register, and the second issue is because of the way TGEA handles the camera/view.
Setting samplerNames[0] = "$diffuseMap"; is a good practice to get into, as you'll need to set the sampler names if you use multiple samplers in GLSL, but it's not strictly necessary for HLSL as long as your samplers are in the same order in the shader as they are specified in the material data.
04/26/2009 (4:33 pm)
Assuming you're using TGEA 1.8.1, there's 2 problems with your vertex shader.1) You need to make your matrix a parameter to your vertex shader, and you need to name it modelview.
2) You need to reverse your modelview transform, matrix first and position second.
i.e.:
#define IN_HLSL
#include "shdrConsts.h"
struct VS_INPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
};
//modelview as a VS parameter
VS_OUTPUT main( VS_INPUT Input, uniform float4x4 modelview )
{
VS_OUTPUT Output;
//matrix first, position second
Output.Position = mul( modelview, Input.Position );
Output.Texcoord = Input.Texcoord;
return( Output );
}The first issue is because with TGEA 1.8.1, constant buffers are used to set the constants by name rather than register, and the second issue is because of the way TGEA handles the camera/view.
Setting samplerNames[0] = "$diffuseMap"; is a good practice to get into, as you'll need to set the sampler names if you use multiple samplers in GLSL, but it's not strictly necessary for HLSL as long as your samplers are in the same order in the shader as they are specified in the material data.
#3
Thanks so much for your help, it's working great now. Could you point me to where the constants names are defined because I don't remember seeing that. I also plan to use the VC_EYE_POS and VC_LIGHT_DIR1 registers, so do those have defined names as well now in 1.8.1?
As a side question, do you know if 1.8.1 natively supports multiple pass shaders with render-to-texture steps? I remember reading a forum post where someone was able to do this but had to make significant modifications to the source.
Thanks,
Ben
EDIT: From looking at the example shaders it looks like what I am looking for are "inLightVec" and "eyePos". That's great, but is this officially documented somewhere?
04/26/2009 (10:22 pm)
Hi Gerald,Thanks so much for your help, it's working great now. Could you point me to where the constants names are defined because I don't remember seeing that. I also plan to use the VC_EYE_POS and VC_LIGHT_DIR1 registers, so do those have defined names as well now in 1.8.1?
As a side question, do you know if 1.8.1 natively supports multiple pass shaders with render-to-texture steps? I remember reading a forum post where someone was able to do this but had to make significant modifications to the source.
Thanks,
Ben
EDIT: From looking at the example shaders it looks like what I am looking for are "inLightVec" and "eyePos". That's great, but is this officially documented somewhere?
#4
No problem. And no, TGEA does not support multi-pass shaders out of the box, but you can implement the process yourself in code. You'll need to spend some time studying the GFX render system to get going with that. Torque 3D will have much better support for this type of thing, but it's a hack-it-yourself deal in TGEA.
As far as I know there's no official documentation detailing the shader constants, but if you look in shaderGen/shaderGenVars.cpp in the engine source you should be able to figure out most of the ones that are setup by the base engine code. If you setup some custom rendering or extend the MatInstance class you can provide your own constants with the constants buffers as well.
Cheers,
Gerald
04/26/2009 (11:33 pm)
Ben,No problem. And no, TGEA does not support multi-pass shaders out of the box, but you can implement the process yourself in code. You'll need to spend some time studying the GFX render system to get going with that. Torque 3D will have much better support for this type of thing, but it's a hack-it-yourself deal in TGEA.
As far as I know there's no official documentation detailing the shader constants, but if you look in shaderGen/shaderGenVars.cpp in the engine source you should be able to figure out most of the ones that are setup by the base engine code. If you setup some custom rendering or extend the MatInstance class you can provide your own constants with the constants buffers as well.
Cheers,
Gerald
#5
04/26/2009 (11:46 pm)
Excellent, thanks again for the help!
Torque Owner Jeremiah Fulbright
samplerNames[0] = "$diffuseMap";