- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在 Metal 中实现体素锥体追踪。该算法的步骤之一是使用几何着色器对几何进行体素化。 Metal 没有几何着色器,所以我正在考虑使用计算着色器来模拟它们。我将顶点缓冲区传入计算着色器,执行几何着色器通常会执行的操作,并将结果写入输出缓冲区。我还将绘制命令添加到间接缓冲区。我使用输出缓冲区作为顶点着色器的顶点缓冲区。这工作正常,但我的顶点需要两倍的内存,一个用于顶点缓冲区,另一个用于输出缓冲区。有没有办法直接将计算着色器的输出传递给顶点着色器而不将其存储在中间缓冲区中?我不需要保存计算着色器的输出缓冲区的内容。我只需要将结果提供给顶点着色器。
这可能吗?谢谢
编辑
本质上,我试图从 glsl 模拟以下着色器:
#version 450
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
layout(location = 0) in vec3 in_position[];
layout(location = 1) in vec3 in_normal[];
layout(location = 2) in vec2 in_uv[];
layout(location = 0) out vec3 out_position;
layout(location = 1) out vec3 out_normal;
layout(location = 2) out vec2 out_uv;
void main()
{
vec3 p = abs(cross(in_position[1] - in_position[0], in_position[2] - in_position[0]));
for (uint i = 0; i < 3; ++i)
{
out_position = in_position[i];
out_normal = in_normal[i];
out_uv = in_uv[i];
if (p.z > p.x && p.z > p.y)
{
gl_Position = vec4(out_position.x, out_position.y, 0, 1);
}
else if (p.x > p.y && p.x > p.z)
{
gl_Position = vec4(out_position.y, out_position.z, 0, 1);
}
else
{
gl_Position = vec4(out_position.x, out_position.z, 0, 1);
}
EmitVertex();
}
EndPrimitive();
}
最佳答案
这是一个非常推测性的可能性,具体取决于您的几何着色器需要做什么。
我认为你可以只用一个顶点着色器而不是单独的计算着色器来“向后”做它,代价是在 GPU 上进行冗余工作。您会进行绘制,就像您拥有几何着色器输出图元的所有输出顶点的缓冲区一样。但是,您实际上手头上没有那个。您将构建一个可以在飞行中计算它们的顶点着色器。
因此,在应用程序代码中,计算输出基元的数量,从而计算为给定输入基元计数生成的输出顶点数。绘制具有这么多顶点的输出原始类型。
你会不是 提供一个缓冲区,其中输出顶点数据作为此绘图的输入。
您将提供原始索引缓冲区和原始顶点缓冲区作为该绘制的顶点着色器的输入。着色器将根据顶点 ID 计算它所针对的输出图元,以及该图元的哪个顶点(例如,对于三角形,分别是 vid / 3
和 vid % 3
)。根据输出图元 ID,它将计算哪个输入图元会在原始几何着色器中生成它。
着色器将从索引缓冲区中查找该输入图元的索引,然后从顶点缓冲区中查找顶点数据。 (例如,这对三角形列表与三角形带之间的区别很敏感。)它会将任何预几何着色器顶点着色应用于该数据。然后它将执行有助于识别输出图元的识别顶点的几何计算部分。一旦计算出输出顶点数据,您就可以应用任何您想要的后几何着色器顶点着色(?)。结果就是它会返回的内容。
如果几何着色器可以为每个输入图元生成可变数量的输出图元,那么至少您有一个最大数量。因此,您可以为输出图元的最大潜在计数绘制顶点的最大潜在计数。顶点着色器可以进行必要的计算,以确定几何着色器实际上是否会生成该图元。如果没有,顶点着色器可以安排将整个图元剪掉,方法是将其定位在视锥体外或使用 [[clip_distance]]
输出顶点数据的属性。
这避免了将生成的基元存储在缓冲区中。但是,它会导致 GPU 重复执行一些预几何着色器顶点着色器和几何着色器计算。当然,它会被并行化,但可能仍然比你现在正在做的要慢。此外,它可能会破坏一些关于获取索引和顶点数据的优化,而这些优化可能是使用更普通的顶点着色器实现的。
这是几何着色器的转换示例:
#include <metal_stdlib>
using namespace metal;
struct VertexIn {
// maybe need packed types here depending on your vertex buffer layout
// can't use [[attribute(n)]] for these because Metal isn't doing the vertex lookup for us
float3 position;
float3 normal;
float2 uv;
};
struct VertexOut {
float3 position;
float3 normal;
float2 uv;
float4 new_position [[position]];
};
vertex VertexOut foo(uint vid [[vertex_id]],
device const uint *indexes [[buffer(0)]],
device const VertexIn *vertexes [[buffer(1)]])
{
VertexOut out;
const uint triangle_id = vid / 3;
const uint vertex_of_triangle = vid % 3;
// indexes is for a triangle strip even though this shader is invoked for a triangle list.
const uint index[3] = { indexes[triangle_id], index[triangle_id + 1], index[triangle_id + 2] };
const VertexIn v[3] = { vertexes[index[0]], vertexes[index[1]], vertexes[index[2]] };
float3 p = abs(cross(v[1].position - v[0].position, v[2].position - v[0].position));
out.position = v[vertex_of_triangle].position;
out.normal = v[vertex_of_triangle].normal;
out.uv = v[vertex_of_triangle].uv;
if (p.z > p.x && p.z > p.y)
{
out.new_position = float4(out.position.x, out.position.y, 0, 1);
}
else if (p.x > p.y && p.x > p.z)
{
out.new_position = float4(out.position.y, out.position.z, 0, 1);
}
else
{
out.new_position = float4(out.position.x, out.position.z, 0, 1);
}
return out;
}
关于macos - 使用计算着色器的 Metal 模拟几何着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50557224/
在 Metal 中,在着色器内部(进出)使用什么坐标系?当我们渲染到纹理时是一样的吗?也有z缓冲区?有没有不一致的地方?最后 Metal ,opengl和directX有什么区别? 最佳答案 Meta
我正在尝试在 Mac 上的 Apple metal 中开发我自己的迷你游戏引擎,但我被困在我想在 GPU 上渲染文本的地方。我没有太多的图形编程经验,因此我不知道该怎么做。我偶然发现了 Warren
我找不到答案的简单问题,在 openGL 上有一个 glDeleteTextures(1, &t) 显然模型有很大的不同,但我想知道 Metal 是否有相同的需要或要求。 MTLTexture 是通过
我是 Metal 新手。我想使用 Metal 计算来做一些数学运算,所以我创建了一个内核函数(着色器?),比方说 kernel void foo(device float *data1,
我假设除了 Metal 之外的其他 API 中存在颜色附件(我肯定知道 OpenGL),但我是图形编程的新手,我想知道颜色附件在概念上到底是什么。我所做的所有绘图都涉及在颜色附件数组中的第一个设置属性
在计算着色器中,我可以看到双三次是一个选项,但前提是定义了 __HAVE_BICUBIC_FILTERING__。当我将 bicubic 设置为过滤选项时,出现语法错误。 Linear 或Neares
这是一个绝对的初学者问题。 背景:我并不是真正的游戏开发者,但我正在努力学习底层 3D 编程的基础知识,因为这是一个有趣且有趣的话题。我选择了 Apple 的 Metal 作为图形框架。我知道 Sce
在 GLSL 中,我只需使用 out vec3 array[10]; 将数组从顶点着色器传递到片段着色器。然而,在 Metal 中,我想这样做: struct FragmentIn { flo
我看到 Apple GPU 硬件和 iOS/MacOS 版本的组合决定了一个功能集。我可以使用下面的快速代码片段查询我的 MTLDevice 支持哪些功能集。 device.supportsFeatu
我想将深度缓冲区保存到 Metal 纹理中,但我尝试过的任何方法似乎都不起作用。 _renderPassDesc.colorAttachments[1].clearColor = MTLClearCo
我想在我的 Metal 应用程序中实现一个 A-Buffer 算法来实现与订单无关的透明度。该技术的描述提到使用原子计数器。我从未使用过其中之一,甚至没有听说过。我刚刚阅读了 Metal Shadin
假设我有一个 N channel MPSImage 或基于 MTLTexture 的纹理数组。 我如何从中裁剪一个区域,复制所有 N 个 channel ,但改变“像素大小”? 最佳答案 我将只讨论裁
TL;DR:Metal 似乎没有检测到我的顶点着色器返回的内容 我有这两个用 MSL 编写的函数: vertex float4 base_image_rect(constant float4 *pos
如何在目标设置为 iOS 模拟器的情况下在 Xcode 6 中编译 iOS «Metal» 游戏? error: can't exec 'metal' (No such file or directo
将一些基本的 OpenGL ES 2.0 着色器移植到 Metal 着色器时,我不知道如何将 glsl 中的 in/inout/out 限定符转换为 Metal 着色器语言 (MSL)。例如, //O
我不想使用texture1d_array。我可以简单地传递一个 float 组吗?我将把它写入我的内核函数中。 最佳答案 为了写入内核函数内的 float 组,您需要向内核提供一个缓冲区参数。该参数应
我不想使用texture1d_array。我可以简单地传递一个 float 组吗?我将把它写入我的内核函数中。 最佳答案 为了写入内核函数内的 float 组,您需要向内核提供一个缓冲区参数。该参数应
我有一组 Metal 纹理作为纹理集存储在 Xcode Assets 目录中。我正在使用 MTKTextureLoader.newTexture(name:scaleFactor:bundle:opt
Apple 系统中似乎至少有六个矩阵库。其中之一是 simd 库,其类型在 CPU 和 GPU 代码中的工作方式相同。 import simd let mat = float3x3(...) let
有谁知道 Apple 的旧版本 Metal Feature Set Table 的可用性?文件? 当前的 Metal 3.0 文档仅引用 beta MTLGPUFamily 和 MTLSoftware
我是一名优秀的程序员,十分优秀!