Three.js 纹理贴图的实现

在线工具推荐: 3D数字孪生场景编辑器  -  GLTF/GLB材质纹理编辑器  -  3D模型在线转换  -  Three.js AI自动纹理开发包  -  YOLO 虚幻合成数据生成器  -  三维模型预览图生成器  -  3D模型语义搜索引擎

纹理贴图简介

当我们创建一个网格时,比如我们不起眼的立方体,我们传入两个组件:几何体和材质。

网格需要两个子组件:几何体和材料

const mesh = new Mesh(geometry, material);

几何形状定义了网格的形状,材料定义了网格的各种表面属性,特别是它对光的反应。几何体和材质,以及影响网格的任何光影,在渲染场景时控制网格的外观。目前,我们的场景包含一个网格,其形状由 a 定义,曲面由 a 定义,颜色参数设置为紫色。这由单个 照亮,当我们渲染场景时,结果就是这个简单的紫色框。BoxBufferGeometryMeshStandardMaterialDirectionalLight

由 unsplash 的 @christianfregnan 提供

由混凝土制成的立方体。

将其与现实世界中的混凝土盒子进行比较 - 或木箱,或金属箱,或由几乎任何物质制成的盒子,除了光滑的塑料,我们可以立即看到我们的3D盒子根本不现实。现实世界中的物体通常是划伤、破损和肮脏的。但是,应用于我们盒子的材料看起来不是这样的。相反,它由平滑地应用于网格的整个表面的单一颜色组成。除非我们希望我们所有的作品看起来像全新的塑料,否则这是行不通的。

除了颜色之外,材质还有许多参数,我们可以用这些参数来调整物体表面的各种属性,如粗糙度、金属度、不透明度等。但是,就像颜色参数一样,这些参数均匀地应用于网格的整个表面。例如,如果我们增加材料的属性,物体的整个表面将变得更加粗糙。如果我们将 设置为红色,则整个对象将变为红色。.roughness.color

相比之下,大多数真实世界对象的表面属性从一个点到另一个点会发生变化。考虑一个代表人脸的网格。再一次,它由几何形状和材料组成,就像我们的立方体网格一样。大比例特征(如眼睛、鼻子、耳朵、颈部和下巴)由几何图形定义。然而,要创建逼真的面孔,不仅仅是精心制作的几何图形。仔细观察皮肤,我们可以看到有很多小肿块、皱纹和毛孔,更不用说眉毛、嘴唇和轻微的胡须了。在创建像人脸这样的复杂模型时,艺术家必须决定使用几何图形表示模型的哪些部分,以及在材质级别表示哪些部分,请记住,使用材料表示事物通常比几何图形便宜。当模型必须在移动设备上运行时,这是一个特别重要的考虑因素,因为高性能至关重要。例如,虽然可以在几何形状上对眉毛上的每根头发进行建模,但这样做会使该模型不适合在除最强大的设备之外的所有设备上实时使用。相反,我们必须在材质级别表示头发等小特征,并为眼睛、鼻子和耳朵等大比例特征保留几何图形。

另请注意,此面由单个几何图形组成。我们通常希望避免将几何体拆分得过多,因为每个网格只能有一个几何体,因此每个单独的几何体都对应于场景中的新网格。场景中的对象越少,性能越好,开发人员和 3D 美术师也更容易使用。换句话说,我们不想被迫为耳朵和眼睛创造不同的几何形状。无论如何,这是不切实际的。仔细观察嘴唇,我们可以看到嘴唇的红色和下巴的肤色之间没有明显的区别。这意味着我们需要某种方法来修改材料属性,以便它们可以在物体表面上平滑地变化。我们需要能够这样说:

  • 构成嘴唇的几何形状部分是红色的
  • 构成下巴的几何形状部分是肤色,上面覆盖着轻微的胡须
  • 构成眉毛的几何形状部分是头发颜色的

...等等。这不仅适用于颜色。例如,皮肤比头发和嘴唇更有光泽。因此,我们还需要能够指定其他属性(如粗糙度)如何在几何体中从一个点变化到下一个点。

李-佩里-史密斯-颜色.jpg

此颜色纹理使用 UV 映射映射到面部几何体上

这就是纹理映射的用武之地。用最简单的术语来说,纹理映射意味着拍摄图像并将其拉伸到 3D 对象的表面上。我们将以这种方式使用的图像称为纹理,我们可以使用纹理来表示颜色、粗糙度和不透明度等材质属性。例如,要更改几何体某个区域的颜色,我们将位于顶部的纹理区域的颜色更改为颜色,如附着在面部模型上的颜色纹理所示。

虽然获取 2D 纹理并将其拉伸到像立方体这样的规则形状上很容易,但对于像脸这样的不规则几何体来说,要做到这一点要困难得多,多年来,已经开发了许多纹理映射技术。也许最简单的技术是投影映射,它将纹理投射到物体(或场景)上,就好像它通过电影放映机照射一样。想象一下,把你的手放在电影放映机前,看到图像投射到你的皮肤上。

将 UV 坐标<br>明确写入纹理的测试纹理。

将 UV 坐标显式写入纹理的测试纹理。

虽然投影映射和其他技术仍然广泛用于创建阴影(或模拟投影仪)等操作,但这不适用于将面部的颜色纹理附加到面部几何体上。取而代之的是,我们使用一种称为UV映射的技术,它允许我们在几何体上的点和面上的点之间创建连接。使用UV贴图,我们将纹理划分为带有点的2D网格(0,0)在左下角和点(1,1)在右上角。然后,重点(0. 5,0.5)将位于图像的确切中心。同样,几何体中的每个点在网格的 3D 局部空间中都有一个位置。因此,UV 贴图是将纹理中的 2D 点分配给几何体中的 3D 点的过程。例如,假设面部模型中的嘴唇位于该点(0,0,0 ).我们可以看到纹理中的嘴唇靠近中心,在周围(0. 5,0.5).因此,我们将创建一个映射:

(0. 5,0.5)⟶(0,0,0 )

现在,当我们将纹理指定为材质中的颜色映射表时,纹理的中心将映射到嘴唇上。接下来,我们必须对几何体中的许多其他点执行相同的操作,将耳朵、眼睛、眉毛、鼻子和下巴分配给纹理的适当点。如果这听起来像是一个令人生畏的过程,请不要担心,因为手动执行此操作很少见。对于此模型,UV 贴图是在外部程序中创建的,通常,这是创建 UV 贴图的推荐方法。

表示UV贴图的数据存储在几何体上。像 这样的Three.js几何体已经设置了UV贴图,在大多数情况下,当您加载在外部程序中创建的模型(如面)时,它也将准备好UV贴图以供使用。在本章的后面,我们将更详细地探讨盒子几何体的UV贴图,并将黑白测试纹理分配给盒子网格。BoxBufferGeometry

一旦我们有了带有UV贴图的几何体,我们就可以获取任何纹理并将其应用于几何体,它就会立即起作用。但是,可能很难找到其他纹理在面部模型中看起来不错,因为必须仔细协调UV贴图才能将纹理与面部上的正确点相匹配,而做好这项工作是熟练的3D艺术家的工作。但是,对于像立方体这样的简单形状,我们可以使用几乎任何图像作为纹理,将盒子变成木箱、混凝土箱或板条箱,等等。

可以存储在纹理中的数据类型

在本章中,我们将重点介绍如何使用纹理来表示颜色。我们将获取 uv-test-bw.png 纹理,您可以在编辑器的 /assets/textures/ 文件夹中找到它,并将其拉伸到我们的立方体上。当我们这样做时,默认情况下,three.js 会在立方体的每个面上拉伸一个纹理副本,总共六个副本。

在计算机图形学的早期,纹理仅用于存储对象的颜色。然而,如今,纹理可用于存储各种数据,例如颜色、凹凸、不透明度、表面上的小阴影(称为环境光遮蔽)、照明、金属度和粗糙度,仅举几例。例如,不同的材质接受不同种类和组合的纹理,因此 不接受所有相同的纹理。我们将在本书后面更详细地介绍可以存储在纹理中的数据类型。MeshBasicMaterialMeshStandardMaterial

纹理类型

uv-test-bw.png 是一个以 PNG 格式存储的普通 2D 图像文件,下面,我们将使用 加载它,它将返回 Texture 类的实例。您可以以相同的方式使用浏览器支持的任何图像格式,例如 PNG、JPG、GIF、BMP。这是我们将遇到的最常见和最简单的纹理类型:存储在简单 2D 图像文件中的数据。TextureLoader

还有用于 HDR、EXR 和 TGA 等专用图像格式的加载器,它们具有相应的加载器,如 TGALoader。同样,一旦加载,我们将得到一个实例,我们可以以与加载的PNG或JPG图像大致相同的方式使用它。Texture

除此之外,three.js 还支持许多其他类型的纹理,这些纹理不是简单的 2D 图像,例如视频纹理、3D 纹理、画布纹理、压缩纹理、立方体纹理、等距柱状投影纹理等。同样,我们将在本书后面更详细地探讨这些内容。在本章的其余部分,我们将重点介绍以 PNG 或 JPG 格式存储的 2D 纹理。

Texture类

该类是 HTML 图像元素的包装器,其中包含一些与用作纹理而不是普通图像相关的额外设置。我们可以在 下访问原始图像。它是我们在处理纹理时最常用的类,尽管有几个派生类(如 VideoTexture 或 CubeTexture)用于处理其他类型的纹理。不过,通常我们不会直接创建一个,因为会自动为我们创建一个,我们将在下面看到。Textureimage.textureTextureTextureLoader

通过纹理类提供的设置示例包括 和 ,它们控制纹理到达边缘时的换行方式(例如,它是重复、简单地停止,还是将纹理的边缘拉伸到网格的边缘?我们还可以指定各种过滤(using 和 )来控制在远处或近距离看到纹理时的过滤方式。换句话说,这些设置控制用于放大或缩小图像的算法。.wrapS.wrapT.minFilter.magFilter

还有几个属性,如 ,,允许我们控制纹理的位置。另外两个重要设置是 ,它沿.offsetcenter.rotation.flipYY-axis(用于与在某些外部程序中创建的模型兼容)和属性,正如我们稍后将看到的,必须正确设置该属性才能获得最佳结果。.encoding

花几分钟时间浏览文档页面,并查看使用纹理时可用的选项。我们将在本书后面更详细地探讨其中的大多数。

创建纹理

有许多方法可以准备图像以用作纹理,但最简单的方法是拍摄对象的照片。例如,如果您拍摄了一张砖墙的照片并将其分配给材质的颜色槽,您将在场景中看到与 3D 墙的相似性。我们可以通过使用原始图像为其他材质属性(如凹凸或粗糙度)创建额外的纹理来改进这一点。在 freepbr.com 上查看这组纹理,以作个例子(选择虚幻引擎版本用于Three.js,请注意反照率颜色的另一个术语)。我们将在本书的后面部分探索使用一组这样的纹理来创建逼真的材质。

虽然拍摄平坦墙壁的照片是一件简单的事情,但像脸、树或兔子这样的曲面会带来更大的挑战。对于这样的表面,艺术家必须拼合照片,并将拼合图像中的每个点连接到 3D 模型上的相应点,再次使用 UV 贴图。这通常是在外部建模程序中完成的,而不是在 three.js 中完成的。

对于砖墙和木地板等常见表面,您可以在网络上找到高质量的纹理集(如上图),其中许多是免费的。在本书中,我们将使用来自Three.js存储库和 freepbr.com 或 Quixel megascan 等站点的纹理。

纹理术语

在继续加载纹理并将其应用于立方体之前,让我们回顾一下在处理纹理时将使用的所有技术术语。

图像和纹理有什么区别?

您会在计算机图形学文献中看到很多术语纹理图像。这些甚至通常以相同的格式存储,例如 PNG 或 JPG。有什么区别?

  • 图像是设计供人类查看的 2D 图片。
  • 纹理是专门准备的数据,用于 3D 图形中的各种目的

构成图像的各个像素表示颜色。另一种看待这个问题的方式是,图像是一个二维的颜色数组。在计算机图形学的早期,纹理也是如此,但随着时间的推移,纹理的用途越来越多,现在更正确的说法是纹理是数据的二维数组。此数据可以表示任何内容。如今,甚至可以将几何图形或动画存储在纹理中。

当纹理以 PNG 或 JPG 等图像格式存储时,我们可以在任何图像查看器中打开它。在本章中,我们将加载的纹理表示颜色数据,因此如果我们在查看器中打开它,它将看起来像图像。但是,用于其他目的的纹理(例如凹凸贴图、不透明度贴图、光照贴图等)通常看起来不像任何特别的东西,直到它们被应用于材质并由渲染器解释。

纹理贴图

虽然在技术上不正确,但纹理通常也被称为贴图,甚至是纹理贴图,尽管贴图在为材质分配纹理时最常用。当使用纹理来表示颜色时,我们会说我们正在将纹理分配给材质上的颜色映射表槽。下面,我们将向您展示如何将 uv-test-bw.png 纹理分配给 .MeshStandardMaterial

Pixel 和 Texel

数字图像是像素的 2D 数组,每个像素都是一个包含单一颜色的小点。我们的屏幕也由一个由小点组成的 2D 数组组成,每个小点都显示一种颜色,我们也称这些像素为像素。然而,构成屏幕的像素是实际的物理对象,LED或OLED或其他一些高科技设备,而构成图像的像素只是存储在文件中的数字。

为了避免混淆,我们将继续将构成屏幕像素的点称为,但我们将构成纹理的点称为纹素

UV映射

UV 贴图是一种将 2 维纹理映射到 3 维几何体上的方法。想象一下纹理顶部的 2D 坐标系,其中(0,0)在左下角和(1,1)在右上角。由于我们已经使用了字母X,Y和Z对于我们的 3D 坐标,我们将使用字母来指代 2D 纹理坐标U和V.这就是UV贴图这个名字的由来。

以下是UV贴图中使用的公式:

( u,v)⟶(x,y,z)

(u,v)表示纹理上的一个点,并且(x,y,z)表示几何体上的一个点,在局部空间中定义。从技术上讲,几何体上的点称为顶点

UV 将纹理映射到“BoxBufferGeometry”上
UV 将纹理映射到BoxBufferGeometry

在上图中,纹理的左上角已映射到具有坐标的立方体角上的顶点(−1,1,1):

( 0,1)⟶(−1,1,1)

对立方体的其他五个面进行了类似的映射,从而在立方体的六个面中的每一个面上都生成一个完整的纹理副本:

请注意,该点没有映射(0. 5,0.5),纹理的中心。只有纹理的角被映射到立方体的八个角上,其余的点都是从这些角中“猜测”出来的。相比之下,像人脸这样的复杂模型必须定义更多的UV坐标,才能将表示鼻子、耳朵、眼睛、嘴唇等的纹理部分映射到几何体的正确点。

一旦我们更深入地了解了几何体的工作原理,我们将在本书的后面回到UV贴图。幸运的是,我们很少需要手动设置 UV 贴图,因为所有Three.js 几何体(包括 )都内置了 UV 贴图。我们只需要加载纹理并将其应用到我们的材料上,一切都会起作用。BoxBufferGeometry

在本章的其余部分,我们将向您展示如何做到这一点。

重要提示:从现在开始,如果您在本地工作, 则需要设置一个 Web 服务器,否则,由于浏览器安全限制,您将无法加载纹理。

对于使用内联代码编辑器的每个人来说,一切照旧。让我们继续前进。

班级Texture

该类是 HTML 图像元素的包装器,其中包含一些与用作纹理而不是普通图像相关的额外设置。Texture

加载纹理

现在我们已经掌握了所有的理论,加载纹理并将其应用于我们的立方体很简单。我们在本章中添加的所有代码都将进入 cube.js 模块。我们将使用 three.js TextureLoader 类来加载纹理,因此请添加到 cube.js 顶部的导入列表中:TextureLoader

cube.js:导入TextureLoader

import {
  BoxBufferGeometry,
  MathUtils,
  Mesh,
  MeshStandardMaterial,
  TextureLoader,
} from 'three';

将材料设置移动到单独的功能中

为了防止函数变得太大,让我们将材质创建移动到一个新函数中:createCube

cube.js:将材质设置移动到新函数中

function createMaterial() {
// create a "standard" material
const material = new MeshStandardMaterial({ color: 'purple' });

return material;
}

function createCube() {
const geometry = new BoxBufferGeometry(2, 2, 2);

const material = createMaterial();

const cube = new Mesh(geometry, material);

...
}

创建实例TextureLoader

接下来,在新函数的顶部创建一个新实例:TextureLoadercreateMaterial

cube.js:创建纹理加载器实例

function createMaterial() {
// create a texture loader.
const textureLoader = new TextureLoader();

// create a "standard" material using
const material = new MeshStandardMaterial({ color: 'purple' });

return material;
}

用于加载纹理TextureLoader.load

TextureLoader.load 方法可以加载任何标准图像格式的纹理,例如 PNG、JPEG、GIF、BMP 等。在这里,我们将从 assets/textures 文件夹中加载 uv-test-bw.png 文件:

cube.js:加载纹理

function createMaterial() {
// create a texture loader.
const textureLoader = new TextureLoader();

// load a texture
const texture = textureLoader.load(
'/assets/textures/uv-test-bw.png',
);

// create a "standard" material using
const material = new MeshStandardMaterial({ color: 'purple' });

return material;
}

当我们调用时,会发生一些有趣的事情。即使加载纹理需要一些时间(可能几百毫秒),也会立即返回 Texture 类的实例。上面,我们将其存储在一个名为 ..loadTextureLoadertexture

我们可以立即使用这个空,甚至在图像完成加载之前。但是,在图像数据完全加载之前,纹理将显示为黑色。换句话说,如果我们将此纹理分配给材质的颜色映射表插槽,则该材质将在场景中显示为黑色,直到纹理完成加载。texture

加载完成后,将自动插入正确的图像,并且材料的颜色将从黑色变为图像中的任何颜色。如果互联网连接速度较慢,此过程将尤为明显。如果使用内联编辑器更新场景,则可能会看到这种情况发生,尽管图像数据应在几分之一秒内加载。您可能希望避免在场景中显示黑色网格,在这种情况下,您可以等到所有纹理加载完毕后再渲染场景。我们将在本书的后面部分探讨您的选择。TextureLoader

将纹理分配给材质的色彩映射表插槽

以前,我们使用 .color 属性设置材质的颜色。在这里,我们将 material.map 属性分配给 material.map 属性,该属性描述了颜色在对象表面上的变化情况。 应该命名,但是,由于它经常使用,因此为了方便起见,因此将其缩短。texture.map.colorMap

通常,我们设置 .color 或 .map,但不能同时设置两者。如果我们同时设置了两者,纹理中的颜色将以属性。例如,如果我们保持紫色,这种黑白纹理将获得紫色调。这里的一个常见用例是将颜色设置为灰色阴影以使纹理变暗。由于白色是默认颜色,因此设置为白色不会对纹理产生影响。因此,无法用于减轻质地。你只能让它变暗。.color.color.color

与 color 参数一样,我们可以将纹理传递到材质的构造函数中:

在构造函数中将纹理分配给材质

const material = new MeshStandardMaterial({
map: texture,
});

或者,我们可以在创建材质后设置:.map

创建材质后分配纹理

const material = new MeshStandardMaterial();

material.map = texture;

我们将在这里使用第一种方法。再次更新:createMaterial

cube.js:将纹理分配给材质的颜色映射表插槽

function createMaterial() {
  // create a texture loader.
  const textureLoader = new TextureLoader();

  // load a texture
  const texture = textureLoader.load(
    '/assets/textures/uv-test-bw.png',
  );

  // create a "standard" material using
  // the texture we just loaded as a color map
  const material = new MeshStandardMaterial({
    map: texture,
  });

  return material;
}

现在,您的场景将更新,您应该看到纹理映射到立方体的六个面中的每一个面上。

纹理有六个副本,立方体的每个面一个。特别注意拐角处发生的事情。

在上面的场景中,您可以使用鼠标或触摸旋转立方体。实际上,移动的是摄像机,而不是立方体,因为我们在这个场景中添加了一个摄像机控制插件。这个插件允许您平移、旋转和缩放/推车相机以从任何角度查看场景,这非常适合我们设置场景并想要仔细观察所有内容。在下一章中,我们将把这个插件添加到我们的应用程序中。

转载:Three.js 纹理贴图的实现 (mvrlink.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/318567.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大模型开启应用时代 数钉科技一锤定音

叮叮叮叮&#xff01;数钉智造大模型&#xff0c;“定音”强势发布&#xff01; 随着科技的飞速发展&#xff0c;大模型技术已逐渐成为推动产业变革的核心力量。在这一浪潮中&#xff0c;数钉科技凭借深厚的技术积累和敏锐的市场洞察力&#xff0c;成功利用大模型技术搭建起智能…

鸿蒙开发-UI-布局

鸿蒙开发-序言 鸿蒙开发-工具 鸿蒙开发-初体验 鸿蒙开发-运行机制 鸿蒙开发-运行机制-Stage模型 鸿蒙开发-UI 鸿蒙开发-UI-组件 鸿蒙开发-UI-组件-状态管理 鸿蒙开发-UI-应用-状态管理 鸿蒙开发-UI-渲染控制 文章目录 前言 一、布局概述 1.布局结构 2.布局元素组成 3.布局分类 …

场效应管在电路中如何控制电流大小

场效应管的概念 场效应晶体管&#xff08;FieldEffectTransistor缩写&#xff08;FET&#xff09;&#xff09;简称场效应管。主要有两种类型&#xff08;juncTIonFET—JFET&#xff09;和金属-氧化物半导体场效应管&#xff08;metal-oxidesemiconductorFET&#xff0c;简称M…

操作系统详解(5)——信号(Signal)

系列文章&#xff1a; 操作系统详解(1)——操作系统的作用 操作系统详解(2)——异常处理(Exception) 操作系统详解(3)——进程、并发和并行 操作系统详解(4)——进程控制(fork, waitpid, sleep, execve) 文章目录 概述信号的种类Hardware EventsSoftware Events 信号的原理信号…

YOLOv8改进 | 注意力篇 | 实现级联群体注意力机制CGAttention (全网首发)

一、本文介绍 本文给大家带来的改进机制是实现级联群体注意力机制CascadedGroupAttention,其主要思想为增强输入到注意力头的特征的多样性。与以前的自注意力不同,它为每个头提供不同的输入分割,并跨头级联输出特征。这种方法不仅减少了多头注意力中的计算冗余,而且通过增…

虚幻UE 特效-Niagara特效初识

虚幻的Niagara特效系统特别的强大&#xff0c;可以为开发者提供丰富的视觉效果&#xff01; 本篇笔记对Niagara系统进行初步的学习探索 文章目录 前言一、Niagara四大核心组件二、粒子发射器和粒子系统1、粒子发射器的创建2、粒子系统的创建3、Niagara系统的使用 总结 前言 在…

【SSM框架】初识Spring

初识Spring Spring家族 Spring发展到今天已经形成了一种开发的生态圈&#xff0c;Spring提供了若千个项目&#xff0c;每个项目用于完成特定的功能 ✅Spring Framework&#xff08;底层框架&#xff09;Spring Boot&#xff08;提高开发速度&#xff09;Spring Cloud&#xf…

C# 图解教程 第5版 —— 第24章 预处理指令

文章目录 24.1 什么是预处理指令24.2 基本规则24.3 符号指令&#xff08;#define、#undef &#xff09;24.4 条件编译&#xff08;#if、#else、#elif、#endif&#xff09;24.5 条件编译结构24.6 诊断指令&#xff08;#warning、#error&#xff09;24.7 行号指令&#xff08;#li…

最新域名群站开源系统:打造强大网站矩阵,引领SEO优化新潮流!

搭建步骤 第一步&#xff1a;安装PHP和MYSQL服务器环境 对于想要深入了解网站建设的人来说&#xff0c;自己动手安装PHP和MYSQL服务器环境是必不可少的步骤。这将使你能够更好地理解网站的运行机制&#xff0c;同时为后续的网站开发和优化打下坚实基础。 第二步&#xff1a;…

迅腾文化用网络集成化生态系统助力品牌之路的坚实后盾

商业竞争激烈&#xff0c;品牌不仅是企业的标志和形象&#xff0c;更是其核心价值和竞争力的体现。然而&#xff0c;企业在品牌推广过程中面临着诸多如缺乏有效的渠道管理、品牌形象模糊以及竞争激烈的市场环境等。这些阻碍着企业的品牌发展和市场占有率的提升。本文将通过企业…

[GN] nodejs16.13.0版本完美解决node-sass和sass-loader版本冲突问题

项目场景&#xff1a; npm install 运行vue项目时候 问题描述 项目场景&#xff1a;sass-loader &#xff0c;node-sass出错 ! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: smoore-mes-web1.4.0 npm ERR! Found: webpack3.12.0 npm ER…

【计算机组成原理】高速缓冲存储器 Cache 的写策略(Writing Policy)

写策略 Writing Policy 缓存的写策略指的是确定何时将数据写入缓存或主存的策略。 写命中 Write Hit 全写法 Write Through 在全写法策略中&#xff0c;每次发生写操作时都会将数据同时写入缓存和主存。这样可以保证数据的一致性&#xff0c;但会增加主存的写入操作&#xf…

ubuntu连接xshell怎么连接

在网上找了好多办法都不行 例如 太久没打开Ubuntu可能输入命令查不到IP地址&#xff0c;解决办法也比较简单&#xff0c;首先第一步 确定自己能不能进入管理员root权限&#xff08;输入命令su&#xff09;&#xff0c;如果没有的话得重新配置&#xff0c;如下图 这是因为当前Ub…

黑马程序员JavaWeb开发|案例:tlias智能学习辅助系统(1)准备工作、部门管理

一、准备工作 1.明确需求 根据产品经理绘制的页面原型&#xff0c;对部门和员工进行相应的增删改查操作。 2.环境搭建 将使用相同配置的不同项目作为Module放入同一Project&#xff0c;以提高相同配置的复用性。 准备数据库表&#xff08;dept, emp&#xff09; 资料中包含…

[Linux 进程(三)] 进程优先级,进程间切换,main函数参数,环境变量

文章目录 1、进程优先级1.1 Linux下查看进程优先级1.2 Linux 进程优先级的修改PRI and NItop命令配合操作更改优先级 1.3 竞争 独立 并行 并发 2、进程间切换3、Linux2.6内核进程调度队列3.1 活跃进程3.2 过期进程 4 main函数参数 — 命令行参数4.1 利用main函数的参数实现一个…

golang实现rpc方法二:使用jsonrpc库【跨平台】

首先在golang实现rpc方法一net/rpc库中实现了RPC方法&#xff0c;但是那个方法不是跨平台的&#xff0c;没法在其他语言中调用这个实现的RPC方法&#xff0c;接下来我们可以通过jsonroc库实现跨语言的RPC方法。俩种实现方式的代码其实也是差不多的&#xff0c;大差不差&#xf…

Spark---累加器

1.累加器实现原理 累加器用来把 Executor 端变量信息聚合到 Driver 端。在 Driver 程序中定义的变量&#xff0c;在Executor 端的每个 Task 都会得到这个变量的一份新的副本&#xff0c;每个 task 更新这些副本的值后&#xff0c;传回 Driver 端进行 merge。 //建立与Spark框架…

wpf使用Popup封装数据筛选框

(关注博主后,在“粉丝专栏”,可免费阅读此文) 类似于DevExpress控件的功能 这是DevExpress的winform筛选样式,如下: 这是DevExpress的wpf筛选样式,如下: 这是Excel的筛选样式,如下: 先看效果 本案例使用wpf原生控件封装,功能基本上都满足,只是颜色样式没有写…

扫描电镜技术在材料科学中的应用及发展趋势

在材料科学领域&#xff0c;扫描电镜技术扮演着极为重要的角色&#xff0c;广泛应用于多种材料形态结构、界面状况、损伤机制和材料性能预测的研究。本文将深入探讨扫描电镜技术的结构、主要性能、工作原理、试样制备技术以及在不同领域的应用。 第一部分&#xff1a;扫描电镜…

【现代密码学】笔记4--消息认证码与抗碰撞哈希函数《introduction to modern cryphtography》

【现代密码学】笔记4--消息认证码与抗碰撞哈希函数《introduction to modern cryphtography》 写在最前面4 消息认证码与抗碰撞哈希函数MAC概念回顾&#xff08;是的&#xff0c;我忘记这些缩写是什么了。。&#xff09;MAC的定义适应性CMA&#xff08;Chosen Message Attack&a…