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 变量并随后解析数组。
这是我的二维多边形着色器。出于某种原因,即使顶点着色器是 运行 穿过所有的墙,编译器仍然将其视为未使用的变量并将其优化掉,这意味着当我尝试从 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 变量并随后解析数组。