4
\$\begingroup\$

I am trying to build a default color grading map into a 1024x32 RenderTarget. Here is my shader code:

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;
    output.Position = float4(input.Position,1);

    output.TexCoord = input.TexCoord;
    return output;
}

float4 PixelShaderFunction(float2 TexCoord : TEXCOORD0) : COLOR0
{
    float temp = TexCoord.r*1024;
    float4 result = (float4)0;
    result.a = 1;
    result.r = (temp%32)/32;
    result.g = TexCoord.g;
    result.b = TexCoord.r;

    return result;
}

I'm using Catalin Zima's quad renderer to render the color grading map AND to render the contents of the texture back onto the screen. Here is the copy shader:

texture Texture;
sampler targetSampler = sampler_state
{
    Texture = (Texture);
    AddressU = CLAMP;
    AddressV = CLAMP;
    MagFilter = POINT;
    MinFilter = POINT;
    Mipfilter = POINT;
};


VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;
    output.Position = float4(input.Position,1);

    output.TexCoord = input.TexCoord + halfPixel;
    return output;
}

float4 PixelShaderFunction(float2 TexCoord : TEXCOORD0) : COLOR0
{
    return tex2D(targetSampler, TexCoord);
}

When I take the resulting image into the Photoshop, the bottom right pixel of the texture always equals (247, 247, 255), even though top left color equals zero.

What could be the problem? I checked the quad renderer class - it is recording texture coordinates exactly 0,1 into the quad's corners. I am aligning pixels to texels with the halfPixel and using point texture sampling. Somewhy the V component of texture coordinates never reaches one. I have no clue where the problem can be. As I plan to use this texture for color grading, the accuracy is crucial.

enter image description here

UPDATE: So far I can only achieve the needed result with the folowing shader code:

float4 PixelShaderFunction(float2 TexCoord : TEXCOORD0) : COLOR0
{

    float temp = TexCoord.r*1024;
    float4 result = (float4)0;
    result.a = 1;
    float m = (temp%32);
    result.r = m/32+0.035f*m/32;
    result.g = TexCoord.g+0.035f*TexCoord.g;
    result.b = TexCoord.r;

    return result;
}

Which is very wierd.

UPDATE 2: Ok, I had to modulo divide over 33 instead of 32, but I still have to correct the V coordinate.

float4 PixelShaderFunction(float2 TexCoord : TEXCOORD0) : COLOR0
{
    float temp = TexCoord.r*1024;
    float4 result = (float4)0;
    result.a = 1;
    float m = (temp%33);
    result.r = m/33;//+0.035f*m/33;
    result.g = TexCoord.g+0.035f*TexCoord.g;
    result.b = TexCoord.r;

    return result;
}
\$\endgroup\$
1
\$\begingroup\$

Where did 0.035f come from?

I believe your mistake comes from doing (temp%32)/32. If you take a look at it closely, you see that you get values in range 0..31, but you divide it by 32, which gives resulting values from 0 to 0.98675 (0 to 247 in RGB)

Correct code would be like so:

float4 PixelShaderFunction(float2 TexCoord : TEXCOORD0) : COLOR0
{
    float temp = TexCoord.r*1024;
    float m = temp % 32;   // range is 0..31, repeats 32 times
    result.r = m / 31;     // makes range 0..1 (RGBs from 0 to 255)
    result.g = TexCoord.g; // range 0..1 (RGBs from 0 to 255)
    result.b = TexCoord.r;
    result.a = 1;

    return result;
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.