【发布时间】:2020-01-19 13:53:39
【问题描述】:
我正在尝试在球体充当蒙版的球体中显示纹理。我的纹理正确显示,但我不知道如何去除被拉伸以填充球体的边缘像素。我希望它们是透明的。
这就是正在发生的事情
这个想法是图像以其默认外观显示,并且在鼠标悬停时,球体将缩小以掩盖图像的一部分。球体稍后会被修改为其他东西,这只是为了测试,所以不能对 2d 形状做同样的事情。
这就是它的设置方式,没什么特别的,只是为了让你明白。
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.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping 是默认行为,因此完全没用,我可以在文档中找到的唯一其他选择是RepeatWrapping 或MirroredRepeatWrapping,这两者都不是我想要的。我也无法创建具有透明边缘的自定义纹理,因为图像将由客户端上传。
我将如何解决这个问题,我能以某种方式检测我的着色器中的边界吗?
【问题讨论】:
-
vec2 uv = gl_FragCoord.xy / resolution * 2.0 - 1.0;:if (max(abs(uv.x), abs(uv.y)) > 1.0) discard;之后可能是这样的? -
这就像 4 行代码将图像绘制到稍大的画布上,带有 1 像素的黑色边框,然后使用该画布而不是您的纹理.. 或者您可以执行类似的操作如果 uv.y1.) 丢弃;
标签: three.js glsl shader textures mask