【发布时间】:2019-12-17 05:09:06
【问题描述】:
我试图用 renderEncoder 的 drawIndexedPrimitives 画一个半圆
[renderEncoder setVertexBuffer:self.vertexBuffer offset:0 atIndex:0];
[renderEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangleStrip
indexCount:self.indexCount
indexType:MTLIndexTypeUInt16
indexBuffer:self.indicesBuffer
indexBufferOffset:0];
圆的vertexBuffer和indicesBuffer是通过计算创建的
int segments = 10;
float vertices02[ (segments +1)* (3+4)];
vertices02[0] = centerX;
vertices02[1] = centerY;
vertices02[2] = 0;
//3, 4, 5, 6 are RGBA
vertices02[3] = 1.0;
vertices02[4] = 0;
vertices02[5] = 0.0;
vertices02[6] = 1.0;
uint16_t indices[(segments -1)*3];
for (int i = 1; i <= segments ; i++){
float degree = (i -1) * (endDegree - startDegree)/ (segments -1) + startDegree;
vertices02[i*7] = (centerX + cos([self degreesToRadians:degree])*radius);
vertices02[i*7 +1] = (centerY + sin([self degreesToRadians:degree])*radius);
vertices02[i*7 +2] = 0;
vertices02[i*7 +3] = 1.0;
vertices02[i*7 +4] = 0;
vertices02[i*7 +5] = 0.0;
vertices02[i*7 +6] = 1.0;
if (i < segments){
indices[(i-1)*3 + 0] = 0;
indices[(i-1)*3 + 1] = i;
indices[(i-1)*3 + 2] = i+1;
}
}
所以我将 9 个三角形组合成一个 180 度的圆。
然后创建vertexBuffer和indicesBuffer
self.vertexBuffer = [device newBufferWithBytes:vertexArrayPtr
length:vertexDataSize
options:MTLResourceOptionCPUCacheModeDefault];
self.indicesBuffer = [device newBufferWithBytes:indexArrayPtr
length:indicesDataSize
options:MTLResourceOptionCPUCacheModeDefault];
结果是这样的:
我相信这是来自 iOS 的 Metal 的抗锯齿问题。我曾经使用相同的技术在 OpenGL 中创建半圆,但边缘更平滑。
有解决这个问题的建议吗?
warrenm 建议,我应该将 CAMetalLayer 的 drawableSize 设置为 screenSize x 比例。有改进:
【问题讨论】:
-
看起来你的金属层的可绘制尺寸明显小于你的视图的像素尺寸。如果您直接使用
CAMetalLayer,您是否尝试过将其drawableSize属性设置为视图大小乘以屏幕比例? -
您还可以通过将渲染管道的
sampleCount设置为 4 来启用 MSAA,并从适当大小的渲染目标进行渲染/解析,但我认为通过匹配您会看到显着的改进将渲染目标大小调整为视图的像素尺寸,即使不使用 MSAA。 -
@warrenm 感谢您的帮助。是的,我一直在使用 CAMetalLayer,并且在您提到的设置 drawableSize 后有了显着的改进。我想尝试将 pipelineDescriptor 的 sampleCount 设置为 4,但是当我尝试运行时崩溃,我想我需要 MTKView 来匹配 renderPipeline 和 renderTarget 之间的 sampleCount?
-
没错;视图的样本数需要与渲染管线状态的样本数相匹配。如果您使用
MTKView,它将为您创建适当的多重采样纹理;您只需要设置样本数。 -
很高兴这对你有用。在此之前我已经添加了一个答案,其中列出了有关幕后发生的事情的更多详细信息,希望它对将来访问此问题的人有所帮助。
标签: ios objective-c opengl-es metal antialiasing