Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

#Actualvanattab

Posted 04 October 2012 - 04:16 PM

I am writing I SlimDX application to test color contrast sensitivity thresholds of the human visual system. The subject is presented with a large letter that is at low contrast with with the background and asked to identify the letter. However I need the ability to display more colors then is available with a simple 8bit per channel color depth. (i.e. rgb values 0-255). The way I plan to due this is through a simple "dithering" algorithm implemented as an HLSL pixel shader. Basically if request slimDX to render the text to a surface with a color of Color4( 0.55f, 0.55f, 0.55f ) which corresponds to a rgb value of ( 140.25 , 140.25 , 140.25 ) I want each color channel of each pixel to have a 25% chance of being set to 141 and a 75% chance of getting set to 140. This should (in the limit of many pixels) lead to a letter that appears as a shade of gray one 1/4 of the way in-between 140 and 141.
I am however getting errors in my prototype shader code when trying to compile with fxc. I am getting an Illegal character code when I compile and I don't know why. Also if you are a HLSL guru please look over my code and make any comments that strike you. Note I got the HLSL random function from an answer to this question.
http://stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader

Below is my shader code. Please forgive me if there a many mistakes as its my first HLSL code:

float4 DitherByChance(float2 coords : TEXCOORD0) : COLOR
{
  float4 newColor; // The pixel color to return
  float4 oldColor = tex2D(s0, coords);

  // Note I know that as the code stands now rCutOff = gCutOff = bCutOff I will sort a fix for this out later
  float rCutOff = random(coords);  // A random float that determines if the red channel will be rounded up or down
  float gCutOff = random(coords);  // A random float that determines if the green channel will be rounded up or down
  float bCutOff = random(coords);	 // A random float that determines if the blue channel will be rounded up or down
  float rPercentChance = frac(oldColor.r * 255); //Chance to round red channel up
  float gPercentChance = frac(oldColor.g * 255); //Chance to round green channel up
  float bPercentChance = frac(oldColor.b * 255); //Chance to round blue channel up

  //In the code below (1/255) is the floating point represntaion of an incress of one on the 0-255 RGB scale

  if (rCutOff <= rPercentChance) newColor.r = oldColor.r + ((1 - rPercentChance) / 255); //Bump up one r value
  else newColor.r = oldColor.r - rPercentChance * (1 / 255);	 //Bump down to ensure r is not rounded up

  if (gCutOff <= gPercentChance) newColor.g = oldColor.g + ((1 - gPercentChance) / 255); //Bump up one g value
  else newColor.b = oldColor.b - bPercentChance * (1 / 255);	 //Bump down to ensure g is not rounded up

  if (bCutOff <= bPercentChance) newColor.b = oldColor.b + ((1 - bPercentChance) / 255); //Bump up one b value
  else newColor.b = oldColor.b - bPercentChance * (1 / 255);	 //Bump down to ensure b is not rounded up

  return newColor;
}
// Input: It uses texture coords as the random number seed.
// Output: Random number: [0,1), that is between 0.0 and 0.999999... inclusive.
// Author: Michael Pohoreski
// Copyright: Copyleft 2012 :-)
float random( vec2 p )
{
   // We need irrationals for pseudo randomness.
   // Most (all?) known transcendental numbers will (generally) work.
   const vec2 r = vec2(
  23.1406926327792690,  // e^pi (Gelfond's constant)
   2.6651441426902251); // 2^sqrt(2) (Gelfond–Schneider constant)
   return fract( cos( mod( 123456789., 1e-7 + 256. * dot(p,r) ) ) );
}

#2vanattab

Posted 04 October 2012 - 04:15 PM

I am writing I SlimDX application to test color contrast sensitivity thresholds of the human visual system. The subject is presented with a large letter that is at low contrast with with the background and asked to identify the letter. However I need the ability to display more colors then is available with a simple 8bit per channel color depth. (i.e. rgb values 0-255). The way I plan to due this is through a simple "dithering" algorithm implemented as an HLSL pixel shader. Basically if request slimDX to render the text to a surface with a color of Color4( 0.55f, 0.55f, 0.55f ) which corresponds to a rgb value of ( 140.25 , 140.25 , 140.25 ) I want each color channel of each pixel to have a 25% chance of being set to 141 and a 75% chance of getting set to 140. This should (in the limit of many pixels) lead to a letter that appears as a shade of gray one 1/4 of the way in-between 140 and 141.
I am however getting errors in my prototype shader code when trying to compile with fxc. I am getting an Illegal character code when I compile and I don't know why. Also if you are a HLSL guru please look over my code and make any comments that strike you. Note I got the HLSL random function from an answer to this question. Can I generate a random number inside a pixel shader?
Below is my shader code. Please forgive me if there a many mistakes as its my first HLSL code:

float4 DitherByChance(float2 coords : TEXCOORD0) : COLOR
{
  float4 newColor; // The pixel color to return
  float4 oldColor = tex2D(s0, coords);
 
  // Note I know that as the code stands now rCutOff = gCutOff = bCutOff I will sort a fix for this out later
  float rCutOff = random(coords);  // A random float that determines if the red channel will be rounded up or down
  float gCutOff = random(coords);  // A random float that determines if the green channel will be rounded up or down
  float bCutOff = random(coords);	 // A random float that determines if the blue channel will be rounded up or down
  float rPercentChance = frac(oldColor.r * 255); //Chance to round red channel up
  float gPercentChance = frac(oldColor.g * 255); //Chance to round green channel up
  float bPercentChance = frac(oldColor.b * 255); //Chance to round blue channel up
 
  //In the code below (1/255) is the floating point represntaion of an incress of one on the 0-255 RGB scale
 
  if (rCutOff <= rPercentChance) newColor.r = oldColor.r + ((1 - rPercentChance) / 255); //Bump up one r value
  else newColor.r = oldColor.r - rPercentChance * (1 / 255);	 //Bump down to ensure r is not rounded up
 
  if (gCutOff <= gPercentChance) newColor.g = oldColor.g + ((1 - gPercentChance) / 255); //Bump up one g value
  else newColor.b = oldColor.b - bPercentChance * (1 / 255);	 //Bump down to ensure g is not rounded up
 
  if (bCutOff <= bPercentChance) newColor.b = oldColor.b + ((1 - bPercentChance) / 255); //Bump up one b value
  else newColor.b = oldColor.b - bPercentChance * (1 / 255);	 //Bump down to ensure b is not rounded up
 
  return newColor;
}
// Input: It uses texture coords as the random number seed.
// Output: Random number: [0,1), that is between 0.0 and 0.999999... inclusive.
// Author: Michael Pohoreski
// Copyright: Copyleft 2012 :-)
float random( vec2 p )
{
   // We need irrationals for pseudo randomness.
   // Most (all?) known transcendental numbers will (generally) work.
   const vec2 r = vec2(
  23.1406926327792690,  // e^pi (Gelfond's constant)
   2.6651441426902251); // 2^sqrt(2) (Gelfond–Schneider constant)
   return fract( cos( mod( 123456789., 1e-7 + 256. * dot(p,r) ) ) ); 
}

#1vanattab

Posted 04 October 2012 - 04:13 PM

I am writing I SlimDX application to test color contrast sensitivity thresholds of the human visual system. The subject is presented with a large letter that is at low contrast with with the background and asked to identify the letter. However I need the ability to display more colors then is available with a simple 8bit per channel color depth. (i.e. rgb values 0-255). The way I plan to due this is through a simple "dithering" algorithm implemented as an HLSL pixel shader. Basically if request slimDX to render the text to a surface with a color of Color4( 0.55f, 0.55f, 0.55f ) which corresponds to a rgb value of ( 140.25 , 140.25 , 140.25 ) I want each color channel of each pixel to have a 25% chance of being set to 141 and a 75% chance of getting set to 140. This should (in the limit of many pixels) lead to a letter that appears as a shade of gray one 1/4 of the way in-between 140 and 141.
I am however getting errors in my prototype shader code when trying to compile with fxc. I am getting an Illegal character code when I compile and I don't know why. Also if you are a HLSL guru please look over my code and make any comments that strike you. Note I got the HLSL random function from an answer to this question. Can I generate a random number inside a pixel shader?
Below is my shader code. Please forgive me if there a many mistakes as its my first HLSL code:

[source lang="cpp"] float4 DitherByChance(float2 coords : TEXCOORD0) : COLOR { float4 newColor; // The pixel color to return float4 oldColor = tex2D(s0, coords); // Note I know that as the code stands now rCutOff = gCutOff = bCutOff I will sort a fix for this out later float rCutOff = random(coords); // A random float that determines if the red channel will be rounded up or down float gCutOff = random(coords); // A random float that determines if the green channel will be rounded up or down float bCutOff = random(coords);     // A random float that determines if the blue channel will be rounded up or down float rPercentChance = frac(oldColor.r * 255); //Chance to round red channel up float gPercentChance = frac(oldColor.g * 255); //Chance to round green channel up float bPercentChance = frac(oldColor.b * 255); //Chance to round blue channel up //In the code below (1/255) is the floating point represntaion of an incress of one on the 0-255 RGB scale if (rCutOff <= rPercentChance) newColor.r = oldColor.r + ((1 - rPercentChance) / 255); //Bump up one r value else newColor.r = oldColor.r - rPercentChance * (1 / 255); //Bump down to ensure r is not rounded up if (gCutOff <= gPercentChance) newColor.g = oldColor.g + ((1 - gPercentChance) / 255); //Bump up one g value else newColor.b = oldColor.b - bPercentChance * (1 / 255); //Bump down to ensure g is not rounded up if (bCutOff <= bPercentChance) newColor.b = oldColor.b + ((1 - bPercentChance) / 255); //Bump up one b value else newColor.b = oldColor.b - bPercentChance * (1 / 255); //Bump down to ensure b is not rounded up return newColor; } // Input: It uses texture coords as the random number seed. // Output: Random number: [0,1), that is between 0.0 and 0.999999... inclusive. // Author: Michael Pohoreski // Copyright: Copyleft 2012 :-) float random( vec2 p ) {   // We need irrationals for pseudo randomness.   // Most (all?) known transcendental numbers will (generally) work.   const vec2 r = vec2( 23.1406926327792690,  // e^pi (Gelfond's constant) 2.6651441426902251); // 2^sqrt(2) (Gelfond–Schneider constant)   return fract( cos( mod( 123456789., 1e-7 + 256. * dot(p,r) ) ) );   }[/source]

PARTNERS