opengl高级opengl中的混合这一章
-
最好还是看官网文章
-
OpenGL中,混合(Blending)通常是实现物体透明度(Transparency)的一种技术。透明就是说一个物体(或者其中的一部分)不是纯色(Solid Color)的,它的颜色是物体本身的颜色和它背后其它物体的颜色的不同强度结合。一个有色玻璃窗是一个透明的物体,玻璃有它自己的颜色,但它最终的颜色还包含了玻璃之后所有物体的颜色。这也是混合这一名字的出处,我们混合(Blend)(不同物体的)多种颜色为一种颜色。所以透明度能让我们看穿物体。
-
**丢弃片段:**有些图片并不需要半透明,只需要根据纹理颜色值,显示一部分,或者不显示一部分,没有中间情况。比如说草,如果想不太费劲地创建草这种东西,你需要将一个草的纹理贴在一个2D四边形(Quad)上,然后将这个四边形放到场景中。然而,草的形状和2D四边形的形状并不完全相同,所以你只想显示草纹理的某些部分,而忽略剩下的部分。不希望看到草的方形图像,而是只显示草的部分,并能看透图像其余的部分。我们想要丢弃(Discard)显示纹理中透明部分的片段,不将这些片段存储到颜色缓冲中。
-
加载有alpha值的纹理,我们并不需要改很多东西,stb_image在纹理有alpha通道的时候会自动加载,但我们仍要在纹理生成过程中告诉OpenGL,我们的纹理现在使用alpha通道了:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
- 保证你在片段着色器中获取了纹理的全部4个颜色分量,而不仅仅是RGB分量:
void main()
{
// FragColor = vec4(vec3(texture(texture1, TexCoords)), 1.0);
FragColor = texture(texture1, TexCoords);
}
- 去除白边GLSL给了我们discard命令,一旦被调用,它就会保证片段不会被进一步处理,所以就不会进入颜色缓冲。有了这个指令,我们就能够在片段着色器中检测一个片段的alpha值是否低于某个阈值,如果是的话,则丢弃这个片段,就好像它不存在一样:
主要修改
- 有很多直接看代码库代码即可
- 纹理
- 添加新的图片
- 新的model,将坐标直接放到model里边变量以及变量map;注意这里边一样要给文件函数参数前添加const
glm::mat4 modelMatrix;
glm::vec3 worldPosition;
glm::vec3 modelPos;
//生成map和map迭代器
map<string, Model> _models;
map<string, Model>::iterator _modelsIter;
- 新的frag文件用于加载草的纹理
- 新的mesh函数
- 增加setshader函数避免重复设置
void setShader(Shader* shader)
{
shader->useShader();
shader->setMat4("projection", projection);
shader->setMat4("view", view);
shader->setVec4("lightPos", cubePositions[1].r, cubePositions[1].g, cubePositions[1].b, 1);
shader->setVec3("viewPos", camera.Position.r, camera.Position.g, camera.Position.b);
shader->setVec3("front", camera.Front.r, camera.Front.g, camera.Front.b);
shader->setVec3("lightColor", 1.0f, 1.0f, 1.0f);
}
- 点击之后获得模型的坐标然后再进行混合:倒回到模型坐标modelPos
for (_modelsIter = _models.begin(); _modelsIter != _models.end(); _modelsIter++)
{
float _distance = glm::distance(_modelsIter->second.worldPosition + glm::vec3(0, 7.5, 0), glm::vec3(wolrdPostion));
if (_distance < 7.5)
{
modelPos = glm::inverse(_modelsIter->second.modelMatrix) * wolrdPostion;
modelSelected = _modelsIter->first;
cout << _modelsIter->first << "模型被选中..." << endl;
}
}
- 然后在点击之后进行渲染的时候有一个渲染草
model = glm::translate(model, modelPos);
caoShader.setMat4("model", model);
cao.Draw(caoShader);
- 效果: