day01作业打卡

WebGL简介

WebGL(全写Web Graphics Library)是一种3D绘图协议,这种绘图技术标准允许把JavaScriptOpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化

WebGL使用需要图形学知识,对WebGL编程可以通过js和glsl两种语言。如果想直接使用WebGL,使用者可以采用着色器(Shader)用来实现图像渲染的,但对于新手来说,Shader还是困难的。这时我们可以使用Three.js来简化我们对底层图形学的开发知识,更快的上手3D开发过程。

与2D技术相比,Web3D技术运用,可以通过三维呈现,可以更立体,交互更好的展示企业信息,现在的很多智慧项目,如数字孪生,智慧城市都使用到了3D可视化技术。

Web3D的主要展示方式:

  • 第一种:浏览器直接渲染:电脑浏览器、移动端浏览器(包括微信浏览器) 微信小程序;
  • 第二种:服务端渲染(服务端运行,效果好,运营成本高);将3D画面像素推流到前端浏览器/小程序展示;

3D近几年流行的相关概念:

  • 数字孪生:三维实景模型 + 多系统监控/告警数据,实现远程监管(监控、管理);
  • VR:把人装进虚拟环境
  • AR:把虚拟装进现实

浏览器运行3D的方案

  1. ActiveX插件: IE、Chrome老版本、Firefox老版本,已过时;
  2. Flash: 时代王者,官方已停止维护;
  3. WebGL: 浏览器原生支持(IE11基本支持,其它浏览器基本都支持)
  4. WebGPU: 性能高,目前还未得到操作系统和浏览器的广泛支持;

可实现发布WebGL到浏览器的运行方案(从重到轻):

Three.js基础

官网以及下载

Three.js的官网
Three.js下载地址:github下载, 国内码云

什么是3D模型,模型由什么构成?什么是贴图?

3D模型为三维立体展示的模型,模型由网格、材质、贴图等部分组成,贴图的作用是描述物体表面的材质。

空间坐标系

相机类型

基础场景三大件

  • scene 场景 new THREE.Scene();
  • camera 相机 new THREE.PerspectiveCamera(75.windw)
  • renderer 渲染器 new THREE.WebGLRenderer();

灯光

材质

Blender美术协作基础

Blender简介

Blender是一款免费开源三维图形图像软件,提供从建模、动画、材质、渲染、到音频处理、视频剪辑等一系列动画短片制作解决方案。
Blender拥有方便在不同工作下使用的多种用户界面,内置绿屏抠像、摄像机反向跟踪、遮罩处理、后期结点合成等高级影视解决方案。Blender内置有Cycles渲染器与实时渲染引擎EEVEE 。同时还支持多种第三方渲染器。
Blender为全世界的媒体工作者和艺术家而设计,可以被用来进行三维可视化,同时也可以创作广播和电影级品质的视频,另外内置的实时三维游戏引擎,让制作独立回放的三维互动内容成为可能(游戏引擎在2.8版本被移除)。

Blender功能

完整集成的创作套件,提供了全面的 3D 创作工具,包括:

建模(Modeling)、UV 映射(uv-Mapping)、贴图(Texturing)、绑定(Rigging)、蒙皮(Skinning)、动画(Animation)、粒子(Particle)和其它系统的物理学模拟(Physics)、脚本控制(Scripting)、渲染(Rendering)、运动跟踪(Motion Tracking)、合成(Compositing)、后期处理(Post-production)和游戏制作(已移除 [1] );

跨平台支持:

它基于 OpenGL 的图形界面在任何平台上都是一样的(而且可以通过 Python 脚本自定义),可以工作在所有主流的 Windows(10、8、7、Vista)、Linux、OS X 等众多其它操作系统上;

Blender下载与安装

Blender官方下载

将下载好的安装包blender-3.4.0-windows-x64.msi直接运行

软件默认是英文的,在欢迎页面可以选择中文和英文,也可以在进入软件后,依次点击Edit-Preference,进入设置界面选择各自的语言。

Blender视图基本操作

获取模型资源

www.sketchfab.com

Three.js掉落的甜甜圈案例编写代码并运行

import * as THREE from 'three';
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader';let mixer;const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 10);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);camera.position.set(0.3, 0.3, 0.5);const controls = new OrbitControls(camera, renderer.domElement);// scene.background = new THREE.Color(0.6, 0.6, 0.6);// const ambientLight = new THREE.AmbientLight(0xffffff, 0.2);
// scene.add(ambientLight);const directionLight = new THREE.DirectionalLight(0xffffff, 0.4);
scene.add(directionLight);// const boxGeometry = new THREE.BoxGeometry(1,1,1);
// const boxMaterial = new THREE.MeshBasicMaterial({color: 0x00ff00});
// const boxMesh = new THREE.Mesh(boxGeometry, boxMaterial);
// scene.add(boxMesh);let donuts;
new GLTFLoader().load('../resources/models/donuts.glb', (gltf) => {console.log(gltf);scene.add(gltf.scene);donuts = gltf.scene;// gltf.scene.traverse((child)=>{//     console.log(child.name);// })mixer = new THREE.AnimationMixer(gltf.scene);const clips = gltf.animations; // 播放所有动画clips.forEach(function (clip) {const action = mixer.clipAction(clip);action.loop = THREE.LoopOnce;// 停在最后一帧action.clampWhenFinished = true;action.play();});})new RGBELoader().load('../resources/sky.hdr', function (texture) {scene.background = texture;texture.mapping = THREE.EquirectangularReflectionMapping;scene.environment = texture;renderer.outputEncoding = THREE.sRGBEncoding;renderer.render(scene, camera);
});function animate() {requestAnimationFrame(animate);renderer.render(scene, camera);controls.update();if (donuts){donuts.rotation.y += 0.01;}if (mixer) {mixer.update(0.02);}
}animate();

代码运行大功告成!

day02作业打卡

用blender建立自己的展馆模型
blender用到的知识点有:面、边、顶点、添加字体、uv展开,旋转、移动、缩放等操作。
其中uv展开非常重要,是为了使物体更好展示部分贴图的展现,包括块面投影、柱面投影、球面投影。

blender建立展馆模型

three.js展示展馆模型编写代码并运行

import * as THREE from 'three';
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader';let mixer;const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 100);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);camera.position.set(5, 10, 25);const controls = new OrbitControls(camera, renderer.domElement);scene.background = new THREE.Color(0.2, 0.2, 0.2);const directionLight = new THREE.DirectionalLight(0xffffff, 0.4);
scene.add(directionLight);new GLTFLoader().load('../resources/models/test.glb', (gltf) => {// console.log(gltf);scene.add(gltf.scene);gltf.scene.traverse((child)=>{// console.log(child.name);if (child.name === '2023' || child.name === '眼称') {const video = document.createElement('video');video.src = "./resources/yanhua.mp4";video.muted = true;video.autoplay = "autoplay";video.loop = true;video.play();const videoTexture = new THREE.VideoTexture(video);const videoMaterial = new THREE.MeshBasicMaterial({map: videoTexture});child.material = videoMaterial;}if (child.name === '大屏幕01') {const video = document.createElement('video');video.src = "./resources/video01.mp4";video.muted = true;video.autoplay = "autoplay";video.loop = true;video.play();const videoTexture = new THREE.VideoTexture(video);const videoMaterial = new THREE.MeshBasicMaterial({map: videoTexture});child.material = videoMaterial;}if (child.name === '大屏幕02' || child.name === '操作台屏幕') {const video = document.createElement('video');video.src = "./resources/video01.mp4";video.muted = true;video.autoplay = "autoplay";video.loop = true;video.play();const videoTexture = new THREE.VideoTexture(video);const videoMaterial = new THREE.MeshBasicMaterial({map: videoTexture});child.material = videoMaterial;}if (child.name === '环形屏幕') {const video = document.createElement('video');video.src = "./resources/video02.mp4";video.muted = true;video.autoplay = "autoplay";video.loop = true;video.play();const videoTexture = new THREE.VideoTexture(video);const videoMaterial = new THREE.MeshBasicMaterial({map: videoTexture});child.material = videoMaterial;}if (child.name === '柱子屏幕') {const video = document.createElement('video');video.src = "./resources/yanhua.mp4";video.muted = true;video.autoplay = "autoplay";video.loop = true;video.play();const videoTexture = new THREE.VideoTexture(video);const videoMaterial = new THREE.MeshBasicMaterial({map: videoTexture});child.material = videoMaterial;}})mixer = new THREE.AnimationMixer(gltf.scene);const clips = gltf.animations; // 播放所有动画clips.forEach(function (clip) {const action = mixer.clipAction(clip);action.loop = THREE.LoopOnce;// 停在最后一帧action.clampWhenFinished = true;action.play();});})new RGBELoader().load('../resources/sky.hdr', function (texture) {// scene.background = texture;texture.mapping = THREE.EquirectangularReflectionMapping;scene.environment = texture;renderer.outputEncoding = THREE.sRGBEncoding;renderer.render(scene, camera);
});function animate() {requestAnimationFrame(animate);renderer.render(scene, camera);controls.update();// if (donuts){//     donuts.rotation.y += 0.01;// }if (mixer) {mixer.update(0.02);}
}animate();

代码编写运行大功告成!

day03作业打卡

用Three.js实现控制角色在展厅中自由游览

blender人物动作的制作

人物行走、站立动作如何合并?

在blender中,layout窗口,选择非线性动画,引入两个动作。动作编辑完毕,选择物体进行烘焙动作,选择姿态并确认,生成Acion,人物动作制作完成。



threejs阴影设置

阴影四步走:

  1. 打开renderer阴影
  2. 打开灯光阴影;设置灯光阴影大小
  3. 设置灯光阴影体相机远近大小
  4. 设置mesh投射、接收阴影
// 1 打开renderer阴影const renderer = new THREE.WebGLRenderer();renderer.shadowMap.enabled = true;
// 2.1 打开灯光阴影const light = new THREE.DirectionalLight( 0xffffff, 1 );light.position.set( 0, 1, 0 );light.castShadow = true; // 默认值falsescene.add( light );
// 2.2 设置灯光阴影贴图大小light.shadow.mapSize.width = 512; //默认值light.shadow.mapSize.height = 512; //默认值
// 3 设置阴影体 远近 大小,不在这之内的显示不出来light.shadow.camera.near = 0.5; //默认值light.shadow.camera.far = 500; //默认值light.shadow.camera.left = -shadowDistance;light.shadow.camera.right = shadowDistance;light.shadow.camera.top = shadowDistance;light.shadow.camera.bottom = -shadowDistance;
// 4 设置Mesh 投射阴影 接收阴影 gltf.scene.traverse((child) => {child.castShadow = true;child.receiveShadow = true;})
// 阴影调试辅助工具const helper = new THREE.CameraHelper( light.shadow.camera );scene.add( helper );

角色人物控制

  • 简易角色控制相机:
playerMesh.add(camera);
camera.position.y = 2;
camera.position.z = -3;
camera.lookAt(playerMesh.position);
  • 动作面片剪辑工具:
const clipIdle = THREE.AnimationUtils.subclip(gltf.animations[0], 'idle', 31, 281);
actionIdle = playerMixer.clipAction(clipIdle);
actionIdle.play();
  • 渐变切换动画工具函数:
function crossPlay(curAction, newAction) {curAction.fadeOut(0.3);newAction.reset();newAction.setEffectiveWeight(1);newAction.play();newAction.fadeIn(0.3);
}

角色人物碰撞

        // THREE.Raycaster实现角色碰撞检测:const curPos = playerMesh.position.clone();playerMesh.translateZ(1);const frontPos = playerMesh.position.clone();playerMesh.translateZ(-1);const frontVector3 = frontPos.sub(curPos).normalize();const raycasterFront = new THREE.Raycaster(playerMesh.position.clone().add(playerHalfHeight), frontVector3);const collisionResultsFrontObjs = raycasterFront.intersectObjects(scene.children);console.log(collisionResultsFrontObjs);if (collisionResultsFrontObjs && collisionResultsFrontObjs[0].distance > 1) {playerMesh.translateZ(3 * deltaTime);}// 优化角色移动流畅度let deltaTime;const clock = new THREE.Clock();function animate() {requestAnimationFrame(animate);renderer.render(scene, camera);deltaTime = clock.getDelta();};

Three.js实现控制角色在展厅中自由游览代码编写并运行

import * as THREE from 'three';
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader';let mixer;
let playerMixer;const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 50);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.shadowMap.enabled = true;
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);scene.background = new THREE.Color(0.2, 0.2, 0.2);
const ambientLight = new THREE.AmbientLight(0xffffff, 0.1);
scene.add(ambientLight);const directionLight = new THREE.DirectionalLight(0xffffff, 0.2);
scene.add(directionLight);directionLight.lookAt(new THREE.Vector3(0, 0, 0));directionLight.castShadow = true;directionLight.shadow.mapSize.width = 2048;
directionLight.shadow.mapSize.height = 2048;const shadowDistance = 20;
directionLight.shadow.camera.near = 0.1;
directionLight.shadow.camera.far = 40;
directionLight.shadow.camera.left = -shadowDistance;
directionLight.shadow.camera.right = shadowDistance;
directionLight.shadow.camera.top = shadowDistance;
directionLight.shadow.camera.bottom = -shadowDistance;
directionLight.shadow.bias = -0.001;let playerMesh;
let actionWalk, actionIdle;
const lookTarget = new THREE.Vector3(0, 2, 0);
new GLTFLoader().load('../resources/models/player2.glb', (gltf) => {playerMesh = gltf.scene;scene.add(gltf.scene);playerMesh.traverse((child)=>{child.receiveShadow = true;child.castShadow = true;})playerMesh.position.set(13, 0, 0);playerMesh.rotateY(-Math.PI/2);playerMesh.add(camera);camera.position.set(0, 2, -5);camera.lookAt(lookTarget);const pointLight = new THREE.PointLight(0xffffff, 0.1);playerMesh.add(pointLight);pointLight.position.set(0, 1.8, -1);playerMixer = new THREE.AnimationMixer(gltf.scene);const clipWalk = THREE.AnimationUtils.subclip(gltf.animations[0], 'walk', 0, 29);actionWalk = playerMixer.clipAction(clipWalk);// actionWalk.play();const clipIdle = THREE.AnimationUtils.subclip(gltf.animations[0], 'idle', 30, 281);actionIdle = playerMixer.clipAction(clipIdle);actionIdle.play();});let isWalk = false;
const playerHalfHeight = new THREE.Vector3(0, 0.8, 0);
window.addEventListener('keydown', (e) => {if (e.key === 'w') {const curPos = playerMesh.position.clone();playerMesh.translateZ(1);const frontPos = playerMesh.position.clone();playerMesh.translateZ(-1);const frontVector3 = frontPos.sub(curPos).normalize()const raycasterFront = new THREE.Raycaster(playerMesh.position.clone().add(playerHalfHeight), frontVector3);const collisionResultsFrontObjs = raycasterFront.intersectObjects(scene.children);console.log(collisionResultsFrontObjs);if (collisionResultsFrontObjs && collisionResultsFrontObjs[0] && collisionResultsFrontObjs[0].distance > 1) {playerMesh.translateZ(0.1);}if (!isWalk) {crossPlay(actionIdle, actionWalk);isWalk = true;}}if (e.key === 's') {playerMesh.translateZ(-0.1);}
})window.addEventListener('keyup', (e) => {if (e.key === 'w') {crossPlay(actionWalk, actionIdle);isWalk = false;}
});let preClientX;
window.addEventListener('mousemove', (e) => {if (preClientX && playerMesh) {playerMesh.rotateY(-(e.clientX - preClientX) * 0.01);}preClientX = e.clientX;
});let happayNewYear2023;
new GLTFLoader().load('../resources/models/test.glb', (gltf) => {// console.log(gltf);scene.add(gltf.scene);gltf.scene.traverse((child)=>{child.castShadow = true;child.receiveShadow = true;if (child.name === '2023' || child.name === '眼称') {const video = document.createElement('video');video.src = "./resources/yanhua.mp4";video.muted = true;video.autoplay = "autoplay";video.loop = true;video.play();const videoTexture = new THREE.VideoTexture(video);const videoMaterial = new THREE.MeshBasicMaterial({map: videoTexture});child.material = videoMaterial;}if (child.name === '大屏幕01') {const video = document.createElement('video');video.src = "./resources/video01.mp4";video.muted = true;video.autoplay = "autoplay";video.loop = true;video.play();const videoTexture = new THREE.VideoTexture(video);const videoMaterial = new THREE.MeshBasicMaterial({map: videoTexture});child.material = videoMaterial;}if (child.name === '大屏幕02' || child.name === '操作台屏幕') {const video = document.createElement('video');video.src = "./resources/video01.mp4";video.muted = true;video.autoplay = "autoplay";video.loop = true;video.play();const videoTexture = new THREE.VideoTexture(video);const videoMaterial = new THREE.MeshBasicMaterial({map: videoTexture});child.material = videoMaterial;}if (child.name === '环形屏幕') {const video = document.createElement('video');video.src = "./resources/video02.mp4";video.muted = true;video.autoplay = "autoplay";video.loop = true;video.play();const videoTexture = new THREE.VideoTexture(video);const videoMaterial = new THREE.MeshBasicMaterial({map: videoTexture});child.material = videoMaterial;}if (child.name === '柱子屏幕') {const video = document.createElement('video');video.src = "./resources/yanhua.mp4";video.muted = true;video.autoplay = "autoplay";video.loop = true;video.play();const videoTexture = new THREE.VideoTexture(video);const videoMaterial = new THREE.MeshBasicMaterial({map: videoTexture});child.material = videoMaterial;}})mixer = new THREE.AnimationMixer(gltf.scene);const clips = gltf.animations; // 播放所有动画clips.forEach(function (clip) {const action = mixer.clipAction(clip);action.loop = THREE.LoopOnce;// 停在最后一帧action.clampWhenFinished = true;action.play();});})new RGBELoader().load('../resources/sky.hdr', function (texture) {scene.background = texture;texture.mapping = THREE.EquirectangularReflectionMapping;scene.environment = texture;renderer.outputEncoding = THREE.sRGBEncoding;renderer.render(scene, camera);
});function crossPlay(curAction, newAction) {curAction.fadeOut(0.3);newAction.reset();newAction.setEffectiveWeight(1);newAction.play();newAction.fadeIn(0.3);
}function animate() {requestAnimationFrame(animate);renderer.render(scene, camera);// controls.update();if (mixer) {mixer.update(0.02);}if (playerMixer) {playerMixer.update(0.015);}
}animate();

代码编写运行大功告成!

学习地址:

加入猿创营 (v:dashuailaoyuan),一起交流学习

元宇宙基础-Three.js | 大帅老猿threejs特训营相关推荐

  1. Three.js入门 (参考胖达老师)| 大帅老猿threejs特训

    Three.js入门  (参考胖达老师的B站视频)  | 大帅老猿threejs特训 第一天 Three.js基础 空间坐标系   右手坐标系,threejs朝上是Y,朝右是X,朝屏幕外面是Z,Ble ...

  2. Blender基础建模 | 大帅老猿threejs特训

    最近接触到了web3d相关的知识,特别感觉"大帅老猿"和"胖达老师"带我入门! 今天来和大家一起讲讲我建模的故事!顺便教大家一起实现建模自由! 一.首先下载一个 ...

  3. Blender建模笔记 | 大帅老猿threejs特训

    写在前面 随着5G的普及网速变得越来快元宇宙的概念应然而生,需要多公司都开始搭建自己的沉浸式应用.搭建元宇宙项目的方案有很多种,比较常见的就是通过Threejs来实现.对于我们程序员由设计人员提供的模 ...

  4. 2天赚了4个W,手把手教你用Threejs搭建一个Web3D汽车展厅 | 大帅老猿threejs特训

    前言 事情是这样的,前段时间外包工头老杨又来找我了,说某汽车大品牌要开发一个网页展厅,希望可以在网页里360度展示它家新款汽车的3d模型,还要可以让用户DIY汽车部件的颜色. image.png 可能 ...

  5. THREEJS-甜甜圈的掉落| 大帅老猿threejs特训

    渲染第一个物体及场景 1.基本概念 三维的物体要渲染在二维的屏幕上.首先要创建一个场景来放置物体,那么最终怎么显示三维的内容,就应该找一个相机,将相机放在场景的某个位置,然后想要显示就要把相机拍的内容 ...

  6. 教你如何使用blender+threejs搭建一个3d展厅平台 | 大帅老猿threejs特训

    效果图 页面预览链接(服务器配置比较低,加载视频会比较慢,请耐心等候):https://static-8f957b23-c692-40ef-8f26-0a8a8e5422f1.bspapp.com/i ...

  7. 从甜甜圈到数字孪生| 大帅老猿threejs特训

    大家好,我是梦起,今天和大家一起来学习ThreeJs,早日实现ThreeJs自由. 首先,咱们需要安装threejs npm i three 然后,引入three import * as THREE ...

  8. 元宇宙:基础-虚拟现实栈开发和虚拟土地

    元宇宙--如何使用NFTs构建虚拟角色.虚拟环境.空间特征.虚拟土地的沉浸式购买 你会学到什么 元宇宙:从虚拟现实到虚拟双胞胎的基本概念 元宇宙:全栈开发,包括头像.传送.互操作性和隐私 元宇宙:如何 ...

  9. “元宇宙”基础知识汇总

    元宇宙即将到来,无论您是否准备好. 随着技术迅猛发展,我们很容易迷失方向--或者被抛在后面,但没有必要恐慌.本文为大家准备了元宇宙基础知识汇总,由元创元宇宙研究院融合了目前网络对元宇宙的描述和分析的多 ...

最新文章

  1. SynchronousQueue原理解析
  2. 信标灯、三轮车、电容充电
  3. Python应用02 Python服务器进化
  4. 【转载】#323 - A Generic Class is a Template for a Class
  5. 贪心算法设计作业调度c语言,贪心算法 - 数据结构与算法教程 - C语言网
  6. 【Vegas原创】远程桌面下重启xp系统的命令
  7. 【比赛】计算机领域有哪些常见的比赛
  8. 实用网站、软件、App分享
  9. MS08067 第一期 “恶意代码分析”实战班 12.17号开班~
  10. 航空三字代码表_航空运输三字代码表
  11. inode服务器与响应,inode客户端服务器下线请求和
  12. Excel分段线性插值函数实现
  13. php体检管理系统,学生健康体检信息管理系统
  14. 产品运营是什么,如何做产品运营?
  15. 服务器系统怎么用主板做RAID,超微主板如何创建RAID磁盘阵列 服务器组建RAID0、RAID1教程(图文)...
  16. android手机通过wifi控制数码管,淫技:android无屏操作之adb操控wifi
  17. Odbgscript Updated to 1.65.4 by sunbeam
  18. CDS — 数据管理分析平台
  19. 老年食堂:让社区生活充满“幸福滋味”
  20. CAD中 OLE不能旋转_CAD入门学习技巧:图块的各种相关操作和概念汇总(下)

热门文章

  1. 佐治亚理工计算机科学专业排名,佐治亚理工学院计算机科学硕士专业排名
  2. Vue子传父详细教程
  3. 用python画篮球场_如何使用 Python 创建一个 NBA 得分图?
  4. 程序员进阶攻略-笔记-051~061(完)
  5. julius开源语音识别引擎
  6. 论文翻译-A Comprehensive Survey on Graph Neural Networks《图神经网络GNN综述》
  7. 后端返回Json字符串出现乱码问题解决
  8. python 认证机构_利用Python爬了SIG官网BQB认证公司清单,我有一些重大发现..
  9. eclipes 快捷键操作:
  10. matlab 打开xml文件怎么打开方式,导入 XML 文档