Few functions in shader?

Hey guys,

I wonder if it is possible to put more than one function into a shader. I mean if possible how to give some variables, which I compute before to the seconde function?
Or is this the two-pass limitation?

So, not to write some abstract hot air, only - here is my problem and shader. RGB to HSL conversion.

My problem is, that the shader is over 64 arithmetic instructions. That allows me only to change H, S or L but never all three. F****** damn.

{CODE(ln=>1)}
// --------------------------------------------------------------------------------------------------
// PARAMETERS:
// --------------------------------------------------------------------------------------------------

//transforms
float4x4 tW: WORLD; //the models world matrix
float4x4 tV: VIEW; //view matrix as set via Renderer (EX9)
float4x4 tP: PROJECTION;
float4x4 tWVP: WORLDVIEWPROJECTION;

//texture
texture Src <string uiname=“Source”;>;
sampler SrcSamp = sampler_state //sampler for doing the texture-lookup
{
Texture = (Src); //apply a texture to the sampler
MipFilter = LINEAR; //sampler states
MinFilter = LINEAR;
MagFilter = LINEAR;
};

//source transformation
float4x4 tTex: TEXTUREMATRIX <string uiname=“Source Transform”;>;

//pins for the HSL
float Hue
<
string uiname=“Hue”;
float uimin=-1.0f;
float uimax=1.0f;

= 0.0f;

float Saturation
<
string uiname=“Saturation”;
float uimin=-1.0f;
float uimax=1.0f;

= 0.0f;

float Luminance
<
string uiname=“Luminance”;
float uimin=-1.0f;
float uimax=1.0f;

= 0.0f;

//the data structure: “vertexshader to pixelshader”
//used as output data with the VS function
//and as input data with the PS function
struct vs2ps
{
float4 Pos : POSITION;
float2 TexCd : TEXCOORD0;
};

// --------------------------------------------------------------------------------------------------
// VERTEXSHADERS
// --------------------------------------------------------------------------------------------------
vs2ps VS(
float4 Pos : POSITION,
float4 TexCd : TEXCOORD0)
{
//inititalize all fields of output struct with 0
vs2ps Out = (vs2ps)0;

//transform position
Out.Pos = mul(Pos, tWVP);

//transform texturecoordinates
Out.TexCd = mul(TexCd, tTex);

return Out;

}

// --------------------------------------------------------------------------------------------------
// PIXELSHADERS:
// --------------------------------------------------------------------------------------------------

float4 ps_HSV(vs2ps In): COLOR
{
//source1 texture lookup
float4 inColor = tex2D(SrcSamp, In.TexCd);
float4 outColor = 0.0f;

//Conversion code taken from Nvidia and slightly changed
//http://developer.download.nvidia.com/shaderlibrary/webpages/shader_library.html
//RGB to HSV
float3 HSV = (0.0f).xxx;
float3 RGB = float3(inColor.r,inColor.g,inColor.b);
float minVal = min(RGB.r, min(RGB.g, RGB.b));    //Min. value of RGB
float maxVal = max(RGB.r, max(RGB.g, RGB.b));    //Max. value of RGB
float delta = maxVal - minVal;                   //Delta RGB value
HSV.z = maxVal;
if (delta != 0) {                    // If gray, leave H & S at zero
   HSV.y = delta / maxVal;
   float3 delRGB = ( ( ( maxVal.xxx - RGB ) / 6.0 ) + ( delta / 2.0 ) ) / delta;
   if      ( RGB.x == maxVal ) HSV.x = delRGB.z - delRGB.y;
   else if ( RGB.y == maxVal ) HSV.x = ( 1.0/3.0) + delRGB.x - delRGB.z;
   else if ( RGB.z == maxVal ) HSV.x = ( 2.0/3.0) + delRGB.y - delRGB.x;
   if ( HSV.x < 0.0 ) { HSV.x += 1.0; }
   if ( HSV.x > 1.0 ) { HSV.x -= 1.0; }
}
//adjust HSV

// HSV.x = clamp((HSV.x+Hue),0.0f,1.0f);
HSV.y = clamp((HSV.y+Saturation),0.0f,1.0f);
// HSV.z = clamp((HSV.z+Luminance),0.0f,1.0f);

//HSV to RGB
RGB = HSV.z;
if ( HSV.y != 0 ) {
   float var_h = HSV.x * 6;
   float var_i = floor(var_h);   // Or ... var_i = floor( var_h )
   float var_1 = HSV.z * (1.0 - HSV.y);
   float var_2 = HSV.z * (1.0 - HSV.y * (var_h-var_i));
   float var_3 = HSV.z * (1.0 - HSV.y * (1-(var_h-var_i)));
   if      (var_i == 0) { RGB = float3(HSV.z, var_3, var_1); }
   else if (var_i == 1) { RGB = float3(var_2, HSV.z, var_1); }
   else if (var_i == 2) { RGB = float3(var_1, HSV.z, var_3); }
   else if (var_i == 3) { RGB = float3(var_1, var_2, HSV.z); }
   else if (var_i == 4) { RGB = float3(var_3, var_1, HSV.z); }
   else                 { RGB = float3(HSV.z, var_1, var_2); }

}

return float4 (RGB.r,RGB.g,RGB.b,inColor.a);

}

// --------------------------------------------------------------------------------------------------
// TECHNIQUES:
// --------------------------------------------------------------------------------------------------

technique Fader
{
pass P0
{
VertexShader = compile vs_1_1 VS();
PixelShader = compile ps_2_0 ps_HSV();

//can I put here an RGBtoHSV, ConversionFunction and
//HSVtoRGB functions ??? Instead of one. And how to pass variables

}

}

technique TFixedFunction
{
pass P0
{
//transforms
WorldTransform0 = (tW);
ViewTransform = (tV);
ProjectionTransform = (tP);

    //texturing
    Sampler[0](0) = (SrcSamp);
    TextureTransform[0](0) = (tTex);
    TexCoordIndex[0](0) = 0;
    TextureTransformFlags[0](0) = COUNT2;
    //Wrap0 = U;  // useful when mesh is round like a sphere
    
    Lighting       = FALSE;

    //shaders
    VertexShader = NULL;
    PixelShader  = NULL;
}

}

^

Hi Frank,
if your graphic card supports it you should try to change PS 2.0 to 2.a ; 2.b or even 3.0…Then you’ll be able to compute more than 64 instructions.

this one is at least similar and needs PS 2.a.
i try to strip it down.

ShiftHSV.zip (46.4 kB)

Thanks Kalle and Desaximundi.

I tried your patch (looks very slim - nice), but sadly, my graphic card didn’t support PS2.a.

So, have to use for every adjustment an extra technique/function. Not nice, but it works.

Hi guys,

just thought you might be interested to know I’ve been working towards a method for converting HLSL shaders to GLSL, for use on non-Windows machines. It’s early days, yet, but I’ve managed to convert Ernst Hot’s Gradients Pixel Shader to work as a GLSL shader in Quartz Composer on the Mac. I’d post the code, but I haven’t been able to get in touch with Ernst to ask his permission to use his code yet. Anyone heard from him lately? He doesn’t seem to be answering his private messages here, for some reason…

There’s a little about the project on my blog at

Cheers,

alx