草庐IT

swift - 在 Metal 中复制 OpenGL 混合

coder 2023-09-16 原文

我一直致力于将使用固定功能管道编写的开源游戏移植到 Metal。

我已经能够重做所有的投影变换并在哪里绘制它们应该使用正确的纹理和顶点信息绘制的东西,但是我在让片段着色器到匹配 OpenGL 混合,纹理看起来正确,但混合和亮度关闭。

这是我要匹配的内容:

这是它当前的渲染方式:

我可以看到控制 GL 混合的代码如下所示:

glShadeModel(GL_SMOOTH);

glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.0f);

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 2.0f);

它在禁用混合的情况下绘制主要纹理,然后在它们之间的小三角形(在我的版本中非常明显)上启用它。还为每个顶点提供了 RGB 颜色。

可能还有其他改变状态的调用,但我不确定还要寻找什么。

考虑到所有这些,我将其转换为两种管道状态,一种禁用混合,另一种启用混合。混合的设置如下:

 pipelineStateDescriptor.fragmentFunction = viewer.library.makeFunction(name: "borderFragment")!
    pipelineStateDescriptor.colorAttachments[0].isBlendingEnabled = true

    pipelineStateDescriptor.colorAttachments[0].rgbBlendOperation = .add
    pipelineStateDescriptor.colorAttachments[0].alphaBlendOperation = .add

    pipelineStateDescriptor.colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
    pipelineStateDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .sourceAlpha

    pipelineStateDescriptor.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha
    pipelineStateDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha

最佳答案

我发现了问题,问题在于纹理的创建方式,而不是混合的设置方式,这是正确的。在一组上使用 MetalKit 创建纹理时,我使用了以下选项: [MTKTextureLoaderOptionSRGB: NSNumber(value:0)] 而另一方没有。当它们都设置为相同(1 或 0)时,它们匹配并且混合工作正常。

着色器最终成为:

fragment float4 terrainFragment(FragmentIn inFrag [[stage_in]],
                            texture2d<float, access::sample> colorTexture [[ texture(0) ]],
                            sampler colorSampler [[ sampler(0) ]]) {
    float4 color = colorTexture.sample(colorSampler, inFrag.uv * 1.33);
    color *= float4(inFrag.shadow,inFrag.shadow,inFrag.shadow,1);
    return color * 4;
}

关于swift - 在 Metal 中复制 OpenGL 混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41981825/

有关swift - 在 Metal 中复制 OpenGL 混合的更多相关文章

  1. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  2. ruby - 如何在 ruby​​ 中复制目录结构,不包括某些文件扩展名 - 2

    我想编写一个ruby​​脚本来递归复制目录结构,但排除某些文件类型。因此,给定以下目录结构:folder1folder2file1.txtfile2.txtfile3.csfile4.htmlfolder2folder3file4.dll我想复制这个结构,但不包含.txt和.cs文件。因此,生成的目录结构应如下所示:folder1folder2file4.htmlfolder2folder3file4.dll 最佳答案 您可以使用查找模块。这是一个代码片段:require"find"ignored_extensions=[".cs"

  3. ruby - 如何测试正在使用 RSpec 和 Mocha 调用的混合类方法? - 2

    我有一个模块:moduleMyModuledefdo_something#...endend由类使用如下:classMyCommandextendMyModuledefself.execute#...do_somethingendend如何验证MyCommand.execute调用了do_something?我已经尝试使用mocha进行部分模拟,但是当未调用do_something时它不会失败:it"callsdo_something"doMyCommand.stubs(:do_something)MyCommand.executeend 最佳答案

  4. ruby-on-rails - 为什么 DataMapper 使用混合与继承? - 2

    所以我只是对此感到好奇:DataMapper为其模型使用混合classPostincludeDataMapper::Resource虽然active-record使用继承classPost有谁知道为什么DataMapper选择这样做(或者为什么AR选择不这样做)? 最佳答案 它允许您从另一个不是DM类的类继承。它还允许动态地将DM功能添加到类中。这是我正在处理的模块中的类方法:defdatamapper_classklass=self.dupklass.send(:include,DataMapper::Resource)klass

  5. ruby - 在两个 ActiveRecord 类之间合并/复制属性的好方法? - 2

    之前有人问过这个问题,我发现了以下clip关于如何一次设置一个类对象的所有属性,但由于批量分配保护,这在Rails中是不可能的。(例如,您不能Object.attributes={})有没有一种很好的方法可以将一个类的属性合并到另一个类中?object1.attributes=object2.attributes.inject({}){|h,(k,v)|h[k]=vifObjectModel.column_names.include?(k);h}谢谢。 最佳答案 利用assign_attributes使用:without_prote

  6. ruby-on-rails - 将 Ruby 代码和文字标记与 Haml 混合 - 2

    如何用HAML编写这个ERB:#OR我可以:=some_ruby_code+":"#and=some_ruby_code%br但我不想在这里连接,我想将它写成内联:(=some_ruby_code):#and(=some_ruby_code)%br 最佳答案 =some_ruby_code+":"-#and=some_ruby_code+""编辑1:我不确定您在寻找什么。你想要其中之一吗?==#{some_ruby_code}:-#and==#{some_ruby_code}或==#{some_ruby_code}:-#and=so

  7. Ruby:我怎样才能复制这个数组? - 2

    (跟进我之前的问题,Ruby:howcanIcopyavariablewithoutpointingtothesameobject?)我正在编写一个简单的Ruby程序来在.svg文件中进行一些替换。第一步是从文件中提取信息并将其放入数组中。为了避免每次调用此函数时都从磁盘读取文件,我尝试使用memoize设计模式-在第一次调用后的每次调用中都使用缓存结果。为此,我使用了一个在函数之前定义的全局变量。但是,即使我在返回局部变量之前将该变量.dup为局部变量,调用该变量的函数仍在修改全局变量。这是我的实际代码:#memoizetokeepfromhavingtoreadoriginalfi

  8. ruby - 为什么 ruby​​game 和 gosu 比纯 opengl 慢? - 2

    我正在寻找一个好的图形框架来用Ruby制作一个漂亮的2D游戏。我做了3个非常简单的测试,看看哪个图形Ruby框架在Gosu之间更快。和Rubygame.该测试创建了1000个“Square”类的实例,这些实例使用框架的方法以最简单的方式移动和绘制一个红色方block。第三个测试是同一件事,但在纯OpenGL实现中(没有任何框架)。这是结果:纯OPENGL(使用ruby​​-opengl)80Fps:alttexthttp://grab.by/JTMGOSU(使用ruby​​-opengl+gosu)46Fps:alttexthttp://grab.by/JTCRUBYGAME(使用ru

  9. ruby - 如何从 Sass 混合方程中删除测量单位? - 2

    我编写了一个非常简单的Sassmixin,用于将像素值转换为rem值(请参阅JonathanSnook的articleonthebenefitsofusingrems)。这是代码://MixinCode$base_font_size:10;//10px@mixinrem($key,$px){#{$key}:#{$px}px;#{$key}:#{$px/$base_font_size}rem;}//Includesyntaxp{@includerem(font-size,14);}//RenderedCSSp{font-size:14px;font-size:1.4rem;}这个mixi

  10. ruby - 如何将文件从一台服务器复制到另一台服务器? - 2

    我有一台服务器,其中只有xls日志文件。每个文件为5-15Mb,并且在文件随时添加的意义上是动态的。现在我需要一种使用Ruby执行以下过程的方法。通过将文件名从一台只有日志文件的服务器发送到另一台服务器来复制文件。我需要将服务器密码作为参数传递。一切都在后台发生,由Ruby脚本触发。 最佳答案 查看Net::SCP和Net::SSHgem。第一个让您使用安全副本检索文件,第二个让您轻松找到可用于检索的文件的名称。在Net::SSH中,ssh.exec!将成为您的friend。来自Net::SCP文档:Net::SCPimplemen

随机推荐