WebGL试玩(一)-- 环境搭建

本文介绍了一个基于WebGL的实时渲染框架,通过Games202课程的作业来讲解WebGL环境搭建过程及基本原理。涉及内容包括WebGL的初始化、模型加载、材质处理等,并深入探讨了模型渲染的具体实现。

Introduction

   实时渲染中的大部分基础内容已经复习差不多了。应该说,现在已经对实时渲染的一整套体系都有所了解了。开源引擎也仔细研读了几种。应该说已经略窥了实时渲染的核心内容。下一个阶段是整理实时渲染中工业阶中常用算法的代码实现。有一部分已经在Vulkan学习中实现了。渲染方程虽然实现过,但那也是很久远的事情了。但现阶段还是关注实时渲染。具体实现像材质相关,和RTRT相关算法。
  首先,还是从Games202入手,正好了解一下WebGL。之前本职是Java全栈程序员,JS自然很拿手。作业内容部分我会隐藏掉,毕竟老师的话还是要听的#109.

WebGL–Window下环境配置

  • 下载并安装 nodejs :http://nodejs.cn/download/
    • 安装完后:以管理员允许PowerShell
      • 输入:set-ExecutionPolicy RemoteSigned 回车
      • 输入 A 回车
      • 输出 npm -v 显示版本号表示安装成功
  • 下载并安装 VSCode :https://code.visualstudio.com/docs/?dv=win
    • 安装插件:Live Server
    • Ctrl+Shift+P -> 输入 Live Server -> Open with Live Server
  • Node.js 搭建本地服务器
    • 以管理员允许PowerShell
      • npm install http -server -g
      • cd 代码根目录
      • http -server . -p 8000
      • 浏览器输入:127.0.0.1:8000 (本人还是喜欢8080)

Homework0

index.html

  • lib文件夹:引用的第三方库
  • src文件夹:自己编写的代码
<!DOCTYPE html>
<html>
<head>
    <style>
        html,
        body {
   
   
            margin: 0;
            background-color: black;
            height: 100%;
            width: 100%;
            overflow: hidden;
        }
		//设置绘图标签大小
        #glcanvas {
     
     
            top: 0;
            width: 100%;
            height: 100%;
        }
    </style>
    //three.js 渲染引擎
    <script src="lib/three.js" defer></script>
    //相机控件
    <script src="lib/OrbitControls.js" defer></script>
    //加载材质使用的库
    <script type="text/javascript" src="lib/MTLLoader.js" defer></script>
    //加载模型使用的库
    <script type="text/javascript" src="lib/OBJLoader.js" defer></script>
    //图形用户界面库 
    <script type="text/javascript" src="lib/dat.gui.js" defer></script>
    //gl矩阵运算库
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.8.1/gl-matrix-min.js"
        integrity="sha512-zhHQR0/H5SEBL3Wn6yYSaTTZej12z0hVZKOv3TwCUXT1z5qeqGcXJLLrbERYRScEDDpYIJhPC1fk31gqR783iQ=="
        crossorigin="anonymous" defer> </script>
	//内置编写好的shader
    <script src="src/shaders/InternalShader.js" defer></script>
    //编译shader用到的脚本
    <script src="src/shaders/Shader.js" defer></script>
    //材质类,sampler、uniform 和 shader资源组成 
    <script src="src/materials/Material.js" defer></script>
    //贴图资源创建 sampler
    <script src="src/textures/Texture.js" defer></script>
	//自定义的一些几何体
    <script src="src/objects/Mesh.js" defer></script>
    //使用OBJLoader加载模型,并创建gpu资源
    <script src="src/loads/loadOBJ.js" defer></script>
    //加载shader
    <script src="src/loads/loadShader.js" defer></script>
	//灯光类,暂时看起来像平行光
    <script src="src/lights/Light.js" defer></script>
    //点光源
    <script src="src/lights/PointLight.js" defer></script>
	//渲染类
    <script src="src/renderers/WebGLRenderer.js" defer></script>
    //绑定模型gpu资源,并进行渲染
    <script src="src/renderers/MeshRender.js" defer></script>
    //engine类
    <script src="src/engine.js" defer></script>
</head>

<body>
	//绘图标签,即RenderWindow
    <canvas id="glcanvas"></canvas>

</body>

</html>

engine.js

  • engine.js 为程序入口
//全局变量 相机位置
var cameraPosition = [-20, 180, 250];
//JS加载后,立即运行该方法。
GAMES202Main();

function GAMES202Main() {
   
   
	//document.**()是js语法。用于查询标签,这里寻找的是id为glcanvas的图形标签
	const canvas = document.querySelector('#glcanvas');
	//js获取物理分辨率的宽高,设置当前图形标签宽高
	canvas.width = window.screen.width;
	canvas.height = window.screen.height;
	//获取gl
	const gl = canvas.getContext('webgl');
	if (!gl) {
   
   
		alert('Unable to initialize WebGL. Your browser or machine may not support it.');
		return;
	}
	//创建相机,这块就略掉,千篇一律
	const camera = new THREE.PerspectiveCamera(75, gl.canvas.clientWidth / gl.canvas.clientHeight, 0.1, 1000);
	const cameraControls = new THREE.OrbitControls(camera, canvas);
	cameraControls.enableZoom = true;
	cameraControls.enableRotate = true;
	cameraControls.enablePan = true;
	cameraControls.rotateSpeed = 0.3;
	cameraControls.zoomSpeed = 1.0;
	cameraControls.panSpeed = 2.0;
	//刷新相机用到的方法
	function setSize(width, height) {
   
   
		camera.aspect = width / height;
		camera.updateProjectionMatrix();
	}
	setSize(canvas.clientWidth, canvas.clientHeight);
	//监听到resize事件后重置相机投影矩阵
	window.addEventListener('resize', () => setSize(canvas.clientWidth, canvas.clientHeight));
	//相机eye
	camera.position.set(cameraPosition[0], cameraPosition[1], cameraPosition[2]);
	//相机target
	cameraControls.target.set(0, 1, 0);
	//新建点光源
	const pointLight = new PointLight(250, [1, 1, 1]);
	//创建renderer
	const renderer = new WebGLRenderer(gl, camera);
	renderer.addLight(pointLight);
	//加载模型
	loadOBJ(renderer, 'assets/mary/', 'Marry');

	var guiParams = {
   
   
		modelTransX: 0,
		modelTransY: 0,
		modelTransZ: 0,
		modelScaleX: 52,
		modelScaleY: 52,
		modelScaleZ: 52,
	}
	function createGUI() {
   
   
		const gui = new dat.gui.GUI();
		const panelModel = gui.addFolder('Model properties');
		const panelModelTrans = panelModel.addFolder('Translation');
		const panelModelScale = panelModel.addFolder('Scale');
		panelModelTrans.add(guiParams, 'modelTransX').name('X');
		panelModelTrans.add(guiParams, 'modelTransY').name('Y');
		panelModelTrans.add(guiParams, 'modelTransZ').name('Z');
		panelModelScale.add(guiParams, 'modelScaleX').name('X');
		panelModelScale.add(guiParams, 'modelScaleY').name('Y');
		panelModelScale.add(guiParams, 'modelScaleZ').name('Z');
		panelModel.open();
		panelModelTrans.open();
		panelModelScale.open();
	}
	//创建GUI
	createGUI();
	//渲染循环
	function mainLoop(now) {
   
   
		cameraControls.update();

		renderer.render(guiParams);
		requestAnimationFrame(mainLoop);
	}
	requestAnimationFrame(mainLoop);
}

loadOBJ.js


function loadOBJ(renderer, path, name) {
   
   
	//创建manager 
	const manager = new THREE.LoadingManager();
	//输出日志
	manager.onProgress = function (item, loaded, total) {
   
   
		console.log(item, loaded, total);
	};
	//应该是加载进度条
	function onProgress(xhr) {
   
   
		if (xhr.lengthComputable) {
   
   
			const percentComplete = xhr.loaded / xhr.total * 100;
			console.log('model ' + Math.round(percentComplete, 2) + '% downloaded');
		}
	}
	function onError() {
   
    }
	//加载材质信息
	new THREE.MTLLoader(manager)
		.setPath
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值