lilxyzw / lilToon

Feature-rich shaders for avatars
MIT License
927 stars 95 forks source link

Decal Rotation #119

Open Rafacasari opened 1 year ago

Rafacasari commented 1 year ago

Currently, if I try to rotate the decal that I've positioned, it will totally move and lose the position that I've already set.

lilToon https://github.com/lilxyzw/lilToon/assets/32463720/e5ef559a-8f7d-47df-adea-4b9ac3518f4c

Poiyomi (for example) https://github.com/lilxyzw/lilToon/assets/32463720/71953808-d3c3-4538-aac8-208de0e80e62

Seems that the decal isn't rotating in its own axis

Rafacasari commented 1 year ago

I've tried to fix it by myself, but I've never touched shader coding and my brain was on fire trying to understand math. But I was able to almost fix it by changing the end of lilCalcDecalUV function

float2 lilCalcDecalUV(float2 uv, float4 uv_ST, float angle, bool isLeftOnly, bool isRightOnly, bool shouldCopy, bool shouldFlipMirror, bool shouldFlipCopy, bool isRightHand)
{
    float2 outUV = uv;

    // Copy
    if(shouldCopy) outUV.x = abs(outUV.x - 0.5) + 0.5;

    // Scale & Offset
    outUV = outUV * uv_ST.xy + uv_ST.zw;

    // Flip
    if(shouldFlipCopy && uv.x<0.5) outUV.x = 1.0 - outUV.x;
    if(shouldFlipMirror && isRightHand) outUV.x = 1.0 - outUV.x;

    // Hide
    if(isLeftOnly && isRightHand) outUV.x = -1.0;
    if(isRightOnly && !isRightHand) outUV.x = -1.0;

    // Rotate

    // FROM THIS
    //outUV = (outUV - uv_ST.zw) / uv_ST.xy;
    //outUV = lilRotateUV(outUV, angle);
    //outUV = outUV * uv_ST.xy + uv_ST.zw;

    // TO THIS
    float2 center = (uv_ST.zw / 2) / uv_ST.xy;
    outUV = lilRotateUV(outUV - center, angle) + center;

    return outUV;
}

It's kinda a hacky way, but I think with some polishment it will be totally fixed.

lilxyzw commented 1 year ago

Thank you! I will also think about the calculation method.

Rafacasari commented 5 months ago

@lilxyzw Updating the center variable to this seems to completely fix my issue, feel free to give some tests before merging. (full code in PR #182)

float2 center = (uv_ST.zw / 2) / (uv_ST.xy * uv_ST.zw);