[英][SceneKit][Metal] Is there is ability to render transparent nodes based on depth buffer and not by rendering order
我在场景中有很多透明节点。 如果场景在某些方向旋转,整个对象会闪烁而不渲染
有些人建议调整渲染顺序,但这个解决问题部分和视觉错误最终出现
可以取消选中“读取深度”,但它会导致闪烁,我几乎可以肯定这不是解决方案
问题:
是否有一些正确的着色器使用正确的深度缓冲区,以便透明节点不会随机隐藏
还是有另一种正确的方法来解决这个问题?
PS:使用了 Metal 渲染,所以如果你提到从 OpenGL 中提供一些技术建议,就留下它
谢谢
以下是示例屏幕截图:
在这个例子中,为了简单起见,使用了 3 个不透明度为 0.5 的平坦双面平面,透明度也可以用纹理的 alpha Chanel 设置。 在实际项目中对象可以是任何形状,可以是透明的,可以是不透明的,可以是相互放置的,也可以是不透明的
穿越飞机的能见度问题 1:
穿越飞机的能见度问题 2:
好的,看起来像“顺序无关透明度”,A 缓冲区和每像素更改片段数应该解决这个问题,但很常见,如何实现? 我们可以使用 GLSL 着色器,直到它适用于 SceneKit 和 Metal 渲染
http://www.openglsuperbible.com/2013/08/20/is-order-independent-transparency-really-necessary/
对于Metal渲染,有一种可能的方法来渲染场景,我成功了。
我想你引用了id <MTLRenderPipelineState>
,所以我所做的是我创建了另一个并禁用了写入颜色缓冲区(将writeMask
设置添加为无)。
之后,我调用渲染器对模型进行两次渲染(第一次使用第二次创建的id <MTLRenderPipelineState>
,其中写入颜色缓冲区被禁用)每一次传递。
第一条管道:
MTLRenderPipelineDescriptor *volumetricPipelineDescriptor = [MTLRenderPipelineDescriptor new];
volumetricPipelineDescriptor.vertexFunction = vertexFunction;
volumetricPipelineDescriptor.fragmentFunction = fragmentFunction;
volumetricPipelineDescriptor.vertexDescriptor = vertexDescriptor;
volumetricPipelineDescriptor.colorAttachments[0].blendingEnabled = YES;
volumetricPipelineDescriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
volumetricPipelineDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
volumetricPipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
volumetricPipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorSourceAlpha;
volumetricPipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
volumetricPipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
volumetricPipelineDescriptor.colorAttachments[0].pixelFormat = _renderDestination.colorPixelFormat;
volumetricPipelineDescriptor.depthAttachmentPixelFormat = _renderDestination.depthStencilPixelFormat;
volumetricPipelineDescriptor.stencilAttachmentPixelFormat = _renderDestination.depthStencilPixelFormat;
error = nil;
_volumetricPipelineState = [_device newRenderPipelineStateWithDescriptor:volumetricPipelineDescriptor
error:&error];
if (!_volumetricPipelineState) {
NSLog(@"Error occurred when creating render pipeline state: %@", error);
}
第二条流水线:
MTLRenderPipelineDescriptor *volumetricPipelineDescriptor = [MTLRenderPipelineDescriptor new];
volumetricPipelineDescriptor.vertexFunction = vertexFunction;
volumetricPipelineDescriptor.fragmentFunction = fragmentFunction;
volumetricPipelineDescriptor.vertexDescriptor = vertexDescriptor;
volumetricPipelineDescriptor.colorAttachments[0].writeMask = MTLColorWriteMaskNone;
volumetricPipelineDescriptor.colorAttachments[0].pixelFormat = _renderDestination.colorPixelFormat;
volumetricPipelineDescriptor.depthAttachmentPixelFormat = _renderDestination.depthStencilPixelFormat;
volumetricPipelineDescriptor.stencilAttachmentPixelFormat = _renderDestination.depthStencilPixelFormat;
error = nil;
_volumetricPipelineState2 = [_device newRenderPipelineStateWithDescriptor:volumetricPipelineDescriptor
error:&error];
if (!_volumetricPipelineState2) {
NSLog(@"Error occurred when creating render pipeline state: %@", error);
}
深度状态:
MTLDepthStencilDescriptor *volumetricDepthStateDescriptor = [MTLDepthStencilDescriptor new];
volumetricDepthStateDescriptor.depthCompareFunction = MTLCompareFunctionLessEqual;
volumetricDepthStateDescriptor.depthWriteEnabled = YES;
_volumetricDepthState = [_device newDepthStencilStateWithDescriptor:volumetricDepthStateDescriptor];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.