LibGDX - 着色器适用于桌面但不适用于 Android

2024-05-07

我编写了一个简单的程序,可以在 3D 环境中渲染球体,并根据球体周围的四个光源为其着色。 当我在桌面上运行该程序时,它工作得很好,但在 Android 设备上,球体只是纯色的。

下面是一些图片来说明我正在谈论的内容:

enter image description here -> Desktop

enter image description here -> Android

这是着色器代码:

球体.vert

#ifdef GL_ES
    precision mediump float;
#endif

uniform mat4 u_projectionMatrix;
uniform mat3 u_normalMatrix;
uniform mat4 u_modelViewMatrix;

const int MAX_LIGHTS = 8;
uniform int u_lights_active;
uniform vec3 u_ambient;
uniform vec3 u_position[ MAX_LIGHTS ];
uniform vec3 u_diffuse[ MAX_LIGHTS ];
uniform vec3 u_att_coeffs[ MAX_LIGHTS ];

// since builtins aren't used, we use attributes as substitute
attribute vec2 a_texCoord0;
attribute vec4 a_position;
attribute vec3 a_normal;

// outputs to fragment shader
varying vec2 v_tex_coord;
varying vec4 v_color;

void main()
{
    vec3 tempColor  = u_ambient;
    vec3 ecPosition = vec3( u_modelViewMatrix * a_position );
    vec3 viewVec    = normalize( -ecPosition );
    vec3 tnorm      = normalize( u_normalMatrix * a_normal );

    for ( int i = 0; i < u_lights_active; ++i )
    {
        float dist   = length( ecPosition - u_position[i] ); // distance from light to fragment
        float att    = 1.0 / ( u_att_coeffs[i].x + u_att_coeffs[i].y*dist + u_att_coeffs[i].z*dist*dist );

        vec3 lightVec  = normalize( u_position[i] - ecPosition );
        float diffuse  = max( dot( lightVec, tnorm ), 0.0 );
        tempColor      += att * u_diffuse[i] * diffuse;
    }

    tempColor    = clamp( tempColor, 0.0, 1.0 );
    v_color      = vec4( tempColor, 0.0 );

    gl_Position  = u_projectionMatrix * vec4( ecPosition, 1.0 );
    v_tex_coord  = a_texCoord0.xy;
}

球体碎片

#ifdef GL_ES
    precision mediump float;
#endif

uniform sampler2D u_texture;

varying vec2 v_tex_coord;
varying vec4 v_color;

void main()
{
    vec4 texColor = texture2D( u_texture, v_tex_coord );
    gl_FragColor  = texColor * v_color;
}

我真的希望你们中的一个人能够向我解释我做错了什么。

版本号:

LibGDX:0.9.8

ADT:内部版本 v22.0.1-685705

Android 设备:索尼 Xperia S,Android 4.1.2

项目构建目标:Android 4.3,API 18

清单包含

<uses-feature android:glEsVersion="0x00020000" android:required="true" />

着色器是通过以下方式创建的:

shaderProgram = new ShaderProgram( Gdx.files.internal( "shaders/sphere.vert" ), Gdx.files.internal( "shaders/sphere.frag" ) );
if ( !shaderProgram.isCompiled() )
{
    Gdx.app.error( TAG, shaderProgram.getLog() );
}

球体是一个 StillModel:

创建:

final ModelLoaderHints hint = new ModelLoaderHints( true );
model = ModelLoaderRegistry.loadStillModel( Gdx.files.internal( "data/sphere.obj" ), hint );
texture = new Texture( Gdx.files.internal( "data/sphere_tex.png" ), Format.RGB888, false );
material = new Material( "mat", new TextureAttribute( texture, 0, "u_texture" ) );

渲染:

shaderProgram.begin();
texture.bind( 0 );

shaderProgram.setUniformMatrix( C.U_PROJECTION_MATRIX, cam.projection );
// light values
shaderProgram.setUniformi( C.U_LIGHTS_ACTIVE, lightsActive );
shaderProgram.setUniform3fv( C.U_LIGHT_AMBIENT, lightAmbient, 0, 3 );
shaderProgram.setUniform3fv( C.U_LIGHT_POSITION, lightPosition, 0, 3 * lightsActive );
shaderProgram.setUniform3fv( C.U_LIGHT_DIFFUSE, lightDiffuse, 0, 3 * lightsActive );
shaderProgram.setUniform3fv( C.U_LIGHT_ATT_COEFFS, lightAttCoeffs, 0, 3 * lightsActive );

modelMatrix.setToTranslation( positionWrap );
modelMatrix.rotate( rotationAxis, rotation );
modelMatrix.scale( scaleX, scaleY, scaleZ );

modelViewMatrix.set( cam.view ).mul( modelMatrix );
normalMatrix.set( modelViewMatrix ).inv().tra();

shaderProgram.setUniformMatrix( C.U_NORMAL_MATRIX, normalMatrix3x3.set( normalMatrix ) );
shaderProgram.setUniformMatrix( C.U_MODEL_VIEW_MATRIX, modelViewMatrix );

stillModel.render( shaderProgram );

shaderProgram.end();

希望这是所需的全部信息。

提前致谢!


将我的猜测评论转换为答案:

GLSL 规范仅要求支持非常简单的循环(非常“恒定”的循环边界等)。看我的回答着色器代码中的 for 循环使用硬编码数字,但不使用统一变量 https://stackoverflow.com/questions/18925615/for-loop-in-shader-code-working-with-hardcoded-number-but-not-with-uniform-varia/18926519#18926519

在您的情况下,您可以通过始终循环 MAX_LIGHTS 并将非活动灯光的影响乘以 0 来解决此问题(或确保非活动灯光设置全部为零或全部 1.0 或任何使它们无效的设置)。

请注意,由于像素着色器的运行方式(在 SIMD 并行执行中),在循环内添加分支来“跳过”不必要的工作可能会更慢。尝试使所有像素始终运行相同的指令序列。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LibGDX - 着色器适用于桌面但不适用于 Android 的相关文章

  • Android 中多个蓝牙连接的自定义 UUID

    我有一个 Android 设备作为服务器连接到多个蓝牙 Android 客户端 我了解 UUID 的概念以及它的独特之处 我的问题是 我可以为连接到我的服务器的所有客户端使用相同的 UUID 吗 如果没有 我如何以编程方式为我的客户端生成
  • 如何自定义菜单项的背景颜色?

    我正在尝试定制Toolbar的弹出菜单 现在我无法设置菜单项的背景颜色 我的 styles xml 如下所示
  • AdapterContextMenuInfo 始终为 null

    我尝试通过 android 开发文档中的书来做到这一点 this didn t create a menu i don t know why registerForContextMenu getListView setListAdapter
  • 如何正确释放Android MediaPlayer

    我正在尝试向我的 Android 应用程序添加一个按钮 当点击该按钮时它会播放 MP3 我已经让它工作了 但没有办法释放 mediaPlayer 对象 因此即使在我离开活动后它仍然会继续播放 如果我在react 方法之外初始化MediaPl
  • 如何重定向到 instagram://user?username={username}

    我的 html 页面上有这个链接 可以在特定用户上打开 Instagram 应用程序 a href Link to Instagram Profile a 我一直在寻找自动运行 url instagram user username USE
  • 如何更改终端的默认目录?

    我想更改 Android Studio v2 2 2 终端的默认目录 当我打开终端时 它基于项目的目录 C 项目路径 我经常需要使用adb shell 所以我必须导航到 SDK 路径 平台工具 才能使用 adb 命令 是否可以更改终端的默认
  • 以编程方式将文本颜色设置为主要 Android 文本视图

    如何设置我的文本颜色TextView to android textColorPrimary以编程方式 我已经尝试了下面的代码 但它将 textColorPrimary 和 textColorPrimary Inverse 的文本颜色始终设
  • Android 深度链接至 Instagram 应用

    Instagram 已经发布了 iOS 深层链接的 url 方案 但尚未为 Android 创建文档 有没有办法深入链接到 Android 上的 Instagram 应用程序 以转到 Instagram 应用程序中的特定位置 例如 Inst
  • Android Eclipse 上的 Web 服务

    我是 android eclipse java 的新手 事实上这个论坛也是如此 有人遇到过这种情况吗 从用户那里获取输入并通过使用 android eclipse 中的 Web 服务来显示适当的结果 有可用的示例吗 非常感谢 我正在发布教程
  • 当 OnFocusChangeListener 应用于包装的 EditText 时,TextInputLayout 没有动画

    不能比标题说得更清楚了 我有一个由文本输入布局包裹的 EditText 我试图在 EditText 失去焦点时触发一个事件 但是 一旦应用了事件侦听器 TextInputLayout 就不再对文本进行动画处理 它只是位于 editText
  • Android 2.3 模拟器在更新位置时崩溃

    我正在使用 Eclipse 编写和调试 Android 应用程序 我需要做的事情之一是更新设备的位置 因此我尝试使用模拟器控制窗口中的位置控制面板 在 手动 选项卡上 我选择 十进制 输入有效的纬度和经度 然后单击 发送 不幸的是 接下来发
  • 我应该释放或重置 MediaPlayer 吗?

    我有自己的自定义适配器类 称为 WordAdapter 并且我正在使用媒体播放器 名为pronounce WordAdapter 类中的全局变量 我有不同的活动 其中每个列表项都有线性布局 名为linearLayout 我正在设置onCli
  • 如何在 Android 中从 WorkManager 取消工作?

    我已经保存了 WorkManagerUUID转换成String在领域数据库中 这是代码 Constraints constraints new Constraints Builder setRequiredNetworkType Netwo
  • 您使用什么物理 Android 设备进行测试?

    有什么好的推荐用于测试目的的物理 Android 设备吗 我正在苹果阵营寻找像 iPod touch 这样的设备 可以帮助 iOS 开发人员测试他们的东西 我知道有 Nexus One 但那东西相当昂贵 而且我并不真正关心手机的东西 而是可
  • Android:无法使用 DbHelper 和 Contract 类将数据插入 SQLite

    public class Main2Activity extends AppCompatActivity private EditText editText1 editText2 editText3 editText4 private Bu
  • 在命令行上卸载 Android SDK 的选定部分

    这与 卸载旧的 Android SDK 版本 https stackoverflow com questions 15182377 uninstall old android sdk versions 除非我想在无头 Linux CI 服务
  • 没有支持 FEATURE_CAMERA_EXTERNAL 的 Android 设备

    根据this doc https source android com devices camera external usb cameras一些 Android 设备允许使用 Camera2 API 访问外部 USB 摄像头 我检查了大约
  • CamcorderProfile.videoCodec 返回错误值

    根据docs https developer android com reference android media CamcorderProfile html 您可以使用CamcorderProfile获取设备默认视频编解码格式 然后将其
  • 如何使用 AccessibilityService 在 Android 中模拟按键

    我正在编写一个辅助服务 我一直在尝试在应用程序上进行一些自动搜索 我使用accessibilityservice action paste来填充EditText 然后我需要模拟软键盘上的按键 但我不知道如何做 你们能帮我一下吗 你可以尝试A
  • Android 后台倒计时器

    我有一个 Android 应用程序 它管理一个倒计时器 类 CountDownTimer 它显示在应用程序屏幕中 以显示到达 00 00 还剩多少时间 我现在的问题是 当我按主页按钮或启动另一个应用程序时 应用程序 计时器不会在后台运行 所

随机推荐