Updated TerrainRenderer
* Engine will now use it to render terrain * Added directional light source * Added dynamic shadows * Moved visibility computation to CEngine * Removed uniform buffersdev
parent
30d688c1ec
commit
79d4cd9060
|
@ -84,11 +84,18 @@ public:
|
|||
virtual void SetViewMatrix(const glm::mat4& matrix) = 0;
|
||||
//! Sets model matrix
|
||||
virtual void SetModelMatrix(const glm::mat4& matrix) = 0;
|
||||
//! Sets shadow matrix
|
||||
virtual void SetShadowMatrix(const glm::mat4& matrix) = 0;
|
||||
|
||||
//! Sets primary texture, setting texture 0 means using white texture
|
||||
virtual void SetPrimaryTexture(const Texture& texture) = 0;
|
||||
//! Sets secondary texture
|
||||
virtual void SetSecondaryTexture(const Texture& texture) = 0;
|
||||
//! Sets shadow map
|
||||
virtual void SetShadowMap(const Texture& texture) = 0;
|
||||
|
||||
//! Sets light parameters
|
||||
virtual void SetLight(const glm::vec4& position, const float& intensity, const glm::vec3& color) = 0;
|
||||
|
||||
//! Draws terrain object
|
||||
virtual void DrawObject(const glm::mat4& matrix, const CVertexBuffer* buffer) = 0;
|
||||
|
|
|
@ -1927,7 +1927,7 @@ bool CEngine::DetectTriangle(Math::Point mouse, Vertex3D* triangle, int objRank,
|
|||
}
|
||||
|
||||
//! Use only after world transform already set
|
||||
bool CEngine::IsVisible(int objRank)
|
||||
bool CEngine::IsVisible(const Math::Matrix& matrix, int objRank)
|
||||
{
|
||||
assert(objRank >= 0 && objRank < static_cast<int>(m_objects.size()));
|
||||
|
||||
|
@ -1938,7 +1938,7 @@ bool CEngine::IsVisible(int objRank)
|
|||
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>(m_baseObjects.size()));
|
||||
|
||||
const auto& sphere = m_baseObjects[baseObjRank].boundingSphere;
|
||||
if (m_device->ComputeSphereVisibility(sphere.pos, sphere.radius) == Gfx::FRUSTUM_PLANE_ALL)
|
||||
if (ComputeSphereVisibility(matrix, sphere.pos, sphere.radius) == Gfx::FRUSTUM_PLANE_ALL)
|
||||
{
|
||||
m_objects[objRank].visible = true;
|
||||
return true;
|
||||
|
@ -1948,6 +1948,87 @@ bool CEngine::IsVisible(int objRank)
|
|||
return false;
|
||||
}
|
||||
|
||||
int CEngine::ComputeSphereVisibility(const Math::Matrix& m, const Math::Vector& center, float radius)
|
||||
{
|
||||
Math::Vector vec[6];
|
||||
float originPlane[6];
|
||||
|
||||
// Left plane
|
||||
vec[0].x = m.Get(4, 1) + m.Get(1, 1);
|
||||
vec[0].y = m.Get(4, 2) + m.Get(1, 2);
|
||||
vec[0].z = m.Get(4, 3) + m.Get(1, 3);
|
||||
float l1 = vec[0].Length();
|
||||
vec[0].Normalize();
|
||||
originPlane[0] = (m.Get(4, 4) + m.Get(1, 4)) / l1;
|
||||
|
||||
// Right plane
|
||||
vec[1].x = m.Get(4, 1) - m.Get(1, 1);
|
||||
vec[1].y = m.Get(4, 2) - m.Get(1, 2);
|
||||
vec[1].z = m.Get(4, 3) - m.Get(1, 3);
|
||||
float l2 = vec[1].Length();
|
||||
vec[1].Normalize();
|
||||
originPlane[1] = (m.Get(4, 4) - m.Get(1, 4)) / l2;
|
||||
|
||||
// Bottom plane
|
||||
vec[2].x = m.Get(4, 1) + m.Get(2, 1);
|
||||
vec[2].y = m.Get(4, 2) + m.Get(2, 2);
|
||||
vec[2].z = m.Get(4, 3) + m.Get(2, 3);
|
||||
float l3 = vec[2].Length();
|
||||
vec[2].Normalize();
|
||||
originPlane[2] = (m.Get(4, 4) + m.Get(2, 4)) / l3;
|
||||
|
||||
// Top plane
|
||||
vec[3].x = m.Get(4, 1) - m.Get(2, 1);
|
||||
vec[3].y = m.Get(4, 2) - m.Get(2, 2);
|
||||
vec[3].z = m.Get(4, 3) - m.Get(2, 3);
|
||||
float l4 = vec[3].Length();
|
||||
vec[3].Normalize();
|
||||
originPlane[3] = (m.Get(4, 4) - m.Get(2, 4)) / l4;
|
||||
|
||||
// Front plane
|
||||
vec[4].x = m.Get(4, 1) + m.Get(3, 1);
|
||||
vec[4].y = m.Get(4, 2) + m.Get(3, 2);
|
||||
vec[4].z = m.Get(4, 3) + m.Get(3, 3);
|
||||
float l5 = vec[4].Length();
|
||||
vec[4].Normalize();
|
||||
originPlane[4] = (m.Get(4, 4) + m.Get(3, 4)) / l5;
|
||||
|
||||
// Back plane
|
||||
vec[5].x = m.Get(4, 1) - m.Get(3, 1);
|
||||
vec[5].y = m.Get(4, 2) - m.Get(3, 2);
|
||||
vec[5].z = m.Get(4, 3) - m.Get(3, 3);
|
||||
float l6 = vec[5].Length();
|
||||
vec[5].Normalize();
|
||||
originPlane[5] = (m.Get(4, 4) - m.Get(3, 4)) / l6;
|
||||
|
||||
int result = 0;
|
||||
|
||||
if (InPlane(vec[0], originPlane[0], center, radius))
|
||||
result |= FRUSTUM_PLANE_LEFT;
|
||||
if (InPlane(vec[1], originPlane[1], center, radius))
|
||||
result |= FRUSTUM_PLANE_RIGHT;
|
||||
if (InPlane(vec[2], originPlane[2], center, radius))
|
||||
result |= FRUSTUM_PLANE_BOTTOM;
|
||||
if (InPlane(vec[3], originPlane[3], center, radius))
|
||||
result |= FRUSTUM_PLANE_TOP;
|
||||
if (InPlane(vec[4], originPlane[4], center, radius))
|
||||
result |= FRUSTUM_PLANE_FRONT;
|
||||
if (InPlane(vec[5], originPlane[5], center, radius))
|
||||
result |= FRUSTUM_PLANE_BACK;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CEngine::InPlane(Math::Vector normal, float originPlane, Math::Vector center, float radius)
|
||||
{
|
||||
float distance = originPlane + Math::DotProduct(normal, center);
|
||||
|
||||
if (distance < -radius)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CEngine::TransformPoint(Math::Vector& p2D, int objRank, Math::Vector p3D)
|
||||
{
|
||||
assert(objRank >= 0 && objRank < static_cast<int>(m_objects.size()));
|
||||
|
@ -3301,6 +3382,22 @@ void CEngine::Draw3DScene()
|
|||
|
||||
UseShadowMapping(true);
|
||||
|
||||
SetState(0);
|
||||
|
||||
auto terrainRenderer = m_device->GetTerrainRenderer();
|
||||
terrainRenderer->Begin();
|
||||
|
||||
terrainRenderer->SetProjectionMatrix(m_matProj);
|
||||
terrainRenderer->SetViewMatrix(m_matView);
|
||||
terrainRenderer->SetShadowMatrix(m_shadowTextureMat);
|
||||
terrainRenderer->SetShadowMap(m_shadowMap);
|
||||
terrainRenderer->SetLight(glm::vec4(1.0, 1.0, -1.0, 0.0), 1.0f, glm::vec3(1.0));
|
||||
|
||||
Math::Matrix scale;
|
||||
scale.Set(3, 3, -1.0f);
|
||||
auto projectionViewMatrix = Math::MultiplyMatrices(m_matProj, scale);
|
||||
projectionViewMatrix = Math::MultiplyMatrices(projectionViewMatrix, m_matView);
|
||||
|
||||
for (int objRank = 0; objRank < static_cast<int>(m_objects.size()); objRank++)
|
||||
{
|
||||
if (! m_objects[objRank].used)
|
||||
|
@ -3312,9 +3409,9 @@ void CEngine::Draw3DScene()
|
|||
if (! m_objects[objRank].drawWorld)
|
||||
continue;
|
||||
|
||||
m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform);
|
||||
auto combinedMatrix = Math::MultiplyMatrices(projectionViewMatrix, m_objects[objRank].transform);
|
||||
|
||||
if (! IsVisible(objRank))
|
||||
if (! IsVisible(combinedMatrix, objRank))
|
||||
continue;
|
||||
|
||||
int baseObjRank = m_objects[objRank].baseObjRank;
|
||||
|
@ -3331,21 +3428,20 @@ void CEngine::Draw3DScene()
|
|||
{
|
||||
EngineBaseObjTexTier& p2 = p1.next[l2];
|
||||
|
||||
SetTexture(p2.tex1, 0);
|
||||
SetTexture(p2.tex2, 1);
|
||||
terrainRenderer->SetPrimaryTexture(p2.tex1);
|
||||
terrainRenderer->SetSecondaryTexture(p2.tex2);
|
||||
|
||||
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
|
||||
{
|
||||
EngineBaseObjDataTier& p3 = p2.next[l3];
|
||||
|
||||
SetMaterial(p3.material);
|
||||
SetState(p3.state);
|
||||
|
||||
DrawObject(p3);
|
||||
terrainRenderer->DrawObject(m_objects[objRank].transform, p3.buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
terrainRenderer->End();
|
||||
|
||||
if (!m_qualityShadows)
|
||||
UseShadowMapping(false);
|
||||
|
||||
|
@ -3373,8 +3469,9 @@ void CEngine::Draw3DScene()
|
|||
continue;
|
||||
|
||||
m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform);
|
||||
auto combinedMatrix = Math::MultiplyMatrices(projectionViewMatrix, m_objects[objRank].transform);
|
||||
|
||||
if (! IsVisible(objRank))
|
||||
if (! IsVisible(combinedMatrix, objRank))
|
||||
continue;
|
||||
|
||||
int baseObjRank = m_objects[objRank].baseObjRank;
|
||||
|
@ -3435,8 +3532,9 @@ void CEngine::Draw3DScene()
|
|||
continue;
|
||||
|
||||
m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform);
|
||||
auto combinedMatrix = Math::MultiplyMatrices(projectionViewMatrix, m_objects[objRank].transform);
|
||||
|
||||
if (! IsVisible(objRank))
|
||||
if (! IsVisible(combinedMatrix, objRank))
|
||||
continue;
|
||||
|
||||
int baseObjRank = m_objects[objRank].baseObjRank;
|
||||
|
@ -3930,6 +4028,8 @@ void CEngine::RenderShadowMap()
|
|||
m_device->SetTexture(1, 0);
|
||||
m_device->SetTexture(2, 0);
|
||||
|
||||
auto projectionViewMatrix = Math::MultiplyMatrices(m_shadowProjMat, m_shadowViewMat);
|
||||
|
||||
// render objects into shadow map
|
||||
for (int objRank = 0; objRank < static_cast<int>(m_objects.size()); objRank++)
|
||||
{
|
||||
|
@ -3956,8 +4056,9 @@ void CEngine::RenderShadowMap()
|
|||
}
|
||||
|
||||
m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform);
|
||||
auto combinedMatrix = Math::MultiplyMatrices(projectionViewMatrix, m_objects[objRank].transform);
|
||||
|
||||
if (!IsVisible(objRank))
|
||||
if (!IsVisible(combinedMatrix, objRank))
|
||||
continue;
|
||||
|
||||
int baseObjRank = m_objects[objRank].baseObjRank;
|
||||
|
@ -4170,6 +4271,8 @@ void CEngine::DrawInterface()
|
|||
|
||||
m_device->SetTransform(TRANSFORM_VIEW, m_matView);
|
||||
|
||||
auto projectionViewMatrix = Math::MultiplyMatrices(m_matProj, m_matView);
|
||||
|
||||
for (int objRank = 0; objRank < static_cast<int>(m_objects.size()); objRank++)
|
||||
{
|
||||
if (! m_objects[objRank].used)
|
||||
|
@ -4182,8 +4285,9 @@ void CEngine::DrawInterface()
|
|||
continue;
|
||||
|
||||
m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform);
|
||||
auto combinedMatrix = Math::MultiplyMatrices(projectionViewMatrix, m_objects[objRank].transform);
|
||||
|
||||
if (! IsVisible(objRank))
|
||||
if (! IsVisible(combinedMatrix, objRank))
|
||||
continue;
|
||||
|
||||
int baseObjRank = m_objects[objRank].baseObjRank;
|
||||
|
|
|
@ -1256,7 +1256,11 @@ protected:
|
|||
Texture CreateTexture(const std::string &texName, const TextureCreateParams ¶ms, CImage* image = nullptr);
|
||||
|
||||
//! Tests whether the given object is visible
|
||||
bool IsVisible(int objRank);
|
||||
bool IsVisible(const Math::Matrix& matrix, int objRank);
|
||||
|
||||
int ComputeSphereVisibility(const Math::Matrix& m, const Math::Vector& center, float radius);
|
||||
|
||||
bool InPlane(Math::Vector normal, float originPlane, Math::Vector center, float radius);
|
||||
|
||||
//! Detects whether an object is affected by the mouse
|
||||
bool DetectBBox(int objRank, Math::Point mouse);
|
||||
|
|
|
@ -260,20 +260,15 @@ CGL33TerrainRenderer::CGL33TerrainRenderer(CGL33Device* device)
|
|||
// Setup uniforms
|
||||
auto identity = glm::identity<glm::mat4>();
|
||||
|
||||
m_uniforms.projectionMatrix = identity;
|
||||
m_uniforms.viewMatrix = identity;
|
||||
m_uniforms.modelMatrix = identity;
|
||||
|
||||
glGenBuffers(1, &m_uniformBuffer);
|
||||
glBindBuffer(GL_COPY_WRITE_BUFFER, m_uniformBuffer);
|
||||
glBufferData(GL_COPY_WRITE_BUFFER, sizeof(Uniforms), &m_uniforms, GL_STREAM_DRAW);
|
||||
glBindBuffer(GL_COPY_WRITE_BUFFER, 0);
|
||||
|
||||
// Bind uniform block to uniform buffer binding
|
||||
GLuint blockIndex = glGetUniformBlockIndex(m_program, "Uniforms");
|
||||
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_uniformBuffer);
|
||||
glUniformBlockBinding(m_program, blockIndex, 0);
|
||||
uni_projectionMatrix = glGetUniformLocation(m_program, "uni_ProjectionMatrix");
|
||||
uni_viewMatrix = glGetUniformLocation(m_program, "uni_ViewMatrix");
|
||||
uni_cameraMatrix = glGetUniformLocation(m_program, "uni_CameraMatrix");
|
||||
uni_shadowMatrix = glGetUniformLocation(m_program, "uni_ShadowMatrix");
|
||||
uni_modelMatrix = glGetUniformLocation(m_program, "uni_ModelMatrix");
|
||||
uni_normalMatrix = glGetUniformLocation(m_program, "uni_NormalMatrix");
|
||||
uni_lightPosition = glGetUniformLocation(m_program, "uni_LightPosition");
|
||||
uni_lightIntensity = glGetUniformLocation(m_program, "uni_LightIntensity");
|
||||
uni_lightColor = glGetUniformLocation(m_program, "uni_LightColor");
|
||||
|
||||
// Set texture units to 10th and 11th
|
||||
auto texture = glGetUniformLocation(m_program, "uni_PrimaryTexture");
|
||||
|
@ -282,6 +277,9 @@ CGL33TerrainRenderer::CGL33TerrainRenderer(CGL33Device* device)
|
|||
texture = glGetUniformLocation(m_program, "uni_SecondaryTexture");
|
||||
glUniform1i(texture, 11);
|
||||
|
||||
texture = glGetUniformLocation(m_program, "uni_ShadowMap");
|
||||
glUniform1i(texture, 12);
|
||||
|
||||
// White texture
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glGenTextures(1, &m_whiteTexture);
|
||||
|
@ -319,8 +317,7 @@ void CGL33TerrainRenderer::End()
|
|||
|
||||
void CGL33TerrainRenderer::SetProjectionMatrix(const glm::mat4& matrix)
|
||||
{
|
||||
m_uniforms.projectionMatrix = matrix;
|
||||
m_uniformsDirty = true;
|
||||
glUniformMatrix4fv(uni_projectionMatrix, 1, GL_FALSE, value_ptr(matrix));
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetViewMatrix(const glm::mat4& matrix)
|
||||
|
@ -328,14 +325,24 @@ void CGL33TerrainRenderer::SetViewMatrix(const glm::mat4& matrix)
|
|||
glm::mat4 scale(1.0f);
|
||||
scale[2][2] = -1.0f;
|
||||
|
||||
m_uniforms.viewMatrix = scale * matrix;
|
||||
m_uniformsDirty = true;
|
||||
auto viewMatrix = scale * matrix;
|
||||
auto cameraMatrix = glm::inverse(viewMatrix);
|
||||
|
||||
glUniformMatrix4fv(uni_viewMatrix, 1, GL_FALSE, value_ptr(viewMatrix));
|
||||
glUniformMatrix4fv(uni_cameraMatrix, 1, GL_FALSE, value_ptr(cameraMatrix));
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetModelMatrix(const glm::mat4& matrix)
|
||||
{
|
||||
m_uniforms.modelMatrix = matrix;
|
||||
m_uniformsDirty = true;
|
||||
auto normalMatrix = glm::transpose(glm::inverse(glm::mat3(matrix)));
|
||||
|
||||
glUniformMatrix4fv(uni_modelMatrix, 1, GL_FALSE, value_ptr(matrix));
|
||||
glUniformMatrix3fv(uni_normalMatrix, 1, GL_FALSE, value_ptr(normalMatrix));
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetShadowMatrix(const glm::mat4& matrix)
|
||||
{
|
||||
glUniformMatrix4fv(uni_shadowMatrix, 1, GL_FALSE, value_ptr(matrix));
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetPrimaryTexture(const Texture& texture)
|
||||
|
@ -366,6 +373,27 @@ void CGL33TerrainRenderer::SetSecondaryTexture(const Texture& texture)
|
|||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetShadowMap(const Texture& texture)
|
||||
{
|
||||
if (m_shadowMap == texture.id) return;
|
||||
|
||||
m_shadowMap = texture.id;
|
||||
|
||||
glActiveTexture(GL_TEXTURE12);
|
||||
|
||||
if (texture.id == 0)
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetLight(const glm::vec4& position, const float& intensity, const glm::vec3& color)
|
||||
{
|
||||
glUniform4fv(uni_lightPosition, 1, glm::value_ptr(position));
|
||||
glUniform1f(uni_lightIntensity, intensity);
|
||||
glUniform3fv(uni_lightColor, 1, glm::value_ptr(color));
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::DrawObject(const glm::mat4& matrix, const CVertexBuffer* buffer)
|
||||
{
|
||||
auto b = dynamic_cast<const CGL33VertexBuffer*>(buffer);
|
||||
|
@ -377,18 +405,6 @@ void CGL33TerrainRenderer::DrawObject(const glm::mat4& matrix, const CVertexBuff
|
|||
}
|
||||
|
||||
SetModelMatrix(matrix);
|
||||
|
||||
if (m_uniformsDirty)
|
||||
{
|
||||
glBindBuffer(GL_COPY_WRITE_BUFFER, m_uniformBuffer);
|
||||
glBufferData(GL_COPY_WRITE_BUFFER, sizeof(Uniforms), nullptr, GL_STREAM_DRAW);
|
||||
glBufferSubData(GL_COPY_WRITE_BUFFER, 0, sizeof(Uniforms), &m_uniforms);
|
||||
glBindBuffer(GL_COPY_WRITE_BUFFER, 0);
|
||||
|
||||
m_uniformsDirty = false;
|
||||
}
|
||||
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_uniformBuffer);
|
||||
glBindVertexArray(b->GetVAO());
|
||||
|
||||
glDrawArrays(TranslateGfxPrimitive(b->GetType()), 0, b->Size());
|
||||
|
|
|
@ -108,11 +108,18 @@ public:
|
|||
virtual void SetViewMatrix(const glm::mat4& matrix) override;
|
||||
//! Sets model matrix
|
||||
virtual void SetModelMatrix(const glm::mat4& matrix) override;
|
||||
//! Sets shadow matrix
|
||||
virtual void SetShadowMatrix(const glm::mat4& matrix) override;
|
||||
|
||||
//! Sets primary texture, setting texture 0 means using white texture
|
||||
virtual void SetPrimaryTexture(const Texture& texture) override;
|
||||
//! Sets secondary texture
|
||||
virtual void SetSecondaryTexture(const Texture& texture) override;
|
||||
//! Sets shadow map
|
||||
virtual void SetShadowMap(const Texture& texture) override;
|
||||
|
||||
//! Sets light parameters
|
||||
virtual void SetLight(const glm::vec4& position, const float& intensity, const glm::vec3& color) override;
|
||||
|
||||
//! Draws terrain object
|
||||
virtual void DrawObject(const glm::mat4& matrix, const CVertexBuffer* buffer) override;
|
||||
|
@ -123,19 +130,15 @@ private:
|
|||
CGL33Device* const m_device;
|
||||
|
||||
// Uniform data
|
||||
struct Uniforms
|
||||
{
|
||||
glm::mat4 projectionMatrix;
|
||||
glm::mat4 viewMatrix;
|
||||
glm::mat4 modelMatrix;
|
||||
};
|
||||
|
||||
Uniforms m_uniforms = {};
|
||||
|
||||
// true means uniforms need to be updated
|
||||
bool m_uniformsDirty = false;
|
||||
|
||||
GLuint m_uniformBuffer = 0;
|
||||
GLint uni_projectionMatrix;
|
||||
GLint uni_viewMatrix;
|
||||
GLint uni_cameraMatrix;
|
||||
GLint uni_shadowMatrix;
|
||||
GLint uni_modelMatrix;
|
||||
GLint uni_normalMatrix;
|
||||
GLint uni_lightPosition;
|
||||
GLint uni_lightIntensity;
|
||||
GLint uni_lightColor;
|
||||
|
||||
// Shader program
|
||||
GLuint m_program = 0;
|
||||
|
@ -146,6 +149,8 @@ private:
|
|||
GLuint m_primaryTexture = 0;
|
||||
// Currently bound secondary texture
|
||||
GLuint m_secondaryTexture = 0;
|
||||
// Currently bound shadow map
|
||||
GLuint m_shadowMap = 0;
|
||||
};
|
||||
|
||||
} // namespace Gfx
|
||||
|
|
|
@ -20,8 +20,16 @@
|
|||
// FRAGMENT SHADER - TERRAIN RENDERER
|
||||
#version 330 core
|
||||
|
||||
uniform mat4 uni_CameraMatrix;
|
||||
uniform vec4 uni_LightPosition;
|
||||
uniform float uni_LightIntensity;
|
||||
uniform vec3 uni_LightColor;
|
||||
|
||||
uniform sampler2D uni_PrimaryTexture;
|
||||
uniform sampler2D uni_SecondaryTexture;
|
||||
uniform sampler2DShadow uni_ShadowMap;
|
||||
|
||||
const float PI = 3.1415926;
|
||||
|
||||
in VertexData
|
||||
{
|
||||
|
@ -30,19 +38,80 @@ in VertexData
|
|||
vec2 TexCoord1;
|
||||
vec3 Normal;
|
||||
vec4 ShadowCoord;
|
||||
vec4 LightColor;
|
||||
float Distance;
|
||||
vec3 CameraDirection;
|
||||
vec3 Position;
|
||||
} data;
|
||||
|
||||
out vec4 out_FragColor;
|
||||
|
||||
vec3 schlickFresnel(float LdH, float metalness, vec3 color)
|
||||
{
|
||||
vec3 f = mix(vec3(0.04), color, metalness);
|
||||
|
||||
return f + (1.0 - f) * pow(1.0 - LdH, 5.0);
|
||||
}
|
||||
|
||||
float geomSmith(float dotProd, float roughness)
|
||||
{
|
||||
float k = (roughness + 1.0) * (roughness + 1.0) / 8.0;
|
||||
float denom = dotProd * (1 - k) + k;
|
||||
return 1.0 / denom;
|
||||
}
|
||||
|
||||
float ggxDistribution(float NdH, float roughness)
|
||||
{
|
||||
float alpha2 = roughness * roughness * roughness * roughness;
|
||||
float d = (NdH * NdH) * (alpha2 - 1) + 1.0;
|
||||
return alpha2 / (PI * d * d);
|
||||
}
|
||||
|
||||
vec3 PBR(vec3 position, vec3 color, vec3 normal, float roughness, float metalness)
|
||||
{
|
||||
vec3 diffuseBrdf = mix(color, vec3(0.0), metalness);
|
||||
|
||||
vec3 light = normalize(uni_LightPosition.xyz);
|
||||
float lightIntensity = 1.0;
|
||||
|
||||
vec3 view = normalize(uni_CameraMatrix[3].xyz - position);
|
||||
vec3 halfway = normalize(view + light);
|
||||
|
||||
float NdH = dot(normal, halfway);
|
||||
float LdH = dot(light, halfway);
|
||||
float NdL = max(dot(normal, light), 0.0);
|
||||
float NdV = dot(normal, view);
|
||||
|
||||
vec3 specBrdf = 0.25 * ggxDistribution(NdH, roughness)
|
||||
* schlickFresnel(LdH, metalness, color)
|
||||
* geomSmith(NdL, roughness)
|
||||
* geomSmith(NdV, roughness);
|
||||
|
||||
return (diffuseBrdf + PI * specBrdf) * lightIntensity * uni_LightColor * NdL;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = data.Color;
|
||||
vec3 albedo = data.Color.rgb;
|
||||
|
||||
color = color * texture(uni_PrimaryTexture, data.TexCoord0);
|
||||
color = color * texture(uni_SecondaryTexture, data.TexCoord1);
|
||||
albedo *= texture(uni_PrimaryTexture, data.TexCoord0).rgb;
|
||||
albedo *= texture(uni_SecondaryTexture, data.TexCoord1).rgb;
|
||||
|
||||
out_FragColor = color;
|
||||
float roughness = 0.7;
|
||||
float metalness = 0.0;
|
||||
|
||||
float value = texture(uni_ShadowMap, data.ShadowCoord.xyz);
|
||||
value += textureOffset(uni_ShadowMap, data.ShadowCoord.xyz, ivec2( 1, 0));
|
||||
value += textureOffset(uni_ShadowMap, data.ShadowCoord.xyz, ivec2(-1, 0));
|
||||
value += textureOffset(uni_ShadowMap, data.ShadowCoord.xyz, ivec2( 0, 1));
|
||||
value += textureOffset(uni_ShadowMap, data.ShadowCoord.xyz, ivec2( 0,-1));
|
||||
float shadow = value * (1.0f / 5.0f);
|
||||
|
||||
shadow = mix(0.5, 1.0, shadow);
|
||||
|
||||
vec3 lighting = PBR(data.Position, albedo, data.Normal, roughness, metalness);
|
||||
|
||||
vec3 skyColor = vec3(1.0);
|
||||
float skyIntensity = 0.10;
|
||||
|
||||
vec3 color = lighting * shadow + albedo * skyColor * skyIntensity;
|
||||
|
||||
out_FragColor = vec4(color, 1.0);
|
||||
}
|
||||
|
|
|
@ -20,12 +20,11 @@
|
|||
// VERTEX SHADER - TERRAIN RENDERER
|
||||
#version 330 core
|
||||
|
||||
uniform Uniforms
|
||||
{
|
||||
mat4 uni_ProjectionMatrix;
|
||||
mat4 uni_ViewMatrix;
|
||||
mat4 uni_ModelMatrix;
|
||||
};
|
||||
uniform mat4 uni_ProjectionMatrix;
|
||||
uniform mat4 uni_ViewMatrix;
|
||||
uniform mat4 uni_ModelMatrix;
|
||||
uniform mat4 uni_ShadowMatrix;
|
||||
uniform mat3 uni_NormalMatrix;
|
||||
|
||||
layout(location = 0) in vec4 in_VertexCoord;
|
||||
layout(location = 1) in vec3 in_Normal;
|
||||
|
@ -40,9 +39,7 @@ out VertexData
|
|||
vec2 TexCoord1;
|
||||
vec3 Normal;
|
||||
vec4 ShadowCoord;
|
||||
vec4 LightColor;
|
||||
float Distance;
|
||||
vec3 CameraDirection;
|
||||
vec3 Position;
|
||||
} data;
|
||||
|
||||
void main()
|
||||
|
@ -50,13 +47,13 @@ void main()
|
|||
vec4 position = uni_ModelMatrix * in_VertexCoord;
|
||||
vec4 eyeSpace = uni_ViewMatrix * position;
|
||||
gl_Position = uni_ProjectionMatrix * eyeSpace;
|
||||
//vec4 shadowCoord = uni_ShadowMatrix * position;
|
||||
vec4 shadowCoord = uni_ShadowMatrix * position;
|
||||
|
||||
data.Color = in_Color;
|
||||
data.TexCoord0 = in_TexCoord0;
|
||||
data.TexCoord1 = in_TexCoord1;
|
||||
data.Normal = in_Normal;//normalize((uni_NormalMatrix * vec4(in_Normal, 0.0f)).xyz);
|
||||
//data.ShadowCoord = vec4(shadowCoord.xyz / shadowCoord.w, 1.0f);
|
||||
data.Normal = mat3(uni_NormalMatrix) * in_Normal;
|
||||
data.ShadowCoord = vec4(shadowCoord.xyz / shadowCoord.w, 1.0f);
|
||||
//data.Distance = abs(eyeSpace.z);
|
||||
//data.CameraDirection = uni_CameraPosition - position.xyz;
|
||||
data.Position = position.xyz;
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ struct Matrix
|
|||
* \param col column (1 to 4)
|
||||
* \returns value
|
||||
*/
|
||||
float Get(int row, int col)
|
||||
float Get(int row, int col) const
|
||||
{
|
||||
return m[(col-1)*4+(row-1)];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue