我正在尝试移植简单的 iOS sample app到 macOS。 Metal 编译器说
Fragment shader parameter with attribute 'color' is supported only on iOS (requires -std=ios-metal1.[0|1|2]).
如何克服这个错误?我在哪里可以找到指出 macOS 和 iOS 之间 Metal API 差异的文档?
Here是目标为 macOS 的 Xcode 项目。以上错误是由 Light.metal 引发的。
macOS 10.13 英特尔 i5-5257u 虹膜 6100
最佳答案
将来,显示该示例应用程序中的哪个特定文件产生了错误以及确切的行。或者,因为您正在移植(修改)示例,所以显示您项目中的片段着色器代码。此外,请指明您使用的是哪个版本的 macOS。
理论上,this PDF应该显示平台之间的差异。这可能并不明显,但我相信此功能属于该表中的“可编程混合”。基本上,从渲染目标获取现有颜色主要用于在计算新值时使用原始值,即执行新值与旧颜色的自定义混合。
Metal Shading Language spec确实在第 4.3.4.4 节中说,片段函数输入的属性限定符:
The
[[color(m)]]attribute qualifier is only supported in iOS.
如果有错误的shader是https://developer.apple.com/library/content/samplecode/MetalDeferredLighting/Listings/MetalDeferredLighting_Light_metal.html ,那么它实际上只输出到 light 渲染目标(附件 3)。其他的它只是保留(并读取作为其计算的输入)。对于 light 纹理,它(有效地)读取和写入它。
因此,在 macOS 10.13+ 上,您可以使用纹理读写功能,具体取决于光纹理的像素格式和 GPU 的功能。您将以不同于 iOS 的方式为这部分执行渲染过程。您不会指定任何渲染目标。片段着色器将返回 void。它的所有输出都将通过纹理写入。不是使用纹理作为渲染目标(颜色附件),而是通过纹理表传递它们。您不会将 FragOutput 类型与其 [[color(n)]] 字段一起使用,您会使用 [[ texture(n)]] 属性。您将从片段位置 (uint2(in.position)) 的纹理中read()(不是sample())。
所以,像这样:
fragment void lightFrag(VertexOutput in [[stage_in]],
constant LightFragmentInputs *lightData [[buffer(0)]],
texture2d<float, access::read> normal [[texture(0)]],
depth2d<float, access::read> depth [[texture(1)]],
texture2d<float, access::read_write> light_tex [[texture(2), raster_order_group(0)]])
{
uint2 pos = uint2(in.position);
float3 n_s = normal.read(pos).rgb;
float scene_z = depth.read(pos);
float3 n = n_s * 2.0 - 1.0;
// Derive the view-space position of the scene fragment in the G-buffer
// Since the light primitive and the G-buffer were rendered with the same view-projection matrix,
// we can treat the view-space position of the current light primitive fragment as a ray from the origin,
// and derive the view-space position of the scene by projecting along the ray with (scene_z / v_view.z).
// Our scene view-space position is also the view-vector to the scene fragment.
float3 v = in.v_view * (scene_z / in.v_view.z);
// Now, we have everything we need to calculate our view-space lighting vectors.
float3 l = (lightData->view_light_position.xyz - v);
float n_ls = dot(n, n);
float v_ls = dot(v, v);
float l_ls = dot(l, l);
float3 h = (l * rsqrt(l_ls / v_ls) - v);
float h_ls = dot(h, h);
float nl = dot(n, l) * rsqrt(n_ls * l_ls);
float nh = dot(n, h) * rsqrt(n_ls * h_ls);
float d_atten = sqrt(l_ls);
float atten = fmax(1.0 - d_atten / lightData->light_color_radius.w, 0.0);
float diffuse = fmax(nl, 0.0) * atten;
float4 light = light_tex.read(pos);
light.rgb += lightData->light_color_radius.xyz * diffuse;
light.a += pow(fmax(nh, 0.0), 32.0) * step(0.0, nl) * atten * 1.0001;
light_tex.write(light, pos);
}
如果您不能使用纹理读写,那么您可能需要使用两个纹理。您会将旧的光照纹理作为只读参数传递,并让片段着色器将新值(作为 float4 返回类型)返回到新的光照纹理中。您可以在原始代码使用旧光照纹理的帧渲染的其余部分使用该新光照纹理,或者将新光照纹理中的结果复制回旧纹理。
关于ios - 用于 macOS 的具有属性 'color' 的片段着色器参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44861459/
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere