返回首页

{A}{A2的}
{S0的}介绍
这篇文章解释了如何使用像素着色器快速生成Mandelbrot和Julia集。显卡加速,像素值可以异步计算,实时。每个单元的计算分​​配给它的像素。不幸的是,某些显卡不支持双精度浮点数(包括我的卡),所以我们不能让高倍率。但速度是一个优势。
要求:Visual Studio的Express或标准2010 - 创建项目 - 编制的HLSL - 着色语言背景
我学到} {A4纸的HLSL。编写的着色器的文件
让我们的项目中添加一个文本文件,并将其命名为quot; mandel.txtquot。这将是在HLSL着色器的源代码。现在让我们编写着色器的框架:

sampler2D input : register(s0);

// Image to be processed, loaded from Sampler Register 0.



float4 main(float2 uv : TEXCOORD) : COLOR

// uv are the coordinates of the pixel to be processed

{

    float4 color = tex2D(input, uv); // Getting pixel uv from input.

    return color; // Returning new color of processed pixel.

}

// As you see HLSL is similar to C.

着色器适用于对财产的WPF元素。 WPF元素的渲染图像传递到着色包装和发送着色器编译程序的图形卡。包装也发送数据(呈现的元素)图形卡在指定的寄存器。 WPF中的寄存器分配和包装可以通过着色器读取。如果你想了解寄存器更普遍,看看在{A5的}。
输入是从采样寄存器0加载的图像。包装(WPF中没有,它会自动)将在未来将呈现的元素(如电网)在该寄存器。曼德尔布罗不变换图像,它不会产生它的像素,所以我们可以删除在曼德尔布罗着色输入。
让我们回到项目。我们必须编译着色器文件。这样做,让我们去项目属性并建立事件部分。
{S}
现在让我们添加的预生成事件命令:{C}
这将编译我们的着色器。现在,让我们运行该项目。
这是可能的,编译过程中可能会出现错误。它可以是一个着色器文件编码的问题。 FXC编译器只支持ANSI代码页,默认情况下,Visual Studio创建的文件在UTF-8。要更改在Visual Studio为ANSI UTF-8:在解决方案资源管理器中选择mandel.txt。打开文件菜单,并选择保存mandel.txt作为...不要改变路径 - 文件将被覆盖。点击保存与编码...单击"是",当它被覆盖的消息。选择"中欧(Windows中) - 代码页1250quot;并单击确定。
如果一切顺利,你应该看到一个空白窗口的主窗口。现在,我们不会在我们的项目中使用的着色。让编译的着色器文件添加到项目。编译的程序应该是在项目目录作为quot; mandel.psquot;现在,该文件将被覆盖在每个重建。让我们来实现一个简单的曼德尔布罗。要做到这一点,我们必须有一个复杂的数字图书馆。我创建了这一点,你可以从这篇文章的顶部。当你有下载,解压缩文件,并添加quot; complex.txtquot的;您的曼德尔布罗项目。主要在mandel.txt之前加入以下行:
#include "complex.txt"

现在,我们可以轻松地实现曼德尔布罗。删除所有主要的内在。让我们再定义变量:{体C3}
现在写循环:{的C4}
迭代数(i)将代表颜色。功能c_abs,c_add,c_pow ...复杂的库函数的绝对值计算,添加exponenting ...如果z的绝对值??救助,然后循环结束。在的曼德尔布罗中心,迭代次数将是无限的,所以它是一个maxIter变量 - 它抑制了无限循环的形成。行计算z的新的价值是在数学提出:Z(N-1)=郑州日产B,其中A是电源和B是紫外线。
测试,返回红色,如果我== maxIter否则返回黑色。在未来,这将呈现一个复杂的调色板。{C5的}
现在,你的代码应该是这样的:{5233}
,您可以重新编译您的项目。都应该是不错的。封装着色器
我们的编译着色器应该被添加到项目中。如果我们希望包装能够加载着色器,我们必须设置着色器文件生成到资源的行动。
{S2的}
现在,添加新类的项目,并将其命名为quot; MandelbrotEffectquot;这将是我们的包装。添加以下using语句的类:{C7-}
我们的类必须继承从ShaderEffect。让我们的负载着色器:{C8的}
这一行必须添加到MandelbrotEffect类。现在添加构造函数:
public MandelbrotEffect()

{

    PixelShader = m_shader;

}

构造函数设置着色器源的m_shader。我们没有实现输入,因为我们不使用它的着色。如果你想在未来创造的效果,这需要输入,看一看{A6的}。
现在你可以重新编译您的项目。 使用着色器
让我们来测试一下我们现在的着色。 MainPage.xaml中。它应该看起来像这样:{C10的}
加入这一行,那里有一个评论quot; HEREquot;{C11的}
替换的命名空间包含您MandelbrotEffect的ShaderMandelbrot。现在设置网格的任何可见颜色(如红色)的背景,因为那里是唯一可见的像素由像素着色转化。因此,让我们的添加MandelbrotEffect网格:{C12的}
现在,重建项目和运行!
{S3的}添加参数
对于不断变化的最大迭代,电力,或救助,我们必须修改的像素着色器文件。让我们改变这些参数。我们将修改的像素着色器。首先,从主删除以下行:
float maxIter = 32;

float2 power = float2(2, 0);

float bailout = 4;

二,在文件的顶部添加这些行后,输入:
float maxIter : register(c0);

float2 power : register(c1);

float bailout : register(c2);

参数加载的Pixel Shader常量寄存器。
第三,在包装实施这些参数:
public static readonly DependencyProperty MaxIterProperty = 

  DependencyProperty.Register("MaxIter", typeof(double), typeof(MandelbrotEffect), 

  new UIPropertyMetadata(32.0, PixelShaderConstantCallback(0))); // register(c0)

public double MaxIter

{

    get { return (double)GetValue(MaxIterProperty); }

    set { SetValue(MaxIterProperty, value); }

}



public static readonly DependencyProperty PowerProperty = 

  DependencyProperty.Register("Power", typeof(Point), 

  typeof(MandelbrotEffect), new UIPropertyMetadata(new Point(2, 0), 

  PixelShaderConstantCallback(1))); // register(c1)

public Point Power

{

    get { return (Point)GetValue(PowerProperty); }

    set { SetValue(PowerProperty, value); }

}



public static readonly DependencyProperty BailoutProperty = 

  DependencyProperty.Register("Bailout", typeof(double), 

  typeof(MandelbrotEffect), 

  new UIPropertyMetadata(4.0, PixelShaderConstantCallback(2))); // register(c2)

public double Bailout

{

    get { return (double)GetValue(BailoutProperty); }

    set { SetValue(BailoutProperty, value); }

}

第四,更新着色器的值 - 这些行添加到MandelbrotEffect构造:{C16的}
完成。现在重建的项目,你可以在XAML编辑器中设置的参数。{C17的}
创建一个曼德尔布罗突变。
{四至}偏移和大小
现在,我们只能看到一个分部分。让我们重新调整。添加到着色的偏移和大小的参数:{C18的}
执行在包装的参数:{C19的}
更新着色价值观:{C20的}
现在我们必须重新调整着色器中的紫外线:{C21的}
更改所有的UV着色器XY和运行。
{五}调色板
我们的Mandelbrot集是不是很彩色。为了得到漂亮的颜色,我们要创建一个调色板。下面是一个简单的调色板的代码,但非常好:{C22,}
粘贴后quot,包括linequot,在着色。立即更换:{C23的}
与此:{C24的}
这是的结果是:
{六}连续(光滑)着色
归迭代计数算法可以消除难看的颜色阈值。我们可以很容易地实现如下。替换此:
return getColor(i / maxIter);

与此:
{

    i -= log(log(c_abs(z))) / log(c_abs(power));

    return getColor(i / maxIter);

}

就是这样!完成我们的曼德尔布罗着色文件。这是效果:
{七}曼德尔布罗截图
{S8的}朱莉娅
Julia的公式是类似曼德尔布罗。有一个变化。这是为Julia的公式:Z(N-1)=郑州日产B,一个是权力,和b是不是紫外 - 朱莉娅,这是种子。选择它的最简单的方法是从曼德尔布罗切换 - 在示例应用程序,我这样做的。
这是的朱莉娅着色的代码:{C27的}
您必须实现自己的包装或下载的源代码。记住:你必须添加到预编译的命令行编译。朱莉娅截图
{S9的}其他功能
在这个例子应用程序(及其来源),我申请MainWindow中的其他一些功能。这些措施包括移动,缩放形用鼠标,切换到朱莉娅和调节参数的滑块。接下来是什么?
您可以尝试自己实现其他的分形。结论
Mandelbrot集是很容易实现与复数。 Julia的公式是类似曼德尔布罗的公式。与像素着色器,我们可以得到快速的分形,但因为有双精度数的问题,我们不能让高倍率。像素着色器快速图像处理的一个很好的解决方案,并与WPF和HLSL,这是很容易的。历史2011年7月19日 - 更正,补充朱莉娅。

回答

评论会员:游客 时间:2012/02/04
!尼斯的工作......但是哟解释更多关于分形理论为做一个最好的环境,为旅游原型
VUnreal:看到一个写得很好的文章,其凉这个工作在WPF中。
只是因为代码的工作,它并不意味着它是良好的代码
评论会员:toantvo:不坏 时间:2012/02/04
jsh_ec
评论会员:游客 时间:2012/02/04
酷,我爱你的方式使颜色变得顺利
阿德里安・帕西克
评论会员:游客 时间:2012/02/04
大演示。干得好。我希望我们能有更多像这样的文章:|克里斯KMPP:WPF中的HLSL,这是很少见CP上。总之是很不错的工作。pozdrawiamkolegę{S10的}
萨科Dorier
评论会员:游客 时间:2012/02/04
DziękiZAuznanie。{S10的}
克里斯KMPP
评论会员:游客 时间:2012/02/04
什么是输入属性为?我不明白,你不使用它在mandel.txt。什么是注册?我怎样才能创建自己的阴影效果或BlurEffect?(这是我怎样才能创建一个渲染,这取决于应用效果的元素,我)