V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
rabbbit
V2EX  ›  问与答

有人了解 Three.js 吗?想问下为什么导入的贴图会发虚

  •  2
     
  •   rabbbit · 2017-12-25 22:20:25 +08:00 · 3862 次点击
    这是一个创建于 2554 天前的主题,其中的信息可能已经有所发展或是发生改变。
    贴图给到 2000x2000 了还是发虚,搞不清到底是哪里不对了,希望能帮忙看看.



    demo https://aaron-bird.github.io/test/

    相关代码
    10 条回复    2018-05-25 10:07:12 +08:00
    Geeker
        1
    Geeker  
       2017-12-25 23:01:43 +08:00   ❤️ 1
    可以在 renderer 参数里加 { precision: 'highp' }
    然后 renderer.setPixelRatio(window.devicePixelRatio);
    YyYyYyy
        2
    YyYyYyy  
       2017-12-25 23:29:16 +08:00   ❤️ 1
    所有 texture 的 generateMipmaps 设成 false
    所有 texture 的 magFilter 和 minFilter 改成变量名不带 mipmap 的其他任意的值
    再试,试完说下结果。

    PS:不要用非 2 的 pow 的 texture,且一般情况不要想着用超过 1024 的单张 texture,古墓丽影崛起海边背景那种程度的场合才 2048 往上走,texture 越大不代表分辨率越大
    rabbbit
        3
    rabbbit  
    OP
       2017-12-26 00:13:26 +08:00
    @YyYyYyy
    添加了以下参数
    texture0.generateMipmaps = false;
    texture0.magFilter = THREE.LinearFilter;
    texture0.minFilter = THREE.LinearFilter;
    texture1.generateMipmaps = false;
    texture1.magFilter = THREE.NearestFilter;
    texture1.minFilter = THREE.NearestFilter;
    texture2.generateMipmaps = false;
    texture2.magFilter = THREE.LinearFilter;
    texture2.minFilter = THREE.LinearFilter;
    texture3.generateMipmaps = false;
    texture3.magFilter = THREE.LinearFilter;
    texture3.minFilter = THREE.LinearFilter;
    texture4.generateMipmaps = false;
    texture4.magFilter = THREE.LinearFilter;
    texture4.minFilter = THREE.LinearFilter;
    texture5.generateMipmaps = false;
    texture5.magFilter = THREE.LinearFilter;
    texture5.minFilter = THREE.LinearFilter;

    笔记本下表现,分辨率 1366x768


    高分屏下表现,分辨率 2048x1536
    YyYyYyy
        4
    YyYyYyy  
       2017-12-26 00:27:45 +08:00   ❤️ 1
    @rabbbit 关了 mipmap 出现锯齿是正常行为,这种情况下尝试转正方形使某面远离屏幕,如果没有像之前逐渐变模糊说明发虚就是 mipmap 导致的。

    下图是在关了 mipmap 后开了 highp 的结果嘛?看起来已经正常了的样子
    rabbbit
        5
    rabbbit  
    OP
       2017-12-26 00:29:17 +08:00
    抱歉,上边高分屏的那张图片传错了,这张才对

    上边那张(4Re81Ga.png)是加了 renderer.setPixelRatio(window.devicePixelRatio);的效果
    YyYyYyy
        6
    YyYyYyy  
       2017-12-26 00:51:10 +08:00
    @rabbbit 没用过 three.js ,以上内容凭 PC 渲染经验回答的。
    mipmap 是用来解决 3d 物体远离镜头后纹理采样的问题的,一般不应该关闭。
    很纳闷为什么一开始的模糊看起来就像是纹理直接从 mipmap level2/3/4 层开始的样子

    恢复你提问时刚开始的状态:mipmap 保持默认开启,不开 highp,然后按照刚搜到的下贴内容修改
    https://stackoverflow.com/questions/39276191/webgl-image-rendering-bad-quality
    看是否能正常。

    如果结果还不符合预期,把上面提到的几个因素组合尝试(注意控制变量法
    eastpiger
        7
    eastpiger  
       2017-12-26 01:12:33 +08:00   ❤️ 1
    仔细读了一下你的代码,你可以开一下调试看看,问题很明显在 canvas 的参数上可以看出来的:你的 canvas 大小实际上比 renderer 渲染的目标大小要大很多,所以图像被放大了。

    开调试看一下 canvas 的参数,style 的大小应该是你给的,而 renderer 之后依照的大小却是 width height 属性的数值。这样并不正确。

    所以正确的方法应该是在创建 renderer 之后执行如下代:

    ```
    renderer.setSize(element.clientWidth, element.clientHeight);
    ```

    这样就可以正确渲染了。另外 mipmap 不应该关掉,highp 也不一定要有的。renderer.setPixelRatio(window.devicePixelRatio);这个开启 HIDPI 可以考虑留着。

    看一下加上我给的那句话之后的效果:


    rabbbit
        8
    rabbbit  
    OP
       2017-12-26 01:36:29 +08:00
    @YyYyYyy
    @eastpiger
    @Geeker

    非常抱歉,因为这种低级问题耽误大家时间.

    如 eastpiger 所言,渲染器的尺寸和画布大小是不匹配的.而我错误的认为他们是相等.



    感谢各位的耐心帮助,谢谢.
    vicvinc
        9
    vicvinc  
       2017-12-27 01:40:28 +08:00 via iPhone
    分辨率...
    kevinzengXing
        10
    kevinzengXing  
       2018-05-25 10:07:12 +08:00
    @rabbbit 我也遇到了这个问题,在 pc 端显示是正常得,但在移动端就会变模糊,我设置了 render 的 setPixelRatio,也让 renderer 的大小与 domElement 画布的大小一样,但移动端上还是会模糊。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   965 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 19:14 · PVG 03:14 · LAX 11:14 · JFK 14:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.