three.js:修改自定义的ShaderMaterial中的我的纹理的紫外线

发布于 2025-01-22 11:39:24 字数 1354 浏览 2 评论 0原文

我有一个平面的几何形状,正在创建与之相关的定制材料。它将获得一些纹理作为制服。我希望这些纹理能够完美覆盖我的飞机(例如背景大小:cover css属性),

当我使用meshbasicMaterial <的纹理时,我设法使用实用程序功能进行操作。 /code>:

cover( texture, aspect ) {

    var imageAspect = texture.image.width / texture.image.height;

    if ( aspect < imageAspect ) {
        texture.matrix.setUvTransform( 0, 0, aspect / imageAspect, 1, 0, 0.5, 0.5 );

    } else {
        texture.matrix.setUvTransform( 0, 0, 1, imageAspect / aspect, 0, 0.5, 0.5 );

    }

}

但是不幸的是,由于我使用shadermaterial,因此我的“封面”功能不再适用。我强迫在碎片着色器内部做吗?如果是这样,我该如何设法再现这种行为?

这是我的代码:

const vertexShader = `
    precision highp float;
    uniform mat3 uUvTransform;
    varying vec2 vUv;
    void main() {
        vUv = ( uUvTransform * vec3( uv, 1 ) ).xy;
        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`;

const fragmentShader = `
    precision highp float;
    uniform sampler2D uText1;
    varying vec2 vUv;


    void main() {
        vec2 xy = vUv;

        vec4 color = texture2D(uText1,xy);
        gl_FragColor = color;
}`;

这是我当前的结果:

”在此处输入图像描述

非常感谢

I've a plane geometry and I'm creating a CustomShader material related to it. It will receive some textures as uniforms. I'd like the textures to perfectly cover my plane (like the background-size:cover css property)

I managed to do it with an utility function when I used my textures with a MeshBasicMaterial :

cover( texture, aspect ) {

    var imageAspect = texture.image.width / texture.image.height;

    if ( aspect < imageAspect ) {
        texture.matrix.setUvTransform( 0, 0, aspect / imageAspect, 1, 0, 0.5, 0.5 );

    } else {
        texture.matrix.setUvTransform( 0, 0, 1, imageAspect / aspect, 0, 0.5, 0.5 );

    }

}

But unfortunately since I'm using the ShaderMaterial, my "cover" function doesn't apply anymore. Am I force to do it inside my fragment shader? If so how can I manage to reproduce this behavior ?

Here's my code :

const vertexShader = `
    precision highp float;
    uniform mat3 uUvTransform;
    varying vec2 vUv;
    void main() {
        vUv = ( uUvTransform * vec3( uv, 1 ) ).xy;
        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`;

const fragmentShader = `
    precision highp float;
    uniform sampler2D uText1;
    varying vec2 vUv;


    void main() {
        vec2 xy = vUv;

        vec4 color = texture2D(uText1,xy);
        gl_FragColor = color;
}`;

And here's my current result :

enter image description here

Thanks a lot

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

拥有 2025-01-29 11:39:24

您可以简单地使用自定义制服,例如

uniform sampler2D uText1;
uniform vec2 uUvScale;
varying vec2 vUv;
void main() {
    vec2 uv = (vUv - 0.5) * uUvScale + 0.5;
    gl_FragColor = texture2D(uText1, uv);
}

:::

var imageAspect = texture.image.width / texture.image.height;
if ( aspect < imageAspect ) {
    material.uniforms.uUvScale.value.set(aspect / imageAspect, 1)
} else {
    material.uniforms.uUvScale.value.set(1, imageAspect / aspect)
}

You could simply use a custom uniform, e.g. :

uniform sampler2D uText1;
uniform vec2 uUvScale;
varying vec2 vUv;
void main() {
    vec2 uv = (vUv - 0.5) * uUvScale + 0.5;
    gl_FragColor = texture2D(uText1, uv);
}

And :

var imageAspect = texture.image.width / texture.image.height;
if ( aspect < imageAspect ) {
    material.uniforms.uUvScale.value.set(aspect / imageAspect, 1)
} else {
    material.uniforms.uUvScale.value.set(1, imageAspect / aspect)
}
私藏温柔 2025-01-29 11:39:24

Trife 3.js处理纹理转换,例如.offset,.repeat,。rotation,.center是通过matrix3作为roniform传递到Vertex Shader中的Matrix3。顶点着色器执行矩阵乘法,然后将修改后的紫外线传递给片段着色器。

D1A8D3B53104B9DA9EE48968CD5A0323E7F0777F/SRC/RENDERERS /RENDERERS shadermaterial的Vertex着色器,我认为纹理属性将自动在Matrix3中通过。 However, if for some reason it doesn't, you could recreate the Matrix3 通过从源中复制它并手动将其传递为统一。我不知道您的效用功能是什么样的,因此很难说出您如何实现所需的缩放。

The way Three.js handles texture transformations like .offset, .repeat, .rotation, .center is via a Matrix3 that gets passed as a uniform into the vertex shader. The vertex shader performs the matrix multiplication, then passes the modified UVs as a varying to the fragment shader.

You could copy those lines of GLSL code to your ShaderMaterial's vertex shader, and I think the texture properties will come through in the Matrix3 automatically. However, if for some reason it doesn't, you could recreate the Matrix3 by copying it from the source and passing it as a uniform manually. I don't know what your utility function looks like, so it's hard to tell how you're achieving the desired scaling.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文