通过几天的学习,对openGL、shader有了一个大致的了解。

回到学习的初衷吧,在基于pixi.js重构D3项目的时候,因为精灵层级的问题,我得按照一定的先后顺序将不同类别的精灵添加到场景中去。

例如:

针对人物关系的关系图谱,所有的关系线必须要在所有的任务面板下面,但是移动人物面板的时候,与之关联的关系线也要重新绘制;

所以删除精灵之后再添加精灵使得层级增加的做法就有点不适用了(这会导致当前操作的关系线的层级提升,很显然,这不是我们所想要的)。

因此,我们每次操作,都要重新将所有的精灵(处理好新的位置之后),分批次添加到场景中,这就导致出现下面的代码:

人物面板是一类精灵,关系线又是一类精灵,所以我们要用到两个for循环,并且顺序还得讲究(先for循环关系线,再for循环人物面板);

这样一来,如果页面中有10000个人物面板(相对应的就有10000条关系线),那么就要for循环10000+10000=20000次,针对拖拽操作,每触发一次移动就要for循环20000次,

经过测试,由于精灵数组是存于内存中的,for循环的时候很方便,但是对CPU的消耗很高!

当时,遇到这个问题的时候,朋友说可以将这部分的for循环也让GPU去执行,然后就看到了shader,进而学习了openGL;

学完之后,发现着色器程序的渲染模式可以用四个字概括:逐点绘制。确实解决了在CPU上执行for循环的问题。但是一个错综复杂的人物关系图谱,要用着色器去绘制的话(咱先不讨论shader加载纹理的问题),是不是就失去了使用pixi.js的意义,而且这也将使得开发工作变得更加复杂。

所以,我决定,鉴于关系图谱项目的特殊性,使用依次for循环的方式来处理精灵层级的问题。

分析完问题之后,我们还是要看看,在pixi中如何使用我们自定义的着色器程序。

一、pixi_shaders

百度云链接:https://pan.baidu.com/s/16m2BX5qKXr5Wm-J-68eXGA

提取码:j5t9

效果图:

3个iframe,3个片元着色器效果。

二、着色器代码分析

第三个iframe对应的shader,效果是颜色不断变化

let width = window.innerWidth;
let height = window.innerHeight; let app = new PIXI.Application(width, height);
document.body.appendChild(app.view); let shaderFrag = `
precision mediump float;
uniform vec3 iResolution;
uniform float iTime; void main() { // Normalized pixel coordinates (from 0 to 1)
vec2 uv = gl_FragCoord.xy/iResolution.xy; // Time varying pixel color
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(,,)); // Output to screen
gl_FragColor = vec4(col,1.0); }
`; let container = new PIXI.Container();
container.filterArea = app.screen;
app.stage.addChild(container); let filter = new PIXI.Filter(null, shaderFrag);
filter.uniforms.iResolution = [width, height, 1.0];
filter.uniforms.iTime = 1.0;
container.filters = [filter]; // Animate the filter
app.ticker.add(function(delta) {
filter.uniforms.iTime += 0.1;
});

前面我们谈到,着色器的渲染模式是逐点绘制,所以我们只要定义任意一点绘制方式就可以了,因为他会自动将我们的着色器代码应用到指定区域内的每个像素点上。

绘制方式,这个概念有点抽象了,实际上就是颜色,每个像素点的颜色!!!

我们来看上面的着色器代码:

let shaderFrag = `
precision mediump float;
uniform vec3 iResolution;
uniform float iTime; void main() { // Normalized pixel coordinates (from 0 to 1)
vec2 uv = gl_FragCoord.xy/iResolution.xy; // Time varying pixel color
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(,,)); // Output to screen
gl_FragColor = vec4(col,1.0); }
`;

这个着色器接收由外面传入的两个参数:三维坐标iResolution和随着时间递增的时间参数iTime;

let filter = new PIXI.Filter(null, shaderFrag);
filter.uniforms.iResolution = [width, height, 1.0];
filter.uniforms.iTime = 1.0;
container.filters = [filter];

然后着色器程序先将坐标进行转换(转换为pixi适用的坐标),

然后根据转换后的坐标(向量)和时间参数计算出三维颜色(RGB),着色器程序输出的颜色常量gl_FragColor是四维向量(RGBA),所以我们人为地给他加上alpha通道值。

这样一来,单个像素点输出的颜色就确定了,然后逐点绘制,屏幕上所有的点的颜色就渲染出来了。

此外,加上一个pixi的动画,通过改变iTime参数的值,实现改变单个像素点输出的颜色值,这样,我们看上去就是颜色不断变化的屏幕了。

app.ticker.add(function(delta) {
filter.uniforms.iTime += 0.1;
});

在pixi中使用你的自定义着色器的更多相关文章

  1. cocos源码分析--用Sprite加载自定义着色器

    本文写一个使用动态更新属性变量的自定义着色器.在这个例子中,小图标的位置根据手指的触摸而移动,以屏幕重点为参照物,屏幕中向下的部分根据手指的点击乘以一个绿色的颜色值,向上的部分乘以一个红色的颜色值. ...

  2. flask中的endpoint、自定义转化器、与djnago中session区别、利用装饰器实现登录认证

    flask路由中的endpoint 与自定义转化器 ''' endpoint主要用于 反向解析, 例如:login函数中配的路由是/login,其中endpoint='lg' 则在其他函数,可以用 u ...

  3. 【Cesium 颜狗初步】fabric 材质定义与自定义着色器实践

    fabric 材质定义:着色器实践 1. 示例代码 贴到沙盒里就可以运行: var viewer = new Cesium.Viewer("cesiumContainer"); v ...

  4. GDC2017【神秘海域 4】中所使用的顶点着色器技术

    原文链接 http://game.watch.impress.co.jp/docs/news/1047802.html   会場:San Francisco Moscone Convention Ce ...

  5. Flask系列09--Flask中WTForms插件,及自定义验证器

    一.概述 django中的forms组件非常的方便,在flask中有WTForms的组件实现的也是类似的功能, 安装这个插件 二.简单使用 文档地址https://wtforms.readthedoc ...

  6. Swift中使用MPMoviePlayerController实现自定义视频播放器界面

    默认情况下播放器自带各种控制按钮,比如前进后退播放暂停等: var url = NSBundle.mainBundle().URLForResource("1", withExte ...

  7. 使用着色器在WebGL3D场景中呈现行星表面地形

    实验目的:按照一定规律生成类地行星地表地形区块,并用合理的方式将地形块显示出来 涉及知识:Babylon.js引擎应用.着色器编程.正态分布.数据处理.canvas像素操作 github地址:http ...

  8. three中的着色器示例

    其实在3D引擎/库的帮助下,我们做webgl开发的难度已经很大大地降低了,熟悉相关API的话,开发一个简单的3D程序可以说是很轻松的事情. 在我看来,webgl的核心就是着色器(顶点着色器.片元着色器 ...

  9. JavaEE开发之SpringMVC中的自定义拦截器及异常处理

    上篇博客我们聊了<JavaEE开发之SpringMVC中的路由配置及参数传递详解>,本篇博客我们就聊一下自定义拦截器的实现.以及使用ModelAndView对象将Controller的值加 ...

随机推荐

  1. unittest框架(一)用例管理

    在unittest框架的自动化接口测试中,可以用yaml文件来管理用例,这样一方面,不会像excel管理用例那么死板:另一方面,数据读取出来就是一个字典,便于取值,用起来更灵活. 首先,需要安装一个模 ...

  2. Spring boot 开发WebService遇到的问题之一

    当pom.xml文件中的配置: <artifactId>spring-boot-starter-parent</artifactId><version>2.0.6. ...

  3. SpringMVC中@pathVariable和@RequestParam注解的区别

    @pathVariable和@RequestParam的区别 @pathVariable:是从路径中获取变量,也就是把路径当做变量 @RequestParam:是从请求里面获取参数 案例分析: /Sp ...

  4. GPS数据解析

    1.摘要 GPS模块使用串口通信,那么它的的数据处理本质上还是串口通信处理,只是GPS模块的输出的有其特定的格式,需要字符串处理逻辑来解析其含义.如何高效的处理从GPS模块接收到的数据帧,是GPS驱动 ...

  5. HeyWeGo第四周项目总结

    HeyWeGo第四周项目总结 项目内容 使用java程序开发一款扫雷游戏 游戏项目规划: 确定游戏中方块格子的个数 确定游戏中地雷的个数(初始10个),完成布雷 计算每个方块周围的雷数,在方块周围本身 ...

  6. 使用Xshell连接Ubuntu详解

    Xshell是一个安全终端模拟软件,可以进行远程登录.我使用XShell的主要目的是在Windows环境下登录Linux终端,传输一些大文件到Linux环境上去. 1.下载安装xshell客户端,在安 ...

  7. springboot属性类自动加载配置文件中的值

    springboot属性类自动加载配置文件中的值,如Person类加载在yml中配置的name,age等属性值,可以通过如下步骤获取: 类上添加@ConfigurationProperties注解,p ...

  8. BootStrap iCheck插件全选与获取value值的解决方法

    这篇文章主要介绍了BootStrap iCheck插件全选与获取value值的解决方法,解决方法其实很简单,下面小编给大家分享下这方面的知识 在使用jQuery iCheck 插件的时候遇到了一个问题 ...

  9. 简单购物车的实现,session的使用

    购物车浏览商品界面代码<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:// ...

  10. Ubuntu16 nginx安装http_image_filter_module模块

    目录 配置image_filter 配置 重启nginx 如何安装呢? 安装image_filter模块依赖的库. 查看之前的配置 添加上图片模块[由于它是系统模块,不需要额外下载,直接添加就可以了] ...