我怎样才能扩大光斑的半径



我正在编写一个软件过滤器对象,并试图实现一个光绽放效果。我使用的是一种简单的两次卷积方法,除了效果半径很小,而且我似乎无法控制半径之外,这种方法效果很好。我玩过更大的盒子过滤器,并调整了各种像素的权重,但这些似乎都没有任何效果。效果似乎有一个最大大小(不是很大),然后对参数的所有更改都会使其变小。

我希望能够创建一个任意半径的光源。经过大量的实验和网上搜索,我开始怀疑这是否是不可能的。我一直在考虑其他方法——等离子体、梯度和各种播种方案——但我想先找到这条进入地面的路径。有人知道如何(在软件中)创建任意大小的光束吗?

javascript如下(这在HTML5画布上操作;如果需要,我可以在代码中添加注释):

// the kernel functions are called via Array.map on this.backBuffer.data, a canvas surface color array
this.kernelFirstPass = function(val, index, array)
{
    if(index<pitch || index>=array.length-pitch || index%pitch<4 || index%pitch>pitch-5 || index%4==3)
        return;
    var c = 1,
        l1 = 1,
        l2 = 1,
        l3 = 1,
        r1 = 1,
        r2 = 1,
        r3 = 1;
    var avg =
    (
        c*this.frontBuffer.data[index]+
        l1*this.frontBuffer.data[index-4]+
        l2*this.frontBuffer.data[index-8]+
        l3*this.frontBuffer.data[index-12]+
        l1*this.frontBuffer.data[index+4]+
        l2*this.frontBuffer.data[index+8]+
        l3*this.frontBuffer.data[index+12]
    )/(c+l1+l2+l3+l1+l2+l3);
    //this.frontBuffer.data[index] = avg;
    array[index] = avg;
}
this.kernelSecondPass = function(val, index, array)
{
    if(index<pitch || index>=array.length-pitch || index%pitch<4 || index%pitch>=pitch-4 || index%4==3)
        return;
    var c = 1,
        l1 = 1,
        l2 = 1,
        l3 = 1,
        r1 = 1,
        r2 = 1,
        r3 = 1;
    var avg =
    (
        c*array[index]+
        l1*array[index-pitch]+
        l2*array[index-(pitch*2)]+
        l3*array[index-(pitch*3)]+
        l1*array[index+pitch]+
        l2*array[index+(pitch*2)]+
        l3*array[index+(pitch*3)]
    )/(c+l1+l2+l3+l1+l2+l3);
    array[index] = avg;
}

也许我在最初的问题中遗漏了一个重要的点,那就是解释我并没有试图模拟任何真实或特定的现象(我称之为"光"绽放可能于事无补)。在处理真实的光现象时,为了获得任意半径的半影,你可能需要一个任意半径的光源(即"完全饱和区域")。如果真的是这样的话,那么吉姆和茨库兹的解释似乎是合理的模拟方法。无论如何,这不是我想要实现的。我想独立于尺寸/强度等来控制花朵"梯度"部分的半径。源的。我希望能够在屏幕中央设置一个白色(最大值)像素,并让花朵长到我想要的地方,长到屏幕边缘或更远(如果我喜欢的话)。

为了获得良好的绽放效果,您应该使用高动态范围渲染。否则,你的白色会不够亮。

其原因是像素亮度通常在[0,1]范围内表示。因此,最大亮度被箝位为1。然而,在现实世界中,并没有真正的最大值。尽管真正明亮的灯光都被认为是"1",但像绽放这样的视觉副作用并不相同。

所以你要做的是允许真正明亮的区域超过最大亮度,至少对于bloom卷积。然后,在进行渲染时,根据需要钳制值。

完成后,您应该能够通过增加卷积中使用的Airy圆盘的大小来增加bloom半径。

tskuzy的答案的简单总结是:使用浮点缓冲区来存储布隆前的图像,然后卷积到第二个浮点缓冲区(从中将像素饱和为整数格式),或者在将每个输出像素直接存储在整数输出缓冲区之前,动态饱和以将其转换为整数。

Airy卷积必须有净空(即定点或浮点,而现在前者通常不值得用如此常见的快速FPU来麻烦),这样图像中较亮的点就会相应地在其邻近区域流血更多。

注意:色彩的动态饱和度并不像单独剪裁通道那么简单——如果你这样做,你可能会在剪裁的斑点周围出现色调失真和轮廓。

相关内容

  • 没有找到相关文章

最新更新