OpenGL - Extrema pérdida de calidad de la textura

Evgeny Koba:

Estoy tratando de textura ámbito. Mi sombreado de vértices:

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

Mi fragment shader:

#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);
}

Me esfera acumulación de icosaedro, pero la textura usando 6 mismas texturas y conectarlo por cubemap Principe. Thit es el código de cómo traduzco coordenadas esféricas a los rayos 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;
    }

Como resultado consigo la pérdida de calidad de la textura simplemente terrible. Esta es la textura original, y lo que me pasa en la esfera (en este caso es sólo una parte de cubemap, otras partes son en color rojo). He pensado que puede ser conectado con la diferencia de la construcción de métodos (de icosaedro) y texturizado (con tipo de cubemap). Pero puede explicar bordes desiguales de textura, pero la pérdida de la calidad no es tan terrible. Por favor alguien puede explicar a mí lo que pasa aquí?

Brdla:

Esto sucede porque te muestra la textura en el vertex shader que significa que sólo obtendrá tres colores en la esquina de cada triángulo. Los otros píxeles se interpolan.

Para una mejor calidad, el muestreo de textura debe ser movido a la fragment shader y las coordenadas UV debe ser interpolado en lugar de los colores:

Vertex Shader:

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

Fragmento de sombreado:

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

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=316459&siteId=1
Recomendado
Clasificación