(本文是LearnOpenGL的学习笔记, 教程中文翻译地址https://learnopengl-cn.github.io/(备用地址https://learnopengl-cn.readthedocs.io/zh/latest/),写于 2021-10-2)

0.前言

上一节学习了材质和光照贴图(https://gongjianbo1992.blog.csdn.net/article/details/120397134),教程接下来讲了投光物和多光源。

1.知识点

投光物就是在基础光照的内容上进行扩展,之前的光照都是拟定一个点,现实世界中,我们有很多种类的光照,每种的表现都不同。将光投射(Cast)到物体的光源叫做投光物(Light Caster)。教程讲了三种投光物:定向光(Directional Light),点光源(Point Light),聚光(Spotlight)。

平行光:当一个光源处于很远的地方时,来自光源的每条光线就会近似于互相平行。(相对于之前基础光照的点光源,简化了光照方向的计算,只需要固定值,而不是计算光源指向物体表面顶点的向量)

点光源:前面基础光照用的就是点光源,某个点的光源朝着所有方向散射光线。只是前面课程没有进行衰减模拟计算,距离越远光照强度越弱。

聚光:聚光是位于环境中某个位置的光源,它只朝一个特定方向而不是所有方向照射光线(手电筒/聚光灯的效果)。相当于以一个方向为基准,夹角超过一定就不进行光照计算。

2.实现代码

(项目git链接:https://github.com/gongjianbo/OpenGLwithQtWidgets.git)

多光源实现效果:

#pragma once
#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>
#include <QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
#include <QOpenGLTexture>
#include <QVector3D>
#include <QMatrix4x4>
#include <QQuaternion>
#include <QTimer>//多光源
//QOpenGLWidget窗口上下文
//QOpenGLFunctions访问OpenGL接口,可以不继承作为成员变量使用
class GLMultipleLights: public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core
{Q_OBJECT
public:explicit GLMultipleLights(QWidget *parent = nullptr);~GLMultipleLights();protected://【】继承QOpenGLWidget后重写这三个虚函数//设置OpenGL资源和状态。在第一次调用resizeGL或paintGL之前被调用一次void initializeGL() override;//渲染OpenGL场景,每当需要更新小部件时使用void paintGL() override;//设置OpenGL视口、投影等,每当尺寸大小改变时调用void resizeGL(int width, int height) override;private:void initShader();QOpenGLTexture *initTexture(const QString &imgpath);private://着色器程序QOpenGLShaderProgram lightingShader,lampShader;//顶点数组对象QOpenGLVertexArrayObject lightingVao,lampVao;//顶点缓冲QOpenGLBuffer vbo;//纹理QOpenGLTexture *diffuseMap{ nullptr };QOpenGLTexture *specularMap{ nullptr };//QTimer timer;int rotate{ 0 };
};
#include "GLMultipleLights.h"
#include <cmath>
#include <QtMath>
#include <QDebug>GLMultipleLights::GLMultipleLights(QWidget *parent): QOpenGLWidget(parent)
{connect(&timer,&QTimer::timeout,this,[this](){rotate+=1;if(isVisible()){update();}});timer.setInterval(50);
}GLMultipleLights::~GLMultipleLights()
{//initializeGL在显示时才调用,释放未初始化的会异常if(!isValid())return;//QOpenGLWidget//三个虚函数不需要makeCurrent,对应的操作已由框架完成//但是释放时需要设置当前上下文makeCurrent();vbo.destroy();lightingVao.destroy();lampVao.destroy();delete diffuseMap;delete specularMap;doneCurrent();
}void GLMultipleLights::initializeGL()
{//为当前上下文初始化OpenGL函数解析initializeOpenGLFunctions();initShader();//方块的顶点、法向量、纹理坐标float vertices[] = {// positions          // normals           // texture coords-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};vbo=QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);vbo.create();//light vaolightingVao.create();lightingVao.bind();vbo.bind();vbo.allocate(vertices,sizeof(vertices));//setAttributeBuffer(int location, GLenum type, int offset, int tupleSize, int stride = 0)lightingShader.setAttributeBuffer(0, GL_FLOAT, sizeof(GLfloat) * 0, 3, sizeof(GLfloat) * 8);lightingShader.enableAttributeArray(0);lightingShader.setAttributeBuffer(1, GL_FLOAT, sizeof(GLfloat) * 3, 3, sizeof(GLfloat) * 8);lightingShader.enableAttributeArray(1);lightingShader.setAttributeBuffer(2, GL_FLOAT, sizeof(GLfloat) * 6, 2, sizeof(GLfloat) * 8);lightingShader.enableAttributeArray(2);vbo.release();lightingVao.release();//lamp vaolampVao.create();lampVao.bind();vbo.bind();//setAttributeBuffer(int location, GLenum type, int offset, int tupleSize, int stride = 0)lampShader.setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(GLfloat) * 8);lampShader.enableAttributeArray(0);vbo.release();lampVao.release();//纹理diffuseMap = initTexture(":/container2.png");specularMap = initTexture(":/container2_specular.png");//shader configurationlightingShader.bind();lightingShader.setUniformValue("material.diffuse", 0);lightingShader.setUniformValue("material.specular", 1);lightingShader.release();//timer.start();
}//绘制多个盒子
static QVector3D cubePositions[] = {QVector3D( 0.0f,  0.0f,  0.0f),QVector3D( 0.0f, -4.0f,  0.0f),QVector3D( 0.0f,  4.0f,  0.0f),QVector3D( 1.0f, -5.0f, 1.0f),QVector3D(-1.5f, -2.2f, -2.5f),QVector3D(-3.8f, -2.0f, -7.3f),QVector3D( 2.4f, -0.4f, -3.5f),QVector3D(-1.7f, -3.0f, -6.5f),QVector3D( 5.3f, -2.0f, -2.5f),QVector3D(-1.3f,  1.0f, -1.5f)
};//多个光源
static QVector3D pointLightPositions[] = {QVector3D( 0.0f,  2.0f,  0.0f),QVector3D( 2.3f, -3.0f, -1.0f),QVector3D(-3.0f,  2.0f, 0.5f),QVector3D( 2.0f,  3.0f, 2.0f)
};void GLMultipleLights::paintGL()
{glClearColor(0.2f, 0.3f, 0.3f, 1.0f);//清除深度缓冲glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//Z缓冲(Z-buffer),深度缓冲(Depth Buffer)。glEnable(GL_DEPTH_TEST);//draw lightinglightingShader.bind();QMatrix4x4 view; //观察矩阵view.translate(0.0f, 0.0f, -10.0f);view.rotate(45, QVector3D(1.0f, 0.8f, 0.0f));lightingShader.setUniformValue("view", view);QMatrix4x4 projection; //透视投影projection.perspective(45.0f, 1.0f * width() / height(), 0.1f, 100.0f);lightingShader.setUniformValue("projection", projection);// Directional lightlightingShader.setUniformValue("dirLight.direction", -0.2f, -1.0f, -0.3f);lightingShader.setUniformValue("dirLight.ambient", 0.05f, 0.05f, 0.05f);lightingShader.setUniformValue("dirLight.diffuse", 0.2f, 0.2f, 0.2f);lightingShader.setUniformValue("dirLight.specular", 0.5f, 0.5f, 0.5f);QVector3D ambient_color(0.05f, 0.05f, 0.05f);QVector3D diffuse_color(0.0f, 0.0f, 0.4f);QVector3D specular_color(0.0f, 0.0f, 1.0f);// Point light 1lightingShader.setUniformValue("pointLights[0].position", pointLightPositions[0]);lightingShader.setUniformValue("pointLights[0].ambient", ambient_color);lightingShader.setUniformValue("pointLights[0].diffuse", diffuse_color);lightingShader.setUniformValue("pointLights[0].specular", specular_color);lightingShader.setUniformValue("pointLights[0].constant", 1.0f);lightingShader.setUniformValue("pointLights[0].linear", 0.09f);lightingShader.setUniformValue("pointLights[0].quadratic", 0.032f);// Point light 2lightingShader.setUniformValue("pointLights[1].position", pointLightPositions[1]);lightingShader.setUniformValue("pointLights[1].ambient", ambient_color);lightingShader.setUniformValue("pointLights[1].diffuse", diffuse_color);lightingShader.setUniformValue("pointLights[1].specular", specular_color);lightingShader.setUniformValue("pointLights[1].constant", 1.0f);lightingShader.setUniformValue("pointLights[1].linear", 0.09f);lightingShader.setUniformValue("pointLights[1].quadratic", 0.032f);// Point light 3lightingShader.setUniformValue("pointLights[2].position", pointLightPositions[2]);lightingShader.setUniformValue("pointLights[2].ambient", ambient_color);lightingShader.setUniformValue("pointLights[2].diffuse", diffuse_color);lightingShader.setUniformValue("pointLights[2].specular", specular_color);lightingShader.setUniformValue("pointLights[2].constant", 1.0f);lightingShader.setUniformValue("pointLights[2].linear", 0.09f);lightingShader.setUniformValue("pointLights[2].quadratic", 0.032f);// Point light 4lightingShader.setUniformValue("pointLights[3].position", pointLightPositions[3]);lightingShader.setUniformValue("pointLights[3].ambient", ambient_color);lightingShader.setUniformValue("pointLights[3].diffuse", diffuse_color);lightingShader.setUniformValue("pointLights[3].specular", specular_color);lightingShader.setUniformValue("pointLights[3].constant", 1.0f);lightingShader.setUniformValue("pointLights[3].linear", 0.09f);lightingShader.setUniformValue("pointLights[3].quadratic", 0.032f);// SpotLightQMatrix4x4 model;//模型矩阵model.translate(pointLightPositions[0]);model.scale(0.2f);QVector3D light_pos = model.map(QVector3D(0.0f, 0.0f, 0.0f));QVector3D direction_pos = QVector3D(0.0f, -20.0f, 0.0f);lightingShader.setUniformValue("spotLight.direction", direction_pos);lightingShader.setUniformValue("spotLight.position", light_pos);lightingShader.setUniformValue("spotLight.ambient", 0.0f, 0.0f, 0.0f);lightingShader.setUniformValue("spotLight.diffuse", 0.3f, 1.0f, 0.3f);lightingShader.setUniformValue("spotLight.specular", 0.3f, 1.0f, 0.3f);lightingShader.setUniformValue("spotLight.constant", 1.0f);lightingShader.setUniformValue("spotLight.linear", 0.09f);lightingShader.setUniformValue("spotLight.quadratic", 0.032f);lightingShader.setUniformValue("spotLight.cutOff", (float)std::cos(qDegreesToRadians(12.5)));lightingShader.setUniformValue("spotLight.outerCutOff", (float)std::cos(qDegreesToRadians(15.0)));//材质-material properties//shininess影响镜面高光的散射/半径lightingShader.setUniformValue("material.shininess", 32.0f);lightingVao.bind();//绑定2d纹理//bind diffuse mapglActiveTexture(GL_TEXTURE0);diffuseMap->bind();//bind specular mapglActiveTexture(GL_TEXTURE1);specularMap->bind();//glDrawArrays(GL_TRIANGLES, 0, 36);//多个盒子便于对比for (unsigned int i = 0; i < 10; i++) {//模型矩阵QMatrix4x4 box_model;//平移box_model.translate(cubePositions[i]);float angle = 20.0f * i;//旋转box_model.rotate(angle, QVector3D(1.0f, 0.3f, 0.5f));//传入着色器并绘制lightingShader.setUniformValue("model", box_model);glDrawArrays(GL_TRIANGLES, 0, 36);}lightingVao.release();lightingShader.release();//draw lamplampShader.bind();lampShader.setUniformValue("view", view);lampShader.setUniformValue("projection", projection);lampVao.bind();for (unsigned int i = 0; i < 4; i++) {//模型矩阵QMatrix4x4 lamb_model;lamb_model.translate(pointLightPositions[i]);lamb_model.scale(0.2f);//传入着色器并绘制lampShader.setUniformValue("model", lamb_model);glDrawArrays(GL_TRIANGLES, 0, 36);}lampVao.release();lampShader.release();
}void GLMultipleLights::resizeGL(int width, int height)
{glViewport(0, 0, width, height);
}void GLMultipleLights::initShader()
{//lingting shader//in输入,out输出,uniform从cpu向gpu发送const char *lighting_vertex=R"(#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;out vec3 FragPos;
out vec3 Normal;
out vec2 TexCoords;uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;void main()
{FragPos = vec3(model * vec4(aPos, 1.0));Normal = mat3(transpose(inverse(model))) * aNormal;TexCoords = aTexCoords;gl_Position = projection * view * vec4(FragPos, 1.0);
})";const char *lighting_fragment=R"(#version 330 core
struct Material {sampler2D diffuse;sampler2D specular;float shininess;
};struct DirLight {vec3 direction;vec3 ambient;vec3 diffuse;vec3 specular;
};struct PointLight {vec3 position;float constant;float linear;float quadratic;vec3 ambient;vec3 diffuse;vec3 specular;
};struct SpotLight {vec3 position;vec3 direction;float cutOff;float outerCutOff;float constant;float linear;float quadratic;vec3 ambient;vec3 diffuse;vec3 specular;
};#define NR_POINT_LIGHTS 4in vec3 FragPos;
in vec3 Normal;
in vec2 TexCoords;out vec4 color;uniform vec3 viewPos;
uniform DirLight dirLight;
uniform PointLight pointLights[NR_POINT_LIGHTS];
uniform SpotLight spotLight;
uniform Material material;// Function prototypes
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir);
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir);void main()
{// Propertiesvec3 norm = normalize(Normal);vec3 viewDir = normalize(viewPos - FragPos);// == ======================================// Our lighting is set up in 3 phases: directional, point lights and an optional flashlight// For each phase, a calculate function is defined that calculates the corresponding color// per lamp. In the main() function we take all the calculated colors and sum them up for// this fragment's final color.// == ======================================// Phase 1: Directional lightingvec3 result = CalcDirLight(dirLight, norm, viewDir);// Phase 2: Point lightsfor(int i = 0; i < NR_POINT_LIGHTS; i++)result += CalcPointLight(pointLights[i], norm, FragPos, viewDir);// Phase 3: Spot lightresult += CalcSpotLight(spotLight, norm, FragPos, viewDir);color = vec4(result, 1.0);
}// Calculates the color when using a directional light.
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
{vec3 lightDir = normalize(-light.direction);// Diffuse shadingfloat diff = max(dot(normal, lightDir), 0.0);// Specular shadingvec3 reflectDir = reflect(-lightDir, normal);float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);// Combine resultsvec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));return (ambient + diffuse + specular);
}// Calculates the color when using a point light.
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
{vec3 lightDir = normalize(light.position - fragPos);// Diffuse shadingfloat diff = max(dot(normal, lightDir), 0.0);// Specular shadingvec3 reflectDir = reflect(-lightDir, normal);float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);// Attenuationfloat distance = length(light.position - fragPos);float attenuation = 1.0f / (light.constant + light.linear * distance + light.quadratic * (distance * distance));// Combine resultsvec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));ambient *= attenuation;diffuse *= attenuation;specular *= attenuation;return (ambient + diffuse + specular);
}// Calculates the color when using a spot light.
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
{vec3 lightDir = normalize(light.position - fragPos);// Diffuse shadingfloat diff = max(dot(normal, lightDir), 0.0);// Specular shadingvec3 reflectDir = reflect(-lightDir, normal);float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);// Attenuationfloat distance = length(light.position - fragPos);float attenuation = 1.0f / (light.constant + light.linear * distance + light.quadratic * (distance * distance));// Spotlight intensityfloat theta = dot(lightDir, normalize(-light.direction));float epsilon = light.cutOff - light.outerCutOff;float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);// Combine resultsvec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));ambient *= attenuation * intensity;diffuse *= attenuation * intensity;specular *= attenuation * intensity;return (ambient + diffuse + specular);
})";//将source编译为指定类型的着色器,并添加到此着色器程序if(!lightingShader.addCacheableShaderFromSourceCode(QOpenGLShader::Vertex,lighting_vertex)){qDebug()<<"compiler vertex error"<<lightingShader.log();}if(!lightingShader.addCacheableShaderFromSourceCode(QOpenGLShader::Fragment,lighting_fragment)){qDebug()<<"compiler fragment error"<<lightingShader.log();}//使用addShader()将添加到该程序的着色器链接在一起。if(!lightingShader.link()){qDebug()<<"link shaderprogram error"<<lightingShader.log();}//lamp shaderconst char *lamp_vertex=R"(#version 330 core
layout (location = 0) in vec3 aPos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0f);
})";const char *lamp_fragment=R"(#version 330 core
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0);
})"; // set alle 4 vector values to 1.0if(!lampShader.addCacheableShaderFromSourceCode(QOpenGLShader::Vertex,lamp_vertex)){qDebug()<<"compiler vertex error"<<lampShader.log();}if(!lampShader.addCacheableShaderFromSourceCode(QOpenGLShader::Fragment,lamp_fragment)){qDebug()<<"compiler fragment error"<<lampShader.log();}if(!lampShader.link()){qDebug()<<"link shaderprogram error"<<lampShader.log();}
}QOpenGLTexture *GLMultipleLights::initTexture(const QString &imgpath)
{QOpenGLTexture *texture = new QOpenGLTexture(QImage(imgpath), QOpenGLTexture::GenerateMipMaps);if(!texture->isCreated()){qDebug() << "Failed to create texture";}//set the texture wrapping parameters//等于glTexParameteri(GLtexture_2D, GLtexture_WRAP_S, GL_REPEAT);texture->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat);texture->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat);////set texture filtering parameters//等价于glTexParameteri(GLtexture_2D, GLtexture_MIN_FILTER, GL_LINEAR);texture->setMinificationFilter(QOpenGLTexture::Linear);texture->setMagnificationFilter(QOpenGLTexture::Linear);return texture;
}

3.参考

LearnOpenGL:https://learnopengl-cn.github.io/02%20Lighting/05%20Light%20casters/

LearnOpenGL:https://learnopengl-cn.github.io/02%20Lighting/06%20Multiple%20lights/

OpenGL with QtWidgets:投光物、多光源相关推荐

  1. LearnOpenGL->光照->投光物/多光源

    投光物 我们目前使用的光照都来自于空间中的一个点.它能给我们不错的效果,但现实世界中,我们有很多种类的光照,每种的表现都不同.将光投射(Cast)到物体的光源叫做投光物(Light Caster).在 ...

  2. Opengl-光照-基本光照-投光物-多光源(现实世界的光可不只有太阳也并不只有一个)

    前言 相信大家看过各种发光的道具,手电筒?看到过吧?灯泡看到过吧?除了太阳生活中还有各种灯红酒绿的地方(说错了)等着你去看啊 各种光源 平行光-太阳或者很远处的光都可以叫做平行光 平行光的光的方向是一 ...

  3. Learn OpenGL (十二):投光物

    平行光 当一个光源处于很远的地方时,来自光源的每条光线就会近似于互相平行.不论物体和/或者观察者的位置,看起来好像所有的光都来自于同一个方向.当我们使用一个假设光源处于无限远处的模型时,它就被称为定向 ...

  4. OpenGL 投光物Light casters

    OpenGL 投光物Light casters 投光物Light casters简介 平行光 点光源 衰减 选择正确的值 实现衰减 聚光 手电筒Flashlight 平滑/软化边缘 投光物Light ...

  5. 第三十一章 投光物和多光源总结

    投光物:将光投射到物体的光源.不同的投光物代表不同种类的光源. 平行光:(也叫做定向光) 光线都是平行的,物体和光源的相对位置不重要.场景中每个物体的光照计算都是类似的. 定义一个光线方向向量,而不是 ...

  6. 第三十二章 投光物和多光源总结

    Assimp 将模型导入到程序中.需要掌握:解析导出的模型文件以及提取所有有用的信息,存储为OpenGL能够理解的格式. 模型的文件格式不同,每一种都有自己的方式来导出模型数据.有专门的库可以直接用, ...

  7. OpenGL with QtWidgets:练习之甜甜圈

    甜甜圈是 <OpenGL 超级宝典>上的一个示例,用来演示面剔除和深度测试应用,原本的代码顶点和着色器部分不便于学习,我就重新写了下,略去了法线和光照相关. 当我们对渲染出来的甜甜圈进行旋 ...

  8. OpenGL with QtWidgets:练习之扑克翻转

    (本文是LearnOpenGL的学习笔记,教程中文翻译地址https://learnopengl-cn.github.io/(备用地址https://learnopengl-cn.readthedoc ...

  9. OpenGL with QtWidgets:练习之绘制2D环形进度条

    1.实现思路 这里主要涉及几个点:绘制圆环,绘制文字,动画,抗锯齿. 绘制圆环网上有些人是计算好圆边的顶点后传入的,我这里直接在片段着色器里根据距离圆心的距离来渲染的圆环. void main() { ...

最新文章

  1. 2、安装Lync Server 2013
  2. CentOS 7上源码编译安装和配置LNMP Web+phpMyAdmin服务器环境
  3. git bash命令_?你可能不太会用的10个Git命令
  4. 获取设备IMEI ,手机名称,系统SDK版本号,系统版本号
  5. Java 虚拟机内存分配与回收策略
  6. zlib1.2.5的编译
  7. 聚焦数字化智慧安防的新型社区
  8. Unity3d:Unknown type 'System.Collections.Generic.CollectionDebuggerView'1
  9. 空间apiLinux系统调用及用户编程接口(API)学习
  10. Ubuntu“ System Program Problem Detected”问题
  11. 用python玩转数据mooc答案_中国大学慕课mooc用Python玩转数据章节测试答案
  12. c#随机产生常用汉字
  13. 个人收集资料分享(电子、计算机相关)
  14. cad连接不同线段的端点_CAD中怎么把几个线断连接成一个整体
  15. 126邮箱绑定QQ邮箱并微信提醒
  16. python 柱状图折线图共用一个图例_使用python的seaborn绘制折线图与柱状图的组合图...
  17. 怎么正确使用代理IP
  18. 通过构建Paint App学习React Hooks
  19. 形而上者谓之道,形而下者谓之器——asp.net学习总结
  20. 我的世界java版如何装mod_我的世界MOD怎么安装 MOD安装简易教程

热门文章

  1. IRIS鸢尾花数据集(多种格式)-下载地址
  2. 数理逻辑小结3——一阶谓词逻辑演算
  3. matlab 背包问题动态规划,从01背包问题理解动态规划---初体验
  4. spyder(anaconda3)进行汉化
  5. 使用 Unity 和 C# 开发您的首个游戏
  6. 支持物联网的木头 最优雅的智能家居屏幕
  7. TABLE functions
  8. 【lssvm回归预测】基于鸽群算法优化最小二乘支持向量机PIO-lssvm实现数据回归预测附matlab代码
  9. 关于编辑器QScintilla(Scintilla)词法分析器取消非活动代码灰色显示
  10. Ubuntu 安装 Mysql 8