Safari пока не поддерживает image-rendering: pixelated;
в WebGL. Подана ошибка
Также crisp-edges
нет! = pixelated
.crisp-edges
может быть любым количеством алгоритмов.Это не значит pixelated
.Это означает, что применяет некоторый алгоритм, который сохраняет четкие края , из которых существует множество алгоритмов.
Сама спецификация показывает примеры:
Для данного изображения:
Это pixelated
:
Гдев качестве браузера разрешено использовать различные алгоритмы для crisp-edges
, например, результат может быть
Другими словами, ваш CSS можетне дает ожидаемых результатов.Если браузер не поддерживает пиксельную графику, но поддерживает четкие края, и если они используют алгоритм, подобный описанному выше, то пиксельный внешний вид не будет.
Самый эффективный способ рисовать пиксельную графику без image-rendering: pixelated
- этонарисовать небольшую текстуру, а затем нарисовать эту текстуру на холсте с фильтрацией NEAREST
.
const vs = `
attribute vec4 position;
void main() {
gl_Position = position;
}
`;
const fs = `
precision mediump float;
void main() {
gl_FragColor = vec4(1, 0, 0, 1);
}
`;
const screenVS = `
attribute vec4 position;
varying vec2 v_texcoord;
void main() {
gl_Position = position;
// because we know position goes from -1 to 1
v_texcoord = position.xy * 0.5 + 0.5;
}
`;
const screenFS = `
precision mediump float;
varying vec2 v_texcoord;
uniform sampler2D u_tex;
void main() {
gl_FragColor = texture2D(u_tex, v_texcoord);
}
`;
const gl = document.querySelector('canvas').getContext('webgl', {antialias: false});
// compile shaders, link programs, look up locations
const programInfo = twgl.createProgramInfo(gl, [vs, fs]);
const screenProgramInfo = twgl.createProgramInfo(gl, [screenVS, screenFS]);
const width = 16;
const height = 16;
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
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);
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
// create buffers and put data in
const quadBufferInfo = twgl.createBufferInfoFromArrays(gl, {
position: {
numComponents: 2,
data: [
-1, -1,
1, -1,
-1, 1,
-1, 1,
1, -1,
1, 1,
],
}
});
render();
function render() {
// draw at 16x16 to texture
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.viewport(0, 0, width, height);
gl.useProgram(programInfo.program);
// bind buffers and set attributes
twgl.setBuffersAndAttributes(gl, programInfo, quadBufferInfo);
gl.drawArrays(gl.TRIANGLES, 0, 3); // only draw the first triangle
// draw texture to canvas
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.useProgram(screenProgramInfo.program);
// bind buffers and set attributes
twgl.setBuffersAndAttributes(gl, screenProgramInfo, quadBufferInfo);
// uniforms default to 0 so in this simple case
// no need to bind texture or set uniforms since
// we only have 1 texture, it's on texture unit 0
// and the uniform defaults to 0
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
<canvas width="256" height="256"></canvas>
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
Примечание. Если для рендеринга 3D или по какой-либо другой причине требуется буфер глубины, вам необходимо добавить вложение буфера глубины рендеринга в кадровый буфер.
Обратите внимание, что optimizeSpeed
также не является реальным вариантом.Это давно устарело и, как crisp-edges
, браузер должен интерпретировать.