三个 JS Palette 循环着色器

Posted

技术标签:

【中文标题】三个 JS Palette 循环着色器【英文标题】:Three JS Palette Cycling Shader 【发布时间】:2022-01-18 20:50:45 【问题描述】:

我正在 THREE.js(我的第一个着色器)中实现 palette cycling 着色器。

到目前为止一切正常,但我在以下事实中苦苦挣扎:

无法将动态大小的 pixels 数组传递到片段着色器中 无法将动态大小的 palette colors 数组传递到片段着色器中

完整示例: https://jsfiddle.net/dangarfield/Le4t7w60/265/

uniform int w;
uniform int h;
uniform int paletteSize;
uniform int[12] pixels; // Has to be fixed 
uniform vec4[3] colors; // Has to be fixed 
varying vec2 vUv;

vec4 getPixelColorFromPalette (int pixelIndex, int[12] pixels, vec4[3] colors) 
    return colors[pixels[pixelIndex]];


void main() 
    float wF = float(w);
    float hF = float(h);

    vec2 xyPos = floor(vec2(vUv.x*wF,hF-vUv.y*hF));
    int pixelIndex = int((wF * xyPos.y) + (xyPos.x));
    vec4 color = getPixelColorFromPalette( pixelIndex, pixels, colors );
    gl_FragColor = color;

关于如何优化它以便我不必被固定数组大小限制的任何想法?

谢谢

【问题讨论】:

【参考方案1】:

全部排序。我刚刚将像素和调色板数据添加为 THREE.DataTexture 并进行了查找:

更新小提琴 - https://jsfiddle.net/dangarfield/Le4t7w60/398/

最终片段着色器:

uniform int w;
uniform int h;
uniform int paletteSize;
uniform sampler2D palette;
uniform sampler2D pixels;
varying vec2 vUv;

vec4 getPixelColorFromPalette (int pixelIndex, int w, int h, vec2 xyPos, sampler2D pixels, sampler2D palette, int paletteSize) 
    vec4 pixelColor = texture2D(pixels, vec2(1.0 / float(w) * float(xyPos.x),1.0 / float(h) * float(xyPos.y)));
    float paletteIndex = pixelColor.x*255.0;
    vec4 color = texture2D(palette, vec2(1.0 / float(paletteSize) * paletteIndex,0));
    return color;


void main() 
    float wF = float(w);
    float hF = float(h);
        
    vec2 xyPos = floor(vec2(vUv.x*wF,hF-vUv.y*hF));
    int pixelIndex = int((wF * xyPos.y) + (xyPos.x));
    gl_FragColor = getPixelColorFromPalette( pixelIndex, w, h, xyPos, pixels, palette, paletteSize );

【讨论】:

以上是关于三个 JS Palette 循环着色器的主要内容,如果未能解决你的问题,请参考以下文章

three.js 着色器材质基础

Three.js 中的自定义纹理着色器

使用shader着色器程序创建扩散光圈效果(three.js实战10)

使用空的着色器程序绘制是不是有效?

如何将 Three.js 着色器应用于节点

Three.js着色器基础含源码