rendertexture 在 camera target中时,尺寸如何计算?

我用需要额外 camera+ rendertexture 做个物体的影子,所以要控制 rendertexture 在显示回 sprite 之后和原来的尺寸是一致的。我测试了半天,也没发现 camera 写入 rendertexture 的尺寸是按照什么比例。它似乎和 camera 的 Ortho Height 有关,但是我总结不出来它们的比例关系。
camera 的输出会映射到.rt 文件设置的尺寸中去。问题也就是:我在把 rt文件给 sprite 后,sprite 应该设定多少 scale 才能1:1还原物体的尺寸。


如图:现在临时用的一个变灰的 shader,之后会改成染成透明色的影子放在原本物体的后面偏移一下压着。现在只是为了说明问题临时放在上面了。现在看起来偏小了。因为 我找不出来正确的 scale。
当然我也能靠一遍一遍的测试大致找到一个比例,但是适配了不同的分辨率之后,就又乱了。所以还是需要找到印象缩放的参数和内部的 rendertexture 在 cameratarget 上的机制。

取决于你摄像机的照射范围,renderTexture返回的大小就是你的照射范围,所以初始化也是这个范围大小,默认就是视口大小,但是这样输出的精灵也会是这个大小,因为包含了透明像素;


写个shader测试,透明则设置当前像素为红色
1755187707242
结果如下

在setTexture的时候传入第二个参数指定区域

结果正常不含透明像素

1赞

RT的相机,设好对应大小

最后我没有用代码创建 spriteframe和setTexture,我采用了编辑器直接设定的方式简单方便。

看屏幕是高度适配还是宽度适配。
正常竖屏宽度适配时,正交摄像机的ortho height 是屏幕高度的一半(指的是屏幕标准化到你设计分辨率下时,高度的一半,比如设计分辨率750×1334,你手机是iPhone x,那么你的屏幕标准化后,理论上是750×H,那就是ortho height 就是H/2)

如果是iPad 高度适配,那就是1334/2=667

后续做地图摄像机移动、缩放之类的都是这套逻辑

我的方式很简单:
1.资源管理器 assets 对应目录下面 创建-渲染纹理 RenderTexture
2.创建好的纹理在属性检查器里面设定好对应的尺寸,这个尺寸和缩放参数没有关系,但是它自身的长宽比和之后设定的 sprite 长宽比有关系,我设定为1400x1400(我用于表示影子,这个尺寸足够了,并且是方的,简单),越大越清晰,越小越模糊(最终得到的效果好像图片缩小失真再放大后的那种模糊)
3.主摄像机复制自己,作为影子RT摄像机,放在自己下面当子节点,在场景启动后延迟一点时间设定orthoHeight和主摄像机相同

this.cameraBack.orthoHeight = this.camera.orthoHeight;

4.影子 RT 摄像机的 TargetTexture 拖入第一步建立的 RenderTexture
5.需要出现影子的物体改 layer,比如之前是 UI_2D,就改成别的,比如 default
6.主摄像机Visibility增加default,影子RT摄像机Visibility只有 default
7.所需要显示影子的层级上建立 sprite,(在地板上面,其它所有物件下面),放好位置,SizeMode=CUSTOM,尺寸2048x2048(这个尺寸与 renderTexture 设定的长宽比一致),再次拖入第一步建立的RenderTexture;
以上是我提问前所做的,这里会发现尺寸对不上原图
8.设定该 sprite 的scale:view.getVisibleSize().height / 2048。没错就这一行。我的游戏物体所在的根节点会有个尺寸缩放,为了显示更大或者更小的关卡,所以影子节点需要放在这个根节点内,需要前面的 scale 再除以这个根节点的缩放就能还原为匹配的大小。
其实我没太看懂为什么用visibleSize 的高度去除以sprite 的高度尺寸,完全是试出来的。项目的适配设置为 只适配屏幕宽度,估计和这个有关系
9. 编写effect,制作 material 赋给 sprite。(也就是去非透明采样值进行一个染固定透明度的黑色)
10. sprite 的位置稍微偏移几个像素,因为它是影子嘛。

补充:
这个游戏是有 H5版本的关卡编辑器的,编辑之后可以直接切换到运行模式进行关卡设计,而编辑器模式用的是1080x1920 ResolutionPolicy.SHOW_ALL,(这个模式下,策划可以更好的利用电脑的宽屏进行关卡编辑),在这个模式下,上面的 scale 就不对了。上面的简单计算是在 1080x2400 ResolutionPolicy.FIXED_WIDTH 下做适配的。
那么更通用的计算scale方式我也找到了:
view.getVisibleSize().width * screen.windowSize.height / screen.windowSize.width / 2048
尝试了几种分辨率都没什么问题,另外1080x2400 ResolutionPolicy.FIXED_WIDTH下也能工作正常。

二次补充:
发布 H5之后,在ResolutionPolicy.SHOW_ALL模式下,上面补充的还是有问题,继续做了修改:

        let height = Math.max(view.getVisibleSize().width * screen.windowSize.height / screen.windowSize.width, view.getVisibleSize().height);
        let blockShadowNodeScale = v3(1, 1, 1).multiplyScalar(height / 2048);

也就是之前计算的如果长宽比比设计长宽比更方,则 scale 结果依然不对,反而是之前直接用 height 没问题。所以用 Math.max 做了判断,如果按 windowSize 比例算出的高度更高,则使用,如果没有设计高度高,则使用设计高度。

2赞