-
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调试难度更大。目前在反复打包确认中,一个循环可能一个小时就出去了。希望能有高手不吝赐教。非常感谢。