Pixel Shader: I need to test the availability of texture

Started by
8 comments, last by lucky6969b 12 years, 10 months ago

if (texColor != 0) { // float expected
color = gMtrl.diffuse*texColor.rgb;
}



How can I correct the above error? I want to know if the vertex shader is feeding any texture data to the pixel shader or not....
Thanks
Jack
Advertisement
Sample the texture in the pixel shader and simply return the value. If your texture shows up on the object you mapped it to, then it's being fed correctly.

Example:


float4 diffuse = diffuseMap.Sample(linearSam, pIn.texC);

return diffuse;



Where diffuseMap is a texture2D object within your effect file and linearSam is a SamplerState defined in your effect file, and pIn.texC is the texture coordinate fed from the vertex shader.

Sample the texture in the pixel shader and simply return the value. If your texture shows up on the object you mapped it to, then it's being fed correctly.

Example:


float4 diffuse = diffuseMap.Sample(linearSam, pIn.texC);

return diffuse;



Where diffuseMap is a texture2D object within your effect file and linearSam is a SamplerState defined in your effect file, and pIn.texC is the texture coordinate fed from the vertex shader.

This might not work if there isnt a shader resource bound to that shader texture.

@lucky6969b Can you post the full vertex and pixel shaders? Im not sure what are you trying to do... If you want to know if a resource is bound to shader input you should create a shader constant like "int textureAvailable" and pass either 0 or 1 from the application telling if a resource is bound and in shader:

if(textureAvailable)
{
(sample texture)
}

struct Mtrl
{
float4 ambient;
float4 diffuse;
float4 spec;
float specPower;
};

struct DirLight
{
float4 ambient;
float4 diffuse;
float4 spec;
float3 dirW;
};

uniform extern float4x4 gWorld;
uniform extern float4x4 gWorldInvTrans;
uniform extern float4x4 gWVP;
uniform extern Mtrl gMtrl;
uniform extern DirLight gLight;
uniform extern float3 gEyePosW;
uniform extern texture gTex;

uniform extern float4 gAmbientMtrl;
uniform extern float4 gAmbientLight;
uniform extern float4 gDiffuseMtrl;
uniform extern float4 gDiffuseLight;
uniform extern float3 gLightVecW;

sampler TexS = sampler_state
{
Texture = <gTex>;
MinFilter = Anisotropic;
MagFilter = LINEAR;
MipFilter = Point;
MaxAnisotropy = 8;
AddressU = WRAP;
AddressV = WRAP;
};


struct OutputVS
{
float4 posH : POSITION0;
float3 normalW : TEXCOORD0;
float3 toEyeW : TEXCOORD1;
float2 tex0 : TEXCOORD2;
float4 color : COLOR0;
};

OutputVS PhongDirLtTexVS(float3 posL : POSITION0, float3 normalL : NORMAL0, float2 tex0: TEXCOORD0)
{
// Zero out our output.
OutputVS outVS = (OutputVS)0;

// Transform normal to world space.
outVS.normalW = mul(float4(normalL, 0.0f), gWorldInvTrans).xyz;

// Transform vertex position to world space.
float3 posW = mul(float4(posL, 1.0f), gWorld).xyz;

// Compute the unit vector from the vertex to the eye.
outVS.toEyeW = gEyePosW - posW;


// Transform normal to world space.
float3 normalW = mul(float4(normalL, 0.0f), gWVP).xyz;
normalW = normalize(normalW);

// Compute the color: Equation 10.2.
float s = max(dot(gLightVecW, normalW), 0.0f);
float3 diffuse = s*(gDiffuseMtrl*gDiffuseLight).rgb;
float3 ambient = gAmbientMtrl*gAmbientLight;
outVS.color.rgb = ambient + diffuse;
outVS.color.a = gDiffuseMtrl.a;

// Transform to homogeneous clip space.
outVS.posH = mul(float4(posL, 1.0f), gWVP);

// Pass on texture coordinates to be interpolated in rasterization.
outVS.tex0 = tex0;

// Done--return the output.
return outVS;
}

float4 PhongDirLtTexPS(float3 normalW : TEXCOORD0, float3 toEyeW : TEXCOORD1, float2 tex0 : TEXCOORD2) : COLOR
{
// Interpolated normals can become unnormal--so normalize.
normalW = normalize(normalW);
toEyeW = normalize(toEyeW);

// Light vector is opposite the direction of the light.
float3 lightVecW = -gLight.dirW;

// Compute the reflection vector.
float3 r = reflect(-lightVecW, normalW);

// Determine how much (if any) specular light makes it into the eye.
float t = pow(max(dot(r, toEyeW), 0.0f), gMtrl.specPower);

// Determine the diffuse light intensity that strikes the vertex.
float s = max(dot(lightVecW, normalW), 0.0f);

// Compute the ambient, diffuse and specular terms separatly.
float3 spec = t*(gMtrl.spec*gLight.spec).rgb;
float3 diffuse = s*(gMtrl.diffuse*gLight.diffuse).rgb;
float3 ambient = gMtrl.ambient*gLight.ambient;

// Get the texture color.
float4 texColor = tex2D(TexS, tex0);


// Combine the color from lighting with the texture color.
//float3 color = (ambient + diffuse)*texColor.rgb + spec;
// float3 color = (ambient + diffuse) + spec;
float3 color = diffuse;
if (texColor != 0) {
color = gMtrl.diffuse*texColor.rgb;
}

// Sum all the terms together and copy over the diffuse alpha.
//return float4(color, gMtrl.diffuse.a*texColor.a);
return float4(color,1.0f);
}

technique PhongDirLtTexTech
{
pass P0
{
// Specify the vertex and pixel shader associated with this pass.
vertexShader = compile vs_2_0 PhongDirLtTexVS();
pixelShader = compile ps_2_0 PhongDirLtTexPS();
}
}

These shaders come from the book by Frank Luna. I've made several changes to it Thanks Jack
Fixed:color *= gMtrl.diffuse.rgb*texColor.rgb;

What is that 'if' supposed to do? Is it supposed to make the shader still work if there is no texture bound? If so, either use a different shader (which doesn't sample that texture) when the texture isn't required, or bind a white texture when the texture isn't required.
Hmmm, I think a seperate shader is a viable solution thanks
Jack
I'd like to ask too, with the provided shaders, if I'd like to have multiple light sources, how do I modify the code to accommodate this?
Also, I wonder why the ps won't support alpha channel, I had the materials loaded in, setting the scene as A8R8G8B8
and letting it return float4(color, 0.5f);.... but no transparency occurs.... Could you please shed some lights on this?
Thanks
Jack
http://img689.images...psproblemu.jpg/

I have a very strange problem. When I specify all colors output from the PS to be 0.3..... some objects appear not to be able to see thru...
Any ideas why.....


//=============================================================================
// PhongDirLtTex.fx by Frank Luna (C) 2004 All Rights Reserved.
//
// Phong directional light & texture.
//=============================================================================

struct Mtrl
{
float4 ambient;
float4 diffuse;
float4 spec;
float specPower;
};

struct DirLight
{
float4 ambient;
float4 diffuse;
float4 spec;
float3 dirW;
};

uniform extern float4x4 gWorld;
uniform extern float4x4 gWorldInvTrans;
uniform extern float4x4 gWVP;
uniform extern Mtrl gMtrl;
uniform extern DirLight gLight;
uniform extern float3 gEyePosW;
uniform extern texture gTex;

uniform extern float4 gAmbientMtrl;
uniform extern float4 gAmbientLight;
uniform extern float4 gDiffuseMtrl;
uniform extern float4 gDiffuseLight;
uniform extern float3 gLightVecW;

sampler TexS = sampler_state
{
Texture = <gTex>;
MinFilter = Anisotropic;
MagFilter = LINEAR;
MipFilter = Point;
MaxAnisotropy = 8;
AddressU = WRAP;
AddressV = WRAP;
};


struct OutputVS
{
float4 posH : POSITION0;
float3 normalW : TEXCOORD0;
float3 toEyeW : TEXCOORD1;
float2 tex0 : TEXCOORD2;
float4 color : COLOR0;
};

OutputVS PhongDirLtTexVS(float3 posL : POSITION0, float3 normalL : NORMAL0, float2 tex0: TEXCOORD0)
{
// Zero out our output.
OutputVS outVS = (OutputVS)0;

// Transform normal to world space.
outVS.normalW = mul(float4(normalL, 0.0f), gWorldInvTrans).xyz;

// Transform vertex position to world space.
float3 posW = mul(float4(posL, 1.0f), gWorld).xyz;

// Compute the unit vector from the vertex to the eye.
outVS.toEyeW = gEyePosW - posW;


// Transform normal to world space.
float3 normalW = mul(float4(normalL, 0.0f), gWVP).xyz;
normalW = normalize(normalW);

// Compute the color: Equation 10.2.
float s = max(dot(gLightVecW, normalW), 0.0f);
float3 diffuse = s*(gDiffuseMtrl*gDiffuseLight).rgb;
float3 ambient = gAmbientMtrl*gAmbientLight;
outVS.color.rgb = ambient + diffuse;
outVS.color.a = gDiffuseMtrl.a;

// Transform to homogeneous clip space.
outVS.posH = mul(float4(posL, 1.0f), gWVP);

// Pass on texture coordinates to be interpolated in rasterization.
outVS.tex0 = tex0;

// Done--return the output.
return outVS;
}

float4 PhongDirLtTexPS(float3 normalW : TEXCOORD0, float3 toEyeW : TEXCOORD1, float2 tex0 : TEXCOORD2) : COLOR
{
// Interpolated normals can become unnormal--so normalize.
normalW = normalize(normalW);
toEyeW = normalize(toEyeW);

// Light vector is opposite the direction of the light.
float3 lightVecW = -gLight.dirW;

// Compute the reflection vector.
float3 r = reflect(-lightVecW, normalW);

// Determine how much (if any) specular light makes it into the eye.
float t = pow(max(dot(r, toEyeW), 0.0f), gMtrl.specPower);

// Determine the diffuse light intensity that strikes the vertex.
float s = max(dot(lightVecW, normalW), 0.0f);

// Compute the ambient, diffuse and specular terms separatly.
float3 spec = t*(gMtrl.spec*gLight.spec).rgb;
float3 diffuse = s*(gMtrl.diffuse*gLight.diffuse).rgb;
float3 ambient = gMtrl.ambient*gLight.ambient;

// Get the texture color.
float4 texColor = tex2D(TexS, tex0);


// Combine the color from lighting with the texture color.
//float3 color = (ambient + diffuse)*texColor.rgb + spec;
// float3 color = (ambient + diffuse) + spec;
float3 color = (ambient + diffuse)+spec;
// if (texColor != 0) {
// color = gMtrl.diffuse*texColor.rgb;
// }

// Sum all the terms together and copy over the diffuse alpha.
// float3 outcolor = color.rgb * 0.5f;
//return float4(color, gMtrl.diffuse.a*texColor.a);
return float4(color, 0.3f); // 1.0f
}

technique PhongDirLtTexTech
{
pass P0
{
// Specify the vertex and pixel shader associated with this pass.
vertexShader = compile vs_2_0 PhongDirLtTexVS();
pixelShader = compile ps_2_0 PhongDirLtTexPS();
}
}
To get correct looking transparency you need to render your transparent models in the correct order - furthest away ones first. Some more details: http://blogs.msdn.com/b/shawnhar/archive/2009/02/18/depth-sorting-alpha-blended-objects.aspx

You should also obviously make sure you're rendering everything with the correct blend mode.
Thx, Adam, after reading on that art. I've come up with a solution.
Thanks
Jack

This topic is closed to new replies.

Advertisement