Colorize shader to complex to render on sm 2.0

Hi,

I’ve got a problem with a colorize shader (based on Photoshop Color blending mode) which has to run on sm 2.0 but is to complex (not enough arithmetic instructions). The shader is based on moafi implementation:
http://mouaif.wordpress.com/2009/01/05/photoshop-math-with-glsl-shaders/
Basically converting from RGB to HSL and back consumes too much instruction slots. As far as know the solution to this could be to divide the shader to a few passes and use a render target to accumulate the calculations for each pixel. Is this the only way of doing this?

Do you mean that kind of effect where you desaturate the image and turn the grays into a predefined color, but leaving blacks and whites as they are? I doubt you need to convert to HSL and back to do that.

Try this (not tested):

float3 colorize(float3 input, float3 color) {
    float luma = saturate(dot(input, float3(0.299, 0.587, 0.114)));
    return lerp(color, luma, abs(luma - 0.5) * 2.0);
}

With regards to color, that usually mostly refers to HUE, so I guess converting to hue first is one way to do it. Not sure how the math is different. Depends what final results you want. Dolkar’s example will colorize the grayscale version, if that’s ok.

Thanks for the example. Although it’s far from the effect I want to achieve, it’s a good start to play with.

I could be able to help you out if you describe what kind of effect you are after. :wink:

Thank you Dolkar:). Attached is the shader I am currently using. It is used to colorize 2D textures using the Color parameter. I would like to be able to produce the same effect using only sm2.0.

1487425–82830–$Colorize.zip (2.12 KB)

I’d say this behaves similarly to yours:

float RGBToL(float3 color) {
     float fmin = min(min(color.r, color.g), color.b);
     float fmax = max(max(color.r, color.g), color.b);
     return (fmax + fmin) / 2.0;
}
            
float3 BlendColor(float3 base, float3 blend, half balance) {
    float baseLightness = RGBToL(base);
    float blendLightness = RGBToL(blend);
    return lerp(blendLightness, blend, balance) * (baseLightness / blendLightness);
}

It takes the blend color, desaturates it based on the balance and then scales it in such a way that baseLightness = blendLightness.

Unfortunately your solution seems to keep the color in grayscale just modyfing the lightness. No color is applied to the texture.

It works just fine for me. Make sure the balance value is not 0.
And it should actually do the opposite. It keeps the lightness constant, just changes the color.

I was able to make the shader work thanks to Ian Taylor and his RGB<->HSL(HSV) conversion implementation. Attached is a Colorize shader which can be run on sm2.0 devices (one pass).

1512886–85946–$Colorize_SM20.zip (1.44 KB)