植物大战僵尸吧 关注:559,469贴子:5,080,066
几天前在github上发现了0.9.9.1029的反编译,我根据其中的PoolEffect类用vulkan写了个泳池的渲染器,源代码写得太烂就不发出来了
左侧为渲染器画面,右侧为游戏画面


在3d加速关闭时,泳池会直接使用静态图片images/pool.jpg
开启3d加速时,泳池主要由3层组成,白天的泳池还会有一层闪光的粒子
从下到上分别是base,shading,caustic,sparkly
在前三层中,游戏会将泳池切成15x5个网格,然后在cpu上运行类似于顶点着色器的程序,偏移每个顶点的uv,最后使用网格渲染图片
在最后一层中,游戏会在两个矩形区域内绘制多个particles/PoolSparkly.png,每个粒子在0.2~0.8秒或0.2~0.6秒内以0~5或0~10的速度向左移动,并以0~2的速度向上或向下移动,我写的这个跟原版游戏不太一样,不过看着没什么太大的问题
渲染器(度盘):
s/1eG78ZDuzQ8h0YOXdlEOqLA?pwd=pool
提取码: pool
每层的具体细节之后再发


IP属地:日本1楼2024-08-13 11:24回复
    首先是base,shading,caustic三层共用的一些值
    float phase = time * 2 * PI;
    float waveTime1 = phase / 800.0;
    float waveTime2 = phase / 150.0;
    float waveTime3 = phase / 900.0;
    float waveTime4 = phase / 800.0;
    float waveTime5 = phase / 110.0;
    float phaseX = x * 3.0f * 2 * PI / 15.0f;
    float phaseY = y * 3.0f * 2 * PI / 5.0f;
    time以厘秒为单位,表示从关卡开始到现在过了多久
    x为顶点在网格中的x索引
    y为顶点在网格中的y索引


    IP属地:日本2楼2024-08-13 11:36
    收起回复
      广告
      立即查看
      第1层 base
      顶点uv的x偏移 = sin(phaseY + waveTime2) * 0.002f + sin(phaseY + waveTime1) * 0.005f;
      顶点uv的y偏移 = sin(phaseX + waveTime5) * 0.01f + sin(phaseX + waveTime3) * 0.015f + sin(phaseX + waveTime4) * 0.005f;
      如果顶点在网格的边缘,则偏移为0
      蒙版为pool_base_.png,在加载图片时处理


      IP属地:日本4楼2024-08-13 11:44
      回复
        第2层 shading
        顶点uv的x偏移 = sin(phaseY * 0.2f + waveTime2) * 0.015f + sin(phaseY * 0.2f + waveTime1) * 0.012f;
        顶点uv的y偏移 = sin(phaseX * 0.2f + waveTime5) * 0.005f + sin(phaseX * 0.2f + waveTime3) * 0.015f + sin(phaseX * 0.2f + waveTime4) * 0.02f;
        如果顶点在网格的边缘,则偏移为0
        蒙版为pool_shading_.png,在加载图片时处理


        IP属地:日本5楼2024-08-13 11:46
        回复
          第3层 caustic
          顶点uv的x偏移 = x / 15.0f + sin(phaseY + waveTime1 * 1.5f) * 0.004f + sin(phaseY + waveTime2 * 1.5f) * 0.005f;
          顶点uv的y偏移 = y / 5.0f + sin(phaseX * 4.0f + waveTime5 * 2.5f) * 0.005f + sin(phaseX * 2.0f + waveTime3 * 2.5f) * 0.04f + sin(phaseX * 3.0f + waveTime4 * 2.5f) * 0.02f;
          如果顶点在网格的边缘
          顶点uv的x偏移 = x / 15.0f;
          顶点uv的y偏移 = y / 5.0f;
          如果顶点在网格的左侧边缘、右侧边缘或上方边缘
          顶点的不透明度 = 32 / 255;
          否则如果是夜晚
          顶点的不透明度 = 48 / 255;
          否则如果x<=7
          顶点的不透明度 = 192 / 255;
          否则
          顶点的不透明度 = 128 / 255;


          IP属地:日本6楼2024-08-13 12:16
          回复
            caustic的图像不是256x256像素的images/pool_caustic_effect.jpg,而是一张运行时创建的128x64像素的位图
            这张位图的每个像素的不透明度为
            a = 从images/pool_caustic_effect.jpg进行两次双线性插值得到的平均值;
            如果 a >= 160,那么a = 255 - 2 * (a - 160);
            否则如果a >= 128,那么a = 5 * (a - 128);
            否则 a = 0;
            最终的不透明度为a/3
            我在着色器里是这样写的
            float time_mod655_36 = mod(fragTime, 655.36);
            vec2 uv0 = fragUV;
            vec2 uv1 = fragUV;
            uv0.x = (2.0 * uv0.x) - (mod(time_mod655_36 + 0.01, 655.36) / 6.0);
            uv0.y = (2.0 - (2.0 * uv0.y)) + (time_mod655_36 / 8.0);
            uv1.x = (2.0 * uv1.x) + (time_mod655_36 / 10.0);
            uv1.y = (2.0 * uv1.y);
            uv0 /= vec2(2.0, 4.0);
            uv1 /= vec2(2.0, 4.0);
            float alpha0 = texture(textureSampler, uv0).r;
            float alpha1 = texture(textureSampler, uv1).r;
            float a = (alpha0 + alpha1) / 2;
            float alpha = mix(0.0, 5.0 * (a - (128.0 / 255.0)), step(128.0 / 255.0, a));
            alpha = mix(alpha, 1.0 - (2.0 * (a - (160.0 / 255.0))), step(160.0 / 255.0, a));
            vec4 color = fragColor;
            color.a *= alpha / 3.0;
            color.rgb *= color.a;
            outColor = color;


            IP属地:日本7楼2024-08-13 12:30
            回复
              另外,caustic层的尺寸为704x150


              IP属地:日本8楼2024-08-13 12:36
              回复
                稍微改了一下
                s/1LV2_4HeNHTSuo6EkZSayCg?pwd=pool


                IP属地:日本9楼2024-08-13 12:43
                回复
                  广告
                  立即查看
                  最后的sparkly还不是很清楚,粒子的文件为particles/PoolSparkly.xml,https://tieba.baidu.com/p/6763789640
                  我只能调一调各种参数来让它看起来跟原版差不了太多


                  IP属地:日本10楼2024-08-13 13:00
                  回复
                    又改了一下
                    我还是直接分享文件夹吧
                    s/1Es8hG_z475kehzbul_Fdqw?pwd=pool


                    IP属地:日本11楼2024-08-13 13:05
                    回复
                      对了,按空格或者n可以切换白天/夜晚,按s可以禁用/启用闪光粒子


                      IP属地:日本12楼2024-08-13 13:07
                      回复
                        看不懂,但感觉很nb


                        IP属地:河北来自Android客户端13楼2024-08-13 22:55
                        回复
                          道理我都懂但太长懒得看。。
                          你就说你编译完了效果比起原来如何
                          光发一张图看不出有什么差别


                          IP属地:湖南14楼2024-08-13 22:58
                          收起回复
                            不明觉厉


                            IP属地:广东来自Android客户端15楼2024-08-14 09:38
                            回复
                              广告
                              立即查看
                              能使用vulkan的人都是不可思议的天才。。


                              IP属地:北京来自Android客户端16楼2024-08-15 03:39
                              回复