天空盒

天空盒Get知识点:

  • 1、立方体贴图是和其它纹理一样的,所以如果想创建一个立方体贴图的话,我们需要生成一个纹理,并将其绑定到纹理目标上,之后再做其它的纹理操作。这次要绑定到GL_TEXTURE_CUBE_MAP:
unsigned int textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);

因为立方体贴图包含有6个纹理,每个面一个,我们需要调用glTexImage2D函数6次,参数和之前教程中很类似。但这一次我们将纹理目标(target)参数设置为立方体贴图的一个特定的面,告诉OpenGL我们在对立方体贴图的哪一个面创建纹理。这就意味着我们需要对立方体贴图的每一个面都调用一次glTexImage2D。

 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 
        0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);

设定它的环绕和过滤方式:

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);
  • 2.1、天空盒绘制优化:
    先渲染天空盒,之后再渲染场景中的其它物体。这样子能够工作,但不是非常高效。如果我们先渲染天空盒,我们就会对屏幕上的每一个像素运行一遍片段着色器,即便只有一小部分的天空盒最终是可见的。可以使用提前深度测试.所以,最后渲染天空盒,以获得轻微的性能提升。这样子的话,深度缓冲就会填充满所有物体的深度值了,我们只需要在提前深度测试通过的地方渲染天空盒的片段就可以了,很大程度上减少了片段着色器的调用.

  • 2.2、天空盒顶点着色器:

attribute vec3 aPos;

uniform mat4 projectionM;
uniform mat4 modelViewM;

varying lowp vec3 outTextCoord;

void main(){

    outTextCoord = aPos;
    vec4 pos = projectionM * modelViewM * vec4(aPos,1.0);
    //gl_Position = pos.xyww; //透视除法的应用
    //需要通过多边形偏移解决 边界闪烁的问题 (下面那个0.99是可以不乘的,而直接使用gl_Position = pos.xyww;),再查一下
    gl_Position =  vec4(pos.x,pos.y,pos.w*0.99,pos.w);
    
}
  • 3、天空盒片段着色器:

varying lowp vec3 outTextCoord;

uniform samplerCube boxTexture;

void main(){
    
    //gl_FragColor = vec4(0.2,0.2,0.3,1.0);
    gl_FragColor = textureCube(boxTexture,outTextCoord);
}
  • 4、纹理加载:
#pragma mark - cubeShafer
+(GLuint)loadCubeTextureWithImageNames:(NSArray*)fileNames
{
    //glActiveTexture(tex);
       GLuint textId ;
       glGenTextures(1, &textId);
       //绑定纹理
       glBindTexture(GL_TEXTURE_CUBE_MAP, textId);
    [self glCheckError];
    
    for (int i = 0; i < fileNames.count; ++i) {
        NSString* fileName = fileNames[I];
        size_t width,height;
        GLubyte *spriteData = [self getImageData:fileName width:&width height:&height];
        float fw = width,fh = height;
        if (spriteData) {
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X +i , 0, GL_RGBA, fw, fh, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
            //绑定纹理
            //glBindTexture(GL_TEXTURE_2D, 0);
            free(spriteData);
        } else {
            NSLog(@"立方体纹理加载错误---- ");
        }
    }
    [self glCheckError];
    
    //设置纹理的相关参数
    //参数不记得的同学,可以回顾一下OpenGL中的纹理课程
    //放大过滤器,缩小过滤器
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_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);
    [self glCheckError];
    return textId;
}
  • 5、绘制
- (void)draw{
    glViewport(0, 0, _viewWidth,_viewHeight);
    glUseProgram(self.myProgram);

//先绘制盒子  填充深度缓冲区 
    glBindVertexArray(self.blackBoxVAO);
    glBindTexture(GL_TEXTURE_2D, self.textId);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);
    [ZKLodaShader glCheckError];
    
//再绘制天空盒  判断天空盒的深度缓冲区小于等于 当前深度缓冲区值,才比较通过。 
//结果就是天空盒只会在没有可见物体的地方渲染了(只有这样才能通过深度测试,其它所有的东西都在天空盒前面)
    glDepthFunc(GL_LEQUAL);
    glPolygonOffset(1.0, 1.0);
    glUseProgram(self.skyBoxProgram);
    glBindVertexArray(self.VAO);
    glBindTexture(GL_TEXTURE_CUBE_MAP, self.cubemapTexture);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);
    [ZKLodaShader glCheckError];
    glDepthFunc(GL_LESS);
    
    if (_myColorRenderBuffer) {
        glBindRenderbuffer(GL_RENDERBUFFER, _myColorRenderBuffer);
    }
    //绘制
    [self.myContext presentRenderbuffer:GL_RENDERBUFFER];
    
    glDeleteVertexArrays(1,&_VAO);
    glDeleteVertexArrays(1, &_blackBoxVAO);
}
  • 6、效果


    天空盒.gif

反射

折射

这两个等哪天心情好了在写,又懒了,这样不好_

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

推荐阅读更多精彩内容