Deform pixels (Unity3D)

Good afternoon.
I created a shader to pixelate an image on unity.
Now I want to deform the pixels into a X shape.

Pixelated Image:

float4 GetSource(float2 fxUV) {
    return SAMPLE_TEXTURE2D(_PostFXSource, sampler_PostFXSource, fxUV);
}
 
float lightIntensity(float2 fxUV, float thr) {
    float4 colorChannel = GetSourceThreshold(fxUV, thr);
    colorChannel = (pow(colorChannel, 4) * 2) / 333;
    float greyscale = (colorChannel.r + colorChannel.g + colorChannel.b) / 3.0f;
    return greyscale;
}
 
float4 frag(Varyings i) : SV_Target
{
 
                float4 colorChannel = GetSource(i.fxUV);
                float2 uvFX = i.fxUV.xy;
 
                float4 result = float4(0, 0, 0, 0);
               
                    uvFX.x *= _PixelColumns;
                    uvFX.y *= _PixelRows;
 
                    uvFX.x = round(uvFX.x);
                    uvFX.y = round(uvFX.y);
 
                    uvFX.x /= _PixelColumns;
                    uvFX.y /= _PixelRows;
 
                    float greyscale = lightIntensity(uvFX, 1);
 
                    float4 r = float4(greyscale, greyscale, greyscale, 1);
                    result += normalize(r);
 
                if (_Debug == 0)
                return float4(colorChannel.rgb + result, colorChannel.a);
                else {
                return float4(result.rgb, 1);
                }
 
             }

This code is in HLSL! Sorry!

In summary, I want to deform the squares in the shape of X or +.(Stars)

Is it possible to do that?
How can I create this effect?

I assume that you created a geometric model, a pair of shaders and stored model-data somewhere. I assume that you draw each cube with a number of draw-calls. Under these assumptions, you could repeat the group of draw-calls on the same data, but with a translation offset … to get to a cross-like appearance for say 5 or 6 group-calls.
As for stars (or crosses for that matter), I wouldn’t attempt to deform, but store the extra vertex-data for each object and decide at the draw-call, which verticies to use (ie draw-elements).
… I don’t really understand your question: Any notion of doing a d2->d2 image-transform as you kind’a suggest, is a stray-path that leads nowhere.

Thanks for answering!

I’m a shader beginner, I don’t understand much about geometry shaders.
What I want to do is a glare effect, placing these “stars” in the most luminous places.

In this format:
Sem Título-1

My Code:

Shader "Hidden/ScreenSpaceLensFlare"
{
    Properties
    {
        //_MainTexCamera ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType" = "Opaque" }

        ZTest Always Cull Off ZWrite Off

        HLSLINCLUDE
        #include "../../ShaderLibrary/Common.hlsl"
        ENDHLSL

        Pass
        {
            HLSLPROGRAM
            #pragma target 3.5
            #pragma vertex DefaultPassVertex
            #pragma fragment frag

            #include "../../ShaderLibrary/UnityInput.hlsl"
            //#include "../../ShaderLibrary/Light.hlsl"

            TEXTURE2D(_PostFXSource);
            SAMPLER(sampler_PostFXSource);

            TEXTURE2D(_DirtyTexture);
            SAMPLER(sampler_DirtyTexture);

            TEXTURE2D(_Spectral);
            SAMPLER(sampler_Spectral);

            TEXTURE2D(_CameraDeep);
            SAMPLER(sampler_CameraDeep);

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct Varyings {
                float4 positionCS : SV_POSITION;
                float2 fxUV : VAR_FX_UV;
            };

            Varyings DefaultPassVertex(uint vertexID : SV_VertexID) {
                Varyings output;
                output.positionCS = float4(
                    vertexID <= 1 ? -1.0 : 3.0,
                    vertexID == 1 ? 3.0 : -1.0,
                    0.0, 1.0
                    );
                output.fxUV = float2(
                    vertexID <= 1 ? 0.0 : 2.0,
                    vertexID == 1 ? 2.0 : 0.0
                    );
                if (_ProjectionParams.x < 0.0) {
                    output.fxUV.y = 1.0 - output.fxUV.y;
                }
                return output;
            }

            float _Intensity = 1;
            float _PixelColumns = 64;
            float _PixelRows = 64;
            float _Glare = 0;
            
            int _Debug = 0;



float4 GetSource(float2 fxUV) {
    return SAMPLE_TEXTURE2D(_PostFXSource, sampler_PostFXSource, fxUV);
}
static const float ghosts[15] = {
           -0.07014, 0.08258, -0.09, 0.020, -0.0310625, 0.0320625,	-0.025414, -0.065258, 0.051, 0.031, 0.011, 0.02866, 0.0567777765, 0.071578, 0.067891,
};
float4 Glarator(float2 fxUV,int y) : SV_Target
{
    float4 color = float4(0, 0, 0, 0);
    float2 uv = fxUV - 0.5;

    for (int i = 0; i < y; i++) {
        float projection = ghosts[i];

        float4 colorScene = GetSource(fxUV * projection + 0.52);

        float4 colorChannel = -colorScene;// + pow(colorScene, 4);
        float greyscale = (colorScene.r + colorScene.g + colorScene.b) / 3.0f;
        colorChannel = float4(greyscale, greyscale, greyscale, colorScene.a);

        color += colorChannel * (projection * projection);
    }
    return color;
}

float4 GetSourceThreshold(float2 fxUV, float thr) {
    return SAMPLE_TEXTURE2D(_PostFXSource, sampler_PostFXSource, (fxUV - 0.5) / thr + 0.5);
}

float3 textureDistorted(float2 fxUV) {
    float2 direction = normalize(fxUV - 0.5);
    float r = GetSourceThreshold(fxUV * direction * float3(0, 0, 0.1),20).r;
    float g = GetSourceThreshold(fxUV * direction * float3(0, 0, 0.1),20).g;
    float b = GetSourceThreshold(fxUV * direction * float3(0, 0, 0.1),20).b;
    return float3(r, g, b);
}

float lightIntensity(float2 fxUV, float thr) {
    float4 colorChannel = GetSourceThreshold(fxUV, thr);
    colorChannel = ((+pow(colorChannel, 4)) * 1) / 333;
    float greyscale = (colorChannel.r + colorChannel.g + colorChannel.b) / 3.0f;
    return greyscale;
}

float4 frag(Varyings i) : SV_Target
{

                float4 colorChannel = GetSource(i.fxUV);
                float2 uvFX = i.fxUV.xy;

                float4 result = float4(0, 0, 0, 0);
  
                if (_Glare == 1) {
                   
                    uvFX.x *= _PixelColumns;
                    uvFX.y *= _PixelRows;

                    uvFX.x = floor(uvFX.x);
                    uvFX.y = floor(uvFX.y);

                    uvFX.x /= _PixelColumns;
                    uvFX.y /= _PixelRows;

                    float greyscale = lightIntensity(uvFX, 1);

                    float4 r = float4(greyscale, greyscale, greyscale, 1);
                    //r = pow(r, 10);
                    result += normalize(r);
                 }

                if (_Debug == 0)
                return float4(colorChannel.rgb + result, colorChannel.a);
                else {
                return float4(result.rgb, 1);
                }

             }
            ENDHLSL
        }
    }
}

I found a project where an effect similar to what I want is done:
https://github.com/keijiro/KinoStreak

This is the keijiro code:

// Kino/Streak - Anamorphic lens flare effect for Unity
// https://github.com/keijiro/KinoStreak

#include "UnityCG.cginc"

sampler2D _MainTex;
float4 _MainTex_TexelSize;

sampler2D _HighTex;
float4 _HighTex_TexelSize;

float _Threshold;
float _Stretch;
float _Intensity;
half3 _Color;

// Prefilter: Shrink horizontally and apply threshold.
half4 frag_prefilter(v2f_img i) : SV_Target
{
    // Actually this should be 1, but we assume you need more blur...
    const float vscale = 1.5;
    const float dy = _MainTex_TexelSize.y * vscale / 2;

    half3 c0 = tex2D(_MainTex, float2(i.uv.x, i.uv.y - dy));
    half3 c1 = tex2D(_MainTex, float2(i.uv.x, i.uv.y + dy));
    half3 c = (c0 + c1) / 2;

    float br = max(c.r, max(c.g, c.b));
    c *= max(0, br - _Threshold) / max(br, 1e-5);

    return half4(c, 1);
}

// Downsampler
half4 frag_down(v2f_img i) : SV_Target
{
    // Actually this should be 1, but we assume you need more blur...
    const float hscale = 1.25;
    const float dx = _MainTex_TexelSize.x * hscale;

    float u0 = i.uv.x - dx * 5;
    float u1 = i.uv.x - dx * 3;
    float u2 = i.uv.x - dx * 1;
    float u3 = i.uv.x + dx * 1;
    float u4 = i.uv.x + dx * 3;
    float u5 = i.uv.x + dx * 5;

    half3 c0 = tex2D(_MainTex, float2(u0, i.uv.y));
    half3 c1 = tex2D(_MainTex, float2(u1, i.uv.y));
    half3 c2 = tex2D(_MainTex, float2(u2, i.uv.y));
    half3 c3 = tex2D(_MainTex, float2(u3, i.uv.y));
    half3 c4 = tex2D(_MainTex, float2(u4, i.uv.y));
    half3 c5 = tex2D(_MainTex, float2(u5, i.uv.y));

    // Simple box filter
    half3 c = (c0 + c1 + c2 + c3 + c4 + c5) / 6;

    return half4(c, 1);
}

// Upsampler
half4 frag_up(v2f_img i) : SV_Target
{
    half3 c0 = tex2D(_MainTex, i.uv) / 4;
    half3 c1 = tex2D(_MainTex, i.uv) / 2;
    half3 c2 = tex2D(_MainTex, i.uv) / 4;
    half3 c3 = tex2D(_HighTex, i.uv);
    return half4(lerp(c3, c0 + c1 + c2, _Stretch), 1);
}

// Final composition
half4 frag_composite(v2f_img i) : SV_Target
{
    half3 c0 = tex2D(_MainTex, i.uv) / 4;
    half3 c1 = tex2D(_MainTex, i.uv) / 2;
    half3 c2 = tex2D(_MainTex, i.uv) / 4;
    half3 c3 = tex2D(_HighTex, i.uv);
    half3 cf = (c0 + c1 + c2) * _Color * _Intensity * 5;
    return half4(cf + c3, 1);
}

But he creates the glares in just one direction.
I also didn’t understand what are these Downsampler and Upsampler

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.