重新自学学习openGL 之光照材质

在现实世界里,每个物体会对光产生不同的反应。比如说,钢看起来通常会比陶瓷花瓶更闪闪发光,木头箱子也不会像钢制箱子那样对光产生很强的反射。每个物体对镜面高光也有不同的反应。有些物体反射光的时候不会有太多的散射(Scatter),因而产生一个较小的高光点,而有些物体则会散射很多,产生一个有着更大半径的高光点。如果我们想要在OpenGL中模拟多种类型的物体,我们必须为每个物体分别定义一个材质(Material)属性。

知识点,
颜色计算 把光源的颜色与物体的颜色值相乘

上一节,我们指定了一个物体和光的颜色,以及结合环境光和镜面强度分量,来定义物体的视觉输出. 因此, 我们可以用这三个分量来定义一个材质颜色(Material Color):环境光照(Ambient Lighting)、漫反射光照(Diffuse Lighting)和镜面光照(Specular Lighting).

struct Material {
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
    float shininess;
}; 
uniform Material material;

编码
在片段着色器中,我们创建一个结构体(Struct)来储存物体的材质属性。我们也可以把它们储存为独立的uniform值,但是作为一个结构体来储存会更有条理一些。

你可以看到,我们为每个冯氏光照模型的分量都定义一个颜色向量。ambient材质向量定义了在环境光照下这个物体反射得是什么颜色,通常这是和物体颜色相同的颜色。diffuse材质向量定义了在漫反射光照下物体的颜色。(和环境光照一样)漫反射颜色也要设置为我们需要的物体颜色。specular材质向量设置的是镜面光照对物体的颜色影响(或者甚至可能反射一个物体特定的镜面高光颜色)。最后,shininess影响镜面高光的散射/半径。

这四个元素定义了一个物体的材质,通过它们我们能够模拟很多现实世界中的材质。
下面列举一些材质

Name Ambient Diffuse Specular Shininess
emerald 0.0215 0.1745 0.0215 0.07568 0.61424 0.07568 0.633 0.727811 0.633 0.6
jade 0.135 0.2225 0.1575 0.54 0.89 0.63 0.316228 0.316228 0.316228 0.1
obsidian 0.05375 0.05 0.06625 0.18275 0.17 0.22525 0.332741 0.328634 0.346435 0.3
pearl 0.25 0.20725 0.20725 1 0.829 0.829 0.296648 0.296648 0.296648 0.088
ruby 0.1745 0.01175 0.01175 0.61424 0.04136 0.04136 0.727811 0.626959 0.626959 0.6
turquoise 0.1 0.18725 0.1745 0.396 0.74151 0.69102 0.297254 0.30829 0.306678 0.1
brass 0.329412 0.223529 0.027451 0.780392 0.568627 0.113725 0.992157 0.941176 0.807843 0.21794872
bronze 0.2125 0.1275 0.054 0.714 0.4284 0.18144 0.393548 0.271906 0.166721 0.2
chrome 0.25 0.25 0.25 0.4 0.4 0.4 0.774597 0.774597 0.774597 0.6
copper 0.19125 0.0735 0.0225 0.7038 0.27048 0.0828 0.256777 0.137622 0.086014 0.1
gold 0.24725 0.1995 0.0745 0.75164 0.60648 0.22648 0.628281 0.555802 0.366065 0.4
silver 0.19225 0.19225 0.19225 0.50754 0.50754 0.50754 0.508273 0.508273 0.508273 0.4
black plastic 0.0 0.0 0.0 0.01 0.01 0.0 1 0.50 0.50 0.50 .25
cyan plastic 0.0 0.1 0.06 0.0 0.50980392 0.50980392 0.50196078 0.50196078 0.50196078 .25
green plastic 0.0 0.0 0.0 0.1 0.35 0.1 0.45 0.55 0.45 .25
red plastic 0.0 0.0 0.0 0.5 0.0 0. 0 0.7 0.6 0.6 .25
white plastic 0.0 0.0 0.0 0.55 0.55 0.55 0.70 0.70 0.70 .25
yellow plastic 0.0 0.0 0.0 0.5 0.5 0.0 0.60 0.60 0.50 .25
black rubber 0.02 0.02 0.02 0.01 0.01 0.01 0.4 0.4 0.4 . 078125
cyan rubber 0.0 0.05 0.05 0.4 0.5 0.5 0.04 0.7 0.7 .078125
green rubber 0.0 0.05 0.0 0.4 0.5 0.4 0.04 0.7 0.04 .078125
red rubber 0.05 0.0 0.0 0.5 0.4 0.4 0.7 0.04 0.04 .078125
white rubber 0.05 0.05 0.05 0.5 0.5 0.5 0.7 0.7 0.7 .078125
yellow rubber 0.05 0.05 0.0 0.5 0.5 0.4 0.7 0.7 0.04 .078125

这里需要注意 Shininess 是基于128 做底数来计算的.

它们模拟了现实世界中的真实材质。下面的图片展示了几种现实世界的材质对我们的立方体的影响:


这里是我根据上面材质做的一个模型


emerald

材质编码

这里我们只需要将上一节的shader 进行简单修改就行了.如下

precision lowp float;
uniform vec3 lightPos; ///光源位置
uniform vec3 lightColor; ///光源颜色
uniform vec3 viewPos;

//uniform vec3  ambientLight; ///环境光

varying lowp vec3 normal;
varying lowp vec3 FragPos;
//varying lowp vec3 vary_vertexColor;

struct Material{
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
    float shininess;
};

uniform Material material;

void main(){
    // 环境光
    vec3 ambient = lightColor * material.ambient;
    
    // 漫反射
    vec3 norm = normalize(normal);
    vec3 lightDir = normalize(lightPos - FragPos);
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = lightColor * (diff * material.diffuse);
    
    // 镜面光
    vec3 viewDir = normalize(viewPos - FragPos);
    vec3 reflectDir = reflect(-lightDir, norm);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess*128.0);
    vec3 specular = lightColor * (spec * material.specular);
    
    vec3 result = ambient + diffuse + specular;
    gl_FragColor =vec4(result, 1.0);;
}

这里有个结构体,如何给结构体传值呢?
给结构体赋值,我们需要依次填充结构体

typedef union{
    struct {
        GLKVector3 ambient;
        GLKVector3 diffuse;
        GLKVector3 specular;
        float shininess;
    };
    float m[10];
}Material;

 Material material;
    material.ambient = GLKVector3Make(0.0215, 0.1745, 0.0215);
    material.diffuse =GLKVector3Make(0.07568, 0.61424, 0.07568);
    material.specular =GLKVector3Make(0.633, 0.727811, 0.633);
    material.shininess =0.6;
    glUniform1fv(self.bindObject->uniforms[MaterialUniformLocationMaterialShininess],1,&material.shininess);
    glUniform3fv(self.bindObject->uniforms[MaterialUniformLocationMaterialDiffuse], 1, &material.diffuse);
    glUniform3fv(self.bindObject->uniforms[MaterialUniformLocationMaterialsSpecular], 1, &material.specular);
    glUniform3fv(self.bindObject->uniforms[MaterialUniformLocationMaterialAmbient], 1, &material.ambient);

光属性

光源对环境光、漫反射和镜面光分量也具有着不同的强度。
假如我们设置光源对环境光、漫反射和镜面光分量是固定的话.
那么光源lightColor是vec3(1.0),代码会看起来像这样:

vec3 ambient  = vec3(1.0) * material.ambient;
vec3 diffuse  = vec3(1.0) * (diff * material.diffuse);
vec3 specular = vec3(1.0) * (spec * material.specular);

从上面代码能看出来,我们不能通过改变光的分量来改变材质的单一属性.为了改变材质的单一属性,我们就需要把光分成三部分,每一部分对应材质的一种分量.
定义光的结构如下

struct Light {
    vec3 position;
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};

uniform Light light;

一个光源对它的ambient、diffuse和specular光照有着不同的强度。环境光照通常会设置为一个比较低的强度,因为我们不希望环境光颜色太过显眼。光源的漫反射分量通常设置为光所具有的颜色,通常是一个比较明亮的白色。镜面光分量通常会保持为vec3(1.0),以最大强度发光。注意我们也将光源的位置添加到了结构体中。
和材质uniform一样,我们需要更新片段着色器:

precision mediump float;
uniform vec3 lightPos; ///光源位置
uniform vec3 lightColor; ///光源颜色

uniform vec3 viewPos;

varying lowp vec3 normal;
varying lowp vec3 FragPos;
//varying lowp vec3 vary_vertexColor;

struct Material{
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
    float shininess;
};
uniform Material material;

struct Light{
    vec3 lightPos;
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};
uniform Light light;



void main(){
    // 环境光
  
    vec3 ambient = light.ambient * material.ambient;
    
    // 漫反射
    vec3 norm = normalize(normal);
    vec3 lightDir = normalize(light.lightPos - FragPos);
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = light.diffuse * (diff * material.diffuse);
    
    // 镜面光
    vec3 viewDir = normalize(viewPos - FragPos);
    vec3 reflectDir = reflect(-lightDir, norm);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess*128.0);
    vec3 specular = light.specular * (spec * material.specular);
    
    vec3 result = ambient + diffuse + specular;
    gl_FragColor =vec4(result, 1.0);;
}

这样我们就可以改变光来控制材质的单一属性了.

   MaterialObject material;
    material.ambient = GLKVector3Make(1.0f, 0.5f, 0.31f);
    material.diffuse =GLKVector3Make(1.0f, 0.5f, 0.31f);
    material.specular =GLKVector3Make(0.5f, 0.5f, 0.5f);
    material.shininess =0.08988;
    glUniform1fv(self.bindObject->uniforms[MaterialObjectUniformLocationMaterialShininess],1,&material.shininess);
    glUniform3fv(self.bindObject->uniforms[MaterialObjectUniformLocationMaterialDiffuse], 1, &material.diffuse);
    glUniform3fv(self.bindObject->uniforms[MaterialObjectUniformLocationMaterialsSpecular], 1, &material.specular);
    glUniform3fv(self.bindObject->uniforms[MaterialObjectUniformLocationMaterialAmbient], 1, &material.ambient);
    
    
    Light light;
    light.lightPos =  GLKVector3Make(2.0, 0.0,0);
    light.ambient  =GLKVector3Make(0.2,0.2,0.2);
    light.diffuse  =GLKVector3Make(0.5,0.5,0.5);
    light.specular  =GLKVector3Make(1.0,1.0,1.0);

    glUniform3fv(self.bindObject->uniforms[LightUniformLocationLightPos], 1, &light.lightPos);
    glUniform3fv(self.bindObject->uniforms[LightUniformLocationLightsSpecular], 1, &light.specular);

渲染结果


QQ20190806-164942.gif

综合上面代码demo源码

demo结果


#import "LightTestViewController.h"
#import "GLLightBindObject.h"
#import "CubeManager.h"

@interface LightTestViewController ()

@property (nonatomic ,strong) Vertex * vertexPostion ;
@property (nonatomic ,strong) Vertex * vertexColor ;
@property (nonatomic ,strong) Vertex * vertexNormal ;
@end

@implementation LightTestViewController

-(void)initSubObject{
    //生命周期三秒钟
    __weakSelf
    self.bindObject = [GLLightBindObject new];
    self.bindObject.uniformSetterBlock = ^(GLuint program) {
        weakSelf.bindObject->uniforms[MVPMatrix] = glGetUniformLocation(self.shader.program, "u_mvpMatrix");
        weakSelf.bindObject->uniforms[LightUniformLocationModel] = glGetUniformLocation(self.shader.program, "u_model");
        weakSelf.bindObject->uniforms[LightUniformLocationInvermodel] = glGetUniformLocation(self.shader.program, "u_inverModel");
        weakSelf.bindObject->uniforms[LightUniformLocationviewPos] = glGetUniformLocation(self.shader.program, "viewPos");
        weakSelf.bindObject->uniforms[MaterialObjectUniformLocationMaterialAmbient] = glGetUniformLocation(self.shader.program, "material.ambient");
        weakSelf.bindObject->uniforms[MaterialObjectUniformLocationMaterialDiffuse] = glGetUniformLocation(self.shader.program, "material.diffuse");
        weakSelf.bindObject->uniforms[MaterialObjectUniformLocationMaterialsSpecular] = glGetUniformLocation(self.shader.program, "material.specular");
        weakSelf.bindObject->uniforms[MaterialObjectUniformLocationMaterialShininess] = glGetUniformLocation(self.shader.program, "material.shininess");
        
        weakSelf.bindObject->uniforms[LightUniformLocationLightPos] = glGetUniformLocation(self.shader.program, "light.lightPos");
        weakSelf.bindObject->uniforms[LightUniformLocationLightAmbient] = glGetUniformLocation(self.shader.program, "light.ambient");
        weakSelf.bindObject->uniforms[LightUniformLocationLightsSpecular] = glGetUniformLocation(self.shader.program, "light.specular");
        weakSelf.bindObject->uniforms[LightUniformLocationLightDiffuse] = glGetUniformLocation(self.shader.program, "light.diffuse");
        
        
    };
}



-(void)createShader{
    __weakSelf
    self.shader = [Shader new];
    [self.shader compileLinkSuccessShaderName:self.bindObject.getShaderName completeBlock:^(GLuint program) {
        [self.bindObject BindAttribLocation:program];
    }];
    if (self.bindObject.uniformSetterBlock) {
        self.bindObject.uniformSetterBlock(self.shader.program);
    }
}///消除0x502 操作
-(void)createTextureUnit{
    
}
-(void)loadVertex{
    //顶点数据缓存
    self.vertexPostion= [Vertex new];
    int vertexNum =[CubeManager getNormalVertexNum];
    [self.vertexPostion allocVertexNum:vertexNum andEachVertexNum:3];
    for (int i=0; i<vertexNum; i++) {
        float onevertex[3];
        for (int j=0; j<3; j++) {
            onevertex[j]=[CubeManager getNormalVertexs][i*9+j];
        }
        [self.vertexPostion setVertex:onevertex index:i];
    }
    [self.vertexPostion bindBufferWithUsage:GL_STATIC_DRAW];
    [self.vertexPostion enableVertexInVertexAttrib:BeginPosition numberOfCoordinates:3 attribOffset:0];
    
    //    self.vertexColor = [Vertex new];
    //    [self.vertexColor allocVertexNum:vertexNum andEachVertexNum:3];
    //    for (int i=0; i<vertexNum; i++) {
    //        float onevertex[3];
    //        for (int j=0; j<3; j++) {
    //            onevertex[j]=[CubeManager getNormalVertexs][i*9+j+6];
    //        }
    //        [self.vertexColor setVertex:onevertex index:i];
    //    }
    //    [self.vertexColor bindBufferWithUsage:GL_STATIC_DRAW];
    //    [self.vertexColor enableVertexInVertexAttrib:LightBindAttribLocationVertexColor numberOfCoordinates:3 attribOffset:0];
    
    self.vertexNormal= [Vertex new];
    [self.vertexNormal allocVertexNum:vertexNum andEachVertexNum:3];
    for (int i=0; i<vertexNum; i++) {
        float onevertex[3];
        for (int j=0; j<3; j++) {
            onevertex[j]=[CubeManager getNormalVertexs][i*9+j+3];
        }
        [self.vertexNormal setVertex:onevertex index:i];
    }
    [self.vertexNormal bindBufferWithUsage:GL_STATIC_DRAW];
    [self.vertexNormal enableVertexInVertexAttrib:LightBindAttribLocationNormal numberOfCoordinates:3 attribOffset:0];
    
    GLKVector3 ambientLigh = GLKVector3Make(1.0, 1.0, 1.0);
    //    emerald    0.0215    0.1745    0.0215    0.07568    0.61424    0.07568    0.633    0.727811    0.633    0.6
    
    MaterialObject material;
    material.ambient = GLKVector3Make(1.0f, 0.5f, 0.31f);
    material.diffuse =GLKVector3Make(1.0f, 0.5f, 0.31f);
    material.specular =GLKVector3Make(0.5f, 0.5f, 0.5f);
    material.shininess =0.08988;
    glUniform1fv(self.bindObject->uniforms[MaterialObjectUniformLocationMaterialShininess],1,&material.shininess);
    glUniform3fv(self.bindObject->uniforms[MaterialObjectUniformLocationMaterialDiffuse], 1, &material.diffuse);
    glUniform3fv(self.bindObject->uniforms[MaterialObjectUniformLocationMaterialsSpecular], 1, &material.specular);
    glUniform3fv(self.bindObject->uniforms[MaterialObjectUniformLocationMaterialAmbient], 1, &material.ambient);
    
    
    Light light;
    light.lightPos =  GLKVector3Make(2.0, 0.0,0);
    light.ambient  =GLKVector3Make(0.2,0.2,0.2);
    light.diffuse  =GLKVector3Make(0.5,0.5,0.5);
    light.specular  =GLKVector3Make(1.0,1.0,1.0);

    glUniform3fv(self.bindObject->uniforms[LightUniformLocationLightPos], 1, &light.lightPos);
    glUniform3fv(self.bindObject->uniforms[LightUniformLocationLightsSpecular], 1, &light.specular);
    
}

-(GLKMatrix4)getMVP{
    GLfloat aspectRatio= CGRectGetWidth([UIScreen mainScreen].bounds) / CGRectGetHeight([UIScreen mainScreen].bounds);
    GLKMatrix4 projectionMatrix =
    GLKMatrix4MakePerspective(
                              GLKMathDegreesToRadians(85.0f),
                              aspectRatio,
                              0.1f,
                              20.0f);
    GLKMatrix4 modelviewMatrix =
    GLKMatrix4MakeLookAt(
                         0.0, 0.0, 2.0,   // Eye position
                         0.0, 0.0, 0.0,   // Look-at position
                         0.0, 1.0, 0.0);  // Up direction
    return GLKMatrix4Multiply(projectionMatrix,modelviewMatrix);
}


-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glClearColor(1, 1, 1, 1);
    GLKMatrix4  mvp= [self getMVP];
    static GLfloat angle=0;
    angle ++ ;
//            angle = 45;
    GLKMatrix4 mode =GLKMatrix4MakeRotation(45*M_PI/180, 0, 1, 0);
    
    glUniformMatrix4fv(self.bindObject->uniforms[MVPMatrix], 1, 0,mvp.m);
    glUniformMatrix4fv(self.bindObject->uniforms[LightUniformLocationModel], 1, 0,mode.m);
    bool isSuccess = YES;
    mode = GLKMatrix4InvertAndTranspose(mode,&isSuccess);
    glUniformMatrix4fv(self.bindObject->uniforms[LightUniformLocationInvermodel], 1, 0,mode.m);
    
    GLKVector3 viewPos = GLKVector3Make(.0, 0.0,5.0);
    glUniform3fv(self.bindObject->uniforms[LightUniformLocationviewPos], 1,viewPos.v);
    
    GLfloat timer = angle/10.0;
    GLKVector3 light = GLKVector3Make(sin(timer*2.0),sin( timer*0.7), sin(timer*1.3));
    GLKVector3 diffuseColor = GLKVector3Multiply(light, GLKVector3Make(0.5, 0.5, 0.5));
    GLKVector3 ambientColor = GLKVector3Multiply(light, GLKVector3Make(0.2, 0.2, 0.2));

    glUniform3fv(self.bindObject->uniforms[LightUniformLocationLightDiffuse], 1, &diffuseColor);
    glUniform3fv(self.bindObject->uniforms[LightUniformLocationLightAmbient], 1, &ambientColor);

    [self.vertexPostion drawVertexWithMode:GL_TRIANGLES startVertexIndex:0 numberOfVertices:[CubeManager getNormalVertexNum]];
}



@end


#import "GLBaseViewController.h"

NS_ASSUME_NONNULL_BEGIN

@interface LightTestViewController : GLBaseViewController

@end

NS_ASSUME_NONNULL_END


#import "GLBaseBindObject.h"

NS_ASSUME_NONNULL_BEGIN
typedef enum {
    LightBindAttribLocationBegin = BaseBindLocationEnd,
    LightBindAttribLocationVertexColor,
    LightBindAttribLocationNormal
}LightBindAttribLocation;

typedef union {
    struct {
        BaseBindAttribType baseBindAttrib;
        GLKVector3 vertextColor;
    };
    float t[6];
}LightBindAttrib;

typedef union{
    struct {
        GLKVector3 lightPos;
        GLKVector3 ambient;
        GLKVector3 diffuse;
        GLKVector3 specular;
    };
    float m[12];
}Light;

typedef union{
    struct {
        GLKVector3 ambient;
        GLKVector3 diffuse;
        GLKVector3 specular;
        float shininess;
    };
    float m[10];
}MaterialObject;



typedef enum {
    LightUniformLocationBegin = BaseUniformLocationEnd,
    LightUniformLocationModel,
    LightUniformLocationInvermodel,
    LightUniformLocationviewPos,
    LightUniformLocationLightPos, //
    LightUniformLocationLightAmbient, //材质
    LightUniformLocationLightDiffuse,
    LightUniformLocationLightsSpecular,
    MaterialObjectUniformLocationMaterialAmbient, //材质
    MaterialObjectUniformLocationMaterialDiffuse,
    MaterialObjectUniformLocationMaterialsSpecular,
    MaterialObjectUniformLocationMaterialShininess
}LightUniformLocation;

@interface GLLightBindObject : GLBaseBindObject

@end

NS_ASSUME_NONNULL_END


#import "GLLightBindObject.h"

@implementation GLLightBindObject
-(void)BindAttribLocation:(GLuint)program{
    glBindAttribLocation(program, BeginPosition, "beginPostion");
    glBindAttribLocation(program,LightBindAttribLocationNormal, "aNormal");
}

-(NSString *)getShaderName{
    return @"light";
}
@end

light.fsh

precision mediump float;
uniform vec3 lightPos; ///光源位置
uniform vec3 lightColor; ///光源颜色

uniform vec3 viewPos;

varying lowp vec3 normal;
varying lowp vec3 FragPos;
//varying lowp vec3 vary_vertexColor;

struct Material{
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
    float shininess;
};
uniform Material material;

struct Light{
    vec3 lightPos;
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};
uniform Light light;



void main(){
    // 环境光
  
    vec3 ambient = light.ambient * material.ambient;
    
    // 漫反射
    vec3 norm = normalize(normal);
    vec3 lightDir = normalize(light.lightPos - FragPos);
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = light.diffuse * (diff * material.diffuse);
    
    // 镜面光
    vec3 viewDir = normalize(viewPos - FragPos);
    vec3 reflectDir = reflect(-lightDir, norm);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess*128.0);
    vec3 specular = light.specular * (spec * material.specular);
    
    vec3 result = ambient + diffuse + specular;
    gl_FragColor =vec4(result, 1.0);;
}

light.vsh

precision lowp float;

attribute vec3 beginPostion; ///开始位置
//attribute vec3 vertexColor;
attribute vec3 aNormal; //法向量

uniform mat4 u_mvpMatrix;
uniform mat4 u_model;
uniform mat4  u_inverModel;

varying lowp vec3 normal;
varying lowp vec3 FragPos;


//varying lowp vec3 vary_vertexColor;

void main(){
    gl_Position =u_mvpMatrix *u_model* vec4(beginPostion, 1.0);
//    vary_vertexColor  = vertexColor;
    FragPos = vec3(u_model * vec4(beginPostion, 1.0));
    normal =  mat3(u_inverModel) * aNormal;;
}

以上是核心代码, 可以下载demo查看具体效果

源码地址 对应的demo是OpenGLZeroStudyDemo(7)-光照

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

推荐阅读更多精彩内容