OpenGL ES 2.0 / 3.0中的折射。大像素纹理

问题描述 投票:1回答:1

尝试在OpenGL ES 2.0 / 3.0中实现折射。使用了以下着色器:

顶点着色器:

#version 300 es
precision lowp float; 
uniform mat4 u_mvMatrix;

in vec4 a_position;  
in vec3 a_normal;
...
out mediump vec2 v_refractCoord;

const mediump float eta = 0.95;

void main() {
    vec4 eyePositionModel = u_mvMatrix * a_position;

    // eye direction in model space
    mediump vec3 eyeDirectModel = normalize(a_position.xyz - eyePositionModel.xyz);

    // calculate refraction direction in model space
    mediump vec3 refractDirect = refract(eyeDirectModel, a_normal, eta);

    // project refraction
    refractDirect = (u_mvpMatrix * vec4(refractDirect, 0.0)).xyw;

    // map refraction direction to 2d coordinates
    v_refractCoord = 0.5 * (refractDirect.xy / refractDirect.z) + 0.5;
    ...
}

片段着色器:

...
in mediump vec2 v_refractCoord;
uniform samplerCube s_texture; // skybox

void main() {
    outColor = texture(s_texture, vec3(v_refractCoord, 1.0));
}

加载纹理的方法:

@JvmStatic
fun createTextureCubemap(context: Context, rowID: Int) {
    val input = context.resources.openRawResource(rowID)
    val bitmap = BitmapFactory.decodeStream(input)

    val textureId = IntArray(1)
    glGenTextures(1, textureId, 0)
    glBindTexture(GL_TEXTURE_CUBE_MAP, textureId[0])

    GLUtils.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, bitmap, 0)
    GLUtils.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, bitmap, 0)
    GLUtils.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, bitmap, 0)
    GLUtils.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, bitmap, 0)
    GLUtils.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, bitmap, 0)
    GLUtils.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, bitmap, 0)

    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
    return textureId[0]
}

但是纹理是通过大像素获得的,例如:

enter image description here

这可能是什么原因?对于低聚模型来说,这可能是正常的吗?似乎纹理太接近。

注意:多边形越少-质量越差。

感谢您的任何评论/回答!

来自goodfon.ru的图像

android opengl-es glsl shader opengl-es-3.0
1个回答
1
投票

这是法线矢量属性的问题,而不是着色器的问题。该问题是由以下事实引起的:法线矢量是按面计算的,而不是针对每个顶点单独计算的。注意,折射方向(refractDirect)取决于顶点坐标(eyeDirectModel)和法向矢量(a_normal):

mediump vec3 refractDirect = refract(eyeDirectModel, a_normal, eta);

由于相邻表面之间的法线向量不同,因此您可以在网格面之间看到明显的边缘。

如果法线向量是针对每个顶点计算的,则相邻面共享顶点坐标和相应的法线向量。这将导致从一个面对面的平滑过渡。


此外,还有另一个问题。 a_position.xyz - eyePositionModel.xyz没有任何意义,因为a_position是模型空间中的顶点坐标,而eyePositionModel是视图空间中的顶点坐标。您必须在视图空间中计算refract的入射向量。那就是从眼睛位置到顶点的向量。由于眼睛在视图空间中的位置为(0,0,0),因此为:

refract
© www.soinside.com 2019 - 2024. All rights reserved.