webgl 实现地球月球绕转(时间原因有内存泄漏问题后续优化)带阴影雾化光照效果

代码纯webgl原生实现 

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script src="../lib/webgl-utils.js"></script>
        <script src="../lib/webgl-debug.js"></script>
        <script src="../lib/cuon-utils.js"></script>
        <script src="../lib/cuon-matrix.js"></script>
	</head>
	<body>
		
		<canvas id="webgl" width="1024" height="1024">
	      Please use a browser that supports "canvas"
	    </canvas>
	    <div>helloworld</div>
		
		<script type="application/javascript">
		     var OFFSCREEN_WIDTH = 1024, OFFSCREEN_HEIGHT = 1024;
		     //初始化星空
		     //随机产生 200 个星星   大小是 10 到 20  20个间距 
		     let pointBase = 1
		     let size = 2
		     let duansize = 2
		     var points = []
		     for(let i = 0 ; i < 50 ; i++){
		     	let point = []
		     	let div = Math.random();
		     	let div1 = Math.random();
		     	let div3 = Math.random();
		     	let divf = div > 0.7?1:-1;
		     	let divf2 = div1 > 0.6?1:-1;
		     	let divf3 = div3 > 0.5?1:-1;
	     		point[0] = divf*div;
	     		point[1] = divf2*div1;
	     		point[2] = divf3*div3-2.9;
	     		point[3] = size + duansize*div;

		     	points = points.concat(point);
		     }
		    // Shadow.js (c) 2012 matsuda and tanaka
			// Vertex shader program for generating a shadow map
			var SHADOW_VSHADER_SOURCE =
			  'attribute vec4 a_Position;\n' +
		      'uniform mat4 u_MvpMatrix;\n' +
			  'void main() {\n' +
			 '  gl_Position = u_MvpMatrix * a_Position;\n' +
			  '}\n';
			
			// Fragment shader program for generating a shadow map
			var SHADOW_FSHADER_SOURCE =
			  'precision mediump float;\n' +
			  'void main() {\n' +
//			  '  if((gl_FragCoord.z) > 0.9) {\n' +  // Radius is 0.5
			  '  gl_FragColor = vec4(gl_FragCoord.z, 0.0, 0.0, 1.0);\n' + // Write the z-value in R
//			  '  } else { gl_FragColor = vec4(0.0, gl_FragCoord.z/gl_FragCoord.w, 0.0, 1.0); }\n' +
			  '}\n'; 
		     
		    // 星星 顶点着色器
			var VSHADER_SOURCE_XX =
			  'attribute vec4 a_Position;\n' +
			  'attribute float a_PointSize;\n' +
			  'uniform mat4 u_ModelMatrix;\n' +
			  'uniform mat4 u_ViewMatrix;\n' +
			  'uniform mat4 u_ProjMatrix;\n' +
			  'varying float v_Dist;\n' +
			  'void main() {\n' +
			  '  gl_Position = u_ProjMatrix * u_ViewMatrix * u_ModelMatrix * a_Position;\n' +
			  '  gl_PointSize = a_PointSize;\n' +
			  '  v_Dist = gl_Position.w;\n' +
			  '}\n';
			
			// 星星 片元着色器
			var FSHADER_SOURCE_XX =
			  'precision mediump float;\n' +
			  'uniform vec3 u_FogColor;\n' + // Color of Fog
              'uniform vec2 u_FogDist;\n' +  // Distance of Fog (starting point, end point)
              'varying float v_Dist;\n' +
			  'void main() {\n' +    // Center coordinate is (0.5, 0.5)
			  '  float d = distance(gl_PointCoord, vec2(0.5, 0.5));\n' +
			  '  if(d < 0.5) {\n' +  // Radius is 0.5
			     // Calculation of fog factor (factor becomes smaller as it goes further away from eye point)
			  '  float fogFactor = (u_FogDist.y - v_Dist) / (u_FogDist.y - u_FogDist.x);\n' +
			     // Stronger fog as it gets further: u_FogColor * (1 - fogFactor) + v_Color * fogFactor
			  '  vec4 v_Color =  vec4(1.0, 1.0, 0.0, 1.0);\n' +
			  '  vec3 color = mix(u_FogColor, vec3(v_Color), clamp(fogFactor, 0.0, 1.0));\n' +
			  '  gl_FragColor = vec4(color, v_Color.a);\n' +
			  '  } else { discard; }\n' +
			  '}\n';
			  
			  
			  var VSHADER_SOURCE_DQ =
				  'attribute vec4 a_Position;\n' +
				  'attribute vec2 a_TexCoord;\n' +
                  'varying vec2 v_TexCoord;\n' +
				   //  'attribute vec4 a_Color;\n' + // Defined constant in main()
				  'attribute vec4 a_Normal;\n' +
				  'uniform mat4 u_MvpMatrix;\n' +
				  'uniform mat4 u_ModelMatrix;\n' +    // Model matrix
				  'uniform mat4 u_NormalMatrix;\n' +   // Transformation matrix of the normal
				  'varying vec4 v_Color;\n' +
				  'varying vec3 v_Normal;\n' +
				  'varying vec3 v_Position;\n' +
				  'uniform mat4 u_MvpMatrixFromLight;\n' +
				  'varying vec4 v_PositionFromLight;\n' +
				  'void main() {\n' +
				  '  v_TexCoord = a_TexCoord;\n' +
				  '  vec4 color = vec4(1.0, 1.0, 1.0, 1.0);\n' + // Sphere color
				  '  gl_Position = u_MvpMatrix * a_Position;\n' +
				     // Calculate the vertex position in the world coordinate
				  '  v_Position = vec3(u_ModelMatrix * a_Position);\n' +
				  '  v_Normal = normalize(vec3(u_NormalMatrix * a_Normal));\n' +
				  '  v_Color = color;\n' + 
				  '  v_PositionFromLight = u_MvpMatrixFromLight * a_Position;\n' +
				  '}\n';
			
			 // Fragment shader program
			 var FSHADER_SOURCE_DQ =
				  'precision mediump float;\n' +
				  'uniform vec3 u_LightColor;\n' +     // Light color
				  'uniform vec3 u_LightPosition;\n' +  // Position of the light source
				  'uniform vec3 u_AmbientLight;\n' +   // Ambient light color
				  'varying vec3 v_Normal;\n' +
				  'varying vec3 v_Position;\n' +
				  'varying vec4 v_Color;\n' +
				  'varying vec2 v_TexCoord;\n' +
				  'uniform sampler2D u_Sampler;\n' +
				  'uniform sampler2D u_ShadowMap;\n' +
				  'varying vec4 v_PositionFromLight;\n' +
				  'void main() {\n' +
				  '  vec3 shadowCoord = (v_PositionFromLight.xyz/v_PositionFromLight.w)/2.0 + 0.5;\n' +
				  '  vec4 rgbaDepth = texture2D(u_ShadowMap, shadowCoord.xy);\n' +
				     // Normalize the normal because it is interpolated and not 1.0 in length any more
				  '  vec3 normal = normalize(v_Normal);\n' +
				     // Calculate the light direction and make it 1.0 in length
				  '  vec3 lightDirection = normalize(u_LightPosition - v_Position);\n' +
				     // The dot product of the light direction and the normal
				  '  float nDotL = max(dot(lightDirection, normal), 0.0);\n' +
				     // Calculate the final color from diffuse reflection and ambient reflection
				  '  vec4 texColor = texture2D(u_Sampler, v_TexCoord);\n' +
				  '  vec3 diffuse = u_LightColor * texColor.rgb * nDotL;\n' +
				  '  vec3 ambient = u_AmbientLight * texColor.rgb;\n' +
				  '  float depth = rgbaDepth.r;\n' + // Retrieve the z-value from R
				  '  float visibility = (shadowCoord.z  > depth + 0.002  ) ? 0.3 : 1.0;\n' +
                  '  gl_FragColor = vec4((diffuse + ambient)* visibility, v_Color.a);\n' +
				   //'  gl_FragColor = vec4(visibility,0.0,0.0,1.0);\n' +
				  '}\n';
		   let ANGLE = 0;
		   let ZANGLE = 0;
   		   	      //获取webgl上下文
	       // Get the rendering context for WebGL
	       var canvas = document.getElementById('webgl');
		   var gl = getWebGLContext(canvas);
		   window.onload = function(){
		   	     //加载地球图片
	             var image = new Image();  // Create the image object
	               // Register the event handler to be called on loading an image
				 image.onload = function(){ 
	         
			     };
			      // Tell the browser to load an image
			     image.src = '../resources/earth1.png';
			     
			     //加载月球图片
			     var imageMoon = new Image();
			     imageMoon.onload = function(){
			     	
			     };
			     imageMoon.src = '../resources/moon.png';
			     
			     setTimeout(function(){
			     	setInterval(function () {
				 		ANGLE += 0.2
				 		ZANGLE += 2
			          window.renderCanvas(image,imageMoon, ANGLE, ZANGLE)
			        }, 100);
			     }, 2000)
		   }
		   function renderCanvas(image,imageMoon, ZANGLE, ANGLE){
				  gl.enable(gl.DEPTH_TEST);
				  if (!gl) {
				    console.log('Failed to get the rendering context for WebGL');
				    return;
				  }
		   	      //释放缓冲区
//		   	      gl.deleteBuffer()
//		   	      gl.deleteTexture()
		   	      
		   	      // Specify the color for clearing <canvas>
			      gl.clearColor(0.0, 0.0, 0.0, 1.0);
			      // Clear <canvas>
			      gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);  
			      var fbo = initFramebufferObject(gl);
			      gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);  
		          //绘制阴影贴图 用于给地球贴阴影
		          var shadowProgram = createProgram(gl, SHADOW_VSHADER_SOURCE, SHADOW_FSHADER_SOURCE);
		          gl.useProgram(shadowProgram);
			      gl.program = shadowProgram;
			      //开始绘制地球贴图
			      gl.activeTexture(gl.TEXTURE1); // Set a texture object to the texture unit
                  gl.bindTexture(gl.TEXTURE_2D, fbo.texture);
			      var n = initVertexBuffers(gl,0.2,true);
                  //地球的矩阵
                  // Get the storage locations of uniform variables and so on
				  var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');
				  var modelMatrix = new Matrix4();  // Model matrix
				  var Tx = -0.6;     // Translation distance
				  modelMatrix.setRotate(ANGLE, 0, 0, 1);  // Set rotation matrix
				  modelMatrix.translate(Tx, 0, 0); 
				  modelMatrix.rotate(ZANGLE, 0, 0, 1);// Multiply modelMatrix by the calculated translation matrix
				  var mvpMatrix = new Matrix4();   // Model view projection matrix
				  var normalMatrix = new Matrix4(); // Transformation matrix for normals
				  // Calculate the view projection matrix
				  mvpMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);
				  mvpMatrix.lookAt(-5.0, 7.0, 8.0, 0, 0, 0, 0, 0, 1);
				  mvpMatrix.multiply(modelMatrix);
				  // Pass the model view projection matrix to u_MvpMatrix
				  gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
				  // Draw the cube(Note that the 3rd argument is the gl.UNSIGNED_SHORT)
	              gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_SHORT, 0);	
	              //绘制月球贴图阴影
	                // Set the vertex coordinates, the color and the normal
	              var n = initVertexBuffers(gl,0.08,true);
				
				  var modelMatrix = new Matrix4();  // Model matrix
				  var Tx = -0.6;      // Translation distance
				  modelMatrix.setRotate(ANGLE, 0, 0, 1);  // Set rotation matrix
				  modelMatrix.translate(Tx, 0, 0); 
				  modelMatrix.rotate(ANGLE, 0, 1, 0); 
				  modelMatrix.translate(0.29, 0, 0); 
				  modelMatrix.rotate(ZANGLE, 0, 0, 1);// Multiply modelMatrix by the calculated translation matrix
				  var mvpMatrix = new Matrix4();   // Model view projection matrix
				
				  // Calculate the view projection matrix
				  mvpMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);
				  mvpMatrix.lookAt(-5.0, 7.0, 8.0, 0, 0, 0, 0, 0, 1);
				  mvpMatrix.multiply(modelMatrix);
				  // Pass the model view projection matrix to u_MvpMatrix
				  gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
		          gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_SHORT, 0);	
		          //纹理贴图已经画入到texture中
		          gl.bindFramebuffer(gl.FRAMEBUFFER, null); 
		          
		          
			      //渲染星空
			      var shitiProgram = createProgram(gl, VSHADER_SOURCE_XX, FSHADER_SOURCE_XX);
			      gl.useProgram(shitiProgram)
			      gl.program = shitiProgram;
			      // Create a buffer object
				  var vertexSizeBuffer = gl.createBuffer();  
				  if (!vertexSizeBuffer) {
				    console.log('Failed to create the buffer object');
				    return -1;
				  }
				  // Bind the buffer object to target
				  gl.bindBuffer(gl.ARRAY_BUFFER, vertexSizeBuffer);
				  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(points), gl.STATIC_DRAW);
				  //缓冲区数据和着色器 变量绑定和启用
				  var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
				  if (a_Position < 0) {
				    console.log('Failed to get the storage location of a_Position');
				    return -1;
				  }
				  var FSIZE = Float32Array.BYTES_PER_ELEMENT;
				  gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 4, 0);
				  gl.enableVertexAttribArray(a_Position);  // Enable the assignment of the buffer object
				
				  // Get the storage location of a_PointSize
				  var a_PointSize = gl.getAttribLocation(gl.program, 'a_PointSize');
				  if(a_PointSize < 0) {
				    console.log('Failed to get the storage location of a_PointSize');
				    return -1;
				  }
				  gl.vertexAttribPointer(a_PointSize, 1, gl.FLOAT, false, FSIZE * 4, FSIZE * 3);
				  gl.enableVertexAttribArray(a_PointSize);  // Enable buffer allocation
				  var u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix');
				  var u_ViewMatrix = gl.getUniformLocation(gl.program, 'u_ViewMatrix');
				  var u_ProjMatrix = gl.getUniformLocation(gl.program, 'u_ProjMatrix');
				  
				  var modelMatrix = new Matrix4(); // The model matrix
				  var viewMatrix = new Matrix4();  // The view matrix
				  var projMatrix = new Matrix4();  // The projection matrix
				    // Calculate the view matrix and the projection matrix
	              modelMatrix.setTranslate(0, 0, 0);  // Translate 0.75 units along the positive x-axis
	              viewMatrix.setLookAt(0, 0, 3, 0, 0, -100, 0, 1, 0);
	              projMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);
				  // Pass the model, view, and projection matrix to the uniform variable respectively
				  gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
				  gl.uniformMatrix4fv(u_ViewMatrix, false, viewMatrix.elements);
				  gl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix.elements);
				    // Color of Fog
				  var fogColor = new Float32Array([0.137, 0.231, 1.0]);
				  // Distance of fog [where fog starts, where fog completely covers object]
				  var fogDist = new Float32Array([1, 10]);
				  var u_FogColor = gl.getUniformLocation(gl.program, 'u_FogColor');
                  var u_FogDist = gl.getUniformLocation(gl.program, 'u_FogDist');
                   // Pass fog color, distances, and eye point to uniform variable
				  gl.uniform3fv(u_FogColor, fogColor); // ColorssetPerspective
				  gl.uniform2fv(u_FogDist, fogDist);   // Starting point and end point
				  //绘制
				  //初始化黑色星空
			      // Specify the color for clearing <canvas>
			      gl.clearColor(0.0, 0.0, 0.0, 1.0);
			      // Clear <canvas>
			      gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);  
				  // Draw the rectangle
	              gl.drawArrays(gl.POINTS, 0, 50);
	              gl.bindBuffer(gl.ARRAY_BUFFER, null);
			      //启动地球着色器
	              var shadowProgram_dq = createProgram(gl, VSHADER_SOURCE_DQ, FSHADER_SOURCE_DQ);
	              gl.useProgram(shadowProgram_dq)
			      gl.program = shadowProgram_dq;
			      // Set the vertex coordinates, the color and the normal
	              var n = initVertexBuffers(gl,0.2);
	              // Get the storage locations of uniform variables and so on
				  var u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix');
				  var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');
				  var u_NormalMatrix = gl.getUniformLocation(gl.program, 'u_NormalMatrix');
				  var u_LightColor = gl.getUniformLocation(gl.program, 'u_LightColor');
				  var u_LightPosition = gl.getUniformLocation(gl.program, 'u_LightPosition');
				  var u_AmbientLight = gl.getUniformLocation(gl.program, 'u_AmbientLight');
				  //阴影矩阵TODO
				  var u_MvpMatrixFromLight = gl.getUniformLocation(gl.program, 'u_MvpMatrixFromLight'); 
				  // Set the light color (white)
				  gl.uniform3f(u_LightColor, 1.0, 1.0, 1.0);
				  // Set the light direction (in the world coordinate)
				  gl.uniform3f(u_LightPosition, -5.0, 7.0, 8.0);
				  // Set the ambient light
				  gl.uniform3f(u_AmbientLight, 0.1, 0.1, 0.1);
				
				  var modelMatrix = new Matrix4();  // Model matrix
				  var Tx = -0.6;     // Translation distance
				  modelMatrix.setRotate(ANGLE, 0, 0, 1);  // Set rotation matrix
				  modelMatrix.translate(Tx, 0, 0); 
				  modelMatrix.rotate(ZANGLE, 0, 0, 1);// Multiply modelMatrix by the calculated translation matrix
				  var mvpMatrix = new Matrix4();   // Model view projection matrix
				  var normalMatrix = new Matrix4(); // Transformation matrix for normals
				  //TODO
				  var mvpMatrixFromLight = new Matrix4();
				
				  // Pass the model matrix to u_ModelMatrix
				  gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
				
				  // Calculate the view projection matrix
				  mvpMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);
				  mvpMatrix.lookAt(3, 3, 5, 0, 0, 0, 0, 0, 1);
				  mvpMatrix.multiply(modelMatrix);
				  // Pass the model view projection matrix to u_MvpMatrix
				  gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
				  //TODO
				  mvpMatrixFromLight.setPerspective(30, canvas.width/canvas.height, 1, 100);;
				  mvpMatrixFromLight.lookAt(-5.0, 7.0, 8.0, 0, 0, 0, 0, 0, 1);
				  mvpMatrixFromLight.multiply(modelMatrix);
				  //设置阴影矩阵
				  gl.uniformMatrix4fv(u_MvpMatrixFromLight, false, mvpMatrixFromLight.elements);
				
				  // Calculate the matrix to transform the normal based on the model matrix
				  normalMatrix.setInverseOf(modelMatrix);
				  normalMatrix.transpose();
				  // Pass the transformation matrix for normals to u_NormalMatrix
				  gl.uniformMatrix4fv(u_NormalMatrix, false, normalMatrix.elements);
				  //纹理
				  var texture = gl.createTexture();   // Create a texture object
				  var u_Sampler = gl.getUniformLocation(gl.program, 'u_Sampler');
				  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); // Flip the image's y axis
				  // Enable texture unit0
				  gl.activeTexture(gl.TEXTURE0);
				  // Bind the texture object to the target
				  gl.bindTexture(gl.TEXTURE_2D, texture);			
				  // Set the texture parameters
				  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
				  // Set the texture image
				  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
				  // Set the texture unit 0 to the sampler
				  gl.uniform1i(u_Sampler, 0);
				  
				  //设置阴影纹理渲染TODO
	              var u_ShadowMap = gl.getUniformLocation(gl.program, 'u_ShadowMap');
//	              gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0);
//	              // Enable texture unit0
//				  gl.activeTexture(gl.TEXTURE1);
//				  // Bind the texture object to the target
//				  gl.bindTexture(gl.TEXTURE_2D, fbo.texture);	
//				  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
//			      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
				  gl.uniform1i(u_ShadowMap, 1);
				   // Draw the cube(Note that the 3rd argument is the gl.UNSIGNED_SHORT)
	              gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_SHORT, 0);	
	              
	              gl.bindTexture(gl.TEXTURE_2D, null);	
	              gl.bindBuffer(gl.ARRAY_BUFFER, null);
	              
	              //开始画月球了!!!
	               // Set the vertex coordinates, the color and the normal
	              var n = initVertexBuffers(gl,0.08);
	              // Get the storage locations of uniform variables and so on
				  var u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix');
				  var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');
				  var u_NormalMatrix = gl.getUniformLocation(gl.program, 'u_NormalMatrix');
				  var u_LightColor = gl.getUniformLocation(gl.program, 'u_LightColor');
				  var u_LightPosition = gl.getUniformLocation(gl.program, 'u_LightPosition');
				  var u_AmbientLight = gl.getUniformLocation(gl.program, 'u_AmbientLight');
				  //阴影矩阵TODO
				  var u_MvpMatrixFromLight = gl.getUniformLocation(gl.program, 'u_MvpMatrixFromLight'); 
				  // Set the light color (white)
				  gl.uniform3f(u_LightColor, 1.0, 1.0, 1.0);
				  // Set the light direction (in the world coordinate)
				  gl.uniform3f(u_LightPosition, -5.0, 7.0, 8.0);
				  // Set the ambient light
				  gl.uniform3f(u_AmbientLight, 0.1, 0.1, 0.1);
				
				  var modelMatrix = new Matrix4();  // Model matrix
				  var Tx = -0.6;     // Translation distance
				  modelMatrix.setRotate(ANGLE, 0, 0, 1);  // Set rotation matrix
				  modelMatrix.translate(Tx, 0, 0); 
				  modelMatrix.rotate(ANGLE, 0, 1, 0); 
				  modelMatrix.translate(0.29, 0, 0); 
				  modelMatrix.rotate(ZANGLE, 0, 0, 1);// Multiply modelMatrix by the calculated translation matrix
				  var mvpMatrix = new Matrix4();   // Model view projection matrix
				  var normalMatrix = new Matrix4(); // Transformation matrix for normals
				  //TODO
				  var mvpMatrixFromLight = new Matrix4();
				
				  // Pass the model matrix to u_ModelMatrix
				  gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
				
				  // Calculate the view projection matrix
				  mvpMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);
				  mvpMatrix.lookAt(3, 3, 5, 0, 0, 0, 0, 0, 1);
				  mvpMatrix.multiply(modelMatrix);
				  // Pass the model view projection matrix to u_MvpMatrix
				  gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
				   //TODO
				  mvpMatrixFromLight.setPerspective(30, canvas.width/canvas.height, 1, 100);
				  mvpMatrixFromLight.lookAt(-5.0, 7.0, 8.0, 0, 0, 0, 0, 0, 1);
				  mvpMatrixFromLight.multiply(modelMatrix);
				  //设置阴影矩阵
				  gl.uniformMatrix4fv(u_MvpMatrixFromLight, false, mvpMatrixFromLight.elements);
				
				  // Calculate the matrix to transform the normal based on the model matrix
				  normalMatrix.setInverseOf(modelMatrix);
				  normalMatrix.transpose();
				  // Pass the transformation matrix for normals to u_NormalMatrix
				  gl.uniformMatrix4fv(u_NormalMatrix, false, normalMatrix.elements);
				  //纹理
				  var texture = gl.createTexture();   // Create a texture object
				  var u_Sampler = gl.getUniformLocation(gl.program, 'u_Sampler');
				  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); // Flip the image's y axis
				  // Enable texture unit0
				  gl.activeTexture(gl.TEXTURE0);
				  // Bind the texture object to the target
				  gl.bindTexture(gl.TEXTURE_2D, texture);			
				  // Set the texture parameters
				  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
				  // Set the texture image
				  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, imageMoon);
				  // Set the texture unit 0 to the sampler
				  gl.uniform1i(u_Sampler, 0);
				  
				  //设置阴影纹理渲染TODO
	             // var u_ShadowMap = gl.getUniformLocation(gl.program, 'u_ShadowMap');
//	              gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0);
//	              // Enable texture unit0
//				  gl.activeTexture(gl.TEXTURE1);
//				  // Bind the texture object to the target
//				  gl.bindTexture(gl.TEXTURE_2D, fbo.texture);	
//				  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
//			      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
				  //gl.uniform1i(u_ShadowMap, 1);
				   // Draw the cube(Note that the 3rd argument is the gl.UNSIGNED_SHORT)
	              gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_SHORT, 0);	
	            
		   }
		   function initVertexBuffers(gl,size,need) { // Create a sphere
			  var SPHERE_DIV = 13;
			
			  var i, ai, si, ci;
			  var j, aj, sj, cj;
			  var p1, p2;
			
			  var positions = [];
			  var indices = [];
			  var textures = [];
			  // Generate coordinates
			  for (j = 0; j <= SPHERE_DIV; j++) {
			    aj = j * Math.PI / SPHERE_DIV;
			    sj = Math.sin(aj);
			    cj = Math.cos(aj);
			    for (i = 0; i <= SPHERE_DIV; i++) {
			      ai = i * 2 * Math.PI / SPHERE_DIV;
			      si = Math.sin(ai);
			      ci = Math.cos(ai);
			      positions.push(size*si * sj);  // X
			      positions.push(size*cj);       // Y
			      positions.push(size*ci * sj);  // Z
			      //设置纹理坐标
			      let heigh = j/SPHERE_DIV
			      let width = i/SPHERE_DIV
			      textures.push(width);
			      textures.push(heigh);
			    }
			  }
			
			  // Generate indices
			  for (j = 0; j < SPHERE_DIV; j++) {
			    for (i = 0; i < SPHERE_DIV; i++) {
			      p1 = j * (SPHERE_DIV+1) + i;
			      p2 = p1 + (SPHERE_DIV+1);
			      indices.push(p1);
			      indices.push(p2);
			      indices.push(p1 + 1);
			      indices.push(p1 + 1);
			      indices.push(p2);
			      indices.push(p2 + 1);
			    }
			  }
			
			  // Write the vertex property to buffers (coordinates and normals)
			  // Same data can be used for vertex and normal
			  // In order to make it intelligible, another buffer is prepared separately
			  if (!initArrayBuffer(gl, 'a_Position', new Float32Array(positions), gl.FLOAT, 3)) return -1;
			  if(!need){
			  	 if (!initArrayBuffer(gl, 'a_Normal', new Float32Array(positions), gl.FLOAT, 3))  return -1;
			  	 if (!initArrayBuffer(gl, 'a_TexCoord', new Float32Array(textures), gl.FLOAT, 2))  return -1;
			  }
			  // Unbind the buffer object
			  gl.bindBuffer(gl.ARRAY_BUFFER, null);
			
			  // Write the indices to the buffer object
			  var indexBuffer = gl.createBuffer();
			  if (!indexBuffer) {
			    console.log('Failed to create the buffer object');
			    return -1;
			  }
			  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
			  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
			
			  return indices.length;
			}
			
			function initArrayBuffer(gl, attribute, data, type, num) {
			  // Create a buffer object
			  var buffer = gl.createBuffer();
			  if (!buffer) {
			    console.log('Failed to create the buffer object');
			    return false;
			  }
			  // Write date into the buffer object
			  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
			  gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
			  // Assign the buffer object to the attribute variable
			  var a_attribute = gl.getAttribLocation(gl.program, attribute);
			  if (a_attribute < 0) {
			    console.log('Failed to get the storage location of ' + attribute);
			    return false;
			  }
			  gl.vertexAttribPointer(a_attribute, num, type, false, 0, 0);
			  // Enable the assignment of the buffer object to the attribute variable
			  gl.enableVertexAttribArray(a_attribute);
			
			  gl.bindBuffer(gl.ARRAY_BUFFER, null);
			
			  return true;
			}
			
			function initFramebufferObject(gl) {
			  var framebuffer, texture, depthBuffer;
			
			  // Define the error handling function
			  var error = function() {
			    if (framebuffer) gl.deleteFramebuffer(framebuffer);
			    if (texture) gl.deleteTexture(texture);
			    if (depthBuffer) gl.deleteRenderbuffer(depthBuffer);
			    return null;
			  }
			
			  // Create a framebuffer object (FBO)
			  framebuffer = gl.createFramebuffer();
			  if (!framebuffer) {
			    console.log('Failed to create frame buffer object');
			    return error();
			  }
			
			  // Create a texture object and set its size and parameters
			  texture = gl.createTexture(); // Create a texture object
			  if (!texture) {
			    console.log('Failed to create texture object');
			    return error();
			  }
			  gl.bindTexture(gl.TEXTURE_2D, texture);
			  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
			  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
			
			  // Create a renderbuffer object and Set its size and parameters
			  depthBuffer = gl.createRenderbuffer(); // Create a renderbuffer object
			  if (!depthBuffer) {
			    console.log('Failed to create renderbuffer object');
			    return error();
			  }
			  gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
			  gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT);
			
			  // Attach the texture and the renderbuffer object to the FBO
			  gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
			  gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
			  gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer);
			
			  // Check if FBO is configured correctly
			  var e = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
			  if (gl.FRAMEBUFFER_COMPLETE !== e) {
			    console.log('Frame buffer object is incomplete: ' + e.toString());
			    return error();
			  }
			
			  framebuffer.texture = texture; // keep the required object
			
			  // Unbind the buffer object
			  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
			  gl.bindTexture(gl.TEXTURE_2D, null);
			  gl.bindRenderbuffer(gl.RENDERBUFFER, null);
			
			  return framebuffer;
			}
		</script>
	</body>
</html>

月球图片

                                                      地球图片

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值