我正在开发一款使用pixelart和相机的游戏,该游戏与像素艺术的大小不一致。为了让像素看起来像像素一样,我希望以更高的分辨率渲染整个游戏,然后将其下采样到实际的窗口分辨率(类似于GeDoSaTo mod在Dark Souls 2中所做的那样)并且只是在游戏中使用最接近的过滤纹理作为磁过滤器。如何在代码中进行下采样?
答案 0 :(得分:4)
我为您编写了一些伪代码,演示了如何使用尺寸设置FBO:
scale
*(res_x
x res_y
)。
2x超级采样将使用{strong> 2.0 的scale
。
我做了一些额外的工作来为你的颜色缓冲区提供纹理图像附件,这样你就可以使用纹理四边形(更好的性能)而不是blitting来绘制它。但是,由于这样做会涉及编写(简单)着色器,glBlitFramebuffer (...)
是最快的解决方案。
GLuint supersample_fbo,
supersample_tex,
supersample_rbo_depth;
glGenTextures (1, &supersample_tex);
glBindTexture (GL_TEXTURE_2D, supersample_tex);
glGenRenderbuffers (1, &supersample_rbo_depth);
glBindRenderbuffer (GL_RENDERBUFFER, supersample_rbo_depth);
// Allocate storage for your texture (scale X <res_x,res_y>)
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, res_x * scale, res_y * scale, 0, GL_RGBA, GL_FLOAT, NULL);
// Allocate storage for your depth buffer
glRenderBufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, res_x * scale, res_y * scale);
glGenFramebuffers (1, &supersample_fbo);
glBindFramebuffer (GL_FRAMEBUFFER, supersample_fbo);
// Attach your texture to the FBO: Color Attachment 0.
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, supersample_tex, 0);
// Attach the depth buffer to the FBO.
glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, supersample_rbo_depth);
glBindFramebuffer (GL_FRAMEBUFFER, supersample_fbo);
// You need to modify the viewport mapping to reflect the difference in size.
// Your projection matrix can stay the same since everything is uniformly scaled.
//
glViewport (0, 0, res_x * scale, res_y * scale);
// DRAW
glBindFramebuffer (GL_READ_FRAMEBUFFER, supersample_fbo); // READ: Supersampled
glBindFramebuffer (GL_DRAW_FRAMEBUFFER, 0); // WRITE: Default
// Downsample the supersampled FBO using LINEAR interpolation
glBlitFramebuffer (0,0,res_x * scale, res_y * scale,
0,0,res_x, res_y,
GL_COLOR_BUFFER_BIT,
GL_LINEAR);
// You probably want all subsequent drawing to go into the default framebuffer...
glBindFramebuffer (GL_FRAMEBUFFER, 0);
glViewport (0,0,res_x,res_y);
此代码中存在大量缺少错误检查,并且FBO 非常 容易出错,但它应该指向正确的方向。