2.4.4 shader渲染四方连续遇到的问题

  • Creator 版本: 2.4.4

  • 目标平台: 目前已测试浏览器和安卓

先说思路。我们在游戏中,想做连续地形铺装。意思是不同的tiled sprite在相邻或遮挡时,贴图无缝拼接。
目前的方法是向shader里面传递偏移量。但是如果用材质参数,则因为每个对象的材质参数不同,完全无法合批。所以我想使用自定义渲染参数的方式。
尝试了重新构造Assembler2D,目前使用的方法,是直接替换缺省Assembler的更新函数(因为发现使使用不同的资源配置,会导致创建不同的Assembler,例如TiledAssembler)。
代码如下:

export default class RepeatPicSprite extends cc.Sprite {
    public offset = cc.Vec2.ZERO;

    _resetAssembler() {
        super._resetAssembler();

        //@ts-ignore
        const assembler = this._assembler;
        //@ts-ignore
        const normalUpdateUVs = this._assembler.updateUVs.bind(assembler);
        const hackUpdateUVs = (sprite) => {
            normalUpdateUVs(sprite);

            //@ts-ignore
            const verts = assembler._renderData.vDatas[0];
            //@ts-ignore
            for (let i = 0, len = verts.length; i < len; i += assembler.floatsPerVert) {
                //@ts-ignore
                const dstOffset = i + assembler.uvOffset;
                verts[dstOffset] = verts[dstOffset] + this.offset.x;
                verts[dstOffset + 1] = verts[dstOffset + 1] - this.offset.y;
            }
        }

        //@ts-ignore
        this._assembler.updateUVs = hackUpdateUVs;
    }
}

shader核心代码:

    vec2 uv = v_uv0;
    uv.x = mod(uv.x, 1.);
    uv.x += step(uv.x, 0.);
    uv.y = mod(uv.y, 1.);
    uv.y += step(uv.y, 0.);

    vec4 o = texture(texture, uv);

经查,step一行不调用,结果也是正常的。
其中offset是在外面计算出的贴图偏移量。
测试结果类似下面这样:

但是这个结果只能在浏览器内正常。

放到真机的话,会有贴图错乱,存在几个情况的猜测,
1、packable,通过打印日志,uv坐标确实不是0,1了。
2、如果在这个基础上,我修改offset的计算,是否可以纠正。
3、这里存在一个纠正后归一化的问题,例如x的值,起始和结束分别是0.2和0.8,此时渲染正常。如果同时增加0.4,就会变成0.6和1.2,归一化以后就成了0.6和0.2,会导致贴图内容逆反。显然是不对的。
4、或者我如果修改这张贴图的packable为false,是否明确可以解决这个问题,同时,真机情况下(非webgl),offset的值大于1或者小于-1是否会产生实质性的影响,溢出[0, 1]空间后应该如何理解和修正。各类问题应该如何避免。

因为自己不是技术美术,所以对这块有着若干疑问。真机调试难度大,shader调试难度更大。目前在反复打包确认中,一个循环可能一个小时就出去了。希望能有高手不吝赐教。非常感谢。

1赞

image 还得改成repeat

为什么不舍得给一个DC呢,它不值得吗。

因为不是2的幂宽高,所以不允许改。您这边是有把握,只要修改为2的幂次宽高,并且改为Repeat就可以正常了吗?

我要在全屏放好多个同类对象,如果每个都是单独DC,增长太快了。