OpenGL – ¿Cómo crear transparencia independiente de orden?

He estado trabajando en un motor de juego con fines educativos y me encontré con este problema. Parece que no puedo encontrar una respuesta para:

El canal alfa solo funciona para objetos que ya han sido dibujados antes del objeto que tiene el canal alfa (Por ejemplo: en una escena con 3 objetos, digamos un gato, un perro y una botella (transparente). Tanto el gato como el perro están detrás de la botella, primero se dibuja el perro, el biberón se coloca en segundo lugar, el gato se coloca tercero, solo el perro se verá a través de la botella).

Aquí hay una imagen de este problema: Los objetos se dibujan en el orden en que aparecen en el cuadro de lista

Usé C ++ para el motor, Win32 API para el editor y GLSL para sombreado:

// some code here vec4 alpha = texture2D(diffuse, texCoord0).aaaa; vec4 negalpha = alpha * vec4(-1,-1,-1,1) + vec4(1,1,1,0); vec4 textureComponentAlpha = alpha*textureComponent+negalpha*vec4(1,1,1,0);//(texture2D ( diffuse, texCoord0 ) ).aaaa; gl_FragColor = (textureComponentAlpha + vec4(additiveComponent.xyz, 0)) * vec4(lightingComponent.xyz, 1); 

En C ++:

 glEnable(GL_ALPHA_TEST); glDepthFunc(GL_EQUAL); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

Supongo que tiene algo que ver con la forma en que se realiza la prueba alfa, o algo así.

¿Alguien podría ayudarme a solucionar esto, por favor?

Estoy usando algo similar a esa respuesta vinculada por el comentario de @RetoKoradi, pero obtuve modelos transparentes de doble capa con texturas (vidrio con superficie interna y externa) con maquinaria completamente sólida y todo.

Para tales escenas también estoy usando el enfoque de varios pasos y la clasificación Z se realiza por secuencia de configuración de la cara frontal.

  1. renderizar todos los objetos sólidos
  2. renderizar todos los objetos transparentes

    Esta es la parte difícil primero que establezco

     glGetIntegerv(GL_DEPTH_FUNC,&depth_funct); glDepthFunc(GL_ALWAYS); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_CULL_FACE); 

    Obtuve las capas de geometría almacenadas por separado (exterior interno) así que la clasificación Z se hace así:

    • glFrontFace(GL_CW); caras posteriores de la capa externa con glFrontFace(GL_CW);
    • glFrontFace(GL_CW); caras traseras de la capa interna con glFrontFace(GL_CW);
    • glFrontFace(GL_CCW); caras frontales de la capa interna con glFrontFace(GL_CCW);
    • glFrontFace(GL_CCW); caras frontales de la capa externa con glFrontFace(GL_CCW);

    Y por último restaurar

     glDisable(GL_BLEND); glDepthFunc(depth_funct); 
  3. renderizar todos los objetos sólidos otra vez

Está lejos de ser perfecto, pero lo suficiente para mis propósitos se ve así:

ejemplo

No puedo alentarlo lo suficiente como para echar un vistazo a este documento de NVidia y la publicación del blog relacionada por Morgan McGuire.

Esto es bastante fácil de implementar y tiene excelentes resultados en general.

No estoy del todo seguro de que esto ayude a su situación, pero ¿tiene mezclado y habilitado alfa? Como en :

  glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);