Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用自定义着色器进行OpenGL/ES渲染=网格上的瑕疵_C++_Opengl_Opengl Es_3d_Opengl Es 2.0 - Fatal编程技术网

C++ 使用自定义着色器进行OpenGL/ES渲染=网格上的瑕疵

C++ 使用自定义着色器进行OpenGL/ES渲染=网格上的瑕疵,c++,opengl,opengl-es,3d,opengl-es-2.0,C++,Opengl,Opengl Es,3d,Opengl Es 2.0,我试图在屏幕上渲染一个正方形平面网格,分辨率为255 x 255,128个世界单位(读取浮动) 在RAM中分配和填充此网格,将其上载到V-RAM,绑定到属性和索引缓冲区,在其上正确调用

我试图在屏幕上渲染一个正方形平面网格,分辨率为255 x 255,128个世界单位(读取浮动)

在RAM中分配和填充此网格,将其上载到V-RAM,绑定到属性和索引缓冲区,在其上正确调用
不是问题,对象按预期绘制

这是一个水面模拟我的工作和顶点高度得到计算和上传每一帧。当在水面上“点击”时,会产生扰动,然后计算水流并更新法线(考虑从下到上从左到右的水流)

我的问题是,在网格的某些部分,我得到的渲染效果可以在下面的图片中看到(第三个sans消隐)

值得注意的是,在最后一张图片中,效果似乎从视口最左侧的某个位置开始,继续向右延伸另一半宽度。仅当摄影机向左平移时,此效果才可见,在某些相对于网格的位置,但在其他位置不可见,并且摄影机的前进方向或ViewMatrix似乎对瑕疵没有影响。如果我将相机从一边滑动到另一边,我可以注意到工件的原点随着相机移动。该原点似乎位于视口的中心,其高度等于视口的高度,但有时仅为其宽度的四分之一,其他时间则可以达到一半。如前所述,摄影机的前进方向/注视向量对渲染没有影响。即使从“鸟瞰”视图进行渲染,仍然可以观察到效果

似乎相机位置干扰了
gl\u position=mat4\u ModelViewProjection*位置位,或者在顶点颜色计算中,
浮点点=点(N,V)需要某种(怪物)验证吗

以下是我的一些代码:

顶点着色器

"attribute vec2 pos;"
"attribute vec2 normal;"
"attribute float height;"

"uniform vec3 sunColor;"
"uniform float ax;"

"varying PRECISION_MEDIUM vec4 waterColor_;"
"varying PRECISION_LOW vec2 tex_coord;"

"const vec3 g_WaterBlue  = vec3( 0.05, 0.25, 0.3 );"
"const vec3 g_WaterGreen = vec3( 0.05, 0.3, 0.2 );"

"vec3 CalculateWaterColor(vec3 V, vec3 N)"
"{"
    "float dot = dot(N, V);"

    "vec3 waterColor = mix(g_WaterGreen, g_WaterBlue, dot);"
    "waterColor = mix(sunColor, waterColor, dot);"
    "waterColor = mix(waterColor, g_WaterBlue, dot);"

    "return waterColor;"
"}"

"void main()"
"{"
    "vec4 position = vec4(pos.x, height, pos.y, 1.0);"

    "vec3 V = camera_pos.xyz + camera_forward.xyz - position.xyz;"
    "V = normalize(V);"

    "vec3 N = vec3(normal.x, 1, normal.y);"
    "N = normalize(N);"

    "waterColor_.xyz = CalculateWaterColor(V, N);"
    "waterColor_.w = 1.0;"//ax * 18 / length(camera_pos.xyz - position.xyz);"

    "gl_Position = mat4_ModelViewProjection * position;"
"}"
// LEFT to RIGHT, BOTTOM to TOP
for (index1 = 0; index1 < (Resolution - 1); ++index1)
{
    for (index2 = 0; index2 < (Resolution - 1); ++index2)
    {
        // CLOCKWISE
        *++p_data = index2      + index1        * Resolution;
        *++p_data = index2      + (index1 + 1)  * Resolution;
        *++p_data = index2 + 1  + (index1 + 1)  * Resolution;

        *++p_data = index2      + index1        * Resolution;
        *++p_data = index2 + 1  + (index1 + 1)  * Resolution;
        *++p_data = index2 + 1  + index1        * Resolution;

        // COUNTER-CLOCKWISE
        //*++p_data = index2 +     (index1 + 1) * Resolution;
        //*++p_data = index2 +     index1       * Resolution;
        //*++p_data = index2 + 1 + index1       * Resolution;

        //*++p_data = index2 + 1 + index1       * Resolution;
        //*++p_data = index2 + 1 + (index1 + 1) * Resolution;
        //*++p_data = index2 +     (index1 + 1) * Resolution;
        // ..
    }
}
平面网格顶点生成

// set accelerators
accel1 = Size / static_cast<float>(Resolution - 1);
accel2 = -Size / 2.0f;

x = accel2;
y = accel2;
z = 1.0f;
// ..

// fill the vertex buffer
p_data = reinterpret_cast<float*>(buf_vertex->DataPointer) - 1;
for (index1 = 0; index1 < Resolution; ++index1)
{
    for (index2 = 0; index2 < Resolution; ++index2)
    {
        *++p_data = x;
        *++p_data = y;

        if (buf_vertex->Dimension == 3)
        {
            *++p_data = z;
        }

        x += accel1;
    }

    x = accel2; // Size / 2
    y += accel1;
}
// ..
//设置加速器
accel1=尺寸/静态投影(分辨率-1);
accel2=-Size/2.0f;
x=2;
y=2;
z=1.0f;
// ..
//填充顶点缓冲区
p_data=reinterpret_cast(buf_顶点->数据指针)-1;
对于(index1=0;index1<分辨率;++index1)
{
对于(index2=0;index2<分辨率;++index2)
{
*++p_数据=x;
*++p_数据=y;
如果(buf_顶点->尺寸==3)
{
*++p_数据=z;
}
x+=1;
}
x=accel2;//大小/2
y+=1;
}
// ..
平面网格索引生成器

"attribute vec2 pos;"
"attribute vec2 normal;"
"attribute float height;"

"uniform vec3 sunColor;"
"uniform float ax;"

"varying PRECISION_MEDIUM vec4 waterColor_;"
"varying PRECISION_LOW vec2 tex_coord;"

"const vec3 g_WaterBlue  = vec3( 0.05, 0.25, 0.3 );"
"const vec3 g_WaterGreen = vec3( 0.05, 0.3, 0.2 );"

"vec3 CalculateWaterColor(vec3 V, vec3 N)"
"{"
    "float dot = dot(N, V);"

    "vec3 waterColor = mix(g_WaterGreen, g_WaterBlue, dot);"
    "waterColor = mix(sunColor, waterColor, dot);"
    "waterColor = mix(waterColor, g_WaterBlue, dot);"

    "return waterColor;"
"}"

"void main()"
"{"
    "vec4 position = vec4(pos.x, height, pos.y, 1.0);"

    "vec3 V = camera_pos.xyz + camera_forward.xyz - position.xyz;"
    "V = normalize(V);"

    "vec3 N = vec3(normal.x, 1, normal.y);"
    "N = normalize(N);"

    "waterColor_.xyz = CalculateWaterColor(V, N);"
    "waterColor_.w = 1.0;"//ax * 18 / length(camera_pos.xyz - position.xyz);"

    "gl_Position = mat4_ModelViewProjection * position;"
"}"
// LEFT to RIGHT, BOTTOM to TOP
for (index1 = 0; index1 < (Resolution - 1); ++index1)
{
    for (index2 = 0; index2 < (Resolution - 1); ++index2)
    {
        // CLOCKWISE
        *++p_data = index2      + index1        * Resolution;
        *++p_data = index2      + (index1 + 1)  * Resolution;
        *++p_data = index2 + 1  + (index1 + 1)  * Resolution;

        *++p_data = index2      + index1        * Resolution;
        *++p_data = index2 + 1  + (index1 + 1)  * Resolution;
        *++p_data = index2 + 1  + index1        * Resolution;

        // COUNTER-CLOCKWISE
        //*++p_data = index2 +     (index1 + 1) * Resolution;
        //*++p_data = index2 +     index1       * Resolution;
        //*++p_data = index2 + 1 + index1       * Resolution;

        //*++p_data = index2 + 1 + index1       * Resolution;
        //*++p_data = index2 + 1 + (index1 + 1) * Resolution;
        //*++p_data = index2 +     (index1 + 1) * Resolution;
        // ..
    }
}
//从左到右,从下到上
对于(index1=0;index1<(分辨率-1);+index1)
{
对于(index2=0;index2<(分辨率-1);+index2)
{
//顺时针
*++p_data=index2+index1*分辨率;
*++p_数据=index2+(index1+1)*分辨率;
*++p_数据=index2+1+(index1+1)*分辨率;
*++p_data=index2+index1*分辨率;
*++p_数据=index2+1+(index1+1)*分辨率;
*++p_data=index2+1+index1*分辨率;
//逆时针
//*++p_数据=index2+(index1+1)*分辨率;
//*++p_data=index2+index1*分辨率;
//*++p_data=index2+1+index1*分辨率;
//*++p_data=index2+1+index1*分辨率;
//*++p_数据=index2+1+(index1+1)*分辨率;
//*++p_数据=index2+(index1+1)*分辨率;
// ..
}
}
我尝试过的事情:

  • 启用/禁用深度测试
  • 将更大的值设置为深度缓冲区大小(尝试16、32、8——所有值的结果相同)
  • 玩弄扑杀
  • 玩阿尔法混合
  • 深度排序--没用,反正不做混合
  • 将大世界大小设置为网格(10000.0f),以避免世界单位(1.0f)百万分之一的舍入误差
  • 使用不同的索引缓冲区,以不同的顺序渲染顶点,从上到下,从左到右,以及它们各自的反转——对减弱或加重伪影渲染没有任何影响
    • 问题不在发布的代码中——这完全正确

      问题是:

          // enable blending
          glEnable(GL_BLEND);
          // ..
      
          glBlendFunc
          (
              GL_SRC_ALPHA,
              GL_ONE_MINUS_SRC_ALPHA
          );
      
      GL_ONE_减去SRC_ALPHA应该是GL_ONE,以避免使用此类工件进行绘制

      下面是一些更好地理解glBlendFunc工作原理的示例

    • 另外,非常重要的是,在进行混合时,您应该记住禁用glDisable(GL\u DEPTH\u TEST)。

      问题不在发布的代码中——这都是正确的

      问题是:

          // enable blending
          glEnable(GL_BLEND);
          // ..
      
          glBlendFunc
          (
              GL_SRC_ALPHA,
              GL_ONE_MINUS_SRC_ALPHA
          );
      
      GL_ONE_减去SRC_ALPHA应该是GL_ONE,以避免使用此类工件进行绘制

      下面是一些更好地理解glBlendFunc工作原理的示例


    • 另外,非常重要的是,在进行混合时,您应该记住glDisable(GL\u DEPTH\u TEST)

      您是否启用了MSAA?启用后会发生什么情况?将不得不就此向您反馈,因为我没有投入实现裸机win OpenGL上下文之外的任何东西的努力—可以做到,但这需要一些时间——对reside的效果表示怀疑……你打算怎么做?检查我是否从代码中理解:2d位置和高度是独立的属性,但只是属性(高度不是从纹理中采样的,因此采样错误已排除);更改生成索引的方式没有任何效果(因此,索引生成可能不是罪魁祸首)?如果将CPU上的水模拟替换为输出平面或简单的正弦曲线,会发生什么情况?你在多大程度上排除了实际的水模拟