神说,要有光

dev-VirtualTexture
wuyize 2022-07-22 16:36:48 +08:00
parent 9908e9e416
commit 4059101aa7
7 changed files with 183 additions and 58 deletions

View File

@ -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);
}
// 绘制网格

View File

@ -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);

View File

@ -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);
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -1 +1,5 @@
# ArchitectureColoredPainting
# ArchitectureColoredPainting
采用pbr材质现在有一个光源和摄像机绑定足以分辨出不同材质的效果
TODO改用延迟渲染并指定一块材质使用独立管线进行纹理采样