Кажется, работает на меня.Может быть, сравните и посмотрите, что вы делаете по-другому?
const img = new Image();
img.addEventListener('load', render);
img.crossOrigin = "";
img.src = "https://i.imgur.com/ZKMnXce.png";
function render() {
const vs = `
attribute vec4 position;
void main() {
gl_PointSize = 80.0;
gl_Position = position;
}
`;
const fs = `
precision mediump float;
uniform sampler2D tex;
void main() {
gl_FragColor = texture2D(tex, gl_PointCoord);
}
`;
const gl = document.querySelector("canvas").getContext("webgl");
const program = twgl.createProgram(gl, [vs, fs]);
const positionLoc = gl.getAttribLocation(program, "position");
const ctx = document.createElement("canvas").getContext("2d");
ctx.canvas.width = img.width;
ctx.canvas.height = img.height;
ctx.fillStyle = '#FFF'
ctx.drawImage(img, 0, 0);
ctx.font = "bold 48px sans-serif";
ctx.fillText("imageData", 10, 200);
const imgData = ctx.getImageData(0, 0, img.width, img.height);
ctx.drawImage(img, 0, 0);
ctx.fillText("canvas", 10, 200);
gl.useProgram(program);
createTextureAndDraw(img, -.6);
createTextureAndDraw(ctx.canvas, 0);
createTextureAndDraw(imgData, .6);
function createTextureAndDraw(src, x) {
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
{
const level = 0;
const internalFormat = gl.RGBA;
const width = 1;
const height = 1;
const border = 0;
const format = gl.RGBA;
const type = gl.UNSIGNED_BYTE;
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
format, type, src);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
}
gl.vertexAttrib1f(positionLoc, x);
const primitiveType = gl.POINTS;
const offset = 0;
const count = 1;
gl.drawArrays(primitiveType, offset, count);
}
}
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
<canvas></canvas>
Читая обновления вашего вопроса, вы, вероятно, должны открыть новый вопрос, поскольку ваша реальная проблема вовсе не связана с заданным вами вопросом.
Во-первых, Canvas ВСЕГДА ПРЕОБРАЗОВАННЫЙ .Это означает, что это с потерями.
Это подробно описано в этом ответе: https://stackoverflow.com/a/50566789/128511
Так как вы собираетесь использовать Image (png) -> Canvas -> ImageData, тогда, если ваш PNG имеет не 255альфа, вы потеряете данные.
Во-вторых, вы упомянули гамма-коррекцию.Да, браузер будет корректировать гамму и / или применять другие преобразования цветов к изображениям.Это делается для того, чтобы изображения, нарисованные в WebGL, соответствовали изображениям, нарисованным в Canvas, и изображениям, отображаемым на странице.
Чтобы избежать преобразования цвета, вам нужно установить gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE)
, который говорит WebGL делать все, что нужно, чтобы получить исходные данные из изображения (что может включать в себя повторное декодирование изображения с нуля, так как изображение по умолчанию)Данные - это любой формат, который необходим браузеру для рисования тегов изображений в HTML).
Вот пример неприменения преобразования цвета.Создает 2 текстуры из одного изображения.Один раз с преобразованием цветов по умолчанию, один раз без.
const img = new Image();
img.addEventListener('load', render);
img.crossOrigin = "";
img.src = "https://cdn.rawgit.com/KhronosGroup/WebGL/8ea92581/sdk/tests/resources/small-square-with-colorspin-profile.png";
function render() {
const vs = `
attribute vec4 position;
void main() {
gl_PointSize = 130.0;
gl_Position = position;
}
`;
const fs = `
precision mediump float;
uniform sampler2D tex;
void main() {
gl_FragColor = texture2D(tex, gl_PointCoord);
}
`;
const gl = document.querySelector("canvas").getContext("webgl");
const program = twgl.createProgram(gl, [vs, fs]);
const positionLoc = gl.getAttribLocation(program, "position");
gl.useProgram(program);
createTextureAndDraw(img, -.5, true); // default (with COLOR CONVERSION)
createTextureAndDraw(img, .5, false); // color conversion OFF
function createTextureAndDraw(src, x, colorConversion) {
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
const mode = colorConversion ? gl.BROWSER_DEFAULT_WEBGL : gl.NONE;
gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, mode);
{
const level = 0;
const internalFormat = gl.RGBA;
const width = 1;
const height = 1;
const border = 0;
const format = gl.RGBA;
const type = gl.UNSIGNED_BYTE;
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
format, type, src);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
}
gl.vertexAttrib1f(positionLoc, x);
const primitiveType = gl.POINTS;
const offset = 0;
const count = 1;
gl.drawArrays(primitiveType, offset, count);
}
}
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
<canvas></canvas>
Примечание: это крайний пример, так как текстура красная с преобразованием цвета, а синяя без.Если вы откроете файл в фотошопе, вы увидите, что необработанные данные отображаются синим цветом, но в зависимости от цветового профиля они отображаются красным цветом.
В тесте на соответствие WebGL для этой функции есть несколько крайних примеров , чтобы проверить, что вы можете получить необработанные данные из PNG в WebGL.