我一直在将一个使用固定功能管线编写的开源游戏移植到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