Learn OpenGL 笔记5.6 Cubemaps(立方体贴图)

立方体贴图。就是多个texture纹理,对应到一个立方体之上。

 

要把多个贴图合并成一个,再赋值给cube,因为立方体贴图有一个有用的特性,它们可以使用方向向量进行索引/采样

 只要提供了方向,OpenGL 就会检索该方向(最终)命中的相应纹素并返回正确采样的纹理值。

 基础知识:

1.Creating a cubemap (创建一个立方体Map)

int width, height, nrChannels;
unsigned char *data;  
for(unsigned int i = 0; i < textures_faces.size(); i++)
{
    data = stbi_load(textures_faces[i].c_str(), &width, &height, &nrChannels, 0);
    glTexImage2D(
        //这个参数代表要渲染的面的方向,这些方向的enum参数是逐个增加的
        GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 
        0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data
    );
}

 wrapping and filtering 包裹和采样

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代表三维,一维:S 二维:T 三维:R

使用方法:

//一个方向向量,代表投射在方块表面的那个texture的点
in vec3 textureDir; // direction vector representing a 3D texture coordinate
uniform samplerCube cubemap; // cubemap texture sampler

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

2.Skybox(天空盒)

 天空盒是一个(大)立方体,它包含整个场景并包含周围环境的 6 个图像,让玩家产生一种错觉,即他所处的环境实际上比实际大得多。

 

如果你将这 6 个边折叠成一个立方体,你会得到一个完全有纹理的立方体,它模拟了一个大景观。

去除天空盒的平移,只留下旋转:(原理是transform平移变换的参数是在变换矩阵的第四列里面,把变化矩阵缩减成3x3,然后再扩充,多余部分补0,就去掉了平移变换了)

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

  具体可以看之前的笔记2.7。

3.Skybox optimization(天空盒的一些配置)

3.1 需要进行早期深度测试,防止天空盒无效渲染给fragment造成压力

3.2 天空盒只是一个 1x1x1 的立方体,很可能会在所有其他对象之上渲染,通过大多数深度测试。需要手动把天空盒的深度设置为最大深度1.0

 设置方法:

void main()
{
    TexCoords = aPos;
    vec4 pos = projection * view * vec4(aPos, 1.0);
    //核心是这一句,把z设置成w,这样透视划分的时候,深度值depth=z/w变成了1.0
    gl_Position = pos.xyww;
}  

3.3 我们必须通过将深度函数设置为 GL_LEQUAL 而不是默认的 GL_LESS 来更改深度函数。

 (防止有物品深度和天空盒相等?此时也让物品覆盖天空盒?)

4.Environment mapping(环境贴图)

使用带有环境的立方体贴图,我们可以赋予物体反射或折射特性。 使用像这样的环境立方体贴图的技术称为Environment mapping环境贴图技术,两种最流行的技术是reflection and refraction反射和折射。 

 4.1 Reflection (反射)

反射是物体(或物体的一部分)反射其周围环境的属性。

计算出一个reflection vector反射向量,然后用这个向量对cubemap进行采样。

R:反射向cubemap的向量

N:法线向量

I:观察者向量

FS解析


#version 330 core
out vec4 FragColor;

in vec3 Normal;
in vec3 Position;

uniform vec3 cameraPos;
uniform samplerCube skybox;

void main()
{             
    //计算视角向量
    vec3 I = normalize(Position - cameraPos);
    //用内置函数reflect计算出反射向量
    vec3 R = reflect(I, normalize(Normal));
    //利用反射向量对cubemap进行采样
    FragColor = vec4(texture(skybox, R).rgb, 1.0);
}

实际上大多数模型并不是完全反射的。 例如,我们可以引入reflection maps 反射贴图,为模型提供另一个额外的细节层次。

 5.Refraction(折射)

折射是由于光流过的材料发生变化而引起的光方向的变化。 折射是我们通常在类似水的表面上看到的,其中光线不会直接进入,而是稍微弯曲

 

 refractive indices 折射率:

 FS解析:

void main()
{             
    float ratio = 1.00 / 1.52;
    vec3 I = normalize(Position - cameraPos);
    //使用内置的折射函数,根据入射向量,以及折射率,算出折射的向量
    vec3 R = refract(I, normalize(Normal), ratio);
    //根据折射向量算出天空盒的对应fragment
    FragColor = vec4(texture(skybox, R).rgb, 1.0);
}  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值