简体   繁体   English

如果我使用具有不同参数的 glsl 纹理函数,模型将不可见的 opengl glsl 错误

[英]opengl glsl bug in which model goes invisible if i use glsl texture function with different parameters

I want to replicate a game.我想复制一个游戏。 The goal of the game is to create a path between any 2 squares that have the same color.游戏的目标是在任意 2 个颜色相同的方格之间创建一条路径。

Here is the game: www.mypuzzle.org/3d-logic-2这是游戏:www.mypuzzle.org/3d-logic-2

The cube has 6 faces.立方体有 6 个面。 Each faces has 3x3 squares.每个面都有 3x3 的正方形。

The cube has different square types: empty squares(reflect the environment), wall squares(you cant color them), start/finish squares(which have a black square in the middle but the rest of it is the colored).立方体有不同的方块类型:空方块(反映环境)、墙方块(你不能给它们上色)、开始/结束方块(中间有一个黑色方块,其余部分是彩色的)。

I've close to finishing my project but i'm stuck with a bug.我已经接近完成我的项目,但我遇到了一个错误。 I used c++,sfml,opengl,glm.我用过 c++、sfml、opengl、glm。

The problem is in the shaders.问题出在着色器中。

Vertex shader:顶点着色器:

#version 330 core

layout (location = 0) in vec3 vPosition;
layout (location = 1) in vec3 vColor;
layout (location = 2) in vec2 vTexCoord;
layout (location = 3) in float vType;
layout (location = 4) in vec3 vNormal;

out vec3 Position;
out vec3 Color;
out vec2 TexCoord;
out float Type;
out vec3 Normal;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    gl_Position = projection * view * model * vec4(vPosition, 1.0f);

    Position = vec3(model * vec4(vPosition, 1.0f));
    Color=vColor;
    TexCoord=vTexCoord;
    Type=vType;
    Normal = mat3(transpose(inverse(model))) * vNormal;
}

Fragment shader:片段着色器:

#version 330 core
in vec3 Color;
in vec3 Normal;
in vec3 Position;

in vec2 TexCoord;
in float Type;

out vec4 color;

uniform samplerCube skyboxTexture;
uniform sampler2D faceTexture;
uniform sampler2D centerTexture;

void main()
{
    color=vec4(0.0,0.0,0.0,1.0);
    if(Type==0.0)
    {
        vec3 I = normalize(Position);
        vec3 R = reflect(I, normalize(Normal));
        if(texture(faceTexture, TexCoord)==vec4(1.0,1.0,1.0,1.0))
            color=mix(texture(skyboxTexture, R),vec4(1.0,1.0,1.0,1.0),0.3);*/
    }
    else if(Type==1.0)
    {
        if(texture(centerTexture, TexCoord)==vec4(1.0,1.0,1.0,1.0))
            color=vec4(Color,1.0);
    }
    else if(Type==-1.0)
    {
        color=vec4(0.0,0.0,0.0,1.0);
    }
    else if(Type==2.0)
    {
        if(texture(faceTexture, TexCoord)==vec4(1.0,1.0,1.0,1.0))
            color=mix(vec4(Color,1.0),vec4(1.0,1.0,1.0,1.0),0.5);
    }
}

/*
Type== 0 ---> blank square(reflects light)
Type== 1 --->  start/finish square
Type==-1 ---> wall square
Type== 2 ---> colored square that was once a black square
*/

In the fragment shader i draw the pixels of a square that has a certain type, so the shader only enters in 1 of the 4 if's for each square.在片段着色器中,我绘制了具有特定类型的正方形的像素,因此着色器仅输入每个正方形的 4 个 if 中的 1 个。 The program works fine if i only use the glsl function texture with the same texture.如果我只使用具有相同纹理的 glsl 函数texture ,该程序运行良好。 If i use this function 2 times with different textures ,in 2 differents if's ,my model goes invisible.如果我对不同的纹理使用此功能 2 次,如果使用 2 次,我的模型将不可见。 Why is that happening?为什么会这样?

https://postimg.org/image/lximpl0bz/ https://postimg.org/image/lximpl0bz/

https://postimg.org/image/5dzvqz2r7/ https://postimg.org/image/5dzvqz2r7/

The red square is of type 1. I've modified code in the type==0 if and then my model went invisible.红色方块是类型 1。我修改了 type==0 中的代码,然后我的模型变得不可见。

Texture sampler in OpenGL should only be accessed in (at least) dynamically uniform control flow. OpenGL 中的纹理采样器只能在(至少)动态统一控制流中访问。 This basically means, that all invocations of a shader execute the same code path.这基本上意味着,着色器的所有调用都执行相同的代码路径。 If this is not the case, then no automatic gradients are available and mipmapping or anisotropic filtering will fail.如果不是这种情况,则没有可用的自动梯度,并且 mipmapping 或各向异性过滤将失败。

In your program this problem happens exactly when you try to use multiple textures.在您的程序中,当您尝试使用多个纹理时,这个问题就会发生。 One solution might be not to use anything that requires gradients.一种解决方案可能是不使用任何需要渐变的东西。 There are also a number of other options, for example, patching all textures together in a texture atlas and just selecting the appropriate uv-coordinates in the shader or drawing each quad separately and providing the type through a uniform variable.还有许多其他选项,例如,将所有纹理拼凑到一个纹理图集中,然后在着色器中选择合适的 uv 坐标,或者单独绘制每个四边形并通过统一变量提供类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM