神说,要有光
parent
9908e9e416
commit
4059101aa7
|
@ -23,19 +23,11 @@ void Mesh::Draw()
|
|||
for (unsigned int i = 0; i < textures.size(); 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();
|
||||
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;
|
||||
return;
|
||||
}
|
||||
qDebug() << directory.absolutePath() << "Load Successfully";
|
||||
qDebug() << directory.absolutePath() << "Loaded Successfully";
|
||||
qDebug() << "NumMeshes: " << scene->mNumMeshes;
|
||||
qDebug() << "NumMaterials: " << scene->mNumMaterials;
|
||||
qDebug() << "NumTextures: " << scene->mNumTextures;
|
||||
|
@ -45,8 +45,8 @@ void Model::draw() {
|
|||
|
||||
void Model::destroy()
|
||||
{
|
||||
context->doneCurrent();
|
||||
delete this;
|
||||
context->doneCurrent();
|
||||
}
|
||||
|
||||
Model* Model::createModel(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram)
|
||||
|
@ -135,35 +135,29 @@ Mesh* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model)
|
|||
// ´¦Àí²ÄÖÊ
|
||||
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
|
||||
|
||||
// 1. 漫反射贴图
|
||||
QVector<Texture*> diffuseMaps = loadMaterialTextures(material, aiTextureType_DIFFUSE, "texture_diffuse");
|
||||
QVector<Texture*> diffuseMaps = loadMaterialTextures(material, aiTextureType_BASE_COLOR, "texture_basecolor");
|
||||
for (auto& it : diffuseMaps)
|
||||
m_mesh->textures.push_back(it);
|
||||
|
||||
// 2. 镜面贴图
|
||||
QVector<Texture*> specularMaps = loadMaterialTextures(material, aiTextureType_SPECULAR, "texture_specular");
|
||||
for (auto& it : specularMaps)
|
||||
QVector<Texture*> metalnessMaps = loadMaterialTextures(material, aiTextureType_METALNESS, "texture_metallic_roughness");
|
||||
for (auto& it : metalnessMaps)
|
||||
m_mesh->textures.push_back(it);
|
||||
|
||||
// 3. 法向量图
|
||||
QVector<Texture*> normalMaps = loadMaterialTextures(material, aiTextureType_HEIGHT, "texture_normal");
|
||||
QVector<Texture*> normalMaps = loadMaterialTextures(material, aiTextureType_NORMALS, "texture_normal");
|
||||
for (auto& it : normalMaps)
|
||||
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();
|
||||
return m_mesh;
|
||||
}
|
||||
|
||||
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++)
|
||||
{
|
||||
//qDebug() << typeName;
|
||||
aiString str;
|
||||
mat->GetTexture(type, i, &str);
|
||||
|
||||
|
|
|
@ -5,13 +5,12 @@
|
|||
#include <sstream>
|
||||
|
||||
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);
|
||||
lastFrame = std::clock();
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
setMouseTracking(true);
|
||||
setCursor(Qt::BlankCursor);
|
||||
|
||||
}
|
||||
|
||||
RendererWidget::~RendererWidget()
|
||||
|
@ -69,7 +68,8 @@ void RendererWidget::initializeGL()
|
|||
reinterpret_cast<void*>(3 * sizeof(GLfloat)));
|
||||
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()
|
||||
{
|
||||
//std::cout << (double)CLOCKS_PER_SEC/(std::clock() -lastFrame) << std::endl;
|
||||
|
@ -81,6 +81,10 @@ void RendererWidget::paintGL()
|
|||
// camera/view transformation
|
||||
QMatrix4x4 view = camera.GetViewMatrix();
|
||||
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);
|
||||
model->draw();
|
||||
m_program->release();
|
||||
|
@ -90,7 +94,7 @@ void RendererWidget::resizeGL(int width, int height)
|
|||
{
|
||||
m_program->bind();
|
||||
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);
|
||||
|
||||
}
|
||||
|
@ -100,9 +104,16 @@ void RendererWidget::timerEvent(QTimerEvent* event)
|
|||
clock_t currentFrame = std::clock();
|
||||
deltaTime = (float)(std::clock() - lastFrame) / CLOCKS_PER_SEC;
|
||||
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)) {
|
||||
camera.ProcessKeyboard(FORWARD, deltaTime);
|
||||
}
|
||||
|
@ -126,7 +137,9 @@ void RendererWidget::timerEvent(QTimerEvent* event)
|
|||
|
||||
void RendererWidget::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
if (!event->isAutoRepeat())
|
||||
if (event->key() == Qt::Key_Escape)
|
||||
clearFocus();
|
||||
else if (!event->isAutoRepeat())
|
||||
pressedKeys.insert(event->key());
|
||||
QOpenGLWidget::keyPressEvent(event);
|
||||
}
|
||||
|
@ -138,20 +151,15 @@ void RendererWidget::keyReleaseEvent(QKeyEvent* event)
|
|||
QOpenGLWidget::keyReleaseEvent(event);
|
||||
}
|
||||
|
||||
void RendererWidget::mouseMoveEvent(QMouseEvent* event)
|
||||
|
||||
void RendererWidget::focusInEvent(QFocusEvent* event)
|
||||
{
|
||||
static bool firstMouse = true;
|
||||
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);
|
||||
}
|
||||
setCursor(Qt::BlankCursor);
|
||||
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 keyPressEvent(QKeyEvent* event) override;
|
||||
void keyReleaseEvent(QKeyEvent* event) override;
|
||||
void mouseMoveEvent(QMouseEvent* event) override;
|
||||
void focusInEvent(QFocusEvent* event) override;
|
||||
void focusOutEvent(QFocusEvent* event) override;
|
||||
private:
|
||||
QSet<int> pressedKeys;
|
||||
Camera camera;
|
||||
|
|
|
@ -1,12 +1,133 @@
|
|||
#version 330 core
|
||||
|
||||
|
||||
uniform sampler2D texture_basecolor;
|
||||
uniform sampler2D texture_metallic_roughness;
|
||||
uniform sampler2D texture_normal;
|
||||
|
||||
out vec4 FragColor;
|
||||
in vec2 TexCoords;
|
||||
|
||||
uniform sampler2D texture_diffuse1;
|
||||
|
||||
void main()
|
||||
in vec3 WorldPos;
|
||||
in vec3 Normal;
|
||||
|
||||
// lights
|
||||
uniform vec3 lightPositions[4];
|
||||
uniform vec3 lightColors[4];
|
||||
|
||||
uniform vec3 camPos;
|
||||
|
||||
const float PI = 3.14159265359;
|
||||
|
||||
vec3 getNormalFromMap()
|
||||
{
|
||||
gl_FragColor = texture2D(texture_diffuse1,TexCoords);
|
||||
if(gl_FragColor.a==0)
|
||||
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()
|
||||
{
|
||||
vec4 baseColor = texture(texture_basecolor, TexCoords);
|
||||
if(baseColor.a==0)
|
||||
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;
|
||||
|
||||
out vec2 TexCoords;
|
||||
out vec3 WorldPos;
|
||||
out vec3 Normal;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
|
@ -12,6 +14,9 @@ uniform mat4 projection;
|
|||
void main()
|
||||
{
|
||||
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