計(jì)算機(jī)圖形學(xué)(OPENGL):IBL-環(huán)境光

本文同時(shí)發(fā)布在我的個(gè)人博客上:https://dragon_boy.gitee.io

??IBL,image based lighting舞骆,即基于圖片的光照,是將周圍的環(huán)境作為一個(gè)大的發(fā)光體來進(jìn)行間接的光照,通常使用立方體貼圖技術(shù)進(jìn)行計(jì)算宝泵。
??IBL算法使用周圍的環(huán)境進(jìn)行光照厨疙,它的輸入可以被考慮為一種精度較高的環(huán)境光照洲守,或者更為自然的模擬-全局光照。使用IBL的PBR流程的物體會得到更為真實(shí)的效果。
??在講解IBL前梗醇,先給出反射方程:


??在之前說過暑始,我們主要的目的是處理包含在半球內(nèi)的所有入射光,進(jìn)行積分運(yùn)算婴削。在之前的PBR例子中廊镜,我們只考慮了有限的光源,所以可以很簡單地通過遍歷所有光源進(jìn)行積分運(yùn)算唉俗,但這次針對周圍的環(huán)境進(jìn)行光照計(jì)算嗤朴,這些可能并不方便積分的計(jì)算,這也給我們帶來了兩個(gè)計(jì)算積分的要求:

  • 我們需要某種方式來方便我們根據(jù)所給定的{\omega}_i獲得場景的輻射率虫溜。
  • 處理積分要快速且實(shí)時(shí)雹姊。
    ??現(xiàn)在第一個(gè)要求我們已經(jīng)提過了,可以使用立方體貼圖技術(shù)來完成衡楞,我們可以將立方體貼圖的每個(gè)紋素都當(dāng)成一個(gè)單獨(dú)的發(fā)光源吱雏,通過不同的{\omega}_i我們采樣這立方體貼圖,這樣就可以得到每個(gè)不同方向的場景的輻射率瘾境。
    ??根據(jù){\omega}_i獲得場景的輻射率就像這樣:
vec3 radiance = texture(_cubemapEnvironment, w_i).rgb;  

??但處理積分我們需要多個(gè)方向的采樣值歧杏,不過這也意味著每個(gè)片段都需要大量的調(diào)用這些采樣值,計(jì)算的開銷是巨大的迷守。我們可以提前進(jìn)行大量的計(jì)算來讓積分的計(jì)算更有效率一些犬绒,為此我們需要深入了解一下反射方程:


??根據(jù)積分的特性,我們可以將其分成漫反射和高光兩部分:

??這一章我們只需要關(guān)注漫反射部分兑凿。lambert模型公式和折射比率作為常量凯力,我們可以將其提出來放在外面:

??我們可以假設(shè)點(diǎn)在環(huán)境貼圖的中心,那么我們這個(gè)積分的值只取決于礼华。通過這些知識點(diǎn)咐鹤,我們可以通過卷積提前計(jì)算一個(gè)新的立方體貼圖,貼圖中存儲的是每個(gè)采樣方向的漫反射積分結(jié)果圣絮。
??卷積對數(shù)據(jù)集中的每個(gè)輸入進(jìn)行一些計(jì)算祈惶,同時(shí)也考慮到了數(shù)據(jù)集中的其它輸入,數(shù)據(jù)集可以是場景的輻射率或環(huán)境貼圖晨雳。因此行瑞,當(dāng)采樣某一方向的立方體貼圖時(shí),其它的采樣值也被考慮到計(jì)算當(dāng)中餐禁。
??為了卷積計(jì)算出一張環(huán)境貼圖血久,我們對每個(gè)輸出方向采樣方向的積分進(jìn)行處理,通過半球內(nèi)的離散地進(jìn)行大量的采樣帮非,并平均所有的輻射率氧吐,而這個(gè)半球的朝向是輸出采樣方向:

??這個(gè)提前計(jì)算出的立方體貼圖讹蘑,對每個(gè)存儲一個(gè)積分結(jié)果,可以看作是提前計(jì)算了場景的所有非直接漫反射光沿著照射到一個(gè)表面筑舅。這個(gè)立方體貼圖常被稱為反照貼圖座慰。
??比如下面的立方體貼圖和根據(jù)它計(jì)算的反照貼圖:

PBR和HDR

??由于PBR是基于物理模擬真實(shí)的效果,所以說HDR是必須要考慮在內(nèi)的翠拣。如果不考慮環(huán)境貼圖版仔,HDR的效果可以很簡單的實(shí)現(xiàn),不過使用環(huán)境貼圖的話误墓,我們需要某種方式將HDR信息保存在一張環(huán)境貼圖中蛮粮。
??我們之前都是通過立方體貼圖來實(shí)現(xiàn)環(huán)境貼圖的,但它的數(shù)據(jù)存儲范圍在[0.0,1.0]之間谜慌,即LDR然想,所以這種存儲方式的值不適合作為PBR的輸入值。

hdr文件格式

??看名字就知道這是專門存儲適合HDR范圍數(shù)據(jù)的圖片格式欣范。這種格式使用的是每通道8bit存儲顏色变泄,并且使用alpha通道作為指數(shù)。下面是一張HDR格式圖片的示意:



??可以看到恼琼,這種圖片格式的圖片和立方體貼圖不一樣妨蛹,它是由一張球形圖片投影到一個(gè)平面上形成的,這樣的話驳癌,我們就可以將環(huán)境存儲在一張單獨(dú)的名為等矩形貼圖的貼圖中滑燃。

導(dǎo)入hdr

??這里可以很簡單地使用stb_image.h導(dǎo)入,像下面這樣:

#include "stb_image.h"
[...]

stbi_set_flip_vertically_on_load(true);
int width, height, nrComponents;
float *data = stbi_loadf("newport_loft.hdr", &width, &height, &nrComponents, 0);
unsigned int hdrTexture;
if (data)
{
    glGenTextures(1, &hdrTexture);
    glBindTexture(GL_TEXTURE_2D, hdrTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, data); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    stbi_image_free(data);
}
else
{
    std::cout << "Failed to load HDR image." << std::endl;
}  

將等矩形貼圖轉(zhuǎn)化為立方體貼圖

??雖然可以直接使用等距形貼圖進(jìn)行計(jì)算颓鲜,但相比使用立方體貼圖,開銷較大典予,因此我們將等矩形貼圖轉(zhuǎn)化為立方體貼圖進(jìn)行計(jì)算甜滨。
??為了進(jìn)行轉(zhuǎn)換,我們需要渲染一個(gè)單位立方體瘤袖,接著將等矩形貼圖從立方體內(nèi)部投影到6個(gè)面上衣摩。頂點(diǎn)著色器很簡單:

#version 330 core
layout (location = 0) in vec3 aPos;

out vec3 localPos;

uniform mat4 projection;
uniform mat4 view;

void main()
{
    localPos = aPos;  
    gl_Position =  projection * view * vec4(localPos, 1.0);
}

??在片元著色器中,我們通過立方體的位置進(jìn)行插值運(yùn)算獲得片段的采樣方向捂敌,接著使用這個(gè)方向向量艾扮,在進(jìn)行一些三角變換后,用來采樣等矩形貼圖:

#version 330 core
out vec4 FragColor;
in vec3 localPos;

uniform sampler2D equirectangularMap;

const vec2 invAtan = vec2(0.1591, 0.3183);
vec2 SampleSphericalMap(vec3 v)
{
    vec2 uv = vec2(atan(v.z, v.x), asin(v.y));
    uv *= invAtan;
    uv += 0.5;
    return uv;
}

void main()
{       
    vec2 uv = SampleSphericalMap(normalize(localPos)); // make sure to normalize localPos
    vec3 color = texture(equirectangularMap, uv).rgb;
    
    FragColor = vec4(color, 1.0);
}

??接著我們需要渲染同一個(gè)立方體六次占婉,每次通過一個(gè)面的方向渲染泡嘴,我們將渲染結(jié)果存儲在一個(gè)幀緩沖中:

unsigned int captureFBO, captureRBO;
glGenFramebuffers(1, &captureFBO);
glGenRenderbuffers(1, &captureRBO);

glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
glBindRenderbuffer(GL_RENDERBUFFER, captureRBO);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 512, 512);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, captureRBO);  

??同樣,為每個(gè)面創(chuàng)建一個(gè)紋理來存儲渲染結(jié)果:

unsigned int envCubemap;
glGenTextures(1, &envCubemap);
glBindTexture(GL_TEXTURE_CUBE_MAP, envCubemap);
for (unsigned int i = 0; i < 6; ++i)
{
    // note that we store each face with 16 bit floating point values
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 
                 512, 512, 0, GL_RGB, GL_FLOAT, nullptr);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

??接著我們通過設(shè)置6個(gè)不同的視圖矩陣渲染6次立方體:

glm::mat4 captureProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f);
glm::mat4 captureViews[] = 
{
   glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 1.0f,  0.0f,  0.0f), glm::vec3(0.0f, -1.0f,  0.0f)),
   glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f,  0.0f,  0.0f), glm::vec3(0.0f, -1.0f,  0.0f)),
   glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 0.0f,  1.0f,  0.0f), glm::vec3(0.0f,  0.0f,  1.0f)),
   glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 0.0f, -1.0f,  0.0f), glm::vec3(0.0f,  0.0f, -1.0f)),
   glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 0.0f,  0.0f,  1.0f), glm::vec3(0.0f, -1.0f,  0.0f)),
   glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 0.0f,  0.0f, -1.0f), glm::vec3(0.0f, -1.0f,  0.0f))
};

// convert HDR equirectangular environment map to cubemap equivalent
equirectangularToCubemapShader.use();
equirectangularToCubemapShader.setInt("equirectangularMap", 0);
equirectangularToCubemapShader.setMat4("projection", captureProjection);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, hdrTexture);

glViewport(0, 0, 512, 512); // don't forget to configure the viewport to the capture dimensions.
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
for (unsigned int i = 0; i < 6; ++i)
{
    equirectangularToCubemapShader.setMat4("view", captureViews[i]);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
                           GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, envCubemap, 0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    renderCube(); // renders a 1x1 cube
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);  

??現(xiàn)在encCubemap中存儲的就是轉(zhuǎn)換過后的立方體貼圖逆济。我們用一個(gè)天空盒來測試一下酌予。
??頂點(diǎn)著色器如下:

#version 330 core
layout (location = 0) in vec3 aPos;

uniform mat4 projection;
uniform mat4 view;

out vec3 localPos;

void main()
{
    localPos = aPos;

    mat4 rotView = mat4(mat3(view)); // remove translation from the view matrix
    vec4 clipPos = projection * rotView * vec4(localPos, 1.0);

    gl_Position = clipPos.xyww;
}

??記得修改深度測試選項(xiàng):

glDepthFunc(GL_LEQUAL);  

??片元著色器如下(記得將HDR范圍色調(diào)映射到LDR磺箕,同時(shí)將結(jié)果進(jìn)行伽馬校正):

#version 330 core
out vec4 FragColor;

in vec3 localPos;
  
uniform samplerCube environmentMap;
  
void main()
{
    vec3 envColor = texture(environmentMap, localPos).rgb;
    
    envColor = envColor / (envColor + vec3(1.0));
    envColor = pow(envColor, vec3(1.0/2.2)); 
  
    FragColor = vec4(envColor, 1.0);
}

??渲染結(jié)果如下:



??這里我們只是測試了環(huán)境貼圖,接下來將其用來進(jìn)行光照計(jì)算

立方體貼圖卷積

??就像上面介紹過的抛虫,我們需要將環(huán)境貼圖中心半球\Omega內(nèi)的所有{\omega}_i的輻射率卷積運(yùn)算到朝向松靡,即法線N


??接下來我們嘗試通過上面轉(zhuǎn)化好的立方體貼圖生成反照貼圖建椰。片元著色器:

#version 330 core
out vec4 FragColor;
in vec3 localPos;

uniform samplerCube environmentMap;

const float PI = 3.14159265359;

void main()
{       
    // 采樣方向等于半球的朝向
    vec3 normal = normalize(localPos);
  
    vec3 irradiance = vec3(0.0);
  
    [...] // 卷積運(yùn)算
  
    FragColor = vec4(irradiance, 1.0);

??目前存在許多方式進(jìn)行對環(huán)境貼圖進(jìn)行卷積運(yùn)算雕欺,這里我們將根據(jù)半球朝向生成一定數(shù)量的采樣方向向量,最后將結(jié)果平均棉姐。
??反射方程的積分運(yùn)算的立體角d\omega并不方便計(jì)算阅茶,這里我們使用替代的球形坐標(biāo)\theta\phi


??我們使用極坐標(biāo)方位角繞著半球豎直圓環(huán)(到)進(jìn)行采樣谅海,使用傾角繞著水平圓環(huán)采樣(到)脸哀,這樣,積分式可以改為:

??我們通過黎曼和將上述積分改為有限的連續(xù)和:

??我們離散的采樣球形值扭吁,由于球的特性撞蜂,傾角越大,采樣范圍越小侥袜,為了補(bǔ)償這一變化蝌诡,我們可以通過縮放區(qū)域。
??上述積分操作用代碼表示如下:

vec3 irradiance = vec3(0.0);  

vec3 up    = vec3(0.0, 1.0, 0.0);
vec3 right = cross(up, normal);
up         = cross(normal, right);

float sampleDelta = 0.025;
float nrSamples = 0.0; 
for(float phi = 0.0; phi < 2.0 * PI; phi += sampleDelta)
{
    for(float theta = 0.0; theta < 0.5 * PI; theta += sampleDelta)
    {
        // 將球形坐標(biāo)轉(zhuǎn)為笛卡爾坐標(biāo)(切線空間)
        vec3 tangentSample = vec3(sin(theta) * cos(phi),  sin(theta) * sin(phi), cos(theta));
        // 切線空間轉(zhuǎn)換到世界空間
        vec3 sampleVec = tangentSample.x * right + tangentSample.y * up + tangentSample.z * N; 

        irradiance += texture(environmentMap, sampleVec).rgb * cos(theta) * sin(theta);
        nrSamples++;
    }
}
irradiance = PI * irradiance * (1.0 / float(nrSamples));

??操作沒啥好說的枫吧,下面創(chuàng)建一個(gè)立方體貼圖來進(jìn)行紋理映射:

unsigned int irradianceMap;
glGenTextures(1, &irradianceMap);
glBindTexture(GL_TEXTURE_CUBE_MAP, irradianceMap);
for (unsigned int i = 0; i < 6; ++i)
{
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 32, 32, 0, 
                 GL_RGB, GL_FLOAT, nullptr);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

??注意浦旱,由于反照貼圖中存儲的都是平均過的結(jié)果,所以沒有很豐富的細(xì)節(jié)九杂,使用32*32分辨率足夠了颁湖。接著,我們修改幀緩沖的分辨率:

glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
glBindRenderbuffer(GL_RENDERBUFFER, captureRBO);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 32, 32);  

??最后例隆,設(shè)置渲染代碼:

irradianceShader.use();
irradianceShader.setInt("environmentMap", 0);
irradianceShader.setMat4("projection", captureProjection);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, envCubemap);

glViewport(0, 0, 32, 32); // don't forget to configure the viewport to the capture dimensions.
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
for (unsigned int i = 0; i < 6; ++i)
{
    irradianceShader.setMat4("view", captureViews[i]);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
                           GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, irradianceMap, 0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    renderCube();
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);  

??結(jié)果如下:



??渲染結(jié)果像是模糊版的環(huán)境貼圖甥捺。

PBR和非直接輻照光照

??我們接下來使用渲染好的反照貼圖進(jìn)行非直接的環(huán)境光計(jì)算。

uniform samplerCube irradianceMap;

??由于從反照貼圖采樣的顏色同時(shí)包含漫反射和高光部分镀层,我們需要用菲涅爾等式計(jì)算的比率將其分離開:

vec3 kS = fresnelSchlick(max(dot(N, V), 0.0), F0);
vec3 kD = 1.0 - kS;
vec3 irradiance = texture(irradianceMap, N).rgb;
vec3 diffuse    = irradiance * albedo;
vec3 ambient    = (kD * diffuse) * ao; 

??由于環(huán)境光方向來自于朝向法線半球內(nèi)的所有方向镰禾,所以說沒有一個(gè)特定的中間向量來決定菲涅爾等式的結(jié)果,所以我們將法線和觀察方向點(diǎn)乘來模擬菲涅爾的效果唱逢。但之前的微表面模型構(gòu)建中吴侦,我們使用了微表面的中間向量,通過表面的粗糙度影響坞古,并將其作為輸入用在菲涅爾的計(jì)算中备韧,但這次我們不考慮粗糙度,也就意味著绸贡,表面的反射率肯定是偏高的盯蝴,不過我們所期望的是反射部分相對低一些毅哗,非直接光照的菲涅爾效果應(yīng)該是這樣的,在粗糙度較高的非金屬表面甚至?xí)ジ吖猓?/p>


??我們可以將粗糙度加入菲涅爾的運(yùn)算來改善這一問題:

vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
{
    return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cosTheta, 5.0);
}   

??最后計(jì)算環(huán)境光代碼為:

vec3 kS = fresnelSchlickRoughness(max(dot(N, V), 0.0), F0, roughness); 
vec3 kD = 1.0 - kS;
vec3 irradiance = texture(irradianceMap, N).rgb;
vec3 diffuse    = irradiance * albedo;
vec3 ambient    = (kD * diffuse) * ao; 

??渲染結(jié)果應(yīng)該如下:


??很明顯缺少高光部分捧挺,這個(gè)我們在下一章節(jié)講解虑绵。
??最后,貼出原文地址供參考:https://learnopengl.com/PBR/IBL/Diffuse-irradiance

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末闽烙,一起剝皮案震驚了整個(gè)濱河市翅睛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌黑竞,老刑警劉巖捕发,帶你破解...
    沈念sama閱讀 212,222評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異很魂,居然都是意外死亡扎酷,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,455評論 3 385
  • 文/潘曉璐 我一進(jìn)店門遏匆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來法挨,“玉大人,你說我怎么就攤上這事幅聘》材桑” “怎么了?”我有些...
    開封第一講書人閱讀 157,720評論 0 348
  • 文/不壞的土叔 我叫張陵帝蒿,是天一觀的道長荐糜。 經(jīng)常有香客問我,道長葛超,這世上最難降的妖魔是什么暴氏? 我笑而不...
    開封第一講書人閱讀 56,568評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮巩掺,結(jié)果婚禮上偏序,老公的妹妹穿的比我還像新娘。我一直安慰自己胖替,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,696評論 6 386
  • 文/花漫 我一把揭開白布豫缨。 她就那樣靜靜地躺著独令,像睡著了一般。 火紅的嫁衣襯著肌膚如雪好芭。 梳的紋絲不亂的頭發(fā)上燃箭,一...
    開封第一講書人閱讀 49,879評論 1 290
  • 那天,我揣著相機(jī)與錄音舍败,去河邊找鬼招狸。 笑死敬拓,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的裙戏。 我是一名探鬼主播乘凸,決...
    沈念sama閱讀 39,028評論 3 409
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼累榜!你這毒婦竟也來了营勤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,773評論 0 268
  • 序言:老撾萬榮一對情侶失蹤壹罚,失蹤者是張志新(化名)和其女友劉穎葛作,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體猖凛,經(jīng)...
    沈念sama閱讀 44,220評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赂蠢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,550評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了辨泳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片虱岂。...
    茶點(diǎn)故事閱讀 38,697評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖漠吻,靈堂內(nèi)的尸體忽然破棺而出量瓜,到底是詐尸還是另有隱情,我是刑警寧澤途乃,帶...
    沈念sama閱讀 34,360評論 4 332
  • 正文 年R本政府宣布绍傲,位于F島的核電站,受9級特大地震影響耍共,放射性物質(zhì)發(fā)生泄漏烫饼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,002評論 3 315
  • 文/蒙蒙 一试读、第九天 我趴在偏房一處隱蔽的房頂上張望杠纵。 院中可真熱鬧,春花似錦钩骇、人聲如沸比藻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,782評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽银亲。三九已至,卻和暖如春纽匙,著一層夾襖步出監(jiān)牢的瞬間务蝠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,010評論 1 266
  • 我被黑心中介騙來泰國打工烛缔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留馏段,地道東北人轩拨。 一個(gè)月前我還...
    沈念sama閱讀 46,433評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像院喜,于是被迫代替她去往敵國和親亡蓉。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,587評論 2 350