- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是完整的 shadertypes.h 文件。我将把它分解成我无法理解的部分。
#ifndef ShaderTypes_h
#define ShaderTypes_h
//Part 1 Compiler flags
#ifdef __METAL_VERSION__
#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
#define NSInteger metal::int32_t
#else
#import <Foundation/Foundation.h>
#endif
#include <simd/simd.h>
//Part 2 buffer index
typedef NS_ENUM(NSInteger, BufferIndex)
{
BufferIndexMeshPositions = 0,
BufferIndexMeshGenerics = 1,
BufferIndexUniforms = 2
};
//Part 3 vertex attribute and position
typedef NS_ENUM(NSInteger, VertexAttribute)
{
VertexAttributePosition = 0,
VertexAttributeTexcoord = 1,
};
//Part 4 texture index color
typedef NS_ENUM(NSInteger, TextureIndex)
{
TextureIndexColor = 0,
};
//Part 5 uniforms
typedef struct
{
matrix_float4x4 projectionMatrix;
matrix_float4x4 modelViewMatrix;
} Uniforms;
#endif /* ShaderTypes_h */
第 1 部分
#ifdef __METAL_VERSION__
#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
#define NSInteger metal::int32_t
#else
#import <Foundation/Foundation.h>
#endif
//A bunch of definitions go after this
#endif
我的困惑主要在于为什么我们要编写所有这些代码。它似乎在检查用户是否有 Metal ,但它定义的这个 NS_ENUM 是什么?为什么要定义一个 metal 变量?而粉底是有条件进口的吗?
第 2 部分
typedef NS_ENUM(NSInteger, BufferIndex)
{
BufferIndexMeshPositions = 0,
BufferIndexMeshGenerics = 1,
BufferIndexUniforms = 2
};
不太确定这是在做什么,尤其是因为我找不到任何人在任何地方明确引用它们。
第 3 部分
typedef NS_ENUM(NSInteger, VertexAttribute)
{
VertexAttributePosition = 0,
VertexAttributeTexcoord = 1,
};
这个有一点更明确的用法,因为它在 .metal 文件中被引用
typedef struct
{
float3 position [[attribute(VertexAttributePosition)]];
float2 texCoord [[attribute(VertexAttributeTexcoord)]];
} Vertex;
以及顶点描述符代码的属性部分
mtlVertexDescriptor.attributes[VertexAttribute.position.rawValue].format = MTLVertexFormat.float3
mtlVertexDescriptor.attributes[VertexAttribute.position.rawValue].offset = 0
mtlVertexDescriptor.attributes[VertexAttribute.position.rawValue].bufferIndex = BufferIndex.meshPositions.rawValue
...
它似乎以某种方式跟踪各种元素的索引,而不是像缓冲区一样。
第 4 部分
这是我得到的,因为它在此处的渲染中被引用
renderEncoder.setFragmentTexture(colorMap, index: TextureIndex.color.rawValue)
还有这里的shader
fragment float4 fragmentShader(..., texture2d<half> colorMap [[ texture(TextureIndexColor) ]]){
我有点明白这个(减去 NSEnum 部分)但是我不明白只为一件事做这件事是个好习惯。
第 5 部分
这实际上是我理解的唯一一个它看起来像是所有统一组件的结构,这很有意义,因为它存储了统一的实际类型,允许着色器也暴露给该结构作为渲染器。
我想最终我想知道为什么采用这种方法以及为什么它是 Apple 建议的最佳实践。我认为以这种方式做事有点有意义,除了 Metal 似乎更适合 objective-c,尽管它看起来像 swift。
最佳答案
这是一个 header ,旨在由 Metal 着色器代码和应用程序代码(Objective-C 或通过桥接 Swift)共享。必须在这两种语言之间共享它需要一点小心。
#ifdef __METAL_VERSION__
测试确定它正在编译的语言。对于 Metal,定义了几个宏。对于 Objective-C,它导入 Foundation。 (当然,在编译 Metal 代码时不能导入 Foundation。)
在他们的 (Objective-)C 头文件中,Apple 通常使用 NS_ENUM()
宏来声明枚举。该宏是在 Foundation header 中定义的,因此可以在将此 header 编译为应用程序代码时使用它。它没有在 Metal header 中定义,因此如果它想使用它(就像它所做的那样),这个 header 需要为自己定义它。宏的 Foundation 版本很有用,因为它检测编译器功能,如果可用则使用类型化枚举,如果不可用则使用常规枚举。在这个 header 中,Apple 正在为 Metal 着色器语言实现相同的宏。由于毫无疑问编译器是否支持类型化枚举(它支持),因此只有一个宏定义利用了该功能。
在 header 的后面,他们计划使用 NSInteger
类型。这是由应用程序代码的 Foundation header 定义的。由于他们想对 Metal 使用相同的代码,但该类型未在此处定义,因此他们需要在此 header 中定义它。不过,他们做出了一些奇怪的选择。首先,他们使用宏而不是 typedef
。其次,他们将其定义为等同于 int32_t
(在 metal
命名空间中)。这很奇怪,因为应用程序代码将是 64 位的(Metal 不适用于 32 位应用程序)导致 NSInteger
成为 64 位整数类型(相当于 int64_t
)。因此,这两个世界将不同意 NSInteger
的大小,因此所有基于它的枚举。这有点糟糕,但考虑到这些枚举的实际使用方式,可能不会导致真正的问题。
将枚举简单地基于 int
可能会更好,它在所有 Apple 环境中都是 32 位的。
第 2、3 和 4 部分都很相似。使用“符号”常量而不仅仅是魔数(Magic Number)(即代码中的整数文字)通常是一种很好的做法。它不易出错并提高了可读性。这些部分只是定义了一些这样的符号常量,供 Metal 代码和应用程序代码共享。事实上,其中一些名称未在您正在检查的特定示例项目中使用,这表明 Apple 对多个示例项目或类似项目使用了相同的 header 。
关于ios - "ShaderTypes.h"中演示的 Metal 着色器类型顶点和缓冲区最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47257504/
我想使用图中所示的迷宫,使用迭代深度优先搜索找到从起始节点到目标的路径。它是一个仅包含一对数字的文本文件,例如成对连接,又称边/弧。像这样: 11 3 2 3 0 3 1 4 5 4 5 7 6 7
问题:您有一个无向图 G = (V, E)(V = 顶点,E = 边),您必须访问每个顶点并在两个方向上通过每个边。 我所知道的图算法只有 DFS、BFS 和一些 MST(Kruskal 等)不幸的是
枚举任意图中两个顶点之间的所有简单路径通常需要指数时间,因为顶点之间可能存在指数数量的简单路径。但是,如果我们只对位于两个末端顶点之间的至少一条简单路径上的顶点怎么办? 即:给定一个无向图和两个不同的
我正在开发一个简单的 opengl 游戏以了解更多相关信息。但是由于某种原因,当我尝试随时间旋转我的立方体时,它会被拉伸(stretch)。你可以在照片中看到它: 我认为这与我的模型矩阵有关,但我不确
我已经在谷歌上搜索了很长一段时间,但我找不到任何东西。如何使用 Graphviz 绘制没有连接顶点的图形? 最佳答案 像这样: digraph g { SingleNode; } 简单地不定义
我目前正在使用 R 中的“igraph”包进行一些社交网络分析,我想知道是否有一种方法可以个性化社交网络中节点的放置。 例如,使用以下玩具代码: library(igraph) edg
我在 Box2D 中有一个多边形形状。形状是一个三角形,我希望有 3 个顶点。事实上,我创建的所有形状都会输出 8 个顶点。为什么是这样?如果我输出顶点数,那总是正确的数量。我不想渲染不必要的线条,但
来自user manual CGAL Surface_mesh 类: the data structure uses integer indices as descriptors for vertic
我正在尝试找到引用 ARFaceGeometry 网格索引的方法为了使用 ARKit 将图形放置在面部的特定部位。 我见过很多例子,其中功能与一些索引号,但我找不到对此列表的任何引用。它似乎有超过12
Apache TomCat(版本未知) 业务对象 4.1 顶点 4.4.3 在一台服务器上,我们拥有 TomCat 和 Business Objects。 APEX 也使用 TomCat。 在对我们的
我正在使用 MX Graph 进行一些工作,以帮助识别网站中的关键内容路径。我将其设置为每个顶点代表网站上的一个页面,每条边代表一组从页面 A 访问页面 B 的访问者。 一切都运行良好,除了边太多,我
我正在尝试使用三角形 strip 绘制一个平面。我了解如何手动执行此操作,但我真的很难使用 for 循环来执行此操作。到目前为止,下面的代码绘制了两个三角形。 //vertices for trian
如果我想通过 id 顶点获取名称,我可以使用这个函数:VAS(g, "name",id)但是如果我想要相反的方式,通过名称获取 id,我该怎么做呢? 最佳答案 igraph 本身不提供按名称查找顶点的
我有一个三角形,其任意顶点位于 3D 空间中。 我知道通过以下操作很容易找到这种三角形的质心: float centroid[3] = { 0, 0, 0 }; for (int i = 0; i =
我有一个点数组。每个点都有位置(x, y, z) 和法 vector (xn, yn, zn) ,一共6个 double 。考虑到浮点容差,我需要在此数组中找到唯一元素并删除重复条目。 实现它的简单有
我有一个相互连接的边列表 (E),如何找到从一个顶点连接到另一个顶点的最短路径? 我正在考虑使用 lowest common ancestors ,但边缘没有明确定义的根,所以我认为该解决方案不起作用
我现在正在使用计算着色器开发粒子系统。我将所有粒子都放在着色器存储缓冲区中。一个粒子包含两个顶点,当前位置和先前位置。 struct Particle{ glm::vec4 _currPo
我将我的顶点剪裁在边缘上,如这张专辑所示: http://imgur.com/a/VkCrJ 当我的地形大小为 400 x 400 时,我得到裁剪,但在 40x40 或更小时,我没有得到任何裁剪。这是
总是在顶点着色器中而不是在片段着色器中更好地进行硬计算吗?即使是具有超过 100.000 个多边形的高网格模型(假设有一堆独特的顶点)? 最佳答案 不,它并不总是更好。 选择合适的计算位置的最佳方法是
我想编辑一个立方体上的 1 个顶点,但我不知道该怎么做。我试过到处寻找此功能,但找不到解决方案。 这是我想要实现的目标的图像: 最佳答案 http://answers.unity3d.com/ques
我是一名优秀的程序员,十分优秀!