【问题标题】:Texture which maintain proportion as scene background in three.js在three.js中保持比例作为场景背景的纹理
【发布时间】:2018-09-20 06:51:36
【问题描述】:

我有一个场景,我想添加背景,我有一个 png 图像(2k 分辨率),但是当我在 pc 上尝试它时它的大小合适,在移动设备上很多“不成比例” 我的代码如下:

var texture = THREE.ImageUtils.loadTexture('img/texture.png');

将其添加为背景就是这样:

  scene = new THREE.Scene();
  scene.background = texture;

我通过一些搜索看到,也许我必须为背景创建一个单独的场景,但我认为这不是最简单的解决方案,也许有更好的解决方案?

(一如既往,对不起我的英语不好)

【问题讨论】:

标签: javascript css image three.js textures


【解决方案1】:

您可以尝试使用THREE.ShaderMaterial 解决此问题

class MyBackgroundPlane extends THREE.Mesh{
    constructor(){
        super( 
            new THREE.PlaneBufferGeometry(2,2,1,1), 
            new THREE.ShaderMaterial({
                uniforms:{
                    uTexture: { value: null },
                    uAspect: { value: 1 }
                },
                vertexShader: `
                    varying vec2 vUv;
                    uniform float uAspect;

                    void main(){

                        vUv = uv; //pass coordinates to screen
                        vUv.x *= uAspect; //scale the coordinates

                        gl_Position = vec4(position.xy, 1., 1.);

                    }

                `,

                fragmentShader:`
                    varying vec2 vUv;
                    uniform sampler2D uTexture;

                    void main(){

                        gl_FragColor = texture2D( uTexture, vUv );
                    }

                `

            })
        )

        this.frustumCulled = false
    }

    setAspect( aspect ){
        this.material.uniforms.uAspect.value = aspect
    }

    setTexture( texture ){
        this.material.uniforms.uTexture.value = texture
    }
}

你必须弄清楚当它的纵向和横向时需要发生什么。

一种方法是使用uniform vec2 uScale;,然后根据方向设置不同的垂直和水平方向。

例如,通过将常规平面连接到相机,然后管理它的比例,可以对场景图进行同样的操作。

【讨论】:

    【解决方案2】:

    作为替代方案,您可以使用基于 CSS 的背景:

    #background {
        background-image: url('http://youring.com/test/img/texture.png');
        position: fixed;
        top: 0;
        left: 0;
        height: 100%;
        width: 100%;
        z-index: -1;
    }
    

    只需像这样创建您的渲染器,这样就可以看穿画布:

    renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
    

    演示:https://jsfiddle.net/f2Lommf5/5052/

    【讨论】:

    • 好点,没有理由假设 OP 希望这些像素位于画布中。不过可能会慢一点?
    • 可能。如果浏览器检测到后备缓冲区/帧缓冲区仅包含 RGB,则最终图像的合成速度可能更快。
    猜你喜欢
    • 2016-06-24
    • 2021-08-30
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-23
    • 1970-01-01
    • 2023-04-08
    • 2015-05-16
    相关资源
    最近更新 更多