Opengl es OpenGL半透明四边形工件

Opengl es OpenGL半透明四边形工件,opengl-es,glsl,Opengl Es,Glsl,我目前正试图使我的水纹理半透明。我添加了以下混合参数: void Application::initialiseOpenGL() { printf("Initialising OpenGL context\n"); context = SDL_GL_CreateContext(window); assertFatal(context != NULL, "%s\n", SDL_GetError()); SDL_GL_SetSwapInterv

我目前正试图使我的水纹理半透明。我添加了以下混合参数:

void Application::initialiseOpenGL() {
  printf("Initialising OpenGL context\n");
  context = SDL_GL_CreateContext(window);
  assertFatal(context != NULL, "%s\n", SDL_GetError());
  SDL_GL_SetSwapInterval(0);
  glClearColor(0.0, 0.0, 0.0, 1.0);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glEnable(GL_DEPTH_TEST);
  // glEnable(GL_CULL_FACE);
  // glCullFace(GL_BACK);
}
我的水从一边看起来很好:

但是,从另一方面看,它似乎覆盖了已渲染的四边形:

这就是水下的样子:

这里可能有什么问题

这些是我的着色器:

#version 300 es
layout(location = 0) in vec3 position;
layout(location = 1) in float vertexFaceIndex;
layout(location = 2) in vec2 vertexUV;

out float fragmentFaceIndex;
out vec2 fragmentUV;
out float visibility;

uniform mat4 view;
uniform mat4 viewProjection;
uniform float currentTime;

const float fogDensity = 0.005;
const float fogGradient = 5.0;

void main() {
  fragmentFaceIndex = vertexFaceIndex;
  fragmentUV = vertexUV;
  float distance = length(vec3(view * vec4(position, 1.0)));
  visibility = exp(-1.0f * pow(distance * fogDensity, fogGradient));
  visibility = clamp(visibility, 0.0, 1.0);
  if(vertexFaceIndex == 6.0f) {
    float yVal = position.y - 0.4 +
    min(0.12 * sin(position.x + currentTime / 1.8f) + 0.12 * sin(position.z + currentTime / 1.3f), 0.12);
    gl_Position = viewProjection * vec4(vec3(position.x, yVal, position.z), 1.0);
  }
  else
    gl_Position = viewProjection * vec4(position, 1.0);
}
#版本300 es
精密中泵浮子;
统一采样器二维图谱;
输出vec4颜色;
浮动碎片指数;
在vec2片段中;
浮标能见度;
常量浮动环境强度=1.1f;
恒浮扩散强度=0.3f;
常数vec3 lightDirection=vec3(0.2f,-1.0f,0.2f);
const vec4 skyColor=vec4(0.612,0.753,0.98,1.0);
常数vec3 lightColor=vec3(1.0f,0.996f,0.937f);
const vec3 ambientColor=lightColor*ambientStrength;
//已手动验证面法线。。。
常量vec3面法线[7]=vec3[7](
vec3(0.0f,0.0f,1.0f),
vec3(0.0f,0.0f,-1.0f),
vec3(0.0f,1.0f,0.0f),
vec3(0.0f,-1.0f,0.0f),
vec3(-1.0f,0.0f,0.0f),
vec3(1.0f,0.0f,0.0f),
vec3(0.0f、1.0f、0.0f)
);
void main(){
vec4 textureFragment=纹理(atlas,fragmentUV).rgba;
如果(织构折射率a<0.5)丢弃;
浮动扩散因子=最大值(点(面法线[int(fragmentFaceIndex)],归一化(-1.0f*光方向)),0.0)*扩散强度;
vec3 diffuseColor=扩散因子*lightColor;
颜色=vec4((环境颜色+扩散颜色)*textureFragment.rgb,textureFragment.a);
颜色=混合(天空颜色、颜色、可见性);
}

当使用这种多边形渲染方法时,如果存在多个重叠的半透明多边形,则必须从后向前绘制半透明多边形

如果不进行此排序,z缓冲区不足以正确渲染包含半透明多边形的场景

您观察到的问题是,首先绘制水多边形,然后绘制其后面的块,但由于z缓冲区已设置为水位,因此不会渲染任何像素。在绘制水时禁用z缓冲区更新也不起作用,因为在这种情况下,稍后绘制的水下块将以正常颜色显示

你需要最后一次打水。

参见
#version 300 es
precision mediump float;
uniform sampler2D atlas;
out vec4 color;

in float fragmentFaceIndex;
in vec2 fragmentUV;
in float visibility;

const float ambientStrength = 1.1f;
const float diffuseStrength = 0.3f;

const vec3 lightDirection = vec3(0.2f, -1.0f, 0.2f);
const vec4 skyColor = vec4(0.612, 0.753, 0.98, 1.0);
const vec3 lightColor = vec3(1.0f, 0.996f, 0.937f);
const vec3 ambientColor = lightColor * ambientStrength;
// Face normals have been manually verified...
const vec3 faceNormals[7] = vec3[7](
  vec3(0.0f, 0.0f, 1.0f),
  vec3(0.0f, 0.0f, -1.0f),
  vec3(0.0f, 1.0f, 0.0f),
  vec3(0.0f, -1.0f, 0.0f),
  vec3(-1.0f, 0.0f, 0.0f),
  vec3(1.0f, 0.0f, 0.0f),
  vec3(0.0f, 1.0f, 0.0f)
);

void main() {
  vec4 textureFragment = texture(atlas, fragmentUV).rgba;
  if(textureFragment.a < 0.5) discard;
  float diffuseFactor = max(dot(faceNormals[int(fragmentFaceIndex)], normalize(-1.0f * lightDirection)), 0.0) * diffuseStrength;
  vec3 diffuseColor = diffuseFactor * lightColor;
  color = vec4((ambientColor + diffuseColor) * textureFragment.rgb, textureFragment.a);
  color = mix(skyColor, color, visibility);
}