关于着色器LinearGradient的使用

LinearGradient我们可以将之译为线型渐变、线型渲染等,译成什么不重要,重要的是它的显示效果是什么样子,今天我们就一起来看看。

先来看看LinearGradient的构造方法:

[java] view plain copy print?

  1. /** Create a shader that draws a linear gradient along a line.
  2. @param x0           The x-coordinate for the start of the gradient line
  3. @param y0           The y-coordinate for the start of the gradient line
  4. @param x1           The x-coordinate for the end of the gradient line
  5. @param y1           The y-coordinate for the end of the gradient line
  6. @param  colors      The colors to be distributed along the gradient line
  7. @param  positions   May be null. The relative positions [0..1] of
  8. each corresponding color in the colors array. If this is null,
  9. the the colors are distributed evenly along the gradient line.
  10. @param  tile        The Shader tiling mode
  11. */
  12. public LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],
  13. TileMode tile) {
  14. .........
  15. .....
  16. ......
  17. }

LinearGradient的构造方法共有七个参数,分别表示:

x0表示渲染起始位置的x坐标,y0表示渲染起始位置的y坐标,x1表示渲染结束位置的x坐标,y1表示渲染结束位置的y坐标,colors表示渲染的颜色,它是一个颜色数组,数组长度必须大于等于2,positions表示colors数组中几个颜色的相对位置,是一个float类型的数组,该数组的长度必须与colors数组的长度相同。如果这个参数使用null也可以,这时系统会按照梯度线来均匀分配colors数组中的颜色,最后一个参数则表示平铺方式,有三种,我们分别来看:

为了给大家演示不同平铺方式下使用着色器的不同效果,我自定义了一个View,叫做AboutShaderView,我重写了该View中的两个方法,分别是onMeasure以及onDraw,在onMeasure方法中,我把该控件的宽高固定为256dp,代码如下:

[java] view plain copy print?

  1. @Override
  2. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  3. super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  4. setMeasuredDimension((int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 256, getResources().getDisplayMetrics()), (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 256, getResources().getDisplayMetrics()));
  5. }

然后在onDraw方法中通过使用着色器的不同模式,来让它显示不同的效果,最后,我在布局文件中引用自定义View:

[java] view plain copy print?

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. android:orientation="vertical"
  8. tools:context="lenve.customtextview.MainActivity">
  9. <lenve.customtextview.AboutShaderView
  10. android:layout_width="256dp"
  11. android:layout_height="256dp"/>
  12. </LinearLayout>

OK,下面我们一起来看看这几种不同模式的显示效果:

1.LinearGradient.TileMode.CLAMP

这种模式表示重复最后一种颜色直到该View结束的地方,如果我设置着色器开始的位置为(0,0),结束位置为(getMeasuredWidth(), 0)表示我的着色器要给整个View在水平方向上渲染不同的颜色,代码如下:

[java] view plain copy print?

  1. @Override
  2. protected void onDraw(Canvas canvas) {
  3. super.onDraw(canvas);
  4. Paint paint = new Paint();
  5. paint.setColor(Color.GREEN);
  6. LinearGradient linearGradient = new LinearGradient(0, 0, getMeasuredWidth(), 0,new int[]{Color.RED, Color.WHITE, Color.BLUE}, null, LinearGradient.TileMode.CLAMP);
  7. paint.setShader(linearGradient);
  8. canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint);
  9. }

显示效果如下:

水平方向上依次是红白蓝,没问题,那我如果变换一下需求,我想把渲染的方向修改为从左上角到右下角,那么该怎么办?很简单,只需要修改渲染结束的位置为getMeasuredHeight()即可,代码如下:

[java] view plain copy print?

  1. @Override
  2. protected void onDraw(Canvas canvas) {
  3. super.onDraw(canvas);
  4. Paint paint = new Paint();
  5. paint.setColor(Color.GREEN);
  6. LinearGradient linearGradient = new LinearGradient(0, 0, getMeasuredWidth(), getMeasuredHeight(),new int[]{Color.RED, Color.WHITE, Color.BLUE}, null, LinearGradient.TileMode.CLAMP);
  7. paint.setShader(linearGradient);
  8. canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint);
  9. }

显示效果如下:

OK,两个小Demo让大家先感受下Shader,下面我继续变换的我的需求,如果我希望我的着色器的渲染位置变为从(0,0)到(getMeasuredWidth()/2, 0),那么这时候的渲染区域是什么呢?如下图:

OK,也就是说控件只有一半会被渲染,那么剩下的一半怎么办呢?这时候就得看我们的最后一个参数了,我们已经说过,LinearGradient.TileMode.CLAMP模式表示重复最后一种颜色直到该View结束的地方,也就是说从View宽度的1/2处直到View结束的地方都将是蓝色(因为View1/2处的颜色是蓝色),那么究竟是不是呢,我们看代码:

[java] view plain copy print?

  1. @Override
  2. protected void onDraw(Canvas canvas) {
  3. super.onDraw(canvas);
  4. Paint paint = new Paint();
  5. paint.setColor(Color.GREEN);
  6. LinearGradient linearGradient = new LinearGradient(0, 0, getMeasuredWidth()/2, 0,new int[]{Color.RED, Color.WHITE, Color.BLUE}, null, LinearGradient.TileMode.CLAMP);
  7. paint.setShader(linearGradient);
  8. canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint);
  9. }

再看效果图:

和我们想的一样,这就是LinearGradient.TileMode.CLAMP模式的特点。

2.LinearGradient.TileMode.REPEAT

LinearGradient.TileMode.REPEAT表示着色器在水平或者垂直方向上对控件进行重复着色,类似于windows系统桌面背景中的“平铺”,那么接下来我们来看看着色器对这种模式的处理方式,假如我希望着色器开始渲染的位置为(0,0),结束渲染的位置为(getMeasuredWidth()/2,

getMeasuredHeight()/2),但与之前不同的是这次的平铺方式变为LinearGradient.TileMode.REPEAT,我们来看看代码:

[java] view plain copy print?

  1. @Override
  2. protected void onDraw(Canvas canvas) {
  3. super.onDraw(canvas);
  4. Paint paint = new Paint();
  5. paint.setColor(Color.GREEN);
  6. LinearGradient linearGradient = new LinearGradient(0, 0, getMeasuredWidth()/2, getMeasuredHeight()/2,new int[]{Color.RED, Color.WHITE, Color.BLUE}, null, LinearGradient.TileMode.REPEAT);
  7. paint.setShader(linearGradient);
  8. canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint);
  9. }

效果图如下:

OK,沿着举行对角线,着色器对View进行了重复渲染,为了大家更好的理解LinearGradient.TileMode.REPEAT模式,这次我把我的需求该一下,我希望从(0,0)处开始渲染,到(0,
getMeasuredHeight()/2)处结束,这时系统会在垂直方向上重复渲染,代码如下:

[java] view plain copy print?

  1. @Override
  2. protected void onDraw(Canvas canvas) {
  3. super.onDraw(canvas);
  4. Paint paint = new Paint();
  5. paint.setColor(Color.GREEN);
  6. LinearGradient linearGradient = new LinearGradient(0, 0, 0, getMeasuredHeight()/2,new int[]{Color.RED, Color.WHITE, Color.BLUE}, null, LinearGradient.TileMode.REPEAT);
  7. paint.setShader(linearGradient);
  8. canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint);
  9. }

效果图如下:

OK,没问题,如我们所预料的那样。

3.LinearGradient.TileMode.MIRROR

LinearGradient.TileMode.MIRROR模式会在水平方向或者垂直方向上以镜像的方式进行渲染,这种渲染方式的一个特征就是具有翻转的效果,比如我希望我的着色器开始渲染的位置为(0,0),结束渲染的位置为(getMeasuredWidth()/2,
0),那么效果图是什么样子呢?我们先来看看代码:

[java] view plain copy print?

  1. @Override
  2. protected void onDraw(Canvas canvas) {
  3. super.onDraw(canvas);
  4. Paint paint = new Paint();
  5. paint.setColor(Color.GREEN);
  6. LinearGradient linearGradient = new LinearGradient(0, 0, getMeasuredWidth()/2, 0,new int[]{Color.RED, Color.WHITE, Color.BLUE}, null, LinearGradient.TileMode.MIRROR);
  7. paint.setShader(linearGradient);
  8. canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint);
  9. }

效果图如下:

OK,剩下的一部分依然被渲染,但是渲染的前后两部分是对称的,这就是LinearGradient.TileMode.MIRROR模式,很简单吧!

OK,以上就是LinearGradient的用法,有问题欢迎讨论。

时间: 2024-10-25 09:19:28

关于着色器LinearGradient的使用的相关文章

第4章:缓冲区、着色器、GLSL

原文链接: http://www.rastertek.com/gl40tut04.html Tutorial 4: Buffers, Shaders, and GLSL This tutorial will be the introduction to writing vertex and pixel shaders in OpenGL 4.0. It will also be the introduction to using vertex and index buffers in OpenG

游戏框架其九:网和着色器( Mesh and Shader )

网的重要作用可以导入3DMAX等创建的模型,到游戏中:着色器可以实现特定绚丽的效果.它们的实现如下 1. 网 Mesh的实现: #pragma once //======================================================================== // File: Mesh.h - classes to render meshes in D3D9 and D3D11 // 主要是导入3DMAX等软件生成的模型文件 基于Windows Dir

02 传递颜色给着色器

这一节介绍给着色器程序传值的方法.我们通过js把颜色传给着色器程序,来演示具体传值的方法. 顶点坐标.顶点颜色.uv坐标等都可以使用"矩阵"把值传给着色器程序.这个"矩阵"(其实只是个数组)只是我们假想的一个矩阵,它的每一行表示一个顶点,例如:顶点坐标几行就有几个顶点,每一行是坐标xyz值:顶点颜色"矩阵"中每一行是对应顶点的颜色的rgba值(红.绿.蓝.透明度). 它们在着色器程序中,都可以使用vec3.vec4(向量)类型变量接收.虽然他们表

GPU渲染管线与可编程着色器

本文由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/71978861 这篇文章是解析计算机图形学界"九阴真经总纲"一般存在的<Real-Time Rendering 3rd>系列文章的第三篇.将带来RTR3第三章内容"Chapter 3 The Graphics Processing Unit 图形处理器"的总结.概括与提炼. 这章的主要内容是介绍G

[Unity] Shader(着色器)输入输出和语义

在Unity5.x后, 已经支持了基于物理的光照模型,也就是常说的次时代引擎所必须具备的功能. 如果在Properties使用2D,CG里要用sampler2D,代表使用的是2维纹理 如果在Properties使用color, CG里要用fixed4 如果在Properties使用Range, CG里要用half,实际上描述的是一个float struct Input 用于描述UV坐标的结构体.在 Input 中, 变量名必须是 uv_ 开始, 变量名必须是官方文档中已经指定的名称(也就是说不可

(译)Minimal Shader(最小的着色器)

(原文:https://en.wikibooks.org/wiki/Cg_Programming/Unity/Minimal_Shader) This tutorial covers the basic steps to create a minimal Cg shader in Unity. 本节课包含了在Unity中创建一个最小的Cg着色器的基本步骤. Starting Unity and Creating a New Project(打开Unity创建一个新工程) After downlo

Unity3D ShaderLab 透明裁剪着色器

Unity3D ShaderLab 透明裁剪着色器 上一篇,我们介绍了使用Alpha实现透明的手法,其实Unity为我们的#pragma提供了另一种参数,是我们能做出更高效 简单的透明效果,也就是裁剪透明. 这种透明使用一个值来简单的控制某些特定的像素无需渲染到屏幕上,所以我们也可以通过他实现一个要么完全透明或完全不透的着色器. 我们即将利用灰度的值来控制材质的透明度. 准备工作还是新建Shader Material,一张灰度变化图.同样是分分钟完成的代码,请看完成: Shader "91YGa

WebGL 着色器语言(GLSL ES)

1.类型转换内置函数 转换/函数/描述 转换为整形数/int(float)/将浮点数的小数部分删去,转换为整形数(比如,将3.14转换为3) 转换为整形数/intl(bool)/true被转换为1,false被转换为0 转换为浮点数/float(int)/将整形数转换为浮点数(比如,将8转换为8.0) 转换为浮点数/float(bool)/true被转换为1.0,false被转换为0.0 转换为布尔值/bool(int)/0被转换为false,其他非0倍转换为true 转换为布尔值/0.0被转换

D3D三层Texture纹理经像素着色器实现渲染YUV420P

简单记录一下这两天用Texture实现渲染YUV420P的一些要点. 在视频播放的过程中,有的时候解码出来的数据是YUV420P的.表面(surface)通过设置参数是可以渲染YUV420P的,但Texture纹理似乎不支持直接渲染YUV420P.表面(surface)用法似乎比较单一,通常用来显示数据,用Texture的话就可以用上D3D的许多其他功能,做出一些效果.当然,这看个人需求,通常而言显示视频数据用表面就够了. 1.利用像素着色器把YUV420P数据转为RGB32 视频播放过程中帧与