0

这让我发疯!我以前对 OpenGL 做的不多,所以任何指针都表示赞赏。

谁能告诉我为什么我的一些对象出现在我的阴影贴图中而其他对象没有出现的任何原因?

我有 2 个正在渲染的对象;南半球和框架。这两者都被渲染到场景和阴影贴图纹理。场景完美地显示了所有对象,但只有南半球出现在阴影贴图中。

我的阴影贴图纹理是这样绑定的:

- (void)setupShadowmapBuffers {
  glGenTextures(1, &_shadowTexture);
  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, _shadowTexture);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

  glGenFramebuffers(1, &_shadowFBO);
  glGenRenderbuffers(1, &_shadowRenderBuffer);
  glBindRenderbuffer(GL_RENDERBUFFER, _shadowRenderBuffer);
  glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 1024, 1024);
  glBindFramebuffer(GL_FRAMEBUFFER, _shadowFBO);
  glBindTexture(GL_TEXTURE_2D, _shadowTexture);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                            GL_DEPTH_ATTACHMENT,
                          GL_RENDERBUFFER,
                          _shadowRenderBuffer);
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _shadowTexture, 0);
  if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
  {
    printf("Error: FrameBufferObject is not complete!\n");
  }
}

在我的渲染函数中,我渲染到阴影贴图纹理:

// Render the shadow map
glUseProgram(_shadowProgramHandle);
glUniformMatrix4fv(_shadowProjectionUniform, 1, 0, LSprojection.glMatrix);
glUniformMatrix4fv(_shadowLightMPVUniform, 1, 0, lightsourcemat.glMatrix);

glBindFramebuffer(GL_FRAMEBUFFER, _shadowFBO);
glBindRenderbuffer(GL_RENDERBUFFER, _shadowRenderBuffer);

glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, 1024, 1024);


glUniformMatrix4fv(_shadowModelViewUniform, 1, 0, southernHemispheremat.glMatrix);
[self drawSouthernHemisphere];

glUniformMatrix4fv(_shadowModelViewUniform, 1, 0, framemat.glMatrix);
[self drawFrame];

然后我渲染到场景:

// Reset buffers and finally render the scene
glUseProgram(_mainProgramHandle);

glBindFramebuffer(GL_FRAMEBUFFER, msaaFramebuffer);
glBindRenderbuffer(GL_RENDERBUFFER, msaaRenderBuffer);

glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, vFrame.size.width, vFrame.size.height);

glUniformMatrix4fv(_modelViewUniform, 1, 0, shadowmat.glMatrix);
[self drawShadow];

glUniformMatrix4fv(_modelViewUniform, 1, 0, southernHemispheremat.glMatrix);
[self drawSouthernHemisphere];

glUniformMatrix4fv(_modelViewUniform, 1, 0, framemat.glMatrix);
[self drawFrame];

我的绘图功能如下所示:

- (void)drawSouthernHemisphere {

// Southern Hemisphere
glEnable(GL_CULL_FACE);
glBindTexture(GL_TEXTURE_2D, _globeTexture);

glBindVertexArrayOES(_southernHemisphere);

// Draw outside (textured)
glUniform1f(_useTextureSlot, 1);
glCullFace(GL_BACK);
glDrawElements(GL_TRIANGLES, sizeof(Southern)/sizeof(Southern[0]), GL_UNSIGNED_SHORT, 0);

// Draw inside (coloured)
glCullFace(GL_FRONT);
glUniform1f(_useTextureSlot, 0);
glUniform4f(_runTimeColorSlot, 0, 0, 0, 0);

glDrawElements(GL_TRIANGLES, sizeof(Southern)/sizeof(Southern[0]), GL_UNSIGNED_SHORT, 0);

glBindVertexArrayOES(0);

}

- (void)drawFrame {
// Frame

glEnable(GL_CULL_FACE);
glBindTexture(GL_TEXTURE_2D, _frameTexture);

glBindVertexArrayOES(_frame);

// Draw outside (textured)
glUniform1f(_useTextureSlot, 1);

glCullFace(GL_BACK);
glDrawElements(GL_LINES, sizeof(Frame)/sizeof(Frame[0]), GL_UNSIGNED_SHORT, 0);

glBindVertexArrayOES(0);
}

谢谢。

编辑:

我已将问题归结为我的顶点数组 - 特别是法线。

我将帧数组中的值与我的 southHemisphere 数组中的值交换,然后宾果游戏 - 对象同时出现在场景和阴影贴图中!

在对值进行一些调整之后,似乎只有法线的方向与每个向量本身的方向相同时它才会起作用。

让我感到困惑的是,在我的阴影贴图着色器中,我什至不访问法线,所以为什么它们对渲染有任何影响?

这是我的阴影贴图的顶点着色器:

attribute vec4 Position;
uniform mat4 Projection;
uniform mat4 Modelview;
uniform mat4 Light;
varying vec4 TexCoord;

void main()
{
  TexCoord =  Projection * Light * Modelview * Position;
  gl_Position =  Projection * Light * Modelview  * Position;
}

和片段:

precision mediump float;
varying vec4 TexCoord;

void main()
{
  /* Generate shadow map - write fragment depth. */
  float value = 10.0 - TexCoord.z;
  float v = floor(value);
  float f = value - v;
  float vn = v * 0.1;
  gl_FragColor = vec4(vn, f, 0.0, 1.0);
}

编辑2:

这是我为 VAO 设置的功能

// Southern Hemisphere

glGenVertexArraysOES(1, &_southernHemisphere);
glBindVertexArrayOES(_southernHemisphere);

GLuint vb2;
glGenBuffers(1, &vb2);
glBindBuffer(GL_ARRAY_BUFFER, vb2);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);

glEnableVertexAttribArray(_positionSlot);
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Position));
glEnableVertexAttribArray(_colorSlot);
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Color));
glEnableVertexAttribArray(_normalSlot);
glVertexAttribPointer(_normalSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal));
glEnableVertexAttribArray(_texCoordSlot);
glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, TexCoord));

GLuint southernBuffer;
glGenBuffers(1, &southernBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,southernBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Southern) * sizeof(Southern[0]), Southern, GL_STATIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArrayOES(0);

// Frame

glGenVertexArraysOES(1, &_frame);
glBindVertexArrayOES(_frame);

GLuint vb4;
glGenBuffers(1, &vb4);
glBindBuffer(GL_ARRAY_BUFFER, vb4);
glBufferData(GL_ARRAY_BUFFER, sizeof(Frame_Vertices), Frame_Vertices, GL_STATIC_DRAW);

glEnableVertexAttribArray(_positionSlot);
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Position));
glEnableVertexAttribArray(_colorSlot);
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Color));
glEnableVertexAttribArray(_normalSlot);
glVertexAttribPointer(_normalSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal));
glEnableVertexAttribArray(_texCoordSlot);
glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, TexCoord));

GLuint legsBuffer;
glGenBuffers(1, &frameBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,frameBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Frame) * sizeof(Frame[0]), Frame, GL_STATIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArrayOES(0);

我的数组都遵循相同的形式:

const Vertex Vertices[] = {
{{0.0000,-1.5000,0.0000},{0.3843137254902,0.14117647058824,0.082352941176471,1},{0.0000,-1.0000,0.0000},{0.0000,1.0000}},
{{0.0000,-1.4872,0.1958},{0.3843137254902,0.14117647058824,0.082352941176471,1},{0.0000,-0.9914,0.1305},{0.0000,0.9583}},
....
}

从设置代码中可以看出,它由位置、颜色、法线、纹理坐标组成。

链接着色器后,我完成了这些设置:

- (void)useMainProgram:(GLfloat[])lightsource {

const GLfloat l_ambient = 0.7;

glUseProgram(_mainProgramHandle);

_positionSlot = glGetAttribLocation(_mainProgramHandle, "Position");
_colorSlot = glGetAttribLocation(_mainProgramHandle, "Color");
_normalSlot = glGetAttribLocation(_mainProgramHandle, "Normal");
_lightingSlot = glGetUniformLocation(_mainProgramHandle, "l1");
_ambientLightingSlot = glGetUniformLocation(_mainProgramHandle, "l_ambient");
_texCoordSlot = glGetAttribLocation(_mainProgramHandle, "TexCoordIn");
_useTextureSlot = glGetUniformLocation(_mainProgramHandle, "use_texture");
_runTimeColorSlot = glGetUniformLocation(_mainProgramHandle, "RunTimeColor");

glEnableVertexAttribArray(_positionSlot);
glEnableVertexAttribArray(_colorSlot);
glEnableVertexAttribArray(_normalSlot);
glEnableVertexAttribArray(_texCoordSlot);

_projectionUniform = glGetUniformLocation(_mainProgramHandle, "Projection");
_modelViewUniform = glGetUniformLocation(_mainProgramHandle, "Modelview");

for (int i=0;i<_num_bottles; i++){
    _bottlesUniform[i] = glGetUniformLocation(_mainProgramHandle, "Modelview");
}
_textureUniform = glGetUniformLocation(_mainProgramHandle, "Texture");

// Lighting doesn't change, so we set it here.
glUniform3fv(_lightingSlot, 1, lightsource);
glUniform1fv(_ambientLightingSlot, 1, &l_ambient);

}

- (void)useShadowProgram:(GLfloat[])lightsource {

glUseProgram(_shadowProgramHandle);

_shadowPositionSlot = glGetAttribLocation(_shadowProgramHandle, "Position");
_shadowLightMPVUniform = glGetUniformLocation(_shadowProgramHandle, "Light");
_shadowProjectionUniform = glGetUniformLocation(_shadowProgramHandle, "Projection");
_shadowModelViewUniform = glGetUniformLocation(_shadowProgramHandle, "Modelview");

glEnableVertexAttribArray(_shadowPositionSlot);

}
4

0 回答 0