通过几天的学习,对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. Windows7系统运行hadoop报Failed to locate the winutils binary in the hadoop binary path错误

    程序运行的过程中,报Failed to locate the winutils binary in the hadoop binary path  Java.io.IOException: Could ...

  2. CentOS7.0安装Nginx 1.10.0

    首先由于nginx的一些模块依赖一些lib库,所以在安装nginx之前,必须先安装这些lib库,这些依赖库主要有g++.gcc.openssl-devel.pcre-devel和zlib-devel ...

  3. JDBC连接数据库(二)

    原文地址https://blog.csdn.net/jq_ak47/article/details/55049639 Mysql for java 的JDBC 驱动库安装 1.将下载下来的5.1.40 ...

  4. 非线性方程(组):一维非线性方程(二)插值迭代方法 [MATLAB]

    一般而言,方程没有能够普遍求解的silver bullet,但是有几类方程的求解方法已经非常清晰确凿了,比如线性方程.二次方程或一次分式.一次方程可以直接通过四则运算反解出答案,二次方程的求根公式也给 ...

  5. Python tricks(1) -- 动态定义一个新变量

    python是动态语言, 无需声明变量即可使用. 传递一个tuple, list或者dict等等方式, 有时候这种方式的使用不是很好. 对于tuple和list来说都是用下标的访问方式(即使用[]), ...

  6. “System.Runtime.InteropServices.COMException (0x80070422): 无法启动服务”解决方法

    应用程序中发生了无法处理的异常.如果单击“退出”,应用程序将立即关闭.无法启动服务,原因可能是已被禁用或其相关联设备没有启动.(异常来自HRESULT:0X80070422).点击详细内容:有关调用实 ...

  7. VMware Vcenter Server 6.0忘记密码

    windows 版Vcenter6.0 重置密码首先要登录到安装Vcenter的windows服务器上 用管理员身份打开CMD命令行 进入VMware VCenter的目录 默认是C:\Program ...

  8. Coursera SDN M1.2.1 SDN History: Programmable Networks 2

    NOTE Capsules Example 1.Type Field: excute forwarding routine => carry program 2.Previous address ...

  9. SDN前瞻 软件定义网络的一些概念

    SDN的核心:可编程性 SDN的思想:SOA面向服务 面向服务的体系结构(service-oriented architecture SOA) 使网络连接的大量计算机易于合作,以 服务 而不是人工交互 ...

  10. P4factory ReadMe Quickstart 安装p4factory

    操作系统: Ubuntu 14.04 前言 在之前,我直接从P4.org给的GitHub网址上下载了p4factory,但是在根据ReadMe的内容进行QuickStart的时候,发生了shell脚本 ...