gpt4 book ai didi

swift - MTKView 顶点透明度在 "additive"混合模式下未拾取

转载 作者:行者123 更新时间:2023-11-30 11:47:02 24 4
gpt4 key购买 nike

我正在尝试实现一个 Metal 支持的绘图应用程序,其中通过沿着路径重复冲压纹理方 block 来在 MTKView 上绘制笔触。我在绘制笔触时在顶点级别改变图章的颜色/透明度,这样我就可以模拟墨水效果,例如颜色/透明度随着时间的推移而褪色等。当我使用时,这似乎工作正常经典的“过度”类型混合(不会随着时间的推移积累值),但是当我使用“附加”混合时,顶点透明度被完全忽略(即我只获得纹理透明度)。以下是相关代码片段:

首先,我的顶点程序:

vertex VertexOut basic_vertex(const device VertexIn* vertex_array [[ buffer(0) ]], unsigned int vid [[ vertex_id ]]) {

VertexIn VertexIn = vertex_array[vid];
VertexOut VertexOut;
VertexOut.position = float4(VertexIn.position,1);
VertexOut.color = VertexIn.color;
VertexOut.texCoord = VertexIn.texCoord;

return VertexOut;
}

接下来,我的片段程序将图章的纹理(带 Alpha)乘以顶点颜色(也带 Alpha),这是在笔触上逐渐着色或褪色每个图章所需要的

fragment float4 basic_fragment(VertexOut interpolated [[stage_in]], texture2d<float>  tex2D     [[ texture(0) ]], sampler           sampler2D [[ sampler(0) ]]) 
{
float4 color = interpolated.color * tex2D.sample(sampler2D, interpolated.texCoord); // texture multiplied by vertex color
return color;
}

接下来,以下是混合定义:

// 5a. Define render pipeline settings
let renderPipelineDescriptor = MTLRenderPipelineDescriptor()
renderPipelineDescriptor.vertexFunction = vertexProgram
renderPipelineDescriptor.sampleCount = self.sampleCount
renderPipelineDescriptor.colorAttachments[0].pixelFormat = self.colorPixelFormat
renderPipelineDescriptor.colorAttachments[0].isBlendingEnabled = true
renderPipelineDescriptor.colorAttachments[0].alphaBlendOperation = .add

// settings for additive blending
if drawColorBlendMode == colorBlendMode.compositeAdd {
renderPipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = .one
renderPipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = .one
renderPipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .one
renderPipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .one
}

// settings for classic 'over' blending
if drawColorBlendMode == colorBlendMode.compositeOver {
renderPipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
renderPipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha
renderPipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .sourceAlpha
renderPipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha
}

renderPipelineDescriptor.fragmentFunction = fragmentProgram

最后,我的渲染编码:

brushTexture = MetalTexture(resourceName: "stamp_stipple1_0256", ext: "png", mipmaped: true)
brushTexture.loadTexture(device: device!, commandQ: commandQueue, flip: true)
renderCommandEncoder?.setRenderPipelineState(renderPipeline!)
renderCommandEncoder?.setVertexBuffer(vertexBuffer, offset: 0, index: 0)
renderCommandEncoder?.setFragmentTexture(brushTexture.texture, index: 0)
renderCommandEncoder?.setFragmentSamplerState(samplerState, index: 0)

我有什么遗漏的吗?如前所述,这在“over”模式下按预期工作,但在“additive”模式下则不然。同样,所需的效果是将不同的颜色/透明度设置传递给每个图章(一对纹理三角形)。

最佳答案

通过反复试验,我得到了以下设置来获得我想要的结果:

// Settings for compositeOver
renderPipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = .one
renderPipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha
renderPipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .one
renderPipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha

此外,因为我正在处理许多重叠的图章,所以我必须将颜色/alpha 值除以重叠数,以避免过度饱和。我认为这最重要的是我没有按照我预期的方式看到颜色/alpha 积累的原因。

stampColor = UIColor(red: (rgba.red * rgba.alpha / numOverlappingStamps), green: (rgba.green * rgba.alpha / numOverlappingStamps), blue: (rgba.blue * rgba.alpha / numOverlappingStamps), alpha: (rgba.alpha / numOverlappingStamps))

关于swift - MTKView 顶点透明度在 "additive"混合模式下未拾取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48713020/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com