Project1

标题: Pixel Shader[来吧 杀了这个就能升级了] [打印本页]

作者: viktor    时间: 2013-4-3 08:14
标题: Pixel Shader[来吧 杀了这个就能升级了]
本帖最后由 viktor 于 2013-4-3 21:39 编辑

===拿出所有的VIP悬赏 跪求能够在RM中使用Shader的脚本===



具体要求:
能够使用Shader对RM的Bitmap进行操作,或者使用其他的合适方式,引入Shader对RM的画面进行处理也行
处理速度要能满足实时处理:至少20fps吧
使用的hlsl/cg脚本很容易在脚本里修改
原创脚本或者在网上搜索的都可以(虽然在下已经粗略地搜索过了,没有相关内容),请提供一个中文或者英文的样例

现在的讨论进展:





以下是背景资料和线索

1【Shader是什么?】
pixel shader是在显卡上执行的一种程序。它可以高效地对纹理的每一个像素进行运算。
这使我们能够实时地完成多种特殊效果,比如多重纹理、逐像素光照、视野深度、云层仿真、火焰仿真和复杂阴影技术。
可以部分理解为使用显卡,实时地对游戏的图片进行PS

2 【为什么RM需要Shader?】
为了更炫丽的效果。
有很多前辈都开发过RM的图片滤镜库,例如6R天干宝典中就有“图片滤镜效果样例”,或者11区的WF-RGSS,或者RMVA自带的Bitmap.blur/radial_blur模糊效果。
但是这些库里面各种效果都没有办法实时使用,原因就是“这一操作需要时间”

因为它们都是使用CPU进行计算,没有利用到显卡。
而Shader的最大特点就是他完全是在显卡里运行,非常高效而且不耗CPU。现在即使是集显也支持相当数量的Shader效果

3 【有什么线索么?】
在下不会DX,知道的只有以下这些:
http://blog.csdn.net/pizi0475/article/details/4241024
RM的Bitmap,其实就是DX的纹理。所以用Pixel Shader去操作RM的图片,实际上是对纹理进行操作

4 【我拿这个准备用在哪里】
Shader有很多用途,上面已经说了。
我自己写了一个实时视野光效的脚本,现在需要增加一个动态模糊效果,否则效果只能是这样的……

如果有了动态模糊,这个光影就会变得非常自然。我曾经用那个WF-RGSS试过,非常慢(0.5fps)


再次跪谢


@喵呜喵5 @晴兰 @yangff @凌童鞋  
堵上人参的悬赏,当掉了骑士的高头大马,重新拿起量产型长剑
作者: j433463    时间: 2013-4-3 08:21
看不懂,是类似这种东西吗?
http://www.santuariorpgmaker.com/forum/index.php?topic=10336
作者: viktor    时间: 2013-4-3 15:33
没人回答么……自己顶一下,顺便站楼备用
作者: 晴兰    时间: 2013-4-3 16:02
提示: 作者被禁止或删除 内容自动屏蔽
作者: yangff    时间: 2013-4-3 16:09
……除非换引擎,不然不可能。
作者: Sion    时间: 2013-4-3 19:28
我对这个工程比较感兴趣,可以的话,发一个范例给我吧。
可以试着帮你优化一下。
[email protected]
作者: bbaugle    时间: 2013-4-3 19:40
对于RGSS引擎还是算了吧。
作者: yangff    时间: 2013-4-3 21:42
我来解释一下为什么DX(OGL)+RM无法对画面进行具有实用意义的实时的修改。
首先先说一下我现在能做到的。
可以将RM的Bitmap,或者每一帧更新时的整个画面,打了个包丢给DX,OpenACC这类的GPU计算(群集计算)的库。
然后GPU高效计算之后。代替RM原有的绘制操作,进行绘制。
但是路人皆知显存和内存交换数据简直就是茶几上的悲剧。
什么,你不信……你知道自从我用了batch之后画面绘制的效率提高了100倍么?
-----------
可以看出,楼主想要实现的是对RM中的图元(Bitmap)进行修改。
大家都知道,RM使用DD进行画面绘制,原生不支持Shader。
然后,RM非常悲剧,Bitmap什么的都在内存里面。
如果要Hook的话,可以用过一些简单的方法,把这部分(DX)数据撸到Shader,然后两面交换一下丢回来。这是没有问题的。
包括Tilemap。
但是这样操作会有比较蛋疼的效率问题。
目测精灵超过200个就得跪。
怎么办?
当然有办法。
只要智商没有问题的人都看出来了这里该死的内存和显存……你们……
于是,只要愉快的接管RM的Graphics啦,Tilemap啦,Bitmap啦,Viewport啦,Sprite啦,吧啦吧啦,把数据统统塞在显存就可以轻松高效加愉快的解决问题了。
接下来是抢答时间……请问如果你用了fmod,RM的引擎还剩下什么,你确定是Ruby而不是Ruby而是Ruby!
> 然后你可以去找@晴兰 考虑一下在RM的窗口里面塞个DX然后就没有然后了。不对……你还是可以画RM本来有的东西……
作者: viktor    时间: 2013-4-3 21:46
Sion 发表于 2013-4-3 19:28
我对这个工程比较感兴趣,可以的话,发一个范例给我吧。
可以试着帮你优化一下。
...

额……因为这个脚本是和机油合作的,不能随意处置。
我大概说下原理吧……

1.每一帧计算每一格的光照值,视分辨率一共要算400-800次;
2.使用Fill_rect把亮度矩形画在1个Sprite上,只画改变的部分,一共要画0-800次;
4.把那个Sprite放在地图上面

其中第2步就是使用CPU进行像素填充,这已经非常吃亏了。在默认分辨率下很流畅,但是1024*600的时候就只有20-40fps了。
还有没做的第3步是动态模糊。每一帧只要把光照图模糊1个像素,显示效果就可以大幅提高。我曾经用过WF-RGSS和PRFilter的滤镜测试,他们都是用CPU进行模糊,加上以后直接变成0.5fps
作者: 晴兰    时间: 2013-4-3 21:48
提示: 作者被禁止或删除 内容自动屏蔽
作者: viktor    时间: 2013-4-3 21:50
yangff 发表于 2013-4-3 21:42
我来解释一下为什么DX(OGL)+RM无法对画面进行具有实用意义的实时的修改。
首先先说一下我现在能做到的。
...

[目测精灵超过200个就得跪]
恩……内存和显存的问题我意识到了,但是没有办法想的这么清楚。 但是
(还在找希望……)
如果我只有10个等于屏幕大小的精灵呢?

作者: yangff    时间: 2013-4-3 21:52
晴兰 发表于 2013-4-3 21:48
其实仔细想想差点就被@yangff 骗了。。yangff一直强调显存和内存要数据交换效率很低,
但是实际上显存里 ...


= =这样更麻烦了,你要考虑RM有draw、blt这样的操作。换句话说,你选的了自行维护显存与内存数据统一,却没有完整的操作维护……或许你需要对Texture进行Hook?(把它绑定到ITexture9,建立为DEFAULT)
Tilemap目测只有元数据,其他的现场合成吧。

这特么几乎就换引擎了好么,也不是一个DXRuby能解决的= =。
听说你能用Ruby做COMHook?
没错我是来刷经验的。
作者: 晴兰    时间: 2013-4-3 21:57
提示: 作者被禁止或删除 内容自动屏蔽
作者: yangff    时间: 2013-4-3 22:02
晴兰 发表于 2013-4-3 21:57
这个不麻烦。。draw/blt的操作原来是对RGSS::Bitmap,现在还是对RGSS::Bitmap这么操作,
操作完重新载入 ...


我说了,不用Hook你写,
Bitmap#draw_text
Bitmap#blt
Tilemap
能使用能Shader再说。
特么RM的Lock你说我的Lock,滚。
作者: 晴兰    时间: 2013-4-3 23:02
提示: 作者被禁止或删除 内容自动屏蔽
作者: yangff    时间: 2013-4-3 23:21
本帖最后由 yangff 于 2013-4-3 23:24 编辑
晴兰 发表于 2013-4-3 23:02
别的我不说。。yangff前辈的DX开发经验肯定比兰兰丰富,但未必不能实现上面所述的东西,
因为我在下载DXS ...


这不就是单独出来了。我所谓的不更换引擎是指不对原有RM代码逻辑进行修改……LZ明显要做的是光源。。
作者: 晴兰    时间: 2013-4-3 23:29
提示: 作者被禁止或删除 内容自动屏蔽
作者: yangff    时间: 2013-4-3 23:57
不知道lz的具体做法,如果只是遮罩的话完全不用GPU。直接根据光源数据预先生成一张遮罩层,然后人物移动进行更新就行了(只会阻碍光线,很容易做的)

我还以为是想terraria那样的粒子光源,那样绝对是要我说的那样的。里面涉及到的东西有点复杂。
@晴兰
我从来没有设计好RM3D的模式,严格的说,只要用了dx,我就不认为这是纯粹RM引擎了。
所以我从不认为RM3D有任何实用意义。
当然,用DX画然后rtt然后画到RM上除外。不过这也不算纯粹RM了,而且同样毫无意义。

我所谓的使用RM的意义是不引入其他的引擎、图形库、音频库。
至于鼠标……你觉得一个小挂件能说是引擎么。
如果你用了hge来实现鼠标,我当然就说你引入了别的引擎,同样,DirectInput也是。但是Win32API显然不是,RM自己也在用。
如果你用了DD7,我也不会说这是别的引擎,但是shader至少用d3d9.


简单的说,我认为,用了D3D9,就是使用了别的引擎。混合进RM的逻辑,就是引入了这个引擎(举个例子,和引入和使用不同的是,引入可以考虑zorder,使用不行)。
作者: 晴兰    时间: 2013-4-4 00:27
提示: 作者被禁止或删除 内容自动屏蔽
作者: yangff    时间: 2013-4-4 10:12
本帖最后由 yangff 于 2013-4-4 10:20 编辑
晴兰 发表于 2013-4-4 00:27
不管你怎么界定,和我相同也好不同也好(二进制层面上是不分引用/导入/需要/包含啥的。。),
现在的实际 ...


LZ的做法我只想知道,会不会涉及到对tilemap图元的操作,如果不会(也就是简单的加法减法合成,给方块光源增加梯度),我有不需要shader的处理方法(在RM的最后一次描绘的之后直接MMX修改,效率不会太差,至少640*480.。)。

如果只是问题本身的话,绝对是要dd7hook的,这货谁爱弄谁弄去。
作者: viktor    时间: 2013-4-4 12:29
yangff 发表于 2013-4-4 10:12
LZ的做法我只想知道,会不会涉及到对tilemap图元的操作,如果不会(也就是简单的加法减法合成,给方块光 ...

不需要操作Tilemap,只需要引用里面的地形标记。现在是直接Fill_rect填充32x32的格子,每帧大概0-800次操作,是可以流畅运行的。
但是我还需要动态模糊效果。所以想到用shader
当然如果使用MMX混合的话,还有一种办法就是做一个32x32的圆形渐变图,把它按照当前格子的亮度值 blend到光照mask上面,但是这样做也就是15年前云风那个时代使用的折中的处理办法。在云风的博客里面也有很多相关内容。相比之下,如果能够使用Shader 岂不更加优美一些?
作者: yangff    时间: 2013-4-4 13:21
本帖最后由 yangff 于 2013-4-4 13:35 编辑
viktor 发表于 2013-4-4 12:29
不需要操作Tilemap,只需要引用里面的地形标记。现在是直接Fill_rect填充32x32的格子,每帧大概0-800次操 ...


如果只是这样用shader的话,直接用兰兰的DxRuby就行了。
不过我很奇怪,这种覆盖的操作方式是怎么处理加法和减法的?
另外,你这样的操作(我是指你现在这种效果,其实不用fillrect,直接操作单点,然后zoom=32就行了……)
模糊不是很理解,阙值多少?
作者: viktor    时间: 2013-4-4 22:43
yangff 发表于 2013-4-4 13:21
如果只是这样用shader的话,直接用兰兰的DxRuby就行了。
不过我很奇怪,这种覆盖的操作方式是怎么处理加 ...

另外因为我暂时只需要对1个大的Bitmap进行处理,从效率上来说,就按你先前说的,先拷贝过去,再处理,再拷贝回来,那也是完全可以接受的。
所以就按你说的做一个就行了~不要想那么多

1. 把Bitmap的内容拷贝到DX可以处理的结构里
2.渲染
3.拷回来

我会拿DxRuby试一下的
作者: yangff    时间: 2013-4-4 23:58
本帖最后由 yangff 于 2013-4-5 00:01 编辑
viktor 发表于 2013-4-4 22:43
另外因为我暂时只需要对1个大的Bitmap进行处理,从效率上来说,就按你先前说的,先拷贝过去,再处理,再 ...


我懂了,你的光照是一个窗口大小的bitmap是吧。
很遗憾的告诉你……就算你用了Shader,优化效果不会特别明显(比Ruby肯定快,但是和直接用C操作),而且这种实现其实是有问题的。
首先,你是要计算一个BrightnessMap作为每个像素的亮度,
如果直接
for i in 0...width
  for j in 0...height
  end
end
的话非常慢(O(N^2))(其实我搞不懂你为什么一定要用模糊)。
另外我也不知道你到底用了什么算法计算:
是根据光源暴力扩展亮度还是根据距离和轮廓线进行计算……
【另外提一点,这里可以用kdtree优化……具体看《计算几何算法与应用》光线采样什么的。。】

但是实际上就算你用了shader……也不能改变内存和显存交换数据的问题……
(如果要做到兰兰所谓的单向,仅仅外包一个dx是不够的)
数据交换还是width*height的……

所以我还是坚持,MMX解决问题……

另外,我不知道你是怎么把光源合成进地图的。
如果是修改地图的亮度,然后把光源用加法合成上去……其实是会出问题的。
不细说,你把全局亮度调到0,然后光源亮度随便给,东西会全部没掉。
不过如果是固定alpha然后修改颜色……虽然可以……但是其实效果比较坑爹。。
作者: viktor    时间: 2013-4-5 15:22
本帖最后由 viktor 于 2013-4-5 15:29 编辑
yangff 发表于 2013-4-4 23:58
我懂了,你的光照是一个窗口大小的bitmap是吧。
很遗憾的告诉你……就算你用了Shader,优化效果不会特别 ...


恩……好吧我还是把视野脚本悄悄地贴出来吧。关于实现原理在这里不想做更多的解释了,看了就知道了其实做法很水 而且也并不是真正的【光照】计算。
因为我根本就没有想要做光照 只是想做一个根据当前的地图障碍物的情况改变视野明暗的,实时的 但是是伪的 视野效果。这个效果有点像是Elona的那种

主要的函数是iterate_tiles和update_bitmap,像素填充和准备做的模糊都写在update_bitmap里面,那个也是主要要优化的地方
http://blog.csdn.net/xulai1001/article/details/8761416
@Sion @yangff  
作者: 晴兰    时间: 2013-4-5 16:01
提示: 作者被禁止或删除 内容自动屏蔽
作者: chd114    时间: 2013-4-5 19:06
除非你不用RMAV,否则不可能,因为语言不同,就算转换成同种语言也不会是一种效果
作者: viktor    时间: 2013-4-24 14:09
yangff 发表于 2013-4-4 23:58
我懂了,你的光照是一个窗口大小的bitmap是吧。
很遗憾的告诉你……就算你用了Shader,优化效果不会特别 ...

果然是我想复杂了。
如果光是为了做视野的话,根本不需要用到Shader,只要能用DX往画面上叠加3D模型就好了。

如果屏幕是20x15格的话 ,就搞一个20x15格的3D平面模型,顶点是每个格子的中心点,
然后顶点的颜色是那个格子的亮度,格子中间的颜色让他自己去插值。
设置合适的视角让他显示出来和屏幕一样大。
生成了这样一个3D模型以后,渲染到纹理,然后传送给RGSSBitmap 就可以了。

但是这个问题还是留在这里。毕竟用了Shader可以实现更多的功能啊
作者: 秋寒    时间: 2013-4-25 13:02
建议下个《少侠一炷香》开源版,记得里面有一个技能使用后突然全场变黑白,效果差不多吧...




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1