Android Developers
Published in

Android Developers

RenderNode for Bigger, Better Blurs

RenderEffects #3: Using RenderNode for faster, better blurring

The caption is drawn with a shader which both blurs and frosts that area

The problem(s)

val blur = RenderEffect.createBlurEffect(
30f, 30f, Shader.TileMode.CLAMP)
val shader = RenderEffect.createRuntimeShaderEffect(
FROSTED_GLASS_SHADER, "inputShader")
val chain = RenderEffect.createChainEffect(blur, shader)
setRenderEffect(chain)
Applying a RenderEffect blur to a view blurs the entire view, which is… not what I wanted

Okay, what about using a separate View?

The caption effect is now being done directly in the TextView. (But it’s not being done well).
The caption effect as it should be (shader applied to underlying ImageView)

A Better Way… with RenderNode

RenderNode: How Views Actually Draw Their Stuff

RenderNodes are used internally for all Views by default and are not typically used directly.

RenderNode is used to build hardware accelerated rendering hierarchies.

Drawing with Multiple RenderNodes

val contentNode = RenderNode("image")
val blurNode = RenderNode("blur")
override fun onDraw(canvas: Canvas?) {

contentNode.setPosition(0, 0, width, height)
val rnCanvas = contentNode.beginRecording()
super.onDraw(rnCanvas)
contentNode.endRecording()

canvas?.drawRenderNode(contentNode)

// ... rest of code below
}
    // ... rest of code above    blurNode.setRenderEffect(RenderEffect.createBlurEffect(30f, 30f,
Shader.TileMode.CLAMP))
blurNode.setPosition(0, 0, width, 100)
blurNode.translationY = height - 100f

val blurCanvas = blurNode.beginRecording()
blurCanvas.translate(0f, -(height - 100f))
blurCanvas.drawRenderNode(contentNode)
blurNode.endRecording()

canvas?.drawRenderNode(blurNode)
}
Better blur in the label by combining a RenderEffect blur in addition to frosted-glass shader, with two RenderNodes.

… And That’s It!

  • RenderEffect: The class used to create effects for blurs, bitmaps, chains and more. These effects are set on Views or RenderNodes to change the way those objects are drawn.
  • RenderNode: The object which holds the underlying operations used to draw Views, but which can also be used directly to record and store custom drawing operations.
  • RuntimeShader: The object which holds the code for an AGSL shader.
  • AGSL: Android Graphics Shading Language. Like SkSL, but for Android. It provides a mechanism for creating very custom per-pixel drawing effects.
  • SkSL: The shading language for Skia. It’s like GLSL, but for the Skia rendering pipeline.
  • GLSL shaders: The language for fragment shaders when using OpenGL.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store