Why does this .fx shader not work with a newer vid card?

i’m not a shader guy, so my pre-apologies for ignorance but…

using this vertex blend shader in max 2010 with GeForce 8600 GT, everything renders in the viewport fine. however, we have one machine with a newer card, a GeForce 9800 GTX that the shader doesn’t work properly with. it renders in the viewport, but the first texture displays white.

hoping one of you shader guys can take a look & see if there’s something i’m missing or give me some pointers on how to fix it.

thx!

Does it give you any errors ?

no errors at all. it looks like the shader is trying to do its thing, just not rendering right.

updating the driver for the errant machine/card doesn’t yield any results either.

I’m sorry for shooting in the dark here. I don’t have access to a machine that I can help debug this. Here are a few techniques you can try though. It’s a little bit cargo-cult, but they might work.

Switch the textures in the slots. If the same slot is white, damn.
Feed the same texture param to both samplers in the shader. Is the first sampler still white?
(edit: forgot how to force a serialize.). If you can trick the compiler into serializibg, you can see if that fixes it. I thought there was a [serialize] attribute, but I was wrong. You might be able to trick it using [isolate] or something.

I’m on a mobile phone, so I’m sorry I can’t look deeper. I will take a look tonight if I can.

thanks for giving it a shot. the following…

float4 colora = tex2D(aSampler, In.ATex);
[serialize];
float4 colorb = tex2D(bSampler, In.BTex);

doesn’t fix it & i tried the other two suggestions & still have white where texture 1 should be.

i’m willing to try other suggestions if you have 'em! :wink:

oops - just saw your edit.

what does

float4 colora = tex2D(aSampler, In.ATex);
float4 colorb = tex2D(aSampler, In.BTex);

yield?

And to confirm, using one “texture” variable in HLSL for both asampler and bsampler leaves asampler yielding white, and bsampler correct?

Also, what about changing the samplers to wrap? I think someone else here had a problem with a newer version of max defaulting to clamp. This Is all very puzzling. I’ll see if I can put together some Debug shaders to try and isolate the problem.

So… I’m starting to feel really dumb, and I’m sorry I’m not really helping you, but here are my last stabs to try. I can’t really find anything glaringly wrong.

Try:

sampler aSampler = sampler_state
{
    Texture   = (aTexture);
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    AddressU = WRAP;
    AddressV = WRAP;
};


sampler bSampler = sampler_state
{
    Texture   = (bTexture);
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    AddressU = WRAP;
    AddressV = WRAP;
};

If aSampler gives you white in this example, and bSampler doesn’t… I will be really confused:

sampler aSampler = sampler_state
{
    Texture   = (aTexture);
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};


sampler bSampler = sampler_state
{
    Texture   = (aTexture);   # Here be Dragons!
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};

The last one is that your variable definitions are a bit wrong. I didn’t catch this at first. The semantics you are binding aren’t quite correct, and maybe the compiler doesn’t like that.

texture aTexture : MapA

MapA isn’t a real semantic. http://developer.nvidia.com/object/using_sas.html
Maybe the graphics card is somehow not liking that.

The last thing to try is

[isolate]
{
float4 colora = tex2D(aSampler, In.ATex);
}

[isolate]
{
    float4 colorb = tex2D(bSampler, In.BTex);
}

This should force the compiler to leave those samplers alone. It might still try to do something wacky with them after, but it should be doing less.

I’m sorry man, I’m running low on ideas. At this point I’m just starting to feel like an idiot because all the ideas left are bad ideas… =/ Good Luck.

Cheers,
Lith

hey lithium -

the first snippet worked like a charm!

thanks for helping, i really appreciate it!

Awesome! I’m glad it worked. I think I know what is going on, because I think someone else reported a similar problem.

The ViewCube in fancy new Max whatever it is. ( Damn you ViewCube! In Maya you can’t automatically go orthographic like the Compass could! ) leaves the sampler state of sampler0 as something like


sampler aSampler = sampler_state
{
    // ... < snip> ...
    AddressU = BORDER;
    AddressV = BORDER;
    BorderColor = 1;      // I honestly have no idea the syntax for this particular state.
};

As a result, if your UVs not in 0,1 as they expect ( and I think 0,1 is actually the bottom right for MAX, not where the texture shows up by default ), you will hit the address edge, the graphics card will say “Oh I should go for my border color!” and that was white from the ViewCube, so your texture shows up completely white.

Now this means two things, one Max isn’t being very clean with it’s Graphics States. Leaving the Device in a specialty state like that is just plain mean. Second, this means that in Max, you have to be very explicit with your Shaders. Unlike in a game engine where you might want to let the renderer do state management, and change things as rarely as possible, you should probably always just state it all for Max. In fact, for any distributable Shader, where you don’t control the environment completely, you probably want to do that.

I’m incredibly happy that we finally got it!

Cheers,
-Lith