更新一些GPU相关知识

在学完并实现路径追踪之后,即使增加了多线程渲染,在SPP=1024的情况下,依然需要30+分钟才能渲染一帧。 为了更快的渲染速度 ,我试图通过使用GPU的CUDA SDK来加速渲染。然而测下来竟然还没我的CPU跑的快,一方面我没有更好的显卡,另一方面我也不太确定是不是我CUDA使用错误所致。再加上就算使用GPU也不可能达到每帧秒级渲染。于是GPU的学习就搁置了。 然而在最近研究Splat地形渲染方案时, 我无意间发现了一个现象。测试地形为4层混合,在所有Texture都不开Mipmapping的情况下, FPS……

2020

写年终总结前,照例翻了一下今年以来的blog, 意外的发现2019去年的年终总结同样拖到很晚。不过今年之所以拖这么晚,大部分原因是今年特别冷。坐到电脑前只顾着瑟瑟发抖了,哪还有心情写年终总结。 翻了一下去年的目标: 《概率论及其应用·卷1》 《具体数学》 《计算机程序设计艺术》 重新温习一下以往学习过的知识,看看能不能再次打破一下这几年形成的思维定式 总的来讲 有部分完成。 《概率论及其应用·卷1》看了一大半,该看正态分布了,不过现在应该差不多忘光了。 《具体数学》……

地形渲染之爬过的坑

目前我们采用TiledMap的菱形模式来编辑地形,然后再导入到Unity, 将TiledMap的每一个菱形以Unity中的Quad为单位来拼出来。 以目前我的知识水平来看,这么做至少有4个问题。 Quad是以正方形为单位拼接的,而我们在TiledMap中每一个菱形是以Quad为单位渲染而成,客户端在使用Quad进行渲染时,为了表现的像个菱形,每两个Quad都会在顶角进行重叠,这需要我们美术出的图四个角Alpha通道都是0,这会增加无用的Overdraw。 为了降低纹理大小,整个地形都是由有限个基础Tile相互叠加来生成……

Lua5.3 GC源码阅读(5)

这篇内容并不是上篇提到的关于弱表实现的分析。而是最近有位同学与我探讨了一些Lua的GC时,发现了两个以前从没注意过的智慧闪光点。 首先是luaC_fullgc的实现. [c] #define keepinvariant(g) ((g)->gcstate <= GCSatomic) static void entersweep (lua_State *L) { global_State *g = G(L); g->gcstate = GCSswpallgc; lua_assert(g->sweepgc == NULL); g->sweepgc = sweeplist(L, &g->allgc, 1); } void luaC_fullgc (lua_State *L, int isemergenc……

实现一个数据库存储队列

大约在在两年前, 我就意识到定点存库的必要性,并在今年应用到实际项目中了。 从历史经验来看,将数据库存储行为收集并合并起来,确实可以极大的降低抽象代码过程中的心智负担。我们在写代码时已经不需要考虑数据库的存储频率,反正最终所有修改过的数据,只会存一次。 从我意识到定点存库的必要性之后,我就一直对当时的抽象不太满意,在最原始的抽象中,刷新数据是需要业务逻辑来完成的。而数据库合并模块本质上只做了去重而已,这也就是说,其实大量定点存储代码实际是散落在业……

再学计算机图形学入门

在网上查资料时,无意间发现了一门课叫《现代计算机图形学入门》。于是事隔将近3年后,我再一次尝试图形学入门。这次学习从8月20号开始,一直到10月11日,约持续了一个半月。 但是这次的学习体验和上次是完全不同的,最直接的感受有3点。 《现代计算机图形学入门》要比《3D游戏编程大师技巧》中的内容现代的多,内容和知识体系都更全面。 现代计算机的性能远超《3D游戏编程大师技巧》著作当时,因此很多为了提高性能的Trick已经没有必要使用。这会使我们花费大量精力在局部细节……

再谈分布式服务架构

在两年前,我曾经设计过一版,高可伸缩服务器架构, 但只进行了理论推演,并没有使用具体业务逻辑验证过。以这两年的经验来看,这个架构不具备可实施性。 在之前的架构中,我只考虑了Gate和其服务之间的交互。没有考虑其他服务之间也会有基于"玩家"的交互,还可能有基于"联盟"等其他对象的交互。 按这套模型继续演化下去,为了解决"任意两服务"之间的交互问题,势必需要所有服务都有一份相同的Agent对象。这样一来,整个架构的复杂性就大大提升了。 ……

游戏上线一个月后的反思

大约在1个月前,游戏终于上线了,在这一个月以来,服务器竟然crash了5+次,还有几次严重Bug. 除了觉得测试力度不够之外,我也在想到底有那些环节是我能做而没做好的。 仔细思考下来,出Bug的原因大概有两种典型情况。 写代码时,逻辑思维不严谨,并且函数之间耦合性过强,导致随便一个很平常的改动,都会产生新的Bug, 甚至是crash. 比如我经常写出类似下面这种函数之间耦合性过强代码。 struct foo { bool isfinish; time_t rsttime; //... }; static viod try_reset(s……

一次并发Bug

最近碰到一个bug, 约7天发生一次,历时3周才找到问题并修复。 在找到bug并修复后,我仔细反思了一下。 我发现不仅这个bug是并发bug的一个典型,修复bug的过程也是直击我的弱点。 下面记录一下整个过程。 最近突然想对我的网络框架做一次RPC浸泡测试。 写了一段代码,开了6000个客户端,去并发RPC请求,服务端收到RPC之后会随机10~2500ms 延时之后再返回。 丢到我的VPS上之后,也没在意,过了两天就忘记这回事了。 过了大概一周,我突然想起来我还有一个浸泡测试在跑着呢,就上去看了……

双向链表的三种实现

这篇文章,其实很像是“茴字的四种写法”。这让人不由的想起来孔乙己。在我印象中,大多数人对孔乙己是持嘲讽态度的。 但是从技术上讲,我觉得”茴字的四种写法”在满足需求的前提下,有助于我们简化实现。 在我的历史经验中,我一共写过三种双向链表。 在最开始实现时,就是按算法导论最朴素的实现。 //算法1 struct node { struct node *prev; struct node *next; } struct node *head = NULL; void insert(struct node *n) { n->prev……