Optimization HLSL着色器的优化

Optimization HLSL着色器的优化,optimization,xna,shader,hlsl,Optimization,Xna,Shader,Hlsl,我正在尝试为我的XNA游戏优化我的地形着色器,因为它似乎消耗了很多资源。在我的计算机上大约需要10到20 FPS,而我的地形是512*512个顶点,所以PixelShader被调用了很多次 我已经看到分支使用了一些资源,我的着色器中有3/4个条件。 我该怎么做才能绕过他们?三元运算符是否比条件更有效 例如: float a = (b == x) ? c : d; 或 我还多次使用了函数lerp和clamp,使用算术运算是否更有效 下面是我代码中效率较低的部分: float fog;

我正在尝试为我的XNA游戏优化我的地形着色器,因为它似乎消耗了很多资源。在我的计算机上大约需要10到20 FPS,而我的地形是512*512个顶点,所以PixelShader被调用了很多次

我已经看到分支使用了一些资源,我的着色器中有3/4个条件。 我该怎么做才能绕过他们?三元运算符是否比条件更有效

例如:

float a = (b == x) ? c : d;

我还多次使用了函数lerp和clamp,使用算术运算是否更有效

下面是我代码中效率较低的部分:

    float fog;
    if(FogWaterActivated && input.WorldPosition.y-0.1 < FogWaterHeight)
    {
        if(!IsUnderWater)
            fog = clamp(input.Depth*0.005*(FogWaterHeight - input.WorldPosition.y), 0, 1);
        else
            fog = clamp(input.Depth*0.02, 0, 1);

        return float4(lerp(lerp( output * light, FogColorWater, fog), ShoreColor, shore), 1);
    }
    else
    {
        fog = clamp((input.Depth*0.01 - FogStart) / (FogEnd - FogStart), 0, 0.8);
        return float4(lerp(lerp( output * light, FogColor, fog), ShoreColor, shore), 1);
    }
float-fog;
如果(雾化水激活和输入.WorldPosition.y-0.1<雾化水高度)
{
如果(!在水下)
fog=夹具(输入深度*0.005*(FogWaterHeight-input.WorldPosition.y),0,1);
其他的
fog=夹具(输入深度*0.02,0,1);
返回浮标4(lerp(lerp(输出*光,雾色水,雾),ShoreColor,shore),1);
}
其他的
{
fog=夹具((输入深度*0.01-FogStart)/(FogEnd-FogStart),0,0.8);
返回浮点数4(lerp(lerp(输出*灯光,雾色,雾色),ShoreColor,shore),1);
}

谢谢

任何时候都可以更好地预先计算对着色器常量执行的操作。另一个有用的技巧是通过将逆运算传递到着色器中来删除除法运算,因为除法通常比乘法慢


在你的例子中,预先计算(1/(FogEnd-FogStart)),然后在你的最后一行代码上乘以它。

我在我编写的着色器中有一堆
if
语句,大约是
20fps
。然后我删除了
if
语句并使用alpha映射,得到了
60fps
easy。我会尝试用alpha图之类的东西替换我的
if
语句,看看这是否有帮助。(或者尝试注释
if
语句,看看是否有很大区别。)
FogWaterActivated
IsUnderWater
全局着色器参数是否已激活?如果是这样,您可以删除条件并将不同的代码路径实现为不同的着色器技术。谢谢您的想法!我是HLSL的新手,我没有想过。事实上,这两个参数是全局的,所以你认为我应该为每种情况创建4种技术(雾和水下,!雾和水下,雾和水下,!雾和水下)?我不能说你是否应该;我只能说,这样做将允许您删除几个条件。试试看,测量一下结果!谢谢我没有获得很多FPS,但仍然值得。我还有一个问题,我这里有两个“lerp”:
float4(lerp(输出*光,雾,雾,水,雾),ShoreColor,shore),1)你认为有什么把戏可以让你只用一个来达到同样的效果吗?
    float fog;
    if(FogWaterActivated && input.WorldPosition.y-0.1 < FogWaterHeight)
    {
        if(!IsUnderWater)
            fog = clamp(input.Depth*0.005*(FogWaterHeight - input.WorldPosition.y), 0, 1);
        else
            fog = clamp(input.Depth*0.02, 0, 1);

        return float4(lerp(lerp( output * light, FogColorWater, fog), ShoreColor, shore), 1);
    }
    else
    {
        fog = clamp((input.Depth*0.01 - FogStart) / (FogEnd - FogStart), 0, 0.8);
        return float4(lerp(lerp( output * light, FogColor, fog), ShoreColor, shore), 1);
    }