将向量数组传递给着色器
Passing Array Of Vectors To Shader
尝试将 vec3 数组传递给着色器时,Firefox 给我这个警告:
WebGL warning: uniform setter: (uniform u_colors[0]) 'values' length
(4) must be a positive integer multiple of size of <enum 0x8b51>.
此外,它只呈现黑色,而不是给定的颜色。
const colrs = [
[239, 71, 111],
[255, 209, 102],
[6, 214, 160],
[17, 138, 178]
],
dmnsn = [1200, 300],
glCtx = (() => twgl.getContext(document.createElement("canvas")))(
twgl.setDefaults({ attribPrefix: "a_" })
);
var bfInf = twgl.primitives.createXYQuadBufferInfo(glCtx),
pgInf = twgl.createProgramInfo(glCtx, ["vs", "fs"]);
function rendr(fbi, pi, u) {
twgl.bindFramebufferInfo(glCtx, fbi);
twgl.drawObjectList(glCtx, [
{
programInfo: pi,
bufferInfo: bfInf,
uniforms: u
}
]);
}
function prepr() {
glCtx.canvas.width = dmnsn[0];
glCtx.canvas.height = dmnsn[1];
document.body.append(glCtx.canvas);
rendr(null, pgInf, { u_colors: colrs });
}
prepr();
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<script id="vs" type="x-shader/x-vertex">
attribute vec4 a_position;
attribute vec2 a_texcoord;
varying vec2 v_texcoord;
void main() {
v_texcoord = a_texcoord;
gl_Position = a_position;
}
</script>
<script id="fs" type="x-shader/x-fragment">
precision highp float;
uniform vec3 u_colors[4];
void main() {
gl_FragColor= vec4(u_colors[0], 1.0);
}
</script>
WebGL 不需要数组的数组。
const someArrayWith4ArraysOf3Values = [
[11, 22, 33],
[44, 55, 66],
[77, 88, 99],
[10, 11, 12],
];
gl.uniform3fv(some4ElementVec3Uniform, someArrayWith4ArraysOf3Values); // bad
它想要一个平面阵列。
const someArrayWith12Values = [
11, 22, 33,
44, 55, 66,
77, 88, 99,
10, 11, 12,
];
gl.uniform3fv(some4ElementVec3Uniform, someArrayWith12Values); // good
此外,着色器中的颜色是从 0 到 1 的浮点值,因此您可能希望在着色器中将颜色设置为 0 到 1 的值或除以 255
const colrs = [
[1, 0.7, 0.5],
[255, 209, 102],
[6, 214, 160],
[17, 138, 178]
].flat(),
dmnsn = [1200, 300],
glCtx = (() => twgl.getContext(document.createElement("canvas")))(
twgl.setDefaults({ attribPrefix: "a_" })
);
var bfInf = twgl.primitives.createXYQuadBufferInfo(glCtx),
pgInf = twgl.createProgramInfo(glCtx, ["vs", "fs"]);
function rendr(fbi, pi, u) {
twgl.bindFramebufferInfo(glCtx, fbi);
twgl.drawObjectList(glCtx, [
{
programInfo: pi,
bufferInfo: bfInf,
uniforms: u
}
]);
}
function prepr() {
glCtx.canvas.width = dmnsn[0];
glCtx.canvas.height = dmnsn[1];
document.body.append(glCtx.canvas);
rendr(null, pgInf, { u_colors: colrs });
}
prepr();
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<script id="vs" type="x-shader/x-vertex">
attribute vec4 a_position;
attribute vec2 a_texcoord;
varying vec2 v_texcoord;
void main() {
v_texcoord = a_texcoord;
gl_Position = a_position;
}
</script>
<script id="fs" type="x-shader/x-fragment">
precision highp float;
uniform vec3 u_colors[4];
void main() {
gl_FragColor=vec4(u_colors[0], 1.0);
}
</script>
尝试将 vec3 数组传递给着色器时,Firefox 给我这个警告:
WebGL warning: uniform setter: (uniform u_colors[0]) 'values' length (4) must be a positive integer multiple of size of <enum 0x8b51>.
此外,它只呈现黑色,而不是给定的颜色。
const colrs = [
[239, 71, 111],
[255, 209, 102],
[6, 214, 160],
[17, 138, 178]
],
dmnsn = [1200, 300],
glCtx = (() => twgl.getContext(document.createElement("canvas")))(
twgl.setDefaults({ attribPrefix: "a_" })
);
var bfInf = twgl.primitives.createXYQuadBufferInfo(glCtx),
pgInf = twgl.createProgramInfo(glCtx, ["vs", "fs"]);
function rendr(fbi, pi, u) {
twgl.bindFramebufferInfo(glCtx, fbi);
twgl.drawObjectList(glCtx, [
{
programInfo: pi,
bufferInfo: bfInf,
uniforms: u
}
]);
}
function prepr() {
glCtx.canvas.width = dmnsn[0];
glCtx.canvas.height = dmnsn[1];
document.body.append(glCtx.canvas);
rendr(null, pgInf, { u_colors: colrs });
}
prepr();
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<script id="vs" type="x-shader/x-vertex">
attribute vec4 a_position;
attribute vec2 a_texcoord;
varying vec2 v_texcoord;
void main() {
v_texcoord = a_texcoord;
gl_Position = a_position;
}
</script>
<script id="fs" type="x-shader/x-fragment">
precision highp float;
uniform vec3 u_colors[4];
void main() {
gl_FragColor= vec4(u_colors[0], 1.0);
}
</script>
WebGL 不需要数组的数组。
const someArrayWith4ArraysOf3Values = [
[11, 22, 33],
[44, 55, 66],
[77, 88, 99],
[10, 11, 12],
];
gl.uniform3fv(some4ElementVec3Uniform, someArrayWith4ArraysOf3Values); // bad
它想要一个平面阵列。
const someArrayWith12Values = [
11, 22, 33,
44, 55, 66,
77, 88, 99,
10, 11, 12,
];
gl.uniform3fv(some4ElementVec3Uniform, someArrayWith12Values); // good
此外,着色器中的颜色是从 0 到 1 的浮点值,因此您可能希望在着色器中将颜色设置为 0 到 1 的值或除以 255
const colrs = [
[1, 0.7, 0.5],
[255, 209, 102],
[6, 214, 160],
[17, 138, 178]
].flat(),
dmnsn = [1200, 300],
glCtx = (() => twgl.getContext(document.createElement("canvas")))(
twgl.setDefaults({ attribPrefix: "a_" })
);
var bfInf = twgl.primitives.createXYQuadBufferInfo(glCtx),
pgInf = twgl.createProgramInfo(glCtx, ["vs", "fs"]);
function rendr(fbi, pi, u) {
twgl.bindFramebufferInfo(glCtx, fbi);
twgl.drawObjectList(glCtx, [
{
programInfo: pi,
bufferInfo: bfInf,
uniforms: u
}
]);
}
function prepr() {
glCtx.canvas.width = dmnsn[0];
glCtx.canvas.height = dmnsn[1];
document.body.append(glCtx.canvas);
rendr(null, pgInf, { u_colors: colrs });
}
prepr();
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<script id="vs" type="x-shader/x-vertex">
attribute vec4 a_position;
attribute vec2 a_texcoord;
varying vec2 v_texcoord;
void main() {
v_texcoord = a_texcoord;
gl_Position = a_position;
}
</script>
<script id="fs" type="x-shader/x-fragment">
precision highp float;
uniform vec3 u_colors[4];
void main() {
gl_FragColor=vec4(u_colors[0], 1.0);
}
</script>