openGL系列文章目录

文章目录

  • openGL系列文章目录
  • 前言
  • 一、代码
    • 主程序c++
  • 效果

前言

现在我们扩展法线贴图的概念——从纹理图像用于扰动法向量到扰乱顶点位置本身。实
际上,以这种方式修改对象的几何体具有一定的优势,例如使表面特征沿着对象的边缘可
见,并使特征能够响应阴影贴图。我们将会看到,它还可以帮助构建地形。
一种实用的方法是使用纹理图像来存储高度值,然后使用该高度值来提升(或降低)顶
点位置。含有高度信息的图像称为高度图,使用高度图更改对象的顶点的方法称为高度贴
图①。高度图通常将高度信息编码为灰度颜色:(0,0,0)(黑色)=低高度,(1,1,1)(白色)=
高高度。这样一来通过算法或使用“画图”程序就可以轻松创建高度图。图像的对比度越
高,其表示的高度变化越大。这些概念将在图1(显示随机生成的地图)和图10.13(显
示有组织的模式的地图)中说明。

图1
改变顶点位置是否有用取决于改变的模型。顶点操作可以在顶点着色器中轻松完成,当模型顶点细节级别够高(例如在足够高精度的球体中)时,改变顶点高度的方法效果很好。但是,当模型的顶点数量很少(例如立方体的角)时,渲染对象的表面需要依赖于光栅器中的顶点插值来填充细节。当顶点着色器中可用于改变高度的顶点很少时,许多像素的高度将无法从高度图中检索,而需要由插值生成,从而导致表面细节较差。当然,在片段着色器中是不可能进行顶点操作的,因为这时顶点已被光栅化为像素位置。程序 展示了一个将顶点“向外”(即在表面法向量的方向上)移动的顶点着色器代
码。它通过将顶点法向量乘以从高度图检索所得的值,然后将该乘积与顶点位置相加,以
“向外”移动顶点。

一、代码

主程序c++

#include <GL\glew.h>
#include <GLFW\glfw3.h>
#include <SOIL2\soil2.h>
#include <string>
#include <iostream>
#include <fstream>
#include <glm\gtc\type_ptr.hpp> // glm::value_ptr
#include <glm\gtc\matrix_transform.hpp> // glm::translate, glm::rotate, glm::scale, glm::perspective
#include "ImportedModel.h"
#include "Utils.h"
using namespace std;float toRadians(float degrees) { return (degrees * 2.0f * 3.14159f) / 360.0f; }#define numVAOs 1
#define numVBOs 3float cameraX, cameraY, cameraZ;
float gndLocX, gndLocY, gndLocZ;
GLuint renderingProgram;
GLuint vao[numVAOs];
GLuint vbo[numVBOs];// variable allocation for display
GLuint mvLoc, projLoc;
int width, height;
float aspect;
glm::mat4 pMat, vMat, mMat, mvMat;ImportedModel ground("grid.obj");
int numGroundVertices;GLuint heightMap;
GLuint heightTexture;void setupVertices(void) {numGroundVertices = ground.getNumVertices();std::vector<glm::vec3> vert = ground.getVertices();std::vector<glm::vec2> tex = ground.getTextureCoords();std::vector<glm::vec3> norm = ground.getNormals();std::vector<float> pvalues;std::vector<float> tvalues;std::vector<float> nvalues;for (int i = 0; i < numGroundVertices; i++) {pvalues.push_back((vert[i]).x);pvalues.push_back((vert[i]).y);pvalues.push_back((vert[i]).z);tvalues.push_back((tex[i]).x);tvalues.push_back((tex[i]).y);nvalues.push_back((norm[i]).x);nvalues.push_back((norm[i]).y);nvalues.push_back((norm[i]).z);}glGenVertexArrays(1, vao);glBindVertexArray(vao[0]);glGenBuffers(numVBOs, vbo);glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);glBufferData(GL_ARRAY_BUFFER, pvalues.size() * 4, &pvalues[0], GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);glBufferData(GL_ARRAY_BUFFER, tvalues.size() * 4, &tvalues[0], GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);glBufferData(GL_ARRAY_BUFFER, nvalues.size() * 4, &nvalues[0], GL_STATIC_DRAW);
}void init(GLFWwindow* window) {renderingProgram = Utils::createShaderProgram("vertShader.glsl", "fragShader.glsl");cameraX = 0.03f; cameraY = 0.03f; cameraZ = 0.8f;gndLocX = 0.0f; gndLocY = 0.0f; gndLocZ = 0.0f;glfwGetFramebufferSize(window, &width, &height);aspect = (float)width / (float)height;pMat = glm::perspective(1.0472f, aspect, 0.1f, 1000.0f);setupVertices();heightTexture = Utils::loadTexture("heightTexture.jpg");heightMap = Utils::loadTexture("height.jpg");
}void display(GLFWwindow* window, double currentTime) {glClear(GL_DEPTH_BUFFER_BIT);glClearColor(0.0, 0.0, 0.0, 1.0);glClear(GL_COLOR_BUFFER_BIT);glUseProgram(renderingProgram);mvLoc = glGetUniformLocation(renderingProgram, "mv_matrix");projLoc = glGetUniformLocation(renderingProgram, "proj_matrix");vMat = glm::translate(glm::mat4(1.0f), glm::vec3(-cameraX, -cameraY, -cameraZ));mMat = glm::translate(glm::mat4(1.0f), glm::vec3(gndLocX, gndLocY, gndLocZ));mMat = glm::rotate(mMat, toRadians(15.0f), glm::vec3(1.0f, 0.0f, 0.0f));mvMat = vMat * mMat;glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvMat));glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(pMat));glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);glEnableVertexAttribArray(0);glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);glEnableVertexAttribArray(1);glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0);glEnableVertexAttribArray(2);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, heightTexture);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, heightMap);glEnable(GL_CULL_FACE);glFrontFace(GL_CCW);glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LEQUAL);glDrawArrays(GL_TRIANGLES, 0, numGroundVertices);
}void window_size_callback(GLFWwindow* win, int newWidth, int newHeight) {aspect = (float)newWidth / (float)newHeight;glViewport(0, 0, newWidth, newHeight);pMat = glm::perspective(1.0472f, aspect, 0.1f, 1000.0f);
}int main(void) {if (!glfwInit()) { exit(EXIT_FAILURE); }glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);GLFWwindow* window = glfwCreateWindow(800, 800, "Chapter10 - program4a", NULL, NULL);glfwMakeContextCurrent(window);if (glewInit() != GLEW_OK) { exit(EXIT_FAILURE); }glfwSwapInterval(1);glfwSetWindowSizeCallback(window, window_size_callback);init(window);while (!glfwWindowShouldClose(window)) {display(window, glfwGetTime());glfwSwapBuffers(window);glfwPollEvents();}glfwDestroyWindow(window);glfwTerminate();exit(EXIT_SUCCESS);
}

## 2.着色器程序
顶点着色器```cpp
#version 430layout (location=0) in vec3 vertPos;
layout (location=1) in vec2 texCoord;
layout (location=2) in vec3 vertNormal;out vec2 tc;uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
layout (binding=0) uniform sampler2D t;    // for texture
layout (binding=1) uniform sampler2D h;    // for height mapvoid main(void)
{   vec4 p = vec4(vertPos,1.0) + vec4((vertNormal*((texture(h, texCoord).r)/5.0f)),1.0f);tc = texCoord;gl_Position = proj_matrix * mv_matrix * p;
}

2.片元着色器

#version 430in vec2 tc;
out vec4 fragColor;uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
layout (binding=0) uniform sampler2D t;    // for texture
layout (binding=1) uniform sampler2D h;    // for height mapvoid main(void)
{   fragColor = texture(t, tc);
}

效果

openGL增强表面细节----高度贴图相关推荐

  1. openGL增强表面细节--凹凸贴图

    openGL系列文章目录 文章目录 openGL系列文章目录 前言 一.凹凸贴图 二.代码 1.主程序c++ 总结 前言 假设我们想要对不规则表面的物体进行建模,例如橘子凹凸的表皮.葡萄干褶皱的表面 ...

  2. openGL增强表面细节--凹凸贴图具体实现

    openGL系列文章目录 文章目录 openGL系列文章目录 前言 一.凹凸贴图 二.代码 1.主程序c++ 2.着色器程序 运行效果 源码下载 前言 假设我们想要对不规则表面的物体进行建模,例如橘子 ...

  3. OpenGL基础49:高度贴图(下)

    接上文:OpenGL基础48:高度贴图(上) 四.陡峭视差映射 上文计算纹理偏移的方法是最简单的,但问题也比较大:当你斜视贴图的时候可以看到非常明显的错误 这里有另一种方法,这种方法类似于找连续函数在 ...

  4. Android+JNI+OpenGL开发自己的美图秀秀

    https://blog.csdn.net/oshunz/article/details/50537631 Android+JNI+OpenGL开发自己的美图秀秀 2016年01月18日 16:39: ...

  5. OpenGL shadow mapping 阴影贴图的实例

    OpenGL shadow mapping 阴影贴图 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <glad/glad.h> #i ...

  6. OpenGL shader normals法线贴图的实例

    OpenGL shader normals法线贴图 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <glad/glad.h> #in ...

  7. OpenGL Cube Map立方体贴图的实例

    OpenGL Shadow Mapping阴影贴图 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include "vermilion.h" ...

  8. OpenGL Shadow Mapping阴影贴图的实例

    OpenGL Shadow Mapping阴影贴图 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include "vapp.h" #inc ...

  9. OpenGL equirectangular等矩形环境图的实例

    OpenGL equirectangular等矩形环境图 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <vmath.h> #inc ...

最新文章

  1. 2021年春季学期-信号与系统-第十次作业参考答案-第二小题
  2. 多返回值函数的编写方法
  3. linux route命令的使用详解(转)
  4. 高效程序员的45个习惯 pdf_如何培养孩子高效学习?养成高效学习的7 个习惯。建议收藏...
  5. frame跨页传值/AJAX出错解决方案 + 知识补充:浏览器同源政策
  6. BZOJ 1015 题解
  7. Java中int为什么占四个字节?
  8. docker-compose学习
  9. android状态栏自定义,如何自定义Android状态栏颜色
  10. 仿IBM首页焦点图,缩略图大图,带文字
  11. 用python实现计算器功能_Python实现的计算器功能示例
  12. 晶体管放大电路基础——共射放大电路分析
  13. 论如何做好IE和Chrome互殴时的一条好池鱼之事件绑定篇
  14. 算法 | 八皇后问题
  15. 正则表达式中问号(?)的用法详解
  16. 西门子PLC 冷启动、暖启动、热启动的一种通俗解释
  17. 用计算机画有常数的函数图像,信息技术应用 用计算机画函数图象ppt配用优秀获奖教案...
  18. NameError: name 'mnist' is not defined
  19. Binary Particle Swarm Optimization(BPSO) for Feature Selection(二进制粒子群求解特征选择)
  20. nginx 上传文件大小限制

热门文章

  1. 计算机技术发展迅速的原因,飞速发展的计算机技术,你知道它的历史源流吗?...
  2. html切换导航不同页面,HTML按钮:导航到其他页面 - 不同的方法
  3. 足球竞赛规则的部分补充说明
  4. 写给认真学习却进步缓慢的大一学生
  5. 2021年年度总结(记录一下自己大学期间吧)
  6. 对于电脑命令你了解多少?电脑命令大全
  7. 链家数据分析(社招),骗局???
  8. Android adb.exe程序启动不起来 具体解决方法
  9. 1.PSTN与VoIP基础
  10. 商标销售可以是有利可图的业务