通过几天的学习,对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. 9.python的列表

    list2 = [1, 2, 3, 4, 5, 6, 7 ]; print ("list2[1:5]: ", list2[1:5]) 得到 list2[1:5]:  [2, 3, ...

  2. 分布式版本管理git学习资料整理推荐

    一.什么是git? Git is a free and open source distributed version control system designed to handle everyt ...

  3. Sparsity稀疏编码(三)

    稀疏编码(sparse coding)和低秩矩阵(low rank)的区别        上两个小结介绍了稀疏编码的生命科学解释,也给出一些稀疏编码模型的原型(比如LASSO),稀疏编码之前的探讨文章 ...

  4. python3 os.walk()使用

    os.walk() 方法用于通过在目录树种游走输出在目录中的文件名,向上或者向下. 在Unix,Windows中有效. os.walk(top[, topdown=True[, onerror=Non ...

  5. fedora修改主目录文件名为英文

           在gnome-terminal里面能够显示中文的,但是在文本终端里面中文都是不能显示的,是一个小小的正方形.因此可以只把主目录文件名换成英文的,方便文本终端命令输入,而其他的一些地方还是 ...

  6. Python: 字符串中嵌入变量

    问题:想创建一个内嵌变量的字符串,变量被它的值替换掉 解决方案: ①Python并没有对在字符串中简单替换变量值提供直接的支持,但是通过字符串的format()方法来解决这个问题 ②如果要被替换的变量 ...

  7. 常用技巧之JS判断数组中某元素出现次数

    先上代码:function arrCheck(arr){  var newArr = [];  for(var i=0;i<arr.length;i++){    var temp=arr[i] ...

  8. 微信小程序:WXSS 样式

    微信小程序:WXSS 样式 一.WXSS 样式 XSS 具有 CSS 大部分的特性,小程序在 WXSS 也做了一些扩充和修改. 1,新增了尺寸单位: 在写 CSS 样式时,开发者需要考虑到手机设备的屏 ...

  9. Sublime Text3编辑器简介

    Sublime Text3编辑器简介 下载地址 绿色中文版v3.3038下载地址:http://www.cncrk.com/downinfo/60832.html 官方网址(英文安装版)下载地址:ht ...

  10. myeclipse删除项目后重新导入

    今天安装了myeclipse2017版,刚开始导入项目后然后删除了,发现再次导入进来的时候不可以了. 解决方法:点击file -- >switch workspace -- >other ...