Shader

Posted winfredzen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shader相关的知识,希望对你有一定的参考价值。

Shader

参考:HenCoder Android 开发进阶: 自定义 View 1-2 Paint 详解

Shader 这个英文单词很多人没有见过,它的中文叫做「着色器」,也是用于设置绘制颜色的。「着色器」不是 android 独有的,它是图形领域里一个通用的概念,它和直接设置颜色的区别是,着色器设置的是一个颜色方案,或者说是一套着色规则。当设置了 Shader 之后,Paint 在绘制图形和文字时就不使用 setColor/ARGB() 设置的颜色了,而是使用 Shader 的方案中的颜色。

通常并不直接使用Shader,而是使用使用其子类:LinearGradient RadialGradient SweepGradient BitmapShader ComposeShader

渐变

通过paint.setShader(shader) 设置shader来绘制渐变,shader的意思是着色器

LinearGradient

方法如下:

LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)

参数说明:

  • x0 、y0 、x1、y1 - 渐变的两个端点的位置
  • color0 color1 - 是端点的颜色
  • tile - 着色规则
    • CLAMP - replicate the edge color if the shader draws outside of its original bounds
    • MIRROR
    • REPEAT

如下,方向为斜对角

        Shader shader = new LinearGradient(100, 100, 500, 500, Color.parseColor("#E91E63"), Color.parseColor("#2196F3"), Shader.TileMode.CLAMP);
        paint.setShader(shader);
        canvas.drawCircle(300, 300, 200, paint);

效果如下

调整下方向

Shader shader = new LinearGradient(100, 100, 500, 100, Color.parseColor("#E91E63"), Color.parseColor("#2196F3"), Shader.TileMode.CLAMP);

修改下x1 y1坐标,设置tile为Shader.TileMode.CLAMP

Shader shader = new LinearGradient(100, 100, 300, 300, Color.parseColor("#E91E63"), Color.parseColor("#2196F3"), Shader.TileMode.CLAMP);

设置tile为Shader.TileMode.MIRROR

谁知tile为Shader.TileMode.REPEAT

RadialGradient

RadialGradient(float centerX, float centerY, float radius, int centerColor, int edgeColor, Shader.TileMode tileMode)

参数说明:

  • centerX centerY - 中心坐标
  • radius - 辐射半径
  • centerColor - 辐射中心的颜色
  • edgeColor - 辐射边缘的颜色
  • tileMode - 同上

如下

        Shader shader = new RadialGradient(300, 300, 200, Color.parseColor("#E91E63"), Color.parseColor("#2196F3"), Shader.TileMode.CLAMP);
        paint.setShader(shader);
        canvas.drawCircle(300, 300, 200, paint);

将radius设置小点,tile设置为Shader.TileMode.MIRROR

tile设置为Shader.TileMode.REPEAT

SweepGradient

SweepGradient为扫描渐变

SweepGradient(float cx, float cy, int color0, int color1)
  • cx cy - 扫描的中心
  • color0 - 扫描的起始颜色
  • color1 - 扫描的终止颜色
        Shader shader = new SweepGradient(300, 300, Color.parseColor("#E91E63"), Color.parseColor("#2196F3"));
        paint.setShader(shader);
        canvas.drawCircle(300, 300, 200, paint);

BitmapShader

BitmapShader解释如下:

Shader used to draw a bitmap as a texture. The bitmap can be repeated or mirrored by setting the tiling mode.
使用特定的图片来作为纹理来使用

方法

BitmapShader(Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY)
  • bitmap - 用来做模板的 Bitmap 对象
  • tileX - 横向的 TileMode
  • tileY - 纵向的 TileMode

如上使用drawCircle() + BitmapShader绘制圆形的bitmap

        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.batman);
        Shader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        paint.setShader(shader);
        canvas.drawCircle(200, 200, 200, paint);

drawRect时,横向的TileMode为Shader.TileMode.CLAMP,纵向的TileMode为Shader.TileMode.CLAMP

canvas.drawRect(0, 0, 800, 800, paint);

TileMode都为Shader.TileMode.MIRROR

TileMode都为Shader.TileMode.REPEAT

ComposeShader

ComposeShader:

A subclass of shader that returns the composition of two other shaders, combined by an Xfermode subclass.
着色器的子类,它返回另外两个着色器的组成,并由Xfermode子类组合

ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode)
  • shaderA shaderB - 两个相继使用的 Shader
  • mode - 两个 Shader 的叠加模式,即 shaderA 和 shaderB 应该怎样共同绘制。它的类型是 PorterDuff.Mode

PorterDuff.Mode

PorterDuff.Mode.SRC_OVER时的效果

        Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.batman);
        Shader shader1 = new BitmapShader(bitmap1, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

        Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.batman_logo);
        Shader shader2 = new BitmapShader(bitmap2, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

        Shader shader = new ComposeShader(shader1, shader2, PorterDuff.Mode.DST_OUT);
        paint.setShader(shader);

        canvas.drawCircle(200, 200, 200, paint);

PorterDuff.Mode.DST_OUT相当于是挖空的效果

PorterDuff.Mode.DST_IN相当于是蒙版抠图效果

以上是关于Shader的主要内容,如果未能解决你的问题,请参考以下文章

ShaderLab学习小结通过Shader变换物体形状

unity 支持圆形切倒角和虚化UGUI Shader

知识点3 shader_基础纹理

Unity Shader入门精要学习笔记 - 第7章 基础纹理

OPENGL初学

css 只写div右边的阴影怎么写?