Search code examples
rotationpivottextureshlslsample

rotate part of texture around pivot


I would like to "mask" a area of the sampled texture and rotate that part in circular motion. the mask is also moving around the uv map.

https://ibb.co/JshCDFZ

new to this.. I know I miss a step somewhere.. any tipps appreciated!

float4 PS_circleSampler(psInput In): SV_Target
{
    float2 uv = In.TexCd.xy;
    float4 col;

    float s = sin(phase);
    float c = cos(phase);
    float2x2 rotationMatrix = float2x2(c, -s, 
                                      s, c);    

    float4 colOriginal = texA.Sample(linearSampler, uv);
    float4 colRotated = texA.Sample(linearSampler,  mul( pos - uv, rotationMatrix ));       

    float inCircle = 0.5 - distance (In.TexCd.xy, pos);

    colOriginal *= 1- ceil(inCircle);
    colRotated *= ceil(inCircle) ;


    return colOriginal + colRotated;
}



Solution

  • found the solution myself..

    rotating in vertex shader is easier because it uses a -1 to 1 coordinate system. first translating the uv to the center, then roating, then translating back to its original pos

    
    float2 pos;
    float radius;
    float phase;
    
    Texture2D texA <string uiname="Texture A";>;
    Texture2D texB <string uiname="Texture B";>;
    
    cbuffer cbPerDraw : register( b0 )
    {
        float4x4 tVP : LAYERVIEWPROJECTION; 
    };
    
    cbuffer cbPerObj : register( b1 )
    {
        float4x4 tW : WORLD;
    };
    
    SamplerState linearSampler
    {
        Filter = MIN_MAG_MIP_LINEAR;
        AddressU = Clamp;
        AddressV = Clamp;
    };
    
    struct vsInput
    {
        float4 PosO : POSITION;
        float2 TexCd : TEXCOORD0;
    
    };
    
    struct psInput
    {
        float4 PosWVP: SV_Position;
        float2 TexCd: TEXCOORD0;
        float2 TexCdRotated: TEXCOORD1;
    };
    
    psInput VS(vsInput In)
    {   
        psInput output;
    
        float2 uv = In.TexCd;
        float2 center = pos;
    
    
        float s = sin(phase);
        float c = cos(phase);       
    
        float2x2 rotationMatrix = float2x2(c, -s,
                                            s, c);
    
        float2 uv2 = uv - center; // translate into center
        uv2 = mul(uv2, rotationMatrix);    // rotate the space    
        uv2 += center; // move it back to the original place
    
    
        output.TexCdRotated = uv2;
    
        output.PosWVP = In.PosO;
        output.TexCd = In.TexCd;
    
    
        return output;
    }
    
    
    float4 PS_circleSampler(psInput In): SV_Target
    {
        float2 uv = In.TexCd.xy;
        float2 uvRot = In.TexCdRotated.xy;      
    
        float4 colOriginal = texA.Sample(linearSampler, uv);
        float4 colRotated = texA.Sample(linearSampler,  uvRot );
    
    
        float inCircle = radius - distance (In.TexCd.xy, pos);
    
        colOriginal *= 1- ceil(inCircle);
        colRotated *= ceil(inCircle) ;
    
        return colOriginal + colRotated;
    }
    
    
    technique10 circleSampler
    {
        pass P0
        {
            SetVertexShader( CompileShader( vs_4_0, VS() ) );
            SetPixelShader( CompileShader( ps_4_0, PS_circleSampler() ) );
        }
    }
    
    
    ``