Skip to content

Commit

Permalink
Implement anisotropic mipmapping
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamYuan committed Jun 9, 2018
1 parent f220bd3 commit 1b96b29
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 31 deletions.
2 changes: 2 additions & 0 deletions Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ void Renderer::Render(bool debug_voxel, bool indirect_trace, bool show_albedo)
skybox_.Get().Bind(4);
shadow_map_.Get().Bind(5);
voxelize_.Get().Bind(6);
for(int i = 0; i < 6; ++i)
voxelize_.GetMipmap()[i].Bind(i + 7u);

trace_shader_.Use();

Expand Down
47 changes: 35 additions & 12 deletions Voxelize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,29 @@ void Voxelize::Initialize()
printf("Mipmap level: %d\n", max_mipmap_level_);
printf("Voxel dimension: (%d, %d, %d)\n", kVoxelDimension.x, kVoxelDimension.y, kVoxelDimension.z);

//base voxel texture
voxel_texture_.Initialize();

auto *data = new GLubyte[kVoxelDimension.x * kVoxelDimension.y * kVoxelDimension.z * 4];
std::fill(data, data + kVoxelDimension.x * kVoxelDimension.y * kVoxelDimension.z * 4, 0);
voxel_texture_.Load(mygl3::ImageInfo(kVoxelDimension.x, kVoxelDimension.y, kVoxelDimension.z,
GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, data), true);
GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, data), false);
delete[] data;

GLfloat border_color[] = { 0.0f, 0.0f, 0.0f, 0.0f };
glTextureParameterfv(voxel_texture_.Get(), GL_TEXTURE_BORDER_COLOR, border_color);
voxel_texture_.SetSizeFilter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
voxel_texture_.SetSizeFilter(GL_LINEAR, GL_LINEAR);
voxel_texture_.SetWrapFilter(GL_CLAMP_TO_BORDER);

//mipmap voxel textures
for(auto &t : mipmap_textures_)
{
t.Initialize();
t.Load(mygl3::ImageInfo(kVoxelDimension.x / 2, kVoxelDimension.y / 2, kVoxelDimension.z / 2,
GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, nullptr), true);
glTextureParameterfv(t.Get(), GL_TEXTURE_BORDER_COLOR, border_color);
t.SetSizeFilter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
t.SetWrapFilter(GL_CLAMP_TO_BORDER);
}

voxelize_shader_.Initialize();
voxelize_shader_.SetULightDir(kLightDir);
voxelize_shader_.SetULightMatrix(res::light_matrix);
Expand All @@ -44,8 +54,8 @@ void Voxelize::Initialize()

void Voxelize::Update(const mygl3::Texture2D &shadow_map)
{
glBindImageTexture(7, voxel_texture_.Get(), 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_RGBA8);
glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST);
glBindImageTexture(7, voxel_texture_.Get(), 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);

glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, 1000, 1000);
Expand All @@ -54,24 +64,37 @@ void Voxelize::Update(const mygl3::Texture2D &shadow_map)
shadow_map.Bind(5);
res::sponza_model.Render();
printf("Voxelize lasted: %lf sec\n", glfwGetTime() - start);

glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST);


//mipmap
start = glfwGetTime();

mipmap_shader_.Use();
glm::ivec3 mipmap_texture_size{kVoxelDimension};
for(int i = 1; i < max_mipmap_level_; ++i)

mipmap_shader_.Use();
for(int level = 1; level < max_mipmap_level_; ++level)
{
glBindImageTexture(6, voxel_texture_.Get(), i, GL_TRUE, 0, GL_WRITE_ONLY, GL_RGBA8);
voxel_texture_.Bind(7);
for(GLuint f = 0; f < 6; ++f)
glBindImageTexture(f, mipmap_textures_[f].Get(), level - 1, GL_TRUE, 0, GL_WRITE_ONLY, GL_RGBA8);

if(level == 1)
voxel_texture_.Bind(0);
else
{
for(GLuint f = 0; f < 6; ++f)
mipmap_textures_[f].Bind(f);
}

mipmap_shader_.SetUSourceLod(level - 1);

mipmap_shader_.SetUSourceLod(i - 1);
mipmap_texture_size = glm::max(mipmap_texture_size / 2, glm::ivec3(1));
printf("Voxel %d: (%d, %d, %d)\n", level, mipmap_texture_size.x, mipmap_texture_size.y, mipmap_texture_size.z);

mipmap_shader_.SetUVoxelDimensionMipmap(mipmap_texture_size);

glm::uvec3 compute_group{mipmap_texture_size / 4 + 1};
glDispatchCompute(compute_group.x, compute_group.y, compute_group.z);
printf("Voxel %d: (%d, %d, %d)\n", i, mipmap_texture_size.x, mipmap_texture_size.y, mipmap_texture_size.z);
}

//voxel_texture_.GenerateMipmap();
Expand Down
3 changes: 2 additions & 1 deletion Voxelize.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@
class Voxelize
{
private:
mygl3::Texture3D voxel_texture_;
mygl3::Texture3D voxel_texture_, mipmap_textures_[6];
asserts::VoxelizeShader voxelize_shader_;
asserts::VoxelMipmapShader mipmap_shader_;
int max_mipmap_level_;
public:
void Initialize();
void Update(const mygl3::Texture2D &shadow_map);
const mygl3::Texture3D &Get() const { return voxel_texture_; }
const decltype(mipmap_textures_) &GetMipmap() const { return mipmap_textures_; }
};


Expand Down
6 changes: 6 additions & 0 deletions data
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,9 @@ begin SkyboxShader
u mat4 uProjection
u mat4 uView
end

begin VoxelMipmapShader
src shaders/mipmap.comp GL_COMPUTE_SHADER
u ivec3 uVoxelDimensionMipmap
u int uSourceLod
end
37 changes: 24 additions & 13 deletions shaders/mipmap.comp
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
#version 450 core
layout (local_size_x = 4, local_size_y = 4, local_size_z = 4) in;

layout (rgba8, binding = 6) uniform writeonly image3D uVoxelTextureMipmap;
layout (binding = 7) uniform sampler3D uVoxelTextureSource;
layout (binding = 0, rgba8) uniform writeonly image3D uVoxelTextureMipmaps[6];
layout (binding = 0) uniform sampler3D uVoxelTextureSources[6];

uniform int uSourceLod;
uniform ivec3 uVoxelDimensionMipmap;
uniform int uSourceLod;

const ivec3 kOffsets[8] =
{
{0, 0, 0}, {0, 0, 1}, {0, 1, 0}, {0, 1, 1},
{1, 0, 0}, {1, 0, 1}, {1, 1, 0}, {1, 1, 1},
};
const ivec3 kOpposite[8] =
const int kOpposites[8][3] =
{
{4, 2, 1}, {5, 3, 0}, {6, 0, 3}, {7, 1, 2},
{0, 6, 5}, {1, 7, 4}, {2, 4, 7}, {3, 5, 6}
};
const int kSides[6][4] =
{
{0, 1, 2, 3}, {4, 5, 6, 7}, {0, 1, 4, 5},
{2, 3, 6, 7}, {0, 2, 4, 6}, {1, 3, 5, 7}
};

void main()
{
Expand All @@ -29,15 +34,21 @@ void main()
ivec3 mipmap_pos = ivec3(gl_GlobalInvocationID);

vec4 arr[8];
for(int i = 0; i < 8; ++i)
arr[i] = texelFetch(uVoxelTextureSource, mipmap_pos * 2 + kOffsets[i], uSourceLod);

vec4 sum = vec4(0.0f);
for(int i = 0; i < 8; ++i)
if(uSourceLod == 0)
for(int i = 0; i < 8; ++i)
arr[i] = texelFetch(uVoxelTextureSources[0], mipmap_pos * 2 + kOffsets[i], 0);

for(int f = 0; f < 6; ++f)
{
sum += arr[i] * 0.125f;
sum += arr[i] * (3.0f - arr[kOpposite[i].x].a - arr[kOpposite[i].y].a - arr[kOpposite[i].z].a) / 24.0f;
}
if(uSourceLod > 0)
for(int i = 0; i < 8; ++i)
arr[i] = texelFetch(uVoxelTextureSources[f], mipmap_pos * 2 + kOffsets[i], uSourceLod - 1);

imageStore(uVoxelTextureMipmap, mipmap_pos, sum);
vec4 sum = vec4(0.0f);
for(int b = 0; b < 4; ++b)
sum += arr[kSides[f][b]] + arr[kOpposites[kSides[f][b]][f>>1]] * (1.0f - arr[kSides[f][b]].a);
sum *= 0.25f;

imageStore(uVoxelTextureMipmaps[f], mipmap_pos, sum);
}
}
30 changes: 25 additions & 5 deletions shaders/trace.frag
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ layout (binding = 4) uniform samplerCube uSkyboxTexture;
layout (binding = 5) uniform sampler2DShadow uShadowMap;
layout (binding = 6) uniform sampler3D uVoxelTexture;

layout (binding = 7) uniform sampler3D uVoxelTextureMipmaps[6];

uniform mat4 uLightMatrix;
uniform vec3 uLightDir;

Expand Down Expand Up @@ -53,10 +55,22 @@ void ons(in vec3 v1, inout vec3 v2, out vec3 v3)
v3 = cross(v1, v2);
}

vec4 SampleVoxel(in vec3 world_pos, in float lod)
vec4 SampleVoxel(in vec3 world_pos, in float lod, in ivec3 indices, in vec3 weights)
{
vec3 voxel_uv = ((world_pos - uVoxelGridRangeMin) / uVoxelWorldSize) / vec3(uVoxelDimension);
return textureLod(uVoxelTexture, voxel_uv, lod);

float mipmap_lod = max(0.0f, lod - 1.0f);
vec4 mipmap_color =
textureLod(uVoxelTextureMipmaps[indices.x], voxel_uv, mipmap_lod) * weights.x +
textureLod(uVoxelTextureMipmaps[indices.y], voxel_uv, mipmap_lod) * weights.y +
textureLod(uVoxelTextureMipmaps[indices.z], voxel_uv, mipmap_lod) * weights.z;
//vec4 mipmap_color = textureLod(uVoxelTextureMipmaps[5], voxel_uv, mipmap_lod);
if(lod < 1.0f)
{
return mix(texture(uVoxelTexture, voxel_uv), mipmap_color, lod);
}
else
return mipmap_color;
}

vec3 ConeTrace(in vec3 start_pos, in vec3 direction, in float tan_half_angle)
Expand All @@ -65,13 +79,19 @@ vec3 ConeTrace(in vec3 start_pos, in vec3 direction, in float tan_half_angle)

float dist = uVoxelWorldSize * 4.0f;

ivec3 load_indices = ivec3(
direction.x < 0.0f ? 0 : 1,
direction.y < 0.0f ? 2 : 3,
direction.z < 0.0f ? 4 : 5);
vec3 weights = direction * direction;

while(dist < 32.0f && color.a < 1.0f)
{
vec3 pos = start_pos + dist * direction;

float diameter = max(uVoxelWorldSize, 2.0f * tan_half_angle * dist);
float lod = log2(diameter / uVoxelWorldSize);
vec4 voxel_color = SampleVoxel(pos, lod);
vec4 voxel_color = SampleVoxel(pos, lod, load_indices, weights);
color += voxel_color * (1.0f - color.a);

dist += diameter * 0.5f;
Expand Down Expand Up @@ -132,14 +152,14 @@ void main()

final_color = DirectLight(normal) * CalculateShadow(position);
if(uEnableIndirectTrace)
final_color += IndirectLight(position, mat3(tangent, normal, bitangent));
final_color += IndirectLight(position + normal * uVoxelWorldSize, mat3(tangent, normal, bitangent));
//final_color += ConeTrace(position, reflect(vViewDir, normal), 0.2f);
if(uShowAlbedo)
final_color *= albedo.rgb;
final_color *= kLightColor;

//debug mipmap
//final_color = SampleVoxel(position, 5.0f).rgb;
//final_color = SampleVoxel(position, 4.0f, ivec3(0), vec3(0.0f)).rgb;
}
}
else
Expand Down

0 comments on commit 1b96b29

Please sign in to comment.