跳到主要内容

构建场景

下面使用 PlayCanvas Web Components 逐步搭建简单三维场景,最终得到蓝天下放在地面上的彩色球体,并理解每行代码的作用。

各代码片段都给出页面 body 的完整内容。外围 import map、脚本标签和样式沿用入门。若已完成前一页,请清空原场景,我们将从头构建并继续扩展。

起点​

先通过 <pc-app> 和 <pc-scene>,向 HTML body 添加应用基础结构。

<pc-app>
<pc-scene>
</pc-scene>
</pc-app>

这会创建空三维场景,但目前没有可见内容,还需要摄像机和对象。

备注

始终写闭合标签,例如 <pc-camera></pc-camera>。HTML 自定义元素不支持自闭合;浏览器会将 <pc-camera /> 当作开始标签,后续内容都会嵌套进去。

添加摄像机​

使用 <pc-entity> 和 <pc-camera> 添加摄像机,以观察场景。

<pc-app>
<pc-scene>
<pc-entity name="camera" position="0 0 5">
<pc-camera></pc-camera>
</pc-entity>
</pc-scene>
</pc-app>

摄像机位于 Z 轴正方向 5 单位处,默认朝负 Z,因此正对原点。当前画面为纯灰色,即默认清屏颜色:

摄像机默认清屏颜色形成的纯灰画面

虽然只有灰色,但说明渲染器已经运行。

添加对象​

通过 <pc-render> 添加球体,为场景提供可见对象。

<pc-app>
<pc-scene>
<pc-entity name="camera" position="0 0 5">
<pc-camera></pc-camera>
</pc-entity>
<pc-entity name="sphere">
<pc-render type="sphere"></pc-render>
</pc-entity>
</pc-scene>
</pc-app>

屏幕中央出现黑色圆盘。球体已存在,但场景没有灯光,表面没有照明,因此显示为黑色轮廓:

灰色背景上未受光的黑色球体

添加灯光​

使用 <pc-light>,在摄像机和球体之间添加平行光。

<pc-app>
<pc-scene>
<pc-entity name="camera" position="0 0 5">
<pc-camera></pc-camera>
</pc-entity>
<pc-entity name="light" rotation="45 45 0">
<pc-light type="directional"></pc-light>
</pc-entity>
<pc-entity name="sphere">
<pc-render type="sphere"></pc-render>
</pc-entity>
</pc-scene>
</pc-app>

将灯光旋转为斜向下照射,比正面照明更有立体感。球体现在有了明暗:

灰色背景上受光的白色球体

添加颜色​

目前都使用默认值,即白色材质和灰色背景。通过 <pc-material> 定义材质,直接放在 <pc-app> 下,因为它是共享资源,而非某一场景的一部分。渲染组件通过 material 属性引用材质 id。同时使用摄像机的 clear-color 修改背景。

<pc-app>
<pc-material id="crimson" diffuse="crimson"></pc-material>
<pc-scene>
<pc-entity name="camera" position="0 0 5">
<pc-camera clear-color="lightskyblue"></pc-camera>
</pc-entity>
<pc-entity name="light" rotation="45 45 0">
<pc-light type="directional"></pc-light>
</pc-entity>
<pc-entity name="sphere">
<pc-render type="sphere" material="crimson"></pc-render>
</pc-entity>
</pc-scene>
</pc-app>

这里使用 CSS 颜色名称。颜色还支持十六进制和空格分隔数字,完整规则详见属性。

浅蓝背景上的深红球体

添加地面​

为球体添加可落脚的地面:使用放大的 plane 图元和第二个材质。球体直径为 1,将其设为 position="0 0.5 0" 恰好落在平面上。抬高并倾斜摄像机以构图,为灯光添加 cast-shadows 生成阴影;这是存在即启用的布尔属性,详见属性。两个 bias 属性避免表面自阴影形成条纹,即阴影痤疮,详见修复阴影伪影。

<pc-app>
<pc-material id="crimson" diffuse="crimson"></pc-material>
<pc-material id="gray" diffuse="lightgray"></pc-material>
<pc-scene>
<pc-entity name="camera" position="0 1.5 6" rotation="-10 0 0">
<pc-camera clear-color="lightskyblue"></pc-camera>
</pc-entity>
<pc-entity name="light" rotation="45 45 0">
<pc-light type="directional" cast-shadows normal-offset-bias="0.05" shadow-bias="0.2"></pc-light>
</pc-entity>
<pc-entity name="sphere" position="0 0.5 0">
<pc-render type="sphere" material="crimson"></pc-render>
</pc-entity>
<pc-entity name="ground" scale="8 1 8">
<pc-render type="plane" material="gray"></pc-render>
</pc-entity>
</pc-scene>
</pc-app>

下面是最终场景的实时预览,标记与上述相同,编辑时会重新运行。

实时示例
<pc-app>
<pc-material id="crimson" diffuse="crimson"></pc-material>
<pc-material id="gray" diffuse="lightgray"></pc-material>
<pc-scene>
<pc-entity name="camera" position="0 1.5 6" rotation="-10 0 0">
<pc-camera clear-color="lightskyblue"></pc-camera>
</pc-entity>
<pc-entity name="light" rotation="45 45 0">
<pc-light type="directional" cast-shadows normal-offset-bias="0.05" shadow-bias="0.2"></pc-light>
</pc-entity>
<pc-entity name="sphere" position="0 0.5 0">
<pc-render type="sphere" material="crimson"></pc-render>
</pc-entity>
<pc-entity name="ground" scale="8 1 8">
<pc-render type="plane" material="gray"></pc-render>
</pc-entity>
</pc-scene>
</pc-app>

可以尝试:

  • 将灯光实体设为 rotation="70 45 0",模拟更低太阳,观察阴影拉长。
  • 删除 normal-offset-bias 和 shadow-bias,观察它们所避免的阴影痤疮。
  • 将球体 type 改为 "box",盒体尺寸同样为 1,因此仍恰好放在地上。

这就是一个完整场景:摄像机、灯光、几何体和材质,全部通过 HTML 组合。

元素层级​

刚搭建的结构遵循所有 PlayCanvas Web Components 文档通用的规则:

pc-app ................... 应用
├── pc-material .......... 应用级资源,也包括 pc-asset
└── pc-scene ............. 实体层级根节点
└── pc-entity ........ 场景图中的节点,实体可以嵌套
└── pc-camera .... 赋予实体功能的组件
(也包括 pc-light、pc-render 等)

后续步骤​