围绕枢轴旋转纹理的一部分

时间:2019-11-02 14:48:00

标签: rotation pivot textures hlsl sample

我想“遮盖”采样纹理的某个区域并以圆周运动旋转该部分。遮罩也在uv贴图周围移动。

https://ibb.co/JshCDFZ

这个新手..我知道我在某个地方错过了一步。 任何小费表示赞赏!

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;
}


1 个答案:

答案 0 :(得分:0)

自己找到解决方案。.

在顶点着色器中旋转更容易,因为它使用-1到1坐标系。 首先将uv转换到中心,然后旋转,然后再转换回其原始位置


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() ) );
    }
}


``