WebGL笔记:WebGL中绘制圆点,设定透明度,渲染动画

threejs 绘制球体_【webGl】threejs实现一个简单的动画-弹跳的小球 在这里,我们将动态画面简称为动画(animation)。正如动画片的原理一样,动画的本质是利用了人眼的视觉暂留特性,快速地变换画面,从而产生物体在运动的假象。而对于Three.js程序而言,动画的实现也是通过在每秒中多次重绘画面实现的。为了衡量画面切换速度,引入了每秒帧数FPS(Frames Per Second)的概念,是指每秒画面重绘的次数。FPS越大,则动画效果越平滑,当FPS小于20时,一... 阅读详情

WebGL 绘制圆点

  • 基于片元着色器来画圆形
  • 片元着色器在屏幕中画图是基于一个个的像素的
  • 每次画一个像素时,都会执行片元着色器中的main方法
  • 那么,我们就可以从这一堆片元中(n个像素点)找出属于圆形的部分
  • 片元的位置叫做 gl_PointCoord (一个点中片元的坐标位)
    • 比如,一个点的宽高都是1 , 片元的 x,y 位置在 0 - 1 之间
    • 点的中心点的坐标位置是(0.5, 0.5), 如果片元到中心的位置 小于 0.5
    • 那么可以认为这个片元是在圆内的,这样,只渲染圆内的片元,圆外的片元就不再渲染
  • 文档:
    • https://registry.khronos.org/OpenGL-Refpages/gl4/html/gl_PointCoord.xhtml
    • https://registry.khronos.org/OpenGL-Refpages/gl4/
<script id="fragmentShader" type="x-shader/x-fragment">
    precision mediump float;
    uniform vec4 u_FragColor;
    void main() {
        float dist = distance(gl_PointCoord, vec2(0.5, 0.5));
        if(dist < 0.5) {
            gl_FragColor = u_FragColor;
        } else {
            discard;
        }
    }
</script>
  • distance 是计算两个点之间距离的函数
  • discard 丢弃,即不会一个片元进行渲染
  • 其他参考上篇文章,来画出圆形

WebGL 中与CSS配合展示背景图

  • 在 css 中设置背景图
    #canvas {
        background: url("./bg.jpg");
        background-size: cover;
        background-position: right bottom;
    }
    
  • 在 js 刷底色的时候, 给一个透明色, 这样才能看见canvas的css背景
    gl.clearColor(0, 0, 0, 0);
    gl.clear(gl.COLOR_BUFFER_BIT);
    

WebGL中片元透明度的设定

  • 一般来说,绘制图形,让图形有一定的颜色,并且有一定的透明度,光是使用 uniform4fv 设置是不行的
  • 还需要做两件事:
    gl.enable(gl.BLEND); // 开启片元的颜色合成功能
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); // 设置片元的合成方式
    
  • 之后正常使用uniform4fv进行渲染即可
    
    const arr = new Float32Array([0.87, 0.91, 1, a]);
    gl.uniform4fv(u_FragColor, arr);
    

WebGL中设置图形的动画

  • 所谓的动画,就是一帧一帧的图像变化累计的结果,如果我们想要使用代码实现动画,还需要了解一下概念
    • 关键帧:可以说这是动画中的里程碑,连续两个关键帧之间,我们可以用数学来实现渐变
    • 时间轨:一次动画执行完成所需要的时间轨道,包含不同的关键帧,通过关键帧,对其中目标对象的状态进行插值计算
    • 补间动画:一个物体不同关键帧,即连续相邻的两个关键帧之间的状态进行差值运算,得到当前过渡时间的不同画面,来实现平滑过渡
    • 合成:不同物体所表示的多个时间轨的集合
  • 对动画进行封装
    • 框架层面,我们要针对合成对象做设计:画布上可能会有多个对象做动画运动
    • 运动层面,我们要对时间轨做计算:针对每个对象,在一个完整动画的时间轨上应如何补全关键帧之间的间隔渲染

1 )框架层面的设计

export default class Compose {
    constructor() {
        this.parent = null // 当前对象parent置空,这是一个编程习惯
        this.children = [] // 用于存储多个对象
    }
    add(obj) {
        obj.parent = this // 当前对象和当前工具建立关系
        this.children.push(obj) // 将当前对象加入子队列数组
    }
    // 这里是工具的update
    update(t) {
        // 内部调用每个对象的update方法实现动画
        this.children.forEach(ele => {
            ele.update(t)
        })
    }
}

2 )时间轨的设计

export default class Track {
    constructor(target) {
        this.target = target // 当前对象
        this.parent = null // 父对象,合成对象,默认为空
        this.start = 0 // 开始时间默认是0
        this.timeLen = 5 // 一个时间轨的长度,也就是完成一次完整动画所需要的时间,单位毫秒
        this.loop = false // 是否循环播放动画
        this.keyMap = new Map() // 关键帧的集合
    }
    // 当前对象的每一帧运动函数
    update(t) {
        const { keyMap, timeLen, target, loop } = this
        let time = t - this.start // 当前时间距离开始时间的时间长度
        // 如果开启循环,则加入取余操作,将当前时间循环递增,不让超过自身设定
        if(loop) {
            time = time % timeLen
        }
        for(const [key,fms] of keyMap.entries()) {
            const last = fms.length - 1 // 最后一项
            if(time < fms[0][0]) {
                // 在第一个关键帧之前的设置为第一个关键帧的状态
                target[key] = fms[0][1]
            } else if(time > fms[last][0]) {
                // 时间在最后一个关键帧之后设定为最后一个关键帧的状态
                target[key] = fms[last][1]
            } else {
                // 在各个中间态实行数学计算状态渐变,即:补间状态
                target[key] = getValBetweenFms(time, fms, last)
            }
        }
    }
}

// 补间状态计算函数
function getValBetweenFms(time,fms,last) {
    for(let i = 0; i < last; i++) {
        const fm1 = fms[i]
        const fm2 = fms[i+1]
        if(time >= fm1[0] && time <= fm2[0]) {
            const delta = {
                x: fm2[0] - fm1[0],
                y: fm2[1] - fm1[1],
            }
            const k = delta.y / delta.x
            const b = fm1[1] - fm1[0] * k
            return k * time + b
        }
    }
}
  • 上述 keyMap 关键帧集合,这里是一个对象的关键帧集合,结构如下,
    [
      [
        '对象属性1',
        [
          [时间1,属性值], //关键帧
          [时间2,属性值], //关键帧
        ]
      ],
      [
        '对象属性2',
        [
          [时间1,属性值], //关键帧
          [时间2,属性值], //关键帧
        ]
      ],
    ]
    
  • time 当前时间
  • fms 某个属性的关键帧集合
  • last 最后一个关键帧的索引位置
  • 其实现思路如下
    • 遍历所有关键帧
    • 判断当前时间在哪两个关键帧之间
    • 基于这两个关键帧的时间和状态,求点斜式
    • 基于点斜式求本地时间对应的状态
  • 这里 y = kx + b 这个公式是一般公式(推荐),还可以用其他曲线公式来处理动画

3 )应用

const compose = new Compose()
const stars = [] // 点数据的集合
canvas.addEventListener('click', function(event) {
    const { x, y } = getPosByMouse(event,canvas) // 获取当前坐标,这里具体实现可看之前博客代码,只是做了个函数封装
    const a = 1
    const s = Math.random() * 5 + 2
    const obj = { x, y, s, a } // x坐标,y坐标,s尺寸,a透明度
    stars.push(obj)

    const track = new Track(obj)
    track.start = new Date()
    track.keyMap = new Map([
        ['a', [
            [500, a],
            [1000, 0],
            [1500, a],
        ]]
    ])
    track.timeLen = 2000
    track.loop = true
    compose.add(track)
})

渲染方法如下,参考之前博客代码

function render(){
    gl.clear(gl.COLOR_BUFFER_BIT);
    stars.forEach(({x,y,s,a}) => {
        gl.vertexAttrib2f(a_Position,x,y);
        gl.vertexAttrib1f(a_PointSize,s);
        gl.uniform4fv(u_FragColor, new Float32Array([0.87,0.92,1, a]));
        gl.drawArrays(gl.POINTS, 0, 1);
    })
}

用请求动画帧驱动动画,连续更新数据,渲染视图

!(function ani() {
    compose.update(new Date())
    render()
    requestAnimationFrame(ani) // 重复执行
})()
OpenGL/WebGL用点绘制有立体感的小球 点默认绘制的是一个正方形,要想变成圆形,需要丢弃一部分像素。本文实现一个将网格绘制成一个个球形,并有一定的立体感特效,希望对大家有帮助。衰减因子可以自己根据距离等规则进行调整。 阅读详情

相关推荐

第六节 WebGL画球算法

学习交流欢迎加群:789723098,博主会将一些demo整理共享 很多学习WebGL的小伙伴,刚开始一直都是学怎么画立方体,等到立方体画的炉火纯青的时候,却被另一个东西难住了,那就是球。what,还会被一个球难住?下面就给大家介绍一种画球的算法: 我们的地球现在被划分为很多经线和纬线,如下图所示: 由下面的图,我们来推导一下计算球面上点的坐标: 假设图中圆的半径R=1...

Bruce_wjh的博客 6379

WebGL画圆的几种方式

需求: 看了一段时间WebGL,现在想画一个圆,方式应该有很多,我现在列出自己练习的几个 分析: WebGL只能画点、线、三角形,我现在要画一个圆,基本上就只能靠三角形模拟出来一个 下表的图形都是通过三角形来构造的“正多边形”几何体 发现只要三角形数量足够多,“正多边形”会越来越倾向于“圆”。 6个三角形 15个三角形 36个三角形 具体实施方案: 1、顶点着色器中做文章 为了简要表达,会省略不重要的代码 1.1和1.2使用的绘画方式为 gl.dr

wzwxwc1987的专栏 2910

LightningChart JS散点图实战:百万级数据点WebGL高性能渲染指南

数据可视化场景中,散点图以最直观的方式呈现变量间的分布、相关性和离群点,但当数据量从几千增长到数十万甚至百万级时,传统基于SVG或Canvas 2D的JS图表库往往因CPU渲染瓶颈而出现卡顿、掉帧甚至浏览器无响应。WebGL作为浏览器内置的GPU图形接口,通过着色器并行处理海量顶点数据,为前端高性能可视化提供了新的解决路径。LightningChart正是基于这一底层技术构建的商业级图表库,它专为PointSeries等密集点数据场景设计,在保持60帧交互的同时可承载百万级坐标点,广泛应用于金融行情、物联网

weixin_31556767的博客 168

WebGL 绘制圆点

这篇文章不说WebGL相关概念了,初学者先到网上看看WebGL相关概念。这里着重写一下在vue3前端框架下,如何通过webGL绘制圆点。

liubangbo的专栏 3365

Canvas实现高性能网页雪景动画:从物理模拟到交互优化

前端动画是提升网页视觉体验和用户交互沉浸感的关键技术,其核心原理在于通过JavaScript控制DOM元素或Canvas绘图实现动态效果。在技术实现层面,Canvas 2D API因其高性能和灵活控制能力,成为实现复杂粒子系统的首选方案,尤其适合模拟自然现象如雨雪、火焰等。从技术价值看,优秀的动画不仅能增强页面表现力,还能通过交互反馈提升用户参与度,常见于节日活动页面、数据可视化、游戏等场景。本文聚焦于利用Canvas实现逼真的雪景动画,深入探讨雪花物理属性建模、动画循环优化以及鼠标交互等关键技术点,其中涉

weixin_34221073的博客 337

OpenLayers实战,WebGL图层根据Feature要素的变量动态渲染多种颜色和不同直径大小的圆形和圆点图形,适用于大量圆形圆点渲染不同颜色不同大小

本章使用OpenLayers根据Feature要素的变量动态渲染不同颜色和不同直径大小的圆形和圆点图形。通过一个WebGL图层生成四种不同颜色和不同大小的圆形圆点图形要素,适用于WebGL图层需要根据大量点要素区分颜色区分不同大小显示圆形圆点的需求。

GIS技术方向,GIS地图技术分享(GIS入门、Openlayers教程、Leaflet教程),做最好的GIS地图开发教程。关注博主公众号:eguid 898

WebGL编程指南高级技术篇(常见需求的处理)

一、鼠标控制模型旋转 实质的根据鼠标移动前后的位置比较得出x,y轴的旋转角度; 图中是一个屏幕,有一个模型(恩,他是一个模型),鼠标由P点移动到P1点,我们假定移动单位步长旋转β角度; P(x1,y1)--->P1(x2,y2),x轴移动(x2-x1),y轴移动(y2-y1),所以x轴旋转 (x2-x1)β度,y轴旋转(y2-y1)β度: 二、判断物体被点击 当鼠标点击的时...

weixin_30883271的博客 161

OpenLayers实战,WebGL图层鼠标经过要素高亮显示,根据变量自动修改WebGL图层要素的透明度、大小和颜色

本章讲解OpenLayers使用WebGL图层情况下,鼠标经过要素高亮显示,根据变量自动修改WebGL图层要素的透明度、大小和颜色的功能。webgl图层的样式并不像普通矢量图层直接修改或者切换样式就可以的,而是要预先通过webgl的运算符编写特定规则才能动态切换。本章使用match运算符来配合鼠标事件完成整个高亮切换过程。

GIS技术方向,GIS地图技术分享(GIS入门、Openlayers教程、Leaflet教程),做最好的GIS地图开发教程。关注博主公众号:eguid 1840

WebGL

WebGL 可供参考的链接: MDN:https://developer.mozilla.org/zh-CN/docs/Web/API/WebGL2RenderingContext 网站:https://webglfundamentals.org/webgl/lessons/zh_cn/ 初步介绍 绘制流程:页面添加canvas元素 - 获取webgl对象 - 清空屏幕 - 设置好着色器等 - 绘制 页面添加canvas元素 <canvas id="canvas" width="400"

qq_52769681的博客 362

OpenLayers实战,WebGL图层根据Feature要素的变量动态渲染多种颜色、不同长度和不同透明度的长方形(矩形)图形,适用于大量矩形图形渲染

本章使用OpenLayers根据Feature要素的变量动态渲染多种颜色、不同长度和不同透明度的矩形(长方形、四边形和正方形)图形。通过一个WebGL图层生成四种不同颜色、不同大小和不同透明度的矩形图形要素,适用于WebGL图层根据大量点要素区分颜色、区分不同大小和区分透明度显示矩形的需求。本文使用case运算符结合逻辑运算符生成透明度,match运算符生成多种颜色和插值运算符生成长度。

GIS技术方向,GIS地图技术分享(GIS入门、Openlayers教程、Leaflet教程),做最好的GIS地图开发教程。关注博主公众号:eguid 1290

OpenLayers实战,WebGL图层根据Feature要素的变量动态渲染多种颜色的三角形,适用于大量三角形渲染不同颜色

本章使用OpenLayers根据Feature要素的变量动态渲染不同颜色的三角形。通过一个WebGL图层生成四种不同颜色的图形要素,适用于WebGL图层需要根据大量点要素区分颜色显示的需求。更多的WebGL图层使用运算符动态生成样式的内容将会陆续更新。## WebGL图层样式运算符详解OpenLayers入门,OpenLayers6的WebGLPointsLayer图层样式运算符详解。

GIS技术方向,GIS地图技术分享(GIS入门、Openlayers教程、Leaflet教程),做最好的GIS地图开发教程。关注博主公众号:eguid 1045

HTML中的Canvas入门:从零开始绘制图形世界

本文介绍了HTML5 Canvas的核心概念与实用技巧。Canvas作为HTML5的绘图元素,通过JavaScript实现像素级图形绘制,适合开发动态图形、动画和游戏。文章从基础绘制方法入手,详细讲解了矩形、路径、圆形等图形的创建,以及样式控制和坐标系统。进阶部分涵盖动画实现和事件交互技术,并提供了性能优化建议。最后列举了Canvas在数据可视化、游戏开发等场景的应用,为开发者提供了从入门到实践的完整指南,为进一步探索Web图形编程奠定基础。

得塔云的博客 702

OpenLayers实战,WebGL图层如何使用一张拼接合成图片根据坐标切片成单个图片进行渲染

本章主要讲解OpenLayers使用WebGL图层的情况下,如何使用一张拼接合成图片根据坐标切片成单个图片进行渲染不同图片到地图上的功能。为方便讲解原理,本章使用的一张图片是按照横向4等分,纵向两等分规则拼接了6个图标的合成图片。并使用WebGLPointsLayer图层的match运算符将一张切片图片为6个图标,并分别渲染这6个图标到地图上。

GIS技术方向,GIS地图技术分享(GIS入门、Openlayers教程、Leaflet教程),做最好的GIS地图开发教程。关注博主公众号:eguid 866

Two.js 的 Two.Points 图元详解:从散点绘制到渲染器源码级剖析

Two.Points 是 Two.js 中专门用于快速绘制一组独立点的核心图元(primitive)类。它允许你通过一个顶点列表(`Two.Vector[]`)定义任意数量的坐标位置,再由 Three.js 无关的渲染器(Canvas / SVG / WebGL)分别绘制为独立的实心圆点。阅读完本文,你将掌握 `Two.Points` 的完整构造方式、全部样式与几何属性的语义与默认值、基于 `Tw

gitblog_01009的博客 370

Vue+OpenLayers6实战进阶专栏目录,Vue+OpenLayers实战案例,Vue+OpenLayers6实战教程

本篇作为Vue整合OpenLayers实战进阶教程的目录,用于整理汇总专栏所有文章,方便查找。本专栏是讲解主流前端框架Vue整合前端最流行的JS二维地图引擎之一OpenLayers的实战教程。

GIS技术方向,GIS地图技术分享(GIS入门、Openlayers教程、Leaflet教程),做最好的GIS地图开发教程。关注博主公众号:eguid 2852

OpenLayers入门,webgl图层叠加大量Icon图片到地图,解决叠加超大数据量图片导致浏览器卡住变慢的问题

上一章中《OpenLayers入门,使用webgl图层叠加大量点要素,解决OpenLayers地图中叠加大量点导致浏览器卡住变慢的问题》已经讲了如何地图中如何添加大量点到webgl图层优化大量点浏览器页面卡顿的问题,本章补充一下叠加图片图标到地图的情况下。

GIS技术方向,GIS地图技术分享(GIS入门、Openlayers教程、Leaflet教程),做最好的GIS地图开发教程。关注博主公众号:eguid 2083

HTML5 Canvas粒子动画实战:浪漫表白文字特效开发

简介:本项目基于HTML5 Canvas API与JavaScript技术,实现了一个具有浪漫氛围的粒子文字动画特效,适用于表白场景的创意网页设计。通过Canvas绘制动态粒子系统,结合JS控制粒子运动、碰撞与视觉效果,营造出星光流动、心形闪烁等梦幻动画。项目包含完整的HTML结构、图片资源与数据配置,展示了前端动画开发的核心流程,是学习HTML5图形绘制与交互效果实现的优秀实践案例。

weixin_35797963的博客 1116

HTML5 Canvas实现炫酷3D螺旋圆点线条动画特效

Canvas内部维护着一个叫当前变换矩阵(Current Transformation Matrix, CTM)的东西。默认情况下它是这样的:$$$$每当你调用rotate()或scale(),这个矩阵就会发生变化。比如你执行,系统其实是把这个旋转矩阵右乘到当前CTM上。这就引出了两个关键方法的区别:累加式变换,适合做连续操作强制重置,直接覆盖现有矩阵举个例子:// 方式一:连续变换// 平移// 再缩放。

weixin_42146230的博客 828
上一篇: WebGL笔记:WebGL中的顶点着色器尺寸,颜色的修改
下一篇: WebGL笔记:绘制多个点,三角形,以及画各种不同的线条,面
Wang's Blog
博客等级 码龄12年 7438粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值