`
flyfox1982
  • 浏览: 81224 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

WebGL 绘制Line的bug(三)

阅读更多

上一篇已经讲述了通过面模拟线条时候,每一个顶点的顶点数据包括:端点坐标、偏移量、前一个端点坐标、后一个端点坐标,当然如果我们通过索引的方式来绘制的话,还包括索引数组,下面的代码通过传递一组线条的端点数组来创建上述相关数据:

 ```

bk.Line3D = function (points,colors){

     this.points = points;

     this.colors = colors;

}

 

bk.Line3D.prototype.computeData = function() {

      var len = this.points.length;

      var count = len * 3 * 2;    

      var position = new Float32Array(count);

      var positionPrev =  new Float32Array(count);

      var positionNext = new Float32Array(count);

      var color = new Float32Array(count);

 

      var offset = new Float32Array(len * 2);

      var indicesCount = 3 * 2 * (len - 1);

      var indices = new Uint16Array(indicesCount);

      var triangleOffset = 0,vertexOffset = 0;

      for(var i = 0; i < len; i ++){

            var i3 = i * 3 * 2;

            var point = this.points[i];

            position[i3 + 0] = point.x;

            position[i3 + 1] = point.y;

            position[i3 + 2] = point.z;

            position[i3 + 3] = point.x;

            position[i3 + 4] = point.y;

            position[i3 + 5] = point.z;

 

            var r = (i + 1) / len;

            var g = Math.random();

            var b = Math.random();

            g = r;

            b = 0;

            r =  1- r;

            color[i3 + 0] = r;

            color[i3 + 1] = g;

            color[i3 + 2] = b;

            color[i3 + 3] = r;

            color[i3 + 4] = g;

            color[i3 + 5] = b;

 

             if (i < count - 1) {

                    var i3p = i3 + 6;

                    positionNext[i3p + 0] = point.x;

                    positionNext[i3p + 1] = point.y;

                    positionNext[i3p + 2] = point.z;

 

                    positionNext[i3p + 3] = point.x;

                    positionNext[i3p + 4] = point.y;

                    positionNext[i3p + 5] = point.z;

                }

             if (i > 0) {

                    var i3n = i3 - 6;

                    positionPrev[i3n + 0] = point.x;

                    positionPrev[i3n + 1] = point.y;

                    positionPrev[i3n + 2] = point.z;

 

                    positionPrev[i3n + 3] = point.x;

                    positionPrev[i3n + 4] = point.y;

                    positionPrev[i3n + 5] = point.z;

             }

 

             var idx = 3 * i;

 

             var i2 = i * 2;

             offset[i2 + 0]  = 5;

             offset[i2 + 1]  = -5;

      }

      var end = count - 1;

      for(i = 0;i < 6 ;i ++){

          positionNext[i] = positionNext[i + 6];

          positionPrev[end - i] = positionPrev[end - i - 6];

      }

      for(i = 0;i < indicesCount ;i ++){

          if(i % 2 == 0){

             indices[triangleOffset ++] = i;

             indices[triangleOffset ++] = i + 1;

             indices[triangleOffset ++] = i + 2;

          }else{

             indices[triangleOffset ++] = i + 1;

             indices[triangleOffset ++] = i;

             indices[triangleOffset ++] = i + 2;

          }

      }

 

      this.position  = position;

      this.positionNext  = positionNext;

      this.positionPrev = positionPrev;

      this.color = color;

      this.offset = offset;

      this.indices = indices;

};

```

代码首先定义了一个类,该类构造函数可以传入端点数组;在该类上定义了一个方法 computeData,用来计算顶点数组,每个顶点包括上文所述的4个信息,另外增加了一个颜色信息。

读者,可以结合第二篇的思路和上面的代码来来理解,此处不再详述 代码的细节。

 

另外一个比较重要的代码是顶点着色器中,通过传入的这些顶点信息来计算最终的顶点坐标,代码如下:

```

var lineVS = `

attribute vec3 aPosition;

attribute vec3 aPositionPre;

attribute vec3 aPositionNext;

attribute float aOffset;

attribute vec3 aColor;

varying  vec3  vColor;

 

uniform mat4 uWorldViewProjection;

uniform vec4 uViewport;

uniform float uNear;

 

uniform mat4 uViewMatrix;

      uniform mat4 uProjectMatrix;

 

vec4 clipNear(vec4 p1,vec4 p2){

float n = (p1.w - uNear) / (p1.w - p2.w);

return vec4(mix(p1.xy,p2.xy,n),-uNear,uNear);

}

 

void main(){

 

vec4 prevProj = uWorldViewProjection * vec4(aPositionPre, 1.0);

vec4 currProj = uWorldViewProjection * vec4(aPosition, 1.0);

             vec4 nextProj = uWorldViewProjection * vec4(aPositionNext, 1.0);

             if (currProj.w < 0.0) {

   if (prevProj.w < 0.0) {

currProj = clipNear(currProj, nextProj);

   }else {

currProj = clipNear(currProj, prevProj);

   }

}

vec2 prevScreen = (prevProj.xy / abs(prevProj.w) + 1.0) * 0.5 * uViewport.zw;

vec2 currScreen = (currProj.xy / abs(currProj.w) + 1.0) * 0.5 * uViewport.zw;

vec2 nextScreen = (nextProj.xy / abs(nextProj.w) + 1.0) * 0.5 * uViewport.zw;

vec2 dir;

float len = aOffset;

if(aPosition == aPositionPre){

dir = normalize(nextScreen - currScreen);

}else if(aPosition == aPositionNext){

dir = normalize(currScreen - prevScreen);

}else {

vec2 dirA = normalize(currScreen - prevScreen);

vec2 dirB = normalize(nextScreen - currScreen);

vec2 tanget = normalize(dirA + dirB);

float miter = 1.0 / max(dot(tanget,dirA),0.5);

len *= miter;

dir = tanget;

}

dir = vec2(-dir.y,dir.x) * len;

currScreen += dir;

currProj.xy = (currScreen / uViewport.zw - 0.5) * 2.0 * abs(currProj.w);

vec4 pos = uProjectMatrix * uViewMatrix *  vec4(aPosition,1.0);

vColor = aColor;

gl_Position = currProj;

}

`;

```

计算的原理,也可以参考第二篇的论述,此处需要注意的是,为了能够计算顶点在屏幕上的最终位置,需要把canvans的尺寸大小传递给着色器(uniform 变量 uViewport),同样为了计算裁剪,需要把镜头的near值传递给着色器(uniform 变量 uNear),而变量uWorldViewProjection表示模型视图透视变换的矩阵,熟悉WebGL的同学一定清楚。

 

如果你有兴趣,请关注公众号。

 

ITman彪叔公众号
ITman彪叔公众号
0
0
分享到:
评论

相关推荐

    WebGL之绘制三维地球.docx

    WebGL 之绘制三维地球 本文将详细介绍如何使用 WebGL 从零开始绘制三维地球模型,包括构建网格、编写着色器、实现 3D 地球等步骤。 1. 构建网格 构建网格是绘制三维地球的第一步,我们需要建立球体的三维模型,该...

    通过js底层获取H264的数据,然后通过webgl绘制出来

    看的懂,需要自己具备对js有自己的理解,原型链,this的指向,c++,webgl的基本理解和使用,ip地址是不能看的,因为播放的流量都是收费的,如果你们有ip,可以连接你们自己的ip地址,逻辑就是这样的逻辑,你让我分析...

    webgl入门-基础三角形绘制

    webgl入门-基础三角形绘制

    网页动画素材 WebGL基于canvas画布绘制3D噪音线条酷炫动画特效。(抖音资料)

    网页动画素材 WebGL基于canvas画布绘制3D噪音线条酷炫动画特效。(抖音资料)网页动画素材 WebGL基于canvas画布绘制3D噪音线条酷炫动画特效。(抖音资料)网页动画素材 WebGL基于canvas画布绘制3D噪音线条酷炫动画...

    html5 webgl绘制3D洞穴穿越无限延伸动画特效.zip

    这个“html5 webgl绘制3D洞穴穿越无限延伸动画特效.zip”文件包含了一套完整的实现3D洞穴穿越效果的代码示例,对于学习和应用WebGL的开发者来说,这是一个非常实用的学习资源。 首先,我们要理解WebGL的基本概念。...

    image3D::tangerine: 使用webGL绘制三维图片。:bar_chart::chart_increasing::party_popper:Drawing three-dimensional images using webGL

    :tangerine: image3D使用webGL绘制三维图片。:bar_chart::chart_increasing::party_popper: Drawing three-dimensional images using webGL.鉴于当前浏览器支持情况,本项目只支持webGL 1上下文,更高级版本未来会...

    WebGL-water

    在Web环境中,WebGL通过JavaScript与GPU进行交互,绘制复杂的3D场景。开发者可以通过顶点着色器和片段着色器来定义物体的形状和颜色,这些着色器是用类似于C的语言GLSL(OpenGL Shading Language)编写的。 在WebGL...

    Webgl旋转三角形源码

    在JavaScript中,WebGL的核心概念是`WebGLRenderingContext`对象,它是用于在画布元素上绘制3D图形的接口。要创建一个WebGL上下文,你需要获取HTML `&lt;canvas&gt;`元素并调用其`getContext('webgl')`方法。 描述中的...

    WebGL--三角形

    首先,WebGL使用顶点(vertices)来定义形状,每个顶点是一个三维坐标(x, y, z)。在这个实验中,三个顶点被用来构成一个三角形。这些顶点会被传递给WebGL的上下文,并由GPU(图形处理单元)进行处理。 接着,我们...

    JavaScript基于WebGL技术实现的三维BS端开发平台(含Cesium 的核心操作库+UI组件库).zip

    JavaScript基于WebGL技术实现的三维BS端开发平台(含Cesium 的核心操作库+UI组件库).zipJavaScript基于WebGL技术实现的三维BS端开发平台(含Cesium 的核心操作库+UI组件库).zipJavaScript基于WebGL技术实现的三维BS端...

    WebGL--三维三角形分裂图

    这个“WebGL--三维三角形分裂图”项目是利用WebGL来实现三维空间中三角形的动态分裂效果,提供了一个交互式的体验,用户可以开始、暂停和终止这一过程。它特别适用于学习和理解计算机图形学中的几何变换、渲染原理...

    webgl 实现的炫酷地球 基于three.js

    WebGL是一种在网页上实现3D图形渲染的技术,它允许开发者在浏览器中创建交互式的、图形丰富的应用程序,而无需任何插件。Three.js是基于WebGL的JavaScript库,它简化了WebGL的复杂性,提供了丰富的功能和易用的API,...

    WebGLVolumeRendering, WebGL体绘制容易.zip

    WebGLVolumeRendering, WebGL体绘制容易 WebGL体绘制容易一个非常简单的步骤介绍像素着色器体渲染使用和 ThreeJS 。转到 http://lebarba.com/blog/ 一步教程中的步骤在 GitHub http://www.lebarba.com/WebGL/

    WebGL 3D雪花飘落动画特效.zip

    【WebGL 3D雪花飘落动画特效】是一种利用JavaScript和WebGL技术在网页上实现的视觉效果。WebGL(Web Graphics Library)是基于OpenGL标准的JavaScript API,它允许开发者在浏览器环境中创建交互式的3D图形,无需插件...

    webGL编程示例源码

    《WebGL编程指南》的主要篇幅讲解了WebGL 原生API 和三维图形学的基础知识,包括渲染管线、着色器、矩阵变换、着色器编程语言(GLSL ES)等等,也讲解了使用WebGL 渲染三维场景的一般技巧,如光照、阴影、雾化等等。...

    使用webGL绘制三维图片

    这个“使用WebGL绘制三维图片”的主题涵盖了多个关键知识点,包括WebGL的基本概念、工作原理、以及如何利用JavaScript来创建和操作三维场景。 1. **WebGL基础**: WebGL是WebGLRenderingContext接口的实现,它允许...

    WebGL+鼠标响应+如何绘制爱心.rar

    接着,JavaScript部分的工作主要分为三个步骤:初始化WebGL上下文,处理鼠标事件,以及根据鼠标位置绘制爱心。WebGL的初始化涉及创建一个WebGL渲染上下文,并设置必要的视口大小和投影矩阵。这通常通过调用`gl....

    HTML5 javascript调用WebGL实现 下雪闪电打雷下雪天气效果天气现象 太逼真了,这其实就是游戏开发了.zip

    HTML5 javascript调用webgl实现 下雪闪电打雷下雪天气效果天气现象 太逼真了,这其实就是游戏开发了.zip

    WebGL Overview

    WebGL是一种三维图形API,用于在网页浏览器中渲染三维图形。它的设计灵感来自于OpenGL ES 2.0标准,是一种JavaScript的移植版本。WebGL采用立即模式,即直接操作图形调用,而非保留模式,不需要显式地维护和更新显示...

    基于vue3.0+esmap+springboot+WebGL的智慧楼宇三维监控系统源码(毕设项目).zip

    基于vue3.0+esmap+springboot+WebGL的智慧楼宇三维监控系统源码(毕设项目).zip 基于vue3.0+esmap+springboot+WebGL的智慧楼宇三维监控系统源码(毕设项目).zip 基于vue3.0+esmap+springboot+WebGL的智慧楼宇三维监控...

Global site tag (gtag.js) - Google Analytics