平滑不同幅度的噪声(第 2 部分)

2023-12-08

好吧,我继续这个问题而不回答(平滑不同幅度的随机噪声)我还有另一个问题。

我选择使用形状的轮廓/阴影(翻译/转换?距离其中心有偏移/距离的点列表).

该轮廓/阴影比当前路径大。我使用了这个存储库(https://github.com/n-yoda/unity-vertex-effects)来重新创建阴影。除了一个事实之外,这种方法非常有效。

要知道所有点的高度(通过此阴影算法获得(ModifiedShadow.cs 第 13 行 & CircleOutline.cs 第 69 行)) 我得到当前点到中心的距离,然后除以到中心的最大距离:

float dist = orig.Max(v => (v - Center).magnitude);
foreach Point in poly --> float d = 1f - (Center - p).magnitude / dist;

其中 orig 是阴影算法获得的点的完整列表。 D是阴影的高度。

但问题很明显我得到了一个完美的圆:

...

看看红色和黑色的对比:

...

这不是我想要的:

...

正如你所看到的,这不是一个完美的渐变。让我们解释一下发生了什么。

我使用这个库来生成噪音:https://github.com/Auburns/FastNoise_CSharp

Note:如果你想知道我用什么来获得不同幅度的噪声:平滑不同幅度的随机噪声(参见第一块代码),要查看其实际效果,看到这个回购协议

...

  • 绿色背景代表平均高度为-0.25、幅度为0.3的噪声
  • 白色背景色代表平均高度为 0、幅度为 0.1 的噪声
  • 红色表示 1(与白色像素对应的噪声的总插值)
  • 黑色表示 0(绿色像素对应的噪声的总插值)

这就是为什么我们有这样的输出:

...

实际上,我尝试比较每个点到中心的距离,但这输出了一个奇怪且意想不到的结果。

其实我不知道该尝试什么...


问题是 lerp 百分比(例如,可视化中从高/低或“红色”到“黑色”)只是该点到中心的距离的函数,该距离除以一个常数(恰好是任意点距中心的最大距离)。这就是为什么它看起来是圆形的。

例如,多边形左侧的最中心点可能距中心 300 像素,而右侧的最中心点可能距中心 5 像素。两者都需要是红色的,但基于0 distance from center = red都不会是红色的,并且基于min distance from center = red只有右侧有红色。

相关的最小和最大距离将根据点所在的位置而变化

一种替代方法是针对每个点:找到最近的白色像素,并找到最近的绿色像素(或者,与绿色/白色相邻的最近的阴影像素,例如here)。然后,根据这两个点与当前点之间的距离比较来选择红色。

因此,您可以这样做(伪 C#):

foreach pixel p in shadow_region {

    // technically, closest shadow pixel which is adjacent to x Pixel: 
    float closestGreen_distance = +inf;
    float closestWhite_distance = +inf;

    // Possibly: find all shadow-adjacent pixels prior to the outer loop 
    // and cache them. Then, you only have to loop through those pixels.
    foreach pixel p2 in shadow {
        float p2Dist = (p-p2).magnitude;

        if (p2 is adjacent to green) {
           if (p2Dist < closestGreen_distance) {
               closestGreen_distance = p2Dist;
           }
        }

        if (p2 is adjacent to white) {
           if (p2Dist < closestWhite_distance) {
               closestWhite_distance = p2Dist;
           }
        }
    }

    float d = 1f - closestWhite_distance / (closestWhite_distance + closestGreen_distance)
}

使用您在评论中发布的代码,这可能看起来像:

foreach (Point p in value)
{
    float minOuterDistance = outerPoints.Min(p2 => (p - p2).magnitude);
    float minInnerDistance = innerPoints.Min(p2 => (p - p2).magnitude);

    float d = 1f - minInnerDistance / (minInnerDistance + minOuterDistance);

    Color32? colorValue = func?.Invoke(p.x, p.y, d);

    if (colorValue.HasValue)
        target[F.P(p.x, p.y, width, height)] = colorValue.Value;
}

选择以上部分作为解决方案。下面的部分作为另一个选项提到,但事实证明是不必要的。


如果您无法确定阴影像素是否与白色/绿色相邻,这里有一个替代方案,只需要计算粉红色(原始)轮廓中每个顶点的法线。

通过转到每个粉红色顶点并遵循其法线向外来创建外部“黄色”顶点。通过转到每个粉红色顶点并遵循其法线向内创建内部“蓝色”顶点。

然后,当循环遍历阴影中的每个像素时,循环遍历黄色顶点以获得“最接近绿色”,循环遍历蓝色顶点以获得“最接近白色”。

问题是,由于您的形状不是完全凸的,因此这些投影的蓝色和黄色轮廓在某些地方可能会从内到外,因此您需要以某种方式处理这个问题。我无法确定处理该问题的确切方法,但到目前为止我所拥有的方法如下:

第一步是忽略任何具有指向当前阴影像素的向外法线的蓝色/黄色。

但是,如果当前像素位于黄色/蓝色形状由内向外的点内部,我不确定如何继续。可能存在忽略比应有的距离最近的粉色顶点更近的蓝色/黄色顶点的情况。

极其粗糙的伪代码:

list yellow_vertex_list = new list 
list blue_vertex_list = new list 
foreach pink vertex p:
    given float dist;
    vertex yellowvertex = new vertex(p+normal*dist)
    vertex bluevertex = new vertex(p-normal*dist)

    yellow_vertex_list.add(yellowvertex)
    blue_vertex_list.add(bluevertex)

create shadow

for each pixel p in shadow:
    foreach vertex v in blue_vertex_list
        if v.normal points towards v: break;
        if v is the wrong side of inside-out region: break;
        if v is closest so far:
            closest_blue = v
            closest_blue_dist = (v-p).magnitude

    foreach vertex v in yellow_vertex_list
        if v.normal points towards v break;
        if v is the wrong side of inside-out region: break;
        if v is closest so far:
            closest_yellow = v
            closest_yellow_dist = (v-p).magnitude


    float d = 1f - closest_blue_dist / (closest_blue_dist + closest_yellow_dist)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

平滑不同幅度的噪声(第 2 部分) 的相关文章

  • .NET 单点登录

    我一直在尝试使用 C 为 NET Web 应用程序实现 WEB SSO 服务提供程序插件 我将使用 shibboleth 身份提供商 我已经使用 OpenSAML 库为 java 应用程序实现了相同的功能 我想知道在 NET 应用程序中使用
  • 为什么我会收到未找到分析器的警告?

    我创建了一个玩具项目来检查最新的 NET 7 预览版 5 和正则表达式代码生成 它效果很好 所以我对现有项目应用了相同的更改 不是为了生产 而是为了个人生产力 由于某种原因 我收到这些警告 CS8032 An instance of ana
  • Caliburn.Micro - ShowDialog() 如何关闭对话框?

    EDIT 新信息 刚刚设法让记录器工作 老实说 我不知道 cm 有一个 并且在尝试使用时收到此消息TryClose TryClose requires a parent IConductor or a view with a Close m
  • ASP.NET Web 应用程序中的身份验证遇到问题

    我正在尝试对从登录页面登录我的 Web 应用程序的用户进行身份验证 我正在使用本教程 http support microsoft com kb 301240作为指南 它几乎准确地解释了我希望做什么 但是当我输入用户名和密码时 验证不起作用
  • 平滑手绘曲线

    我有一个允许用户绘制曲线的程序 但这些曲线看起来不太好 它们看起来摇摇欲坠 而且是手绘的 所以我想要一种能够自动平滑它们的算法 我知道平滑过程中存在固有的模糊性 因此它不会每次都完美 但这种算法似乎确实存在于多个绘图包中 并且它们工作得很好
  • 警告 C4800:“int”:强制值为 bool“true”或“false”(性能警告)

    我的代码中有这个问题 bool CBase isNumber return id MID NUMBER bool CBase isVar return id MID VARIABLE bool CBase isSymbol return i
  • 如何从 Qt 应用程序通过 ODBC 连接到 MySQL 数据库?

    我有一个新安装的 MySQL 服务器 它监听 localhost 3306 从 Qt 应用程序连接到它的正确方法是什么 原来我需要将MySQL添加到ODBC数据源 我在遵循这个视频教程后做到了这一点 https youtu be K3GZi
  • C# 无法捕获 SerializationException

    我的程序在加载序列化文件的部分遇到问题 如果文件无法反序列化 我希望很好地失败 但由于某种原因 我的程序将中断而不是进入 catch 子句 这是我的代码 using FileStream fs new FileStream openFile
  • 如何减少 MinGW g++ 编译器生成的可执行文件的大小?

    我有一个简单的 Hello world C 程序 在 Win XP 下由 MinGW g 编译器编译为 500kB 可执行文件 有人说这是由于iostream的库和静态链接libstdc dll Using s链接器选项有点帮助 减少了 5
  • 如何将 Q 格式整数转换为浮点数(反之亦然)?

    我四处搜寻 找不到一个很好的问题来回答这个问题 给定一个整数 使用Q Format https en wikipedia org wiki Q number format 如何将该数字转换为普通浮点类型 反之亦然 如何将浮点类型转换为Q F
  • 如何将STL容器数据转储到gdb中?

    我无法在 gdb 中转储 STL 无序映射容器值 变量类型是 std unordered map var 我的 gdb 版本 7 7 1 GDB配置 configure host x86 64 linux gnu target x86 64
  • 我在使用 ado.net 时收到错误 Argument 2 may not be pass with ref keywords

    int t 0 cmd Parameters AddWithValue Res ref t 我在第二行收到错误 参数 2 不能与 ref 关键字一起传递 您只能通过引用传递参数ref if the 范围 is a ref参数也是如此 Add
  • 我可以将 UseCSharpNullComparisonBehavior 用于单个查询吗?

    我有一个查询 该查询曾经是存储过程 现已转换为 EF 查询 现在已经超时了 使用 SQL Profiler 我可以看到生成的 SQL 的唯一区别是 EF 转变的新行为entity Property value into entity Pro
  • 您对“大规模 C++ 软件设计”的看法 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 正在阅读亚马逊评论 https rads stackoverflow com amzn click com 0201633620 and ACC
  • 更改 Xamarin.Forms 应用中顶部栏和底部栏(ControlsBar、StatusBar)的颜色

    无论如何 即使后面需要特定于平台的代码 也可以更改顶部栏 蓝色的 和底部栏 黑色的 的颜色吗 我希望添加对浅色和深色模式的支持 因此我希望能够在运行时更改它 有可能的 Android Using Window SetStatusBarCol
  • 如何在 C# 中更改公共 IP 地址

    我正在创建一个 C winform 应用程序 我想在其中更改公共 IP 地址 而不是像 Hotspot Shield ZenMate OpenVPN 等那样更改 IPv4 地址 我已经检查了以下链接 但没有找到足够的帮助 所以我发布了这个问
  • Type.GetInterfaces() 仅适用于声明的接口

    首先 像这样的问题有很多 也许有些OP甚至在问同样的问题 问题是这些问题的答案 无论是否接受 都没有真正回答这个问题 至少我找不到 如何确定类直接声明的接口 而不是由父级或声明的接口继承的接口 e g interface I interfa
  • 连接到没有元数据的网络服务

    我想连接到此网络服务 https training api temando com schema 2009 06 server wsdl https training api temando com schema 2009 06 serve
  • 当我的进程被终止时到底会发生什么?

    我有一个包含本机代码和托管代码的混合进程 在 Windows Server 2003 上运行 当我从进程资源管理器中终止进程时 它会进入 100 cpu 的状态 并在消失之前保持这种状态一段时间 有时甚至 10 分钟 在此期间我无法 杀死
  • 如何在 C 中创建最低有效位设置为 1 的掩码

    这个功能如何运作 最低有效 n 位设置为 1 的掩码 Example n 6 gt 0x2F n 17 gt 0x1FFFF 我根本不明白这些 尤其是 n 6 gt 0x2F 另外 什么是面膜 通常的方法是采取1 并将其左移n位 这会给你类

随机推荐