python - 像素着色器中的 Mandelbrot
问题描述
我现在在 Mandelbrot 集的 DirectX 11 版本上工作了几天。到目前为止,我所做的是创建一个带有纹理的四边形。我可以使用 Pixel Shader 为点着色,但由于某种原因,Pixel Shader 中设置的 Mandelbrot 没有返回预期的结果。我用纯 C++ 代码测试了逻辑,我得到了同样错误的结果。知道代码有什么问题吗?我有一个在 Python 中工作的正确版本,我只是复制了代码,但似乎缺少一些东西。
设置的宽度为 2.5(将图像拉伸一点)。它假定一个 1024*960 的窗口和最大。1000 次迭代。我使用 Shader Model 5.0 编译。它从默认设置开始
RealStart = -2.0;
ImagStart = -1.25;
通过常量缓冲区传递
cbuffer cBuffer
{
double RealStart; 'equals -2.5 from the default view of the set
double ImagStart; 'equals -1.25 from the default view of the set
};
// Pixel Shader
float4 main(float4 position : SV_POSITION) : SV_TARGET
{
double real, imag;
double real2, imag2;
int ite = 0;
float4 CalcColor = { 1.0f , 1.0f, 1.0f, 1.0f };
'position is the position of the pixel from 1.0f to 0.0f
real = RealStart + (double) position.x / 1024 * 2.5;
imag = ImagStart + (double) position.y / 960 * 2.5;
for (int i = 0; i < 1000; i++)
{
'breaking down the complex number by its constituents
real2 = real * real;
imag2 = imag * imag;
if (real2 + imag2 > 4.0)
{
break;
}
else {
imag = 2 * real * imag + ImagStart;
real = real2 - imag2 + RealStart;
ite++;
}
}
CalcColor[0] = (float) (ite % 333) / 333 ;
CalcColor[1] = (float) (ite % 666) / 666 ;
CalcColor[2] = (float) (ite % 1000) / 1000;
return CalcColor;
}
编辑 Python 版本
def Mandelbrot(creal, cimag, maxNumberOfIterations):
real = creal
imag = cimag
for numberOfIterations in range(maxNumberOfIterations):
real2 = real * real
imag2 = imag * imag
if real2 + imag2 > 4.0:
return numberOfIterations
imag = 2 * real * imag + cimag
real = real2 - imag2 + creal
return maxNumberOfIterations
creal、cimag 和是这样创建的,然后循环播放。
realAxis = np.linspace(realStart, realStart + width, dim)
imagAxis = np.linspace(imagStart, imagStart + width, dim)
它将 maxNumberOfIterations 返回到一个二维数组,该数组用于绘制 Mandelbrot 集。
解决方案
错误在于 Else 中的 ImagStart 和 RealStart 也需要缩放。Shader中的代码修改如下:
cbuffer cBuffer
{
double2 C;
float2 Param;
float MaxIt;
};
// Pixel Shader
float4 main(float4 position : SV_POSITION, float2 texcoord : TEXCOORD) : SV_TARGET
{
double real, imag;
double real2, imag2;
uint ite = 0;
float4 CalcColor = { 1.0f , 1.0f, 1.0f, 1.0f };
real = C.x + ((double) texcoord.x - 0.5) * 2.0 * 2.5;
imag = C.y + ((double) texcoord.y - 0.5) * 2.0 * 2.5;
for (int i = 0; i < 100; i++)
{
real2 = real * real;
imag2 = imag * imag;
if (real2 + imag2 > 4.0)
{
break;
}
else {
imag = 2 * real * imag + C.y + ((double) texcoord.y - 0.5) * 2.0 * 2.5;
real = real2 - imag2 + C.x + ((double) texcoord.x - 0.5) * 2.0 * 2.5;
ite++;
}
}
if (ite > 100)
ite = 100;
CalcColor[0] = (float)(ite % 33) / 33;
CalcColor[1] = (float)(ite % 66) / 66;
CalcColor[2] = (float)(ite % 100) / 100;
return CalcColor;
}
推荐阅读
- google-earth-engine - Google Earth Engine: trying to get an array of values from a feature collection but I'm getting an empty array out
- taskwarrior - Adding tasks that others depend on in one line
- amazon-web-services - querying AWS firehose data in s3 with Athena - can't query batches
- python - How to work with columns after using to_flat_index?
- homebrew - Does Homebrew keep a log of installed packages/casks?
- excel - Multiple VBA Worksheet Change Events
- graphql-spring-boot - GraphQL 引起:graphql.AssertException:您必须提供数据提取器。如何在这里存根数据提取器?
- sql - SYNTAX_ERROR: line 1:1: DISTINCT in window function parameters not yet supported
- c# - 在 C# 中运行 Powershell 脚本时出现转义字符问题
- excel - Can you guys help me to make this code shorter? and smarter i guess