mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-06-18 00:27:02 +08:00
refactor: transparent render (#14)
* fix(renderer): defer uniform location retrieval and add view matrix in outline rendering * refactor(gameplay): encapsulate per-type vertex data into VertexData struct * feat(rendering): separate transparent blocks into discard and blend modes * feat(renderer): implement order-independent transparency * fix(shaders): reduce alpha discard threshold to 0.8
This commit is contained in:
@@ -47,11 +47,16 @@ struct BlockData {
|
||||
bool is_passable = false;
|
||||
bool is_cross_plane = false;
|
||||
bool is_transparent = false;
|
||||
|
||||
bool is_discard = false;
|
||||
bool is_blend = false;
|
||||
|
||||
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)
|
||||
: name(b_name), id(b_id), is_liquid(liquid), is_gas(gas),
|
||||
is_passable(passable), is_cross_plane(cross_plane),
|
||||
is_transparent(transparent) {}
|
||||
is_transparent(transparent), is_discard(discard), is_blend(blend) {}
|
||||
};
|
||||
|
||||
class BlockManager {
|
||||
@@ -69,6 +74,10 @@ public:
|
||||
static bool is_cross_plane(BlockType id);
|
||||
static bool is_transparent(BlockType id);
|
||||
static bool is_passable(BlockType id);
|
||||
|
||||
static bool is_discard(BlockType id);
|
||||
static bool is_blend(BlockType id);
|
||||
|
||||
static BlockType cross_plane_index(BlockType id);
|
||||
|
||||
private:
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "Cubed/gameplay/block.hpp"
|
||||
#include "Cubed/gameplay/chunk_generator.hpp"
|
||||
#include "Cubed/gameplay/chunk_pos.hpp"
|
||||
#include "Cubed/primitive_data.hpp"
|
||||
#include "Cubed/gameplay/vertex_data.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
@@ -17,13 +17,10 @@ private:
|
||||
static constexpr int SIZE_X = CHUNK_SIZE;
|
||||
static constexpr int SIZE_Y = WORLD_SIZE_Y;
|
||||
static constexpr int SIZE_Z = CHUNK_SIZE;
|
||||
|
||||
static constexpr int VERTEX_DATA_SUM = 4;
|
||||
std::atomic<bool> m_dirty{false};
|
||||
std::atomic<bool> m_need_upload{true};
|
||||
std::atomic<bool> m_is_on_gen_vertex_data{false};
|
||||
std::atomic<size_t> m_normal_vertices_sum = 0;
|
||||
std::atomic<size_t> m_cross_vertices_sum = 0;
|
||||
std::atomic<size_t> m_transparent_vertices_sum = 0;
|
||||
std::atomic<BiomeType> m_biome = BiomeType::PLAIN;
|
||||
std::mutex m_vertexs_data_mutex;
|
||||
|
||||
@@ -34,12 +31,14 @@ private:
|
||||
HeightMapArray m_heightmap;
|
||||
// the index is a array of block id
|
||||
std::vector<BlockType> m_blocks;
|
||||
GLuint m_normal_vbo = 0;
|
||||
GLuint m_cross_plane_vbo = 0;
|
||||
GLuint m_transparent_normal_vbo = 0;
|
||||
std::vector<Vertex> m_normal_vertices;
|
||||
std::vector<Vertex> m_cross_plane_vertices;
|
||||
std::vector<Vertex> m_transparent_normal_vertices;
|
||||
|
||||
/*
|
||||
0 - normal
|
||||
1 - cross_plane
|
||||
2 - normal_discard
|
||||
3 - transparent and blend
|
||||
*/
|
||||
std::vector<VertexData> m_vertex_data;
|
||||
float frequency = 0.01f;
|
||||
float height = 80;
|
||||
unsigned m_seed = 0;
|
||||
@@ -47,9 +46,10 @@ private:
|
||||
BiomeConditions m_conditions;
|
||||
|
||||
void clear_dirty();
|
||||
void gen_normal_vertices(
|
||||
void gen_vertices(
|
||||
const std::array<const std::vector<BlockType>*, 4>& neighbor_block);
|
||||
void gen_cross_plane_vertices();
|
||||
void gen_cross_plane_vertices(int world_x, int world_y, int world_z,
|
||||
BlockType id);
|
||||
|
||||
public:
|
||||
Chunk(World& world, ChunkPos chunk_pos);
|
||||
@@ -107,8 +107,11 @@ public:
|
||||
GLuint get_cross_vbo() const;
|
||||
size_t get_cross_vertices_sum() const;
|
||||
|
||||
GLuint get_transparent_vbo() const;
|
||||
size_t get_transparent_vertices_sum() const;
|
||||
GLuint get_normal_discard_vbo() const;
|
||||
size_t get_normal_discard_vertices_sum() const;
|
||||
|
||||
GLuint get_normal_blend_vbo() const;
|
||||
size_t get_normal_blend_vertices_sum() const;
|
||||
|
||||
bool is_dirty() const;
|
||||
void mark_dirty();
|
||||
|
||||
24
include/Cubed/gameplay/vertex_data.hpp
Normal file
24
include/Cubed/gameplay/vertex_data.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include "Cubed/primitive_data.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <glad/glad.h>
|
||||
#include <vector>
|
||||
namespace Cubed {
|
||||
class World;
|
||||
struct VertexData {
|
||||
std::vector<Vertex> m_vertices;
|
||||
GLuint m_vbo = 0;
|
||||
std::atomic<std::size_t> m_sum{0};
|
||||
World& m_world;
|
||||
VertexData(World& world);
|
||||
~VertexData();
|
||||
VertexData(const VertexData&) = delete;
|
||||
VertexData(VertexData&&) noexcept;
|
||||
VertexData& operator=(const VertexData&) = delete;
|
||||
VertexData& operator=(VertexData&&) noexcept;
|
||||
|
||||
void upload();
|
||||
void update_sum();
|
||||
};
|
||||
} // namespace Cubed
|
||||
@@ -19,8 +19,10 @@ struct ChunkRenderSnapshot {
|
||||
size_t normal_vertices_count;
|
||||
GLuint cross_vbo;
|
||||
size_t cross_vertices_count;
|
||||
GLuint transparent_vbo;
|
||||
size_t transparent_vertices_count;
|
||||
GLuint normal_discard_vbo;
|
||||
size_t normal_discard_vertices_count;
|
||||
GLuint normal_blend_vbo;
|
||||
size_t normal_blend_vertices_count;
|
||||
glm::vec3 center;
|
||||
glm::vec3 half_extents;
|
||||
};
|
||||
@@ -90,9 +92,6 @@ public:
|
||||
|
||||
Player& get_player(const std::string& name);
|
||||
void init_world();
|
||||
bool is_aabb_in_frustum(const glm::vec3& center,
|
||||
const glm::vec3& half_extents);
|
||||
|
||||
int get_block(const glm::ivec3& block_pos) const;
|
||||
bool is_solid(const glm::ivec3& block_pos) const;
|
||||
bool can_pass_block(const glm::ivec3& block_pos) const;
|
||||
@@ -100,9 +99,6 @@ public:
|
||||
static ChunkPos chunk_pos(int world_x, int world_z);
|
||||
|
||||
void need_gen();
|
||||
void render(const glm::mat4& mvp_matrix,
|
||||
const TextureManager& texture_manager,
|
||||
const glm::vec3& camera_pos);
|
||||
|
||||
void set_block(const glm::ivec3& pos, unsigned id);
|
||||
void update(float delta_time);
|
||||
@@ -121,6 +117,8 @@ public:
|
||||
|
||||
CaveCarver& cave_carcer();
|
||||
RiverWorm& river_worm();
|
||||
std::vector<glm::vec4>& planes();
|
||||
std::vector<ChunkRenderSnapshot>& render_snapshots();
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
|
||||
@@ -15,7 +15,7 @@ class World;
|
||||
class DevPanel;
|
||||
class Renderer {
|
||||
public:
|
||||
constexpr static int NUM_VAO = 6;
|
||||
constexpr static int NUM_VAO = 7;
|
||||
|
||||
Renderer(const Camera& camera, World& world,
|
||||
const TextureManager& texture_manager, DevPanel& dev_panel);
|
||||
@@ -40,6 +40,9 @@ private:
|
||||
|
||||
float m_delta_time = 0.0f;
|
||||
|
||||
float m_width = 0.0f;
|
||||
float m_height = 0.0f;
|
||||
|
||||
glm::mat4 m_p_mat, m_v_mat, m_m_mat, m_mv_mat, m_mvp_mat;
|
||||
|
||||
GLuint m_mv_loc = 0;
|
||||
@@ -55,6 +58,10 @@ private:
|
||||
GLuint m_screen_texture = 0;
|
||||
GLuint m_depth_render_buffer = 0;
|
||||
|
||||
GLuint m_oit_fbo = 0;
|
||||
GLuint m_accum_texture = 0;
|
||||
GLuint m_reveal_texture = 0;
|
||||
GLuint m_oit_depth_render_buffer = 0;
|
||||
GLuint m_quad_vbo = 0;
|
||||
|
||||
glm::mat4 m_ui_proj;
|
||||
|
||||
@@ -9,6 +9,9 @@ void extract_frustum_planes(const glm::mat4& mvp_matrix,
|
||||
std::vector<glm::vec4>& planes);
|
||||
|
||||
float smootherstep(float edge0, float edge1, float x);
|
||||
bool is_aabb_in_frustum(const glm::vec3& center, const glm::vec3& half_extents,
|
||||
const std::vector<glm::vec4>& planes);
|
||||
|
||||
} // namespace Math
|
||||
|
||||
} // namespace Cubed
|
||||
Reference in New Issue
Block a user