渲染阴影时是否可以让DropShadowEffect忽略某些颜色?要有 mask 的(有颜色选择的)阴影吗?

我的问题是什么阴影可以分配给整个视觉元素(图形)。看起来像这样:

而且我要

注意没有阴影的网格线(0,0除外)。这可以通过使2个缩放/偏移图同步来实现,一个不带阴影效果包含网格,另一个不带阴影效果包含网格。但是我对此解决方案并不满意(我预计该解决方案将来会出现很多问题)。因此,我宁愿以某种方式修改DropShadowEffect

我可以创建和使用ShaderEffect,但是我不知道如何对着色器进行编程以使其具有实际的阴影效果(如果它完全可以由着色器产生)。

也许有比DropShadowEffect本身更简单的方法了吗?任何人?

编辑

我试图使着色器效果:

sampler2D _input : register(s0);
float _width : register(C0);
float _height : register(C1);
float _depth : register(C2); // shadow depth

float4 main(float2 uv : TEXCOORD) : COLOR
{
    // get pixel size
    float2 pixel = {1 / _width, 1 / _height};

    // find color at offset
    float2 offset = float2(uv.x - pixel.x * _depth, uv.y - pixel.y * _depth);
    float4 color = tex2D(_input, offset);

    // convert to gray?
    //float gray = dot(color, float4(0.1, 0.1, 0.1, 0));
    //color = float4(gray, gray, gray, 1);

    // saturate?
    //color = saturate(color);

    return tex2D(_input, uv) + color;
}

但是,一切都失败了。

编辑

这是我喜欢的图形外观的屏幕截图(对于那些试图说服我不要这样做的人):

目前,它是通过具有模板的特殊Graph实现的
<Border x:Name="PART_Border" BorderThickness="1" BorderBrush="Gray" CornerRadius="4" Background="White">
    <Grid>
        <Image x:Name="PART_ImageBack" Stretch="None"/>
        <Image x:Name="PART_ImageFront" Stretch="None">
            <Image.Effect>
                <DropShadowEffect Opacity="0.3"/>
            </Image.Effect>
        </Image>
    </Grid>
</Border>

一切都渲染到PART_ImageFront(有阴影)上,而网格渲染到PART_ImageBack(无阴影)上。性能方面还是不错的。

最佳答案

我对像素着色器的使用经验为零,但这是我快速而肮脏的尝试,尝试忽略“无色”像素的阴影效果:

sampler2D _input : register(s0);
float _width : register(C0);
float _height : register(C1);
float _depth : register(C2);
float _opacity : register(C3);

float3 rgb_to_hsv(float3 RGB) {
    float r = RGB.x;
    float g = RGB.y;
    float b = RGB.z;

    float minChannel = min(r, min(g, b));
    float maxChannel = max(r, max(g, b));

    float h = 0;
    float s = 0;
    float v = maxChannel;

    float delta = maxChannel - minChannel;

    if (delta != 0) {
        s = delta / v;

        if (r == v) h = (g - b) / delta;
        else if (g == v) h = 2 + (b - r) / delta;
        else if (b == v) h = 4 + (r - g) / delta;
    }

    return float3(h, s, v);
}

float4 main(float2 uv : TEXCOORD) : COLOR {
    float width = _width; // 512;
    float height = _height; // 512;
    float depth = _depth; // 3;
    float opacity = _opacity; // 0.25;

    float2 pixel = { 1 / width, 1 / height };

    float2 offset = float2(uv.x - pixel.x * depth, uv.y - pixel.y * depth);
    float4 srcColor = tex2D(_input, offset);

    float3 srcHsv = rgb_to_hsv(srcColor);
    float4 dstColor = tex2D(_input, uv);

    // add shadow for colored pixels only
    // tweak saturation threshold as necessary
    if (srcHsv.y >= 0.1) {
        float gray = dot(srcColor, float4(0.1, 0.1, 0.1, 0.0));
        float4 multiplier = float4(gray, gray, gray, opacity * srcColor.a);
        return dstColor + (float4(0.1, 0.1, 0.1, 1.0) * multiplier);
    }

    return dstColor;
}

这是针对我使用铅笔工具在Blend中绘制的(完全合法的)图表进行的操作:

着色器效果应用于包含轴,网格线和序列线的根面板,并且仅为序列线生成阴影。

我认为期望着色器在忽略网格线的同时能够将阴影应用于轴和标签并不现实。文本上的抗锯齿势必会与网格线的颜色/饱和度范围相交。我认为将阴影仅应用到系列线条上会更清洁,并且在美学上更令人愉悦。

10-08 14:36