WebGL 统一参数类型
WebGL Uniform Argument Type
我正在尝试使用 PixiJS 库编写 WebGL 图像过滤器。我的过滤器应该采用一个数组数组,其中每个内部数组代表一种可能的像素颜色。然后该函数将决定使用外部数组中的哪个元素。
我已经设法编写了一个简单的 GLSL 函数,它将 单一 颜色数组作为 "uniform" 参数,但是我不知道如何传递嵌套数组。你能指出正确的类型声明来接受这个片段中的嵌套浮点数组吗?
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>
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 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);
并打印
所以这行得通
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
s 变成更大的数组
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]);
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);
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.5.1/pixi.min.js"></script>
我正在尝试使用 PixiJS 库编写 WebGL 图像过滤器。我的过滤器应该采用一个数组数组,其中每个内部数组代表一种可能的像素颜色。然后该函数将决定使用外部数组中的哪个元素。
我已经设法编写了一个简单的 GLSL 函数,它将 单一 颜色数组作为 "uniform" 参数,但是我不知道如何传递嵌套数组。你能指出正确的类型声明来接受这个片段中的嵌套浮点数组吗?
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>
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 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);
并打印
所以这行得通
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
s 变成更大的数组
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]);
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);
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.5.1/pixi.min.js"></script>