HLSL: simple shader is returning solid colour when it shouldn't (SOLVED)

Started by
8 comments, last by g9icy 14 years, 10 months ago
Hi all, I'm entering into the world of HLSL. Got a simple pixel shader atm that looks like the following (a segment):

float4 main(float4 Tex : TEXCOORD0) : COLOR0
{
    float4 Color;
    
    Color = tex2D( source, Tex.xy );
    
    return Color;
}


As is my understanding, this should simply pass all the original colour data directly out of the pixel shader, and the resulting image should be identical to the original data fed in. The problem is, that it just returns a solid colour, which varies depending on the texture fed to the simple tri-based rectangle i'm using as a test. Some info on how I set things up: I have no vertex shaders setup (is one required?). There's no vertex buffers used, I draw with DrawPrimitiveUP, which is temporary as I just want something on the screen first. I've ensured that the texture coords are correct. I'm using shaders 3.0 in DirectX 9.0c (nov), and I have an 8800GT. And...that's it really... Thanks, -g9 [Edited by - g9icy on May 30, 2009 12:48:09 PM]
Advertisement
Hi, typically texture coordinates are of the float2 data type.

1. You don't have to have a vertex shader, many post processes require just the pixel shader, and render to a full screen quad.

2. If you're wanting to render geometry you will need a vertex shader to transform the verticies. The minimum requirement for a vertex shader is to write all four components POSITION, without this, you won't see anything of your mesh.
Hi,

Sorry, the float4 was me fiddling with things to see if anything changed, it's been returned back to float2 since I posted the code, and ran with the same problems.

I don't require a vertex shader at the moment, I just wanted to clarify if one was required and my lack of definition was causing my problem.

No other ideas as to why this could be returning one block of solid colour?

Here's a slightly simplified copy of my setup code:

// Executed in the "initialisation" stage of my code...if (D3DXCreateTextureFromFileEx( dx.Device(), "pic.jpg",  D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, NULL, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_DEFAULT,D3DX_DEFAULT, 0, NULL, NULL, &texture ) != D3D_OK)assert(texture);dx.Device()->SetTexture(0, texture);rect.CreateTriRect(point<float>(1.0f, 1.0f)); // my custom code						LPD3DXBUFFER pShader = NULL, errors = NULL;D3DXCompileShaderFromFile("shader.psh", NULL, NULL, "main", "ps_3_0", NULL, &pShader, &errors, NULL);// Error checking heredx.Device()->CreatePixelShader((DWORD*)pShader->GetBufferPointer(), &psh);dx.Device()->SetPixelShader(psh);// Render elsewhere...


[Edited by - g9icy on May 30, 2009 4:46:29 AM]
Hey, could you post the render code in your main app? Here's an example of what seems to work fine when drawing a full screen quad (mapping texels to pixels):



// this binds the s0 register to the name s0 sampler s0 : register(s0);float4 ExamplePixelShader(in float2 vScreenPosition : TEXCOORD0) : COLOR0{     float4 Colour = tex2D(s0, vScreenPosition);     return Colour}


you will have to set the texture with device.SetTexture(0, pTexture), if you would rather use Effect.SetTexture()/SetValue, then the below would be more appropriate:

texture Texture;sampler diffuseSampler = sampler_state{    Texture = (Texture);    MAGFILTER = LINEAR;    MINFILTER = LINEAR;    MIPFILTER = LINEAR;    AddressU = Wrap;    AddressV = Wrap;};float4 ExamplePixelShader(in float2 vScreenPosition : TEXCOORD0) : COLOR0{    float4 Colour;    Colour = tex2D(diffuseSampler, vScreenPosition);    return Colour;}


Hope that helps
Hi,

In my second post I set the texture:

dx.Device()->SetTexture(0, texture);


My render code is literally one line at the moment:

dx.Device()->DrawPrimitiveUP(D3DPT_TRIANGLELIST, m.size()/3, m.vertices(), sizeof(Vertex));


"m" being my custom model object.

I didn't see the need to SetTexture and SetPixelShader each frame, as there's no other objects besides the one model i'm trying to render.

For completeness, here's the full shader text file:

sampler2D source : register(s0);float4 main(in float2 Tex : TEXCOORD0) : COLOR0{    float4 Color = tex2D( source, Tex.xy );        return Color;}
How are you producing your texture coordinates? It sounds like your shader is sampling from the same pixel in your texture for every pixel.
It does seem that way, given the colours in the original image.

// Elsewhere: the FVF:dx.Device()->SetFVF(D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1);// "Rect" creation code...Texture comes out fine with shaders off// dim=dimensions, p="position" (xyz), t = UV_vertices[0].p = Vector3(dim.x, -dim.y, 0);_vertices[0].t = point<float>(1.0f,1.0f);_vertices[1].p = Vector3(-dim.x, -dim.y, 0);_vertices[1].t = point<float>(0,1.0f);_vertices[2].p = Vector3(dim.x, dim.y, 0);_vertices[2].t = point<float>(1.0f,0);_vertices[3] = _vertices[2];_vertices[4] = _vertices[1];_vertices[5].p = Vector3(-dim.x, dim.y, 0);_vertices[5].t = point<float>(0, 0);for (unsigned int i=0; i < size(); ++i)	_vertices.n = Vector3(0, 0, -1.0f);
I'd advise you use vertex declarations rather than FVF's which can be a little more complicated to use with programable pipeline.
I've now got a vertex declaration going:

const D3DVERTEXELEMENT9 dec[4] ={{0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,0},{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,  0},{0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,0},D3DDECL_END()};			dx.Device()->CreateVertexDeclaration(dec, &d);dx.Device()->SetVertexDeclaration(d);


In my "initialisation" function...

Same problem exists.

The declaration matches my vertex object members exactly.
Thanks All for your help.

It turns out, after running it with DirectX in debug mode, I had to create a vertex shader to match the pixel shader, both using SM3.0.

When using 2.0, my code ran fine as intended without the vertex shader.

This topic is closed to new replies.

Advertisement