webgl-画任意多边形
Posted 不穿铠甲的穿山甲
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webgl-画任意多边形相关的知识,希望对你有一定的参考价值。
注意:
let canvas = document.getElementById('webgl')
canvas.width = window.innerWidth
canvas.height = window.innerHeight
let radio = window.innerWidth/window.innerHeight;
let ctx = canvas.getContext('webgl')
由于屏幕长宽像素不一样,导致了长宽像素比不是1,进而导致每个像素四边形不是正方形,画出来的图形有误差
需要let radio = window.innerWidth/window.innerHeight;计算
关键代码
for (let index = 0; index < n; index++)
let angle = Math.PI*2/n * index;
let x = 0.5 * Math.cos(angle)/radio //解决像素比不是1的问题,导致画出的图形与预期不一致,如画圆可能画出来的时椭圆
let y = 0.5 * Math.sin(angle)
vertexs.push(x, y, (Math.random() -0.5) * 2, (Math.random() -0.5) * 2, (Math.random() -0.5) * 2)
控制多边形
let n = 3;
<!DOCTYPE html>
<head>
<style>
*
margin: 0px;
padding: 0px;
</style>
</head>
<body>
<canvas id = 'webgl'>
您的浏览器不支持HTML5,请更换浏览器
</canvas>
<script src="./main.js"></script>
</body>
main.js
let canvas = document.getElementById('webgl')
canvas.width = window.innerWidth
canvas.height = window.innerHeight
let radio = window.innerWidth/window.innerHeight;
let ctx = canvas.getContext('webgl')
//创建顶点资源和像素资源(颜色)
let vertexSource = `
attribute vec2 a_Position;
attribute vec3 a_Position_color;
varying vec3 a_color;
void main()
a_color = a_Position_color;
gl_Position = vec4(a_Position, 0.0, 1.0);
gl_PointSize = 10.0;
`
let fragmentSource = `
precision mediump float;
uniform vec3 u_color;
varying vec3 a_color;
void main ()
gl_FragColor = vec4(a_color, 1.0);
`
if (initShader(ctx, vertexSource, fragmentSource))
//设置颜色
let color = ctx.getUniformLocation(ctx.program, "u_color2")
ctx.uniform3f(color, 1.0, 0.0, 0.0)
//画三角形
let vertexs = []
let n = 3;
for (let index = 0; index < n; index++)
let angle = Math.PI*2/n * index;
let x = 0.5 * Math.cos(angle)/radio
let y = 0.5 * Math.sin(angle)
vertexs.push(x, y, (Math.random() -0.5) * 2, (Math.random() -0.5) * 2, (Math.random() -0.5) * 2)
// //画三角形
// let vertexs = [
// // x y R G B
// -0.5, 0.5, 1.0, 0.0, 0.0, //第一个点的信息
// -0.5, -0.5, 0.0, 1.0, 0.0, //第二个点的信息
// 0.5, -0.5, 0.0, 0.0, 1.0,//第三个点的信息
// 0.5, 0.5, 1.0, 1.0, 1.0 //第三个点的信息
// ]
let float32Array = new Float32Array(vertexs)
//创建buffer
let buffer = ctx.createBuffer()
//绑定buffer
ctx.bindBuffer(ctx.ARRAY_BUFFER, buffer)
//往buffer中填充值,并指定数据用途
ctx.bufferData(ctx.ARRAY_BUFFER, float32Array, ctx.STATIC_DRAW)
//获取vertexShader指定变量内存
let a_Position = ctx.getAttribLocation(ctx.program, "a_Position")
//指定每两个数组元素为一个点
/*
* 当数组元素不需进行分割拆分的时候最后两位可以指定为0,0
*
*
*/
ctx.vertexAttribPointer(
a_Position, //location: vertex Shader里面的attributes变量的location
2, ctx.FLOAT, //size: attribute变量的长度 vec2长度2 vec3长度3
false, //normalized: 正交化 true或false , [1, 2] => [1/根号5, 2/根号5]
5 * float32Array.BYTES_PER_ELEMENT, //stride: 每个点的信息所占的BYTES
0 //offset: 每个点的信息,从第几个BYTES开始数
)
ctx.enableVertexAttribArray(a_Position);
//获取vertexShader指定变量内存
let a_Position_color = ctx.getAttribLocation(ctx.program, "a_Position_color")
ctx.vertexAttribPointer(
a_Position_color, //location: vertex Shader里面的attributes变量的location
3, ctx.FLOAT, //size: attribute变量的长度 vec2长度2 vec3长度3
false, //normalized: 正交化 true或false , [1, 2] => [1/根号5, 2/根号5]
5 * float32Array.BYTES_PER_ELEMENT, //stride: 每个点的信息所占的BYTES
2 * float32Array.BYTES_PER_ELEMENT //offset: 每个点的信息,从第几个BYTES开始数
)
//确认吧带有数据的buffer赋值给a_Position
ctx.enableVertexAttribArray(a_Position_color);
ctx.drawArrays(ctx.TRIANGLE_FAN, 0, n)
//创建顶点阴影和像素阴影
function createShader(ctx, type, source)
//创建shader
let shader = ctx.createShader(type)
//绑定
ctx.shaderSource(shader, source)
//编译shader
ctx.compileShader(shader)
//获取编译结果
let compiler = ctx.getShaderParameter(shader, ctx.COMPILE_STATUS)
if (compiler)
return shader
else
let log = ctx.getShaderInfoLog(shader)
console.log("compile shaders error", log)
//删除异常的shader,防止内存泄露
ctx.deleteShader(shader)
return null
function createProgram(ctx, vertexShader, fragmentShader)
//创建program
let program = ctx.createProgram()
if (!program)
return null
//点资源和像素资源合并
ctx.attachShader(program, vertexShader)
ctx.attachShader(program, fragmentShader)
ctx.linkProgram(program)
//获取linked的结果
let linked = ctx.getProgramParameter(program, ctx.LINK_STATUS)
if (linked)
return program
else
//获取link错误信息
let log = ctx.getProgramInfoLog(program)
console.log("link program error", log)
//删除防止内存泄漏
ctx.delete(program)
ctx.deleteShader(vertexShader)
ctx.deleteShader(fragmentShader)
return null
function initShader(ctx, vertexSource, fragmentSource)
let vertexShader = createShader(ctx, ctx.VERTEX_SHADER, vertexSource)
let fragmentShader = createShader(ctx, ctx.FRAGMENT_SHADER, fragmentSource)
let program = createProgram(ctx, vertexShader, fragmentShader)
if (program)
ctx.useProgram(program)
//挂载到ctx
ctx.program = program
return true
else
return false
效果
n=3
n=4
n=6
n=50
WebGL学习系列-WebGL简介
前言
本篇简要介绍一下WebGL的历史以及用途。
WebGL概述
相信大家都知道Web中有个叫canvas的画布,通过其提供的一些API,我们可以很方便的在浏览器的页面上画点、线、多边形、图片等。现在很多的html5小游戏也是由canvas来实现的。canvas技术相当于所见即所得,你画什么就在页面上展示什么,原理比较好懂。但是canvas主要是针对2D的,所以通常我们主要用于实现2D类的游戏。
要说WebGL,得提提OpenGL。OpenGL是一套开放的图形库,用于在pc端上绘制3D图形,它是一套开放的标准API,在不同平台上底层有不同的实现。可以把WebGL看成是Web端的OpenGL。先来看下OpenGL的版本图,如下所示:
可以看到,目前Web端使用的WebGL为WebGL1.0,它是基于OpenGL ES2.0的, 而
OpenGL ES主要服务于一些嵌入式设备。可以说,我们将要学习的WebGL和OpenGL ES2.0是比较像的,至少很多原理都是共通的。所以有时候,当你遇到WebGL一些问题的时候,可以尝试通过OpenGL关键字去查找相关的资料。
OpenGL从2.0开始便支持可编程着色器,着色器通俗的说,就是给界面中的每一个像素上色,这个很快就会了解到了。自然的,WebGL也继承了这个重大的特性。
最后,再来看下WebGL程序的结构,先看下图:
左边为传统的web页面开发,右边为包含了WebGL的网页,GLSL ES是用于编写着色器的语言,开发WebGL程序的时候,除了直接调用WebGL相关的api,我们还要编写着色器。
结束语
借由WebGL,我们可以打开通往3D的一个切入点,因为学习WebGL是需要学习计算机图形学一些基础知识的,当然,这里不会假设你懂的很多。笔者也是在学习过程中一点一点弥补的。笔者水平有限,但仍然会尝试使用最最简单的语言来进行表述,这也是自我提升的一种方式。
参考资料:
<<WebGL编程指南>>
以上是关于webgl-画任意多边形的主要内容,如果未能解决你的问题,请参考以下文章