gpt4 book ai didi

android - libgdx:SpriteBatch,Samsung Android 设备上的 fragment 着色器工作不正确

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:57:35 24 4
gpt4 key购买 nike

我正在使用 libgdx 及其 SpriteBatch 类为 Andoid 开发 2D 动态壁纸。这是一 block watch ,所以我需要的只是从 libgdx 绘制多个纹理,将它们旋转到特定角度。

我已经使用 SpriteBatch 类解决了这个问题,一切正常。

但现在我需要在我的场景中添加放大镜效果。任务是以特定比例放大特定区域以模拟真实镜头。

我通过渲染到 FrameBuffer、从 FrameBuffer 获取纹理区域并最终使用 SpriteBatch 使用自定义着色器绘制该区域来解决此问题。

问题:在三星设备上(我在 Galaxy Note N7000 和 Galaxy Tab 10.1 上试过)在放大区域的中心有一个小矩形,大约 16x16 像素,放大率略有增加。抱歉,我现在无法发布屏幕截图,因为我没有三星设备。在其他设备上一切正常,在 HTC Vivid、Acer A500、Google Nexus One 上试过。

我认为,如果三星设备上的 Mali GPU 存在问题,但不知道如何解决。

我已将此问题中的 fragment 着色器代码改编为 SpriteBatch Add Fisheye effect to images at runtime using OpenGL ES这是它:

#ifdef GL_ES
#define LOWP lowp
precision mediump float;
#else
#define LOWP
#endif

varying LOWP vec4 v_color;
varying vec2 v_texCoords;
uniform sampler2D u_texture;

void main() {
vec2 m = vec2(0.622 , 0.4985); // lens center point, note that in live wallpaper center of texture is (0.5,0.5)
float lensSize = 0.045; //diameter of lens
float lensCut = 0.0342; //length of cut lines

vec2 d = v_texCoords - m;
float r = sqrt(dot(d, d)); // distance of pixel from mouse
float cuttop = m.y + lensCut;
float cutbottom = m.y - lensCut;

vec2 uv;
if (r >= lensSize) {
uv = v_texCoords;
} else if ( v_texCoords.y >= cuttop) {
uv = v_texCoords;
} else if (v_texCoords.y <= cutbottom) {
uv = v_texCoords;
} else {
uv = m + normalize(d) * asin(r) / (3.14159 * 0.37);
}

gl_FragColor = texture2D(u_texture, uv);
}

顶点着色器默认来自 SpriteBatch 源:

attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;

uniform mat4 u_projTrans;

varying vec4 v_color;
varying vec2 v_texCoords;

void main() {
v_color = a_color;
v_texCoords = a_texCoord0;
gl_Position = u_projTrans * a_position;
}

这是我的render() 方法:

    GL20 gl = Gdx.graphics.getGL20();
gl.glEnable(GL20.GL_TEXTURE_2D);
gl.glActiveTexture(GL20.GL_TEXTURE0);

gl.glClearColor(WallpaperService.bg_red, WallpaperService.bg_green, WallpaperService.bg_blue, 1f);
gl.glClear(GL20.GL_COLOR_BUFFER_BIT);


// Creating framebuffer, if it has gone
if (mFrameBuffer == null) {
mFrameBuffer = new FrameBuffer(Format.RGBA4444, BG_WIDTH, BG_HEIGHT, true);

mFrameBufferRegion = new TextureRegion(mFrameBuffer.getColorBufferTexture());
mFrameBufferRegion.flip(false, true);

}

//Camera setting according to background texture
camera = new OrthographicCamera(BG_WIDTH, BG_HEIGHT);
camera.position.set(BG_WIDTH / 2, BG_WIDTH / 2, 0);
camera.update();
batch.setProjectionMatrix(camera.combined);

//Rendering scene to framebuffer
mFrameBuffer.begin();
batch.begin();
//main Drawing goes here
batch.end();

//Drawing frame to screen with applying shaders for needed effects
if (mFrameBuffer != null) {
mFrameBuffer.end();

camera = new OrthographicCamera(width, height);
camera.position.set(width / 2, height / 2, 0);
camera.update();
batch.setProjectionMatrix(camera.combined);

batch.begin();
batch.setShader(null);

batch.setShader(shader);

batch.draw(mFrameBufferRegion, width / 2 - (BG_WIDTH / 2) + (MARGIN_BG_LEFT * ratio), height / 2
- (BG_HEIGHT / 2) + (MARGIN_BG_TOP * ratio), (float) BG_WIDTH / 2, (float) BG_HEIGHT / 2,
(float) BG_WIDTH, (float) BG_HEIGHT, (float) ratio, (float) ratio, 0f);

batch.setShader(null);
batch.end();
}

最佳答案

我已经设法解决了这个问题。问题出在 Mali gpu 中。Mali 不支持 fragment 着色器中的高精度浮点计算。当中心到点的距离接近于零时 - r 变量变为零。

所以我在计算中添加了常数系数,这就成功了。

这是工作 fragment 着色器:

precision mediump float;

varying lowp vec4 v_color;
varying vec2 v_texCoords;


uniform sampler2D u_texture;

const float PI = 3.14159;
const float koef = 10.0;
void main() {
vec2 uv;
vec2 m = vec2(0.622 , 0.4985); // lens center point, note that in live wallpaper center of texture is (0.5,0.5)
float lensSize = 0.045; //radius of lens
float lensCut = 0.0342; //height of cut

float cuttop = m.y + lensCut;
float cutbottom = m.y - lensCut;
float cutleft = m.x-lensSize;
float cutright = m.x+lensSize;

//don't transform pixels, that aren't in lens area
if ( v_texCoords.y >= cuttop) {
uv = v_texCoords;
} else if (v_texCoords.y <= cutbottom) {
uv = v_texCoords;
} else if (v_texCoords.x <= cutleft) {
uv = v_texCoords;
} else if (v_texCoords.x >= cutright) {
uv = v_texCoords;
} else {
vec2 p = v_texCoords*koef; //current point
vec2 d = p - m*koef; //vector differnce between current point and center point
float r = distance(m*koef,p); // distance of pixel from center

if (r/koef >= lensSize) {
uv = v_texCoords;
} else {
uv =m + normalize(d) * asin(r) / (PI*0.37*koef);
}
}

gl_FragColor = texture2D(u_texture, uv);
}

关于android - libgdx:SpriteBatch,Samsung Android 设备上的 fragment 着色器工作不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14192330/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com