Kotlin 在libGDX中将音频频谱作为纹理传递给着色器

Kotlin 在libGDX中将音频频谱作为纹理传递给着色器,kotlin,libgdx,glsl,shader,Kotlin,Libgdx,Glsl,Shader,我正在使用libGDX开发一个音频可视化工具 我想将音频频谱数据(一个包含音频样本FFT的数组)传递给我从Shadertoy获取的着色器 在GLSL代码中,我希望有一个包含纹理数据的统一: 均匀采样二维iChannel0 问题是我不知道如何将任意数组作为纹理传递给libGDX中的着色器 我已经在SO和libGDX的论坛上搜索过了,但是我的问题没有令人满意的答案 下面是我的Kotlin代码(这显然不适用于xD): 您可以简单地使用drawPixel方法,将数据存储在每个像素的第一个通道中,就像sh

我正在使用libGDX开发一个音频可视化工具

我想将音频频谱数据(一个包含音频样本FFT的数组)传递给我从Shadertoy获取的着色器

在GLSL代码中,我希望有一个包含纹理数据的统一:

均匀采样二维iChannel0

问题是我不知道如何将任意数组作为纹理传递给libGDX中的着色器

我已经在SO和libGDX的论坛上搜索过了,但是我的问题没有令人满意的答案

下面是我的Kotlin代码(这显然不适用于xD):


您可以简单地使用
drawPixel
方法,将数据存储在每个像素的第一个通道中,就像shadertoy示例中一样(它们使用红色通道)

float[]fftData=//您的数据
颜色tmpColor=新颜色();
Pixmap Pixmap=新的Pixmap(fftData.length,1,Pixmap.Format.rgba888);
对于(int i=0;i
为了提高效率并减少4倍的内存(以及可能减少的采样,具体取决于着色器),可以通过在r、g、b和a通道上拆分数据来使用每像素4个通道。但是,这将使着色器复杂化一点


但是,在您提供的着色器示例中传递的数据不是任意的,它的精度非常有限,范围在0到1之间。如果要提高精度,可能需要跨多个通道存储浮点值(尽管着色器中的IEEE重新编译可能会很痛苦)或传递要缩小的整数(定点)。如果需要-inf和inf之间的数据,可以使用sigmoid和anti-sigmoid函数,但代价是再次大大降低精度。不过,我相信这项技术适用于您的示例,因为它们似乎只需要0到1之间的值,而精度并不是非常重要,因为结果是平滑的。

如果在将数据加载到
Pixmap
后创建
纹理会怎么样?@Genhis nothing bro:(您应该调用shader.begin()在设置制服之前。由于这是一个实时更新的FFT,我认为您只需要创建一次纹理和Pixmap,并使用
Texture.draw(Pixmap,0,0)
在每次更新数据时应用Pixmap更改。
val p = Pixmap(512, 1, Pixmap.Format.Alpha)
val t = Texture(p)
val map = p.pixels
map.putFloat(....) // fill the map with FFT data
[...]
t.bind(0)
shader.setUniformi("iChannel0", 0)
float[] fftData = // your data

Color tmpColor = new Color();
Pixmap pixmap = new Pixmap(fftData.length, 1, Pixmap.Format.RGBA8888);
for(int i = 0; i < fftData.length i++)
{
    tmpColor.set(fftData[i], 0, 0, 0); // using only 1 channel per pixel
    pixmap.drawPixel(i, 0, Color.rgba8888(tmpColor));
}
// then create your texture and bind it to the shader