WebGL之通过外部传入a_PontSize值改变点着色器vshader内置变量gl_PointSize的值
最近分配到一个看起来非常简单的优化需求、通过地图上设置工具来改变地图上显示的点的大小和透明度。无非过程就是从控件面板获取到用户设置的值保存到数据库中、然后地图上画点的时候取出设置的值渲染出点即可。前端绘制图形无非canvas、这个方面我之前也是不怎么涉及的部分、所以趁这次分配的任务比较轻时间相对宽裕的情况下、可谓是好好学了一把WebGL的内容。通过一个星期的查找学习、总算有了比较清晰的理解、足以好好理解代码了。
俗话说、工欲善其事必先利其器、我这次可是深刻体会了一把。一开始觉得好像蛮容易的、后来怎么也搞不到一起才静下心来认认真真看了webGL的内容、比较不好理解、反正我对着代码翻来覆去看了四五六七遍以上吧、才终于理解了代码执行的逻辑顺序。
学习准备:
WebGL教程: http://www.yanhuangxueyuan.com/WebGL_course.html (推荐、跟着里面说明的方法来学习理解)
W3C关于WebGL的基础学习 (动手前最好看明白的基础理论学习) https://www.w3cschool.cn/webgl/157h1oh3.html
WebGL入门教程(一)-初识webgl (可以跟着搞起来的实例教程) http://www.cnblogs.com/bsman/p/6128447.html
从OpenGL传颜色数值到Shader,改变绘图颜色(看了这篇才找到答案的) http://blog.csdn.net/huutu/article/details/21460835
WebGL基础(辅助理解) https://www.cnblogs.com/mazhenyu/p/3804518.html
开始解题:
1.大体的思路如下图、代码有省略

其实图上看明白了题已经解了、屡一下思路、WebGL先要声明点着色器和片着色器、然后放在program上建立起来、在建立好program后我们定义一个变量gl.aPointSize,将点着色器的一个属性值a_pointSize赋值给这个变量gl.aPointSize,然后我们根据实际项目需求通过控制这个gl.aPointSize进而改变点着色器中内部变量gl_PointSize。就这么简单,主要是看明白webGL每一个语句的用法,就容易做了。
2.代码参考
①在main.aspx中声明点着色器
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Ext5.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Import Namespace="F5WS.Web" %> <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server"> <script type="text/javascript">var tinyItems = <%= ViewData["TinyItems"] %></script>
<script id="vshader" type="x-shader/x-vertex">
uniform mat4 u_matrix;
attribute vec4 a_vertex;
attribute float a_pointSize;
attribute vec4 a_color;
varying vec4 v_color; void main() {
// Set the size of the point
// a_pointSize; gl_PointSize = a_pointSize; // multiply each vertex by a matrix.
gl_Position = u_matrix * a_vertex; // pass the color to the fragment shader
v_color = a_color;
}
</script>
<!-- fragment shader --> <!-- vec4 color1 = vec4(v_color[], v_color[], v_color[], 0.6);调整透明度在这里 -->
<script id="fshader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 v_color;
uniform sampler2D uSampler;
void main() { float border = 0.1;
float radius = 0.5;
vec4 color0 = vec4(0.0, 0.0, 0.0, 0.0);
// 最后一个参数为 透明度设定
vec4 color1 = vec4(v_color[], v_color[], v_color[], v_color[]); vec2 m = gl_PointCoord.xy - vec2(0.5, 0.5);
float dist = radius - sqrt(m.x * m.x + m.y * m.y); float t = 0.0;
if (dist > border)
t = 1.0;
else if (dist > 0.0)
t = dist / border; // float centerDist = length(gl_PointCoord - 0.5);
// works for overlapping circles if blending is enabled gl_FragColor = mix(color0, color1, t); } </script> </script>
</asp:Content>
main.aspx
②在CanvasOverlayGL.js中使用、截取了WebGL部分的代码、方便核对自己的代码理解
setWebGL: function () {
var me = this;
var gl = this._canvas.getContext('experimental-webgl', { antialias: true });
if (!gl) {
me._usingGL = false;
return;
}
me._gl = gl;
this._pixelsToWebGLMatrix = new Float32Array(16);
this._mapMatrix = new Float32Array(16);
// -- WebGl setup
if (!gl) return;
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
if (!document.getElementById('vshader')) return;
gl.shaderSource(vertexShader, document.getElementById('vshader').text);
gl.compileShader(vertexShader);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
if (!document.getElementById('fshader')) return;
gl.shaderSource(fragmentShader, document.getElementById('fshader').text);
gl.compileShader(fragmentShader);
// link shaders to create our program
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
gl.enable(gl.BLEND);
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
// look up the locations for the inputs to our shaders.
this._u_matLoc = gl.getUniformLocation(program, "u_matrix");
this._colorLoc = gl.getAttribLocation(program, "a_color");
this._vertLoc = gl.getAttribLocation(program, "a_vertex");
gl.aPointSize = gl.getAttribLocation(program, "a_pointSize");
// Set the matrix to some that makes 1 unit 1 pixel.
this._pixelsToWebGLMatrix.set([2 / this._canvas.width, 0, 0, 0, 0, -2 / this._canvas.height, 0, 0, 0, 0, 0, 0, -1, 1, 0, 1]);
gl.viewport(0, 0, this._canvas.width, this._canvas.height);
gl.uniformMatrix4fv(this._u_matLoc, false, this._pixelsToWebGLMatrix);
},
loadData: function (data, total) {
var me = this;
var gl = me._gl;
var usingGL = me._usingGL;
var verts = data; //你自己要渲染的数据
this._size = verts[2]; //我这里的verts[2] = -50
this._cSize = verts[7]; // 我这里的verts[7] = 5.0
this._numPoints = total;
if (usingGL) {
if (!this._buffer) {
var vertBuffer = gl.createBuffer();
this._buffer = vertBuffer;
gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
gl.enableVertexAttribArray(this._vertLoc);
gl.enableVertexAttribArray(this._colorLoc);
}
var vertArray = new Float32Array(verts);
var fsize = vertArray.BYTES_PER_ELEMENT;
gl.bufferData(gl.ARRAY_BUFFER, vertArray, gl.STATIC_DRAW);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, fsize * 7, 0);
// -- offset for color buffer
gl.vertexAttribPointer(this._colorLoc, 4, gl.FLOAT, false, fsize * 7, fsize * 3);
}
this.redraw();
},
drawingOnCanvas: function () {
if (this._gl == null) return;
var gl = this._gl;
gl.clear(gl.COLOR_BUFFER_BIT);
this._pixelsToWebGLMatrix.set([2 / this._canvas.width, 0, 0, 0, 0, -2 / this._canvas.height, 0, 0, 0, 0, 0, 0, -1, 1, 0, 1]);
//debugger;
var pointSize = 78271.5170 / Math.pow(2, this._map.getZoom() - 1);
var size = this._size;
if (size < 0.0) {
size = -size / pointSize;
if (size < 7.0) {
//size = 7.0;
size = this._cSize + 2 ; //我这里 this._cSize=5,我想设定点大小为7,所以+2了
}
}
// console.log(size);
gl.vertexAttrib1f(gl.aPointSize, size); //将size传给点着色器的gl.aPointSize,从而改变到点的大小了
// -- set base matrix to translate canvas pixel coordinates -> webgl coordinates
this._mapMatrix.set(this._pixelsToWebGLMatrix);
//debugger;
var bounds = this._map.getBounds();
var topLeft = new L.LatLng(bounds.getNorth(), bounds.getWest());
var newLatlng = this.offsetFn(topLeft.lat, topLeft.lng);
var offset = this.LatLongToPixelXY(topLeft.lat - newLatlng.lat + topLeft.lat, topLeft.lng - newLatlng.lng + topLeft.lng);
this._offset.x = offset.x;
this._offset.y = offset.y;
this._offset.topLeft = topLeft;
// -- Scale to current zoom
var scale = Math.pow(2, this._map.getZoom());
this.scaleMatrix(this._mapMatrix, scale, scale);
this.translateMatrix(this._mapMatrix, -offset.x, -offset.y);
// -- attach matrix value to 'mapMatrix' uniform in shader
gl.uniformMatrix4fv(this._u_matLoc, false, this._mapMatrix);
//debugger;
gl.drawArrays(gl.POINTS, 0, this._numPoints);
},
LatLongToPixelXY: function (latitude, longitude) {
var pi_180 = Math.PI / 180.0;
var pi_4 = Math.PI * 4;
var sinLatitude = Math.sin(latitude * pi_180);
var pixelY = (0.5 - Math.log((1 + sinLatitude) / (1 - sinLatitude)) / (pi_4)) * 256;
var pixelX = ((longitude + 180) / 360) * 256;
var pixel = { x: pixelX, y: pixelY };
return pixel;
},
translateMatrix: function (matrix, tx, ty) {
// translation is in last column of matrix
matrix[12] += matrix[0] * tx + matrix[4] * ty;
matrix[13] += matrix[1] * tx + matrix[5] * ty;
matrix[14] += matrix[2] * tx + matrix[6] * ty;
matrix[15] += matrix[3] * tx + matrix[7] * ty;
},
scaleMatrix: function (matrix, scaleX, scaleY) {
// scaling x and y, which is just scaling first two columns of matrix
matrix[0] *= scaleX;
matrix[1] *= scaleX;
matrix[2] *= scaleX;
matrix[3] *= scaleX;
matrix[4] *= scaleY;
matrix[5] *= scaleY;
matrix[6] *= scaleY;
matrix[7] *= scaleY;
},
CanvasOverlayGL.js
WebGL之通过外部传入a_PontSize值改变点着色器vshader内置变量gl_PointSize的值的更多相关文章
- 内置变量WEBGL
gl_FragCoord是片元着色器中的只读变量,它保存了片元相对窗口的坐标位置:x, y, z, 1/w.这个值是顶点处理产生片元后固定功能内插图元的结果.组件z是用于表示片元深度的深度值. gl_ ...
- awk内置变量 awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出了最常用的一些变量。
ARGC 命令行参数个数 ARGV 命令行参数排列 ENVIRON 支持队列中系统环境变量的使用 FILENAME awk浏览的文件名 FNR 浏览文件的记录数 FS 设置输入域分隔符,等价于命令行 ...
- 使用外部容器运行spring-boot项目:不使用spring-boot内置容器让spring-boot项目运行在外部tomcat容器中
前言:本项目基于maven构建 spring-boot项目可以快速构建web应用,其内置的tomcat容器也十分方便我们的测试运行: spring-boot项目需要部署在外部容器中的时候,spring ...
- WebGL 创建和初始化着色器过程
1.编译GLSL ES代码,创建和初始化着色器供WebGL使用.这些过程一般分为7个步骤: 创建着色器对象(gl.createBuffer()); 向着色器对象中填充着色器程序的源代码(gl.shad ...
- WebGL简易教程(二):向着色器传输数据
目录 1. 概述 2. 示例:绘制一个点(改进版) 1) attribute变量 2) uniform变量 3) varying变量 3. 结果 4. 参考 1. 概述 在上一篇教程<WebGL ...
- WebGL中的OpenGL着色器语言
在webgl中,调用了OpenGL-ES-2.0的API,而在OpenGL-ES专为嵌入式设备设计,其和其它设备一样,都是使用GLSL(GL Shading Language)来编写片段程序并执行于G ...
- Python第七天 函数 函数参数 函数里的变量 函数返回值 多类型传值 函数递归调用 匿名函数 内置函数
Python第七天 函数 函数参数 函数里的变量 函数返回值 多类型传值 函数递归调用 匿名函数 内置函数 目录 Pycharm使用技巧(转载) Python第一天 ...
- WebGL 着色器语言(GLSL ES)
1.类型转换内置函数 转换/函数/描述 转换为整形数/int(float)/将浮点数的小数部分删去,转换为整形数(比如,将3.14转换为3) 转换为整形数/intl(bool)/true被转换为1,f ...
- WebGL编程指南案例解析之多数据存储于一个缓冲区以及着色器通信
//顶点着色器往片元着色器传值 //多个参数值存于一个缓冲对象中 var vShader = ` attribute vec4 a_Position; attribute float a_PointS ...
随机推荐
- 【Python】 用户图形界面GUI wxpython IV 菜单&对话框
更多组件 ■ 菜单栏 Menu 菜单是很多GUI必不可少的一部分.要建立菜单,必须先创建菜单栏: menuBar = MenuBar() menu = Menu() item1 = menu.Appe ...
- 如何在IOS上调试Hybrid应用
最近在找关于在xcode上调试Hybrid应用的方法,比如我想进行断点调试.日志打印.屏幕适配等等,刻意去搜了下方法,虽然之前已经大致知道了,这里系统归纳一下,原文在https://developer ...
- [luogu1168]中位数_优先队列
中位数 题目大意:输出读入的前2*k+1个数的中位数.一共有n个数,按照读入顺序. 注释:$1\le n \le 10^9$. 想法:这是优先队列的一个应用qwq.我们弄两个堆.小根堆和大根堆,保证: ...
- mysqldump 备份脚本
#!/bin/bash DUMP=/usr/bin/mysqldump OUT_DIR=/home/mysql LINUX_USER=root DB_NAME=snale DB_USER=root D ...
- Jmeter-基于Ubuntu运行
这几天折腾了很久,整合了一套接口自动化的持续集成工具,先从最基础的运行Jmeter说起.由于我是用Docker部署的持续集成环境,所以接口运行必须在服务器上 一:在Linux服务器先安装jdk 1:先 ...
- 使用idea新建jsp
使用idea解决新建jsp文件而找不到jsp文件模版的新建选项,这样每次创建一个新的jsp文件岂不是很耗时间? 解决办法: 就是要让idea知道你需要在这个目录下创建jsp文件 左上角,file中点击 ...
- 软工实践项目需求分析(团队)修改版get√-黄紫仪
日常前言:随笔距离文档大体完成已经过去了2天+(因为中间插了一波结对作业),所以目测感受没有那时候清晰(那时候烦的想打人了都--)需求分析那边去百度找了模板.emmmm好多东西感觉听都没听说过QAQ, ...
- Scala Option类型
转载自: Scala 初学者指南, 这里有一系列很棒的文章 类型 Option 可能你已经见过它在 Map API 中的使用:在实现自己的提取器时,我们也用过它, 然而,它还需要更多的解释. 你可能会 ...
- RESTful三问
我觉得学习一个技术,其实就是要弄明白三件事情:是什么(what),为什么(why),怎么用(how).正是所谓的三W方法. 所以打算总结一个"三问"系列.为了自己学习,也分享给别人 ...
- NFC驱动调试
1.NFC基本概念: NFC 又称为近场通信,是一种新兴技术,可以在彼此靠近的情况下进行数据交换,是由非接触式射频识别(RFID) 及互连互通技术整合演变而来,通过单一芯片集成感应式读卡器: NFC有 ...