6

ズームインして、ピクセル間にまっすぐに定義されたエッジを使用して描画したいビットマップがあります。

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;
}
4

1 に答える 1

4

[解決済み]問題は、テクスチャの異方性を有効にしていたことでした。異方性は gl_NEAREST よりも優れているようです。テクスチャで gl_NEAREST を使用する場合は、異方性を設定しないことが重要です。

于 2013-03-15T10:06:54.040 に答える