OpenGL应用:天空盒子(SkyBox)

天空盒子(skyBox)

SkyBox 制作3D游戏的一个经典技术应用。

原理

SkyBox 是基于正方体模型的渲染技术。将6个方向拍下来的天空图片分别贴在正方体的对应面上,从内部观察正方体就可以得到一个密闭的天空环境

这是我们skyBox贴图。

可以把它分成上下左右前后六张图,然后创建CubeMap。标准化ModelMatrix矩阵处理后的顶点位置,就可以用来在CubeMap上进行采样了。渲染SkyBox时不需要使用光照模型,直接使用采样CubeMap得到的颜色即可。所以需要为天空盒单独写一个Fragment Shader。

天空盒几何体

首先准备基本的Cube几何体,创建SkyBox类,让它继承Cube类,这样就具备了渲染一个Cube的能力。然后对draw方法进行一些特殊处理。因为需要在内部观察这个Cube,所以需要让这个Cube的正面被裁剪,反面显示出来。 glCullFace(GL_FRONT);正是用来做这件事情。渲染完后还需要将裁减状态回归到裁减背面。

- (void)draw:(GLContext *)glContext {
    glCullFace(GL_FRONT);
    glDepthMask(GL_FALSE);
    [super draw:glContext];
    glDepthMask(GL_TRUE);
    glCullFace(GL_BACK);
}

天空CubeMap

上图中的6张图就是我们用于生成CubeMap的6张图。

- (void)createCubeTexture {
    NSMutableArray *files = [NSMutableArray new];
    for (int i = 0; i < 6; ++i) {
        NSString *filename = [NSString stringWithFormat:@"cube-%d", i + 1];
        NSString *filePath = [[NSBundle mainBundle] pathForResource:filename ofType:@"jpg"];
        [files addObject:filePath];
    }
    NSError *error;
    self.cubeTexture = [GLKTextureLoader cubeMapWithContentsOfFiles:files options:nil error:&error];
}

Fragment Shader

生成采样向量,返回采样结果。

precision highp float;

varying vec2 fragUV;
varying vec3 fragPosition;

uniform samplerCube envMap;
uniform mat4 modelMatrix;
void main(void) {
    vec3 sampleVector = normalize(modelMatrix * vec4(fragPosition, 1.0)).xyz;
    gl_FragColor = textureCube(envMap, sampleVector);
}

 

效果图:

 

 
posted @ 2018-12-25 21:23  _NeverMore  阅读(2377)  评论(0编辑  收藏  举报