如何在WPF中实现圆锥/圆锥/圆形渐变

时间:2021-09-25 14:34:03

I would like to recreate a conical/circular gradient in WPF. I've looked into inheriting System.Windows.Media.GradientBrush - which can be inherited from - but uses a lot of internal plumbing to get the job done (inherited from System.Windows.Media.Brush)

我想在WPF中重新创建一个圆锥/圆形渐变。我已经研究过继承System.Windows.Media.GradientBrush - 它可以继承 - 但是使用了很多内部管道来完成工作(继承自System.Windows.Media.Brush)

Any ideas on how to achieve this would be appreciated (preferrably without resorting to bitmaps)

任何有关如何实现这一点的想法都将受到赞赏(最好不要使用位图)

Cheers.

干杯。

Dan

This question was asked some time back in July (Circular Gradient and WPF) but I didn't want to resurrect an old question.

这个问题在七月(循环渐变和WPF)问了一段时间,但我不想复活一个旧问题。

1 个解决方案

#1


5  

You could create a custom Effect. I would recommend downloading Shazzam you will also need the DirectX SDK. Give the element a horizontal gradient then apply the effect to transform it into a cone gradient.

您可以创建自定义效果。我建议下载Shazzam,你还需要DirectX SDK。为元素提供水平渐变,然后应用效果将其转换为锥形渐变。

/// <class>AngleGradient</class>
/// <description>Renders an angle gradient.</description>
//-----------------------------------------------------------------------------------------
// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.)
//-----------------------------------------------------------------------------------------
/// <summary>The centre of the gradient.</summary>
/// <minValue>0</minValue>
/// <maxValue>1</maxValue>
/// <defaultValue>0.5,0.5</defaultValue>
float2 Centre : register(C0);

/// <summary>The start angle.</summary>
/// <minValue>0</minValue>
/// <maxValue>1</maxValue>
/// <defaultValue>0</defaultValue>
float Angle : register(C1);

//--------------------------------------------------------------------------------------
// Sampler Inputs (Brushes, including ImplicitInput)
//--------------------------------------------------------------------------------------

sampler1D implicitInputSampler : register(S0);
static const float PI = 3.14159265f;
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 main(float2 uv : TEXCOORD) : COLOR
{
    float angle = atan2(uv.y-Centre.y, uv.x-Centre.x)+PI;
    angle = (angle/(2*PI)) + Angle; 
    return tex1D(implicitInputSampler,min(angle > 1 ? angle-1 : angle,0.99));

#1


5  

You could create a custom Effect. I would recommend downloading Shazzam you will also need the DirectX SDK. Give the element a horizontal gradient then apply the effect to transform it into a cone gradient.

您可以创建自定义效果。我建议下载Shazzam,你还需要DirectX SDK。为元素提供水平渐变,然后应用效果将其转换为锥形渐变。

/// <class>AngleGradient</class>
/// <description>Renders an angle gradient.</description>
//-----------------------------------------------------------------------------------------
// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.)
//-----------------------------------------------------------------------------------------
/// <summary>The centre of the gradient.</summary>
/// <minValue>0</minValue>
/// <maxValue>1</maxValue>
/// <defaultValue>0.5,0.5</defaultValue>
float2 Centre : register(C0);

/// <summary>The start angle.</summary>
/// <minValue>0</minValue>
/// <maxValue>1</maxValue>
/// <defaultValue>0</defaultValue>
float Angle : register(C1);

//--------------------------------------------------------------------------------------
// Sampler Inputs (Brushes, including ImplicitInput)
//--------------------------------------------------------------------------------------

sampler1D implicitInputSampler : register(S0);
static const float PI = 3.14159265f;
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 main(float2 uv : TEXCOORD) : COLOR
{
    float angle = atan2(uv.y-Centre.y, uv.x-Centre.x)+PI;
    angle = (angle/(2*PI)) + Angle; 
    return tex1D(implicitInputSampler,min(angle > 1 ? angle-1 : angle,0.99));