【问题标题】:Blur parts of image monogame pixelshader模糊图像monogame像素着色器的部分
【发布时间】:2021-04-24 01:33:09
【问题描述】:

所以我设法提出了一个着色器,它将根据某些线段的位置来阻挡图像的某些部分(总结像素着色器,它只是检查从灯光中心到任何给定的像素与任何“墙”线段相交,因此如果是这样就不会绘制图像)。

但是,我的问题是光线的截止非常尖锐,我想稍微模糊一下,不要模糊光线与墙段相交的硬边。什么是实现这一目标的好方法?我附上了正在运行的着色器的 gif 图像和相关代码。

Light Shader

Stuff circled in red should be blurry, green should remain sharp

float4 MainPS(VertexShaderOutput input) : COLOR
{
    float4 color = tex2D(s0, input.TextureCoordinates);
    float2 centerPos = float2(150.0f + mX, 150.0f + mY);
    float2 coords = float2((input.TextureCoordinates.x * 300) + mX, (input.TextureCoordinates.y * 300) + mY);

    //change alpha based on distance
    color.w = map(distance(centerPos, coords), 0, 150, .5, .1f);
    //If the line segment from the center to this pixel intersects any given line segment (hardcoded for now, don't draw it)
    if (intersect(centerPos, coords, float2(160.0f, 200.0f), float2(200.0f, 140.0f)) || 
    intersect(centerPos, coords, float2(160.0f, 200.0f), float2(250.0f, 200.0f)) || intersect(centerPos, coords, float2(200.0f, 140.0f), float2(250.0f, 200.0f)))
        color = float4(0, 0, 0, 0);
    return color;
}

任何帮助/提示将不胜感激。

【问题讨论】:

    标签: c# monogame hlsl


    【解决方案1】:

    除了计算从中心到当前像素的线是否与线段相交,还可以计算出交点的准确位置,然后利用交点到当前像素的距离来柔化阴影,类似于以下内容:

    float2 intersectionPos;
    if (intersect(centerPos, coords, float2(160.0f, 200.0f), float2(200.0f, 140.0f), intersectionPos) ||
        intersect(centerPos, coords, float2(160.0f, 200.0f), float2(250.0f, 200.0f), intersectionPos) || 
        intersect(centerPos, coords, float2(200.0f, 140.0f), float2(250.0f, 200.0f), intersectionPos)) 
    {
        color.w *= lerp(1, 0, saturate(distance(coords, intersectionPos) / BLUR_DISTANCE))
    }
    

    其中BLUR_DISTANCE 是一个小数字,表示从线段到模糊像素的距离,intersect 定义为:

    bool intersect(float2 origin, float2 point, float2 segEnd1, float2 segEnd2, inout float2 intersectionPos) {
        // implement this to set intersectionPos *only* if there's actually an intersection
    } 
    

    为了更漂亮的结果,您可以使用非线性插值函数,或者计算到直线上最近点的距离而不是射线交点,但基本思想是相同的。

    【讨论】:

    • 对不起,当我尝试使用具有相同着色器的多个灯光时,我刚刚注意到一个单独的问题 - 线段似乎在移动?我觉得这和我在绘制之前如何设置灯光的参数有关?
    • _spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Additive); lightEffect.CurrentTechnique.Passes[0].Apply(); lightEffect.Parameters["mX"].SetValue(pos.X); lightEffect.Parameters["mY"].SetValue(pos.Y); _spriteBatch.Draw(lightTexture, pos, Color.White); lightEffect.Parameters["mX"].SetValue(pos.X + 50); lightEffect.Parameters["mY"].SetValue(pos.Y + 50); _spriteBatch.Draw(lightTexture, pos + new Vector2(50, 50), Color.White); _spriteBatch.End();
    • 想通了,这与调用顺序有关吗?设置参数值和应用技术通道的正确程序是什么?
    • @AdrianWheeler 虽然我知道 HLSL,但我对 MonoGame 的细节一无所知。如果你再次遇到它,你可以再问一个问题,更有资格的人可以提供帮助。
    猜你喜欢
    • 2012-09-28
    • 2019-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-26
    • 2023-03-07
    • 1970-01-01
    相关资源
    最近更新 更多