Blend Mode in Metal

Blend Mode in Metal

You configure blending on your render pipeline descriptor. I believe the equivalent configurations for your GL code are:

// glEnable(GL_BLEND)
renderPipelineDescriptor.colorAttachments[0].isBlendingEnabled = true

// glBlendFuncSeparate(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA,GL_ONE,GL_ONE_MINUS_SRC_ALPHA)
renderPipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
renderPipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha
renderPipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .one
renderPipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha

// glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_SRC_ALPHA, GL_ONE)
renderPipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
renderPipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = .one
renderPipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .sourceAlpha
renderPipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .one

Changing the blend mode in Metal

Some objects in Metal are designed to be transient and extremely lightweight, while others are more expensive and can last for a long time, perhaps for the lifetime of the app.

Command buffer and command encoder objects are transient and designed for a single use. They are very inexpensive to allocate and deallocate, so their creation methods return autoreleased objects.

MTLRenderPipelineState is not transient.

Does changing the blend function in Metal needs setting a whole new
MTLRenderPipelineState?

Yes, you must create a whole new MTLRenderPipelineState object for each blending configuration.

Replicate OpenGL Blending in Metal

I found the problem, it was with how the textures were created, not how the blending was set up which was correct. When creating the textures with MetalKit on one set I used the option:
[MTKTextureLoaderOptionSRGB: NSNumber(value:0)] and didn't on the other. When they both were set to be the same (either 1 or 0) they matched and blending worked correctly.

Shader ended up being:

fragment float4 terrainFragment(FragmentIn inFrag [[stage_in]],
texture2d<float, access::sample> colorTexture [[ texture(0) ]],
sampler colorSampler [[ sampler(0) ]]) {
float4 color = colorTexture.sample(colorSampler, inFrag.uv * 1.33);
color *= float4(inFrag.shadow,inFrag.shadow,inFrag.shadow,1);
return color * 4;
}

What blending mode do I need to make images more transparent by drawing transparent images over them?

ShapeRenderer doesn't know you're changing the blendfunc, so you're drawing both the circle and the square with the second blendfunc that you set. You need to flush it in between.

Is it possible to use mix-blend-mode to blur a background while ignoring an opaque layer?

The semi transparent overlay will always add shade to entire card. We can have same image in the overlay and fade it there.

html,
body {
min-height: 100vh;
display: flex;
flex-direction: column;
webkit-font-smoothing: antialiased;
moz-osx-font-smoothing: grayscale;
font-family: 'Squada One', sans-serif !important;
}

body::before {
content: '';
background: black background-attachment: fixed;
background-repeat: no-repeat;
background-size: cover;
overflow: hidden;
position: fixed;
z-index: -1;
filter: blur(2.5px);
width: 100vw;
height: 100vh;
transform: scale(1.1);
}

.parenttile {
margin: 0 auto;
text-align: center;
display: flex;
align-items: center !important;
}

.link_wrapper2 {
width: auto;
padding: 0px;
}

.boxborder {
border-color: blue;
border-width: 0.3em;
border-style: solid;
border-radius: 15px !important;
}

.front {
position: relative;
z-index: 2 !important;
}

.blend {
text-shadow: 0 2px 2px #fdee00;
-webkit-filter: invert(100%);
filter: invert(100%);
mix-blend-mode: lighten;
}

.img1 {
background-image: url("https://images.unsplash.com/photo-1641225635705-139a1a5e3938?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=261&q=80");
}

.img2 {
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/2017/17_04_cat_bg_02.jpg");
}

.img3 {
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/2017/17_04_cat_bg_01.jpg");
}

.test-box {
background-size: 101% 101%;
background-repeat: no-repeat;
height: 150px;
border-radius: 15px !important;
position: relative;
}

.test-box::before {
content: ' ';
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
border-radius: 15px !important;
background-size: 100% 100%;
background-repeat: no-repeat;
background-color: #faa4;
/*blending #faa4 with background image to make it look fade out*/
background-blend-mode: lighten;
}

/*add image to the pseudo element and then fade it*/

.img1.test-box:before {
background-image: url("https://images.unsplash.com/photo-1641225635705-139a1a5e3938?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=261&q=80");
}

.img2.test-box:before {
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/2017/17_04_cat_bg_02.jpg");
}

.img3.test-box:before {
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/2017/17_04_cat_bg_01.jpg");
}

header.blending {
color: white;
text-shadow: 0 3px 1px orange;
mix-blend-mode: difference;
font-size: 5rem;
font-weight: bolder;
filter: saturate(4);
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css" integrity="sha512-IgmDkwzs96t4SrChW29No3NXBIBv8baW490zk5aXvhCD8vuZM3yUSkbyTBcXohkySecyzIrUwiF/qV0cuPcL3Q==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<div class="columns is-centered desktop front">
<div class="column is-4">
<div class="tile is-ancestor parenttile ml-3 mr-3">
<div class="tile is-12 is-parent">
<div class="tile is-child box test-box img1 boxborder has-text-white has-text-centered" style="overflow:hidden;">
<a href="#">
<header class="blending">Contra..</header>
</a>
</div>
</div>
</div>
</div>
<div class="column is-4">
<div class="tile is-ancestor parenttile ml-3 mr-3">
<div class="tile is-12 is-parent">
<div class="tile is-child box test-box img2 boxborder has-text-white has-text-centered" style="overflow:hidden;">
<a href="#">
<header class="blending">Contra..</header>
</a>
</div>
</div>
</div>
</div>
<div class="column is-4">
<div class="tile is-ancestor parenttile ml-3 mr-3">
<div class="tile is-12 is-parent">
<div class="tile is-child box test-box img3 boxborder has-text-white has-text-centered" style="overflow:hidden;">
<a href="#">
<header class="blending">Contra..</header>
</a>
</div>
</div>
</div>
</div>
</div>

Need something like mix-blend-mode to invert matching text color when intersecting bg color is the same

You need to apply mix-blend-mode to the parent element and color: white (on the text) to apply the desired effect. Keep in mind that if you're not using black (#000) or white (#fff) you might not get the colors you started out with due to blending.

My solution:

.content__heading {
position: sticky;
padding: 1.5rem;
mix-blend-mode: difference;
}

.content__heading h2 {
position: sticky;
top: 1.5rem;
font-size: clamp(4.5rem, 20vmin, 7.875rem);
line-height: 1;
-ms-writing-mode: tb-lr;
writing-mode: vertical-lr;
transform: rotate(180deg);
text-align: right;
/* add color white to achieve the right inversion */
color: white;
}

Correct blending mode for r8Unorm texture

I solved my problem with this configuration:

descriptor.colorAttachments[0].isBlendingEnabled = true
descriptor.colorAttachments[0].rgbBlendOperation = .max
descriptor.colorAttachments[0].sourceRGBBlendFactor = .one
descriptor.colorAttachments[0].destinationRGBBlendFactor = .one


Related Topics



Leave a reply



Submit