作者pnpncat (meow)
站内Programming
标题[请益] 写作绘图软体碰到的一些问题@@
时间Fri Aug 3 01:09:39 2012
最近自己在写一个绘图软体
被一些问题卡住了
想跟大家讨论看看
我想要写一个类似 Photoshop 的图层系统
这个系统要可以同时容纳
1. 可切换各种混色模式的绘图图层
以及
2. 其他一些具有调整效果的参数图层
我以 C++ 将它实做为类似 Link List 的资料结构
也就是将每个图层设计为一个物件
此物件含有图层本身的资讯(图像或调整参数)以及一个指向下一图层的指标
实际混色时是使用递回方式
也就是每个图层都先呼叫下一图层的混色函数
然後再将自己这一层的资讯叠加到 Buffer 上去
递回到碰到最底层为止
从行为上来说这个设计是没有问题的
但是我发现当图层增多到一个程度之後
时间和空间上的开销都会有点不合理
以空间而言
假设一张图是 3000*2000px 的 RGBA 格式
那麽不压缩的大小就是 24M bytes
由於任何一个图层有改变时
都必须将混色结果即时显示到萤幕上
因此所有图层资讯都要同时载入记忆体
这种情况下 只要开20 个绘图图层
就已经用掉 480M 的记忆体了
但我用 Photoshop 作实测
它用的记忆体连我所预估的一半都远远不到
如何做到这点让我颇为好奇......
我想过几种改善的可能
例如将「目前工作图层」以下的所有图层都存进硬碟
只将这些「以下图层」混色过後的结果载入记忆体
但这方法得要烧香拜佛
祈祷使用者多编辑上方图层 少编辑下方图层.....
我还想过是否可以用这种预计算的方法对付「所有以上图层的结合」
但由於图层的某些混色模式和某些调整颜色的演算法
都必须先决定下层图层的颜色才能计算
所以这想法似乎也行不太通
不晓得在这方面各位有没有什麽高见?
另外一个问题则是时间上的:
假设使用者开了100个图层而且都没关掉
(一般修图情况下调整图层比绘图图层多出数倍是正常的)
又将视窗画面缩放到可以看到全图的话
那麽必须做的即时运算
竟然有 3000*2000*100 = 100M 次混色之多!!
即使我已经对混色演算法做了 bitwise 的优化
但每次混色毕竟还是包含多次的是否判断式、加法、乘法、位移......等等
从现实情况上来说跟本不可能来得及
(流畅动画的最低标准是 24fps,也就是最慢0.04秒内要完成全部混色动作)
我想过一个改善方式
就是对每个像素侦测「是否已经掩盖下层图层」
换句话说
如果有某个像素在某一层的 Alpha 值已经是 FF
那就可以不用管他下面是三小了
但後来发现这方法会快速地在不同图层间切换
造成 Cache 效率极差 反而不如整张一起算 老老实实的算到底XD
总之 我实在是想破头也想不出好方法
关於这两个问题 如果有人能给我一点方向 我会非常感激 ^^”
--
直接阅读《琴剑六记》
http://gs.cathargraph.com/p/list.html
《琴剑六记》Facebook专页
https://www.facebook.com/GSannals
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 61.62.253.66
1F:→ tkcn:若图层只存有色彩的矩型,而不是整张画布呢? 140.114.78.231 08/03 01:26
2F:→ pnpncat:这也是要烧香拜佛啊XD 使用者有可能会把 61.62.253.66 08/03 01:34
3F:→ pnpncat:十几张照片各自载入为图层 那就整张画布 61.62.253.66 08/03 01:35
4F:→ pnpncat:都有资讯了 61.62.253.66 08/03 01:35
5F:→ MOONRAKER:photoshop之所以为photoshop就是因为他118.165.219.222 08/03 01:37
6F:→ MOONRAKER:能掌握每一layer最多需要多少空间118.165.219.222 08/03 01:37
7F:→ MOONRAKER:不是用「原子弹爆炸」的做法118.165.219.222 08/03 01:38
8F:→ pnpncat:如果姑且不论储存空间 关於效能的问题呢? 61.62.253.66 08/03 01:40
9F:→ pnpncat:我想到的效能改善都是跟使用者行为有关的 61.62.253.66 08/03 01:41
10F:→ pnpncat:还没想到什麽通用的方法 61.62.253.66 08/03 01:41
11F:→ pnpncat:如果真的没办法 可能就得探到更下面了 61.62.253.66 08/03 01:46
12F:→ pnpncat:例如用 Cuda 做平行运算之类的@@ 61.62.253.66 08/03 01:46
13F:推 bill42362:cuda不错阿 shader 本来就是为这设计的 118.161.109.88 08/03 07:28
14F:→ pnpncat:其实有考虑用 cuda 但一直没用的原因是不 219.84.209.192 08/03 11:06
15F:→ pnpncat:太想写需要特定显示卡支持的程式 唉 219.84.209.192 08/03 11:06
16F:→ Chikei:PS对於这种极端case也这麽厉害嘛?像是20层 211.72.92.133 08/03 13:01
17F:→ Chikei:都是复杂照片一样只消耗预估的50%-? 211.72.92.133 08/03 13:02
18F:→ MOONRAKER:那不可能吧,他只会开始用硬碟当scratch 118.163.12.174 08/03 17:52
19F:→ MOONRAKER:disk而已,接着就开始变得很慢 118.163.12.174 08/03 17:52
20F:→ Chikei:那就应该是只存最小面积/色彩index吧 211.72.92.133 08/03 18:34
21F:→ Chikei:我也很怀疑对於3Kx2Kx100L这种东西PS真的能 211.72.92.133 08/03 18:42
22F:→ Chikei:办到很流畅的混图层嘛XD 211.72.92.133 08/03 18:43
23F:→ pnpncat:100 Layers 是不少见啦 但现实情况中 219.85.123.240 08/04 00:04
24F:→ pnpncat:很少会将100层同时打开 219.85.123.240 08/04 00:05
25F:→ pnpncat:我可能要对 PS 作更详细的测试了@@ 219.85.123.240 08/04 00:06
26F:推 abcdefghi:把各layer scale成萤幕大小(dpi)再放记 114.44.183.241 08/04 21:27
27F:→ abcdefghi:忆体, 只有在zoom in/out的时候才重算 114.44.183.241 08/04 21:28
28F:推 bill42362:不用 cuda 可以考虑看看 OpenCL @@"118.161.191.142 08/05 00:26
29F:→ pnpncat:a兄的方法很好 不过那样就不能做滚轮缩放 180.176.20.143 08/05 03:50
30F:→ pnpncat:了吧我想 变成缩放成本很高 180.176.20.143 08/05 03:50
31F:推 abcdefghi:开另一个threads专职作scaling,每个laye 114.42.176.184 08/05 08:30
32F:→ abcdefghi:只要完成就丢给主thread,互动性应该不差 114.42.176.184 08/05 08:33
33F:→ pnpncat:感谢指点 我再试试看^^ 219.84.209.244 08/06 09:40
34F:推 yoco315:我确定ps只有保存有像素的区块 58.115.137.102 08/07 21:01
35F:→ yoco315:超出那个矩形的地方根本不吃记忆体 58.115.137.102 08/07 21:02
36F:→ yoco315:但相对的,如果那个图层被移动到超出边缘 58.115.137.102 08/07 21:03
37F:→ yoco315:即使已经超出画纸,也依然会吃记忆体 58.115.137.102 08/07 21:03
38F:→ yoco315:这个设计很合理,也省记忆体,move的实作 58.115.137.102 08/07 21:03
39F:→ yoco315:也很快速,缺点就是blending的时候比较贵 58.115.137.102 08/07 21:04
40F:→ yoco315:另外,你要求的流畅度可能有点太超规格了 58.115.137.102 08/07 21:05
41F:→ yoco315:即使是adobe的千里马,在多层的时候,即使在 58.115.137.102 08/07 21:05
42F:→ yoco315:高级电脑上也是卡卡的,除非使用GPU加速 58.115.137.102 08/07 21:06
43F:→ yoco315:这是我上次去参加conference的时候,CUDA给 58.115.137.102 08/07 21:06
44F:→ yoco315:的其中一个展示... 人家也要GPU才能作到:( 58.115.137.102 08/07 21:07
45F:→ pnpncat:多谢y兄 我再次测试的结果 正如y兄所述 219.85.243.227 08/11 17:31
46F:→ pnpncat:此外 先scale的方法似乎行不通 即使只做 219.85.243.227 08/11 17:32
47F:→ pnpncat:Bilinear 多次缩放的成本也太高了 不会 219.85.243.227 08/11 17:33
48F:→ pnpncat:低於Blending本身 先Blending 然後用显 219.85.243.227 08/11 17:33
49F:→ pnpncat:卡缩放(我用openGL)还是比较节省 219.85.243.227 08/11 17:34
50F:→ pnpncat:经过一番讨论 目前我已经比较有方向了 219.85.243.227 08/11 17:35
51F:→ pnpncat:正在努力coding中XD 219.85.243.227 08/11 17:36