HTML5与WebGL编程(1):介绍

23人阅读 评论(0) 收藏 举报
分类:

      代码https://github.com/tparisi/Programming3DApplications

      HTML5是HTML标准的大规模修订,包括语法的清理、新的JavaScript语言特性和API、移动端支持以及突破性的多媒体支持。HTML5平台的核心是一系列先进的图形技术。

  • WebGL,使得JavaScript支持硬件3D加速渲染。WebGL基于OpenGL,几乎所有的PC端浏览器都支持WebGL,而越来越多的移动端浏览器也开始支持WebGL。
  • CSS3 3D变换、平移以及可以支持更高级页面效果的用户自定义滤镜。经过过去几年的发展,CSS现在已经支持硬件3D加速渲染和动画。
  • Canvas元素和相应的2D绘图API。浏览器普遍支持这个JavaScript的API,它使得开发者可以在一个DOM元素上绘制任意图形。尽管Canvas是一个2D绘图API,但如果使用一些JavaScript库的话,它也可以用于渲染3D效果---在不支持WebGL和CSS3 3D的平台上,这通常被作为3D渲染的替代解决方案。

      这些技术各有其优势和适用场景,它们在构建3D可视化交互的过程中发挥着各自的作用。至于究竟要选择哪一种,你需要综合考虑多方面的因素---你想要构建什么,需要支持哪些平台,性能问题,等等。举例来说,如果你开发一个具有高质量图像的第一人称射击游戏,若不借助WebGL访问图形硬件的能力,这将很难实现。又或者你在为某个视频网站开发一个有趣的调台器界面,包括当前视频缩略图、换频道的旋转效果,以及视频剪辑切换间隙的雪花噪点特效。在这个场景下,CSS3会是创造优秀体验的良好选择。

      requestAnimationFrame()函数是替代setInterval()和setTimeout()来驱动动画,使得开发这能够以和浏览器刷新页面元素同步的刷新频率来更新canvas元素的绘图内容,这大大地提升了性能,并防止了绘图残影的产生。

      HTML5浏览器同时也支持多线程编程(Web Workers)、全双工TCP/IP通信(WebSockets)、本地数据存储等新特性。

      3D坐标系

      网格、多边形和顶点

      材质、纹理与光源

      变换与矩阵

      相机、透视、视口与投影

      着色器

<html>
<head>
<title>Programming 3D Applications in HTML5 and WebGL — Example 2-3</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<script src="../libs/jquery-1.9.1/jquery-1.9.1.js"></script>
<script src="../libs/gl-matrix/gl-matrix.js"></script>
<script src="../libs/requestAnimationFrame/RequestAnimationFrame.js"></script>
<script type="text/javascript">
    function initWebGL(canvas) {
	    var gl = null;
	    var msg = "Your browser does not support WebGL, " +
	    	"or it is not enabled by default.";
	    try 
	    {
	        gl = canvas.getContext("experimental-webgl");
	    } 
	    catch (e)
	    {
	        msg = "Error creating WebGL Context!: " + e.toString();
	    }
	
	    if (!gl)
	    {
		    alert(msg);
	    	throw new Error(msg);
	    }
        return gl;        
     }
    function initViewport(gl, canvas)
    {
        gl.viewport(0, 0, canvas.width, canvas.height);
    }
    var projectionMatrix, modelViewMatrix;
    var rotationAxis;
    function initMatrices(canvas)
    {
        // Create a model view matrix with object at 0, 0, -8
        modelViewMatrix = mat4.create();
        mat4.translate(modelViewMatrix, modelViewMatrix, [0, 0, -8]);

        // Create a project matrix with 45 degree field of view
        projectionMatrix = mat4.create();
        mat4.perspective(projectionMatrix, Math.PI / 4, canvas.width / canvas.height, 1, 10000);

        rotationAxis = vec3.create();
        vec3.normalize(rotationAxis, [1, 1, 1]);
    }
    // Create the vertex, color and index data for a multi-colored cube
    function createCube(gl) {  
        // Vertex Data
        var vertexBuffer;
    	vertexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
        var verts = [
           // Front face
           -1.0, -1.0,  1.0,
            1.0, -1.0,  1.0,
            1.0,  1.0,  1.0,
           -1.0,  1.0,  1.0,

           // Back face
           -1.0, -1.0, -1.0,
           -1.0,  1.0, -1.0,
            1.0,  1.0, -1.0,
            1.0, -1.0, -1.0,

           // Top face
           -1.0,  1.0, -1.0,
           -1.0,  1.0,  1.0,
            1.0,  1.0,  1.0,
            1.0,  1.0, -1.0,

           // Bottom face
           -1.0, -1.0, -1.0,
            1.0, -1.0, -1.0,
            1.0, -1.0,  1.0,
           -1.0, -1.0,  1.0,

           // Right face
            1.0, -1.0, -1.0,
            1.0,  1.0, -1.0,
            1.0,  1.0,  1.0,
            1.0, -1.0,  1.0,

           // Left face
           -1.0, -1.0, -1.0,
           -1.0, -1.0,  1.0,
           -1.0,  1.0,  1.0,
           -1.0,  1.0, -1.0
           ];
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);

        var texCoordBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
        var textureCoords = [
          // Front face
          0.0, 0.0,
          1.0, 0.0,
          1.0, 1.0,
          0.0, 1.0,

          // Back face
          1.0, 0.0,
          1.0, 1.0,
          0.0, 1.0,
          0.0, 0.0,

          // Top face
          0.0, 1.0,
          0.0, 0.0,
          1.0, 0.0,
          1.0, 1.0,

          // Bottom face
          1.0, 1.0,
          0.0, 1.0,
          0.0, 0.0,
          1.0, 0.0,

          // Right face
          1.0, 0.0,
          1.0, 1.0,
          0.0, 1.0,
          0.0, 0.0,

          // Left face
          0.0, 0.0,
          1.0, 0.0,
          1.0, 1.0,
          0.0, 1.0,
        ];
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW);

        // Index data (defines the triangles to be drawn)
        var cubeIndexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeIndexBuffer);
        var cubeIndices = [
            0, 1, 2,      0, 2, 3,    // Front face
            4, 5, 6,      4, 6, 7,    // Back face
            8, 9, 10,     8, 10, 11,  // Top face
            12, 13, 14,   12, 14, 15, // Bottom face
            16, 17, 18,   16, 18, 19, // Right face
            20, 21, 22,   20, 22, 23  // Left face
        ];
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeIndices), gl.STATIC_DRAW);
        
        var cube = {buffer:vertexBuffer, texCoordBuffer:texCoordBuffer, indices:cubeIndexBuffer,
                vertSize:3, nVerts:24, texCoordSize:2, nTexCoords: 24, nIndices:36,
                primtype:gl.TRIANGLES};
        
        return cube;
    }

    function createShader(gl, str, type) {
        var shader;
        if (type == "fragment") {
            shader = gl.createShader(gl.FRAGMENT_SHADER);
        } else if (type == "vertex") {
            shader = gl.createShader(gl.VERTEX_SHADER);
        } else {
            return null;
        }

        gl.shaderSource(shader, str);
        gl.compileShader(shader);

        if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
            alert(gl.getShaderInfoLog(shader));
            return null;
        }

        return shader;
    }
    
	var vertexShaderSource =
		
		"    attribute vec3 vertexPos;\n" +
		"    attribute vec2 texCoord;\n" +
		"    uniform mat4 modelViewMatrix;\n" +
		"    uniform mat4 projectionMatrix;\n" +
		"    varying vec2 vTexCoord;\n" +
		"    void main(void) {\n" +
		"		// Return the transformed and projected vertex value\n" +
		"        gl_Position = projectionMatrix * modelViewMatrix * \n" +
		"            vec4(vertexPos, 1.0);\n" +
		"        // Output the texture coordinate in vTexCoord\n" +
		"        vTexCoord = texCoord;\n" +
		"    }\n";

	var fragmentShaderSource = 
		"    precision mediump float;\n" +
		"    varying vec2 vTexCoord;\n" +
		"    uniform sampler2D uSampler;\n" + 
		"    void main(void) {\n" +
		"    // Return the pixel color: always output white\n" +
        "    gl_FragColor = texture2D(uSampler, vec2(vTexCoord.s, vTexCoord.t));\n" +
    	"}\n";


    var shaderProgram, shaderVertexPositionAttribute, shaderVertexColorAttribute, 
    	shaderProjectionMatrixUniform, shaderModelViewMatrixUniform, shaderSamplerUniform;

    function initShader(gl) {

    	// load and compile the fragment and vertex shader
        //var fragmentShader = getShader(gl, "fragmentShader");
        //var vertexShader = getShader(gl, "vertexShader");
        var fragmentShader = createShader(gl, fragmentShaderSource, "fragment");
        var vertexShader = createShader(gl, vertexShaderSource, "vertex");

        // link them together into a new program
        shaderProgram = gl.createProgram();
        gl.attachShader(shaderProgram, vertexShader);
        gl.attachShader(shaderProgram, fragmentShader);
        gl.linkProgram(shaderProgram);

        // get pointers to the shader params
        shaderVertexPositionAttribute = gl.getAttribLocation(shaderProgram, "vertexPos");
        gl.enableVertexAttribArray(shaderVertexPositionAttribute);

        shaderTexCoordAttribute = gl.getAttribLocation(shaderProgram, "texCoord");
        gl.enableVertexAttribArray(shaderTexCoordAttribute);
        
        shaderProjectionMatrixUniform = gl.getUniformLocation(shaderProgram, "projectionMatrix");
        shaderModelViewMatrixUniform = gl.getUniformLocation(shaderProgram, "modelViewMatrix");
        shaderSamplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
        
        if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
            alert("Could not initialise shaders");
        }
    }

    var okToRun = false;
    
    function handleTextureLoaded(gl, texture) {
        gl.bindTexture(gl.TEXTURE_2D, texture);
        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.image);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
        gl.bindTexture(gl.TEXTURE_2D, null);
        okToRun = true;
    }
    
    var webGLTexture;

    function initTexture(gl) {
    	webGLTexture = gl.createTexture();
    	webGLTexture.image = new Image();
      
    	webGLTexture.image.onload = function () {
            handleTextureLoaded(gl, webGLTexture)
        }
      webGLTexture.image.crossOrigin = "anonymous"; 
    	webGLTexture.image.src = "../images/webgl-logo-256.jpg";
    }

    
    function draw(gl, obj) {

        // clear the background (with black)
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        gl.enable(gl.DEPTH_TEST);
        gl.clear(gl.COLOR_BUFFER_BIT  | gl.DEPTH_BUFFER_BIT);

        // set the shader to use
        gl.useProgram(shaderProgram);

 		// connect up the shader parameters: vertex position, texture coordinate,
 		// projection/model matrices and texture
   	    // set up the buffers
        gl.bindBuffer(gl.ARRAY_BUFFER, obj.buffer);
        gl.vertexAttribPointer(shaderVertexPositionAttribute, obj.vertSize, gl.FLOAT, false, 0, 0);
        gl.bindBuffer(gl.ARRAY_BUFFER, obj.texCoordBuffer);
        gl.vertexAttribPointer(shaderTexCoordAttribute, obj.texCoordSize, gl.FLOAT, false, 0, 0);
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, obj.indices);

        gl.uniformMatrix4fv(shaderProjectionMatrixUniform, false, projectionMatrix);
        gl.uniformMatrix4fv(shaderModelViewMatrixUniform, false, modelViewMatrix);

        gl.activeTexture(gl.TEXTURE0);
        gl.bindTexture(gl.TEXTURE_2D, webGLTexture);
        gl.uniform1i(shaderSamplerUniform, 0);

        // draw the object
        gl.drawElements(obj.primtype, obj.nIndices, gl.UNSIGNED_SHORT, 0);
    }

    var duration = 5000; // ms
    var currentTime = Date.now();
	function animate() {
        var now = Date.now();
        var deltat = now - currentTime;
        currentTime = now;
        var fract = deltat / duration;
        var angle = Math.PI * 2 * fract;
        mat4.rotate(modelViewMatrix, modelViewMatrix, angle, rotationAxis);
	}
	
    function run(gl, cube) {
        requestAnimationFrame(function() { run(gl, cube); });
        if (okToRun)
        {
	        draw(gl, cube);
	        animate();
        }
    }
          
	$(document).ready(
			function() {
		        var canvas = document.getElementById("webglcanvas");
			    var gl = initWebGL(canvas);
		        initViewport(gl, canvas);
		        initMatrices(canvas);
		        var cube = createCube(gl);
		        initShader(gl);
		        initTexture(gl);
		        run(gl, cube);
			}
	);
</script>
</head>
<body>
    <canvas id="webglcanvas" style="border: none;" width="500" height="500"></canvas>
</body>
</html>

查看评论

webgl基础篇-坚如磐石

1.从基础开始介绍webgl技术,介绍基本的webgl渲染管线,各种常用的缓冲区的作用,以及用法,结合程序实例做到全方位的讲解. 2.精讲三维的理论,针对三维理论中的三个矩阵变换一个坐标变换深入讲解.针对webgl核心技术逐个讲解, 3.针对可编程管线,理论结合实践,让学员深刻的体验到shader的作用. 3.重点围绕webgl的核心技术进行实践.
  • 2015年11月19日 21:09

WebGl(Three.js) 读取ArcgisServer发布的管线数据服务

&amp;lt;!DOCTYPE html&amp;gt;&amp;lt;html lang=&quot;en&quot;&amp;gt;&amp;lt;head&amp;gt;    &amp;lt...
  • u013236043
  • u013236043
  • 2018-03-26 14:04:18
  • 32

webgl开源三维引擎的选择

webgl发展的很快,可谓日新月异,所以下面的这些引擎过一个月,半年可能就不是现在这样了,对应的连接地址以方便查看比较。 一。小场景的开源三维js引擎 1.babylonjs:http://www....
  • lh1162810317
  • lh1162810317
  • 2016-03-08 16:43:10
  • 8355

WebGL框架:Three.js和Babylon.js的比较

今天的web浏览器已经走了很长的路。由于出色的JavaScript WebGL api ,现代浏览器完全有能力在没有第三方插件帮助的情况下呈现先进的2 d和3 d图形。利用专用的图形处理器的性能,We...
  • qq_38144370
  • qq_38144370
  • 2017-04-10 11:26:32
  • 3970

GitHub上的WebGL库调研

1.three.js  star: 32.9K   更新速率:频繁   这个无需多说,当下最流行的WebGL库, 轻量级,容易使用,很多webgl库都是基于它来构建。 官网地址:https:...
  • u013929284
  • u013929284
  • 2017-05-22 10:43:05
  • 1437

WebGL可视化地球和地图引擎:Cesium.js

Cesium介绍Cesium是国外一个基于JavaScript编写的使用WebGL的地图引擎。Cesium支持3D,2D,2.5D形式的地图展示,可以自行绘制图形,高亮区域,并提供良好的触摸支持,且支...
  • xk_zhang
  • xk_zhang
  • 2016-07-23 22:37:03
  • 11110

基于HTML5和WebGL的碰撞测试

可能你会好奇这个是怎么俯视图是怎么放上去的?如果3d中的图元变化,这个俯视图中的图元也会跟着变化么?如何把右上角的form表单和左下角的视图又是怎么放的?如何只移动3d二把这两个固定在这边?或者你可能...
  • u013161495
  • u013161495
  • 2017-10-19 14:18:18
  • 450

基于HT的CSG功能构建HTML5的3D书架

构造实体几何CSG全称Constructive solid geometry,是3D计算机图形学中构建模型的常用技术,可通过合并Union、相减Subtraction和相交Intersction的三种...
  • u013161495
  • u013161495
  • 2014-12-25 01:51:26
  • 2124

学习 WebGL 的开源库 Three.js

百度 第一个词条是:   http://hewebgl.com/      然后就照着学习呗  , 后面是需要花钱的! 开发环境搭建  VS Code(编辑器)  + python(自带的文件服务器)...
  • u010019717
  • u010019717
  • 2017-03-17 09:25:32
  • 1578

WebGL框架比较之Three.js和Babylon.js的比较

转自:http://www.xiwnn.com/article/UTVRJ.html
  • czq7511
  • czq7511
  • 2017-08-24 20:39:04
  • 1527
    个人资料
    持之以恒
    等级:
    访问量: 9万+
    积分: 4426
    排名: 8624
    文章存档
    最新评论