绘制圆形的点

  • 1. demo效果
  • 2. 实现要点
    • 2.1 绘制原理
    • 2.1 绘制实现
  • 3. demo代码

1. demo效果


如上图,绘制出了三个红色的小圆点

2. 实现要点

2.1 绘制原理

我们已经知道在绘制图形时有一个光栅化的过程,在光栅化的过程中可以在片元着色器中通过内置变量 gl_FragCoord 来访问片元的坐标,实际上片元着色器还提供了另一个内置变量来获取当前片元在所属点内的坐标,它就是 gl_PointCoord ,归纳一下这两个变量

片元着色器内置变量(输入)

变量类型名称 描述
vec4 gl_FragCoord 片元的窗口坐标
vec4 gl_PointCoord 当前片元在所属点内的坐标(从0.0到1.0)


上图用来说明通过内置变量 gl_PointCoord 绘制圆点的原理,上图中的所有小方块表示当前绘制点所有片元,为了将这个点削成圆形,从图上得知,该点的正中心的坐标为(0.5,0.5),我们只要削掉以这点为圆心,半径大于0.5的片元,就可以绘制成成一个圆点

2.1 绘制实现

  • 计算片元距离所属点中心的距离
    首先定义圆的中心点vec2(0.5, 0.5),与内置变量gl_PointCoord计算距离,通过内置函数 distance() 实现
'  float d = distance(gl_PointCoord, vec2(0.5, 0.5));\n' + //计算像素距离中心点的距离
  • 根据距离大小(是否大于0.5)判断是否舍弃像素
    上一步中已经计算出了片元片元到圆心的距离,这里我们只需要判断这个距离是否大于0.5,如果大于0.5则使用 discard 语句舍弃当前片元
'  if(d < 0.5) {\n' + //距离大于0.5放弃片元,小于0.5保留片元
'    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +
'  } else { discard; }\n' +

3. demo代码

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title></title>
</head><body><!--通过canvas标签创建一个800px*800px大小的画布--><canvas id="webgl" width="800" height="800"></canvas><script type="text/javascript" src="./lib/cuon-matrix.js"></script><script>//顶点着色器var VSHADER_SOURCE = '' +'attribute vec4 a_Position;\n' + //声明attribute变量a_Position,用来存放顶点位置信息'void main(){\n' +'  gl_Position = a_Position;\n' + //将顶点坐标赋值给顶点着色器内置变量gl_Position'  gl_PointSize = 30.0;\n' + //设置顶点大小'}\n'//片元着色器var FSHADER_SOURCE = '' +'#ifdef GL_ES\n' +' precision mediump float;\n' + // 设置精度'#endif\n' +'varying vec4 v_Color;\n' + //声明varying变量v_Color,用来接收顶点着色器传送的片元颜色信息'void main(){\n' +'  float d = distance(gl_PointCoord, vec2(0.5, 0.5));\n' + //计算像素距离中心点的距离'  if(d < 0.5) {\n' + //距离大于0.5放弃片元,小于0.5保留片元'    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +'  } else { discard; }\n' +'}\n'//初始化着色器函数function initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE) {//创建顶点着色器对象var vertexShader = loadShader(gl, gl.VERTEX_SHADER, VSHADER_SOURCE)//创建片元着色器对象var fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, FSHADER_SOURCE)if (!vertexShader || !fragmentShader) {return null}//创建程序对象programvar program = gl.createProgram()if (!gl.createProgram()) {return null}//分配顶点着色器和片元着色器到programgl.attachShader(program, vertexShader)gl.attachShader(program, fragmentShader)//链接programgl.linkProgram(program)//检查程序对象是否连接成功var linked = gl.getProgramParameter(program, gl.LINK_STATUS)if (!linked) {var error = gl.getProgramInfoLog(program)console.log('程序对象连接失败: ' + error)gl.deleteProgram(program)gl.deleteShader(fragmentShader)gl.deleteShader(vertexShader)return null}//使用programgl.useProgram(program)gl.program = program//返回程序program对象return program}function loadShader(gl, type, source) {// 创建顶点着色器对象var shader = gl.createShader(type)if (shader == null) {console.log('创建着色器失败')return null}// 引入着色器源代码gl.shaderSource(shader, source)// 编译着色器gl.compileShader(shader)// 检查顶是否编译成功var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS)if (!compiled) {var error = gl.getShaderInfoLog(shader)console.log('编译着色器失败: ' + error)gl.deleteShader(shader)return null}return shader}function init() {//通过getElementById()方法获取canvas画布var canvas = document.getElementById('webgl')//通过方法getContext()获取WebGL上下文var gl = canvas.getContext('webgl')//初始化着色器if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {console.log('初始化着色器失败')return}// 设置canvas的背景色gl.clearColor(0.0, 0.0, 0.0, 1.0)//清空颜色缓冲区gl.clear(gl.COLOR_BUFFER_BIT)//初始化顶点坐标和顶点颜色var n = initVertexBuffers(gl)//绘制点gl.drawArrays(gl.POINTS, 0, n)}//初始化顶点坐标和顶点颜色function initVertexBuffers(gl) {//顶点var vertices = new Float32Array([0, 0.5, -0.5, -0.5, 0.5, -0.5])var n = 3//创建缓冲区对象var buffer = gl.createBuffer()//将顶点坐标和顶点颜色信息写入缓冲区对象gl.bindBuffer(gl.ARRAY_BUFFER, buffer)gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)//获取顶点着色器attribute变量a_Position存储地址, 分配缓存并开启var a_Position = gl.getAttribLocation(gl.program, 'a_Position')gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0)gl.enableVertexAttribArray(a_Position)return n}init()</script>
</body></html>

WebGL入门(三十七)-绘制圆形的点相关推荐

  1. WebGL入门(三十九)-透明与不透明物体共存,绘制透明面和不透明面的立方体

    绘制透明面和不透明面的立方体 1. 绘制透明立方体 1.1 绘制透明立方体要点 1.2 绘制透明立方体demo效果 1.3 绘制透明立方体demo代码 1.4 开启隐藏面消除后 2. 透明与不透明共存 ...

  2. WebGL入门(三十五)-三维物体雾化效果,立方体雾化效果

    立方体雾化效果 1. demo效果 2.相关知识点 2.1 雾化相关概念 2.2 雾化因子计算 2.3 片元颜色计算 3.实现要点 3.1 计算顶点与视点的距离 3.2 计算雾化后片元颜色 3.3 计 ...

  3. WebGL入门(三十六)-HUD(平视显示器)实现

    HUD(平视显示器)实现 1. demo效果 2.实现要点 2.1 什么是HUD 2.2 HUD实现 2.2.1 准备画布 2.2.2 绘制三维图形 2.2.3 绘制HUD信息 3.demo代码 1. ...

  4. WebGL入门(三十四)-三维空间中鼠标控制物体旋转,用鼠标控制立方体的旋转

    用鼠标控制立方体的旋转 1. demo效果 2. 实现要点 2.1 注册鼠标事件 2.1.1 注册鼠标事件函数的声明 2.1.2 注册鼠标事件函数的调用 2.2 纹理图片加载 2.3 图形绘制 3. ...

  5. [WebGL入门]三,3D绘图的基础知识

    注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中如果有我的额外说明,我会加上[lufy:],另外,鄙人webgl研究还不够深入,一些专业词语,如果翻译有误,欢迎大家指 ...

  6. [Python从零到壹] 三十七.图像处理基础篇之图像融合处理和ROI区域绘制

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  7. WebGL(三)——学习Canvas及简单图形绘制

    WebGL(三)--学习Canvas及简单图形绘制 Canvas简介 canvas是HTML5新增的一个可以使用javascript脚本在其中绘制图像的HTML元素(容器),它可以用来制作图像.动画, ...

  8. 九宫怎么排列和使用_剪映零基础入门教程第三十七篇:一学就会系列之九宫格小程序配音...

    很多玩儿抖音的朋友都看过九宫格视频,但是并不是每个玩抖音的人都会制作这个九宫格视频,实际这个需要借助小工具来帮忙,而常用抖音的朋友们会对剪映更加熟悉一些,且九宫格视频在剪映内的制作方式则比较简单.那么 ...

  9. 深度学习入门(三十七)计算性能——硬件(TBC)

    深度学习入门(三十七)计算性能--硬件(CPU.GPU) 前言 计算性能--硬件(CPU.GPU) 课件 电脑 提升CPU利用率① 提升CPU利用率② CPU VS GPU 提升GPU利用率 CPU/ ...

最新文章

  1. 一文看尽目标检测:从YOLO v1到v3的进化之路
  2. 有bug!PyTorch在AMD CPU的计算机上卡死了
  3. C语言中的关键字详略
  4. 域创实业谋定功能性-农业大健康·万祥军:借创新引领潮流
  5. Linux内核设计第四周——扒开系统调用三层皮
  6. 【实践】美团到店综合业务场景下的知识图谱构建与应用实践.pdf(附下载链接)...
  7. 我用 Python 破解了同事的加密压缩包!
  8. 擷取 GridView 資料列的欄位值集合
  9. java带圈数字,小1,小2
  10. linux根目录下各子目录的作用
  11. 全面剖析泛微协同管理平台(e-cology)十大亮点
  12. win2008服务器系统玩红警,win8系统玩不了红色警戒2如何解决?win8系统玩不了红色警戒2解决方法...
  13. html表格中加背景,css表格怎么添加背景颜色?
  14. IDEA 使用 hibernate
  15. zlib库介绍四:zlib算法(LZ77、LZ78、霍夫曼编码、滑动窗口、Rabin-Karp算法、哈希链、I/O缓冲区)
  16. c语言实现数据写入存储地址,c语言中通过指针将数值赋值到制定内存地址
  17. 涉及到的数据安全技术包括哪些内容
  18. 决战Python之巅(一)
  19. WINDOWS XP开启telnet服务
  20. java弱化胖瘦客户端_Java架构师成长直通车百度云

热门文章

  1. Azure云服务保留IP
  2. 11.15中移在线面试
  3. 高效使用Mac桌面和窗口的技巧方法
  4. 知易行难与抓大放小 - 不止写给百度
  5. 已被macOS使用不能打开解决,iphone照片到移动硬盘
  6. 创建线程的几种方式?JSP的九大内置对象及作用分别是什么?servlet的生命周期及常用方法?转发和重定向区别?ajax书写方式及内部主要参数都有哪些
  7. 网络--- Nagle算法理解
  8. 儿童智能手表行业未老先衰:5亿家长被伪智能忽悠
  9. GBase 8c管理平台——3.管理控制平台GBase 8c AMT
  10. [Android开发] app在华为手机的应用市场和安装时候显示未兼容android7.0