mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
feat(renderer): add roughness-based specular lighting to blocks
This commit is contained in:
@@ -7,4 +7,5 @@ is_liquid = false
|
|||||||
is_passable = true
|
is_passable = true
|
||||||
is_transitional = false
|
is_transitional = false
|
||||||
is_transparent = true
|
is_transparent = true
|
||||||
name = 'air'
|
name = 'air'
|
||||||
|
roughness = 1.0
|
||||||
@@ -7,4 +7,5 @@ is_liquid = false
|
|||||||
is_passable = false
|
is_passable = false
|
||||||
is_transitional = true
|
is_transitional = true
|
||||||
is_transparent = false
|
is_transparent = false
|
||||||
name = 'dirt'
|
name = 'dirt'
|
||||||
|
roughness = 1.0
|
||||||
@@ -7,4 +7,5 @@ is_liquid = false
|
|||||||
is_passable = true
|
is_passable = true
|
||||||
is_transitional = false
|
is_transitional = false
|
||||||
is_transparent = true
|
is_transparent = true
|
||||||
name = 'grass'
|
name = 'grass'
|
||||||
|
roughness = 0.9
|
||||||
@@ -7,4 +7,5 @@ is_liquid = false
|
|||||||
is_passable = false
|
is_passable = false
|
||||||
is_transitional = true
|
is_transitional = true
|
||||||
is_transparent = false
|
is_transparent = false
|
||||||
name = 'grass_block'
|
name = 'grass_block'
|
||||||
|
roughness = 0.9
|
||||||
@@ -7,4 +7,5 @@ is_liquid = false
|
|||||||
is_passable = false
|
is_passable = false
|
||||||
is_transitional = false
|
is_transitional = false
|
||||||
is_transparent = true
|
is_transparent = true
|
||||||
name = 'leaf'
|
name = 'leaf'
|
||||||
|
roughness = 0.7
|
||||||
@@ -7,4 +7,5 @@ is_liquid = false
|
|||||||
is_passable = false
|
is_passable = false
|
||||||
is_transitional = false
|
is_transitional = false
|
||||||
is_transparent = false
|
is_transparent = false
|
||||||
name = 'log'
|
name = 'log'
|
||||||
|
roughness = 0.7
|
||||||
@@ -7,4 +7,5 @@ is_liquid = false
|
|||||||
is_passable = false
|
is_passable = false
|
||||||
is_transitional = true
|
is_transitional = true
|
||||||
is_transparent = false
|
is_transparent = false
|
||||||
name = 'sand'
|
name = 'sand'
|
||||||
|
roughness = 0.8
|
||||||
@@ -7,4 +7,5 @@ is_liquid = false
|
|||||||
is_passable = false
|
is_passable = false
|
||||||
is_transitional = true
|
is_transitional = true
|
||||||
is_transparent = false
|
is_transparent = false
|
||||||
name = 'snowy_grass_block'
|
name = 'snowy_grass_block'
|
||||||
|
roughness = 0.9
|
||||||
@@ -7,4 +7,5 @@ is_liquid = false
|
|||||||
is_passable = false
|
is_passable = false
|
||||||
is_transitional = true
|
is_transitional = true
|
||||||
is_transparent = false
|
is_transparent = false
|
||||||
name = 'stone'
|
name = 'stone'
|
||||||
|
roughness = 0.75
|
||||||
@@ -8,3 +8,4 @@ is_transparent = false
|
|||||||
is_discard = false
|
is_discard = false
|
||||||
is_blend = false
|
is_blend = false
|
||||||
is_transitional = false
|
is_transitional = false
|
||||||
|
roughness = 1.0
|
||||||
@@ -7,4 +7,5 @@ is_liquid = true
|
|||||||
is_passable = true
|
is_passable = true
|
||||||
is_transitional = false
|
is_transitional = false
|
||||||
is_transparent = true
|
is_transparent = true
|
||||||
name = 'water'
|
name = 'water'
|
||||||
|
roughness = 0.02
|
||||||
@@ -4,6 +4,7 @@ in vec2 tc;
|
|||||||
in vec3 normal;
|
in vec3 normal;
|
||||||
in vec3 vert_pos;
|
in vec3 vert_pos;
|
||||||
in vec4 FragPosLightSpace;
|
in vec4 FragPosLightSpace;
|
||||||
|
in float roughness;
|
||||||
flat in int tex_layer;
|
flat in int tex_layer;
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
layout (binding = 0) uniform sampler2D shadowMap;
|
layout (binding = 0) uniform sampler2D shadowMap;
|
||||||
@@ -12,9 +13,10 @@ layout (binding = 1) uniform sampler2DArray samp;
|
|||||||
uniform float ambientStrength;
|
uniform float ambientStrength;
|
||||||
uniform vec3 sunlightColor;
|
uniform vec3 sunlightColor;
|
||||||
uniform vec3 sunlightDir;
|
uniform vec3 sunlightDir;
|
||||||
|
uniform vec3 cameraPos;
|
||||||
uniform bool shader_on;
|
uniform bool shader_on;
|
||||||
uniform int shadowMode;
|
uniform int shadowMode;
|
||||||
|
uniform float specularStrength;
|
||||||
uniform float lightSizeUV;
|
uniform float lightSizeUV;
|
||||||
uniform float minRadius;
|
uniform float minRadius;
|
||||||
uniform float maxRadius;
|
uniform float maxRadius;
|
||||||
@@ -271,17 +273,56 @@ void main(void) {
|
|||||||
|
|
||||||
vec3 lightDir = normalize(-sunlightDir);
|
vec3 lightDir = normalize(-sunlightDir);
|
||||||
|
|
||||||
vec3 ambient = ambientStrength * sunlightColor;
|
|
||||||
|
|
||||||
vec3 norm = normalize(normal);
|
vec3 norm = normalize(normal);
|
||||||
|
|
||||||
|
vec3 V =
|
||||||
|
normalize(cameraPos - vert_pos);
|
||||||
|
|
||||||
|
vec3 H =
|
||||||
|
normalize(lightDir + V);
|
||||||
|
|
||||||
|
vec3 ambient = ambientStrength * sunlightColor;
|
||||||
|
|
||||||
float diff = max(dot(norm, lightDir), 0.0);
|
float diff = max(dot(norm, lightDir), 0.0);
|
||||||
|
|
||||||
vec3 diffuse = diff * sunlightColor;
|
vec3 diffuse = diff * sunlightColor;
|
||||||
|
|
||||||
|
float r =
|
||||||
|
clamp(roughness, 0.0, 1.0);
|
||||||
|
|
||||||
|
float shininess =
|
||||||
|
mix(
|
||||||
|
512.0,
|
||||||
|
4.0,
|
||||||
|
r
|
||||||
|
);
|
||||||
|
float ks =
|
||||||
|
mix(
|
||||||
|
0.8,
|
||||||
|
0.02,
|
||||||
|
r
|
||||||
|
);
|
||||||
|
|
||||||
|
float spec = 0.0;
|
||||||
|
|
||||||
|
if(diff > 0.0)
|
||||||
|
{
|
||||||
|
spec =
|
||||||
|
ks *
|
||||||
|
pow(
|
||||||
|
max(dot(norm,H),0.0),
|
||||||
|
shininess
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vec3 specular = spec * sunlightColor * specularStrength;
|
||||||
|
|
||||||
float shadow = ShadowCalculation(FragPosLightSpace, norm, lightDir);
|
float shadow = ShadowCalculation(FragPosLightSpace, norm, lightDir);
|
||||||
|
|
||||||
color = vec4((ambient + (1.0 - shadow) * (diffuse)) * objectColor.rgb, objectColor.a);
|
color = vec4((ambient + (1.0 - shadow) * (diffuse)) * objectColor.rgb + (1.0-shadow) * specular, objectColor.a);
|
||||||
|
|
||||||
//color = varyingColor;
|
//color = varyingColor;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,14 @@ layout (location = 0) in vec3 pos;
|
|||||||
layout (location = 1) in vec2 texCoord;
|
layout (location = 1) in vec2 texCoord;
|
||||||
layout (location = 2) in float layer;
|
layout (location = 2) in float layer;
|
||||||
layout (location = 3) in vec3 aNormal;
|
layout (location = 3) in vec3 aNormal;
|
||||||
|
layout (location = 4) in float Roughness;
|
||||||
|
|
||||||
out vec2 tc;
|
out vec2 tc;
|
||||||
out vec3 normal;
|
out vec3 normal;
|
||||||
out vec3 vert_pos;
|
out vec3 vert_pos;
|
||||||
flat out int tex_layer;
|
flat out int tex_layer;
|
||||||
out vec4 FragPosLightSpace;
|
out vec4 FragPosLightSpace;
|
||||||
|
out float roughness;
|
||||||
|
|
||||||
mat4 buildRotateX(float rad);
|
mat4 buildRotateX(float rad);
|
||||||
mat4 buildRotateY(float rad);
|
mat4 buildRotateY(float rad);
|
||||||
@@ -28,7 +31,7 @@ void main(void) {
|
|||||||
tc = texCoord;
|
tc = texCoord;
|
||||||
|
|
||||||
tex_layer = int(layer);
|
tex_layer = int(layer);
|
||||||
|
roughness = Roughness;
|
||||||
normal = mat3(norm_matrix) * aNormal;
|
normal = mat3(norm_matrix) * aNormal;
|
||||||
FragPosLightSpace = lightSpaceMatrix * vec4(pos, 1.0);
|
FragPosLightSpace = lightSpaceMatrix * vec4(pos, 1.0);
|
||||||
gl_Position = proj_matrix * viewPos;
|
gl_Position = proj_matrix * viewPos;
|
||||||
|
|||||||
@@ -51,13 +51,14 @@ struct BlockData {
|
|||||||
bool is_discard = false;
|
bool is_discard = false;
|
||||||
bool is_blend = false;
|
bool is_blend = false;
|
||||||
bool is_transitional = false;
|
bool is_transitional = false;
|
||||||
|
float roughness = 1.0f;
|
||||||
BlockData(BlockType b_id, std::string_view b_name, bool liquid,
|
BlockData(BlockType b_id, std::string_view b_name, bool liquid,
|
||||||
bool passable, bool cross_plane, bool transparent, bool gas,
|
bool passable, bool cross_plane, bool transparent, bool gas,
|
||||||
bool discard, bool blend, bool transitional)
|
bool discard, bool blend, bool transitional, float r)
|
||||||
: name(b_name), id(b_id), is_liquid(liquid), is_gas(gas),
|
: name(b_name), id(b_id), is_liquid(liquid), is_gas(gas),
|
||||||
is_passable(passable), is_cross_plane(cross_plane),
|
is_passable(passable), is_cross_plane(cross_plane),
|
||||||
is_transparent(transparent), is_discard(discard), is_blend(blend),
|
is_transparent(transparent), is_discard(discard), is_blend(blend),
|
||||||
is_transitional(transitional) {}
|
is_transitional(transitional), roughness(r) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class BlockManager {
|
class BlockManager {
|
||||||
@@ -79,6 +80,7 @@ public:
|
|||||||
static bool is_discard(BlockType id);
|
static bool is_discard(BlockType id);
|
||||||
static bool is_blend(BlockType id);
|
static bool is_blend(BlockType id);
|
||||||
static bool is_transitional(BlockType id);
|
static bool is_transitional(BlockType id);
|
||||||
|
static float roughness(BlockType id);
|
||||||
static BlockType cross_plane_index(BlockType id);
|
static BlockType cross_plane_index(BlockType id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -224,6 +224,7 @@ struct Vertex3D {
|
|||||||
float s = 0.0f, t = 0.0f;
|
float s = 0.0f, t = 0.0f;
|
||||||
float layer = 0.0f;
|
float layer = 0.0f;
|
||||||
float nx = 0.0f, ny = 0.0f, nz = 0.0f;
|
float nx = 0.0f, ny = 0.0f, nz = 0.0f;
|
||||||
|
float roughness = 1.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Vertex2D {
|
struct Vertex2D {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public:
|
|||||||
float& min_radius();
|
float& min_radius();
|
||||||
float& max_radius();
|
float& max_radius();
|
||||||
int& samples();
|
int& samples();
|
||||||
|
float& specular_strength();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr glm::vec3 SUNLIGHT_COLOR{1.0f, 1.0f, 1.0f};
|
static constexpr glm::vec3 SUNLIGHT_COLOR{1.0f, 1.0f, 1.0f};
|
||||||
@@ -108,6 +109,9 @@ private:
|
|||||||
float m_min_radius = 2.0f;
|
float m_min_radius = 2.0f;
|
||||||
float m_max_radius = 20.0f;
|
float m_max_radius = 20.0f;
|
||||||
int m_samples = 16;
|
int m_samples = 16;
|
||||||
|
|
||||||
|
float m_specular_strength = 0.5f;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
0 - quad vao
|
0 - quad vao
|
||||||
1 - sky vao
|
1 - sky vao
|
||||||
|
|||||||
@@ -111,6 +111,15 @@ bool BlockManager::is_transitional(BlockType id) {
|
|||||||
}
|
}
|
||||||
return m_datas[id].is_transitional;
|
return m_datas[id].is_transitional;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float BlockManager::roughness(BlockType id) {
|
||||||
|
if (id >= sums()) {
|
||||||
|
Logger::error("Id {}, is Over The Max Id", id, sums() - 1);
|
||||||
|
return m_datas[0].roughness;
|
||||||
|
}
|
||||||
|
return m_datas[id].roughness;
|
||||||
|
}
|
||||||
|
|
||||||
void BlockManager::init() {
|
void BlockManager::init() {
|
||||||
fs::path data_path{block_data_dir};
|
fs::path data_path{block_data_dir};
|
||||||
|
|
||||||
@@ -149,9 +158,11 @@ void BlockManager::init() {
|
|||||||
auto is_discard = safe_get_value(block, "is_discard", false);
|
auto is_discard = safe_get_value(block, "is_discard", false);
|
||||||
auto is_blend = safe_get_value(block, "is_blend", false);
|
auto is_blend = safe_get_value(block, "is_blend", false);
|
||||||
auto is_transitional = safe_get_value(block, "is_transitional", false);
|
auto is_transitional = safe_get_value(block, "is_transitional", false);
|
||||||
|
auto roughness = safe_get_value(block, "roughness", 1.0);
|
||||||
m_datas.emplace_back(*id, *name, *is_liquid, *is_passable,
|
m_datas.emplace_back(*id, *name, *is_liquid, *is_passable,
|
||||||
*is_cross_plane, *is_transparent, *is_gas,
|
*is_cross_plane, *is_transparent, *is_gas,
|
||||||
*is_discard, *is_blend, *is_transitional);
|
*is_discard, *is_blend, *is_transitional,
|
||||||
|
static_cast<float>(*roughness));
|
||||||
}
|
}
|
||||||
std::sort(
|
std::sort(
|
||||||
m_datas.begin(), m_datas.end(),
|
m_datas.begin(), m_datas.end(),
|
||||||
|
|||||||
@@ -621,6 +621,8 @@ void DevPanel::show_shader_tab_item() {
|
|||||||
&m_app.renderer().ambient_strength(), 0.0f,
|
&m_app.renderer().ambient_strength(), 0.0f,
|
||||||
0.35f))
|
0.35f))
|
||||||
;
|
;
|
||||||
|
ImGui::SliderFloat("SpecularStrength",
|
||||||
|
&m_app.renderer().specular_strength(), 0.0f, 2.0f);
|
||||||
ImGui::Checkbox("Discard Transparent",
|
ImGui::Checkbox("Discard Transparent",
|
||||||
&m_app.renderer().discard_transparent());
|
&m_app.renderer().discard_transparent());
|
||||||
ImGui::Combo("ShaderMode", &m_app.renderer().shadow_mode(), shader_mode,
|
ImGui::Combo("ShaderMode", &m_app.renderer().shadow_mode(), shader_mode,
|
||||||
|
|||||||
@@ -377,7 +377,8 @@ void Chunk::gen_vertices(const OptionalBlockVectorArray& neighbor_block) {
|
|||||||
|
|
||||||
NORMALS[face][i][0],
|
NORMALS[face][i][0],
|
||||||
NORMALS[face][i][1],
|
NORMALS[face][i][1],
|
||||||
NORMALS[face][i][2]
|
NORMALS[face][i][2],
|
||||||
|
BlockManager::roughness(cur_id)
|
||||||
|
|
||||||
};
|
};
|
||||||
if (BlockManager::is_transparent(cur_id)) {
|
if (BlockManager::is_transparent(cur_id)) {
|
||||||
@@ -427,7 +428,8 @@ void Chunk::gen_cross_plane_vertices(int world_x, int world_y, int world_z,
|
|||||||
static_cast<float>(BlockManager::cross_plane_index(id)),
|
static_cast<float>(BlockManager::cross_plane_index(id)),
|
||||||
CROSS_NORMALS[face][i][0],
|
CROSS_NORMALS[face][i][0],
|
||||||
CROSS_NORMALS[face][i][1],
|
CROSS_NORMALS[face][i][1],
|
||||||
CROSS_NORMALS[face][i][2]
|
CROSS_NORMALS[face][i][2],
|
||||||
|
BlockManager::roughness(id)
|
||||||
|
|
||||||
};
|
};
|
||||||
m_vertex_data[1].m_vertices.emplace_back(vex);
|
m_vertex_data[1].m_vertices.emplace_back(vex);
|
||||||
|
|||||||
@@ -51,10 +51,13 @@ void VertexData::upload() {
|
|||||||
(void*)offsetof(Vertex3D, layer));
|
(void*)offsetof(Vertex3D, layer));
|
||||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D),
|
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D),
|
||||||
(void*)offsetof(Vertex3D, nx));
|
(void*)offsetof(Vertex3D, nx));
|
||||||
|
glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex3D),
|
||||||
|
(void*)offsetof(Vertex3D, roughness));
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
glEnableVertexAttribArray(1);
|
glEnableVertexAttribArray(1);
|
||||||
glEnableVertexAttribArray(2);
|
glEnableVertexAttribArray(2);
|
||||||
glEnableVertexAttribArray(3);
|
glEnableVertexAttribArray(3);
|
||||||
|
glEnableVertexAttribArray(4);
|
||||||
|
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|||||||
@@ -640,6 +640,10 @@ void Renderer::render_world() {
|
|||||||
glUniform1f(normal_block_shader.loc("minRadius"), m_min_radius);
|
glUniform1f(normal_block_shader.loc("minRadius"), m_min_radius);
|
||||||
glUniform1f(normal_block_shader.loc("maxRadius"), m_max_radius);
|
glUniform1f(normal_block_shader.loc("maxRadius"), m_max_radius);
|
||||||
glUniform1i(normal_block_shader.loc("samples"), m_samples);
|
glUniform1i(normal_block_shader.loc("samples"), m_samples);
|
||||||
|
glUniform1f(normal_block_shader.loc("specularStrength"),
|
||||||
|
m_specular_strength);
|
||||||
|
glUniform3fv(normal_block_shader.loc("cameraPos"), 1,
|
||||||
|
glm::value_ptr(m_camera.get_camera_pos()));
|
||||||
m_mvp_mat = m_p_mat * m_mv_mat;
|
m_mvp_mat = m_p_mat * m_mv_mat;
|
||||||
|
|
||||||
auto& m_planes = m_world.planes();
|
auto& m_planes = m_world.planes();
|
||||||
@@ -825,4 +829,5 @@ int& Renderer::light_size_uv() { return m_light_size_uv; }
|
|||||||
float& Renderer::min_radius() { return m_min_radius; }
|
float& Renderer::min_radius() { return m_min_radius; }
|
||||||
float& Renderer::max_radius() { return m_max_radius; }
|
float& Renderer::max_radius() { return m_max_radius; }
|
||||||
int& Renderer::samples() { return m_samples; }
|
int& Renderer::samples() { return m_samples; }
|
||||||
|
float& Renderer::specular_strength() { return m_specular_strength; }
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
Reference in New Issue
Block a user