ズームインして、ピクセル間にまっすぐに定義されたエッジを使用して描画したいビットマップがあります。
MAGフィルターをNEARESTに設定してみました。
gl.bindTexture(gl.TEXTURE_2D,this.tex);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.NEAREST);
...
gl.drawArrays(gl.TRIANGLES,0,6); // draw the texture
ただし、描画すると、ピクセルが一緒ににじみます。
これはwebGLなので、シェーダーがあります。私のシェーダーコードは非常に単純です。
バーテックスシェーダー:
...
attribute vec2 texCoord;
varying vec2 texel;
void main() {
texel = texCoord;
...
そしてフラグメントシェーダー:
...
varying vec2 texel;
uniform sampler2D texture;
void main() {
vec4 fragColour = texture2D(texture,texel);
...
相対コードのより大きなスニペットは次のとおりです。
map = {
vbo: gl.createBuffer(),
tex: gl.createTexture(),
program: createProgram(
"precision mediump float;\n"+
"uniform mat4 mvMatrix, pMatrix;\n"+
"attribute vec3 vertex;\n"+
"attribute vec2 texCoord;\n"+
"varying vec2 texel;\n"+
"void main() {\n"+
" texel = texCoord;\n"+
" gl_Position = pMatrix * mvMatrix * vec4(vertex,1.0);\n"+
"}\n",
"precision mediump float;\n"+
"uniform vec4 colour;\n"+
"uniform float fogDensity;\n"+
"uniform vec4 fogColour;\n"+
"varying vec2 texel;\n"+
"uniform sampler2D texture;\n"+
"const float LOG2 = 1.442695;\n"+
"void main() {\n"+
" float z = gl_FragCoord.z / gl_FragCoord.w;\n"+
" float fogFactor = exp2(-fogDensity*fogDensity*z*z*LOG2);\n"+
" fogFactor = clamp(fogFactor,0.0,1.0);\n"+
" vec4 fragColour = texture2D(texture,texel) * colour;\n"+
" gl_FragColor = mix(fogColour,fragColour,fogFactor);\n"+
"}\n",
["mvMatrix","pMatrix","colour","fogDensity","fogColour","texture"],
["vertex","texCoord"]),
plane: [[0,0,0],[0,1,0]],
init: function(w,h) {
this.w = w;
this.h = h;
var vertices = [
w,0,0, 1,0,
0,0,0, 0,0,
w,0,h, 1,1,
w,0,h, 1,1,
0,0,0, 0,0,
0,0,h, 0,1,
];
gl.bindBuffer(gl.ARRAY_BUFFER,this.vbo);
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices),gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER,null);
this._mapArrayBuffer = new ArrayBuffer(w*h*4);
this._mapByteBuffer = new Uint8Array(this._mapArrayBuffer);
this.map = new Uint32Array(this._mapArrayBuffer);
for(var i=0; i<w*h; i++) // test data: red and green pixels
this.map[i] = Math.random()>0.5? 0xff000080: 0xff008000;
createTexture(this.tex,w,h,this._mapByteBuffer,true);
},
draw: function() {
var program = this.program;
gl.useProgram(program);
gl.uniformMatrix4fv(program.pMatrix,false,camera.pMatrix);
gl.uniformMatrix4fv(program.mvMatrix,false,camera.mvMatrix);
gl.uniform4f(program.colour,1,1,1,1);
gl.uniform4f(program.fogColour,1,1,1,1);
gl.uniform1f(program.fogDensity,0.03);
gl.bindTexture(gl.TEXTURE_2D,this.tex);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.NEAREST);
gl.bindBuffer(gl.ARRAY_BUFFER,this.vbo);
gl.enableVertexAttribArray(program.vertex);
gl.vertexAttribPointer(program.vertex,3,gl.FLOAT,false,5*4,0);
gl.enableVertexAttribArray(program.texCoord);
gl.vertexAttribPointer(program.texCoord,2,gl.FLOAT,false,5*4,3*4);
gl.drawArrays(gl.TRIANGLES,0,6);
gl.disableVertexAttribArray(program.texCoord);
gl.disableVertexAttribArray(program.vertex);
gl.bindBuffer(gl.ARRAY_BUFFER,null);
gl.bindTexture(gl.TEXTURE_2D,null);
gl.useProgram(null);
},
};
function createTexture(tex,width,height,data,noMipMap) {
tex = tex || gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D,tex);
tex.width = width || data.width;
tex.height = height || data.height;
if(width != null)
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,width,height,0,gl.RGBA,gl.UNSIGNED_BYTE,data || null);
else
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,data);
if(anisotropy)
gl.texParameterf(gl.TEXTURE_2D,anisotropic.TEXTURE_MAX_ANISOTROPY_EXT,anisotropy);
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.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);
if(!noMipMap && !(tex.width&(tex.width-1)) && !(tex.height&(tex.height-1))) { //pow2
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR_MIPMAP_LINEAR);
gl.generateMipmap(gl.TEXTURE_2D);
} else
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);
gl.bindTexture(gl.TEXTURE_2D,null);
_textures.push(tex);
return tex;
}