Add density levels to grass example z slices

This commit is contained in:
Nikita Lisitsa 2020-10-03 20:42:37 +03:00
parent d8069308ee
commit 969dc1d2f5

View file

@ -110,31 +110,53 @@ static char const grass_slice_vs[] =
R"(#version 330 R"(#version 330
uniform mat4 u_transform; uniform mat4 u_transform;
uniform mat4 u_tile_transform;
uniform float u_density00;
uniform float u_density01;
uniform float u_density10;
uniform float u_density11;
layout (location = 0) in vec4 in_position; layout (location = 0) in vec4 in_position;
layout (location = 1) in vec2 in_texcoord; layout (location = 1) in vec2 in_texcoord;
out vec2 texcoord; out vec3 texcoord;
void main() void main()
{ {
gl_Position = u_transform * in_position; vec2 p = (u_tile_transform * vec4(in_position.xy, 0.0, 1.0)).xy;
texcoord = in_texcoord;
vec2 o = (u_tile_transform * vec4(0.5, 0.5, 0.0, 1.0)).xy;
o = vec2(floor(o.x), floor(o.y));
vec2 d = p - o;
float level = mix(mix(u_density00, u_density01, d.x), mix(u_density10, u_density11, d.x), d.y);
gl_Position = u_transform * vec4(p, in_position.z, 1.0);
texcoord = vec3(in_texcoord, level);
} }
)"; )";
static char const grass_slice_fs[] = static char const grass_slice_fs[] =
R"(#version 330 R"(#version 330
uniform sampler2D u_texture; uniform sampler2DArray u_texture;
in vec2 texcoord; in vec3 texcoord;
out vec4 out_color; out vec4 out_color;
void main() void main()
{ {
vec4 c = texture(u_texture, texcoord); float l0 = floor(texcoord.z);
float l1 = l0 + 1;
float t = texcoord.z - l0;
vec4 c0 = texture(u_texture, vec3(texcoord.xy, l0));
vec4 c1 = texture(u_texture, vec3(texcoord.xy, l1));
vec4 c = mix(c0, c1, t);
// vec4 c = c0;
out_color = vec4(c.rgb / c.a, c.a); out_color = vec4(c.rgb / c.a, c.a);
} }
)"; )";
@ -146,6 +168,8 @@ struct grass_app
int size = 64; int size = 64;
int const density_level_count = 8;
pcg::perlin<float, 2> density; pcg::perlin<float, 2> density;
gfx::program ground_program{ground_vs, ground_fs}; gfx::program ground_program{ground_vs, ground_fs};
@ -156,7 +180,7 @@ struct grass_app
gfx::texture_1d grass_texture; gfx::texture_1d grass_texture;
gfx::program grass_slice_program{grass_slice_vs, grass_slice_fs}; gfx::program grass_slice_program{grass_slice_vs, grass_slice_fs};
gfx::texture_2d grass_slice_z_texture; gfx::texture_2d_array grass_slice_z_texture;
gfx::mesh grass_slice_z_mesh; gfx::mesh grass_slice_z_mesh;
gfx::framebuffer grass_slice_framebuffer; gfx::framebuffer grass_slice_framebuffer;
@ -378,7 +402,7 @@ struct grass_app
{ {
struct vertex struct vertex
{ {
geom::vector<float, 3> position; geom::point<float, 3> position;
geom::vector<float, 2> texcoord; geom::vector<float, 2> texcoord;
}; };
@ -393,20 +417,22 @@ struct grass_app
vertices.push_back({{1.f, 0.f, slice_width}, {1.f, 0.f}}); vertices.push_back({{1.f, 0.f, slice_width}, {1.f, 0.f}});
vertices.push_back({{1.f, 1.f, slice_width}, {1.f, 1.f}}); vertices.push_back({{1.f, 1.f, slice_width}, {1.f, 1.f}});
grass_slice_z_mesh.setup<geom::vector<float, 3>, geom::vector<float, 2>>(); grass_slice_z_mesh.setup<geom::point<float, 3>, geom::vector<float, 2>>();
grass_slice_z_mesh.load(vertices, gl::TRIANGLES, gl::STATIC_DRAW); grass_slice_z_mesh.load(vertices, gl::TRIANGLES, gl::STATIC_DRAW);
std::size_t slice_resolution = 256; std::size_t slice_resolution = 256;
grass_slice_z_texture.load<gfx::color_rgba>(slice_resolution, slice_resolution); grass_slice_z_texture.load<gfx::color_rgba>(slice_resolution, slice_resolution, density_level_count);
grass_slice_renderbuffer.storage(gl::DEPTH24_STENCIL8, slice_resolution, slice_resolution); grass_slice_renderbuffer.storage(gl::DEPTH24_STENCIL8, slice_resolution, slice_resolution);
grass_slice_framebuffer.color(grass_slice_z_texture); for (int d = 0; d < density_level_count; ++d)
{
grass_slice_framebuffer.color(grass_slice_z_texture, d);
grass_slice_framebuffer.depth(grass_slice_renderbuffer); grass_slice_framebuffer.depth(grass_slice_renderbuffer);
grass_slice_framebuffer.assert_complete(); grass_slice_framebuffer.assert_complete();
gl::Viewport(0, 0, slice_resolution, slice_resolution); gl::Viewport(0, 0, slice_resolution, slice_resolution);
gl::ClearColor(0.f, 0.f, 0.f, 0.f); gl::ClearColor(0.f, 0.f, 0.f, 0.f);
gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT); gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
gl::Disable(gl::DEPTH_TEST); gl::Enable(gl::DEPTH_TEST);
gl::DepthFunc(gl::LEQUAL); gl::DepthFunc(gl::LEQUAL);
grass_program.bind(); grass_program.bind();
grass_program["u_tile_transform"] = geom::matrix<float, 4, 4>::identity(); grass_program["u_tile_transform"] = geom::matrix<float, 4, 4>::identity();
@ -421,7 +447,8 @@ struct grass_app
for (int y = -1; y <= 1; ++y) for (int y = -1; y <= 1; ++y)
{ {
grass_program["u_transform"] = geom::translation<float, 3>({-1.f + 2.f * x, -1.f + 2.f * y, 0.f}).homogeneous_matrix() * geom::scale<float, 3>({2.f, 2.f, 1.f}).homogeneous_matrix(); grass_program["u_transform"] = geom::translation<float, 3>({-1.f + 2.f * x, -1.f + 2.f * y, 0.f}).homogeneous_matrix() * geom::scale<float, 3>({2.f, 2.f, 1.f}).homogeneous_matrix();
grass_mesh.draw(); grass_mesh.draw(0, (grass_mesh.index_count() * (d + 1)) / density_level_count);
}
} }
} }
gfx::framebuffer::null().bind(); gfx::framebuffer::null().bind();
@ -429,6 +456,7 @@ struct grass_app
grass_slice_z_texture.linear_filter(); grass_slice_z_texture.linear_filter();
grass_slice_z_texture.anisotropy(); grass_slice_z_texture.anisotropy();
grass_slice_z_texture.generate_mipmap(); grass_slice_z_texture.generate_mipmap();
grass_slice_z_texture.clamp();
// grass_slice_z_texture.bind(); // grass_slice_z_texture.bind();
// gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST); // gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST);
// gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR); // gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR);
@ -529,10 +557,8 @@ struct grass_app
float d = density({(x + 0.5f) / size, (y + 0.5f) / size}); float d = density({(x + 0.5f) / size, (y + 0.5f) / size});
int const N = 8; int i = std::floor(d * density_level_count);
if (i > density_level_count - 1) i = density_level_count - 1;
int i = std::floor(d * N);
if (i > N - 1) i = N - 1;
{ {
float h00 = density({(x + 0.f) / size, (y + 0.f) / size}); float h00 = density({(x + 0.f) / size, (y + 0.f) / size});
@ -544,14 +570,15 @@ struct grass_app
grass_program["u_height01"] = h01; grass_program["u_height01"] = h01;
grass_program["u_height10"] = h10; grass_program["u_height10"] = h10;
grass_program["u_height11"] = h11; grass_program["u_height11"] = h11;
grass_mesh.draw(0, ((i + 1) * grass_mesh.index_count()) / N); grass_mesh.draw(0, ((i + 1) * grass_mesh.index_count()) / density_level_count);
triangles += (((i + 1) * grass_mesh.index_count()) / N) / 3; triangles += (((i + 1) * grass_mesh.index_count()) / density_level_count) / 3;
} }
} }
} }
grass_slice_program.bind();; grass_slice_program.bind();;
grass_slice_program["u_transform"] = camera_transform;
grass_slice_program["u_texture"] = 0; grass_slice_program["u_texture"] = 0;
grass_slice_z_texture.bind(); grass_slice_z_texture.bind();
@ -561,10 +588,19 @@ struct grass_app
{ {
if (x >= size / 2) continue; if (x >= size / 2) continue;
grass_slice_program["u_transform"] = camera_transform grass_slice_program["u_tile_transform"] = geom::translation<float, 3>(geom::vector{x, y, 0.f}).homogeneous_matrix()
* geom::translation<float, 3>(geom::vector{x, y, 0.f}).homogeneous_matrix()
* random_transform[random_transform_index(x, y)]; * random_transform[random_transform_index(x, y)];
float d00 = density({(x + 0.f) / size, (y + 0.f) / size}) * density_level_count;
float d01 = density({(x + 1.f) / size, (y + 0.f) / size}) * density_level_count;
float d10 = density({(x + 0.f) / size, (y + 1.f) / size}) * density_level_count;
float d11 = density({(x + 1.f) / size, (y + 1.f) / size}) * density_level_count;
grass_slice_program["u_density00"] = d00;
grass_slice_program["u_density01"] = d01;
grass_slice_program["u_density10"] = d10;
grass_slice_program["u_density11"] = d11;
grass_slice_z_mesh.draw(); grass_slice_z_mesh.draw();
} }
} }