Blog logo

Blog logoJustZht

2020.5.31

 • 

在朋友圈发了张 AppFigures 的图,从生日那天到前几天算是三个月,总计收入也只有 2704 刀,可以说是非常不顺了。每个尖尖都是和媒体合作推广 giveaway 后升起的,过了几天随即又掉下去,因此压根维持不了每天 150 刀的进账。关于 Google Play 个性化品类的实验也就此为止,后期估计不太会再在这个品类里面投入太多精力了,而会回去做 Epoch,最近刚好就在研究怎么用 Voxel 插件在 UE4 里生成可以形变的星球。


之前搜索我自己的软件的时候碰到了一个 Reddit thread 是有人在求我的软件的破解版,底下遂有人回复用 lucky patcher 之流等等,但似乎并没有人成功。这倒也挺令我惊讶的,因为我在 Diffuse 的两个版本里都只集成了 Google 官方的基础本地验证,即 LVL 和 Billing Library,而没有像在 Metropolis 那样配合 Firebase Functions 做了一个后端验证,反破解能力可以说是非常弱了。
看完那串 thread 我在下面回了句,大意是“我是 Diffuse 的作者,仅以此回复让大家知道,想要用 Diffuse Pro 的人都可以写信给我,我虽然不能满足每个人的需求,但我心情好的时候会发激活码,不过可以肯定的是用 patcher 破解我的软件不在能让心情好的范畴里”。我也不知道当时为什么要写这个回复,或许只是想做一个社会试验,看看大家的反应吧。随后楼主就 dm 我要了个激活码,我给之后顺便让他帮我好评下,因为 Diffuse 总是有某名奇妙的低评分拉低整体排名,如果能让用户给个好评也算变相弥补了。
接下来的两周里,我间断地收到了差不多 20 个请求,给了 15 个。有些人给了之后会和我比较友好地聊一会,甚至里面有职业做云计算和社交推广的人给了我一些建议作为激活码的感谢,而有些人就没有回复过,倒也正常。这之中能看到很多为什么不买软件而问我要激活码的理由,有的是说中东地区没有买软件的习惯,我回复说我能理解,我住的国度也没有这个习惯;有的是说因为疫情节省开支,等结束了会支持我,我回复说希望我的壁纸能在这艰难的时光让你的生活稍微变得轻松起来;还有的说自己是学生,这个时候我总会哑然失笑:我也是个学生,而且是乱世中连 F1 签证都不知道能不能拿得到的学生。
再之后有一位西班牙的用户留言说是否能翻译软件作为激活码的酬劳。这对我当然是好事,因为彼时我正在和西班牙语频道 HowToMen 沟通在他们的视频里推广 Diffuse 的事情,有本地化自然会对软件的传播有好处。于是合作很愉快地,软件被翻译成了西班牙语,我也加了一个 acknowledge 界面挂了他的全名,顺便送了 5 个激活码,大家都很开心。
做这些事情总会让我有一种世界还很好的感觉,似乎世界仍然是全球化的样子,自己的软件被分发到世界各处运行在不同的设备上,被众包的方式翻译到另外一种语言,通过一个软件集结起一批志同道合的人们,不管是在乎版权还是不在乎的,而我虽然想靠卖软件挣钱,但似乎深入下去也不关心自己被盗版的事情,有人用并且认可我就很开心。
总体来说,虽然也有人会在我的软件评论里打一星说我的软件是中国开发,是给 CCP 收集数据的(后来怼回去他自己删掉了),但这三个月的独立软件生涯还算开心。只不过我又一次要放弃对软件的维护了,就像是当时放弃 Skyline 的维护一样。原因有很多:不挣钱,这三个月做外包都比做独立软件挣的多,而用户的 feature request 我认为仅靠 1.99 的单价压根买不到;我提出了分手,情绪低落不再能支撑软件售后的工作;国际政策变化,要做不读书去找工作的两手准备,等等。


听了 Hold Onwould you love mecomfortableSeaside Breeze

2020.5.25

 • 

这几天出门见了一些人,结果都说看起来变瘦了些。除去季节变换衣服穿少之外,可能真的是这几个月节食起到了作用。
聊到这里我总会想到海边的卡夫卡里,男主自言自语道胃是可以训练变小的,而若胃变小,吃饭的时候就会很快感觉饱腹,也因此节省了开销。这话应该是男主决定离家出走的时候说的,而我没有什么迫切的要离家出走的理由,也没有什么节省的实质目的,只是单纯地想回到大三的体重而已。


听了 TECHNOVASay GoodbyeNoite De VerãoSavageRick JamesTom Nook。看了 History 10180'S Japanese City Pop Vol.2,还有 TENET 的预告片。


UniLWP.Droid 上架被拒了,原因是里面包含了 Unity 和 Android 机器人的 Logo。估计需要几天把素材换下来重新上架(估计又要 20 天的审核)。👇

UniLWP-Cover-Image-1

2020.5.18

 • 

算起来这个月 Google Play 上靠两个壁纸赚了 2000 刀,虽然肯定没有 Skyline 一夜暴富赚得多,但作为额外收入我也很满意了,只可惜目前看起来并不是稳定的可以当作生活费一样的收入流,需要持续的推广,给科技媒体写邮件,在用户社区回复评论,根据 feature request 写新功能,如果是按照全职 indie dev 的标准来看 2000 刀并不是很高,甚至只能说刚好及格线,毕竟这个收入也没到 18 年临近毕业签三方时某厂开的工资,而两年也已经过去了,某厂应届生的薪资都赶得上后来在另外一家创业公司作为联合创始人拿到的 package 了。
不过我也大可不必对自己这么刻薄,毕竟我也不是什么按部就班来的人,每年都会有几次大起大落的,而且九月就又要上学了,要度过两年的研究生时光,又会有大把时间可以用来试错。
今天早上和某个手机厂商聊了下可能的合作,被灵魂拷问问到后面的规划是如何,我才发现 23 了,我还是没有明确的目标,而且甚至有些习以为常。我到底算是要做什么呢,读个 master 然后去当 SDE,业余做点独立游戏,然后创业期待着被买下来,还是开个 agency 接外包,这些事情都太飘忽虚渺了。
虽然该做的事情都做了,我对很多事情的必要性和态度反而没有大学的时候那么坚定了。

听了 巫堵

Diffuse: 如何做一个类似于 Apple Music 的假流体壁纸

 • 

其实 Diffuse 最后做出来的效果和 Apple Music 的 Live Lyrics 效果不太像,因为后期我也不管苹果的效果如何了,完全按照自己的喜好来调的。而且 Apple 的方案比我的要 versatile 很多,这个词可能比较在描述软件的时候有特定的内涵,导致我也不知道中文要怎么描述了,反正和鲁棒差不多,但是更多的是指对不同的输入都有类似的效果,因为我的方案在纯色封面时效果会特别差,输出的图像没有对比度,Apple Music 的效果会好一些,所以我怀疑他们对图片是有在做预处理,或者压根没有对封面做模糊而是直接根据封面提取出一个色盘后做了渐变。
Diffuse 的基本思路就是对专辑封面先模糊再扭曲。一开始模糊用的是全分辨率高斯模糊,一个纵向 pass 一个横向 pass。后来发现太费资源了,于是改为了马老师(MartinRGB)推荐的 Kawase Blur。有关 Kawase Blur 的详情可以看 Intel 的这个博客,我是在 LibGDX 内实现的,这段从哪来的也忘了,估计是某个 ShaderToy(

// kawaseBlur.frag

#ifdef GL_ES
precision mediump float;
#endif

uniform sampler2D u_texture;
uniform int u_level;
uniform vec2 u_resolution;

varying vec4 v_color;
varying vec2 v_texCoord;

vec4 reSample(sampler2D texture, vec2 res, in int d, in vec2 uv)
{
    vec2 step1 = (vec2(d) + 0.5) / res;
    vec4 color = vec4(0.0);
    color += texture2D(texture, uv + step1) / float(4);
    color += texture2D(texture,  uv - step1) / float(4);
    vec2 step2 = step1;
    step2.x = -step2.x;
    color += texture2D(texture, uv + step2) / float(4);
    color += texture2D(texture,  uv - step2) / float(4);
    return color;
}


void main() {
    gl_FragColor = reSample(u_texture, u_resolution, u_level, v_texCoord);
}
// kawaseBlur.vert

uniform mat4 u_projTrans;

attribute vec4 a_position;
attribute vec2 a_texCoord0;
attribute vec4 a_color;

varying vec4 v_color;
varying vec2 v_texCoord;

void main() {
    gl_Position = u_projTrans * a_position;
    v_texCoord = a_texCoord0;
    v_color = a_color;
}

关于 kernels (u_level) 我选的是 0,1,1,2,2,3,3,4,用了两个 192*192 像素的贴图 squareBufferA 和 squareBufferB 互相渲染,效果还不错,性能在高通 8xx 上都没遇到太大的问题。

blurShader.begin();
blurShader.setUniform2fv("u_resolution", new float[]{squareSize,squareSize}, 0, 2); // squareSize 就是 192
blurShader.end();
batch.setShader(blurShader);
int[] levels = new int[] {0,1,1,2,2,3,3,4};
for (int i = 0; i < levels.length; i++) {
    int level = levels[i] * 2;
    boolean swap = i % 2 == 0;
    blurShader.begin();
    blurShader.setUniformi("u_level", level);
    blurShader.end();
    batch.begin();
    if (swap) {
        squareBufferB.begin();
    } else {
        squareBufferA.begin();
    }
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    batch.draw(swap ? squareBufferA.getColorBufferTexture() : squareBufferB.getColorBufferTexture(), 0, 0, width, height, 0, 0, 1, 1);
    batch.flush();
    if (swap) {
        squareBufferB.end();
    } else {
        squareBufferA.end();
    }
    batch.end();
}

blur

然后就是扭曲的过程了。这个部分用的是 Domain Wrapping,基本上就是照着 iquilezles 来了,最后得到的 vec2 作为 uv 去 sample 之前模糊后的专辑图

noise

然后就可以放大分辨率输出到屏幕上了,就这么简单(

2020.4.21

 • 

准备早睡的,但是又一次睡不着。刷了下新闻,原油价格都变负数了
总觉得是什么了不得的事情,但是又说不出来,毕竟自己也只是一个迷茫的,靠写点小软件找乐子的普通人,对这个世界上的其他东西都没什么实体的概念,看到消息也不会跳起来去操作什么期货终端,只是觉得今年的事情真的多啊
要说睡不着的原因,可能牙疼算是一个。总觉得今年会再拔掉一颗烂牙,但因为只是有的时候才发作,因此自己也不置可否,还是无节制地吃巧克力。偶尔在被窝里咽口水的时候能感到缺口穿过空气时微妙的酸痛,像是从空调房突然切换到室外,短暂一阵子就又习惯了,呆滞了几秒钟后就又翻个身子继续胡思乱想
拖了很久没写博客,原因是前段时间在纠结选什么学校。其实到最后就只用选东北大学 MSIS 和纽约大学 MSCEI,个人倾向还是纽约大学,但一年项目外加目前的疫情对找工作这个长远目标不太友好,因此只能安慰自己东北也很不错了,而且多出来的时间可以把游戏开发完。
于是想着可以写个申请总结了,甚至在 Ghost 的后台开了一个 draft 题为 20 fall 申请总结。但又觉得提不起兴趣,毕竟不是什么凯旋而归的结局,对于我来说已经决定就 move on 不提也罢。短短地说的话,今年的总结大致就是低 GPA 的 CS 本科生申请 master 就把自己当成转专业的人来选学校,心态和结果会好很多。我没绕过这个弯,虽然没有死磕 CS 但是还是申请了好几个 Professional CS 或者 Course based MCS,结果只有一个过的 UMass CS。此外,当时还是不够大胆,也不够果敢,本来自己的经历就这么不寻常了,申请的时候还可以多加点戏妨碍不了什么,比如再加十个学校申请把头部学校的偏门项目轮一遍,比如被 rej 了立即写信求转项目,这些都是当时觉得不太好吧所以没去做的事情,现在看没什么大不了的。
啰嗦完这个感觉我的总结草稿可以删了,很多时候倒不是没有写作的心情,而是前方总是有要做的事情,让我感觉做完才有资格能去写博客介绍我干了什么,或是有什么我不想做却又必须要做的事情,拦在前面让我每次想去写博客的时候觉得还不如先把讨厌的事情做完。如此往复写作的乐趣和期待就开始消失殆尽了。
写独立软件也是,一旦套上挣学费这么一个目标,就很难再开心地做下去了,而且还会被别人的灵魂拷问问得自己也怀疑人生。是,以之前尝试做跨平台 markdown 编辑器的我来看,目前做的这些项目都是上不了台面的 Personalize 软件,甚至连 Utility 都不算,但也是因为之前在这个领域有点经验,觉得也许能复制点结果。话说回来,挣学费这件事情,也完全是我自己给自己套上的一个附加目标,我也总喜欢自己给自己这么加戏,力求成为想做什么就能做到的人。
但是本科的前半段的时候我的目标还没这么现实,当时的想法更多的是想做 100rabbits 他们那对 couple 在做的事情,就是开着小船环游世界,船里带着台笔记本,开发各种自用的东西,从小型操作系统到 2D 游戏到相机软件,不管别人用不用得到,自己开心就好。然而那种存粹的乐趣,在我经历很多事情后或许也很难再有了,只希望东北这个两年的项目,能让我在去美国搬砖之外,给我留出一点时间再去做类似的事情,看在学校的生活永远比外面的要单一的份上。
爬起来敲了这么多,到最后公布下之前提到过的 libGDX 项目的网页好了。Diffuse 按理说一周前就应该上架开始推广了,然而因为 Play Store 审核时间变长,目前还处于半上架的状态中,让我卡在不知道要不要准备 presskit 的尴尬境地中。我对这个项目还是挺喜欢的,喜欢到甚至想把这个移植到个人电台 fin.fm 的推流端里去,这个想法反而有点像是有那种自做自用的精神了。
然而全世界那么多人,我也无法保证到底大家的口味如何,究竟令我着迷的这些事情在其他人眼里算什么呢?就像是我放弃的事情在有些人眼里也不可理喻一样。不管怎么说,把自己当个普通人会让这些事情好理解很多,大家都是普通人,在不同的路上周游世界而已,没有什么要比的,这个世界或许就是太容易让人从头到脚互相打量了,反而开一个 echo chamber 会自在一些。

2020.4.10

 • 

Vortex 之前因为 Awareness API 移除天气数据几乎变废了,还好 Yahoo Weather API 可以非商用的前提下免费试用,最近申请通过了,花了一下午迁移了过去,新版本几小时后就会更新到 stable channel 里。
Metropolis 增长依然比较乏力,在 Sam BeckmanGadget Gig 的两个推广视频后有增长,Google Play 的个性化定制这个分类里能排名到新增榜前五,畅销榜前一百,但 that is it,后来就开始掉了,我也不太想再找其他的曝光机会了,投入过大不值,就先这样放着。
之前的博客里还提过一个基于 Rajawali 的项目,后来改成 libGDX 做了,已经在内部测试中了,感觉大家的反响都还不错。只是因为疫情的原因 Google Play 的审核变得特别慢,因此到现在还没有真正发布。

2020.3.25

 • 

找到了一个电影评论的频道 Jack's Movie Reviews,结果看上瘾了,连看了好几个。这种情况越来越少了,之前大学的时候经常碰到好频道,订阅后扫之前的历史投稿能在宿舍里懒在靠椅上看一天,比如 videogamedunkey,lesson from screenplay,escapist 的 zero punctuation 系列,等等。这个频道说借刀杀人的那一期挺合我意,因此还专门给那一期配了中文字幕。可惜的是后来才发现这个频道已经停更了,貌似是因为作者找到了一个实习。
说到停更,h3h3productions 今天倒是久违地一年之后突然更新了一部。YouTube 的推荐算法有的时候还是能给我推荐他们以前的视频,我对他们的价值观还挺认同,比如要大家 chill out 的这期。此外,他们还有很多搞笑的回忆,都是看后能让人放松的视频。

2020.3.20

 • 

天气开始变热了。穿着睡衣在家里写东西的时候经常暖和得很烦躁。
最想去的一个项目给我 rej 了,剩下的要么比现在拿到的最好的 offer 同级要么靠后,因此目前也可以准备决定去哪了。不管怎么说,对于一个本科 GPA 超低的人来说,今年已经超过预期了,所有对之前没有多申请点好学校的后悔都是事后之言,放几个月前我也是不敢对父母保证的。


天气变暖后,莫名地感觉和大学入学前的暑假气氛很像,也是一个看似无忧无虑,实际上也许需要我提前做很多准备的时间。已经有同样录取的人在刷题群里聊天,而我呢,虽然知道要去刷题,但是还在做严重延期的几个项目。
基本上这些项目分为两类,一种是独立软件,希望能快速地重新实践下 Skyline 推广被报道的经验,提前挣一些美元当生活费。然而 Metropolis 的增长并没有达到预期,或者说 Skyline 被报道本身也只是无心插柳的一次成功。因此目前手里还有一个基于 Rajawali 的项目,留着快速开发再试一次,如果还是不行我也就放弃独立开发挣生活费的想法了,转而刷题准备当地的实习。
第二类就是独立游戏。Epoch 已经准备从头开始写了,不过 2016 到现在 Unity 的生态和主推技术栈也改变了很多,再加上目前的 Unity 是一个各类框架都在交接的状态,UI 方面 UI Elements Runtime 要到 2020.1 才有预览包,UGUI 不想用,UIWidgets 又太专注 flutter 的 render to quad 模式,不足以支持特定的 3D UI 需求;渲染方面 LWRP 到 URP 还是鸡飞狗跳,选 legacy pipeline 又怕后期 Unity 直接宣布弃用,接着 Runtime GI 也是 2021 的排期了。倒不是说前期就要做视觉效果,我也可以直接先什么都不管只做数据层,但总是觉得少了很多信心和乐趣。
感觉几个项目在投入和放弃的取舍上都已经不是自己真正想要的了。或许等到下次写博客的时候,能带来一些有趣的消息。

2020.3.13

 • 

最近又陷入了坐立不安的情形,修 Metropolis bug 的时候想打游戏,打 Forza 的时候又觉得不妥,想去把 WWDC 的申请写了或者开始做 Epoch。想起来之前博客上写过实习的时候一旦觉得不自由了就会到处折腾让大家不高兴,现在其实也是差不多的情况。
理论来说现在的确有很多事情要做,比如驾照和刷题,但是又觉得申请的最终结果尚未决定,况且目前各地的情况也不明朗,做事的意义也不知道在哪,因此总是懈怠下去。


Metropolis 做了一些 PR 的工作,但是效果只能说一般,当然原因也是本身软件还有很多我自己都觉得不满意的地方。因此自己总是在做新项目和修 bug 中间来回。关于 WWDC 奖学金的申请,今年想做一个 SwiftUI Prototype Tool,结合去年的节点编辑器,通过节点生成对应的 SwiftUI struct,中间通过 codable 转接。但是后来仔细想了下貌似意义又不是很大,所以也只是开了个头就没投入了。


UniLWP 在 Metropolis 投放的过程中发现和一加手机在 Android 10 上严重不兼容,具体表现就是对 unityPlayer 调用 displayChanged(0,null) 或者 pause 的时候经常超时,导致 ANR 被系统砍掉。原本以为是 call rate 的问题做了一个 debounce,但是看貌似也没用,于是后面考虑利用 Unity 的多显示器支持,把不同的 surface 作为不同的显示屏幕传入 displayChanged 里,避免和主要的 Display(即 index = 0)交互,但是试了下貌似也不稳定,而且每次调试都要生成 jar - 打包 apk - 上传到阿里云云测 - 复现抓 log - 下载下来看,这又是特别消耗 san 值的事情,因此现在已经不想碰了。


所以现在就漫无目的地翻看网页,偶尔查下录取结果,期待某个时候能灵光一现,让我能去做点具体的事情。我还是挺喜欢做这些细细碎碎的写软件的差事的,就是最近太把兴趣当成业务来做了,还是跳票的生活舒服些。

2020.3.6

 • 

距离上次写博客又过去一周了,过得真快。


移动硬盘因为笔记本莫名其妙内核恐慌断电跟着出现了问题,怎么修复也修不好,索性不管了。硬盘里面装着大约 12 年到现在存下来的四五千首歌,损失倒是挺惨重的,虽然云端貌似还有着一份备份,但是是最近一次整理 ID3 信息之前的了,想想就头痛。自己的个人项目存在了另外一个硬盘里,倒是没有受到太大影响,不过也因此停滞了两天的工作。


Metropolis 的官网上线了,页面内的视频也是最近渲染好的。网站里面用 babylon.js 做了一个小型的软件模拟,可以模拟解锁的三维动画。这个写起来比之前 Skyline 的那个要容易很多,因为 Skyline 那次是 three.js,手机本身也不只是个矢量图而是真正的模型,因此当时又做了个 render texture 来模拟手机显示,现在看真的是玩票性质的。


听了 Panini