Sign in to follow this  
maxest

Passing textures to pixel shader

Recommended Posts

maxest    622
Let's assume that I have in pixel shader something like this:
uniform sampler2D decal0;
uniform sampler2D decal1;
...
output.color = tex2D(decal0, texCoord) * 0.25f*tex2D(decal1, texCoord);
..
How can I "say" to the pixel shader from my application which texture is decal0, and which is decal1? I found out a function SetTexture but it's a part of ID3DXEffect. However, I'm not using this interface but simple IDirect3DPixelShader9 and ID3DXConstantTable interfaces

Share this post


Link to post
Share on other sites
51mon    342
It was a long time since I coded an dx application without using ID3DXEffect but I think IDirect3DDevice9::SetTexture will work for you. Inside the shader you need to connect the sampler with a texture. Here is an example of how that might look like:

texture g_decal0Texture;
sampler decal0=
sampler_state
{
Texture = <g_decal0Texture>;
MinFilter = POINT;
MagFilter = POINT;
AddressU = CLAMP;
AddressV = CLAMP;
};

It has to be done globally. You declare the sampler with desirable amount of sampler states. You can find the different states available in the Effect States article in the SDK. It's mandatory to declare a specific texture object.

Share this post


Link to post
Share on other sites
sirob    1181
You can map textures to samplers using Device::SetTexture. The problem with the code you've posted is that there is no way of knowing which HLSL samplers match which sampling registers. The HLSL compiler is free to sort, or even remove some of them if it pleases, and if any of them isn't used, it'll be optimized out.

To assign a specific register to an HLSL sampler, use this syntax:
sampler2D decal0 : register(s0);
This then maps this HLSL sampler to s0 explicitly. If you use this syntax, you can then use Device::SetTexture(0, texture) to map a texture to the HLSL sampler named decal0, and would not encounter problems if any samplers were optimized out.

Hope this helps.

Share this post


Link to post
Share on other sites
maxest    622
sirob: That's exactly what I was looking for! Thanks a lot :)

51mon: I've tried such pixel shader code

...

texture groundTex;
texture projTex;

sampler decal0=
sampler_state
{
Texture = <groundTex>;
MinFilter = POINT;
MagFilter = POINT;
AddressU = CLAMP;
AddressV = CLAMP;
};

sampler decal1=
sampler_state
{
Texture = <projTex>;
MinFilter = POINT;
MagFilter = POINT;
AddressU = CLAMP;
AddressV = CLAMP;
};

PS_OUTPUT main(in float2 texCoord: TEXCOORD0, in float4 texCoordProj: TEXCOORD1, in float4 fragmentPosition: TEXCOORD2)
{
PS_OUTPUT output;
float4 projColor;

projColor = tex2Dproj(decal1, texCoordProj);
output.color = tex2D(decal0, texCoord) * projColor;

return output;
}


But it doesn't seem to work

Share this post


Link to post
Share on other sites
Schrompf    1035
The "official" way is to query the shader on which sampler index the compiler has placed your samplers. To do this, get hold of the shader's constant table, use GetConstantByName() to acquire a handle for that sampler and pass this handle to GetSamplerIndex(). The latter returns the sampler index that you can use in ID3DDevice9::SetTexture() to assign a texture to, define filter and address modes and such.

The method 51mon proposed in his post is just an extended way to define filter and address modes for the sampler inside the shader source. I'm not sure if this works for bare HLSL shaders as well. To my knowledge, these settings are only respected when used inside the Effect framework.

Bye, Thomas

Share this post


Link to post
Share on other sites
51mon    342
According to the SDK sampler_state is both a legal keyword and explained in the "Writing HLSL Shaders" article. But it's possible that the sampler_state declaration don't work in your situation? It appear that you can only pass textures to sampler objects (and not to texture objects) when you work without ID3DXEffect?

Share this post


Link to post
Share on other sites
maxest    622
Schrompf: the way you showed seems to work as I expected. However, the shortest way for assigning samplers to textures is by using register(sn) :). Even though it reminds of low-level shaders :D
Thank you guys a lot for your help

Share this post


Link to post
Share on other sites

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