RGB shift shader

Hi all,
I’m trying to port my HLSL shader that makes a simple RGB shift and ended up with shifting the entire texture left or right instead of only shifting red, green, blue pixels.

float4 PSSmoothen(VertexShaderOutput input) : COLOR0
{
float hPixel = 1.0f / width;
float vPixel = 1.0f / height;

float3 color = float3(0, 0, 0);
float redX = 3hPixel;
float redY = -2
vPixel;
float greenX = 4*hPixel;
color.r = tex2D(TextureSampler, input.TexCoord + float2(redX,redY )).r;
color.g = tex2D(TextureSampler, input.TexCoord + float2(greenX, 0)).g;
color.b = tex2D(TextureSampler, input.TexCoord).b;

return float4(color, 1);
}

Any help would be appreciated.

If the pixels aren’t being separated by color, then your offset is evaluating to 0. Following your variables back, it must mean your ‘height’ and ‘width’ don’t have the correct values.

Unity has built-in shader variables for width and height in _ScreenParams.x and _ScreenParams.y.

Though you shouldn’t be using those at all. You should calculate the offsets in script, and set Property values in the shader that you can simply reference. Right now you are re-doing the pixel offset calculations for each pixel for no reason (at least 5 multiplies per pixel). You may want to calculate a different offset for each pixel, but even then you should pre-calculate hPixel and vPixel. The screen size certainly isn’t going to change between pixels in the middle of a shader pass.

Also, you texture is shifting because you are sampling from the texture coordiantes with an offset. For changing just the colour of the texture, you will want to sample the whole texture and then change specific colours by values probably passed in via a script that TheShane mentioned:

fixed4 color = tex2D(TextureSampler, input.TexCoord);
color.r *= [Some value to change colour]
color.g*= [Some  value to change colour]
color.b *= [Some  value to change colour]

Are you trying to shift the red, green and blue color planes separately? Try this:

Shader "Rectalogic/ColorShift" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _RedShiftX ("Red Shift X", Range(-10, 10)) = 3.0
        _RedShiftY ("Red Shift Y", Range(-10, 10)) = -2.0
        _GreenShiftX ("Green Shift X", Range(-10, 10)) = 4.0
        _GreenShiftY ("Green Shift Y", Range(-10, 10)) = 0.0
        _BlueShiftX ("Blue Shift X", Range(-10, 10)) = 0.0
        _BlueShiftY ("Blue Shift Y", Range(-10, 10)) = 0.0
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
        
        CGPROGRAM
        #pragma surface surf Lambert

        sampler2D _MainTex;
        half _RedShiftX;
        half _RedShiftY;
        half _GreenShiftX;
        half _GreenShiftY;
        half _BlueShiftX;
        half _BlueShiftY;
        half2 _MainTex_TexelSize;

        struct Input {
            float2 uv_MainTex;
        };

        void surf(Input IN, inout SurfaceOutput o) {
            half2 redShift = half2(_RedShiftX, _RedShiftY) * _MainTex_TexelSize;
            half2 greenShift = half2(_GreenShiftX, _GreenShiftY) * _MainTex_TexelSize;
            half2 blueShift = half2(_BlueShiftX, _BlueShiftY) * _MainTex_TexelSize;
            half3 c;
            c.r = tex2D(_MainTex, IN.uv_MainTex + redShift).r;
            c.g = tex2D(_MainTex, IN.uv_MainTex + greenShift).g;
            c.b = tex2D(_MainTex, IN.uv_MainTex + blueShift).b;
            o.Albedo = c.rgb;
            o.Alpha = 1.0;
        }
        ENDCG
    } 
    FallBack "Diffuse"
}

Hi! rectalogic, any idea, why it’s ain’t working for me without adding “#pragma target 3.0”(platform-Windows)?

Thank you rectalogic.
If I add “#pragma target 3.0” as mouurusai specified it works just fine.