three.js - 边缘像素在使用片段着色器映射的纹理中重复
问题描述
我试图用片段着色器复制笔触。这是我的演示。查看动画开始时的拉伸边缘。
我用three.js进行了这个设置:
material = new THREE.ShaderMaterial( {
side: THREE.DoubleSide,
uniforms: {
time: { type: 'f', value: 0 },
uvRate: {
value: new THREE.Vector2(1,3.7) // aspect ratio of image
},
texture: {
value: THREE.ImageUtils.loadTexture('img/stroke.png')
},
},
vertexShader: vertex,
fragmentShader: fragment
});
plane = new THREE.Mesh(new THREE.PlaneGeometry( 1,1, 1, 1 ),material);
顶点着色器计算纵横比:
uniform vec2 uvRate1;
void main() {
vUv1 = uv - 0.5;
vUv1 *= uvRate.xy;
vUv1 += 0.5;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`
片段着色器用一点数学来缩放 UV 以“刷”
// math behind this https://www.desmos.com/calculator/8qdmw3a91w
float scale1(float coord,float progress){
coord = coord/progress;
if(coord<0.88) {
final = coord*progress;
} else{
final = pow( (3.*coord - 2.4),3.) + 0.75 + coord/8.;
final *= progress;
}
return final;
}
void main() {
float p = clamp(fract(time/20.) + 0.3, 0.,1.); // 0.3 -> 1.0
vec2 newuv = vUv1;
newuv.x = scale1(vUv1.x,p);
gl_FragColor = texture2D(texture,newuv);
}
但我得到了这种优势:
.
有人知道这背后的原因是什么吗?以及如何解决?
解决方案
它可能与纹理包裹有关,因为它默认夹紧到边缘。( THREE.ClampToEdgeWrapping )
尝试在初始化后更改纹理的 wrapS 和 wrapT 属性,例如。
plane.material.uniforms.texture.wrapS = plane.material.uniforms.texture.wrapT = THREE.RepeatWrapping;
推荐阅读
- sql - 在 SQL Server 中区分多个列
- scala - 当抛出异常 akka 流时,有没有办法获取正在映射的项目?
- python - TypeError: 'str' 对象不可调用 1
- javascript - 如何从动态表单(javascript/reactjs)生成 xml 代码(只是代码)
- php - 仅在尝试使用另一个表时才进行 PDO 无缓冲查询
- javascript - React 架构问题 - 拥有单一全局应用程序状态的最佳方式,在更改时更新子组件
- javascript - 基于公共属性值合并数组
- java - 让一个静态方法负责创建它所在的类的对象是否明智?
- reactjs - storybook @storybook/addon-options 工作
- python - 如何使用 Python 从网站获取脚本标签变量