HLSL 'optimizing' 使用变量

HLSL 'optimizing' used variable

这是我的二维多边形着色器。出于某种原因,即使顶点着色器是 运行 穿过所有的墙,编译器仍然将其视为未使用的变量并将其优化掉,这意味着当我尝试从 monogame 实际设置参数时,参数为空且未设置。我不明白为什么着色器认为 'walls' 变量显然没有被使用。

#if OPENGL
    #define SV_POSITION POSITION
    #define VS_SHADERMODEL vs_3_0
    #define PS_SHADERMODEL ps_3_0
#else
    #define VS_SHADERMODEL vs_4_0_level_9_1
    #define PS_SHADERMODEL ps_4_0_level_9_1
#endif

matrix WorldViewProjection;
float4 walls[6];
float2 lightPos = float2(0, 0);
float4 lightColor = float4(0, 0, 0, 1.0);

struct VertexShaderInput
{
    float4 Position : POSITION0;
    float4 Color : COLOR0;
};

struct VertexShaderOutput
{
    float4 Position : SV_Position;
    float4 Color : COLOR0;
    float2 ScreenPos : TEXCOORD0;
};


int orientation(float2 p, float2 q, float2 r)
{
    int val = (q.y - p.y) * (r.x - q.x) -
        (q.x - p.x) * (r.y - q.y);
    if (val == 0)
        return 0;
    if (val > 0)
        return 1;
    return 2;
}

bool onSegment(float2 p, float2 q, float2 r)
{
    if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) &&
        q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y))
        return true;
    return false;
}

bool intersect(float2 p1, float2 q1, float2 p2, float2 q2)
{
    int o1 = orientation(p1, q1, p2);
    int o2 = orientation(p1, q1, q2);
    int o3 = orientation(p2, q2, p1);
    int o4 = orientation(p2, q2, q1);

    if (o1 != o2 && o3 != o4)
        return true;

    if (o1 == 0 && onSegment(p1, p2, q1))
        return true;
    if (o2 == 0 && onSegment(p1, q2, q1))
        return true;
    if (o3 == 0 && onSegment(p2, p1, q2))
        return true;
    if (o4 == 0 && onSegment(p2, q1, q2))
        return true;

    return false;
}

float map(float value, float min1, float max1, float min2, float max2)
{
    return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
}


VertexShaderOutput MainVS(in VertexShaderInput input)
{
    VertexShaderOutput output = (VertexShaderOutput)0;
    
    float2 screenPos = input.Position.xy;
    output.ScreenPos = screenPos;
    output.Position = mul(input.Position, WorldViewProjection);
    
    bool collided = true;
    
    //Run through all the wall segments and make sure light actually hits this vertex
    for (int i = 0; i < 6; i++)
    {
        float2 p = float2(walls[i].x, walls[i].y), q = float2(walls[i].z, walls[i].w);
        
        if (intersect(lightPos, screenPos, p, q))
        {
            //The light hits a wall before hitting this vertex
            collided = false;
        }
    }
    
    float4 color = input.Color;
    
    if (!collided)
    {
        color = float4(0, 0, 0, 0);
    }
    else
    {
        color *= lightColor;
        color.a = map(distance(screenPos, lightPos), 0, 150, 1.0f, 0);
    }
    output.Color = color;
    
    return output;
}


float4 MainPS(VertexShaderOutput input) : COLOR
{
    return input.Color;
}

technique BasicColorDrawing
{
    pass P0
    {
        VertexShader = compile VS_SHADERMODEL MainVS();
        PixelShader = compile PS_SHADERMODEL MainPS();
    }
};

能够通过在循环之前添加一个 [unroll] 来摆脱编译器优化,这允许在顶点着色器中设置 walls 变量并随后解析数组。