3

【WebGL】纯手写Web端渲染器及其API

 2 years ago
source link: https://1keven1.github.io/2022/05/10/%E3%80%90WebGL%E3%80%91%E7%BA%AF%E6%89%8B%E5%86%99Web%E7%AB%AF%E6%B8%B2%E6%9F%93%E5%99%A8%E5%8F%8A%E5%85%B6API/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

SuzhiのBlog

【WebGL】纯手写Web端渲染器及其API

发表于2022-05-10|更新于2022-05-12|作品集技美网页
字数总计:965|阅读时长:3分钟|阅读量:|评论数:0

还在更新中,内容可能滞后或有变动

效果展示:

# 简介

在认真阅读并学习了WebGL Programming Guide一书后,萌生了制作一个Web端渲染器的想法。由于Web端的全平台特性,之后做了什么材质特效,可以在这个平台上制作展示效果后,无论是手机还是什么设备都可以实时观看,同时也可以很方便地以iframe的形式插入到博文中,顺便还能找机会学学web三件套,可谓是一举多得。

虽然我基本是完全没用过web三件套,但是我不信我硬写写不出来,直接开干。

结果,嘿,您猜怎么着?还真给我写出来了!

界面以及操作

预期要实现的功能为:可以编写简单脚本;可以修改shader并看到效果;可以旋转摄像机,放大缩小;

设计框架介绍

  • 整体为一个WebGLRenderer类,其中有表示场景的Scene类和负责代码编辑器的CodeEditor类
  • Scene类中储存着渲染需要用到的各种资源,渲染的基本单位为Mesh类
  • Actor类为可放置在世界中物品的基类,从其中派生出了Mesh、Light、Camera类。其中Mesh为可渲染的物品,包含一个模型(Model类)和一个材质(Material类);Light为灯光;Camera为摄像机;
  • Model类是3D模型,通过读入的Obj文件加载;
  • Material类是材质类,包含三个着色器(Shader类):Base、Add、ShadowCaster,分别负责主要光源着色、其他光源着色、阴影投射。玩家赋予的材质参数及其值也会储存在其中;
  • Shader类是着色器类,包括顶点着色器和片段着色器,通过读入的GLSL文件编译生成着色器代码。
  1. 【WebGL】从零开始的Web端渲染器(1)——框架搭建
  2. 更新中···

可编辑Script

控制整个场景的生成以及运行逻辑的脚本,在确认修改后会刷新渲染器重新开始渲染。整体而言还算比较复杂,所以基本上只用修改,不用删掉重写。

脚本结构:

// 新建场景内各类元素
// 包括相机 灯光 材质 模型 Mesh 贴图等;
let camera = new Camera(...);
let light = new Light(...);

// 材质由shader组成 shader由顶点和片段着色器文件组成
let shadowCaster = new Shader('...', '...');
let texShader = new Shader('...', '...');
let texMaterial = new Material(texShader, shadowCaster);

// Mesh为可渲染对象 由一个模型和一个材质组成
let cube = new Model('...');
let meshCube = new Mesh(new Transform(), cube, texMaterial);

// 根据具体情况 可能需要新建贴图
let textureOnion = new Texture('...', gl.TEXTURE_2D);

// 要编辑代码的Shader列表
this.codeEditor.editableShaderList = [texShader];
// 清屏颜色
this.clearColor = [0.1, 0.1, 0.11, 1.0];

// 构建场景函数
this.bulidScene = (scene) =>
{
// 需要构建的有 模型列表 材质列表 贴图列表
// Mesh列表 灯光列表 摄像机
// 只有传入Scene的资源会被初始化 未传入的资源不会被初始化 在运行时无法使用
scene.modelList = [cube, sphere, plane];
scene.materialList = [diffuseMaterial, texMaterial];
scene.textureList = [textureSky, textureOnion];
scene.meshList = [meshCube, floor];
scene.lightList = [light];
scene.camera = camera;
}

// 自定义开始游戏函数 在开始渲染时运行一次
this.customBeginPlay = () =>
{
// 写一些只用在开始时运行一次的逻辑
texMaterial.setVector3f('...', 0.2, 0.2, 0.2);
texMaterial.setTexture('...', textureOnion);
}

// 自定义Tick函数 渲染时逐帧运行
this.customTick = (deltaSecond) =>
{
// 写一些需要逐帧运行的逻辑
meshCube.addRotationOffset(new Vector3([0, 1.5, 0]).multiplyf(deltaSecond));
}

// 在下方可以写其他函数

Actor

Mesh(继承自Actor)

Light(继承自Actor)

Camera(继承自Actor)

Shader

Texture

Model

Material

其他函数库


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK