Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Three.js 正在拉伸的三个js纹理边缘像素_Three.js_Glsl_Shader_Textures_Mask - Fatal编程技术网

Three.js 正在拉伸的三个js纹理边缘像素

Three.js 正在拉伸的三个js纹理边缘像素,three.js,glsl,shader,textures,mask,Three.js,Glsl,Shader,Textures,Mask,我试图在一个球体内显示一个纹理,其中球体充当遮罩。我已经正确地显示了我的纹理,但我无法了解如何删除正在拉伸以填充球体的边缘像素。我希望它们是透明的 这就是正在发生的事情 其思想是,图像以其默认外观显示,在鼠标上方,球体将收缩以遮罩图像的一部分。球体稍后将被修改为其他形状,这只是为了测试,因此对2d形状执行相同操作不是一个选项 这就是它的设置方式,没有什么特别的,只是为了让你得到这个想法 texture.wrapS = texture.wrapT = THREE.ClampToEdgeW

我试图在一个球体内显示一个纹理,其中球体充当遮罩。我已经正确地显示了我的纹理,但我无法了解如何删除正在拉伸以填充球体的边缘像素。我希望它们是透明的

这就是正在发生的事情

其思想是,图像以其默认外观显示,在鼠标上方,球体将收缩以遮罩图像的一部分。球体稍后将被修改为其他形状,这只是为了测试,因此对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.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的良好选项