2016.10.12

 • 

最近突然多了很多课程设计和上机安排,于是花了些时间处理课程设计,包括写了一个 Android 软件,配套的 Rails 服务器端,以及些有的没的。写 Android 软件的首要感受是慢。即使是开了 Instant Run 也会觉得太慢了,这个是相对于使用 Objective-C 的 iOS 项目来说。以及个人感觉系统库里有很多东西功能重复但又没有标清楚,有时候都不知道要用哪一个,用了后又会发现有的已经被标为不再支持了,挺困惑的。
理所当然的,个人项目一行都没写,不过倒是花了几个小时尝试用 MODO 建模一辆车,目前是这个样子:


目前的问题是涉及到一些曲面工具的使用时就会没有办法达到想要的效果,此外总是控制不好面数,有些地方扭曲在一起,显得很乱。自己捣鼓估计是没希望了,还是要找教程。


看到 Tisoga 推荐了 Apple Music,于是开了国区。我听歌非常杂,而想把我所有歌曲都一个个配对为 CDN 里的文件,对于每个音乐服务提供商估计都挺困难的。不过 Spotify 港区在我目前感兴趣的歌手/制作人上表现更好一些,比如 FKJ
Apple Music 国区(2 首歌,而且是在选集中)

Spotify 港区(专辑,歌曲,信息齐全)

以及 Apple Music 目前在 Android 上的逻辑和界面仍然是 iOS 9 的风格,这个就有些尴尬了。总而言之,如果日常使用设备全都是苹果公司产品,并且有多年 iTunes 购买记录的话,Apple Music 应该还是不错的。当然满足这个条件的人应该也不会像我一样开国区了。

2016.10.9

 • 

刚刚把 Ghost 升级到 0.11.1,文章全都没了,吓我一跳。后来发现数据库里面还有,于是删了 node_modules 重新安装了一遍。


十一期间主要是呆在家发呆,然后花了些时间写另一个 Unity 项目,Epoch 暂时延后。说到这里又该说我挖坑不填完的问题了,不过 Epoch 在 Ray-Marching 这块折腾了一周,毕竟是在手机上运行,一旦 Ray Step 和 Noise FBM 次数增加 Shader 运行时间就要超过 40 ms,我也实在是想先放着不管了,等到 iPhone 8 出来了应该会好很多吧。然后说起来挖了坑还没填完的还有 Cetacea 的 Mac 和 iOS 版,其实完成度已经相当高了但想到要重构 Cetacea 的 Theme Manager 就觉得蛋疼。
算起来九月份一直在学校呆着,公司的事情只帮忙写了一点点,结果九月的工资还是打了过来,倒是让我感觉挺不好意思的。


花了些时间把本地歌曲迁移到 Spotify 上。想着反正开了 Premium 不如直接把音乐库用 Spotify 做缓存,但发现其实(至少香港区)歌曲数量也挺少的。在这一点上最全的算是 2012 年左右的虾米,那个时候虾米更多的是一个未授权音乐分享平台,而不是一个音乐流媒体平台。但虾米现在已经没救到我不用的程度了。


一个认识的朋友最近创业,拉了一个群。于是我见识了各色少年。之前大二的时候会被一些人说我年轻,现在我也见到了很多不仅更年轻而技术远远超过我的人了。
我总是感觉着急。我把我见识的一些厉害的人和我周围的人说,他们只是耸耸肩 —— 你还能指望什么反应呢。

海边的卡夫卡

 • 

火车上坐对面的人带了本海边的卡夫卡看,虽然翻了不到几页就趴在上面睡着了 —— 这话只是在叙述,不过听起来像是有些自以为是的原教旨主义者嘲笑他人的意味。不过我倒也没有嘲笑他人的资格,火车里晃来晃去,我看了会关于 Rails 的电子书也昏昏欲睡。
海边的卡夫卡是在高三读完的。坐在班级最后面连看三四天,靠窗边的耳朵带着耳机没人管也没人问,实在是现在想来都神奇的体验。现在看来,海边的卡夫卡与其说是一个自我蜕变的故事,倒不如说是一个自我修复的故事。卡夫卡是有着自己意识的一个人,并不需要外界压力来促使自己改变,外界也改变不了什么。
对于我来说,读这本书具体来说最大的收获就是:所有“后悔”大都是一种借口。若是足够清醒又有执行力之人,明白事情走向不对后定会及时改变,如此事态总不至于落到无可挽回的地步。若是什么也不做,眼睁睁看着事态说着自己后悔当初的决定,那大概也是做什么都无可救药。无论成功和失败,都总是人和人自己较劲,正如卡夫卡和乌鸦一样,没有什么要说后悔的,也不应该说。

2016.9.25

 • 


Fun Fact: 刚才用了下 Unity Cloud Build,Epoch 目前生成的安卓 .apk 文件只有 38.4 MB。
而这个版本的 Epoch 在理论上保守估计就已经有实时随机出 32768 个类地星球的能力了(指地形/半径/大气参数不一样的绿色/灰色为主的有海洋覆盖的星球)。考虑到 Unity 新工程什么也不做都有 7-8 MB,我觉得这个还是蛮有趣的。


一篇有趣的文章:Chris Roberts defends CRYENGINE评论里有人说:

Also, it is kind of hard to even call what they use the same Cryengine anymore. It has been so heavily modified for their specific needs, as well as so many of the Cryengine team now works at CiG that i would call it more the Star Citizen engine at this point.

想起来两天前因为 Unity 在 iOS 上缺少 Deferred Rendering 以及一些难以查找源头的问题和 KevinZhow 吐槽,然后 Kevin 说转虚幻引擎吧,我说要是再这么下去我估计真的要把 Epoch Core 重写到 C++ 上了。不过这话当然是有一些开玩笑的意味,重写的话我估计真的会再也不想做太空游戏了。以及幸好最后解决了大部分问题,最新的截图见 FinGameWorks


22 号去听了 Keren Ann 在长沙的演唱会。说是演唱会但到场的人数只有整个厅的一半,到了最后所有人都围在了前面,倒挺像是在 Live House。记得第一次听 Keren Ann 还是在虾米上听的 La Biographie de Luka Philipsen


不在公司的生活基本是就是写自己的游戏,吃饭,睡觉。没有上课一说。
也不怎么发推了,因为在寝室的每天都是一样的,不知道要说啥。
时常我会有这种感觉:看朋友圈里这几个人在参加什么技术大会,那个人作为大会的讲师,还有几个人今天面基,几个人今天出去玩。大家都过的很正常,日常生活罢了,但很丰富。但他们都在北京,或者杭州,或者什么地方。而我哪也去不了。浏览完朋友圈,继续呆在寝室里面,写着 Epoch。

Epoch Dev Blog 8 - Depth Texture Precision on iOS

 • 

这篇 Update 会很短,因为这个问题的解决只有一句话。
Unity 很多海水 Shader 在 iOS 上都有一个类似的问题:A7 及以前的设备(iPhone 5S / iPad mini 2)上一切正常,但是在 之后的所有设备上都会出现 banding 的效果:


(typo in pic : bonding --> banding)


这个问题是相机的 Depth Buffer 精度不足导致的。当然前提是相机打开了 depthTextureMode:

GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;

解决这个问题需要修改 Shader 中的 sampler2D 精度。这个非常奇怪,因为理论上 sampler2D 的精度就应该和 sampler2D_float 一样 而不是 sampler2d_half,但改了后在 A9 设备上就正常了,谁知道呢。

uniform sampler2D _CameraDepthTexture;

改为

uniform sampler2D_float _CameraDepthTexture;

Epoch Dev Blog 7 - Ocean

 • 

解决了 Depth Buffer 只在 A7 设备上正常的 Bug,海水终于在 A8 / A9 设备上渲染出来了。因为有 Vertex Displacement,所以索性只用一个 Sphere Mesh 来做,效果比我想象的还好一些。



到这个地方基本上地球类的基本地形生成算法和大气层都基本完工了,接下来需要做的是树木的 Population 和 天气变化。树木这部分基本就是把之前 Epoch 的 SpeedTree(松树,苹果树,海星,花,等等等等)搬回来,然后用一个 Pooling System 安置在星球的不同高度上。
至于天气做到这个地方我发现还是蛮难的,对于云的生成简单可以做一个 Sphere Mesh + 两面的 Transparent Shader,但不是体积云,太丑了。尝试使用粒子系统的话问题就是如何处理星球夜晚的云层,从远处看会发现照射处和非照射处颜色一样就不对了,而且我想要比较真实的云彩阴影,要解决这个问题估计要使用 Ray Marching,这几天先研究下吧。

2016.9.17

 • 

刚刚检查了下教务系统,补考三门过了两门。(Edit :之前没更新完全,现在看是三门都过了)按照之前的计划,过了两门及以上准备让公司 HR 帮我和学校争取下,争取不了的话只能 Remote。我还在准备另一个事情,如果可行的话理论上可以让我最不济的情况下拿到毕业证。
罢了我为什么要在博客上详细地写这种事情。说些其他的。


第一个事情。有两个小软件上架 App Store 了。之所以说小,因为这两个软件都是一个晚上完工,而且其中一个只有 555 KB。我个人觉得比较有意义的是 Contributions for GitHub,这个软件可以让你在 iOS 的今日视图中查看 GitHub 的贡献图,有二维和三维模式(iOS 10 支持在 Today Extension 使用 SceneKit)。

因为是一晚上写的,有很多地方没有做错误处理。以及我觉得维度切换可以做的更炫酷,这个就等哪天有空修下了。我真应该改下我挖坑不填完的习惯。


第二个事情。这几天闷声写 Epoch,继续优化了 Shader,买了 RTP,地形终于达到了一个我比较满意的效果:



(我知道现在看起来效果还是很简陋,不过东西都会有的,老版本 Epoch 的内容都会渐渐重写到新的工程里)


看了两部电影,星际迷航和 War Dogs。后一部给我的感觉和华尔街之狼非常像,简直就是 Wolf of Wall Street With Guns,我非常喜欢这类题材。以及这部电影的预告片非常带感,可以戳 Youtube

2016.9.11

 • 

Unity Editor
花了两个晚上,把 LibNoise 的 Perlin Noise / Spherical Map Builder 移植到了 Unity Fragment Shader 里面。
毕竟是在 Shader 里面写,修改了一些内容。LibNoise 原先自带的一组 Randoms[1024] 被一个 lookup table 替代了,否则直接嵌在 shader 里会溢出。然后 C++ 版本里面奇奇怪怪的位运算(比如 >>,^=,&=)有的使用了数学等价的代码解决,有的就直接丢精度不管了(LibNoise 原库所有运算都是 double 为基准,这种精度在手机着色器上是达不到的,所以丢失精度也无所谓吧)。
基本功能实现后,速度提升是有的,相比 LibNoise.Net 版本在 iPhone 6S 上提速了至少 50 倍,虽然时间没有上篇文章提到的那样在几十毫秒内,但也基本满足我的要求了。现在要解决的问题就是如何把 LibNoise 的其余部分实现出来,同时保证 Shader 编译后的大小不会太大,速度不会太慢。以及如果可以的话我希望能在 Shader 里面顺便把 ColorMap 和 SplatMap 的生成工作给做了。


回校补考周五结束了。说不上有多好,但我本来也就没有抱多大希望。倒不如说,我盼望着大家都赶紧对我放弃希望,这样我就能去做我喜欢的事情了。
有一个非常有趣的现象是如果你说自己不想干了,大家的态度都是“你都上了两年学了 / 你都寒窗苦读十几年了就差这一两年么 / 你怎么这么急”。倒不论说话者究竟是什么意思,但这般说辞实在是乏味可陈。我实在想不出为何时间一长,任何事情就都成为了一件众人眼里道义上正确的东西。
按照这个逻辑。如果有两个人结婚后才发现不合适,那我应该说什么,
“你俩都结婚一两年了 还差后面几十年么 将就一下 一辈子不就过去了。”
或者说,
“现在不能离婚,等到你俩快死的时候爱怎么折腾怎么折腾。”

glslViewer

 • 

需要使用比较先进的浏览器看。IE 和 RSS 阅读器估计是是没办法了。后面会用这个 js 插件来写一些关于 Noise Shader 的开发内容。
<canvas class="glslCanvas" width="250" height="250" data-fragment="

ifdef GL_ES

precision mediump float;

endif

uniform vec2 u_resolution;
uniform float u_time;

void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
st.x *= u_resolution.x/u_resolution.y;

st += vec2(.0);
vec3 color = vec3(1.);
color = vec3(st.x,st.y,abs(sin(u_time)));

gl_FragColor = vec4(color,1.0);

}" style="top: 10px; background-color: rgb(1, 1, 1);">

Just A Quick Update

 • 

用 Shader 来做 Noise 比 CPU 做快太多了。
举个例子:

CGINCLUDE

		void FAST32_hash_2D( float2 gridcell, out float4 hash_0, out float4 hash_1 )	//	generates 2 random numbers for each of the 4 cell corners
		{
			//    gridcell is assumed to be an integer coordinate
			const float2 OFFSET = float2( 26.0, 161.0 );
			const float DOMAIN = 71.0;
			const float2 SOMELARGEFLOATS = float2( 951.135664, 642.949883 );
			float4 P = float4( gridcell.xy, gridcell.xy + 1.0 );
			P = P - floor(P * ( 1.0 / DOMAIN )) * DOMAIN;
			P += OFFSET.xyxy;
			P *= P;
			P = P.xzxz * P.yyww;
			hash_0 = frac( P * ( 1.0 / SOMELARGEFLOATS.x ) );
			hash_1 = frac( P * ( 1.0 / SOMELARGEFLOATS.y ) );
		}

		float2 Interpolation_C2( float2 x ) { return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); }

		float Perlin2D( float2 P )
		{
			float2 Pi = floor(P);
			float4 Pf_Pfmin1 = P.xyxy - float4( Pi, Pi + 1.0 );
		
			float4 hash_x, hash_y;
			FAST32_hash_2D( Pi, hash_x, hash_y );
		
			float4 grad_x = hash_x - 0.49999;
			float4 grad_y = hash_y - 0.49999;
			float4 grad_results = rsqrt( grad_x * grad_x + grad_y * grad_y ) * ( grad_x * Pf_Pfmin1.xzxz + grad_y * Pf_Pfmin1.yyww );
		
			grad_results *= 1.4142135623730950488016887242097;		//	(optionally) scale things to a strict -1.0->1.0 range    *= 1.0/sqrt(0.5)
			float2 blend = Interpolation_C2( Pf_Pfmin1.xy );
			float2 res0 = lerp( grad_results.xy, grad_results.zw, blend.y );
			return lerp( res0.x, res0.y, blend.x );

		}
		float PerlinNormal(float2 p, int octaves, float2 offset, float frequency, float amplitude, float lacunarity, float persistence)
		{
			float sum = 0;
			for (int i = 0; i < octaves; i++)
			{
				float h = 0;
				h = Perlin2D((p + offset) * frequency);
				sum += h*amplitude;
				frequency *= lacunarity;
				amplitude *= persistence;
			}
			return sum;
		}

	ENDCG

这段代码,取自 briansharpe,在 Unity 上写成 Shader 后使用 RenderTexture (需要 Unity Pro) 渲染到 Texture 上就可以拿到 float[4096][2048] 的数据了,而且在 Update() 里面可以实时更改种子。而相比之下 LibNoise 的 .Net Port 需要半分钟来做到类似的事情。
这个发现让我很兴奋,因为 LibNoise 实在是太慢了,即使是 C++ 版本作者自己也说生成一个星球贴图需要二十分钟。之前尝试了各种加速生成的方法,甚至开始准备写一个 LibNoise 在 Swift 上使用 Accelerate.Framework 来通过 SIMD 加速的移植版本,但是效果都不是很理想。如果一开始就使用 Shader 来做计算的话,这个坎早就过了。