神说,要有光
parent
9908e9e416
commit
4059101aa7
|
@ -23,19 +23,11 @@ void Mesh::Draw()
|
||||||
for (unsigned int i = 0; i < textures.size(); i++)
|
for (unsigned int i = 0; i < textures.size(); i++)
|
||||||
{
|
{
|
||||||
glFunc->glActiveTexture(GL_TEXTURE0 + i); // 在绑定之前激活相应的纹理单元
|
glFunc->glActiveTexture(GL_TEXTURE0 + i); // 在绑定之前激活相应的纹理单元
|
||||||
// »ñÈ¡ÎÆÀíÐòºÅ£¨diffuse_textureN ÖÐµÄ N£©
|
|
||||||
QString number;
|
|
||||||
QString name = textures[i]->type;
|
|
||||||
if (name == "texture_diffuse")
|
|
||||||
number = QString::number(diffuseNr++);
|
|
||||||
else if (name == "texture_specular")
|
|
||||||
number = QString::number(specularNr++);
|
|
||||||
else if (name == "texture_normal")
|
|
||||||
number = QString::number(normalNr++); // transfer unsigned int to stream
|
|
||||||
else if (name == "texture_height")
|
|
||||||
number = QString::number(heightNr++); // transfer unsigned int to stream
|
|
||||||
textures[i]->texture.bind();
|
textures[i]->texture.bind();
|
||||||
shaderProgram->setUniformValue((name + number).toStdString().c_str(), i);
|
//qDebug() << name + number;
|
||||||
|
shaderProgram->setUniformValue(textures[i]->type.toStdString().c_str(), i);
|
||||||
}
|
}
|
||||||
// 绘制网格
|
// 绘制网格
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shader
|
||||||
qDebug() << "ERROR::ASSIMP::" << import.GetErrorString() << endl;
|
qDebug() << "ERROR::ASSIMP::" << import.GetErrorString() << endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qDebug() << directory.absolutePath() << "Load Successfully";
|
qDebug() << directory.absolutePath() << "Loaded Successfully";
|
||||||
qDebug() << "NumMeshes: " << scene->mNumMeshes;
|
qDebug() << "NumMeshes: " << scene->mNumMeshes;
|
||||||
qDebug() << "NumMaterials: " << scene->mNumMaterials;
|
qDebug() << "NumMaterials: " << scene->mNumMaterials;
|
||||||
qDebug() << "NumTextures: " << scene->mNumTextures;
|
qDebug() << "NumTextures: " << scene->mNumTextures;
|
||||||
|
@ -45,8 +45,8 @@ void Model::draw() {
|
||||||
|
|
||||||
void Model::destroy()
|
void Model::destroy()
|
||||||
{
|
{
|
||||||
delete this;
|
|
||||||
context->doneCurrent();
|
context->doneCurrent();
|
||||||
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Model* Model::createModel(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram)
|
Model* Model::createModel(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram)
|
||||||
|
@ -135,26 +135,18 @@ Mesh* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model)
|
||||||
// ´¦Àí²ÄÖÊ
|
// ´¦Àí²ÄÖÊ
|
||||||
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
|
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
|
||||||
|
|
||||||
// 1. 漫反射贴图
|
QVector<Texture*> diffuseMaps = loadMaterialTextures(material, aiTextureType_BASE_COLOR, "texture_basecolor");
|
||||||
QVector<Texture*> diffuseMaps = loadMaterialTextures(material, aiTextureType_DIFFUSE, "texture_diffuse");
|
|
||||||
for (auto& it : diffuseMaps)
|
for (auto& it : diffuseMaps)
|
||||||
m_mesh->textures.push_back(it);
|
m_mesh->textures.push_back(it);
|
||||||
|
|
||||||
// 2. 镜面贴图
|
QVector<Texture*> metalnessMaps = loadMaterialTextures(material, aiTextureType_METALNESS, "texture_metallic_roughness");
|
||||||
QVector<Texture*> specularMaps = loadMaterialTextures(material, aiTextureType_SPECULAR, "texture_specular");
|
for (auto& it : metalnessMaps)
|
||||||
for (auto& it : specularMaps)
|
|
||||||
m_mesh->textures.push_back(it);
|
m_mesh->textures.push_back(it);
|
||||||
|
|
||||||
// 3. 法向量图
|
QVector<Texture*> normalMaps = loadMaterialTextures(material, aiTextureType_NORMALS, "texture_normal");
|
||||||
QVector<Texture*> normalMaps = loadMaterialTextures(material, aiTextureType_HEIGHT, "texture_normal");
|
|
||||||
for (auto& it : normalMaps)
|
for (auto& it : normalMaps)
|
||||||
m_mesh->textures.push_back(it);
|
m_mesh->textures.push_back(it);
|
||||||
|
|
||||||
// 4. 高度图
|
|
||||||
QVector<Texture*> heightMaps = loadMaterialTextures(material, aiTextureType_AMBIENT, "texture_height");
|
|
||||||
for (auto& it : heightMaps)
|
|
||||||
m_mesh->textures.push_back(it);
|
|
||||||
|
|
||||||
m_mesh->setupMesh();
|
m_mesh->setupMesh();
|
||||||
return m_mesh;
|
return m_mesh;
|
||||||
}
|
}
|
||||||
|
@ -162,8 +154,10 @@ Mesh* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model)
|
||||||
QVector<Texture*> Model::loadMaterialTextures(aiMaterial* mat, aiTextureType type, QString typeName)
|
QVector<Texture*> Model::loadMaterialTextures(aiMaterial* mat, aiTextureType type, QString typeName)
|
||||||
{
|
{
|
||||||
QVector<Texture*> textures;
|
QVector<Texture*> textures;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < mat->GetTextureCount(type); i++)
|
for (unsigned int i = 0; i < mat->GetTextureCount(type); i++)
|
||||||
{
|
{
|
||||||
|
//qDebug() << typeName;
|
||||||
aiString str;
|
aiString str;
|
||||||
mat->GetTexture(type, i, &str);
|
mat->GetTexture(type, i, &str);
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,12 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
RendererWidget::RendererWidget(QWidget* parent)
|
RendererWidget::RendererWidget(QWidget* parent)
|
||||||
: QOpenGLWidget(parent), camera(QVector3D(0.0f, 0.0f, 3.0f))
|
: QOpenGLWidget(parent), camera(QVector3D(0.0f, 100.0f, 0.0f))
|
||||||
{
|
{
|
||||||
startTimer(1000 / 120);
|
startTimer(1000 / 120);
|
||||||
lastFrame = std::clock();
|
lastFrame = std::clock();
|
||||||
setFocusPolicy(Qt::StrongFocus);
|
setFocusPolicy(Qt::StrongFocus);
|
||||||
setMouseTracking(true);
|
|
||||||
setCursor(Qt::BlankCursor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RendererWidget::~RendererWidget()
|
RendererWidget::~RendererWidget()
|
||||||
|
@ -69,7 +68,8 @@ void RendererWidget::initializeGL()
|
||||||
reinterpret_cast<void*>(3 * sizeof(GLfloat)));
|
reinterpret_cast<void*>(3 * sizeof(GLfloat)));
|
||||||
m_vbo.release();*/
|
m_vbo.release();*/
|
||||||
}
|
}
|
||||||
|
QVector3D lightPositions[] = { QVector3D(0,0,0), QVector3D(100,100,100) ,QVector3D(-100,100,100) ,QVector3D(100,100,-100) };
|
||||||
|
QVector3D lightColors[] = { QVector3D(150000,150000,150000), QVector3D(0,0,0) ,QVector3D(0,0,0) ,QVector3D(0,0,0) };
|
||||||
void RendererWidget::paintGL()
|
void RendererWidget::paintGL()
|
||||||
{
|
{
|
||||||
//std::cout << (double)CLOCKS_PER_SEC/(std::clock() -lastFrame) << std::endl;
|
//std::cout << (double)CLOCKS_PER_SEC/(std::clock() -lastFrame) << std::endl;
|
||||||
|
@ -81,6 +81,10 @@ void RendererWidget::paintGL()
|
||||||
// camera/view transformation
|
// camera/view transformation
|
||||||
QMatrix4x4 view = camera.GetViewMatrix();
|
QMatrix4x4 view = camera.GetViewMatrix();
|
||||||
m_program->setUniformValue(m_program->uniformLocation("view"), view);
|
m_program->setUniformValue(m_program->uniformLocation("view"), view);
|
||||||
|
m_program->setUniformValue(m_program->uniformLocation("camPos"), camera.Position);
|
||||||
|
lightPositions[0] = camera.Position;
|
||||||
|
m_program->setUniformValueArray("lightPositions", lightPositions, 4);
|
||||||
|
m_program->setUniformValueArray("lightColors", lightColors, 4);
|
||||||
//glDrawArrays(GL_TRIANGLES, 0, 3);
|
//glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
model->draw();
|
model->draw();
|
||||||
m_program->release();
|
m_program->release();
|
||||||
|
@ -90,7 +94,7 @@ void RendererWidget::resizeGL(int width, int height)
|
||||||
{
|
{
|
||||||
m_program->bind();
|
m_program->bind();
|
||||||
QMatrix4x4 projection;
|
QMatrix4x4 projection;
|
||||||
projection.perspective(camera.Zoom, (float)width / (float)height, 0.1f, 10000.0f);
|
projection.perspective(camera.Zoom, (float)width / (float)height, 10.f, 10000.0f);
|
||||||
m_program->setUniformValue(m_program->uniformLocation("projection"), projection);
|
m_program->setUniformValue(m_program->uniformLocation("projection"), projection);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -100,9 +104,16 @@ void RendererWidget::timerEvent(QTimerEvent* event)
|
||||||
clock_t currentFrame = std::clock();
|
clock_t currentFrame = std::clock();
|
||||||
deltaTime = (float)(std::clock() - lastFrame) / CLOCKS_PER_SEC;
|
deltaTime = (float)(std::clock() - lastFrame) / CLOCKS_PER_SEC;
|
||||||
lastFrame = currentFrame;
|
lastFrame = currentFrame;
|
||||||
if (pressedKeys.contains(Qt::Key_Escape)) {
|
|
||||||
close();
|
if (hasFocus())
|
||||||
|
{
|
||||||
|
QPoint center = mapToGlobal(geometry().center());
|
||||||
|
float xoffset = cursor().pos().x() - center.x();
|
||||||
|
float yoffset = center.y() - cursor().pos().y();
|
||||||
|
camera.ProcessMouseMovement(xoffset, yoffset);
|
||||||
|
cursor().setPos(center);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pressedKeys.contains(Qt::Key_W)) {
|
if (pressedKeys.contains(Qt::Key_W)) {
|
||||||
camera.ProcessKeyboard(FORWARD, deltaTime);
|
camera.ProcessKeyboard(FORWARD, deltaTime);
|
||||||
}
|
}
|
||||||
|
@ -126,7 +137,9 @@ void RendererWidget::timerEvent(QTimerEvent* event)
|
||||||
|
|
||||||
void RendererWidget::keyPressEvent(QKeyEvent* event)
|
void RendererWidget::keyPressEvent(QKeyEvent* event)
|
||||||
{
|
{
|
||||||
if (!event->isAutoRepeat())
|
if (event->key() == Qt::Key_Escape)
|
||||||
|
clearFocus();
|
||||||
|
else if (!event->isAutoRepeat())
|
||||||
pressedKeys.insert(event->key());
|
pressedKeys.insert(event->key());
|
||||||
QOpenGLWidget::keyPressEvent(event);
|
QOpenGLWidget::keyPressEvent(event);
|
||||||
}
|
}
|
||||||
|
@ -138,20 +151,15 @@ void RendererWidget::keyReleaseEvent(QKeyEvent* event)
|
||||||
QOpenGLWidget::keyReleaseEvent(event);
|
QOpenGLWidget::keyReleaseEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererWidget::mouseMoveEvent(QMouseEvent* event)
|
|
||||||
|
void RendererWidget::focusInEvent(QFocusEvent* event)
|
||||||
{
|
{
|
||||||
static bool firstMouse = true;
|
setCursor(Qt::BlankCursor);
|
||||||
if (firstMouse)
|
|
||||||
{
|
|
||||||
firstMouse = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float xoffset = event->pos().x() - geometry().center().x();
|
|
||||||
float yoffset = geometry().center().y() - event->pos().y();
|
|
||||||
camera.ProcessMouseMovement(xoffset, yoffset);
|
|
||||||
}
|
|
||||||
cursor().setPos(mapToGlobal(geometry().center()));
|
cursor().setPos(mapToGlobal(geometry().center()));
|
||||||
QOpenGLWidget::mouseMoveEvent(event);
|
}
|
||||||
|
|
||||||
|
void RendererWidget::focusOutEvent(QFocusEvent* event)
|
||||||
|
{
|
||||||
|
setCursor(Qt::ArrowCursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,8 @@ protected:
|
||||||
void timerEvent(QTimerEvent* event) override;
|
void timerEvent(QTimerEvent* event) override;
|
||||||
void keyPressEvent(QKeyEvent* event) override;
|
void keyPressEvent(QKeyEvent* event) override;
|
||||||
void keyReleaseEvent(QKeyEvent* event) override;
|
void keyReleaseEvent(QKeyEvent* event) override;
|
||||||
void mouseMoveEvent(QMouseEvent* event) override;
|
void focusInEvent(QFocusEvent* event) override;
|
||||||
|
void focusOutEvent(QFocusEvent* event) override;
|
||||||
private:
|
private:
|
||||||
QSet<int> pressedKeys;
|
QSet<int> pressedKeys;
|
||||||
Camera camera;
|
Camera camera;
|
||||||
|
|
|
@ -1,12 +1,133 @@
|
||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
|
|
||||||
|
uniform sampler2D texture_basecolor;
|
||||||
|
uniform sampler2D texture_metallic_roughness;
|
||||||
|
uniform sampler2D texture_normal;
|
||||||
|
|
||||||
|
out vec4 FragColor;
|
||||||
in vec2 TexCoords;
|
in vec2 TexCoords;
|
||||||
|
in vec3 WorldPos;
|
||||||
|
in vec3 Normal;
|
||||||
|
|
||||||
uniform sampler2D texture_diffuse1;
|
// lights
|
||||||
|
uniform vec3 lightPositions[4];
|
||||||
|
uniform vec3 lightColors[4];
|
||||||
|
|
||||||
|
uniform vec3 camPos;
|
||||||
|
|
||||||
|
const float PI = 3.14159265359;
|
||||||
|
|
||||||
|
vec3 getNormalFromMap()
|
||||||
|
{
|
||||||
|
vec3 tangentNormal = texture(texture_normal, TexCoords).xyz * 2.0 - 1.0;
|
||||||
|
|
||||||
|
vec3 Q1 = dFdx(WorldPos);
|
||||||
|
vec3 Q2 = dFdy(WorldPos);
|
||||||
|
vec2 st1 = dFdx(TexCoords);
|
||||||
|
vec2 st2 = dFdy(TexCoords);
|
||||||
|
|
||||||
|
vec3 N = normalize(Normal);
|
||||||
|
vec3 T = normalize(Q1*st2.t - Q2*st1.t);
|
||||||
|
vec3 B = -normalize(cross(N, T));
|
||||||
|
mat3 TBN = mat3(T, B, N);
|
||||||
|
|
||||||
|
return normalize(TBN * tangentNormal);
|
||||||
|
}
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
float DistributionGGX(vec3 N, vec3 H, float roughness)
|
||||||
|
{
|
||||||
|
float a = roughness*roughness;
|
||||||
|
float a2 = a*a;
|
||||||
|
float NdotH = max(dot(N, H), 0.0);
|
||||||
|
float NdotH2 = NdotH*NdotH;
|
||||||
|
|
||||||
|
float nom = a2;
|
||||||
|
float denom = (NdotH2 * (a2 - 1.0) + 1.0);
|
||||||
|
denom = PI * denom * denom;
|
||||||
|
|
||||||
|
return nom / denom;
|
||||||
|
}
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
float GeometrySchlickGGX(float NdotV, float roughness)
|
||||||
|
{
|
||||||
|
float r = (roughness + 1.0);
|
||||||
|
float k = (r*r) / 8.0;
|
||||||
|
|
||||||
|
float nom = NdotV;
|
||||||
|
float denom = NdotV * (1.0 - k) + k;
|
||||||
|
|
||||||
|
return nom / denom;
|
||||||
|
}
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
|
||||||
|
{
|
||||||
|
float NdotV = max(dot(N, V), 0.0);
|
||||||
|
float NdotL = max(dot(N, L), 0.0);
|
||||||
|
float ggx2 = GeometrySchlickGGX(NdotV, roughness);
|
||||||
|
float ggx1 = GeometrySchlickGGX(NdotL, roughness);
|
||||||
|
|
||||||
|
return ggx1 * ggx2;
|
||||||
|
}
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
vec3 fresnelSchlick(float cosTheta, vec3 F0)
|
||||||
|
{
|
||||||
|
return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
|
||||||
|
}
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_FragColor = texture2D(texture_diffuse1,TexCoords);
|
vec4 baseColor = texture(texture_basecolor, TexCoords);
|
||||||
if(gl_FragColor.a==0)
|
if(baseColor.a==0)
|
||||||
discard;
|
discard;
|
||||||
|
|
||||||
|
vec3 albedo = pow(baseColor.rgb, vec3(2.2));
|
||||||
|
float metallic = texture(texture_metallic_roughness, TexCoords).b;
|
||||||
|
float roughness = texture(texture_metallic_roughness, TexCoords).g;
|
||||||
|
|
||||||
|
|
||||||
|
vec3 N = getNormalFromMap();
|
||||||
|
vec3 V = normalize(camPos - WorldPos);
|
||||||
|
|
||||||
|
vec3 F0 = vec3(0.04);
|
||||||
|
F0 = mix(F0, albedo, metallic);
|
||||||
|
|
||||||
|
// reflectance equation
|
||||||
|
vec3 Lo = vec3(0.0);
|
||||||
|
for(int i = 0; i < 1; ++i)
|
||||||
|
{
|
||||||
|
// calculate per-light radiance
|
||||||
|
vec3 L = normalize(lightPositions[i] - WorldPos);
|
||||||
|
vec3 H = normalize(V + L);
|
||||||
|
float distance = length(lightPositions[i] - WorldPos);
|
||||||
|
float attenuation = 1.0 / (distance * distance);
|
||||||
|
vec3 radiance = lightColors[i] * attenuation;
|
||||||
|
|
||||||
|
// cook-torrance brdf
|
||||||
|
float NDF = DistributionGGX(N, H, roughness);
|
||||||
|
float G = GeometrySmith(N, V, L, roughness);
|
||||||
|
vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
|
||||||
|
F = clamp(F,vec3(0),vec3(1));
|
||||||
|
|
||||||
|
vec3 kS = F;
|
||||||
|
vec3 kD = vec3(1.0) - kS;
|
||||||
|
kD *= 1.0 - metallic;
|
||||||
|
|
||||||
|
vec3 nominator = NDF * G * F;
|
||||||
|
float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.001;
|
||||||
|
vec3 specular = nominator / denominator;
|
||||||
|
|
||||||
|
// add to outgoing radiance Lo
|
||||||
|
float NdotL = max(dot(N, L), 0.0);
|
||||||
|
Lo += (kD * albedo / PI + specular) * radiance * NdotL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 ambient = vec3(0.03) * albedo;
|
||||||
|
vec3 color = ambient + Lo;
|
||||||
|
|
||||||
|
color = color / (color + vec3(1.0));
|
||||||
|
color = pow(color, vec3(1.0/2.2));
|
||||||
|
|
||||||
|
FragColor = vec4(color, 1.0);
|
||||||
|
|
||||||
}
|
}
|
|
@ -4,6 +4,8 @@ layout (location = 1) in vec3 aNormal;
|
||||||
layout (location = 2) in vec2 aTexCoords;
|
layout (location = 2) in vec2 aTexCoords;
|
||||||
|
|
||||||
out vec2 TexCoords;
|
out vec2 TexCoords;
|
||||||
|
out vec3 WorldPos;
|
||||||
|
out vec3 Normal;
|
||||||
|
|
||||||
uniform mat4 model;
|
uniform mat4 model;
|
||||||
uniform mat4 view;
|
uniform mat4 view;
|
||||||
|
@ -12,6 +14,9 @@ uniform mat4 projection;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
TexCoords = aTexCoords;
|
TexCoords = aTexCoords;
|
||||||
gl_Position = projection * view * model * vec4(aPos, 1.0);
|
WorldPos = vec3(model * vec4(aPos, 1.0));
|
||||||
|
Normal = mat3(model) * aNormal;
|
||||||
|
|
||||||
|
gl_Position = projection * view * vec4(WorldPos, 1.0);
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue