Sign in to follow this  

Shader always returns white

This topic is 1109 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm trying to do some simple D3D9 rendering.

 

Problem is, with the shader below, the output on screen is always white even though I'm clearly telling it to return blue

float4x4 gWorld : WORLD;
float4x4 viewProj : VIEWPROJECTION;
 
 // Vertex Shader
float4 vs( float3 pos : POSITION ) : POSITION
{
    float4 output;
 
    output = mul( float4( pos.xyz,1 ), gWorld );
    output = mul( float4( output.xyz,1 ),viewProj );
 
    return output;
}
 
// Pixel Shader
float4 ps( float4 pos : POSITION ) : COLOR
{
    // Returning blue, but getting white?
    return float4( 0,0,1,1 );
}

this problem doesn't occur if I simply add another semantic to the vertex shader input, then it returns whatever color I want.

 

The object is drawn correctly ( cube in this case ) just the wrong color unless I pass the vertex shader more than just the position.

 

I'll post c++ code if it's needed.  

 

 

EDIT:

I actually found it it will only apply the color the way it should ONLY if I pass the color through vertices.  Continuing to debug...

 

 

EDIT AGAIN:

It seems that the pixel shader isn't even getting called.  Any color I return from the vertex shader will be the color used assuming that I have the COLOR semantic on it, and if no color is returned the color is white.

// This is how I load the shader, not sure where to go from here.  But I'll google some more
 
D3D9* d3d = CEngine::getD3D9();
D3DXCreateEffectFromFileA( d3d->getDevice(),"Assets/Shaders/SimpleShader.fx",0,0,0,0,&shader,0 );
Edited by Muzzy A

Share this post


Link to post
Share on other sites

Effect ? Is this the whole shader source ? No technique/pass ? How do you apply the pass or shaders?  FFP pixel  shader active instead of yours ? D3D debug log good ?

 

Anyway debug one such white pixel with PIX, then you can find out exactly what's happening (compile shader with debug enabled).

 

And yeah, showing more code would help greatly, please.

Share this post


Link to post
Share on other sites

// This is how I load the shader,


That doesn't "load" the shader. As the name of the function implies, it creates an instance of ID3DXEffect.

 

As unbird mentions, (much) more information is needed. In particular, are you trying to compile, set and use vertex and pixel shaders themselves (IDirect3dVertexShader9, IDirect3dPixelShader9), or are you trying to compile and use an instance of ID3DXEffect to render something?

 

EDIT: As it appears you have a HLSL vertex/pixel shader file you're trying to use, I'd suggest (assuming you have the DX SDK June 2010 installed) you work through some of the example solutions in that SDK (located in the (DXSDK)/Samples/C++/Direct3D folder). Several of them demonstrate how to create an effect from a file, set techniques and parameters (such as the world/view/projection matrices), and render objects within an effect Begin/BeginPass-EndPass/End loop.

 

Also, N.B. D3DX functions return an HRESULT value, which indicates the success or failure of the function call. Check those return values! The easiest way is to use the SUCCEEDED(hr) and FAILED(hr) macros. Handle errors gracefully - don't assume your code will execute correctly.

Edited by Buckeye

Share this post


Link to post
Share on other sites

This shader code looks strange to me in parts, if this is the full code then there's something missing. You need at least one technique and one pass.

 

Take  look at my shader here for comparison. It has 2 techniques with 1 pass each. One runs lighting calculation while the other doesn't.

float4x4 WorldViewProjection;
float4x4 WorldInverseTranspose;
 
float4 AmbientColor = float4(1, 1, 1, 1);
float AmbientIntensity = 0.2;
 
float3 DiffuseLightDirection = float3(1, 1, 1);
float4 DiffuseColor = float4(1, 1, 1, 1);
float DiffuseIntensity = 0.9;
 
float Shininess = 50;
float4 SpecularColor = float4(1, 1, 1, 1);
float SpecularIntensity = 0.33;
float3 ViewVector = float3(1, 0, 0);
 
Texture2D Texture;

SamplerState textureSampler;
 
struct VertexShaderInput
{
    float4 Position : SV_POSITION0;
    float4 Normal : NORMAL0;
    float2 TextureCoordinate : TEXCOORD0;
};
 
struct VertexShaderOutput
{
    float4 Position : SV_POSITION0;
    float4 Color : COLOR0;
    float3 Normal : TEXCOORD0;
    float2 TextureCoordinate : TEXCOORD1;
};
 
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;
 
	output.Position = mul(input.Position, WorldViewProjection);
 
    float4 normal = normalize(input.Normal);
    float lightIntensity = dot(normal, DiffuseLightDirection);
    output.Color = saturate(DiffuseColor * DiffuseIntensity * lightIntensity);
 
    output.Normal = normal;
 
    output.TextureCoordinate = input.TextureCoordinate;
    return output;
}
 
VertexShaderOutput VertexShaderStarsphere(VertexShaderInput input)
{
	VertexShaderOutput output;

	output.Position = mul(input.Position, WorldViewProjection);

	output.TextureCoordinate = input.TextureCoordinate;
	return output;
}

float4 PixelShaderFunction(VertexShaderOutput input) : SV_TARGET0
{
    float3 light = normalize(DiffuseLightDirection);
    float3 normal = normalize(input.Normal);
    float3 r = normalize(2 * dot(light, normal) * normal - light);
    float3 v = normalize(mul(normalize(ViewVector), WorldViewProjection));
    float dotProduct = dot(r, v);
 
    float4 specular = SpecularIntensity * SpecularColor * max(pow(abs(dotProduct), Shininess), 0) * length(input.Color);
 
		float4 textureColor = Texture.Sample(textureSampler, input.TextureCoordinate);
    textureColor.a = 1;
 
    return saturate(textureColor * (input.Color) + AmbientColor * AmbientIntensity + specular);
}

float4 PixelShaderStarsphere(VertexShaderOutput input) : SV_TARGET0
{
	float4 textureColor = Texture.Sample(textureSampler, input.TextureCoordinate);
	textureColor.a = 1;

	return textureColor;
}
 
technique Textured
{
    pass Pass1
    {
		AlphaBlendEnable = TRUE;
        DestBlend = INVSRCALPHA;
        SrcBlend = SRCALPHA;
        VertexShader = compile vs_4_0 VertexShaderFunction();
        PixelShader = compile ps_4_0 PixelShaderFunction();
    }
}

technique Starsphere
{
	pass Pass1
	{
		VertexShader = compile vs_4_0 VertexShaderStarsphere();
		PixelShader = compile ps_4_0 PixelShaderStarsphere();
	}
};

Share this post


Link to post
Share on other sites

The technique is fine, I didn't post it as it's quite unnecessary.  It uses version 3.0.

 

The HRESULT returns SUCCESS, already been there done that before I made the post.

 

Here is where I actually render the object

// The technique
technique Tech
{
    pass pass1
    {
        vertexShader = compile vs_3_0 vs();
        pixelShader  = compile ps_3_0 ps();
 
        CullMode = CCW;
        FillMode = Solid;
    }
}
 
// Rendering
IDirect3DDevice9* device = CEngine::getD3D9()->getDevice();  
 
unsigned passes = 0;  
 
pShader->Begin( &passes,0 );  
 
pShader->SetMatrix( "gWorld",&worldMatrix);   // Pass the world matrix
pShader->SetMatrix( "viewProj",&(cam * proj) ); // Pass the View and Projection  
pShader->CommitChanges();  
 
device->SetVertexDeclaration( _pVertDecl );
device->SetStreamSource( 0,_pVertBuff,0,_nVertStride );  
 
for( unsigned i = 0;i < passes;++i )
{    
    pShader->BeginPass( i );      
 
    device->DrawPrimitive( D3DPT_TRIANGLELIST,0,_nNumVerts/3 );
 
    pShader->EndPass();
}  
 
pShader->End();

Initializing

D3DVERTEXELEMENT9 decl[] =
{
    { 0,0,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION,0 },
    { 0,12,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_NORMAL,0 },
    D3DDECL_END()
};
 

unsigned vertSize = nNumVerts * nVertexSize;
 
device->CreateVertexBuffer( vertSize,0,0,D3DPOOL_DEFAULT,&_pVertBuff,0 );
device->CreateVertexDeclaration( decl,&_pVertDecl );
 
void* vram = nullptr;
 
_pVertBuff->Lock( 0,0,&vram,0 );
memcpy( vram,verts,vertSize );
_pVertBuff->Unlock();
 
 
// The actual verts in case you want to see that
 
// CUBE

float size = fWidth/2;
 
VERTEX_POSNORM verts[] =
{
    { Vector3( -size, size,-size ), Vector3(  0, 0,-1 ) }, // 0 Front Top Left
    { Vector3(  size, size,-size ), Vector3(  0, 0,-1 ) }, // 1 Front Top Right
    { Vector3(  size,-size,-size ), Vector3(  0, 0,-1 ) }, // 2 Front Bottom Right
    { Vector3(  size,-size,-size ), Vector3(  0, 0,-1 ) }, // 2 Front Bottom Right
    { Vector3( -size,-size,-size ), Vector3(  0, 0,-1 ) }, // 3 Front Bottom Left
    { Vector3( -size, size,-size ), Vector3(  0, 0,-1 ) }, // 0 Front Top Left
 
    { Vector3( -size, size, size ), Vector3(  0, 0, 1 ) }, // 4 Back Top Left
    { Vector3( -size,-size, size ), Vector3(  0, 0, 1 ) }, // 7 Back Bottom Left
    { Vector3(  size,-size, size ), Vector3(  0, 0, 1 ) }, // 6 Back Bottom Right
    { Vector3(  size,-size, size ), Vector3(  0, 0, 1 ) }, // 6 Back Bottom Right
    { Vector3(  size, size, size ), Vector3(  0, 0, 1 ) }, // 5 Back Top Right
    { Vector3( -size, size, size ), Vector3(  0, 0, 1 ) }, // 4 Back Top Left
 
    { Vector3( -size, size, size ), Vector3( -1, 0, 0 ) }, // 4 Back Top Left
    { Vector3( -size, size,-size ), Vector3( -1, 0, 0 ) }, // 0 Front Top Left
    { Vector3( -size,-size,-size ), Vector3( -1, 0, 0 ) }, // 3 Front Bottom Left
    { Vector3( -size,-size,-size ), Vector3( -1, 0, 0 ) }, // 3 Front Bottom Left
    { Vector3( -size,-size, size ), Vector3( -1, 0, 0 ) }, // 7 Back Bottom Left
    { Vector3( -size, size, size ), Vector3( -1, 0, 0 ) }, // 4 Back Top Left
 
    { Vector3(  size, size,-size ), Vector3(  1, 0, 0 ) }, // 1 Front Top Right
    { Vector3(  size, size, size ), Vector3(  1, 0, 0 ) }, // 5 Back Top Right
    { Vector3(  size,-size, size ), Vector3(  1, 0, 0 ) }, // 6 Back Bottom Right
    { Vector3(  size,-size, size ), Vector3(  1, 0, 0 ) }, // 6 Back Bottom Right
    { Vector3(  size,-size,-size ), Vector3(  1, 0, 0 ) }, // 2 Front Bottom Right
    { Vector3(  size, size,-size ), Vector3(  1, 0, 0 ) }, // 1 Front Top Right
 
    { Vector3( -size, size,-size ), Vector3(  0, 1, 0 ) }, // 0 Front Top Left
    { Vector3( -size, size, size ), Vector3(  0, 1, 0 ) }, // 4 Back Top Left
    { Vector3(  size, size, size ), Vector3(  0, 1, 0 ) }, // 5 Back Top Right
    { Vector3(  size, size, size ), Vector3(  0, 1, 0 ) }, // 5 Back Top Right
    { Vector3(  size, size,-size ), Vector3(  0, 1, 0 ) }, // 1 Front Top Right
    { Vector3( -size, size,-size ), Vector3(  0, 1, 0 ) }, // 0 Front Top Left
 
    { Vector3( -size,-size,-size ), Vector3(  0,-1, 0 ) }, // 3 Front Bottom Left
    { Vector3(  size,-size,-size ), Vector3(  0,-1, 0 ) }, // 2 Front Bottom Right
    { Vector3(  size,-size, size ), Vector3(  0,-1, 0 ) }, // 6 Back Bottom Right
    { Vector3(  size,-size, size ), Vector3(  0,-1, 0 ) }, // 6 Back Bottom Right
    { Vector3( -size,-size, size ), Vector3(  0,-1, 0 ) }, // 7 Back Bottom Left
    { Vector3( -size,-size,-size ), Vector3(  0,-1, 0 ) }, // 3 Front Bottom Left
};
 


Edited by Muzzy A

Share this post


Link to post
Share on other sites

That didn't change anything, it still returns only white.  I've updated the shader since I first posted it so I'll just re-post it here, but I highly doubt the shader is the problem.

float4x4 gWorld : WORLD;
float4x4 viewProj : VIEWPROJECTION;
 
float4 gColor;
float3 gLightPos = float3( 6,4,-5 );
 
struct VS_IN
{
    float4 pos : POSITION;
    float3 norm : NORMAL;
};
struct VS_OUT
{
    float4 pos : POSITION;
    //float4 color : COLOR;
};
 
VS_OUT vs( VS_IN input )
{
    // Positions
    float3 world = mul( float4( input.pos.xyz,1 ), gWorld ).xyz;
    float4 pos = mul( float4( world,1 ),viewProj );
 
    // Normals
    float3 norm = normalize( mul( float4( input.norm,0 ), gWorld ).xyz );
    float3 ldir = normalize( gLightPos - world );
 
    // Amount of light hitting the vertex
    float scale = saturate( dot( ldir,norm ) );
 
    // Save
    VS_OUT output;
    output.pos = pos;
    //output.color = float4( gColor.rgb * scale,gColor.a  );
 
    return output;
}
 
float4 ps( VS_OUT input ) : COLOR
{ 
/*
    float3 ldir = normalize( gLightPos - input.world );
    float3 norm = normalize( input.norm );
 
    float scale = saturate( dot( ldir,norm ) );
 
    input.color.xyz *= scale;
    return float4( input.color.xyz,intput.a );
*/
    return float4( 0,1,0,1 );
}
 
technique Tech
{
    pass pass1
    {
        vertexShader = compile vs_3_0 vs();
        pixelShader  = compile ps_3_0 ps();
 
        CullMode = CCW;
        //FillMode = Solid;
    }
}

Here is the result

 

shader_example.png

 

 

 

 

EDIT:

static volatile const unsigned long long var[5];
 
// ^^ WIN!!

Got bored lol

Edited by Muzzy A

Share this post


Link to post
Share on other sites

FFP pixel shader active instead of yours ? ... debug one such white pixel with PIX, then you can find out exactly what's happening (compile shader with debug enabled).

 

unbird posted an indication of what may be your problem a week ago, which you apparently decided to ignore. I.e., "all white" is an indication that the object is probably being rendered with the FFP pixel shader, not your shader. Did you try his suggestion of using PIX to see if your effect is, in fact, what's being used to render your object?

 

Because you indicate your technique is "fine," and you don't post code you feel is "unnecessary," there's no way to tell, but it still appears you're not setting the technique properly, or, as may be the case, at all. You may want to take a look at the docs for ID3DXEffect::SetTechnique, or, as previously suggested, take a look at some of the examples in the DX SDK for comparison, to see if you are, in fact, setting the technique properly.

Edited by Buckeye

Share this post


Link to post
Share on other sites

Please don't be condescending, I'm trying to get help.  I never post all of my code at once, I try to keep the problem as simple as I possibly can so I can get as much help as possible.  Nobody likes to look at a HUGE wall of code to help with what might simply be a typo when rendering or making the shader =).

 

PIX hasn't been working well for me,  whether I have the Direct X debugging tools turned on or not.  It becomes an annoyance to mess with and get it to work correctly, which is why I've gotten lazy with using PIX lately. I'm trying again though, will reply with my result.

Edited by Muzzy A

Share this post


Link to post
Share on other sites


Please don't be condescending,

 

Acknowledged.

 


I'm trying to get help ... as much help as possible

 

Then a suggestion: acknowledge responses, perhaps with something other than "been there done that" or something is "fine," which seems rather condescending.

 

Having exchanged shots across the bow, did you set the technique properly?

Share this post


Link to post
Share on other sites

OK So trying to set the Technique gives me D3DERR_INVALIDCALL.

 

I can't find anything helpful on google, but I'm continuing to look.  Also, it keeps crashing in PIX when creating the ID3DXEffect.  Looking into that as well.

// Returns D3DERR_INVALIDCALL
HRESULT hr = pShader->SetTechnique( "Tech" );
HRESULT hr = pShader->SetTechnique( pShader->GetCurrentTechnique() );
 

D3DXTECHNIQUE_DESC desc;
pShader->GetTechniqueDesc( pShader->GetCurrentTechnique(),&desc );
 
// 'desc' output is
// desc.name = "Tech"
// desc.passes = 1
// desc.annotations = 0
 
// Again here's the shader code
// SimpleShader.fx

float4x4 gWorld : WORLD;
float4x4 viewProj : VIEWPROJECTION;
 
float4 gColor;
float3 gLightPos = float3( 6,4,-5 );
 
struct VS_IN
{
    float4 pos : POSITION;
    float3 norm : NORMAL;
};
struct VS_OUT
{
    float4 pos : POSITION;
    //float4 color : COLOR;
};
 
VS_OUT vs( VS_IN input )
{
    // Positions
    float3 world = mul( float4( input.pos.xyz,1 ), gWorld ).xyz;
    float4 pos = mul( float4( world,1 ),viewProj );
 
    // Normals
    float3 norm = normalize( mul( float4( input.norm,0 ), gWorld ).xyz );
    float3 ldir = normalize( gLightPos - world );
 
    // Amount of light hitting the obj
    float scale = saturate( dot( ldir,norm ) );
 
    // Save
    VS_OUT output;
    output.pos = pos;
    //output.color = float4( gColor.rgb * scale,gColor.a  );
 
    return output;
}
 
float4 ps( VS_OUT input ) : COLOR
{ 
    return float4( 0,1,0,1 );
}
 
technique Tech
{
    pass pass1
    {
        VertexShader = compile vs_3_0 vs();
         PixelShader  = compile ps_3_0 ps();
 
        CullMode = CCW;
        //FillMode = Solid;
    }
}


Edited by Muzzy A

Share this post


Link to post
Share on other sites

PROBLEM SOLVED

 

My graphics card doesn't support version 3.0 pixel shaders, had to use version 2.0.  I was looking up reasons why ID3DXEffect::ValidateTechnique() would fail and found a topic on here that led me to test the version I'm using.  3.0 works with the vertex shader however... I guess I better put it down to 2.0 just to be safe, just have to be careful with how many calculations I perform.

 

Before I made this topic I thought about changing those down to 2.0 to see if it worked... I should have done it, but I assumed this computer was new enough to be aware of version 3.0, assumptions can cause problems.  Lesson learned.

Edited by Muzzy A

Share this post


Link to post
Share on other sites

This topic is 1109 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this