在 OpenGL基础13:第一个正方体 中给正方体加了箱子的纹理,但是在后面介绍光照的时候又把纹理属性给丢了,现在尝试在有纹理的基础之上增加光照

一、漫反射贴图

先把之前的纹理加回去

顶点着色器和主代码的处理和之前 OpenGL基础9:纹理 纹理这一章一样,而对于片段着色器,需要进行稍加修改

在 OpenGL基础21:材质 这一章里,给予了物体材质属性,包括:

  • ambient:定义了在环境光照下这个物体反射的是什么颜色,通常是和物体颜色相同的颜色
  • diffuse:定义了在漫反射光照下物体的颜色,通常是和物体颜色相同的颜色
  • specular:设置的是物体受到的镜面光照影响的颜色,或者是反射一个物体特定的镜面高光颜色(暂时不考虑)
  • shininess:反光度,值越高,反射光的能力越强,散射得越少,高光点越小(暂时不考虑)

但是,一个物体自身作为一个整体为其拥有一个材质其实是有问题的,例如一辆汽车,轮胎和车窗的材质明显不同,也就是说,对于物体的不同部分,可能会拥有不同的 ambient 和 diffuse 属性

因此,这就需要通过某种方式对每个原始像素独立设置diffuse颜色,这其实就是之前的一直在用的纹理,只不过在这中场景和需求下,我们叫它贴图

用一张图片覆盖住物体,以便我们为每个原始像素索引独立颜色值。在光照场景中,通过纹理来呈现一个物体的diffuse颜色,这个做法被称做漫反射贴图(Diffuse texture)

这样的话,在片段着色器中,原先的 ambient 和 diffuse 属性就要用 diffuse 贴图替代(之所以这两个属性都用 diffuse 是因为大部分情况下,这两者的值是等同的),如下:

#version 330 core
struct Material
{sampler2D diffuse;      //贴图vec3 specular;          //镜面光色float shininess;        //反光度
};
struct Light
{vec3 position;vec3 ambient;vec3 diffuse;vec3 specular;
};
uniform Material material;
uniform Light light;
out vec4 color;
uniform vec3 viewPos;
in vec2 texIn;
in vec3 fragPosIn;
in vec3 normalIn;
void main()
{//环境光vec3 ambient = light.ambient * vec3(texture(material.diffuse, texIn));//漫反射光vec3 norm = normalize(normalIn);vec3 lightDir = normalize(light.position - fragPosIn);float diff = max(dot(norm, lightDir), 0.0f);vec3 diffuse = light.diffuse * (diff * vec3(texture(material.diffuse, texIn)));//镜面光vec3 viewDir = normalize(viewPos - fragPosIn);vec3 reflectDir = reflect(-lightDir, norm);float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);vec3 specular = light.specular * (spec * material.specular);//混合vec3 result = ambient + diffuse + specular;color = vec4(result, 1.0f);
}

好了,效果有了!

如果仔细从各个角度看,会发现一块木箱子居然还会有镜面高光,这不科学,这时可以把 specular 设置为 vec(0.0) 来修正

二、镜面贴图采样

上面的箱子还是非常容易的,因为它有一个特点:每个部分都拥有几乎一致的 diffuse 属性,并且 specular 属性都为 vec(0.0),那么问题来了,假设这个时候我们想要给箱子加一个金属边框要怎么处理?要知道金属拥有较高的反射度,和橡木材质正好相反,如果说只用单独的一个带金属边框的木箱纹理,那肯定也是有问题的,所以这个时候就需要2张纹理贴图:一张为带金属边框的橡木纹理,一张为单纯金属边框纹理

如下,一个 specular 高光的亮度可以通过图片中每个纹理的亮度来获得,可以使用这两张纹理作为漫反射贴图和镜面贴图(来源:https://learnopengl.com/#!Lighting/Lighting-maps)

specular 贴图的每个像素可以显示为一个颜色向量,可以看出,这张纹理中间是一片黑,这也意味着中间部分是露出来的木头材质,在此 specular 属性即对应像素颜色属性正是 vec(0.0)

使用Photoshop或Gimp之类的工具,通过将图片进行裁剪,将某部分调整成黑白图样,并调整亮度/对比度的做法,可以非常容易将一个diffuse纹理贴图处理为specular贴图,这样的贴图最好为黑白

有了上面的经验,就知道怎么修改代码逻辑了:

#version 330 core
struct Material
{sampler2D diffuse;      //贴图sampler2D specular;     //镜面贴图float shininess;        //反光度
};
struct Light
{vec3 position;vec3 ambient;vec3 diffuse;vec3 specular;
};
uniform Material material;
uniform Light light;
out vec4 color;
uniform vec3 viewPos;
in vec2 texIn;
in vec3 fragPosIn;
in vec3 normalIn;
void main()
{//环境光vec3 ambient = light.ambient * vec3(texture(material.diffuse, texIn));//漫反射光vec3 norm = normalize(normalIn);vec3 lightDir = normalize(light.position - fragPosIn);float diff = max(dot(norm, lightDir), 0.0f);vec3 diffuse = light.diffuse * (diff * vec3(texture(material.diffuse, texIn)));//镜面光vec3 viewDir = normalize(viewPos - fragPosIn);vec3 reflectDir = reflect(-lightDir, norm);float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);vec3 specular = light.specular * (spec * vec3(texture(material.specular, texIn)));//混合vec3 result = ambient + diffuse + specular;color = vec4(result, 1.0f);
}

效果如下:

三、放射光贴图

上面使用了漫反射贴图和镜面贴图,物体已经有点真实的感觉了,后面还有法线贴图和反射贴图,可以给物体更完美的细节,只是这里就暂时不讲了

这里可以再提一个非常简单的贴图:放射光贴图,先上整篇文章的完整代码和效果,非常容易

#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 texture;
out vec2 texIn;
out vec3 normalIn;
out vec3 fragPosIn;
uniform mat4 model;             //模型矩阵
uniform mat4 view;              //观察矩阵
uniform mat4 projection;        //投影矩阵
void main()
{gl_Position = projection * view * model * vec4(position, 1.0);texIn = vec2(texture.x, 1.0f - texture.y);fragPosIn = vec3(model * vec4(position, 1.0f));normalIn = mat3(transpose(inverse(model))) * normal;
}//#version 330 core
struct Material
{sampler2D diffuse;      //贴图sampler2D specular;     //镜面贴图sampler2D emission;     //放射贴图float shininess;        //反光度
};
struct Light
{vec3 position;vec3 ambient;vec3 diffuse;vec3 specular;
};
uniform Material material;
uniform Light light;
out vec4 color;
uniform vec3 viewPos;
in vec2 texIn;
in vec3 fragPosIn;
in vec3 normalIn;
void main()
{//环境光vec3 ambient = light.ambient * vec3(texture(material.diffuse, texIn));//漫反射光vec3 norm = normalize(normalIn);vec3 lightDir = normalize(light.position - fragPosIn);float diff = max(dot(norm, lightDir), 0.0f);vec3 diffuse = light.diffuse * (diff * vec3(texture(material.diffuse, texIn)));//镜面光vec3 viewDir = normalize(viewPos - fragPosIn);vec3 reflectDir = reflect(-lightDir, norm);float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);vec3 specular = light.specular * (spec * vec3(texture(material.specular, texIn)));//放射光贴图vec3 emission = vec3(texture(material.emission, texIn));//混合vec3 result = ambient + diffuse + specular + emission;color = vec4(result, 1.0f);
}

main.cpp:

#include<iostream>
#include<opengl/glew.h>
#define GLEW_STATIC
#include<GLFW/glfw3.h>
#include"Camera.h"
#include<glm/glm.hpp>
#include<glm/gtc/matrix_transform.hpp>
#include<glm/gtc/type_ptr.hpp>
#include"Shader.h"
#include<opengl/freeglut.h>
#include<SOIL.h>bool keys[1024];
Camera camera;
GLfloat lastX, lastY;
bool firstMouse = true;
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
void cameraMove();
glm::vec3 lightPos(1.2f, 1.0f, 2.0f);
const GLuint WIDTH = 800, HEIGHT = 600;int main()
{glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr);glfwMakeContextCurrent(window);glfwSetKeyCallback(window, key_callback);glfwSetCursorPosCallback(window, mouse_callback);glfwSetScrollCallback(window, scroll_callback);glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);glewExperimental = GL_TRUE;glewInit();int width, height;glfwGetFramebufferSize(window, &width, &height);glViewport(0, 0, width, height);Shader shaderObj("ObjVShader.txt", "ObjFShader.txt");Shader shaderLight("LightVShader.txt", "LightFShader.txt");GLfloat vertices[] = {-0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f,  0.0f,0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f,  0.0f,0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f,  1.0f,0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f,  1.0f,-0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f,  1.0f,-0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f,  0.0f,-0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  0.0f,  0.0f,0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  1.0f,  0.0f,0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  1.0f,  1.0f,0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  1.0f,  1.0f,-0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  0.0f,  1.0f,-0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  0.0f,  0.0f,-0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f,  0.0f,-0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  1.0f,  1.0f,-0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f,  1.0f,-0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f,  1.0f,-0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  0.0f,  0.0f,-0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f,  0.0f,0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f,  0.0f,0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  1.0f,  1.0f,0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f,  1.0f,0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f,  1.0f,0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  0.0f,  0.0f,0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f,  0.0f,-0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f,  1.0f,0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  1.0f,  1.0f,0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f,  0.0f,0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f,  0.0f,-0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  0.0f,  0.0f,-0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f,  1.0f,-0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f,  1.0f,0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  1.0f,  1.0f,0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f,  0.0f,0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f,  0.0f,-0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  0.0f,  0.0f,-0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f,  1.0f};GLuint VBO, VAO, textureA, textureB, textureC;glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);glEnableVertexAttribArray(0);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));glEnableVertexAttribArray(1);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));glEnableVertexAttribArray(2);int picWidth, picHeight;glGenTextures(1, &textureA);glBindTexture(GL_TEXTURE_2D, textureA);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);unsigned char* image = SOIL_load_image("Texture/wood2.jpg", &picWidth, &picHeight, 0, SOIL_LOAD_RGB);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, picWidth, picHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, image);glGenerateMipmap(GL_TEXTURE_2D);SOIL_free_image_data(image);glGenTextures(1, &textureB);glBindTexture(GL_TEXTURE_2D, textureB);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);image = SOIL_load_image("Texture/specular.jpg", &picWidth, &picHeight, 0, SOIL_LOAD_RGB);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, picWidth, picHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, image);glGenerateMipmap(GL_TEXTURE_2D);SOIL_free_image_data(image);glGenTextures(1, &textureC);glBindTexture(GL_TEXTURE_2D, textureC);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);image = SOIL_load_image("Texture/cloudImg.jpg", &picWidth, &picHeight, 0, SOIL_LOAD_RGB);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, picWidth, picHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, image);glGenerateMipmap(GL_TEXTURE_2D);SOIL_free_image_data(image);glBindTexture(GL_TEXTURE_2D, 0);shaderObj.Use();glUniform1i(glGetUniformLocation(shaderObj.Program, "material.diffuse"), 0);glUniform1i(glGetUniformLocation(shaderObj.Program, "material.specular"), 1);glUniform1i(glGetUniformLocation(shaderObj.Program, "material.emission"), 2);GLuint lightVAO;glGenVertexArrays(1, &lightVAO);glBindVertexArray(lightVAO);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);//VBO数据已经绑定且我们就用之前的顶点数据,所以无需再管理VBOglEnableVertexAttribArray(0);glBindBuffer(GL_ARRAY_BUFFER, 0);glBindVertexArray(0);glEnable(GL_DEPTH_TEST);while (!glfwWindowShouldClose(window)){glfwPollEvents();glClearColor(0.0f, 0.0f, 0.0f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);glClear(GL_DEPTH_BUFFER_BIT);cameraMove();shaderLight.Use();lightPos.x = 1.0f + sin(glfwGetTime()) * 2.0f;lightPos.y = sin(glfwGetTime() / 2.0f) * 1.0f;glm::mat4 view = camera.GetViewMatrix();glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f);glm::mat4 model = glm::translate(glm::mat4(1.0f), lightPos);model = glm::scale(model, glm::vec3(0.2f));GLint modelLoc = glGetUniformLocation(shaderLight.Program, "model");GLint viewLoc = glGetUniformLocation(shaderLight.Program, "view");GLint projLoc = glGetUniformLocation(shaderLight.Program, "projection");glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));glBindVertexArray(lightVAO);glDrawArrays(GL_TRIANGLES, 0, 36);shaderObj.Use();glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, textureA);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, textureB);glActiveTexture(GL_TEXTURE2);glBindTexture(GL_TEXTURE_2D, textureC);GLint matSpecularLoc = glGetUniformLocation(shaderObj.Program, "material.specular");GLint matShineLoc = glGetUniformLocation(shaderObj.Program, "material.shininess");glUniform3f(matSpecularLoc, 0.0f, 0.0f, 0.0f);glUniform1f(matShineLoc, 32.0f);GLint lightPosLoc = glGetUniformLocation(shaderObj.Program, "light.position");GLint lightAmbientLoc = glGetUniformLocation(shaderObj.Program, "light.ambient");GLint lightDiffuseLoc = glGetUniformLocation(shaderObj.Program, "light.diffuse");GLint lightSpecularLoc = glGetUniformLocation(shaderObj.Program, "light.specular");glUniform3f(lightAmbientLoc, 0.2f, 0.2f, 0.2f);glUniform3f(lightDiffuseLoc, 1.0f, 1.0f, 1.0f);glUniform3f(lightSpecularLoc, 1.0f, 1.0f, 1.0f);glUniform3f(lightPosLoc, lightPos.x, lightPos.y, lightPos.z);GLint viewPosLoc = glGetUniformLocation(shaderObj.Program, "viewPos");glUniform3f(viewPosLoc, camera.Position.x, camera.Position.y, camera.Position.z);model = glm::mat4(1.0f);model = glm::rotate(model, glm::radians(57.0f), glm::vec3(-0.5f, 1.0f, 0.0f));modelLoc = glGetUniformLocation(shaderObj.Program, "model");viewLoc = glGetUniformLocation(shaderObj.Program, "view");projLoc = glGetUniformLocation(shaderObj.Program, "projection");glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));glBindVertexArray(VAO);glDrawArrays(GL_TRIANGLES, 0, 36);glBindVertexArray(0);glfwSwapBuffers(window);}glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glfwTerminate();return 0;
}GLfloat deltaTime = 0.0f;
GLfloat lastFrame = 0.0f;
void cameraMove()
{GLfloat currentFrame = glfwGetTime();deltaTime = currentFrame - lastFrame;lastFrame = currentFrame;GLfloat cameraSpeed = 1.0f * deltaTime;if (keys[GLFW_KEY_W])camera.ProcessKeyboard(Camera_Movement(FORWARD), deltaTime);if (keys[GLFW_KEY_S])camera.ProcessKeyboard(Camera_Movement(BACKWARD), deltaTime);if (keys[GLFW_KEY_A])camera.ProcessKeyboard(Camera_Movement(LEFT), deltaTime);if (keys[GLFW_KEY_D])camera.ProcessKeyboard(Camera_Movement(RIGHT), deltaTime);
}void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)glfwSetWindowShouldClose(window, GL_TRUE);if (action == GLFW_PRESS)           //如果当前是按下操作keys[key] = true;else if (action == GLFW_RELEASE)            //松开键盘keys[key] = false;
}void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{camera.ProcessMouseScroll(yoffset);
}void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{if (firstMouse){lastX = xpos;lastY = ypos;firstMouse = false;}GLfloat xoffset = xpos - lastX;GLfloat yoffset = lastY - ypos;lastX = xpos;lastY = ypos;GLfloat sensitivity = 0.05;xoffset *= sensitivity;yoffset *= sensitivity;camera.ProcessMouseMovement(xoffset, yoffset);
}

可以看到,箱子的每个面上都有被贴上了一块无视光照的“云彩”,这就是放射光贴图,顾名思义,它往往是用来显示物体自身发光(Emit)时可能产生的颜色,例如游戏中宝箱上发光的按钮,楼梯间紧急出口牌子亮的绿光等等

OpenGL基础22:贴图相关推荐

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

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

  2. OpenGL基础45:光照矫正(下)之Gamma校正

    接上文:OpenGL基础44:光照矫正(上) 四.Gamma矫正 4.1.人的视觉特性 和很多错视图一样,对于下面这张灰阶图,如果1表示纯白,0表示纯黑,那么这张图片的哪个位置代表的是0.5,也就是自 ...

  3. OpenGL基础23:平行光与点光源

    前面几章主要是针对物体,现在开始针对光源! 一.平行光 在 OpenGL基础18:光照基础 这一章里面讲了几种常见光源,先看平行光吧 一个很好的例子就是太阳光,因为离我们的距离过远,所以太阳光的特点就 ...

  4. OpenGL: 基础篇

    本人水平有限,如有问题请以文章形式提出,大家可以讨论吗... [OPENGL怎么用] OPENGL编程类似C编程,实际接口就是C,所以熟悉C是必要的 一般编程可用到的函数库包括: OPENGL实用库: ...

  5. OpenGL基础知识介绍和简单使用

    OpenGL基础知识介绍 OpenGL简介 OpenGL 专业词解析 1.OpenGL上下文[context] 2.渲染 3.顶点数组和顶点缓冲区 4.着色器程序Shader 5.顶点着色器(Vert ...

  6. opengl基础学习专题 (二) 点直线和多边形

    题外话 随着学习的增长,越来越觉得自己很水.关于上一篇博文中推荐用一个 学习opengl的 基于VS2015的 simplec框架.存在 一些问题. 1.这个框架基于VS 的Debug 模式下,没有考 ...

  7. OpenGL 基础光照ColorsBasic Lighting

    OpenGL 基础光照ColorsBasic Lighting 基础光照ColorsBasic Lighting简介 环境光照 漫反射光照 法向量 计算漫反射光照 最后一件事 镜面光照 基础光照Col ...

  8. [转]OpenGL基础技术讲座--发展历史

    OpenGL基础技术讲座--发展历史 第一讲 OpenGL 的发展历史 人们对三维图形技术的研究已经经历了一个很长的历程,而且涌现了许多三维图形开发工具,其中SGI公司推出的GL(Graphics L ...

  9. [.net 面向对象编程基础] (22) 事件

    [.net 面向对象编程基础] (22)  事件 事件(Event)是学习.net面向对象编程很重要的一部分,在学习事件之前,我们实际上已经在很多地方使用了事件,比如控件的click事件等,这些都是. ...

最新文章

  1. 正则不等于一个字符串_更正一个观念:“积食”不等于“吃多了”
  2. 锁究竟锁住的是什么?
  3. EAGER的获取是代码的味道
  4. 【洛谷 - P1772 】[ZJOI2006]物流运输(dp)
  5. 程序员,你怎么这么忙?为什么天天熬夜加班?
  6. 大象喝水(信息学奥赛一本通-T1032)
  7. 天燃气与电热水器哪个用着成本低?
  8. java 表格树_00030-layui+java 树形表格treeTable
  9. Atitit.atiDataStoreService   v2 新特性
  10. VB2010(29)Web部署应用程序
  11. DH 算法迪菲-赫尔曼算法QUIC协议和HTTP3.0
  12. Theano入门神经网络(三)
  13. oracle中if语句用法,Oracle IF语句的使用 | 学步园
  14. 读书:在别人的盯梢儿和嚼舌根中茁壮成长 | 杂谈
  15. InsecureProgramming-master——abo4
  16. u8系统更改了服务器,用友u8服务器地址修改
  17. Word转图片(使用Spire.doc)
  18. 经典Bug永流传---每周一“虫”(九)
  19. android输入法服务,Android调用系统输入法
  20. pad 锁定屏幕显示方向为竖屏正方向

热门文章

  1. python表白代码-如何用Python代码向心爱的姑娘花式表白?
  2. python自动化办公真的好用吗-Python做什么更合适?|老男孩Python自动化运维
  3. linux系统怎么刷新,Fedora Linux如何更新系统
  4. oracle配置ipv6_配置 IPv6 接口
  5. httpclient java 异步_Java的异步HttpClient
  6. java sort类_JAVA Collections工具类sort()排序方法
  7. 【动态规划】01背包问题:购物袋
  8. 【linux】常用网络操作
  9. 2014——我们都任性过
  10. 怎么看linux的命令说明,在linux下,怎么用命令来查看版本?