首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >智能DropShadowEffect

智能DropShadowEffect
EN

Stack Overflow用户
提问于 2014-10-06 13:07:28
回答 2查看 798关注 0票数 5

在渲染阴影时,是否可以让DropShadowEffect忽略某些颜色?有一种蒙面(颜色选择性)阴影?

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

我想要

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

我可以创建和使用ShaderEffect,但我不知道如何编程着色器有实际的阴影效果(如果它可以产生的着色器在所有)。

也许有更简单的方法来处理DropShadowEffect本身?有没有人?

编辑

我试着使着色器效果:

代码语言:javascript
复制
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来实现的。

代码语言:javascript
复制
<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上(没有阴影)。性能方面,它仍然是好的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-10-23 16:10:46

我对像素着色器没有任何经验,但下面是我对忽略“未着色”像素的阴影效果的快速而肮脏的尝试:

代码语言:javascript
复制
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;
}

在这里,我用铅笔工具画了一个(完全合法的)图表:

着色器效果应用于包含轴、栅格线和串联线的根面板上,它只为系列线生成阴影。

我认为,期望着色器能够在轴和标签上应用阴影而忽略网格线是不现实的;文本上的反混叠必然会与网格线的颜色/饱和范围相交。我认为,应用阴影只是系列线是更干净和更美观的反正。

票数 2
EN

Stack Overflow用户

发布于 2014-10-13 19:25:55

代码语言:javascript
复制
sampler2D input : register(s0);
float4 main(float2 uv : TEXCOORD) : COLOR  {

    float4 Color;
    Color = tex2D( input , uv.xy);
    return Color;
}

这是一个基本的‘无所事事’的着色器。text2D调用的行采用通常在当前位置绘制的颜色。(在本例中,只需返回它)

而不是抽样uv.xy,您可以添加一个偏移向量到uv.xy并返回该颜色。这将使整个图像朝着偏移矢量的方向移动。

你可以把这两者结合起来:

  1. 示例uv.xy,如果设置为该颜色的可见颜色图(这将使所有线条在正确的位置可见)
  2. 如果它是透明的,在左上角取样一点。如果它被设置为一种颜色,您希望有一个阴影:返回阴影颜色。

可以将步骤2更改为:如果设置为不希望有阴影的颜色,则返回透明颜色。

偏移量和要测试的颜色以及用作阴影颜色的颜色可能是效果的参数。

我强烈建议使用沙扎姆,它将允许您测试您的着色器,它将为您生成C#代码。

注意,uv坐标不是以像素为单位,而是缩放到0.0到1.0。

加法

一个可怜的人的模糊(反混叠)可以通过采样更多的像素周围的偏移,并计算出一个平均的颜色发现,应该造成阴影。这将导致更多像素接收阴影。

要计算阴影颜色,只需将现有颜色与0.0 (黑色)和1.0 (原始颜色)之间的因子相乘就可以使其变暗。

通过使用来自模糊的平均值,您可以再次乘上阴影颜色,从而使模糊与原始颜色混合。

更精确(也更昂贵)是将rgb值转换为hls值,并使用“正式”变黑公式来确定阴影颜色。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26216904

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档