如何在 Three.js 中使用多个纹理并将其与自定义值混合?

2023-11-27

在 Three.js 中,是否可以创建一种包含多个纹理的材质(着色器?),每个纹理都有自己的细节,将它们混合在一起并分配给几何体?我想使用箔压花或局部紫外线上光等多种精加工技术来模拟纸张表面。

我想要实现的是一种具有以下特性的材料:

  1. 'Base' layer:
    • 纸张颜色(例如白色、灰白色、米色等)
    • 镜面反射度
    • 反射率
    • 凹凸(光滑或纹理纸)
  2. 'Image' layer (optional):
    • 图像纹理(印刷在纸上的图稿,与“基色”多重混合)
  3. 'Foil' layer (optional):
    • 黑白图像纹理控制图层透明度
    • 颜色(重叠“基础”层)
    • 镜面反射度
    • 反射率
  4. 'Emboss/Deboss' layer (optional):
    • 凹凸纹理(升高或降低“基础”凹凸)
  5. 'Varnish' layer (optional):
    • 黑白图像纹理控制图层透明度
    • 镜面反射度
    • 反射率
    • 凹凸(稍微抬高“底座”凹凸)

所有单独层的原因是我想单独控制它们(替换不同的纹理并在运行时更改值)。除了“图像”层之外,我不确定其他层应该使用什么混合值来实现逼真的模拟。

为了说明应用于纸张的整理技术,请查看以下照片(由 PrintHouse Corporation 提供):

Blind embossing (pattern) & gold foil debossing (logo, title) Blind embossing (pattern) & gold foil debossing (logo, title)

Silver foil debossing (logo) and spot UV varnish (photos) Silver foil debossing (logo) and spot UV varnish (photos)

Spot UV varnish (lines) Spot UV varnish (lines)

这有可能吗?我找不到任何使用如此复杂材料的 Three.js 示例。如果您能给我指出一个或解释如何以编程方式处理此问题,我将不胜感激。


正如评论所说,您可以使用自定义着色器来完成此操作。您只需要考虑如何在着色器中自己组合不同的层。 举个例子,您可以在 js 中设置着色器,如下所示:

blurTexture360 = new THREE.TextureLoader().load(imgURLBlur);
unblurTexture360 = new THREE.TextureLoader().load(imgURLUnblur);
highlight1Texture360 = new THREE.TextureLoader().load(imgURLHighlight1);
highlight2Texture360 = new THREE.TextureLoader().load(imgURLHighlight2);

blurTexture360.magFilter = THREE.LinearFilter;
blurTexture360.minFilter = THREE.LinearFilter;

const shader = THREE.ShaderLib.equirect;
uniforms = {
  u_resolution: { type: "v2", value: resolution },
  u_blur: { type: "t", value: blurTexture360 },
  u_unblur: { type: "t", value: unblurTexture360 },
  u_highlight1: { type: "t", value: highlight1Texture360 },
  u_highlight2: { type: "t", value: highlight2Texture360 },
  u_mix: { type: "f", value: 0.0 },
  u_highlightAmt: { type: "f", value: 0.0 },
  u_highlight1Bool: { type: "f", value: 1.0 },
  u_highlight2Bool: { type: "f", value: 1.0 }
};
let material360 = new THREE.ShaderMaterial({
  uniforms: uniforms,
  vertexShader: shader.vertexShader,
  fragmentShader: fragmentShader(),
  depthWrite: false,
  side: THREE.BackSide
});

然后把制服放在别处

uniforms.u_highlightAmt.value -= 0.05;

这是当 u_highlight1Bool 或 u_highlight2Bool 设置为 1 或 0 时设置不同纹理的示例。希望这为您提供了一个使用逻辑影响着色器代码的示例。

function fragmentShader() {
    return `        
uniform sampler2D u_blur;
uniform sampler2D u_unblur;
uniform sampler2D u_highlight1;
uniform sampler2D u_highlight2;

uniform vec2 u_resolution;
uniform float u_mix;
uniform float u_highlight1Bool;
uniform float u_highlight2Bool;
uniform float u_highlightAmt;

varying vec3 vWorldDirection;
#define RECIPROCAL_PI2 0.15915494309189535
#define RECIPROCAL_PI 0.3183098861837907

vec2 equirectUv( in vec3 dir ) {
    // dir is assumed to be unit length
    float u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;
    float v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;
    return vec2( u, v );
}

void main() {
    vec3 direction = normalize( vWorldDirection );
    vec2 sampleUV = equirectUv( direction );
  vec4 blur =  texture2D(u_blur, sampleUV);
  vec4 unblur =  texture2D(u_unblur,  sampleUV);
  vec4 highlight1 = texture2D(u_highlight1, sampleUV);
  vec4 highlight2 = texture2D(u_highlight2, sampleUV);

    blur = mapTexelToLinear( blur );
  unblur = mapTexelToLinear( unblur );
  highlight1 = mapTexelToLinear(highlight1);
  highlight2 = mapTexelToLinear(highlight2);
  vec4 highlight = (highlight1*u_highlight1Bool) + (highlight2 * u_highlight2Bool);

  vec4 ret = mix(blur, unblur, u_mix);
  float thresh = ceil(highlight.r - 0.09) * u_highlightAmt;
  ret = mix(ret,highlight,thresh);

  gl_FragColor = ret;
}
`;

我从这里的代码中得到了这个:https://glitch.com/edit/#!/hostileterrain94?path=script%2F ThreeSixtyEnv.js%3A202%3A0它的记录不是很好,但如果您想了解它在更广泛的项目中是如何存在的,请随意查看。我并不认为这真的很有效,但我知道它可以完成工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Three.js 中使用多个纹理并将其与自定义值混合? 的相关文章

  • Three.js:基于图像的光照(IBL)

    I m searching to add an IBL to my scene and objects But I can t find anything on the web There are some examples with an
  • 一次性渲染阴影

    考虑到阴影投射的成本 我想知道对于动态定位的静态对象 例如 程序城市 是否有一个功能或可能 实验性的方法可以在 Three js 中仅渲染一次阴影贴图 甚至在 webgl 中 因此 结果可以在静态对象的下一帧中免费使用 仅当物体移动时才会进
  • 使用 ThreeJS 获取球体纹理上的点击位置

    目前 我有一个带有纹理的球体 它绕 y 轴旋转 我还有在 3D 空间中单击的位置 以及球体上的旋转位置 我认为 目标 获取纹理上的位置 例如 我想获取我点击的图像的哪个方块 参见示例球体和下图 在实践中 我不会使用此图像 但我觉得这将是一个
  • Three.js 光线投射器可以与组相交吗?

    我想知道我的光线投射器是否正在查看我已加载的 OBJ 由于从 Cinema4D 导出的方式 我相信 OBJ 是一个具有 3 个子级的 THREE Group 而不是 THREE Object 我可以更改我的 raycaster 代码行来查找
  • Three.js 对象的“中心”是什么?

    当我使用 Blender 对对象进行建模时 我能够明确定义其发生平移和旋转的中心位置 当使用 Three js 对象时 我似乎没有找到等效的对象 Three js 对象是否具有定义其 中心 位置的属性 如果不是 物体的中心是如何确定的 在
  • Three.js 椭圆

    如何在 Three js 中创建一个椭圆 我看过这个 在 THREE js 中绘制椭圆 https stackoverflow com questions 11419896 drawing an ellipse in three js 但如
  • Three.js :face4 生成三角形而不是正方形

    我正在尝试使用 tree js 自定义几何图形生成一个正方形 但是这段代码 var cubeGeo new THREE Geometry cubeGeo vertices push new THREE Vector3 25 25 25 cu
  • Three.js canvas.toDataURL 有时为空

    我正在尝试使用 html2canvas js 渲染 THREE js 场景 一些覆盖的 HTML 元素 有用大多数时候 但并非一直如此 在失败的情况下 将渲染 HTML 元素 背景 覆盖层等 但不会渲染其他元素 THREE js 场景表现得
  • 无面点云 (PLY) 文件的 Web 查看器

    我在尝试Three Js https github com mrdoob three js 用于通过网络查看 PLY 文件 使用这个例子 http threejs org examples webgl loader ply html作为参考
  • 优化重叠矩形的绘制

    我有很多矩形 有些与其他矩形重叠 每个矩形都有一个绝对 z 顺序和一个colour 每个 矩形 实际上是粒子效果 网格或纹理的轴对齐边界框 并且可能是半透明的 但只要您不尝试剔除其他矩形后面的矩形 就更容易抽象地思考彩色矩形 所以我将在问题
  • 如何优化 Three.js 中多个 sphereGeometry 的渲染?

    我想优化 Three js 中 sphereGeometry 的渲染 因为它成为我的程序的瓶颈 javascript程序如下所示 var sphereThree for var idSphere 0 idSphere lt numSpher
  • JavaScript TypedArray 混合类型

    我正在尝试使用 WebGL 并希望将一些不同类型混合到一个字节缓冲区中 我知道 TypedArrays 可以达到这个目的 但不清楚我是否可以与它们混合类型 OpenGL 顶点数据通常是与无符号字节或整数混合的浮点数 在我的测试中 我想将 2
  • 在 Chrome 18 中检测 SwiftShader WebGL 渲染器

    我有一个 2D HTML5 游戏引擎 www scirra com http www scirra com 并且确实想检测 WebGL 是否将使用 Chrome 18 的 Swiftshader 软件渲染器进行渲染 如果是这样我们会much
  • 从matrix4()获取翻译

    对于大多数 Three js 开发人员来说 这可能看起来像是一个虚拟问题 但是如何从转换矩阵中提取翻译呢 实际上 我手动提取它指向 矩阵数组位置 12 13 14 提前致谢 如果要从矩阵中提取平移分量 请使用以下模式 var vec new
  • WebGL iOS 渲染为浮点纹理

    我正在尝试在 iOS Safari 上的 WebGL 中渲染浮点纹理 而不是在本机应用程序中 我已经设法让 iOS 读取手动 例如从 JavaScript 创建的浮点纹理 但是当我创建浮点类型的帧缓冲区并使用 GPU 渲染到其中时 它不起作
  • 计算顶点法线

    我正在使用 3d 修改器https github com foo123 MOD3 https github com foo123 MOD3弯曲一个立方体 几何体更新 顶点位置更改 后 灯光不会更新 立方体仍然着色 就好像没有任何变化一样 所
  • 将 FBX 文件转换为 .gltf 后,模型非常小,为什么?

    问题 将 FBX 文件转换为 gltf 后 模型非常小 为什么 我尝试用以下方法缩放模型frontObject scale set 1000 1000 1000 但我收到以下错误 TypeError Cannot read property
  • Three.js、自定义着色器和具有透明度的 png 纹理

    我有一个非常简单的 PNG 纹理 一个带有透明背景的灰色圆圈 我用它作为制服map for a THREE ShaderMaterial var uniforms THREE UniformsUtils merge basicShader
  • 如何检查 webgl(two.js) 的客户端性能

    我有一个使用 Three JS 的图形项目 现在我想自动检查客户端 GPU 性能并计算可以在应用程序中加载多少元素 我想到了诸如 GPU 基准测试之类的东西 看一眼stats js https github com mrdoob stats
  • Three.js:为相机添加灯光

    我想移动和旋转相机 但将点光源保持在相对于相机的相同位置 我读过很多帖子 说您可以将灯光对象添加到相机而不是场景中 就像这样 pointLight new THREE PointLight 0xffffff pointLight posit

随机推荐