視頻特效學(xué)習(xí)03-OpenGL渲染技巧解析

學(xué)習(xí)目標:
  • 1.渲染過程產(chǎn)生的問題(掌握)
    1. 油畫渲染(了解)
    1. 正面&背面剔除(掌握)
    1. 深度測試(掌握)
    1. ZFighting閃爍(了解)
    1. 窗口、視口呀闻、裁剪區(qū)域(掌握)
    1. 顏色混合(掌握)

1.渲染過程產(chǎn)生的問題

  • 核心代碼
void setupRC(void){
    glClearColor(0.5, 0.5, 0.7, 1);
    shaderManager.InitializeStockShaders();
    viewFrame.MoveForward(10.0f);
    //創(chuàng)建“環(huán)”
    gltMakeTorus(torusBatch, .5f, .3f, 60, 30);
    
}
void renderScene(void){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    modelViewMatix.PushMatrix(viewFrame);
    
    GLfloat vColor[] = { 0.2f, 0.4f, 0.6f, 1.0f };
    //使用默認光源著色器
    //通過光源袜瞬、陰影效果跟提現(xiàn)立體效果
    //參數(shù)1:GLT_SHADER_DEFAULT_LIGHT 默認光源著色器
    //參數(shù)2:模型視圖矩陣
    //參數(shù)3:投影矩陣
    //參數(shù)4:基本顏色值
    shaderManager.UseStockShader(GLT_SHADER_DEFAULT_LIGHT,transformPipeline.GetModelViewMatrix(),transformPipeline.GetProjectionMatrix(),vColor);
    modelViewMatix.PopMatrix();
    torusBatch.Draw();
    glutSwapBuffers();
}
  • 運行結(jié)果


    甜甜圈運行結(jié)果.png
  • 問題分析:旋轉(zhuǎn)一定的角度后,甜甜圈中不可見的部分與可見的部分混在一起垄琐,導(dǎo)致了結(jié)果的混亂。在繪制3D場景的時候,我們需要決定哪些部分對觀察者是可見的,或者哪些部分對觀察者不可見的妇拯。對于不可見的部分,應(yīng)該及早丟棄。例如在一個不透明的墻壁后越锈,就不應(yīng)該渲染仗嗦。這種情況叫做“隱藏面消除”。
  • 解決方法:油畫算法(不可取)甘凭;正背面剔除稀拐。

2.油畫渲染

  • 油畫算法:先繪制場景中的離觀察者較遠的物體,在繪制較近的物體丹弱。例如下圖:先繪制紅色部分德撬,再繪制黃色部分,最后再繪制灰色部分躲胳,即可解決隱藏面消除的問題蜓洪。


    油畫算法.png
  • 弊端:無法處理圖形疊加一起的情況。


    圖形疊在一起.png

3.正面&背面剔除

  • 背面剔除:在渲染的時候坯苹,背對觀察者的面丟棄隆檀,只將正面朝向觀察者進行計算。將看不到的面進行剔除北滥,節(jié)省CPU和GPU的資源刚操。
  • 正/背面區(qū)分


    頂點渲染順序.png
  • 正面:按照逆時針頂點順序連接
  • 背面:按照順時針頂點順序連接
  • 案例:分析立方體的正背面


    立方體正背面.png

    分析:左側(cè)三角形頂點順序為:1->2->3;右側(cè)三角形頂點順序為:1->2->3;當觀察者在右側(cè)時再芋,則右邊的三角形為逆時針方向菊霜,則為正面,而左側(cè)的三角形為順時針济赎,則為背面鉴逞;當觀察者在左側(cè)時,則左邊的三角形為逆時針司训,則為正面构捡,而右側(cè)的三角形為順時針,則為背面壳猜。
    總結(jié):正面和背面是由三角形的頂點定義順序和觀察者方向共同決定的勾徽。隨著觀察者的角度方向改變,正背面也會改變统扳。

  • 相關(guān)代碼
    • 開啟表面剔除(默認背面剔除)
    void glEnable(GL_CULL_FACE);
    
    • 關(guān)閉表面剔除(默認背面剔除)
    void glDissable(GL_CULL_FACE);
    
    • 用戶選擇剔除哪個面(正面/背面)
    void glCullFace(GLenum mode);
    mode參數(shù)為:GL_FRONT,GL_BACK(默認),GL_FRONT_AND_BACK,
    
    • 用戶指定順序哪個為正面
    void glFrontFace(GLenum mode);
     mode參數(shù)為:GL_CW,GL_CCW,默認值為GL_CCW
    
  • Demo中開啟背面剔除:
//召喚場景
void renderScene(void){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    modelViewMatix.PushMatrix(viewFrame);
    //開啟背面剔除
    glEnable(GL_CULL_FACE);
    GLfloat vColor[] = { 0.2f, 0.4f, 0.6f, 1.0f };
    shaderManager.UseStockShader(GLT_SHADER_DEFAULT_LIGHT,transformPipeline.GetModelViewMatrix(),transformPipeline.GetProjectionMatrix(),vColor);
    modelViewMatix.PopMatrix();
    torusBatch.Draw();
    glutSwapBuffers();
}

運行結(jié)果:


背面剔除后的結(jié)果.png

4. 深度測試

  • 深度:深度其實就是該像素點在3D世界中距離攝像機的距離Z值喘帚。
  • 深度緩沖區(qū):深度緩沖區(qū)就是一塊內(nèi)存區(qū)域,專門存儲著每個像素點(繪制在屏幕上的)深度值咒钟。深度值(Z值)越大離攝像機就越遠吹由。在不使用深度測試的時候,如果我們先繪制一個距離比較近的物體朱嘴,在繪制距離比較遠的物體倾鲫,則距離遠的位圖因為后繪制,會把距離近的物體覆蓋掉。有了深度緩沖區(qū)后乌昔,繪制物體的順序就不那么重要了隙疚。實際上,只要存在深度緩沖區(qū)磕道,OpenGL都會把像素的深度值寫入到緩沖區(qū)甚淡。除非調(diào)用glDepthMask(GL_false)來禁止寫入。
  • 深度測試:深度緩沖區(qū)(DepthBuffer)和顏色緩沖區(qū)(ColorBuffer)是對應(yīng)的捅厂。顏色緩沖區(qū)存儲像素的顏色信息,而深度緩沖區(qū)存儲像素的深度信息资柔。在決定是否繪制一個物體表面時焙贷,首先要將表面的當前像素的深度值與深度緩沖區(qū)的值進行比較。如果當前的深度值大于深度緩沖區(qū)的值贿堰,這丟棄這部分辙芍。否者利用這個像素對應(yīng)的深度值和顏色值,分別更新深度緩沖區(qū)和顏色緩沖區(qū)羹与。這個過程稱為”深度測試“故硅。
  • 深度值計算:
    • 深度值一般由16位、24位或者32位值表示纵搁,通常是24位吃衅。位數(shù)越高,深度的精確值越好腾誉。深度值的范圍在[0,1]之間徘层,值越小表示越靠近觀察者,值越大表示越遠離觀察者利职。
    • 在OpenGL中趣效,屏幕空間坐標的Z值即是深度緩沖中的深度值。深度緩沖包含了一個介于0.0和1.0之間的深度值猪贪,它將會與觀察者視角所看見的場景中所有物體的z值進行比較跷敬。我們因此需要一些方法轉(zhuǎn)換這些視圖空間z值到[0,1]的范圍內(nèi),下面的線性方程把z值轉(zhuǎn)換為0.0-1.0之間的值:


      z值轉(zhuǎn)換到0-1.png
  • 使用深度測試:
    • 深度緩沖區(qū)热押,一般由窗口管理系統(tǒng)西傀,GLFW創(chuàng)建。深度值一般由16位楞黄、24位和32位值表示池凄。位數(shù)越高,深度精確度越好鬼廓。
    • 開啟深度測試:
     glEnable(GL_DEPTH_TEST);
    
    • 在繪制場景前肿仑,清除顏色緩存區(qū),深度緩沖區(qū)
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    • 指定深度測試判斷模式
    void glDepthFunc(GLEnum mode);
    
深度測試判斷模式.png
  • Demo中開啟深度測試:
 glEnable(GL_DEPTH_TEST);

運行結(jié)果:


深度測試結(jié)果.png

*5. ZFighting閃爍

  • ZFighting閃爍問題原因:開啟深度測試后,OpenGL就不會再去繪制模型被遮擋的部分尤慰。這樣實現(xiàn)的顯示更加真實馏锡。但是,由于深度緩沖區(qū)精度的限制伟端,對于深度非常小的情況下杯道,就可能導(dǎo)致判斷深度值不正確,導(dǎo)致深度測試的結(jié)果不可預(yù)測责蝠。顯示時交錯閃爍党巾。如下圖時而渲染出綠色,時而渲染出紅色霜医,無法確定,交錯閃爍)齿拂。


    ZFighting01.png
ZFighting02.png
  • 解決方案:
    • 第一步:啟用Polygon Offet方式解決
    //參數(shù)列表:
    //GL_POLYGON_OFFSET_POINT 對應(yīng)光柵化模式:GL_POINT
    //GL_POLYGON_OFFSET_LINE 對應(yīng)光柵化模式:GL_LINE
    //GL_POLYGON_OFFSET_FILL 對應(yīng)光柵化模式:GL_FILL
    glEnable(GL_POLYGON_OFFSET_FILL)
    
    • 第二步:指定偏移量
    void glPolygonOffset(Glfloat factor,Glfloat units);
    //應(yīng)?到片段上總偏移計算?方程式:
    Depth Offset = (DZ * factor) + (r * units); 
    //DZ:深度值(Z值)
    //r:使得深度緩沖區(qū)產(chǎn)生變化的最小值負值,將使得z值距離我們更近肴敛,而正值署海,將使得z值距離我們更遠,我們  設(shè)置factor和units設(shè)置為-1医男,-1
    
    • 第三步:關(guān)閉Polygon Offset
     glDisable(GL_POLYGON_OFFSET_FILL)
    
  • 問題預(yù)防:
    • 不要將兩個物體靠的太近砸狞,避免渲染時三角形疊在一起。這種方式要求對場景中物體插入一個少量的偏移镀梭,那么就可能避免ZFighting現(xiàn)象刀森。例如立方體和平面問題中,將平面下移0.001f就可以解決這個問題丰辣。當然手動去插入這個小的偏移是要付出代價的撒强。
    • 盡可能將近裁剪面設(shè)置的離觀察者遠一些,會使得整個裁剪范圍內(nèi)的精度變高一些笙什。但是這種方式會使離觀察者較近的物體被裁減掉飘哨,因此需要調(diào)試好裁剪面參數(shù)。

6. 窗口琐凭、視口芽隆、裁剪區(qū)域

  • 窗口:就是顯示界面。
  • 視口:就是窗口中用來顯示圖形的一塊矩形區(qū)域统屈,它可以和窗口等大胚吁,也可以比窗口大或小。只有繪制在視口區(qū)域中的圖形才能被顯示愁憔,如果圖形有一部分超出了視口區(qū)域腕扶,那么那一部分是看不到的。通過glViewport()函數(shù)設(shè)置吨掌。
  • 裁剪區(qū)域(平行投影):就是視口矩形區(qū)域的最小最大x坐標(left,right)和最小最大y坐標(bottom,top),而不是窗口的最小最大x坐標和y坐標半抱。通過glOrtho()函數(shù)設(shè)置脓恕,這個函數(shù)還需指定最近最遠z坐標,形成一個立體的裁剪區(qū)域窿侈。
  • 裁剪:是OpenGL提高渲染的一種方式炼幔,只刷新屏幕上發(fā)生變化的部分,OpenGL允許將要進行渲染的窗口只去指定一個裁剪框史简∧诵悖基本原理:用于渲染時限制繪制區(qū)域,通過此技術(shù)可以在屏幕(幀緩沖)指定一個矩形區(qū)域圆兵。啟用裁剪測試之后跺讯,不在此矩形區(qū)域內(nèi)的片元被丟棄,只有在此矩形區(qū)域內(nèi)的片元才有可能進入幀緩沖殉农。因此實際達到的效果就是在屏幕上開辟了一個小窗口抬吟,可以在其中進行指定內(nèi)容的繪制。
     //1.開啟裁剪測試
     glEnable(GL_SCISSOR_TEST);
     //2.關(guān)閉裁剪測試
     gldisable(GL_SCISSOR_TEST)统抬;
     //3.指定裁剪窗口 x,y:指定裁剪框左下角位置  width,height:指定裁剪尺寸
     void glScissor(GLint x, GLSize width,GLSize height);
    

裁剪核心代碼:

void renderScene(void){
    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    //裁剪成紅色分區(qū)
    //1.設(shè)置裁剪區(qū)域的顏色
   glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
   //2.設(shè)置裁剪尺寸
   glScissor(100, 100, 600, 400);
   //3.開啟裁剪測試
   glEnable(GL_SCISSOR_TEST);
   //4.開啟清屏,執(zhí)行裁剪
   glClear(GL_COLOR_BUFFER_BIT);
   
   //裁剪成綠色分區(qū)
   //1.設(shè)置裁剪區(qū)域的顏色
   glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
   //2.設(shè)置裁剪尺寸
   glScissor(200, 200, 400, 200);
   //3.開啟裁剪測試
   glEnable(GL_SCISSOR_TEST);
   //4.開啟清屏危队,執(zhí)行裁剪
   glClear(GL_COLOR_BUFFER_BIT);
   //關(guān)閉裁剪區(qū)域
   glDisable(GL_SCISSOR_TEST);
   
   glutSwapBuffers();
}

7. 顏色混合

  • 混合:在OpenGL中聪建,物體透明技術(shù)通常被叫做混合(Blending)。OpenGL渲染時會把顏色值存在顏色緩沖區(qū)中茫陆,每個片段的深度值也是放在深度緩沖區(qū)中金麸。當深度緩沖區(qū)被關(guān)閉時,新的顏色將簡單的覆蓋原來顏色緩沖區(qū)的顏色值簿盅,當深度緩沖區(qū)再次打開時挥下,新的顏色片段比原來的值更鄰近的裁剪平面時,才會替換原來的顏色片段桨醋。
     // 使用OpenGL的混合功能
      glEnable(GL_BLEND);
     // 關(guān)閉OpenGL的混合功能
     glDisable(GL_BLEND);
    // 設(shè)置混合因子棚瘟,需要用到glBlendFun函數(shù)
    // S:源混合因子
    // D:目標混合因子
    glBlendFunc(GL enum S,GLenum D);
    
  • 組合顏色
    OpenGL 會把源顏色和目標顏色各自取出,并乘以一個系數(shù)(源顏色乘以的系數(shù)稱為“源因子”喜最,目標顏色乘以的系數(shù)稱為“目標因子”)偎蘸,然后相加,這樣就得到了新的顏色瞬内。(也可以不是相加迷雪,新版本的OpenGL可以設(shè)置運算方式,包括加虫蝶、減章咧、取兩者中較大的、取兩者中較小的能真、邏輯運算等)赁严。
    • 目標顏色:已經(jīng)存儲在顏色緩沖區(qū)的顏色值(之前的顏色)扰柠。
    • 源顏色:當前的要進入顏色緩存區(qū)的顏色值(后來要畫上去的顏色)。

    也可以理解成源顏色和目標顏色是跟繪制的順序有關(guān)的误澳。假如先繪制了一個紅色的物體耻矮,再在其上繪制綠色的物體。則綠色是源顏色忆谓,紅色是目標顏色裆装。如果順序反過來,則 紅色就是源顏色倡缠,綠色才是目標顏色哨免。在繪制時,應(yīng)該注意順序昙沦,使得繪制的源顏色與設(shè)置的源因子對應(yīng)琢唾,目標顏色與設(shè)置的目標因子對應(yīng)。(聯(lián)想射箭 目標是靶心 箭是源)

用數(shù)學(xué)公式來表達一下這個運算方式:
盾饮。則混合產(chǎn)生的新顏色可以表示為:

//Cf:最終計算參數(shù)的顏色
//Cs:源顏色
//S:源混合因子
//D:目標混合因子
Cf = (Cs * S) + (Cd * d)
//假設(shè)源顏色的四個分量(指紅色采桃,綠色,藍色丘损,alpha值)是(Rs, Gs, Bs, As)
//目標顏色的四個分量是(Rd, Gd, Bd, Ad)普办,
//源因子為(Sr, Sg, Sb, Sa)
//目標因子為(Dr, Dg, Db, Da)
Cf = (Rs*Sr+Rd*Dr, Gs*Sg+Gd*Dg, Bs*Sb+Bd*Db, As*Sa+Ad*Da)

OpenGL混合因子.png

常用混合函數(shù)
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

  • 混合的Demo
#include <stdio.h>
#include "GLShaderManager.h"
#include "GLTools.h"
#include <GLUT/GLUT.h>
GLBatch     squareBatch;
GLBatch     redBatch;
GLBatch     blackBatch;
GLBatch     blueBatch;
GLBatch     greenBatcch;
GLShaderManager shaderManager;
GLfloat blockSize = 0.2f;
GLfloat vVerts[] = { -blockSize, -blockSize, 0.0f,
    blockSize, -blockSize, 0.0f,
    blockSize,  blockSize, 0.0f,
    -blockSize,  blockSize, 0.0f};

//重塑函數(shù)
void changeSize(int w, int h){
    glViewport(0, 0, w, h);
}

//召喚場景
void renderScene(void){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    //定義4種顏色
    GLfloat vRed[] = { 1.0f, 0.0f, 0.0f, 0.5f };
    GLfloat vGreen[] = { 0.0f, 1.0f, 0.0f, 1.0f };
    GLfloat vBlue[] = { 0.0f, 0.0f, 1.0f, 1.0f };
    GLfloat vBlack[] = { 0.0f, 0.0f, 0.0f, 1.0f };
    
    shaderManager.UseStockShader(GLT_SHADER_IDENTITY,vRed);
    redBatch.Draw();
    
    shaderManager.UseStockShader(GLT_SHADER_IDENTITY,vGreen);
    greenBatcch.Draw();
    
    shaderManager.UseStockShader(GLT_SHADER_IDENTITY,vBlue);
    blueBatch.Draw();
    
    shaderManager.UseStockShader(GLT_SHADER_IDENTITY,vBlack);
    blackBatch.Draw();
    
    //固定矩形的顏色
    shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed);
    squareBatch.Draw();
    
    //核心代碼 顏色混合
    //1.開啟混合
    glEnable(GL_BLEND);
    //2.開啟組合函數(shù) 計算混合顏色因子
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    glutSwapBuffers();
    
}

//設(shè)置渲染環(huán)境
void setupRC(void){
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    shaderManager.InitializeStockShaders();
    
    //繪制移動的矩形
    squareBatch.Begin(GL_TRIANGLE_FAN, 4);
    squareBatch.CopyVertexData3f(vVerts);
    squareBatch.End();
    
    //繪制4個固定矩形
    GLfloat vBlock[] = {
        0.25f, 0.25f, 0.0f,
        0.75f, 0.25f, 0.0f,
        0.75f, 0.75f, 0.0f,
        0.25f, 0.75f, 0.0f
    };
    redBatch.Begin(GL_TRIANGLE_FAN,4);
    redBatch.CopyVertexData3f(vBlock);
    redBatch.End();
    
    GLfloat vBlock1[] = {
        -0.75f, 0.25f, 0.0f,
        -0.25f, 0.25f, 0.0f,
        -0.25f, 0.75f, 0.0f,
        -0.75f, 0.75f, 0.0f
    };
    greenBatcch.Begin(GL_TRIANGLE_FAN,4);
    greenBatcch.CopyVertexData3f(vBlock1);
    greenBatcch.End();
    
    GLfloat vBlock2[] = {
        -0.75f, -0.75f, 0.0f,
        -0.25f, -0.75f, 0.0f,
        -0.25f, -0.25f, 0.0f,
        -0.75f, -0.25f, 0.0f
    };
    blueBatch.Begin(GL_TRIANGLE_FAN,4);
    blueBatch.CopyVertexData3f(vBlock2);
    blueBatch.End();
    
    GLfloat vBlock3[] = {
        0.25f, -0.75f, 0.0f,
        0.75f, -0.75f, 0.0f,
        0.75f, -0.25f, 0.0f,
        0.25f, -0.25f, 0.0f
    };
    blackBatch.Begin(GL_TRIANGLE_FAN,4);
    blackBatch.CopyVertexData3f(vBlock3);
    blackBatch.End();
    
}

//特殊鍵位函數(shù)
void specialKeys(int key, int x, int y){
    
    //每一步移動的距離
    GLfloat stepSize = 0.025f;
    //以左上角的坐標為參照
    GLfloat blockX = vVerts[0];
    GLfloat blockY = vVerts[7];
    
    if (key == GLUT_KEY_UP) {
        blockY += stepSize;
    }
    if (key == GLUT_KEY_DOWN) {
        blockY -= stepSize;
    }
    if (key == GLUT_KEY_LEFT) {
        blockX -= stepSize;
    }
    if (key == GLUT_KEY_RIGHT) {
        blockX += stepSize;
    }
    //邊界處理
    if(blockX < -1.0f) blockX = -1.0f;
    if(blockX > (1.0f - blockSize * 2)) blockX = 1.0f - blockSize * 2;;
    if(blockY < -1.0f + blockSize * 2)  blockY = -1.0f + blockSize * 2;
    if(blockY > 1.0f) blockY = 1.0f;
    vVerts[0] = blockX;
    vVerts[1] = blockY - blockSize*2;
    
    vVerts[3] = blockX + blockSize*2;
    vVerts[4] = blockY - blockSize*2;
    
    vVerts[6] = blockX + blockSize*2;
    vVerts[7] = blockY;
    
    vVerts[9] = blockX;
    vVerts[10] = blockY;
    squareBatch.CopyVertexData3f(vVerts);
       
    glutPostRedisplay();
}

//根據(jù)空格次數(shù)。切換不同的“窗口名稱”
void keyPressFunc(unsigned char key, int x, int y){
    
}

//檢查OpenGL API是否安全可用
int checkOpenGLInit(void){
   GLenum status = glewInit();
    if(status != GLEW_OK){
        printf("GLEW Error:%s\n",glewGetErrorString(status));
        return 1;
    }
    return 0;
}


int main(int argc,char *argv[])
{
    gltSetWorkingDirectory(argv[0]);
    glutInit(&argc, argv);
    glutInitWindowSize(600, 600);
    //申請一個雙緩存區(qū)徘钥、顏色緩存區(qū)衔蹲、深度緩存區(qū)、模板緩存區(qū)
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
    //創(chuàng)建window的名稱
    glutCreateWindow("移動矩形呈础,觀察顏色");
    
    //注冊回調(diào)函數(shù)(改變尺寸)
    glutReshapeFunc(changeSize);
    //點擊空格時舆驶,調(diào)用的函數(shù)
    glutKeyboardFunc(keyPressFunc);
    //特殊鍵位函數(shù)(上下左右)
    glutSpecialFunc(specialKeys);
    //顯示函數(shù)
    glutDisplayFunc(renderScene);
    //判斷一下是否能初始化glew庫,確保項目能正常使用OpenGL 框架
    checkOpenGLInit();
    //繪制
    setupRC();
    //runloop運行循環(huán)
    glutMainLoop();
    
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末而钞,一起剝皮案震驚了整個濱河市沙廉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌臼节,老刑警劉巖蓝仲,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異官疲,居然都是意外死亡袱结,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門途凫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來垢夹,“玉大人,你說我怎么就攤上這事维费」” “怎么了促王?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長而晒。 經(jīng)常有香客問我蝇狼,道長,這世上最難降的妖魔是什么倡怎? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任迅耘,我火速辦了婚禮,結(jié)果婚禮上监署,老公的妹妹穿的比我還像新娘颤专。我一直安慰自己,他們只是感情好钠乏,可當我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布栖秕。 她就那樣靜靜地躺著,像睡著了一般晓避。 火紅的嫁衣襯著肌膚如雪簇捍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天俏拱,我揣著相機與錄音垦写,去河邊找鬼。 笑死彰触,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的命辖。 我是一名探鬼主播况毅,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼尔艇!你這毒婦竟也來了尔许?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤终娃,失蹤者是張志新(化名)和其女友劉穎味廊,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體棠耕,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡余佛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了窍荧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辉巡。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蕊退,靈堂內(nèi)的尸體忽然破棺而出郊楣,到底是詐尸還是另有隱情憔恳,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布净蚤,位于F島的核電站钥组,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏今瀑。R本人自食惡果不足惜程梦,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望放椰。 院中可真熱鬧作烟,春花似錦、人聲如沸砾医。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽如蚜。三九已至压恒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間错邦,已是汗流浹背探赫。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留撬呢,地道東北人伦吠。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像魂拦,于是被迫代替她去往敵國和親毛仪。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容