当前位置: 首页 > 文档资料 > A-Frame 中文文档 >

材质(material)

优质
小牛编辑
121浏览
2023-12-01

材质组件为实体提供外观。我们可以定义颜色、不透明度或纹理等属性。这通常和提供外形的 几何体组件一起工作。

我们可以注册自定义材质来扩展材质组件,以提供广泛的视觉效果。

目录

  • 例子

    使用默认标准材质定义红色材质:

    <a-entity geometry="primitive: box" material="color: red"></a-entity>

    下面是使用不同材质的示例:

    <a-entity geometry="primitive: box" material="shader: flat; color: red"></a-entity>

    下面是使用自定义材质的示例:

    <a-entity geometry="primitive: plane"
    material="shader: ocean; color: blue; wave-height: 10"></a-entity>

    属性

    材质组件具有一些基本特性。根据应用的材质类型,可以使用更多特性。

    属性描述默认值
    depthTest渲染材质时是否启用深度测试。true
    flatShading是否使用 THREE.FlatShading而非 THREE.StandardShading.false
    opacity透明度。如果 transparent属性没有被设置为 true,那么材质将保持为不透明而 opacity将只影响颜色。1.0
    transparent材料是否透明。透明实体在非透明实体之后呈现。false
    shader使用哪种材料。默认为 事件(Events)
    事件名称描述
    materialtextureloaded纹理加载到材质上。
    materialvideoloadeddata视频数据已加载并将播放。
    materialvideoended对于视频纹理,在视频结束时发射(可能无法使用 循环)。

    内置材质(Built-in Materials)

    A-Frame提供了一些内置材质。

    standard

    The standard材质是默认材质。它使用基于物理的 THREE.MeshStandardMaterial.

    属性

    这些特性在基础材料特性之上可用。

    属性描述默认值
    ambientOcclusionMap环境光遮挡贴图。用于向网格添加阴影。可以是 &lt;img&gt;内联URL。None
    ambientOcclusionMapIntensity环境光遮挡贴图的强度,介于0和1之间的数字。1
    ambientOcclusionTextureRepeat环境光遮挡纹理在X和Y方向重复多少次。1 1
    ambientOcclusionTextureOffset环境光遮挡纹理在x,y方向的偏移。0 0
    color基础漫反射颜色。#fff
    displacementMap位移图。用于扭曲网格。可以是&lt;img&gt;内联URL。None
    displacementScale位移图效果强度。1
    displacementBias位移图的零点。0.5
    displacementTextureRepeat置换纹理在X和Y方向重复多少次。1 1
    displacementTextureOffset置换纹理在x,y方向的偏移。0 0
    height定义视频纹理时的视频高度(以像素为单位)。360
    envMap反射的环境立方体贴图纹理。可以选择或以逗号分隔的URL列表。None
    fog材料是否受 fog所影响。true
    metalness材料的金属感,从 010.5
    normalMap法线贴图。用于添加复杂细节的视觉效果。可以是&lt;img&gt;内联URL。None
    normalScale法线贴图在X和Y方向上的效果比例。1 1
    normalTextureRepeat法线纹理在X和Y方向重复多少次。1 1
    normalTextureOffset法线纹理在x,y方向的偏移。0 0
    repeat纹理(定义为src)在X和Y方向重复的次数。1 1
    roughness材质粗糙度,从 01。较粗糙的材料比光滑的材料将反射光散射到更多的方向。0.5
    sphericalEnvMap反射的环境球形纹理。可以是&lt;img&gt;或内联URL。None
    width定义视频纹理时的视频宽度(以像素为单位)。640
    wireframe是否仅渲染几何体框线。false
    wireframeLinewidth以像素为单位的几何体框线宽度。2
    src图像或视频纹理贴图。可以是 <img>or <video>,或者一个内联URL。None

    基于物理的着色(Physically-Based Shading)

    基于物理的着色是一种着色处理模型,其目的是使材质在灯光条件下具有真实的行为。外观是入射光与材料特性相互作用的结果。

    为了达到真实感,漫反射 color, metalness, roughness必须精确控制材料的性质,通常是基于真实的材料研究。有些人已经为不同种类的材料编制了真实感数值图表,我们可以以此为出发点。

    例如,对于树皮材料,作为估计,我们可以设置:

    <a-entity geometry="primitive: cylinder"
    material="src: treebark.png; color: #696969; roughness: 1; metalness: 0">
    </a-entity>

    畸变图(Distortion Maps)

    有三个属性可以给几何体添加高级视觉效果:

    • 环境遮挡图(Ambient occlusion maps)- 将纹理应用于图像来添加阴影。
    • 位移图(Displacement maps)- 以高分辨率扭曲使简单模型获得更多细节。这可以影响网格的轮廓,但代价可能较大。
    • 法线贴图(Normal maps)- 定义曲面在该点的角度。在不扭曲模型的情况下呈现复杂的几何模型。这不会改变几何体,但法线贴图代价较小。

    环境贴图(Environment Maps)

    The envMapsphericalEnvMap属性定义材质所反映的环境。环境反射的清晰度取决于 metalness, 和 roughness属性。

    The sphericalEnvMap属性采用单个球形映射纹理。可以分配给 <a-sky>

    与纹理不同的是 envMap属性获取一个立方体映射,将六个图像组合在一起形成一个立方体。立方体贴图包围网格并被用作一个纹理。

    比如:

    <a-scene>
    <a-assets>
    <a-cubemap>
    <img src="right.png">
    <img src="left.png">
    <img src="top.png">
    <img src="bottom.png">
    <img src="front.png">
    <img src="back.png">
    </a-cubemap>
    </a-assets>

    <a-entity geometry="primitive: box" material="envMap: #sky; roughness: 0"></a-entity>
    </a-scene>

    flat

    flat使用 THREE.MeshBasicMaterial。平面材质不受场景照明条件的影响。这对图像或视频等东西很有用。设置 shaderflat:

    <a-entity geometry="primitive: plane" material="shader: flat; src: #cat-image"></a-entity>

    属性

    属性描述默认值
    color基础漫反射颜色。#fff
    fog材质是否受 fog所影响。true
    height定义视频纹理时的视频高度(像素)。360
    repeat纹理(定义为src)在X和Y方向重复的次数。1 1
    src图像或视频纹理贴图。可以是 &lt;img&gt;&lt;video&gt;或内联URL。None
    width定义视频纹理时的视频宽度(像素)。640
    wireframe是否仅渲染几何体线框。false
    wireframeLinewidth以像素为单位的几何体框线宽度。2

    贴图(Textures)

    若要使用内置材质之一设置纹理,请指定 src属性。 src可以是资产管理系统中的一个 <img>或者 <video>元素的选择器:

    <a-scene>
    <a-assets>
    <img src="texture.png">
    </a-assets>

    <a-entity geometry="primitive: box" material="src: #my-texture"></a-entity>
    </a-scene>

    src也可以是内联URL。请注意,我们没有通过此方法获取浏览器缓存或预加载。

    <a-scene>
    <a-entity geometry="primitive: box" material="src: url(texture.png)"></a-entity>
    </a-scene>

    大多数其他属性可以与纹理一起工作。例如 color属性将充当基色,并将每个像素与纹理相乘。设置为 #fff以保持纹理的原始颜色。

    A-Frame会缓存纹理而避免把冗余纹理推送到GPU。

    视频贴图(Video Textures)

    视频纹理后是否循环或自动播放取决于用于创建纹理的视频元素。如果我们只是传递一个URL而不是创建和传递一个视频元素,那么默认情况下纹理将循环并自动播放。否则,请在资产管理系统中创建一个视频元素,并为 id属性(例如, #my-video)传递一个选择器(selector):

    <a-scene>
    <a-assets>
    <!-- No loop. -->
    <video src="video.mp4" autoplay="true">
    </a-assets>

    <a-entity geometry="primitive: box" material="src: #my-video"></a-entity>
    </a-scene>

    控制视频纹理

    要控制视频播放,例如暂停或查找,可以使用video元素来 控制媒体播放。 比如:

    var videoEl = document.querySelector('#my-video');
    videoEl.currentTime = 122; // Seek to 122 seconds.
    videoEl.pause();

    如果要传递内联URL,则此操作不起作用。在这种情况下,A-Frame会在内部创建一个视频元素。要获得视频元素的handle,我们应该在 <a-assets>中定义一个。

    画布贴图(Canvas Textures)

    我们可以用&lt;canvas&gt;作为纹理源。当画布更改时,纹理将自动刷新自身。

    <script>
    AFRAME.registerComponent('draw-canvas', {
    schema: {default: ''},

    init: function () {
    this.canvas = document.getElementById(this.data);
    this.ctx = this.canvas.getContext('2d');

    // Draw on canvas...
    }
    });
    </script>

    <a-assets>
    <canvas crossorigin="anonymous"></canvas>
    </a-assets>

    <a-entity geometry="primitive: plane" material="src: #my-canvas"
    draw-canvas="my-canvas"></a-entity>

    重复纹理

    我们可能希望平铺纹理,而不是让它们拉伸。repeat属性可以用来指示重复纹理。

    <a-entity geometry="primitive: plane; width: 100"
    material="src: carpet.png; repeat: 100 20"></a-entity>

    透明问题

    透明度和alpha通道在三维图形中是很棘手的。如果您遇到的问题是,前景中的透明材质不能正确组合到背景中的材质上,那么这些问题可能是由于OpenGL合成器(WebGL是其API)的底层设计造成的

    在理想的场景中,A-Frame中的透明性应该没有问题,而不管开发人员将实体放在3D空间的何处,也不管他们在标记中定义元素的顺序如何。可实际情况是我们经常会遇到前景实体遮挡背景实体的场景。这会造成混乱和不必要的视觉缺陷。

    若要规避此问题,一种方法是尝试更改HTML中实体的顺序。

    注册自定义材料

    我们可以使用 AFRAME.registerShader来注册自定义材质的表现和效果。

    registerShader

    与组件一样,自定义材质具有模式(schema)和生命周期处理程序(lifecycle handler)。

    属性描述
    schema定义着色器所需使用的properties、uniforms、attributes来扩展材质组件。
    init在着色器初始化期间调用一次生命周期处理程序。用于创建材质。
    update在着色器初始化期间和数据更新时调用一次生命周期处理程序。用于更新材质或着色器(shader)。

    Schema

    我们可以像定义组件属性一样定义材质属性。数据将作为我们用来创建材料的数据:

    AFRAME.registerShader('custom', {
    schema: {
    emissive: {default: '#000'},
    wireframe: {default: false}
    }
    });

    要将数据值作为uniforms传递到着色器中,在定义中包含is:'uniform'

    AFRAME.registerShader('my-custom', {
    schema: {
    color: {type:'color', is:'uniform', default:'red'},
    opacity: {type:'number', is:'uniform', default:1.0}
    },
    ...