zender 发表于 2024-2-9 11:02:06

关于显存优化方案

1.虚拟纹理(效果最优,但是没有可行性)

向显卡上传纹理时,会将纹理的长宽都扩大成最近的2的幂次(下图中8为透明度和绿色每像素大小,其他为各个加载图片在显存中的实际大小),这意味着长宽非2的幂次的图片上传后会产生部分空白空间,浪费显存(如513*129的图片会被放大为1024*256其中约75%的空间什么也没有)


虚拟纹理一定程度上便是为了解决该问题,通过将多张图片打包成一张长宽均为2的幂次的图片减少显存浪费
在此基础上还能引入纹理压缩
但是为什么说没有可行性:
实际上原版的Sprite包含实现该内容的基础texY和texY


但是这两个字段只暴露了写入,并未暴露读取方式,只有Sprite的几个render函数使用了它,所以基于此制作虚拟纹理系统会导致任何自定义渲染的mod出错
这也意味着原版基本不会做这件事,而其他模组则更加不可能
虚拟纹理示例(该图片包含了graphics\ui中的77张图片,将下图不压缩的传到显卡需要8MB显存,而将这77张图片不压缩的传到显卡需要15.006MB显存):



2.压缩格式(效果好,实现复杂,影响加载)
通过重写GL11的glTexImage2D 函数即可完成,但是要注意的是,GraphicsLib使用的法线贴图(_normal)和表面贴图(_surface)不兼容纹理压缩
因此,这还需要深入混淆部分去检测当前加载的图片的路径
对于无透明度的图片,使用dxt1可以得到6(原):1(压缩)的压缩比,对于有透明度的图片,使用dxt5可以得到4(原):1(压缩)的压缩比
最后,纹理压缩是需要耗时的,这会导致加载时间有所增加
原版可能会在之后添加对dds格式(可以直接存储压缩纹理数据)加载的支持,由于原版对模组读取文件的限制,这无法由模组完成

3.图片缩小(视觉效果差,实现简单(or复杂),甚至优化加载速度)
根据我的研究,graphics/fonts,graphics/ui,graphics/hud,graphics/backgrounds,graphics/warroom,graphics/icons/skills,graphics/icons/cargo,graphics/icon/characters/skills,graphics/starscape,graphics/illustrations,graphics/weapons 之外的图片都可以随意缩放(只要你能接受缩小放大后纹理质量变差)
weapons 的缩小会导致武器的缩小,如果能接受,那也可以缩小
illustrations 的缩小会导致类似进出超空间看到的那张图在框中重复多次
ui 的缩小会导致ui错位
cargo 的缩小会导致图标变小
ships(与大部分其他情况) 的缩小会导致纹理质量变差

简单实现:手动将图片缩小(注意,如果你真的要这么做,缩小一张图片后需要同时等比缩小其法线贴图(_normal)和表面贴图(_surface))
复杂实现:深入并修改混淆函数以在运行时智能缩小

页: [1]
查看完整版本: 关于显存优化方案