如何在OpenGL和GLSL中使用较小的中间纹理?

我正在研究一个通过平滑粒子stream体动力学(SPH)模拟的项目,用非真实感的外观在游戏中使用。

在项目的实际阶段,所有关于这个渲染的事情都是通过C ++中的OpenGL和GLSL来完成的,其中许多着色器的步骤将中间纹理存储在FBO中,后来在最终的着色器中使用,将所有的东西放在一起。

一切工作正常,除了在更好的情况下,在25和30 FPS之间的帧速率,以1024×768像素渲染一切,包括中间纹理。 因此,由于这些中间步骤中的一些步骤涉及耗时的图像平滑algorithm,所以我想减less在中间步骤中产生的纹理的尺寸以使其更快,试图find降低/性能水平之间的最佳点(划分由2,4,8 …)和渲染最终的视觉。

我的问题恰恰在于:我如何在中间步骤中使用较小的纹理,并在最终的着色器步骤中使用它们来渲染更大尺寸的图像?

您所要做的就是创建具有所需宽度和高度的FBO纹理,并在渲染时相应地调整视口,如Fabien Sanglard的Shadow Map教程中所示 。

首先创建FBO,它的纹理与所需的尺寸。 这里fbo_intermediary_colortexture是FBO ID, window_widthwindow_height是名字所暗示的, intermediaryTextureSizeRatio是一个浮点数,它告诉FBO纹理尺寸应该减less多less:

 void createFrameBuffer() { // Color texture glGenTextures(1, &fbo_intermediary_colortexture); glBindTexture(GL_TEXTURE_2D, fbo_intermediary_colortexture); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, window_width * intermediaryTextureSizeRatio, window_height * intermediaryTextureSizeRatio, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); glBindTexture(GL_TEXTURE_2D, 0); // FBO glGenFramebuffersEXT(1, &fbo_intermediary); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_intermediary); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fbo_intermediary_colortexture, 0); // Test if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) cout << "Couldn't create frame buffer" << endl; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } 

之后,在渲染时,只需将视口尺寸调整到相应的位置(在这种情况下,首先在FBO上,然后在屏幕上):

 // Rendering on the FBO, first bind the created FBO and then adjust the viewport dimensions glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_intermediary); glViewport(0,0, window_width * intermediaryTextureSizeRatio, window_height * intermediaryTextureSizeRatio); /** rendering to off screen FBO goes here **/ // Then bind the screen frame buffer, adjust the viewport dimensions again, and render // Notice that the window dimensions are not being multiplied by the reducing factor here glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glViewport(0,0, window_width, window_height); /** rendering to screen goes here **/ 

您可以使用gDEBugger或类似的应用程序检查生成的纹理尺寸。

最后一件事情是:要注意的是,正如前面的教程所示,一些文物可能会从一个较大的屏幕上渲染出一个小纹理,这可能是一个糟糕的结果取决于场景。