通过几天的学习,对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. mongodb 的使用

    install: 1.ubuntu用deb安装. 2.下载压缩文件,绿色的,不用安装.   推荐此方法. 配置dbpath: 1.用deb安装的,会在 /etc 目录下 创建mongodb.conf ...

  2. (转)JSON Web Token - 在Web应用间安全地传递信息

    JSON Web Token(JWT)是一个非常轻巧的规范.这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息. 让我们来假想一下一个场景.在A用户关注了B用户的时候,系统发邮件给B用户, ...

  3. 1124 Raffle for Weibo Followers[简单]

    1124 Raffle for Weibo Followers(20 分) John got a full mark on PAT. He was so happy that he decided t ...

  4. PAT 1105 Spiral Matrix[模拟][螺旋矩阵][难]

    1105 Spiral Matrix(25 分) This time your job is to fill a sequence of N positive integers into a spir ...

  5. C# 多线程编程第二步——线程同步与线程安全

    上一篇博客学习了如何简单的使用多线程.其实普通的多线程确实很简单,但是一个安全的高效的多线程却不那么简单.所以很多时候不正确的使用多线程反倒会影响程序的性能. 下面先看一个例子 : class Pro ...

  6. 系统管理命令之last

    Linux系统中使用以下命令来查看文件的内容: cat  由第一行开始显示文件内容 tac  从最后一行开始显示,可以看出 tac 是 cat 的倒著写! nl   显示的时候,顺道输出行号! mor ...

  7. http之响应报文response

    一般情况下,服务器接收并处理客户端发过来的请求后会返回一个HTTP的响应消息. HTTP响应也由四个部分组成,分别是:状态行.消息报头.空行和响应正文. http响应消息格式.jpg 例子 HTTP/ ...

  8. Python:导入numpy报错 No module named numpy

    Numpy是python的一种开源的数值计算扩展.这种工具可用来存储和处理大型矩阵,比python自身的嵌套列表结构要高效的多.但是在使用numpy时可能会出错(如上图). 解决办法:下载安装对应版本 ...

  9. 一次频繁Full GC问题排查过程分享

    问题描述 应用收到频繁Full GC告警 问题排查 登录到对应机器上去,查看GC日志,发现YGC一分钟已经达到了15次,比Full GC还要频繁一些,其中Full GC平均10分钟超过了4次,如下图 ...

  10. PhpStorm提高效率的使用方法及设置(快捷键)

    原文链接:https://my.oschina.net/chunto/blog/262954 快捷键: CTRL + D  复制当前行到下一行 或 复制选中内容到选中内容之后 CTRL + Y  删除 ...