Three.js 正在拉伸的三个js纹理边缘像素
我试图在一个球体内显示一个纹理,其中球体充当遮罩。我已经正确地显示了我的纹理,但我无法了解如何删除正在拉伸以填充球体的边缘像素。我希望它们是透明的 这就是正在发生的事情 其思想是,图像以其默认外观显示,在鼠标上方,球体将收缩以遮罩图像的一部分。球体稍后将被修改为其他形状,这只是为了测试,因此对2d形状执行相同操作不是一个选项 这就是它的设置方式,没有什么特别的,只是为了让你得到这个想法Three.js 正在拉伸的三个js纹理边缘像素,three.js,glsl,shader,textures,mask,Three.js,Glsl,Shader,Textures,Mask,我试图在一个球体内显示一个纹理,其中球体充当遮罩。我已经正确地显示了我的纹理,但我无法了解如何删除正在拉伸以填充球体的边缘像素。我希望它们是透明的 这就是正在发生的事情 其思想是,图像以其默认外观显示,在鼠标上方,球体将收缩以遮罩图像的一部分。球体稍后将被修改为其他形状,这只是为了测试,因此对2d形状执行相同操作不是一个选项 这就是它的设置方式,没有什么特别的,只是为了让你得到这个想法 texture.wrapS = texture.wrapT = THREE.ClampToEdgeW
texture.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping
texture.minFilter = THREE.LinearFilter
// uniforms
const uniforms = {
texture: {value: texture},
resolution: {type: 'vec2', value: new THREE.Vector2(window.innnerWidth, window.innerHeight)},
offset: {type: 'vec2', value: new THREE.Vector2(offset.x, offset.y)},
size: {type: 'vec2', value: new THREE.Vector2(width, height)},
scroll: {value: 0}
}
// material
const material = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: this.vertex,
fragmentShader: this.fragment
})
const geometry = new THREE.SphereGeometry(5, 32, 32)
this.mesh = new THREE.Mesh(geometry, material)
还有我的碎片着色器
uniform sampler2D texture;
uniform vec2 resolution;
uniform vec2 offset;
uniform vec2 size;
void main() {
vec2 uv = gl_FragCoord.xy / resolution * 2.0 - 1.0;
uv = uv / 2.0 + 0.5;
uv.x = (uv.x - offset.x) / size.x;
uv.y = (uv.y - offset.y - scroll) / size.y + 1.0 ;
gl_FragColor = texture2D(texture, uv);
}
我知道texture.wrapps=texture.wrapT=THREE.claptoedgewrapping
是默认行为,因此完全无用,我在文档中找到的唯一其他替代方法是RepeatWrapping
或MirroredRepeatWrapping
这两者都不是我想要的。我也无法创建带有透明边缘的自定义纹理,因为图像将由客户端上载
如果到视图中心的距离大于1.0,我将如何解决此问题,我是否可以以某种方式检测着色器中的边界?您必须尊重纵横比并丢弃碎片。按纵横比缩放x分量,并计算从中心到当前位置的矢量的比例:
vec2p=gl_FragCoord.xy/分辨率*2.0-1.0;
p、 x*=分辨率.x/分辨率.y;
如果(长度(p)>1.0)
丢弃;
注意,可以在片段着色器中使用关键字来放弃对当前片段的操作。此关键字导致丢弃片段,并且不会对任何缓冲区进行更新
注:甚至可以在像素坐标中定义点和半径,并显示该点周围的圆形区域。
e、 g.您可以通过当前鼠标位置更新中心点。 由于计算是在像素坐标中进行的,因此不需要按纵横比缩放距离的x分量:
uniform vec2中心;//像素坐标中的圆心
均匀浮动半径;//像素半径
void main()
{
vec2 v=gl_FragCoord.xy-center.xy;
if(长度(v)>半径)
丢弃;
// [...]
}
在vec2 uv=gl\u FragCoord.xy/resolution*2.0-1.0之后可能会出现类似的情况代码>:if(max(abs(uv.x)、abs(uv.y))>1.0废弃代码>?将图像绘制到稍大的画布上(带有1像素的黑色边框),然后使用该画布而不是纹理,这就像4行代码一样。。或者你可以做一些事情,比如如果uv.y1.)丢弃;具有p.x*=分辨率.x/分辨率.y的良好选项代码>!