您的位置:首页 > 游戏 > 手游 > 小程序企业网站源码_网站和小程序的区别_南京百度竞价推广公司排名_网站关键词优化推广哪家好

小程序企业网站源码_网站和小程序的区别_南京百度竞价推广公司排名_网站关键词优化推广哪家好

2024/10/5 18:26:12 来源:https://blog.csdn.net/A1215383843/article/details/142458462  浏览:    关键词:小程序企业网站源码_网站和小程序的区别_南京百度竞价推广公司排名_网站关键词优化推广哪家好
小程序企业网站源码_网站和小程序的区别_南京百度竞价推广公司排名_网站关键词优化推广哪家好

目录

  • 准备WebGL上下文
  • 定义几何体
  • 创建顶点缓冲对象
  • 设置顶点属性
  • 定义几何体的面
  • 创建变换矩阵
  • 处理光照
  • 绑定纹理
  • 绘制3D对象
  • 性能优化
  • 添加动画
  • 复杂的光照模型
  • 纹理映射
  • 混合模式
  • 高级技术

准备WebGL上下文

首先,需要获取HTML5 <canvas>元素的WebGL上下文:

<canvas id="webgl-canvas"></canvas>
const canvas = document.getElementById('webgl-canvas');
const gl = canvas.getContext('webgl');

定义几何体

创建3D对象的第一步是定义几何体的顶点数据。这里以一个简单的立方体为例:

const vertices = [// 面1 (前)-1, -1,  1, // 01, -1,  1, // 11,  1,  1, // 2-1,  1,  1, // 3// 面2 (后)-1, -1, -1, // 4-1,  1, -1, // 51,  1, -1, // 61, -1, -1, // 7// ...其他面...
];

创建顶点缓冲对象

将顶点数据存储在顶点缓冲对象中,以便WebGL高效地处理:

const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

设置顶点属性

在顶点着色器中声明顶点属性,并在主程序中关联顶点缓冲对象:

const vertexShaderSource = `
attribute vec3 a_position;
void main() {gl_Position = vec4(a_position, 1.0);
}
`;const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
gl.enableVertexAttribArray(positionAttributeLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);

定义几何体的面

为每个面分配一组顶点,使用索引缓冲对象(Element Array Buffer):

const indices = [// 面10, 1, 2, 2, 3, 0,// 面24, 5, 6, 6, 7, 4,// ...其他面...
];const indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);

创建变换矩阵

创建模型、视图和投影矩阵,用于将3D空间的几何体转换为2D屏幕空间:

const modelMatrix = mat4.create();
const viewMatrix = mat4.create();
const projectionMatrix = mat4.create();// 示例:旋转立方体
mat4.rotate(modelMatrix, modelMatrix, Math.PI / 2, [1, 0, 0]); // 90度绕X轴旋转// 示例:设置相机位置
mat4.translate(viewMatrix, viewMatrix, [-3, 0, -5]);

处理光照

在片段着色器中计算光照效果。这里使用简单的一点光源:

const fragmentShaderSource = `
precision mediump float;
uniform vec3 u_lightPosition;
uniform vec3 u_color;varying vec3 v_normal;void main() {vec3 lightDirection = normalize(u_lightPosition - v_worldPosition);float intensity = max(dot(v_normal, lightDirection), 0.0);vec3 litColor = u_color * intensity;gl_FragColor = vec4(litColor, 1.0);
}`

绑定纹理

加载和应用纹理到3D对象:

const texture = loadTexture(gl, 'texture.jpg');function loadTexture(gl, url) {const texture = gl.createTexture();gl.bindTexture(gl.TEXTURE_2D, texture);gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);const image = new Image();image.onload = () => {gl.bindTexture(gl.TEXTURE_2D, texture);gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);gl.generateMipmap(gl.TEXTURE_2D);};image.src = url;return texture;
}

绘制3D对象

在主循环中,绘制3D对象:

function drawScene() {gl.viewport(0, 0, canvas.width, canvas.height);gl.clearColor(0.1, 0.1, 0.1, 1.0);gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);gl.enable(gl.DEPTH_TEST);gl.enable(gl.BLEND);gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);// 计算模型视图投影矩阵const mvpMatrix = mat4.create();mat4.multiply(mvpMatrix, projectionMatrix, viewMatrix);mat4.multiply(mvpMatrix, mvpMatrix, modelMatrix);// 绑定纹理gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D, texture);// 绘制立方体gl.useProgram(shaderProgram);gl.uniformMatrix4fv(shaderProgram.uniforms.u_mvpMatrix, false, mvpMatrix);gl.uniform3fv(shaderProgram.uniforms.u_lightPosition, [0, 10, 0]);gl.uniform3fv(shaderProgram.uniforms.u_color, [1, 0, 0]); // 红色gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
}setInterval(drawScene, 1000 / 60);

性能优化

使用VBO和EBO减少内存拷贝和提高效率。
使用视锥体剔除和背面剔除减少不必要的渲染。
使用多线程(Web Workers)处理复杂的计算任务。
使用分批渲染(Batch Rendering)减少渲染调用次数。
使用LOD(Level of Detail)根据距离动态调整细节级别。
使用实例化(Instancing)绘制多个相似的物体。

添加动画

为了使3D对象动态变化,我们可以修改模型矩阵(modelMatrix)中的旋转、平移或缩放值。例如,我们可以实现一个旋转动画:

let rotationAngle = 0;function animate() {requestAnimationFrame(animate);// 旋转立方体rotationAngle += 0.01;mat4.fromRotation(modelMatrix, rotationAngle, [0, 1, 0]);drawScene();
}
animate();

复杂的光照模型

简单的点光源不足以模拟真实世界的光照。可以实现更复杂的光照模型,如环境光、漫射光、镜面光和菲涅尔效应:

const fragmentShaderSource = `
precision mediump float;
uniform vec3 u_ambientLight;
uniform vec3 u_diffuseLight;
uniform vec3 u_specularLight;
uniform vec3 u_eyePosition;
uniform vec3 u_shininess;varying vec3 v_normal;
varying vec3 v_worldPosition;void main() {vec3 lightDirection;vec3 viewDirection;vec3 ambient, diffuse, specular;// 环境光ambient = u_ambientLight;// 漫射光lightDirection = normalize(u_lightPosition - v_worldPosition);diffuse = u_diffuseLight * max(dot(v_normal, lightDirection), 0.0);// 镜面光viewDirection = normalize(u_eyePosition - v_worldPosition);vec3 halfVector = normalize(lightDirection + viewDirection);specular = u_specularLight * pow(max(dot(v_normal, halfVector), 0.0), u_shininess);vec3 litColor = ambient + diffuse + specular;gl_FragColor = vec4(litColor, 1.0);
}`

纹理映射

除了颜色,我们还可以使用纹理来增加3D对象的细节。在片段着色器中,可以使用纹理坐标采样纹理:

uniform sampler2D u_texture;varying vec2 v_texCoord;void main() {vec4 texColor = texture2D(u_texture, v_texCoord);vec3 litColor = ... // 计算光照gl_FragColor = vec4(litColor * texColor.rgb, texColor.a);
}

在主程序中,设置纹理坐标属性,并在绘制时传入纹理:

const texCoordAttributeLocation = gl.getAttribLocation(shaderProgram, 'a_texCoord');
gl.enableVertexAttribArray(texCoordAttributeLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
gl.vertexAttribPointer(texCoordAttributeLocation, 2, gl.FLOAT, false, 0, 0);gl.uniform1i(shaderProgram.uniforms.u_texture, 0);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);

混合模式

WebGL支持多种混合模式,可以通过gl.blendFuncSeparate()gl.blendEquationSeparate()设置。例如,实现半透明混合:

gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);

高级技术

  • 阴影映射:使用额外的渲染通道和深度贴图模拟物体在其他物体上的阴影。
  • 法线映射:使用法线贴图模拟高光和凹凸感,无需额外的几何信息。
  • 环境映射:使用环境贴图模拟物体反射周围环境的外观。
  • GPU粒子系统:利用GPU的并行处理能力创建粒子效果,如火花、烟雾、水波等。
  • 屏幕空间后处理:在所有3D渲染完成后,对整个屏幕应用额外的效果,如模糊、色彩校正、抗锯齿等。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com