【Siggraph 2018】the challenges of rendering an open world in far cry 5

今天学习的时Far Cry 5的大世界渲染方案,包含如下几个专题:

  1. 水体
  2. 物理真实的TOD
  3. 局部tonemapping效果
  4. 美术生产
幻灯片1.png
幻灯片3.png

Far Cry 5的基本信息,基于延迟渲染实现,引擎是沿用此前版本的引擎,并根据需要做了优化

幻灯片4.png

图形程序团队分散在各个地方

幻灯片5.png

视觉提升主要包含如下几个大的方面:

  1. 地形部分,在Moore GDC 2018的分享中有详细介绍
  2. 水体部分,在Grujic GDC 2018的分享中有详细介绍
  3. 全局光照
  4. 基于物理的光照
幻灯片6.png

然而本文重点关注的不是一个个的特性,而是在实现开放世界游戏渲染中的一些挑战,尤其侧重的是,如何保障方案在各种情况下的适用。

幻灯片7.png

主要包含上述四个部分

幻灯片8.png

先来看看水体

幻灯片9.png

水体有啥问题呢?

幻灯片10.png

一般来说,我们渲染的顺序是如上图所示的,先不透+延迟光照,之后半透通过前向渲染完成,最后叠加后处理

幻灯片11.png

那么这里水体是否是需要作为半透来完成渲染?

幻灯片12.png

按照这种做法,会导致几个问题:

  1. 半透物件跟水体存在穿插时,不管谁前谁后效果都不对
  2. 折射效果(需要拿到水体的深度,这里说的是水深的深,而不是depthmap那个深度,这个深度可以通过两个depth相减后运算得到)以及水下的光照计算效果也会有问题(?)
幻灯片13.png

这个是目标效果

幻灯片14.png

一个常见的思路是在半透之前绘制水体,同时水体绘制的时候会写深度,从而拿到水深之后用于实现水体的折射效果。

不过这样一来,水下的半透物体效果就可能有问题了?

幻灯片15.png

另一个问题是,水体表面不一定是平面(有可能有河流带来的斜坡),那么传统的平面反射(PR或者PPR)方案就不能用,这里考虑使用SSR来计算,而SSR需要采样深度图,并从Framebuffer中获取颜色。

之前的SSR是在延迟光照环节计算的,那水体自然就享受不到这个作用的效果了。

幻灯片16.png

这里的方案是在延迟光照前,先加个water pre pass(只绘制深度),之后流程跟前面一样,从而可以将SSR作用到水体之上。

幻灯片17.png

带来的新问题是,我们现在有了两张深度图,一张有水体,一张没有;其中部分效果需要使用前者(阴影、SSAO、光照等),部分效果则需要使用后者(SSR)

幻灯片18.png

这里对具体的效果以及对应的输入深度图做了总结,简单来说,就是SSR需要带水体的深度,其他不用。

这里特意提到说,水体的阴影、光照以及大气散射等部分,是希望在水体绘制的前向管线中完成计算的,虽然这种做法会带来更高的性能开销(为啥要这么做呢?)

幻灯片19.png

说到深度贴图,跟其他项目一样,深度贴图并不是一张贴图,而是一套贴图,各个特性需要的分辨率、线性与否等可能都不一样,这里设计了一个专门的pass来完成这些数据的生成。

幻灯片20.png

这个pass作用如上图,一般是在GBuffer生成完成之后,通过异步compute shader来完成计算。

幻灯片21.png
幻灯片22.png
幻灯片23.png

这里展示了可能用到的各种深度数据,其中线性深度贴图mipmap还针对需要做了拆分处理,因为绝大多数情况下,可能是只需要一张全分辨率贴图,不需要后面的mipmap的,所以拆分开来有助于节省带宽消耗。

幻灯片24.png
幻灯片25.png

给出了各个效果与上述各种深度贴图的连接关系。

幻灯片26.png

给出这个pass的一些执行细节

幻灯片27.png

执行两次会有两次消耗,最终通过分析认为,可以只对带水体的深度执行一次计算,这种选择的好处是:

  1. 可以保留水体的SSAO、SSS效果
  2. 可以在水体上通过延迟光照逻辑,实现水体上的阴影、大气散射效果以及雾效

带来的问题在于:

  1. 延迟阴影发生在水面上,水下部分阴影缺失?
  2. 光照的剔除逻辑可能会把水下的光源剔除掉,导致效果异常

不过貌似没有测试同学反馈bug,所以看起来还好。。。。

幻灯片28.png

前面担忧的水下半透物件绘制异常的问题这里也考虑到了

幻灯片29.png

这里的做法是将这些物件分成两部分,水上的跟水下的(是否还有穿插的部分):

  1. 水下的在水体绘制之前绘制(需要将水体设置为近裁平面剔除掉水上部分)
  2. 水上的在水体之后绘制(需要将水体设置为远裁平面,剔除掉水下部分)
  3. 穿插的应该需要绘制两次
幻灯片30.png

伪代码给出如上

幻灯片31.png

水上部分,直接用深度剔除就行,不用额外的剔除逻辑

水下部分则需要将水体设置为剔除平面,在vs中进行剔除

幻灯片32.png

常用的做法是借用SV_ClipDistance的语法,但是实测发现这个是有较大副作用的,所以用了vs剔除的逻辑

幻灯片33.png

前面是假设相机在水上的,那如果相机处于水下呢,上面的方案还能否生效?

幻灯片34.png
幻灯片35.png

那前面的方案在很多特性上表现就是不正常的,这里的解题思路是:

  1. 使用不带水体的深度来实现延迟效果的计算
  2. 使用水体表面作为近裁、远裁平面来实现水下、水上物件的绘制剔除逻辑
  3. 屏蔽掉SSR效果
幻灯片36.png

做一个总结:

  1. 水体跟各种效果具有非常密切的关联,不能作为一个独立的问题来看待
  2. 实现的时候不要只考虑方案本身的实现时间,还得预留充足的问题解决与处理事件
  3. 很多问题并没有完美答案
幻灯片37.png

后续的一些优化思路:

  1. 将水体clip plane的裁剪逻辑优化掉,改成逐像素的深度比对检测,从而适配倾斜水体的效果
  2. 考虑将部分剔除逻辑从CPU搬迁到GPU
  3. 对深度贴图处理pass做进一步优化,按需输出深度贴图
幻灯片38.png

接下来看看基于物理的TOD的实现

幻灯片39.png
  1. 太阳跟月亮的位置(以及月相)可以根据相机当前所在的经纬度来计算得到
幻灯片40.png
  1. 之后从前人的数据中拿到太阳跟月亮的光谱数据
  2. 月亮的光照会基于跟太阳的位置来得到,月相则自动基于月亮的brdf得到(?)
  3. 太阳跟月亮的数据会被用在Bruneton的天空模型来计算大气散射
幻灯片41.png
  1. 为了实现TOD效果,这里给太阳月亮k了11个关键帧(不是连续的?)
  2. 局部光跟天光遮蔽则只有一个关键帧(不考虑开关?)
幻灯片42.png

这里带来的三个问题:

  1. 每天的表现都不一样(什么原因导致?)
  2. 夜晚看起来跟白天一样
  3. 基于物理的光照会导致对比度过高
幻灯片43.png

先来看第一个问题

幻灯片44.png

因为采用的是模拟真实天体的运转方式(真实物理模型也不一定好啊),所以随着时间的推移,太阳跟月亮之间的相对关系在每一天都是不同的

月亮的相位也会导致月亮光强的变化,此外,有的时候晚上是没有月亮的,光照效果可能就无法接受。

幻灯片45.png

上述这些不一致就会导致前面说的太阳、月亮关键帧的结果跟预期效果不匹配,因为按照关键帧的逻辑,其中暗含的意思就是,每一天都是一样的,不然烘焙的数据表现就会失控

幻灯片46.png

为了规避这个问题,部分效果采用了太阳的高度作为输入来保障效果

幻灯片47.png

同样的,bake的GI数据只有正好匹配bake时的太阳、月亮让位置,才会有正确的表现

幻灯片48.png

另外,这里还有一些新的问题:

  1. 美术同学希望任何时候都只有一个方向光(太阳、月亮二选一)
  2. 在时刻变化的情景下,光照效果就不可控
  3. 尤其是夜景
幻灯片49.png

解决方案就是挑选某一天,之后基于这一天来循环,放弃了真实物理模拟方案

幻灯片50.png

没太看懂这里的blend说的是啥意思

幻灯片51.png

不过月亮有月相变化,这个要怎么处理:

  1. 计算的时候按照满月来
  2. 不过视觉上需要做处理(样子货)
  3. 需要根据月相调整月光方向,避免穿帮
幻灯片52.png

再来看第二个问题

幻灯片53.png
幻灯片54.png

白天跟晚上效果一样(自适应曝光)

幻灯片55.png

为了避免晚上太亮,需要对低照明度的区域做曝光降低处理

幻灯片56.png

如图所示,加了一条曲线来实现这个控制

幻灯片57.png

结果看着就好多了

幻灯片58.png

Purkinje效应:长话短说,就是人眼在白天对低频光(长波,红色等)敏感,晚上对高频光(短波,蓝色等)敏感

幻灯片59.png

要想实现这个效果,这里给了三种方案

从性能与效果来看,最合适的方式是给月光做蓝色染色,唯一的问题,中间视觉(mesopic vision)的玩家可能就没法被兼顾了

幻灯片60.png

实现效果如上图所示

幻灯片61.png
幻灯片62.png

给出对比图

幻灯片63.png

最后一个问题

幻灯片64.png
幻灯片65.png
幻灯片66.png
幻灯片67.png
幻灯片68.png

这里给了几个例子

幻灯片69.png

不同区域的光强量化数值如上图所示

幻灯片70.png

一个想法是对日光的亮度做降低处理

幻灯片71.png

比如统一下降4个单位

幻灯片72.png

效果看起来还行

幻灯片73.png

那如果调整局部光,是否也能降低对比度

幻灯片74.png

出于对实际情况的模拟,白天一般是会关掉局部光的

幻灯片75.png

且按照物理光照来看,局部光的效果也不明显

幻灯片76.png

这里给了光源布点位置与亮度的效果对比图,左边放灯具之下,后者放在灯具里,左边是50流明,右边是500.

幻灯片77.png

如果把GI去掉,效果更糟

幻灯片78.png
幻灯片79.png

先看看晚上光源的对比度问题

幻灯片80.png

不同情景下的光强数据

幻灯片81.png

前面两种光强相差4阶(即比值为2^4=16)

幻灯片82.png

如果一个场景只受月光影响,那么其(什么东西的)直方图大概是上面这个样子,我们来看看四阶的对比度是否够用

幻灯片83.png

这里先来说明一下这张图的设定

幻灯片84.png

tonemapping曲线可以用橙色区域表示

幻灯片85.png

假设每一个材料都是100%的diffuse reflector,那么我们可以用红色表示diffuse luminance(diffuse lighting * diffuse albedo)对应的直方图(场景里不同光强区域的占比?)

幻灯片86.png

灰色部分则是最终的场景luminance(叠加了diffuse、specular、emissive等)

幻灯片87.png

红色三角箭头代表自动曝光的计算逻辑(?),看了下,只有轻微区别

幻灯片88.png

蓝色则是目标的曝光度,绿色则是当前的曝光度。

由于是静态的图片,所以这里两者是相同的,在动态的场景下,两者是有区别的,运行时会动态调整曝光值,使之逼近目标曝光

幻灯片89.png

晚上的时候,会降低曝光度,以使场景变暗,通过这种方式来压缩月光跟天光的对比度,如红色箭头指示,只保留尾部的,右边更高数值就clip到最高值。

幻灯片90.png

白天的对比度不变,但是调整曝光度,加大光照范围。

幻灯片91.png
幻灯片92.png
幻灯片93.png

但是发现,情况变得更糟了。。。(?)

幻灯片94.png

这里给出了参考的范围,最多只有13个stop,而夜景的范围是超出这个的,因此有些细节就会丢失。

幻灯片95.png

转到HDR,22个stops就够用了

幻灯片96.png

加大(显示屏?)亮度,还能实现更大范围

幻灯片97.png
幻灯片98.png

另外一个问题是,光照的范围应该怎么设置(半径),100米的局部光(500流明)其强度跟月光接近

幻灯片99.png

1km外的强度则跟天光接近

幻灯片100.png
幻灯片101.png

这个场景中,如果在相机背后放置一个5000流明的灯光,还是能看得出来明显的照明效果的(?)

幻灯片102.png

基于上述分析,我们有如下的结论:

  1. 采用物理灯光强度的设置,夜景下不能完全支持上这些光源的对比度
  2. 如果约束光源的半径,只会导致需要的对比度范围被进一步扩大(?)
  3. 夜景下常用的方案是调暗光源的强度,但这种做法又会引起其他的问题
幻灯片103.png

上述问题的解决方案,虽然写的详细,但还是有些不明所以:

  1. 参考电影业的做法,通过lighting rigs来模拟月光(具体?)
  2. far cry5的做法是增强月光的亮度(调高下限?),同时叠加蓝色以掩盖光强过亮的问题(需要注意,晨昏效果可能会过曝)
幻灯片104.png
幻灯片105.png

可以看到,月光曝光度调高之后,跟局部光源就比较匹配了,同时叠加了蓝色之后看起来更真实了。

幻灯片106.png

晚上的曝光度范围是-11到1

幻灯片107.png

白天则是7~20

幻灯片108.png

在上述设定下,如果放一个自发光(2~6EV)物体到场景里,就会在白天全黑,白天全白,这种情况下,粒子效果(自发光)就很难看了。

幻灯片109.png

出现这种情况的原因是自发光物体的处理逻辑跟光源的处理逻辑不相同,光源会照亮环境,会改变直方图,从而使得自身的效果能够在一系列的计算之后能够兼顾白天、晚上的表现,而自发光则没有这个特点,而我们又不太可能将所有的粒子都转成光源。

幻灯片110.png

解决方案是为自发光物件增加一条额外的bias曲线,在不同的环境(白天、黑夜)下通过添加bias来保证效果。

幻灯片111.png

伪代码给出如上

幻灯片112.png

总结:物理光照从思路到落地还有很多实现层面的坑点,需要通过各种trick来攻克

幻灯片113.png

接下来看看局部tonemapping

幻灯片114.png

经过前面的一系列处理之后,室内外的光照对比度还依然过强

幻灯片115.png

针对这个问题,研发团队不希望通过hack光照强度比例的方式来解决,因为这个会破坏物理光照的正确性。

这里的一个解决思路是采用局部tonemapping方案,简单来说,就是将传统的应用于全屏幕的tonemapping改成局部生效,不同区域采用不同的tonemapping曲线,这里需要解决的几个问题:

  1. 如何分区
  2. 每个区域的tonemapping该如何设计
  3. 如何保障画面效果看起来是和谐的,区域边界是平滑的

这个话题bart wronski写过两篇blog来介绍其具体方式。

幻灯片116.png

先基于Bart Wronski的阴影高光方案,在后处理中完成这个过程

幻灯片117.png

我们可以计算出全局的曝光度跟局部的曝光度(先抛开分区的策略不谈)

幻灯片118.png

大致实现思路,下面是理想情况:

  1. 在全分辨率的buffer中计算场景的log luminance(怎么计算?)
  2. 对这个buffer采用一个大尺寸的双边模糊算子来得到一个模糊(基于颜色,而非深度,说的是啥意思?)
  3. 基于上一步的结果来得到局部曝光度(具体怎么做?)
幻灯片119.png

但实际上消耗太高,需要调整一下:

  1. 第一步计算log luminance的时候改为低分辨率buffer中进行
  2. 因为第一步采用了低分辨率,所以第二步同样也就不用在全分辨率下进行了
幻灯片120.png

示例场景

幻灯片121.png

得到其luminance

幻灯片122.png

得到低分辨率版本的luminance的log结果

幻灯片123.png

做低分辨率的模糊

幻灯片124.png

将原图与模糊后的明度图做减法(?),就得到了高光部分减弱的版本

幻灯片125.png

但是这种做法,由于减去的部分是模糊过的,因此会在一些区域留下halo效果,导致部分本应该是明亮的区域结果没有明亮,本应该是暗淡的区域没有暗淡。

幻灯片126.png
幻灯片127.png

这里做了对比,上述红圈标注的区域都变暗了, 美术同学认为这个是不能接受的。

幻灯片128.png

这里对这个方案做一个总结:

  1. 实施快速,非侵入式
  2. 会有halo瑕疵
幻灯片129.png

这里直接针对问题着手进行解决:问题出现的原因为室内过暗、室外过亮。

一个思路是将两者区别出来,将算法只应用于室外部分。

幻灯片130.png

通过two-side特性来判断是否是室内建筑,下面看看这个方案的实现效果

幻灯片131.png

无曝光处理的效果

幻灯片132.png

对portal添加曝光处理的效果

幻灯片133.png

用红色标注portal范围

幻灯片134.png

这里有一些区域处理起来会有问题

幻灯片135.png

根据到相机的区域添加一个fade效果,看起来会更好一点(?)

幻灯片136.png

做一个总结:

  1. 即使做了相机距离的fade,还是有些情况处理起来不能令人满意
  2. 会增加美术同学摆放portal的工作量
  3. 会跟其他blend物件产生排序问题
  4. 计算复杂度高
幻灯片137.png

一个新的思路是借鉴刺客信条Origin的方案

幻灯片138.png

前面之所以要做一个双边模糊,主要是为了实现对屏幕空间像素的区分,找出那些在3D空间比较接近的区域,并将之在2D屏幕空间区分开,之后基于3D空间的距离来得到平均的亮度。

如果我们本身就能拿到3D空间的平均亮度,那这个过程就不需要了。

幻灯片139.png

而这个信息在Far Cry5的GI系统中是可以拿到的,GI中存储了:

  1. 局部光源跟太阳光的间接光照
  2. 天光遮蔽信息
幻灯片140.png

算法修正为:

  1. 基于当前场景的曝光度,计算得到一个参考的middle grey
  2. 基于天光跟间接光,计算得到当前像素的平均luminance(一个kernel覆盖范围内的平均值),这里需要忽略直接光(因为要的是平均值)
  3. 基于上述两个数值的比对来对光照结果进行调整
幻灯片141.png

看下实现伪代码,下面看下实现效果

幻灯片142.png
幻灯片143.png
幻灯片144.png

计算GI的平均luminance(移除直接光)

幻灯片145.png

基于上述数值,得到tonemapping的factor,这里可以看到,室外的factor是低于室内的

幻灯片146.png
幻灯片147.png

看起来似乎没有太大区别,但实际上也并不需要有多大区别,只是解决了前面的几个问题:

  1. 室内跟室外有了一个较好的对比度
  2. gameplay & 美术同学的问题都得到了解决
幻灯片148.png

总结

幻灯片149.png

还有一些问题希望在后续的工作中被覆盖。

幻灯片150.png
幻灯片151.png

最后看下美术生产管线。

幻灯片152.png

背景:

  1. 资源生产量大
  2. 美术同学期望提供较多种类的资产,避免重复感
  3. FPV对贴图精度要求高:6 texels/cm
  4. 贴图还需要做重用
  5. 为了得到较好的效果,材质之间还需要支持混合
幻灯片153.png

下面用两种材质(white wood跟bare wood)举例来介绍材质混合

幻灯片154.png

公式给出如上,实际上是各种类型的贴图的混合,不过mask要怎么得到呢?

幻灯片156.png

对于左边的建筑,期望用右边的一张贴图来作为mask,贴图的好处是美术同学控制起来比较方便,就是分辨率不能太高(内存、带宽?),导致精度有限。

幻灯片157.png

这里的解决方案,是叠加一层可以tiling的detail mask

幻灯片158.png

两层mask带来的问题是,如何实现两者的组合

幻灯片159.png

首先想到的是直接相乘

幻灯片160.png

按照相乘来看,如果unique mask是0,得到的结果就是材质1,而如果unique mask为1,得到的就是lerp公式,那么要想得到材质2,unique mask得等于多少呢?

幻灯片161.png

针对上面的问题,如上图所示:假设以顶点色为unique mask,detail贴图为detail mask,按照乘法逻辑,我们永远没有办法只通过控制unique mask来得到100%的贴图1的效果。

幻灯片162.png

我们期望的结果是这样,当unique mask为0的时候,得到材质1,为1的时候得到材质2,为0.5的时候,才是lerp。

幻灯片163.png

再把sharpness参数放进来

幻灯片164.png

通过sharpness来控制detail mask的最大幅度

幻灯片165.png

unique mask将可以用于实现detail mask的滑动控制

幻灯片166.png
幻灯片167.png

根据unique mask的数值是0,还是1,detail mask的符号会有所不同

幻灯片168.png

当unique mask处于0,1之间时,detail mask则落在上述范围里

幻灯片169.png

所以我们最终期望的公式形式应该是这样的

幻灯片170.png

根据梯度、偏移来对上述公式进行代入求解

幻灯片171.png

得到这两个参数的表达式

幻灯片172.png

代入得到最后的公式

幻灯片173.png

注意上述代码中的mask offset参数,通过这个参数可以调整unique mask的bias,从而用于:

  1. 固定开启或关闭某个材质
  2. 用于实现材质的动画混合效果,比如用于实现潮湿效果
幻灯片174.png
幻灯片175.png
幻灯片176.png

按照上面公式得到的最终mask结果

幻灯片177.png

集合混合结果

幻灯片178.png

以及最终混合结果,看着还是挺厉害的

幻灯片179.png

材质混合做一个总结:

  1. 可以实现多种丰富且独特效果的材质
  2. 可以支持高精度的材质表现
  3. mask方案的内存消耗相比于其他方案在内存、带宽上消耗更低
  4. 代价是需要额外的几次贴图采样(PC上影响不大,移动端会有点危险)
幻灯片180.png

还会增加ALU消耗,以贴图旋转为例

幻灯片181.png

需要成本高昂的sincos指令,一个想法是能否将这个指令提前预计算,运行时直接取用?

幻灯片182.png

每个材质类型,都会有一个与之匹配的描述文件,记录了:

  1. 材质的shader
  2. 材质的参数
  3. 用户界面的一些数据
幻灯片183.png

而在这个文件里,我们可以将一些数值提前预计算好,作为shader参数传入以降低运行时的shader计算消耗

幻灯片184.png

这里是处理流程

幻灯片185.png

角度参数预计算变成shader参数

幻灯片186.png
幻灯片187.png

这里还有几个更为复杂的案例

幻灯片188.png
幻灯片189.png

这些都可以通过描述文件来做设置(只看到了部分数值提前预计算的优点,似乎可以将这个能力集成到UE的蓝图中,允许美术同学将部分计算转换成shader参数来避免运行时的高频运算)

幻灯片190.png
幻灯片191.png
幻灯片192.png

开放世界研发的一些感受:

  1. 研发困难多
  2. 很多效果是彼此连接的,不能独立看待,一个特性的改动需要考虑对其他模块的影响
  3. 会出现很多预想不到的问题,方案与落地之间,存在巨大的鸿沟
  4. 在方案选型的时候,更倾向于选择那些普适程度高的,相对简洁的,维护与适配成本会低很多
  5. 还有很多问题可能没有一个非常好的解决方案,经常需要通过一些trick手段来解决
幻灯片193.png
幻灯片194.png
幻灯片195.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容