Page 1 of 1

HLSL Texture shows up as soild color

Posted: Fri May 20, 2011 4:11 pm
by Buck1000
I'm trying to get texture splatting to work in my application in both the OpenGL and DirectX renderers. I'm having problems with the HLSL code (using http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=26702). The texture shows up as a solid color, which seems to be an average of the overall color of the texture.

I'm relatively new to all of this, so I'm not sure what I'm doing wrong. Even some tutorials would be a major help =]

Here's a screenie of the problem.
Image

Shader code

Code: Select all

float4x4 matViewProjection : ViewProjection; 

sampler2D AlphaMap : register(s0) = sampler_state 
{ 
   ADDRESSU = WRAP; 
   ADDRESSV = WRAP; 
   ADDRESSW = WRAP; 
}; 

sampler2D TextureOne : register(s1) = sampler_state 
{ 
   MipFilter = LINEAR; 
   MinFilter = LINEAR; 
   MagFilter = LINEAR; 
   ADDRESSU = WRAP; 
   ADDRESSV = WRAP; 
   ADDRESSW = WRAP; 
}; 

sampler2D TextureTwo : register(s2) = sampler_state 
{ 
   MipFilter = LINEAR; 
   MinFilter = LINEAR; 
   MagFilter = LINEAR; 
   ADDRESSU = WRAP; 
   ADDRESSV = WRAP; 
   ADDRESSW = WRAP; 
}; 

sampler2D TextureThree : register(s3) = sampler_state 
{ 
   MipFilter = LINEAR; 
   MinFilter = LINEAR; 
   MagFilter = LINEAR; 
   ADDRESSU = WRAP; 
   ADDRESSV = WRAP; 
   ADDRESSW = WRAP; 
}; 

struct VS_INPUT 
{ 
   float4 Position : POSITION0; 
   float2 alphamap : TEXCOORD0; 
   float2 tex : TEXCOORD1; 
}; 

struct VS_OUTPUT 
{ 
   float4 Position : POSITION0; 
   float2 alphamap : TEXCOORD0; 
   float2 tex : TEXCOORD1; 
}; 

struct PS_OUTPUT 
{ 
   float4 diffuse : COLOR0; 
}; 

VS_OUTPUT vs_main( VS_INPUT Input ) 
{ 
   VS_OUTPUT Output; 
   Output.Position = mul( Input.Position, matViewProjection ); 
   Output.alphamap = Input.alphamap; 
   Output.tex = Input.tex; 

   return( Output ); 
} 

PS_OUTPUT ps_main(in VS_OUTPUT input) 
{ 
   static float texScale = 1.0; 	
   PS_OUTPUT output;

   vector a = tex2D(AlphaMap, input.alphamap); 
   vector i = tex2D(TextureOne, mul(input.tex, texScale));
   vector j = tex2D(TextureTwo, mul(input.tex, texScale)); 
   vector k = tex2D(TextureThree, mul(input.tex, texScale)); 

   float4 oneminusx = 1.0 - a.x; 
   float4 oneminusy = 1.0 - a.y; 
   float4 oneminusz = 1.0 - a.z; 

   vector l = a.x * i + oneminusx * i; 
   vector m = a.y * j + oneminusy * l; 
   vector n = a.z * k + oneminusz * m; 

   output.diffuse = n; 

   return output; 
} 

technique Default_DirectX_Effect 
{ 
   pass Pass_0 
   { 
      VertexShader = compile vs_2_0 vs_main(); 
      PixelShader = compile ps_2_0 ps_main(); 
   } 
}
[/size]

Posted: Sat May 21, 2011 4:18 am
by Buck1000
Anyone?

Posted: Sat May 21, 2011 7:41 am
by Radikalizm
Buck1000 wrote:Anyone?
The use of the 'vector' datatype seems strange to me, try to read your textures and do your intermediate color calculations in a float4 type

I don't know whether this is the issue or not, but I haven't encountered the vector typed in HLSL that much before, as far as I know this can contain any amount of scalar components in the range of [1,4] so this could be an issue

I don't immediately see anything wrong in the calculation of your color, although it's pretty early in the morning over here, so maybe I'm overlooking something, I'll give it another look later today

Posted: Sat May 21, 2011 7:47 am
by Buck1000
I tried changing that too, but the result is the same. The shader is copied and pasted from examples that use it, and work with it perfectly fine. I can run them too, so I know my video card supports it. Did something change between the past and current versions of irrlicht? I'll try an older library version.

Posted: Sat May 21, 2011 7:49 am
by Radikalizm
Buck1000 wrote:I tried changing that too, but the result is the same. The shader is copied and pasted from examples that use it, and work with it perfectly fine. I can run them too, so I know my video card supports it. Did something change between the past and current versions of irrlicht? I'll try an older library version.
Could you maybe post code on how you're loading this shader in irrlicht?


EDIT:

This line doesn't seem right:

Code: Select all

vector l = a.x * i + oneminusx * i; 
this would be the same as saying (a.x + oneminusx) * i, which equals 1.0 * i

Should be:

Code: Select all

vector l = a.x * i; 

Posted: Sat May 21, 2011 8:28 am
by Buck1000
Changing that line to

Code: Select all

vector l = a.x * i;
doesn't change anything in the output. I tried

Code: Select all

output.diffuse = (mul(a.x, i) + mul(a.y, j) + mul(a.z, k));
and now I've got some more detail... =D But, the problem remains.
Image

Here's the code that loads the shader

This comes before my main function

Code: Select all

bool UseHighLevelShaders = true;

class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:
        virtual void OnSetConstants(video::IMaterialRendererServices* services,
                        s32 userData)
        {
                video::IVideoDriver* driver = services->getVideoDriver();
                // set clip matrix
                core::matrix4 worldViewProj;
                worldViewProj = driver->getTransform(video::ETS_PROJECTION);
                worldViewProj *= driver->getTransform(video::ETS_VIEW);
                worldViewProj *= driver->getTransform(video::ETS_WORLD);
                if (UseHighLevelShaders)
                        services->setVertexShaderConstant("matViewProjection", worldViewProj.pointer(), 16);
                else
                        services->setVertexShaderConstant(worldViewProj.pointer(), 4, 4);
		}
};
And this is further down

Code: Select all

if(DX)
    {
        io::path vsFileName = "Dx_Shader.hlsl";
        io::path psFileName = "Dx_Shader.hlsl";

        video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();

        if (gpu)
        {
                MyShaderCallBack* mc = new MyShaderCallBack();
                if (UseHighLevelShaders)
                {
                        newMaterialType = gpu->addHighLevelShaderMaterialFromFiles(
                                vsFileName, "vs_main", video::EVST_VS_2_0,
                                psFileName, "ps_main", video::EPST_PS_2_0,
                                mc, EMT_DETAIL_MAP);
                }
                mc->drop();
        }
    }

	Map->getTerrain()->setMaterialTexture(1,driver->getTexture(".\\Media\\Textures\\gravel.jpg"));
	Map->getTerrain()->setMaterialTexture(2,driver->getTexture(".\\Media\\Textures\\grass.jpg"));
	Map->getTerrain()->setMaterialTexture(3,driver->getTexture(".\\Media\\Textures\\dirt.jpg"));
	Map->getTerrain()->setMaterialTexture(0,driver->getTexture(".\\Media\\Terrains\\splat_map.jpg"));

	if(DX)
        Map->getTerrain()->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType);

Posted: Sat May 21, 2011 9:13 am
by nespa
try with :

EMT_TRANSPARENT_ALPHA_CHANNEL

no :

EMT_DETAIL_MAP


and use the splat_map as .tga file, with alpha channel color

Posted: Sat May 21, 2011 4:34 pm
by Buck1000
I tried that too, know change =/ It looks worse that way, since parts of the terrain actually go transparent. The shader is meant to work with EMT_Detail_Map. I tried EMT_Solid, and its the same thing...

Posted: Sat May 21, 2011 4:38 pm
by Radikalizm
What's the size of the textures you're using, and how are your UV-coordinates laid out?

Posted: Sat May 21, 2011 4:53 pm
by Buck1000
The splatter map is 512x512, and the individual textures are 256x256. I uv-mapped the terrain in LithUnwrap, and then just painted the individual colors onto the map in gimp. Heres the actual splatter map..
Image

And the uv map that LithUnwrap outputs..
Image

Keep in mind that its not as blurry as it appears above. Converting a tga to a jpeg does that. The working copy of it is perfectly sharp.

The problem can't be the textures though, because this works perfectly using the OpenGL renderer and shader...
Image

Posted: Sat May 21, 2011 5:50 pm
by nespa
my HLSL shader is working with EMT_TRANSPARENT_ALPHA_CHANNEL