three.js:修改自定义的ShaderMaterial中的我的纹理的紫外线
我有一个平面的几何形状,正在创建与之相关的定制材料。它将获得一些纹理作为制服。我希望这些纹理能够完美覆盖我的飞机(例如背景大小: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 :
Thanks a lot
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以简单地使用自定义制服,例如
:::
You could simply use a custom uniform, e.g. :
And :
Trife 3.js处理纹理转换,例如
.offset,.repeat,。rotation,.center
是通过matrix3作为roniform
传递到Vertex Shader中的Matrix3。顶点着色器执行矩阵乘法,然后将修改后的紫外线传递给片段着色器。uv_pars_vertex.glsl.js
文件>文件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 auniform
into the vertex shader. The vertex shader performs the matrix multiplication, then passes the modified UVs as a varying to the fragment shader.uv_pars_vertex.glsl.js
fileuv_vertex.glsl.js
fileYou 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.