- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有 2 个着色器程序 - 一个用于渲染带有纹理的 Sprite ,第二个用于渲染多边形。我像这样启用了混合和 Z 缓冲区:
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
GLES20.glEnable( GLES20.GL_DEPTH_TEST );
GLES20.glDepthFunc( GLES20.GL_LEQUAL );
GLES20.glDepthMask( true );
GLES20.glDepthRangef(0, maxZDepth); //maxZDepth = 100f;
我的渲染包含 2 个渲染调用 (glDrawElements):一个用于 Sprite ,紧接着用于具有足够着色器程序的多边形...将对象数据(顶点等...)发送到着色器的顺序从对象的最低 Z 值到最高值,我还必须将这样的指令添加到我的 Sprite 着色器中:
if(gl_FragColor.a == 0.0)
discard;
现在,混合和 Z 缓冲区可以正常工作,但一次只能在一个着色器的范围内工作。第一个着色器绘制的对象的混合似乎与第二个着色器无关......这是一个例子:
这里的 Sprite 比它下面的棕色多边形具有更高的 Z 值,这就是为什么它被绘制在多边形上但混合失败并且您可以看到 Sprite 周围显示灰色背景(由 glClearColor 创建)......
有人知道解决这个问题的好方法吗?我考虑过将 2 个着色器程序合并为一个,然后只有 1 个渲染调用,我希望这能解决它,但我更愿意为 Sprite 和多边形保留 2 个单独的着色器程序...
最佳答案
根据简短的评论讨论,问题是:
深度缓冲区每个像素只保存一个深度。部分透明的像素结合了来自不同深度的两种颜色。但它只能分配一个深度。这最终成为更近像素的深度。
在一个理想的世界中,如果你在远处画一些不透明的东西,然后画一些近处透明的东西,然后画一些介于两者之间的不透明的东西,那么最终的输出将是中间的东西和附近的东西的混合。实际发生的是透明的东西将其深度设置为深度缓冲区。当你开始绘制中间的东西时,不会输出任何像素,因为它比深度缓冲区中最近的东西更远。所以你最终会把远处的东西和近处的东西混合在一起,就好像中间的东西从来没有画过一样。
有很多解决方案,具体取决于您想要达到的精确程度、多少几何体至少部分透明以及您有多少时间。
首先,如果您有任何绝对完全不透明的几何图形,那么您可以先绘制所有这些图形,以最有效的顺序为准。
将透明几何体排序并从后往前渲染是最明显的解决方案。这很好,除了不是所有的几何图形都可以通过返回到前面来正确绘制(参见例如相互重叠),并且在最天真的实现中,您的 GL 状态更改最终可能会非常昂贵,而不是使用一个着色器绘制 50,000 个三角形,然后切换并绘制 50,000 秒,你绘制一个三角形,切换,绘制,切换,绘制等,用于 99,999 个切换。
如果附加透明度是可以接受的,那么您可以按任何旧顺序填充透明内容,而根本不写入深度缓冲区。
Nvidia 提出的一些建议是利用多重采样,但可能会提高一点。想象一下更像是为每个像素组合 8x8 或 16x16 像素样本。在那种情况下,您绘制透明度不是通过从帧缓冲区读取、混合和再次写出,而是通过编写例如如果透明度为 50%,每个单元格中只有一半的样本。你随机选择一半。随着单元格大小的增加,这会为您提供与顺序无关的透明度,从而提高质量。
假设您的多边形始终是不透明的,而您的 sprite 都可能部分透明,那么,正如我认为您现在正在做的那样,首先绘制多边形,然后按从后到前的顺序绘制 sprite。
关于android - 混合和 Z 缓冲区在 2 个独立的着色器程序之间共享?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27636721/
我最近在/ drawable中添加了一些.gifs,以便可以将它们与按钮一起使用。这个工作正常(没有错误)。现在,当我重建/运行我的应用程序时,出现以下错误: Error: Gradle: Execu
Android 中有返回内部存储数据路径的方法吗? 我有 2 部 Android 智能手机(Samsung s2 和 s7 edge),我在其中安装了一个应用程序。我想使用位于这条路径中的 sqlit
这个问题在这里已经有了答案: What's the difference between "?android:" and "@android:" in an android layout xml f
我只想知道 android 开发手机、android 普通手机和 android root 手机之间的实际区别。 我们不能从实体店或除 android marketplace 以外的其他地方购买开发手
自Gradle更新以来,我正在努力使这个项目达到标准。这是一个团队项目,它使用的是android-apt插件。我已经进行了必要的语法更改(编译->实现和apt->注释处理器),但是编译器仍在告诉我存在
我是android和kotlin的新手,所以请原谅要解决的一个非常简单的问题! 我已经使用导航体系结构组件创建了一个基本应用程序,使用了底部的导航栏和三个导航选项。每个导航选项都指向一个专用片段,该片
我目前正在使用 Facebook official SDK for Android . 我现在正在使用高级示例应用程序,但我不知道如何让它获取应用程序墙/流/状态而不是登录的用户。 这可能吗?在那种情
我在下载文件时遇到问题, 我可以在模拟器中下载文件,但无法在手机上使用。我已经定义了上网和写入 SD 卡的权限。 我在服务器上有一个 doc 文件,如果用户单击下载。它下载文件。这在模拟器中工作正常但
这个问题在这里已经有了答案: What is the difference between gravity and layout_gravity in Android? (22 个答案) 关闭 9
任何人都可以告诉我什么是 android 缓存和应用程序缓存,因为当我们谈论缓存清理应用程序时,它的作用是,缓存清理概念是清理应用程序缓存还是像内存管理一样主存储、RAM、缓存是不同的并且据我所知,缓
假设应用程序 Foo 和 Eggs 在同一台 Android 设备上。任一应用程序都可以获取设备上所有应用程序的列表。一个应用程序是否有可能知道另一个应用程序是否已经运行以及运行了多长时间? 最佳答案
我有点困惑,我只看到了从 android 到 pc 或者从 android 到 pc 的例子。我需要制作一个从两部手机 (android) 连接的 android 应用程序进行视频聊天。我在想,我知道
用于使用 Android 以编程方式锁定屏幕。我从 Stackoverflow 之前关于此的问题中得到了一些好主意,并且我做得很好,但是当我运行该代码时,没有异常和错误。而且,屏幕没有锁定。请在这段代
文档说: android:layout_alignParentStart If true, makes the start edge of this view match the start edge
我不知道这两个属性和高度之间的区别。 以一个TextView为例,如果我将它的layout_width设置为wrap_content,并将它的width设置为50 dip,会发生什么情况? 最佳答案
这两个属性有什么关系?如果我有 android:noHistory="true",那么有 android:finishOnTaskLaunch="true" 有什么意义吗? 最佳答案 假设您的应用中有
我是新手,正在尝试理解以下 XML 代码: 查看 developer.android.com 上的文档,它说“starStyle”是 R.attr 中的常量, public static final
在下面的代码中,为什么当我设置时单选按钮的外观会发生变化 android:layout_width="fill_parent" 和 android:width="fill_parent" 我说的是
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
假设我有一个函数 fun myFunction(name:String, email:String){},当我调用这个函数时 myFunction('Ali', 'ali@test.com ') 如何
我是一名优秀的程序员,十分优秀!