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
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 = 1) in vec2 in_texcoord;
out vec2 texcoord;
out vec3 texcoord;
void main()
{
gl_Position = u_transform * in_position;
texcoord = in_texcoord;
vec2 p = (u_tile_transform * vec4(in_position.xy, 0.0, 1.0)).xy;
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[] =
R"(#version 330
uniform sampler2D u_texture;
uniform sampler2DArray u_texture;
in vec2 texcoord;
in vec3 texcoord;
out vec4 out_color;
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);
}
)";
@ -146,6 +168,8 @@ struct grass_app
int size = 64;
int const density_level_count = 8;
pcg::perlin<float, 2> density;
gfx::program ground_program{ground_vs, ground_fs};
@ -156,7 +180,7 @@ struct grass_app
gfx::texture_1d grass_texture;
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::framebuffer grass_slice_framebuffer;
@ -378,7 +402,7 @@ struct grass_app
{
struct vertex
{
geom::vector<float, 3> position;
geom::point<float, 3> position;
geom::vector<float, 2> texcoord;
};
@ -393,35 +417,38 @@ struct grass_app
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}});
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);
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_framebuffer.color(grass_slice_z_texture);
grass_slice_framebuffer.depth(grass_slice_renderbuffer);
grass_slice_framebuffer.assert_complete();
gl::Viewport(0, 0, slice_resolution, slice_resolution);
gl::ClearColor(0.f, 0.f, 0.f, 0.f);
gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
gl::Disable(gl::DEPTH_TEST);
gl::DepthFunc(gl::LEQUAL);
grass_program.bind();
grass_program["u_tile_transform"] = geom::matrix<float, 4, 4>::identity();
grass_program["u_height00"] = 1.f;
grass_program["u_height01"] = 1.f;
grass_program["u_height10"] = 1.f;
grass_program["u_height11"] = 1.f;
grass_program["u_texture"] = 0;
grass_texture.bind();
for (int x = -1; x <= 1; ++x)
for (int d = 0; d < density_level_count; ++d)
{
for (int y = -1; y <= 1; ++y)
grass_slice_framebuffer.color(grass_slice_z_texture, d);
grass_slice_framebuffer.depth(grass_slice_renderbuffer);
grass_slice_framebuffer.assert_complete();
gl::Viewport(0, 0, slice_resolution, slice_resolution);
gl::ClearColor(0.f, 0.f, 0.f, 0.f);
gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
gl::Enable(gl::DEPTH_TEST);
gl::DepthFunc(gl::LEQUAL);
grass_program.bind();
grass_program["u_tile_transform"] = geom::matrix<float, 4, 4>::identity();
grass_program["u_height00"] = 1.f;
grass_program["u_height01"] = 1.f;
grass_program["u_height10"] = 1.f;
grass_program["u_height11"] = 1.f;
grass_program["u_texture"] = 0;
grass_texture.bind();
for (int x = -1; x <= 1; ++x)
{
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();
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_mesh.draw(0, (grass_mesh.index_count() * (d + 1)) / density_level_count);
}
}
}
gfx::framebuffer::null().bind();
@ -429,6 +456,7 @@ struct grass_app
grass_slice_z_texture.linear_filter();
grass_slice_z_texture.anisotropy();
grass_slice_z_texture.generate_mipmap();
grass_slice_z_texture.clamp();
// grass_slice_z_texture.bind();
// gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST);
// 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});
int const N = 8;
int i = std::floor(d * N);
if (i > N - 1) i = N - 1;
int i = std::floor(d * density_level_count);
if (i > density_level_count - 1) i = density_level_count - 1;
{
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_height10"] = h10;
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["u_transform"] = camera_transform;
grass_slice_program["u_texture"] = 0;
grass_slice_z_texture.bind();
@ -561,10 +588,19 @@ struct grass_app
{
if (x >= size / 2) continue;
grass_slice_program["u_transform"] = camera_transform
* geom::translation<float, 3>(geom::vector{x, y, 0.f}).homogeneous_matrix()
grass_slice_program["u_tile_transform"] = geom::translation<float, 3>(geom::vector{x, y, 0.f}).homogeneous_matrix()
* 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();
}
}