OpenGLの - エクストリームテクスチャ品質の損失

エフゲニー・コバ:

私は、テクスチャ球にしようとしています。マイ頂点シェーダ:

attribute vec3 a_position;
attribute vec3 a_normal;
attribute vec3 a_texCoord0;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform sampler2D u_texture;
varying vec3 fragPos;
varying vec3 normal;
varying vec3 color;

void main()
{
    gl_Position = projection * view * model * vec4(a_position, 1.0);
    fragPos = vec3(model * vec4(a_position, 1.0));
    normal = a_normal;
    if(a_texCoord0.x > 50){
        color = vec3(1f, 0.0f, 0.0f);
    } else {
        color = texture(u_texture, a_texCoord0);
    }
}

私のフラグメントシェーダ:

#ifdef GL_ES
    precision mediump float;
#endif
varying vec3 normal;
varying vec3 color;
varying vec3 fragPos;

uniform vec3 lightPos;
uniform vec3 lightColor;

void main()
{
    // Ambient
    float ambientStrength = 0.1;
    vec3 ambient = ambientStrength * lightColor;

    // Diffuse
    vec3 norm = normalize(normal);
    vec3 lightDir = normalize(lightPos - fragPos);
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = diff * lightColor;

    //vec3 result = (ambient + diffuse) * color;
    vec3 result = color;
    gl_FragColor = vec4(result, 1.0);
}

私はそれが6つの同じテクスチャを使用して、二十面体が、テクスチャから球を構築し、キューブマッププリンシペで接続します。THITは、私がUVに球面座標を変換する方法のコードです:

public void fillTexInformation(Vertex vertex){
        float[] sphericalCoord = GeometryHelper.toSphericalCoordinates(vertex.getPosition());
        vertex.setTexCoord(projection(sphericalCoord[1], sphericalCoord[2]));
    }

    /**
     * Project point on shpere to texture coordinate
     * @param theta
     * @param phi
     * @return
     */
    //https://stackoverflow.com/questions/29678510/convert-21-equirectangular-panorama-to-cube-map
    private Vector2 projection(float theta, float phi) {
        if (theta < 0.615) {
            return projectRight(theta, phi);
        } else if (theta > 2.527) {
            return projectLeft(theta, phi);
        } else if (phi <= Math.PI / 4 || phi > 7 * Math.PI / 4) {
            return projectBack(theta, phi);
        } else if (phi > Math.PI / 4 && phi <= 3 * Math.PI / 4) {
            return projectBottom(theta, phi);
        } else if (phi >3 * Math.PI / 4 && phi <= 5 * Math.PI / 4) {
            return projectFront(theta, phi);
        } else if (phi > 5 * Math.PI / 4 && phi <= 7 * Math.PI / 4) {
            return projectTop(theta, phi);
        } else {
            throw new RuntimeException("Algorithm error");
        }
    }

    private Vector2 projectBack(float theta, float phi) {
        float y = (float) Math.tan(phi);
        float z = (float) ((1 / Math.tan(theta)) / Math.cos(phi));
        if (z < -1) {
            return projectLeft(theta, phi);
        }
        if (z > 1) {
            return projectRight(theta, phi);
        }

        return new Vector2(normilizeTexCoord(y), normilizeTexCoord(z));
    }

    private Vector2 projectBottom(float theta, float phi) {
        float x = (float) Math.tan(phi - Math.PI / 2);
        float z = (float) ((1 / Math.tan(theta)) / Math.cos(phi - Math.PI / 2));
        if (z < -1) {
            return projectLeft(theta, phi);
        }
        if (z > 1) {
            return projectRight(theta, phi);
        }

//        return new Vector2(normilizeTexCoord(x), normilizeTexCoord(z));
        return new Vector2(100, 100);
    }

    private Vector2 projectFront(float theta, float phi) {
        float y = (float) Math.tan(phi);
        float z = (float) (-(1 / Math.tan(theta)) / Math.cos(phi));
        if (z < -1) {
            return projectLeft(theta, phi);
        }
        if (z > 1) {
            return projectRight(theta, phi);
        }

//        return new Vector2(normilizeTexCoord(y), normilizeTexCoord(z));
        return new Vector2(100, 100);
    }

    private Vector2 projectTop(float theta, float phi) {
        float x = (float) Math.tan(phi - 3 * Math.PI / 2);
        float z = (float) ((1 / Math.tan(theta)) / Math.cos(phi - 3 * Math.PI / 2));
        if (z < -1) {
            return projectLeft(theta, phi);
        }
        if (z > 1) {
            return projectRight(theta, phi);
        }

//        return new Vector2(normilizeTexCoord(x), normilizeTexCoord(z));
        return new Vector2(100, 100);
    }

    private Vector2 projectRight(float theta, float phi) {
        float x = (float) (Math.tan(theta) * Math.cos(phi));
        float y = (float) (Math.tan(theta) * Math.sin(phi));
//        return new Vector2(normilizeTexCoord(x), normilizeTexCoord(y));
        return new Vector2(100, 100);
    }

    private Vector2 projectLeft(float theta, float phi) {
        float x = (float) (-Math.tan(theta) * Math.cos(phi));
        float y = (float) (-Math.tan(theta) * Math.sin(phi));
//        return new Vector2(normilizeTexCoord(x), normilizeTexCoord(-y));
        return new Vector2(100, 100);
    }

    private float normilizeTexCoord(float coord){
        return (coord + 1) / 2;
    }

その結果、私はちょうどひどいテクスチャ品質の損失を取得します。これは、元のテクスチャ私は球に乗る(ここではキューブマップの一部のみが、他の側面が赤色です)。私はそれが(正二十面体から)メソッドを構築し、(キューブマップの一種で)テクスチャの違いと接続することができることを推測しています。しかし、それは、テクスチャの凹凸のエッジではなく、ひどい品質の損失を説明することができます。誰かがここで何が起こるか私に説明していただけますか?

Brdla:

あなたが唯一の各三角形の角の三色を買ってあげる意味頂点シェーダでテクスチャをサンプリングするためです。他の画素を補間します。

より良い品質のために、テクスチャサンプリングは、フラグメントシェーダに移動さ​​れるべきであり、UV座標は、色の代わりに、補間されるべきです。

頂点シェーダ:

attribute vec3 a_position;
attribute vec3 a_normal;
attribute vec3 a_texCoord0;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

varying vec3 fragPos;
varying vec3 normal;
varying vec2 texcoord0;

void main()
{
    gl_Position = projection * view * model * vec4(a_position, 1.0);
    fragPos = vec3(model * vec4(a_position, 1.0));
    normal = a_normal;
    texcoord0 = a_texCoord0;
}

フラグメントシェーダ:

varying vec3 normal;
varying vec2 texcoord0;
varying vec3 fragPos;

uniform sampler2D u_texture;
uniform vec3 lightPos;
uniform vec3 lightColor;

void main()
{
    vec3 color = texture(u_texture, texcoord0).rgb;

    // Ambient
    float ambientStrength = 0.1;
    vec3 ambient = ambientStrength * lightColor;

    // Diffuse
    vec3 norm = normalize(normal);
    vec3 lightDir = normalize(lightPos - fragPos);
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = diff * lightColor;

    //vec3 result = (ambient + diffuse) * color;
    vec3 result = color;
    gl_FragColor = vec4(result, 1.0);
}

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=316456&siteId=1