Only 2 TEXCOORDs in ps_1_1?

Started by
5 comments, last by ET3D 18 years ago
I'm having trouble with a resampling shader I'm working on. I'm trying to sample a texture with a 4-pixel kernel. My 4 sample locations are uv0, uv1, uv2, and uv3. I set them in the vertex shader, and read them in the pixel shader. It seems that uv0 and uv1 work just fine, but the values of uv2 and uv3 are always (0,0) in the pixel shader, resulting in the top-left pixel in the texture being averaged in with all other pixels.

float sgv_texelSize;

texture sgv_resampleTexture;

sampler SourceSampler = 
sampler_state
	{
	Texture = <sgv_resampleTexture>;    
	MipFilter = LINEAR;
	MinFilter = LINEAR;
	MagFilter = LINEAR;
	AddressU=Clamp;
	AddressV=Clamp;
	};


struct VS_OUTPUT
	{
	float4 Position	: POSITION;   // vertex position 
	float2 uv0	: TEXCOORD0;  // derived texture coords 
	float2 uv1	: TEXCOORD1;  // derived texture coords 
	float2 uv2	: TEXCOORD2;  // derived texture coords 
	float2 uv3	: TEXCOORD3;  // derived texture coords 
	};

VS_OUTPUT vs_Resample(  float4 vPos : POSITION, float2 TexCoord : TEXCOORD0)
	{
	VS_OUTPUT Output;

	sgv_texelSize = 0;
	float4 uvOffset = float4(sgv_texelSize, sgv_texelSize, sgv_texelSize, -sgv_texelSize);
	Output.Position = vPos;


	Output.uv0 = TexCoord + uvOffset.xy;
	Output.uv1 = TexCoord - uvOffset.xy;
	Output.uv2 = TexCoord + uvOffset.zw;
	Output.uv3 = TexCoord - uvOffset.zw;

	return Output;    
	}

struct PS_OUTPUT
	{
	float4 RGBColor : COLOR0;  // Pixel color    
	};

PS_OUTPUT ps_Resample( VS_OUTPUT inVert ) 
	{ 
	PS_OUTPUT Output;	

	float4 sample0 = tex2D(SourceSampler, inVert.uv0);
	float4 sample1 = tex2D(SourceSampler, inVert.uv1);
	float4 sample2 = tex2D(SourceSampler, inVert.uv2);
	float4 sample3 = tex2D(SourceSampler, inVert.uv3);

	Output.RGBColor.rgb = sample0.rgb * 0.25f;
	Output.RGBColor.rgb += sample1.rgb * 0.25f;
	Output.RGBColor.rgb += sample2.rgb * 0.25f;
	Output.RGBColor.rgb += sample3.rgb * 0.25f;
	Output.RGBColor.a = 1;

	return Output;
	}


technique Glare
{
	pass Resample
	{
		cullmode = none;
		ZEnable = false;
		ZWriteEnable = false;		
		VertexShader = compile vs_1_1 vs_Resample();
		PixelShader  = compile ps_1_1 ps_Resample(); 
	}
}

Advertisement
Can you try compiling/executing it at a SM2 or SM3 profile - it wouldn't surprise me if it's a limitation of the SM1 profiles. Although, having said that, most of the times such things have hurt me it's resulted in a compile-time error rather than a run time one...

SM1 has a number of limitations - including the number of times various registers can be used in expressions and then theres also something about having each set of texture coordinates refer to their own sampler stage:

Quote:There is a default one-to-one association between texture stage number and texture coordinate declaration order. By default, the first set of texture coordinates defined in the vertex format is associated with texture stage 0.


I mostly skipped SM1 because I was lazy and couldn't be bothered to get my head around the crazy number of limitations [lol] Might be worth double-checking the documentation to see if you're not stepping on any restrictions.

Another thing is to run via the reference rasterizer. I recently had a problem where ATI hardware allowed me to do things via SM1 that the RefRast and NV hardware wouldn't allow [rolleyes]

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

I've quickly modified FX Composer's default material to perform something similar - seems to work okay. If you don't already have that tool, I'd recommend you grab it from the NVidia developer webpage.

I'd recommend you try outputting each of the 4 texcoords to make sure they are getting into the pixel shader correctly.

Just in case it helps, here's the material I generated in FX Composer that works, maybe it'll help:
string description = "Basic Vertex Lighting with a Texture";//------------------------------------float4x4 worldViewProj : WorldViewProjection;float4x4 world   : World;float4x4 worldInverseTranspose : WorldInverseTranspose;float4x4 viewInverse : ViewInverse;texture diffuseTexture : Diffuse<	string ResourceName = "default_color.dds";>;float4 lightDir : Direction<	string Object = "DirectionalLight";    string Space = "World";> = {1.0f, -1.0f, 1.0f, 0.0f};float4 lightColor : Diffuse<    string UIName = "Diffuse Light Color";    string Object = "DirectionalLight";> = {1.0f, 1.0f, 1.0f, 1.0f};float4 lightAmbient : Ambient<    string UIWidget = "Ambient Light Color";    string Space = "material";> = {0.0f, 0.0f, 0.0f, 1.0f};float4 materialDiffuse : Diffuse<    string UIWidget = "Surface Color";    string Space = "material";> = {1.0f, 1.0f, 1.0f, 1.0f};float4 materialSpecular : Specular<	string UIWidget = "Surface Specular";	string Space = "material";> = {1.0f, 1.0f, 1.0f, 1.0f};float shininess : SpecularPower<    string UIWidget = "slider";    float UIMin = 1.0;    float UIMax = 128.0;    float UIStep = 1.0;    string UIName = "specular power";> = 30.0;//------------------------------------struct vertexInput {    float3 position				: POSITION;    float3 normal				: NORMAL;    float4 texCoordDiffuse		: TEXCOORD0;};struct vertexOutput {    float4 hPosition		: POSITION;    float4 texCoordDiffuse	: TEXCOORD0;    float4 texCoordDiffuse1	: TEXCOORD1;    float4 texCoordDiffuse2	: TEXCOORD2;    float4 texCoordDiffuse3	: TEXCOORD3;    float4 diffAmbColor		: COLOR0;    float4 specCol			: COLOR1;};//------------------------------------vertexOutput VS_TransformAndTexture(vertexInput IN) {    vertexOutput OUT;    OUT.hPosition = mul( float4(IN.position.xyz , 1.0) , worldViewProj);    OUT.texCoordDiffuse = IN.texCoordDiffuse;    OUT.texCoordDiffuse1 = IN.texCoordDiffuse;    OUT.texCoordDiffuse2 = IN.texCoordDiffuse;    OUT.texCoordDiffuse3 = IN.texCoordDiffuse;	//calculate our vectors N, E, L, and H	float3 worldEyePos = viewInverse[3].xyz;    float3 worldVertPos = mul(IN.position, world).xyz;	float4 N = mul(IN.normal, worldInverseTranspose); //normal vector    float3 E = normalize(worldEyePos - worldVertPos); //eye vector    float3 L = normalize( -lightDir.xyz); //light vector    float3 H = normalize(E + L); //half angle vector	//calculate the diffuse and specular contributions    float  diff = max(0 , dot(N,L));    float  spec = pow( max(0 , dot(N,H) ) , shininess );    if( diff <= 0 )    {        spec = 0;    }	//output diffuse    float4 ambColor = materialDiffuse * lightAmbient;    float4 diffColor = materialDiffuse * diff * lightColor ;    OUT.diffAmbColor = diffColor + ambColor;	//output specular    float4 specColor = materialSpecular * lightColor * spec;    OUT.specCol = specColor;    return OUT;}//------------------------------------sampler TextureSampler = sampler_state {    texture = <diffuseTexture>;    AddressU  = CLAMP;            AddressV  = CLAMP;    AddressW  = CLAMP;    MIPFILTER = LINEAR;    MINFILTER = LINEAR;    MAGFILTER = LINEAR;};//------------------------------------sampler TextureSampler1 = sampler_state {    texture = <diffuseTexture>;    AddressU  = CLAMP;            AddressV  = CLAMP;    AddressW  = CLAMP;    MIPFILTER = LINEAR;    MINFILTER = LINEAR;    MAGFILTER = LINEAR;};//------------------------------------sampler TextureSampler2 = sampler_state {    texture = <diffuseTexture>;    AddressU  = CLAMP;            AddressV  = CLAMP;    AddressW  = CLAMP;    MIPFILTER = LINEAR;    MINFILTER = LINEAR;    MAGFILTER = LINEAR;};//------------------------------------sampler TextureSampler3 = sampler_state {    texture = <diffuseTexture>;    AddressU  = CLAMP;            AddressV  = CLAMP;    AddressW  = CLAMP;    MIPFILTER = LINEAR;    MINFILTER = LINEAR;    MAGFILTER = LINEAR;};//-----------------------------------float4 PS_Textured( vertexOutput IN): COLOR{  float4 diffuseTexture = tex2D( TextureSampler, IN.texCoordDiffuse );   diffuseTexture += tex2D( TextureSampler1, IN.texCoordDiffuse1 );   diffuseTexture += tex2D( TextureSampler2, IN.texCoordDiffuse2 );   diffuseTexture += tex2D( TextureSampler3, IN.texCoordDiffuse3 );   diffuseTexture /= 4;  return IN.diffAmbColor * diffuseTexture + IN.specCol;}//-----------------------------------technique textured{    pass p0     {				VertexShader = compile vs_1_1 VS_TransformAndTexture();		PixelShader  = compile ps_1_1 PS_Textured();    }}


Hope this helps.
Sirob Yes.» - status: Work-O-Rama.
Ok I tried vs_2_0 an ps_2_0 and got the following error messages:

Direct3D9: VS->PS Linker: X444: (Warning) Current pixel shader declares input texture coordinate t2.xy. However the current transformed vertex declaration (vertex proc. disabled) does not provide texcoord2 at all.
Direct3D9: VS->PS Linker: X444: (Warning) Current pixel shader declares input texture coordinate t3.xy. However the current transformed vertex declaration (vertex proc. disabled) does not provide texcoord3 at all.

And yes, I am using transformed vertices, so that's why. I wonder why I didn't get this message in SM1.
Try using fxc to see the assembly of that shader. That might help.

Take care about the limitations of ps1_1. It allows 4 texture samples, 8 arithmetic instructions, and extremely limited swizzling. The compiler might be able to optimise things, or it might be stupid (or buggy). HLSL doesn't convert all that naturally to ps1_1. Which is why sirob's example (doing the sum's directly instead of assigning to variables, no .rgb, dividing by 4 at the end) is more ps1_1 friendly.
So I just want to make sure I'm making a good assumption here. If I declare my vertices as transformed with a D3DDECLUSAGE_POSITIONT the vertex shader isn't used at all?
Yes.

This topic is closed to new replies.

Advertisement