高級OpenGL-06.立方體貼圖(Cubemaps)

立方體貼圖(Cubemap)

我們之前一直使用的是2D紋理氧腰,還有更多的紋理類型我們沒有探索過付材,本教程中我們討論的紋理類型是將多個紋理組合起來映射到一個單一紋理樊零,它就是cubemap我磁。

基本上說cubemap它包含6個2D紋理,這每個2D紋理是一個立方體(cube)的一個面驻襟,也就是說它是一個有貼圖的立方體夺艰。為什么費事地把6個獨立紋理結合為一個單獨的紋理,只使用6個各自獨立的不行嗎沉衣?這是因為cubemap有自己特有的屬性郁副,可以使用方向向量對它們索引和采樣。想象一下豌习,我們有一個1×1×1的單位立方體存谎,有個以原點為起點的方向向量在它的中心。

從cubemap上使用橘黃色向量采樣一個紋理值看起來和下圖有點像:

方向向量的大小無關緊要肥隆。一旦提供了方向既荚,OpenGL就會獲取方向向量觸碰到立方體表面上的相應的紋理像素(texel),這樣就返回了正確的紋理采樣值栋艳。

方向向量觸碰到立方體表面的一點也就是cubemap的紋理位置恰聘,這意味著只要立方體的中心位于原點上(此時位置向量和方向向量相同),我們就可以使用立方體的位置向量來對cubemap進行采樣。然后我們就可以獲取所有頂點的紋理坐標憨琳,就和立方體上的頂點位置一樣。所獲得的結果是一個紋理坐標旬昭,通過這個紋理坐標就能獲取到cubemap上正確的紋理篙螟。

創(chuàng)建一個Cubemap

Cubemap和其他紋理一樣,所以要創(chuàng)建一個cubemap问拘,在進行任何紋理操作之前遍略,需要生成一個紋理,激活相應紋理單元然后綁定到合適的紋理目標上骤坐。這次要綁定到 GL_TEXTURE_CUBE_MAP紋理類型:

GLuint textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);

由于立方體貼圖包含6個紋理绪杏,立方體的每個面一個紋理,我們必須調用glTexImage2D函數6次纽绍,函數的參數和前面教程講的相似蕾久。然而這次我們必須把紋理目標(target)參數設置為立方體貼圖特定的面,這是告訴OpenGL我們創(chuàng)建的紋理是對應立方體哪個面的拌夏。因此我們便需要為立方體貼圖的每個面調用一次 glTexImage2D僧著。

由于立方體貼圖有6個面,OpenGL就提供了6個不同的紋理目標障簿,來應對立方體貼圖的各個面盹愚。

紋理目標(Texture target) 方位
GL_TEXTURE_CUBE_MAP_POSITIVE_X
GL_TEXTURE_CUBE_MAP_NEGATIVE_X
GL_TEXTURE_CUBE_MAP_POSITIVE_Y
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
GL_TEXTURE_CUBE_MAP_POSITIVE_Z
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z

和很多OpenGL其他枚舉一樣,對應的int值都是連續(xù)增加的站故,所以我們有一個紋理位置的數組或vector皆怕,就能以GL_TEXTURE_CUBE_MAP_POSITIVE_X為起始來對它們進行遍歷,每次迭代枚舉值加 1西篓,這樣循環(huán)所有的紋理目標效率較高:

int width, height;
unsigned char* image;

glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);
for(GLuint i = 0; i < faces.size(); i++)
{
    image = SOIL_load_image(faces[i], &width, &height, 0, SOIL_LOAD_RGB);
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
    SOIL_free_image_data(image);
}

這兒我們有個vector叫textures_faces愈腾,它包含立方體貼圖所需各個紋理的文件路徑,并且以上表所列的順序排列岂津。它將為每個當前綁定的cubemap的每個面生成一個紋理顶滩。

由于立方體貼圖和其他紋理沒什么不同,我們也要定義它的環(huán)繞方式和過濾方式:

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
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);

別被 GL_TEXTURE_WRAP_R嚇到寸爆,它只是簡單的設置了紋理的R坐標礁鲁,R坐標對應于紋理的第三個維度(就像位置的z一樣)。我們把放置方式設置為 GL_CLAMP_TO_EDGE 赁豆,由于紋理坐標在兩個面之間仅醇,所以可能并不能觸及哪個面(由于硬件限制),因此使用 GL_CLAMP_TO_EDGE后OpenGL會返回它們的邊界的值魔种,盡管我們可能在兩個兩個面中間進行的采樣析二。

在繪制物體之前,將使用立方體貼圖,而在渲染前我們要激活相應的紋理單元并綁定到立方體貼圖上叶摄,這和普通的2D紋理沒什么區(qū)別属韧。
在片段著色器中,我們也必須使用一個不同的采樣器——samplerCube蛤吓,用它來從texture函數中采樣宵喂,但是這次使用的是一個vec3方向向量,取代vec2会傲。下面是一個片段著色器使用了立方體貼圖的例子:

in vec3 textureDir; // 用一個三維方向向量來表示立方體貼圖紋理的坐標

uniform samplerCube cubemap;  // 立方體貼圖紋理采樣器

void main()
{
    color = texture(cubemap, textureDir);
}

使用立方體貼圖可以簡單的實現(xiàn)很多有意思的技術锅棕。其中之一便是著名的天空盒(Skybox)

天空盒

天空盒(Skybox)是一個包裹整個場景的立方體淌山,它由6個圖像構成一個環(huán)繞的環(huán)境裸燎,給玩家一種他所在的場景比實際的要大得多的幻覺。比如有些在視頻游戲中使用的天空盒的圖像是群山泼疑、白云或者滿天繁星德绿。比如下面的夜空繁星的圖像就來自《上古卷軸》:

上圖中使用了幾個夜空的圖片給予玩家一種置身廣袤宇宙的感覺,可實際上退渗,他還是在一個小盒子之中脆炎。

網上有很多這樣的天空盒的資源。這個網站就提供了很多氓辣。這些天空盒圖像通常有下面的樣式:

這個細致(高精度)的天空盒就是我們將在場景中使用的那個秒裕,你可以在這里下載

加載天空盒

由于天空盒實際上就是一個立方體貼圖钞啸,加載天空盒和之前我們加載立方體貼圖的沒什么大的不同几蜻。為了加載天空盒我們將使用下面的函數,它接收一個包含6個紋理文件路徑的vector:

GLuint loadCubemap(vector<const GLchar*> faces)
{
    GLuint textureID;
    glGenTextures(1, &textureID);

    int width, height;
    unsigned char* image;

    glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);
    for(GLuint i = 0; i < faces.size(); i++)
    {
        image = SOIL_load_image(faces[i], &width, &height, 0, SOIL_LOAD_RGB);
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
        SOIL_free_image_data(image);    //  // 釋放源圖像內存
    }
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    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);
    glBindTexture(GL_TEXTURE_CUBE_MAP, 0);

    return textureID;
}

在我們調用這個函數之前体斩,我們將把合適的紋理路徑加載到一個vector之中梭稚,順序還是按照立方體貼圖枚舉的特定順序:

vector<const GLchar*> faces;
faces.push_back("right.jpg");
faces.push_back("left.jpg");
faces.push_back("top.jpg");
faces.push_back("bottom.jpg");
faces.push_back("back.jpg");
faces.push_back("front.jpg");
GLuint cubemapTexture = loadCubemap(faces);

現(xiàn)在我們已經用cubemapTexture作為id把天空盒加載為立方體貼圖。我們現(xiàn)在可以把它綁定到一個立方體來替換不完美的clear color絮吵,在前面的所有教程中這個東西做背景已經很久了弧烤。

顯示天空盒

因為天空盒繪制在了一個立方體上,我們還需要另一個VAO蹬敲、VBO以及一組全新的頂點暇昂,和任何其他物體一樣。你可以從這里獲得頂點數據伴嗡。

立方體貼圖用于給3D立方體帖上紋理急波,可以用立方體的位置作為紋理坐標進行采樣。當一個立方體的中心位于原點(0瘪校,0澄暮,0)的時候名段,它的每一個位置向量也就是以原點為起點的方向向量。這個方向向量就是我們要得到的立方體某個位置的相應紋理值泣懊。出于這個理由伸辟,我們只需要提供位置向量,而無需紋理坐標馍刮。為了渲染天空盒信夫,我們需要一組新著色器,它們不會太復雜渠退。因為我們只有一個頂點屬性忙迁,頂點著色器非常簡單:

#version 330 core
layout (location = 0) in vec3 position;
out vec3 TexCoords;

uniform mat4 projection;
uniform mat4 view;

void main()
{
    gl_Position =   projection * view * vec4(position, 1.0);  
    TexCoords = position;
}

注意脐彩,頂點著色器有意思的地方在于我們把輸入的位置向量作為輸出給片段著色器的紋理坐標碎乃。片段著色器就會把它們作為輸入去采樣samplerCube

#version 330 core
in vec3 TexCoords;
out vec4 color;

uniform samplerCube skybox;

void main()
{
    color = texture(skybox, TexCoords);
}

為了繪制天空盒,我們將把它作為場景中第一個繪制的物體并且關閉深度寫入惠奸。這樣天空盒才能成為所有其他物體的背景來繪制出來梅誓。

glDepthMask(GL_FALSE);
skyboxShader.Use();
// ... Set view and projection matrix
glBindVertexArray(skyboxVAO);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glDepthMask(GL_TRUE);
// ... Draw rest of the scene

當前的視圖矩陣對所有天空盒的位置進行了轉轉縮放和平移變換,所以玩家移動佛南,立方體貼圖也會跟著移動梗掰!我們打算移除視圖矩陣的平移部分,這樣移動就影響不到天空盒的位置向量了嗅回。在基礎光照教程里我們提到過我們可以只用4X4矩陣的3×3部分去除平移及穗。我們可以簡單地將矩陣轉為33矩陣再轉回來,就能達到目標:

glm::mat4 view = glm::mat4(glm::mat3(camera.GetViewMatrix()));

這會移除所有平移绵载,但保留所有旋轉埂陆,因此用戶仍然能夠向四面八方看。由于有了天空盒娃豹,場景即可變得巨大了焚虱。如果你添加些物體然后自由在其中游蕩一會兒你會發(fā)現(xiàn)場景的真實度有了極大提升。最后的效果看起來像這樣:

這里有全部源碼懂版,你可以對比一下你寫的鹃栽。
嘗試用不同的天空盒實驗,看看它們對場景有多大影響躯畴。

優(yōu)化

如果我們先渲染了天空盒民鼓,那么我們就是在為每一個屏幕上的像素運行片段著色器,即使天空盒只有部分在顯示著蓬抄;fragment可以使用前置深度測試(early depth testing)簡單地被丟棄摹察,這樣就節(jié)省了我們寶貴的帶寬。所以最后渲染天空盒就能夠給我們帶來輕微的性能提升倡鲸。采用這種方式供嚎,深度緩沖被全部物體的深度值完全填充,所以我們只需要渲染通過前置深度測試的那部分天空的片段就行了,而且能顯著減少片段著色器的調用克滴。

問題是天空盒是個1×1×1的立方體逼争,極有可能會渲染失敗,因為極有可能通不過深度測試劝赔。簡單地不用深度測試渲染它也不是解決方案誓焦,這是因為天空盒會在之后覆蓋所有的場景中其他物體。我們需要耍個花招讓深度緩沖相信天空盒的深度緩沖有著最大深度值1.0着帽,如此只要有個物體存在深度測試就會失敗杂伟,看似物體就在它前面了。

在坐標系教程中我們說過仍翰,透視除法(perspective division)是在頂點著色器運行之后執(zhí)行的赫粥,把gl_Position的xyz坐標除以w元素。我們從深度測試教程了解到除法結果的z元素等于頂點的深度值予借。利用這個信息越平,我們可以把輸出位置的z元素設置為它的w元素,這樣就會導致z元素等于1.0了灵迫,因為秦叛,當透視除法應用后,它的z元素轉換為w/w = 1.0:


void main()
{
    vec4 pos = projection * view * vec4(position, 1.0);
    gl_Position = pos.xyww;
    TexCoords = position;
}

最終瀑粥,標準化設備坐標就總會有個與1.0相等的z值了挣跋,1.0就是深度值的最大值。只有在沒有任何物體可見的情況下天空盒才會被渲染(只有通過深度測試才渲染狞换,否則假如有任何物體存在避咆,就不會被渲染,只去渲染物體)哀澈。

我們必須改變一下深度方程牌借,把它設置為GL_LEQUAL,原來默認的是GL_LESS割按。深度緩沖會為天空盒用1.0這個值填充深度緩沖膨报,所以我們需要保證天空盒是使用小于等于深度緩沖來通過深度測試的,而不是小于适荣。
你可以在這里找到優(yōu)化過的版本的源碼现柠。

環(huán)境映射

我們現(xiàn)在有了一個把整個環(huán)境映射到為一個單獨紋理的對象,我們利用這個信息能做的不僅是天空盒弛矛。使用帶有場景環(huán)境的立方體貼圖够吩,我們還可以讓物體有一個反射或折射屬性。像這樣使用了環(huán)境立方體貼圖的技術叫做環(huán)境貼圖技術丈氓,其中最重要的兩個是反射(reflection)折射(refraction)周循。

反射

凡是是一個物體(或物體的某部分)反射(Reflect)他周圍的環(huán)境的屬性强法,比如物體的顏色多少有些等于它周圍的環(huán)境,這要基于觀察者的角度湾笛。例如一個鏡子是一個反射物體:它會基于觀察者的角度泛著它周圍的環(huán)境饮怯。

下圖展示了我們如何計算反射向量,然后使用這個向量去從一個立方體貼圖中采樣:

我們基于觀察方向向量I和物體的法線向量N計算出反射向量R嚎研。我們可以使用GLSL的內建函數reflect來計算這個反射向量蓖墅。最后向量R作為一個方向向量對立方體貼圖進行索引/采樣,返回一個環(huán)境的顏色值临扮。最后的效果看起來就像物體反射了天空盒论矾。

因為我們在場景中已經設置了一個天空盒,創(chuàng)建反射就不難了杆勇。我們改變一下箱子使用的那個片段著色器贪壳,給箱子一個反射屬性:

#version 330 core
in vec3 Normal;
in vec3 Position;
out vec4 color;

uniform vec3 cameraPos;
uniform samplerCube skybox;

void main()
{
    vec3 I = normalize(Position - cameraPos);
    vec3 R = reflect(I, normalize(Normal));
    color = texture(skybox, R);
}

我們先來計算觀察/攝像機方向向量I,然后使用它來計算反射向量R靶橱,接著我們用R從天空盒立方體貼圖采樣寥袭。要注意的是路捧,我們有了片段的插值Normal和Position變量关霸,所以我們需要修正頂點著色器適應它。

#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;

out vec3 Normal;
out vec3 Position;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    gl_Position = projection * view * model * vec4(position, 1.0f);
    Normal = mat3(transpose(inverse(model))) * normal;
    Position = vec3(model * vec4(position, 1.0f));
}

我們用了法線向量杰扫,所以我們打算使用一個法線矩陣(normal matrix)變換它們队寇。Position輸出的向量是一個世界空間位置向量。頂點著色器輸出的Position用來在片段著色器計算觀察方向向量章姓。

因為我們使用法線佳遣,你還得更新頂點數據,更新屬性指針凡伊。還要確保設置cameraPos的uniform零渐。

然后在渲染箱子前我們還得綁定立方體貼圖紋理:

glBindVertexArray(cubeVAO);
glBindTexture(GL_TEXTURE_CUBE_MAP, skyboxTexture);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);

編譯運行你的代碼,你等得到一個鏡子一樣的箱子系忙。箱子完美地反射了周圍的天空盒:

你可以從這里找到全部源代碼诵盼。
項目代碼

當反射應用于整個物體之上的時候,物體看上去就像有一個像鋼和鉻這種高反射材質银还。如果我們加載模型教程中的納米鎧甲模型风宁,我們就會獲得一個鉻金屬制鎧甲:

看起來挺驚艷,但是現(xiàn)實中大多數模型都不是完全反射的蛹疯。我們可以引進反射貼圖(reflection map)來使模型有另一層細節(jié)戒财。和diffuse、specular貼圖一樣捺弦,我們可以從反射貼圖上采樣來決定fragment的反射率饮寞。使用反射貼圖我們還可以決定模型的哪個部分有反射能力孝扛,以及強度是多少。本節(jié)的練習中幽崩,要由你來在我們早期創(chuàng)建的模型加載器引入反射貼圖疗琉,這會極大的提升納米服模型的細節(jié)。

折射

環(huán)境映射的另一個形式叫做折射(Refraction)歉铝,它和反射差不多盈简。折射是光線通過特定材質對光線方向的改變。我們通程荆看到像水一樣的表面柠贤,光線并不是直接通過的,而是讓光線彎曲了一點类缤。它看起來像你把半只手伸進水里的效果臼勉。
折射遵守斯涅爾定律,使用環(huán)境貼圖看起來就像這樣:

我們有個觀察向量I餐弱,一個法線向量N宴霸,這次折射向量是R。就像你所看到的那樣膏蚓,觀察向量的方向有輕微彎曲瓢谢。彎曲的向量R隨后用來從立方體貼圖上采樣。

折射可以通過GLSL的內建函數refract來實現(xiàn)驮瞧,除此之外還需要一個法線向量氓扛,一個觀察方向和一個兩種材質之間的折射指數。

折射指數決定了一個材質上光線扭曲的數量论笔,每個材質都有自己的折射指數采郎。下表是常見的折射指數:

材質 折射指數
空氣 1.00
1.33
1.309
玻璃 1.52
寶石 2.42

我們使用這些折射指數來計算光線通過兩個材質的比率。在我們的例子中狂魔,光線/視線從空氣進入玻璃(如果我們假設箱子是玻璃做的)所以比率是1.001.52 = 0.658蒜埋。

我們已經綁定了立方體貼圖,提供了定點數據最楷,設置了攝像機位置的uniform≌荩現(xiàn)在只需要改變片段著色器:

void main()
{
    float ratio = 1.00 / 1.52;
    vec3 I = normalize(Position - cameraPos);
    vec3 R = refract(I, normalize(Normal), ratio);
    color = texture(skybox, R);
}

通過改變折射指數你可以創(chuàng)建出完全不同的視覺效果。編譯運行應用管嬉,結果也不是太有趣皂林,因為我們只是用了一個普通箱子,這不能顯示出折射的效果蚯撩,看起來像個放大鏡础倍。使用同一個著色器,納米服模型卻可以展示出我們期待的效果:玻璃制物體。

你可以向想象一下涮母,如果將光線、反射全蝶、折射和頂點的移動合理的結合起來就能創(chuàng)造出漂亮的水的圖像德迹。一定要注意芽卿,出于物理精確的考慮當光線離開物體的時候還要再次進行折射;現(xiàn)在我們簡單的使用了單邊(一次)折射胳搞,大多數目的都可以得到滿足卸例。

動態(tài)環(huán)境貼圖

現(xiàn)在,我們已經使用了靜態(tài)圖像組合的天空盒肌毅,看起來不錯筷转,但是沒有考慮到物體可能移動的實際場景。我們到現(xiàn)在還沒注意到這點悬而,是因為我們目前還只使用了一個物體呜舒。如果我們有個鏡子一樣的物體,它周圍有多個物體笨奠,只有天空盒在鏡子中可見袭蝗,就好像場景中只有一個物體一樣。

使用幀緩沖可以為提到的物體的所有6個不同角度創(chuàng)建一個場景的紋理般婆,把它們每次渲染迭代儲存為一個立方體貼圖到腥。之后我們可以使用這個(動態(tài)生成的)立方體貼圖來創(chuàng)建真實的反射和折射表面,這樣就能包含所有其他物體了腺兴。這種方法叫做動態(tài)環(huán)境映射(Dynamic Environment Mapping),因為我們動態(tài)地創(chuàng)建了一個物體的以其四周為參考的立方體貼圖左电,并把它用作環(huán)境貼圖廉侧。

它看起效果很好页响,但是有一個劣勢:使用環(huán)境貼圖我們必須為每個物體渲染場景6次,這需要非常大的開銷《翁埽現(xiàn)代應用嘗試盡量使用天空盒子闰蚕,凡可能預編譯立方體貼圖就創(chuàng)建少量動態(tài)環(huán)境貼圖。動態(tài)環(huán)境映射是個非常棒的技術连舍,要想在不降低執(zhí)行效率的情況下實現(xiàn)它就需要很多巧妙的技巧没陡。

練習

嘗試在模型加載中引進反射貼圖,你將再次得到很大視覺效果的提升索赏。這其中有幾點需要注意:Assimp并不支持反射貼圖盼玄,我們可以使用環(huán)境貼圖的方式將反射貼圖從aiTextureType_AMBIENT
類型中來加載反射貼圖的材質。
我匆忙地使用反射貼圖來作為鏡面反射的貼圖潜腻,而反射貼圖并沒有很好的映射在模型上:)埃儿。
由于加載模型已經占用了3個紋理單元,因此你要綁定天空盒到第4個紋理單元上融涣,這樣才能在同一個著色器內從天空盒紋理中取樣童番。

你可以在此獲取解決方案的源代碼精钮,這其中還包括升級過的ModelMesh類,還有用來繪制反射貼圖的頂點著色器片段著色器剃斧。

如果你一切都做對了轨香,那你應該看到和下圖類似的效果:

我沒有做出來,和所給代碼相同幼东,我運行出的結果是七彩的臂容,待解決!8贰策橘!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市娜亿,隨后出現(xiàn)的幾起案子丽已,更是在濱河造成了極大的恐慌,老刑警劉巖买决,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沛婴,死亡現(xiàn)場離奇詭異,居然都是意外死亡督赤,警方通過查閱死者的電腦和手機嘁灯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來躲舌,“玉大人丑婿,你說我怎么就攤上這事∶恍叮” “怎么了羹奉?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長约计。 經常有香客問我诀拭,道長,這世上最難降的妖魔是什么煤蚌? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任耕挨,我火速辦了婚禮,結果婚禮上尉桩,老公的妹妹穿的比我還像新娘筒占。我一直安慰自己,他們只是感情好蜘犁,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布翰苫。 她就那樣靜靜地躺著,像睡著了一般沽瘦。 火紅的嫁衣襯著肌膚如雪革骨。 梳的紋絲不亂的頭發(fā)上农尖,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音良哲,去河邊找鬼盛卡。 笑死,一個胖子當著我的面吹牛筑凫,可吹牛的內容都是我干的滑沧。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼巍实,長吁一口氣:“原來是場噩夢啊……” “哼滓技!你這毒婦竟也來了?” 一聲冷哼從身側響起棚潦,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤令漂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后丸边,有當地人在樹林里發(fā)現(xiàn)了一具尸體叠必,經...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年妹窖,在試婚紗的時候發(fā)現(xiàn)自己被綠了纬朝。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡骄呼,死狀恐怖共苛,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情蜓萄,我是刑警寧澤隅茎,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站绕德,受9級特大地震影響患膛,放射性物質發(fā)生泄漏。R本人自食惡果不足惜耻蛇,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望胞此。 院中可真熱鬧臣咖,春花似錦、人聲如沸漱牵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酣胀。三九已至刁赦,卻和暖如春娶聘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背甚脉。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工丸升, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人牺氨。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓狡耻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親猴凹。 傳聞我的和親對象是個殘疾皇子夷狰,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內容

  • 我們都知道,一個三維場景的畫面的好壞郊霎,百分之四十取決于模型沼头,百分之六十取決于貼圖,可見貼圖在畫面中所占的重要性书劝。在...
    自由的天空閱讀 12,382評論 0 12
  • 在這個處處都倡導讀書與跑步的社會,不讀書洞斯,就會落后毡庆,不跑步,就沒有健康的體魄烙如。 但是無論是讀書和跑步么抗,我們的最終目...
    Miss墨菲閱讀 245評論 2 4
  • 玫瑰的清香,加些許香甜亚铁,檸檬的酸味與輕許的清苦蝇刀,完美融合,冰涼的晶瑩剔透的冰塊浮在蘇打中徘溢,與杯壁碰撞發(fā)出輕脆的...
    葬花留殘香閱讀 327評論 0 1