WebGL统一参数类型

时间:2017-05-12 18:04:18

标签: glsl pixi.js

我正在尝试使用PixiJS库编写WebGL图像过滤器。我的过滤器应该采用一组数组,其中每个内部数组代表一种可能的像素颜色。然后,该函数将决定使用外部数组中的哪个元素。

我设法编写了一个简单的GLSL函数,该函数将单个颜色数组作为" uniform"参数,但我无法弄清楚如何传递嵌套数组。你能指点我正确的类型声明来接受来自这个片段的嵌套浮动数组吗?



 var phrases = [];
        $('#listDiv #hiddenItemList').each(function () {
            var phrase = '';
            $(this).find('li').each(function () {
                var current = $(this);
                phrase += $(this).text() + ";";
            });
            phrases.push(phrase);
        });

        if (phrases === undefined || phrases.length == 0 )
        {
            $.alert("Please select rate type, high rate and low rate", {
                title: "Rates Info",
                type: "danger"
            });
            return false;
        }

var fragmentSrc = [
  "uniform vec4 colorList;", // WHAT TYPE DO I NEED HERE TO PASS THE ARRY IN THE COMMENT BELOW?
  "void main() {",
  "  float GrayScale =  (gl_FragCoord.r * 299.0 / 1000.0) + (gl_FragCoord.g * 587.0 / 1000.0) + (gl_FragCoord.b * 114.0 / 1000.0);",
  "  float sigmoidThreshold = 1.0 / (1.0 + pow(2.7182818284590452353602874713527, (-((GrayScale - 128.0) /32.0))));",
  "  gl_FragColor = colorList;",
  "}",
];

var renderer = PIXI.autoDetectRenderer(750, 750);
document.body.appendChild(renderer.view);
var stage = new PIXI.Container();

function CustomFilter(fragmentSource) {

  PIXI.Filter.call(this,
    null,
    fragmentSource
  );
}

CustomFilter.prototype = Object.create(PIXI.Filter.prototype);
CustomFilter.prototype.constructor = CustomFilter;

var bg = new PIXI.Graphics();
bg.drawRect(0, 0, 375, 375);
bg.endFill();
stage.addChild(bg);

var filter = new CustomFilter(fragmentSrc.join('\r\n'));
filter.uniforms.colorList = [1.0, 1.0, 0.0, 1.0] // WANT TO PASS AN ARRAY OF ARRAYS LIKE: 
// [[1.0, 1.0, 0.0, 1.0], [0.0, 0.0, 1.0, 1.0]]
bg.filters = [filter];

renderer.render(stage);




<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.5.1/pixi.min.js"></script>

1 个答案:

答案 0 :(得分:0)

我将代码更改为此

var fragmentSrc = `
  uniform vec4 colorList[10]; 
  void main() {
    float GrayScale =  (gl_FragCoord.r * 299.0 / 1000.0) + (gl_FragCoord.g * 587.0 / 1000.0) + (gl_FragCoord.b * 114.0 / 1000.0);
    float sigmoidThreshold = 1.0 / (1.0 + pow(2.7182818284590452353602874713527, (-((GrayScale - 128.0) /32.0))));
    gl_FragColor = colorList[9];
  }
`;

var filter = new CustomFilter(fragmentSrc);
console.log(filter.uniforms);

打印

show console

所以这是有效的

filter.uniforms.colorList = [
   1, 0, 0, 0,     // 0
   1, 1, 0, 0,     // 1
   0, 1, 0, 0,     // 2
   0, 1, 1, 0,     // 3 
   0, 0, 1, 0,     // 4
   1, 0, 1, 0,     // 5
   .5, 0, 0, 0,    // 6
   0, .5, 0, 0,    // 7
   1, 1, 0, 1,     // 8
   .5, .5, .7, 1., // 9
];

和这个

filter.uniforms.colorList = new Float32Array([
   1, 0, 0, 0,     // 0
   1, 1, 0, 0,     // 1
   0, 1, 0, 0,     // 2
   0, 1, 1, 0,     // 3 
   0, 0, 1, 0,     // 4
   1, 0, 1, 0,     // 5
   .5, 0, 0, 0,    // 6
   0, .5, 0, 0,    // 7
   1, 1, 0, 1,     // 8
   .5, .5, .7, 1., // 9
]);

等...

如果你真的想在JavaScript中使用数组,你可以这样做,使ArrayBufferView成为更大的数组

const colorValues = [];
for (let i = 0; i < filter.uniforms.colorList.length; i += 4) {
  const buffer = filter.uniforms.colorList.buffer;
  const byteOffset = i * Float32Array.BYTES_PER_ELEMENT;
  const length = 4;
  colorValues.push(new Float32Array(buffer, byteOffset, length));
}

现在你可以像这样设置一个数组元素

colorValues[9].set([1, 1, 0, 1]);

&#13;
&#13;
var fragmentSrc = `
  uniform vec4 colorList[10]; // WHAT TYPE DO I NEED HERE TO PASS THE ARRY IN THE COMMENT BELOW?
  void main() {
    float GrayScale =  (gl_FragCoord.r * 299.0 / 1000.0) + (gl_FragCoord.g * 587.0 / 1000.0) + (gl_FragCoord.b * 114.0 / 1000.0);
    float sigmoidThreshold = 1.0 / (1.0 + pow(2.7182818284590452353602874713527, (-((GrayScale - 128.0) /32.0))));
    gl_FragColor = colorList[9];
  }
`;

var renderer = PIXI.autoDetectRenderer(750, 750);
document.body.appendChild(renderer.view);
var stage = new PIXI.Container();

function CustomFilter(fragmentSource) {

  PIXI.Filter.call(this,
    null,
    fragmentSource
  );
}

CustomFilter.prototype = Object.create(PIXI.Filter.prototype);
CustomFilter.prototype.constructor = CustomFilter;

var bg = new PIXI.Graphics();
bg.drawRect(0, 0, 375, 375);
bg.endFill();
stage.addChild(bg);

var filter = new CustomFilter(fragmentSrc);
const colorValues = [];
for (let i = 0; i < filter.uniforms.colorList.length; i += 4) {
  const buffer = filter.uniforms.colorList.buffer;
  const byteOffset = i * Float32Array.BYTES_PER_ELEMENT;
  const length = 4;
  colorValues.push(new Float32Array(buffer, byteOffset, length));
}

colorValues[9].set([1, 1, 0, 1]);

bg.filters = [filter];

renderer.render(stage);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.5.1/pixi.min.js"></script>
&#13;
&#13;
&#13;