Libgdx 着色器优化

Libgdx shader optimization

大家好libgdx!

由于着色器,我在游戏中有 40 fps。此着色器绘制背景,我想减少它处理的像素数。

在Create方法中我用Pixmap生成了一个纹理,其宽度和高度是实际屏幕尺寸的1/10。

pixmap = new Pixmap( (int)(Math.ceil(WIDTH/10f)), (int)(Math.ceil(HEIGHT/10f)), Pixmap.Format.RGBA8888 );
backGround = new Texture(pixmap);

然后我将 camera.zoom 设置为 0.1,这样纹理现在是全屏的。

camera.position.set( WIDTH/2f*0.1f, HEIGHT/2f*0.1f, 0);
camera.zoom = 0.1f;
camera.update();
batch.setProjectionMatrix(camera.combined);

然后Render方法中的着色器画了一个圆,但是那个着色器处理的是屏幕像素而不是纹理像素,我得到了和以前一样漂亮流畅的画面。

Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.draw(backGround,0,0);

片段着色器的代码:

vec3 yellow = vec3(0.93, 0.93, 0.32);

vec2 relativePosition = gl_FragCoord.xy / u_ScreenResolution;
relativePosition.x *= u_ScreenResolution.x / u_ScreenResolution.y;
float normDistance = pow(   (  pow(relativePosition.x - 0.3,2.0) + pow(relativePosition.y - 0.5,2.0)  ), 0.5   );
int distance = int(  round( normDistance + 0.4  )  );
gl_FragColor = vec4(vec3(0.0) + yellow*clamp(1.0-distance, 0.0, 1.0), 1.0);

不确定我是否表达正确,所以这是一张图片:

“着色器处理屏幕像素而不是纹理像素”<- this

你有一个由像素图(较低分辨率)支持的纹理,但你没有先绘制到那个较低分辨率的像素图。实际情况是,您在屏幕上看到的是着色器根据屏幕坐标计算的结果。也就是说,您的像素图分辨率无关紧要,因为您得到的是由着色器计算得出的,而不是从像素图派生的。

您想要的效果需要首先使用着色器绘制像素图支持的较低分辨率纹理,然后使用映射到纹理的默认着色器将低分辨率渲染纹理放大到屏幕.

使用帧缓冲区,它实际上是一个屏幕,除了在内存中而不是实际在屏幕上,以允许 openGL 将您的低分辨率像素图视为屏幕,首先绘制到屏幕上,然后使用生成的块状纹理作为纹理缩放到屏幕。这是

FrameBuffer fbo = new FrameBuffer(Format.RGB888, screenwidth, screenheight, false);
fbo.begin();
//render here
fbo.end();
//grab and use as texture scaled to the full  screen

这里有个例子

LibGDX FrameBuffer