所以我希望在我的级联阴影贴图分割之间实现抖动作为混合模式。
我不知道它们是什么,所以我观看了这个视频来尝试理解它。
据我了解,这是一种将图像颜色映射到有限托盘的方法,同时试图在不同颜色的像素之间保持令人信服的渐变。
现在,从这个视频中,我了解了如何根据抖动模式的权重计算我的眼睛会看到什么颜色。我不明白的是我们如何拍摄具有 4 字节像素数据的图像,例如尝试将其映射到 1 字节像素数据。如果我们基本上受到限制,我们如何将原始图像中的每个像素颜色映射到其加权平均看起来就像是原始颜色的抖动模式?假设我们仅限于 5 种颜色,我猜测并非使用这 5 种托盘颜色的抖动模式的所有可能加权平均组合都可以产生原始像素颜色,那么如何实现呢?是否还为每个像素计算抖动模式以实现抖动图像?
除了这些关于图像抖动的一般问题之外,我仍然很难理解这种技术如何帮助我们在级联分割之间进行混合,就在代码中实际实现它而言,我已经看到了一个使用片段空间坐标的示例并计算一个抖动(不确定它实际上在计算什么,因为它不返回一个矩阵它返回一个浮点数):
float GetDither2(ivec2 p)
{
float d = 0.0;
if((p.x & 1) != (p.y & 1))
d += 2.0;
if((p.y & 1) == 1)
d += 1.0;
d *= 0.25;
return d;
}
float GetDither4(ivec2 p)
{
float d = GetDither2(p);
d = d * 0.25 + GetDither2(p >> 1);
return d;
}
float threshold = GetDither4(ivec2(gl_FragCoord.xy));
if(factor <= threshold)
{
// sample current cascade
}
else
{
// sample next cascade
}
然后它根据返回的浮点数对任一级联图进行采样。所以我的大脑无法将我了解到的你可以有一个抖动模式来模拟大颜色模式的知识转化为这个使用返回的浮点数作为阈值因子并将其与某个混合因子进行比较的示例,以从任一阴影贴图中进行采样。所以这让我更加困惑。
希望对此有一个很好的解释
编辑:
好的,我看到我提供的算法与维基百科关于有序抖动的文章之间的相关性,据我所知,这是首选的抖动算法,因为根据文章:
此外,由于抖动模式的位置相对于显示帧始终保持不变,因此与误差扩散方法相比,它更不容易出现抖动,因此适用于动画。
现在我看到代码试图为给定的空间坐标获取此阈值,尽管在我看来它有点错误,因为以下阈值计算如下:
Mpre(i,j) = (Mint(i,j)+1) / n^2
它需要设置:float d = 1.0
而不是float d = 0.0
如果我没记错的话。其次,我不确定如何左移ivec2
空间坐标(我什至不确定 glsl 中向量的按位移位的行为是什么......)但我假设它只是组件按位运算,我尝试了插件(头部计算) 对于给定的空间坐标(2,1)
(根据我对按位运算的假设)并得到不同的阈值结果,该阈值应该是 4x4 拜耳矩阵中该位置的阈值。
所以我怀疑这段代码实现有序抖动算法的效果如何。
其次,我仍然不确定这个阈值与在阴影贴图 1 或 2 之间进行选择有什么关系,而不仅仅是减少给定像素的颜色托盘,这个逻辑还没有在我的脑海中解决,因为我不明白使用给定空间坐标的抖动阈值来选择要从中采样的正确地图。
最后会不会选择空间坐标会导致抖动?给定世界位置的片段,(x,y,z)
谁被阴影。给定帧的片段空间坐标是(i,j)
。如果相机移动,这个片段空间坐标是否会改变,从而使为这个片段计算的抖动阈值随着每次移动而改变,从而导致抖动模式的抖动?
EDIT2: 尝试将地图混合如下,尽管结果看起来不太好,有什么想法吗?
const int indexMatrix8x8[64] = int[](
0, 32, 8, 40, 2, 34, 10, 42,
48, 16, 56, 24, 50, 18, 58, 26,
12, 44, 4, 36, 14, 46, 6, 38,
60, 28, 52, 20, 62, 30, 54, 22,
3, 35, 11, 43, 1, 33, 9, 41,
51, 19, 59, 27, 49, 17, 57, 25,
15, 47, 7, 39, 13, 45, 5, 37,
63, 31, 55, 23, 61, 29, 53, 21
);
for (int i = 0; i < NR_LIGHT_SPACE; i++) {
if (fs_in.v_FragPosClipSpaceZ <= u_CascadeEndClipSpace[i]) {
shadow = isInShadow(fs_in.v_FragPosLightSpace[i], normal, lightDirection, i) * u_ShadowStrength;
int x = int(mod(gl_FragCoord.x, 8));
int y = int(mod(gl_FragCoord.y, 8));
float threshold = (indexMatrix8x8[(x + y * 8)] + 1) / 64.0;
if (u_CascadeBlend >= threshold)
{
shadow = isInShadow(fs_in.v_FragPosLightSpace[i + 1], normal, lightDirection, i + 1) * u_ShadowStrength;
}
}
break;
}
}
基本上,如果我理解我正在做的是从矩阵中获取阴影像素的每个空间坐标的阈值,并且它(使用概率)高于混合因子,而不是我对第二张地图进行采样。