Custom Metal Shaders & Transparency

Can somebody explain to/help me with transparency when I use custom metal shaders?


Simple shader like this:


fragment float4 fragmentShader(dataOut vertexShaderIn [[stage_in]])

{

// A

// return float4(1.0, 1.0, 1.0, 0.2);


// B premultiplied alpha

return float4(0.2, 0.2, 0.2, 0.2);

}


Won't cause transparency on my simple plane. I also set


node.renderingOrder = 1


so I'm sure plane is rendered when all background is already in place.


A) approach doesn't work as well as B) - premultiplied alpha one. What else I need to do or set to achieve semi-transparent plane in the scene? Why is it so complex? OpenGL shareds simply returned vec4(1, 1, 1, 0.1) and all worked...


Thanks

Replies

This is what scares me the most. 26 views, 0 replies... One of very few fundamentals of 3d rendering - semi-transparent materials (triangles) and nobody knows how to achieve it in SceneKit when Custom Shaders are used.


Here's very nice and extensive explanation of things related the topic

https://stackoverflow.com/questions/44999255/scenekit-diffuse-alpha-vs-transparency-transparent?answertab=active#tab-top


but it didn't help me that much. Premultiplied alpha is probably optimisation thing, yet very unintuitive.


When I use build-in SCNMaterial and set transparency, it all works. So it has to be possible to achieve transparency even in custom shaders. Unity, Unreal Engine, OpenGL and even low level metal shader rendering techniques can simply return


vec4(1, 0, 0, 0.2) in fragment shader to see semi-transparent red plane in the scene.


SceneKit is different though. They use some magic and optimisations to achieve great FPS, but made it very unfriendly, complicated and complex. There's no proper documentation..


This is very painful experience.. I wouldn't believe how difficult is to render one plane with 2 triangles and hope for transparency...

Sorry for the late reply, but I just came across your question because I had the same challenge. In the end I just had to set SCNProgram.isOpaque to false and return my alpha component from the fragment shader as usual:

In your program code:
...
mySCNProgram.isOpaque = false
...

In fragment shader:
...
return half4(1, 0, 0, 0.2)
...

This rendered the triangle in semi-transparent red color over background (geometries).