试图逆转 HLSL 像素着色器

Trying to reverse HLSL Pixel Shader

我正在学习 HLSL 语言并且有一个我尝试逆向的汇编代码:

mul r0.x, cb0[11].z, cb1[69].w
frc r0.x, r0.x
add r0.y, r0.x, l(0.500000)
frc r0.y, r0.y
add r0.z, r0.y, l(0.250000)
frc r0.z, r0.z
add r0.w, r0.z, l(0.500000)
frc r0.w, r0.w
mul r1.x, r0.w, l(6.283185)
sincos null, r1.x, r1.x

下面是我尝试逆向汇编代码时写的:

float3 ps_main( const PixelInput pixel ) : SV_TARGET
{
    float4 Scroll;
    Scroll.x = frac(colorScroll.z * gameTime.w);
    Scroll.y = frac( Scroll.x + 0.5f);
    Scroll.z = frac( Scroll.y + 0.25f);
    Scroll.w = frac( Scroll.z + 0.5f);

    float3 ScollSpeed =  Scroll.w * 6.283185f;

    return ScollSpeed;
}

但是在编译这个的时候,会生成如下的汇编代码:

dcl_temps 1
mul r0.x, cb0[11].z, cb1[69].w
frc r0.x, r0.x
add r0.x, r0.x, l(0.500000)
frc r0.x, r0.x
add r0.x, r0.x, l(0.250000)
frc r0.x, r0.x
add r0.x, r0.x, l(0.500000)
frc r0.x, r0.x
mul o0.xyz, r0.xxxx, l(6.283185, 6.283185, 6.283185, 0.000000)
ret 

为什么我所有的变量都是r0.x?我希望 Scroll.y 与原始程序集中的 r0.y 一样。

编译器正在优化您的代码以优化寄存器的使用,因为您只在最后使用 w 组件,所以 xyz 可以打包成一个标量:

float3 ScollSpeed =  Scroll.w * 6.283185f;

它检测到 ScollSpeed.xyz 不需要,并且可以打包在一个 float 中(下面的代码是等效的):

float3 PS(  ) : SV_TARGET
{
    float Scroll;
    Scroll = frac(colorScroll.z * gameTime.w);
    Scroll = frac( Scroll + 0.5f);
    Scroll = frac( Scroll + 0.25f);
    Scroll = frac( Scroll + 0.5f);

    float3 ScollSpeed =  Scroll * 6.283185f;

    return ScollSpeed;
}

然后它只需要第一个寄存器组件来执行整个操作(因此你只有 r0.x)