Fix premultiplied alpha artifacts

This commit is contained in:
Krzosa Karol
2022-06-29 18:46:57 +02:00
parent 59dbbc2a57
commit efdc23ea57
5 changed files with 54 additions and 30 deletions

3
.gitignore vendored
View File

@@ -2,6 +2,8 @@
x64/ x64/
assets/ assets/
stats/ stats/
tracy/
optick/
data.txt data.txt
*.ilk *.ilk
@@ -15,3 +17,4 @@ data.txt
*.sublime* *.sublime*
*.bin *.bin
*.4c *.4c
asset.log.txt

View File

@@ -29,7 +29,6 @@ load_image(String path) {
int x, y, n; int x, y, n;
unsigned char* data = stbi_load_from_memory(file.str, file.len, &x, &y, &n, 4); unsigned char* data = stbi_load_from_memory(file.str, file.len, &x, &y, &n, 4);
Bitmap result = { (U32*)data, x, y }; Bitmap result = { (U32*)data, x, y };
#if PREMULTIPLIED_ALPHA_BLENDING
if(data) { if(data) {
U32 *p = result.pixels; U32 *p = result.pixels;
for (int Y = 0; Y < y; Y++) { for (int Y = 0; Y < y; Y++) {
@@ -42,7 +41,6 @@ load_image(String path) {
} }
} }
} }
#endif
return result; return result;
} }
@@ -429,9 +427,6 @@ global FILE *output_file;
function void function void
asset_log(Log_Kind kind, String string, char *file, int line){ asset_log(Log_Kind kind, String string, char *file, int line){
if(!output_file) {
}
fprintf(output_file, "%.*s", string_expand(string)); fprintf(output_file, "%.*s", string_expand(string));
} }

View File

@@ -3,5 +3,7 @@
clang assets.cpp -Wall -Wno-unused-function -Wno-missing-braces -fno-exceptions -fdiagnostics-absolute-paths -g -I".." -o assets.exe -Wl,user32.lib clang assets.cpp -Wall -Wno-unused-function -Wno-missing-braces -fno-exceptions -fdiagnostics-absolute-paths -g -I".." -o assets.exe -Wl,user32.lib
assets.exe assets.exe
rem tracy/TracyClient.cpp -DTRACY_ENABLE
clang main.cpp -Wall -Wno-unused-function -Wno-missing-braces -fno-exceptions -fdiagnostics-absolute-paths -g -I".." -o main.exe -Wl,user32.lib
clang -O2 main.cpp -Wall -Wno-unused-function -Wno-missing-braces -fno-exceptions -fdiagnostics-absolute-paths -g -I".." -o main.exe -Wl,user32.lib -Wl,optick\lib\x64\release\OptickCore.lib

View File

@@ -84,12 +84,17 @@
/// - [x] Asset processor as second program /// - [x] Asset processor as second program
/// ///
/// ///
#if 0
#include "tracy/Tracy.hpp"
#undef assert
#endif
#define PREMULTIPLIED_ALPHA_BLENDING 1
#include "multimedia.cpp" #include "multimedia.cpp"
#include "profile.cpp" #include "profile.cpp"
#include "obj.cpp" #include "obj.cpp"
struct Vertex { struct Vertex {
Vec3 pos; Vec3 pos;
Vec2 tex; Vec2 tex;
@@ -288,7 +293,8 @@ void draw_triangle_nearest(Bitmap* dst, F32 *depth_buffer, Bitmap *src, Vec3 lig
Vec4 p0, Vec4 p1, Vec4 p2, Vec4 p0, Vec4 p1, Vec4 p2,
Vec2 tex0, Vec2 tex1, Vec2 tex2, Vec2 tex0, Vec2 tex1, Vec2 tex2,
Vec3 norm0, Vec3 norm1, Vec3 norm2) { Vec3 norm0, Vec3 norm1, Vec3 norm2) {
if(os.frame > 60) PROFILE_BEGIN(draw_triangle); // if(os.frame > 10) PROFILE_BEGIN(draw_triangle);
// ZoneScopedN("draw_triangle");
F32 min_x1 = (F32)(min(p0.x, min(p1.x, p2.x))); F32 min_x1 = (F32)(min(p0.x, min(p1.x, p2.x)));
F32 min_y1 = (F32)(min(p0.y, min(p1.y, p2.y))); F32 min_y1 = (F32)(min(p0.y, min(p1.y, p2.y)));
F32 max_x1 = (F32)(max(p0.x, max(p1.x, p2.x))); F32 max_x1 = (F32)(max(p0.x, max(p1.x, p2.x)));
@@ -322,6 +328,7 @@ void draw_triangle_nearest(Bitmap* dst, F32 *depth_buffer, Bitmap *src, Vec3 lig
F32 Cx2 = Cy2; F32 Cx2 = Cy2;
for (S64 x = min_x; x < max_x; x++) { for (S64 x = min_x; x < max_x; x++) {
if (Cx0 >= 0 && Cx1 >= 0 && Cx2 >= 0) { if (Cx0 >= 0 && Cx1 >= 0 && Cx2 >= 0) {
// ZoneNamedN(fill, "fill_pixel", true);
F32 w1 = Cx1 / area; F32 w1 = Cx1 / area;
F32 w2 = Cx2 / area; F32 w2 = Cx2 / area;
F32 w3 = Cx0 / area; F32 w3 = Cx0 / area;
@@ -355,7 +362,6 @@ void draw_triangle_nearest(Bitmap* dst, F32 *depth_buffer, Bitmap *src, Vec3 lig
U32 *dst_pixel = destination + x; U32 *dst_pixel = destination + x;
U32 *pixel = src->pixels + (ui + (src->y - 1ll - vi) * src->x); U32 *pixel = src->pixels + (ui + (src->y - 1ll - vi) * src->x);
#if PREMULTIPLIED_ALPHA_BLENDING
Vec4 result_color; { Vec4 result_color; {
U32 c = *pixel; U32 c = *pixel;
F32 a = ((c & 0xff000000) >> 24) / 255.f; F32 a = ((c & 0xff000000) >> 24) / 255.f;
@@ -378,20 +384,18 @@ void draw_triangle_nearest(Bitmap* dst, F32 *depth_buffer, Bitmap *src, Vec3 lig
dst_color = { r,g,b,a }; dst_color = { r,g,b,a };
} }
#if 0
Vec3 light_color = vec3(0.8,0.8,1); Vec3 light_color = vec3(0.8,0.8,1);
constexpr F32 ambient_strength = 0.1f; { constexpr F32 ambient_strength = 0.1f; {
Vec3 ambient = ambient_strength * light_color; Vec3 ambient = ambient_strength * light_color;
Vec3 diffuse = clamp_bot(0.f, -dot(norm, light_direction)) * light_color; Vec3 diffuse = clamp_bot(0.f, -dot(norm, light_direction)) * light_color;
result_color.rgb *= (ambient+diffuse); result_color.rgb *= (ambient+diffuse);
} }
#endif
result_color = premultiplied_alpha(dst_color, result_color); result_color = premultiplied_alpha(dst_color, result_color);
result_color = almost_linear_to_srgb(result_color); result_color = almost_linear_to_srgb(result_color);
U32 color32 = vec4_to_u32abgr(result_color); U32 color32 = vec4_to_u32abgr(result_color);
#else
U32 color32 = *pixel;
#endif
*dst_pixel = color32; *dst_pixel = color32;
} }
@@ -406,7 +410,8 @@ void draw_triangle_nearest(Bitmap* dst, F32 *depth_buffer, Bitmap *src, Vec3 lig
destination += dst->x; destination += dst->x;
} }
if(os.frame > 60) PROFILE_END(draw_triangle); // if(os.frame > 10) PROFILE_END(draw_triangle);
} }
function function
@@ -504,7 +509,9 @@ void draw_triangle_bilinear(Bitmap* dst, F32 *depth_buffer, Bitmap *src, Vec3 li
function function
void draw_mesh(Render *r, String scene_name, Obj_Material *materials, Obj_Mesh *mesh, Vec3 *vertices, Vec2 *tex_coords, Vec3 *normals) { void draw_mesh(Render *r, String scene_name, Obj_Material *materials, Obj_Mesh *mesh, Vec3 *vertices, Vec2 *tex_coords, Vec3 *normals) {
// ZoneNamedN(m, "draw_all_meshes", true);
for (int i = 0; i < mesh->indices.len; i++) { for (int i = 0; i < mesh->indices.len; i++) {
// ZoneNamedN(m, "draw_single_mesh", true);
Obj_Index *index = mesh->indices.data + i; Obj_Index *index = mesh->indices.data + i;
Bitmap *image = &r->img; Bitmap *image = &r->img;
if(index->material_id != -1) { if(index->material_id != -1) {
@@ -665,7 +672,8 @@ UI_SIGNAL_CALLBACK(scene_callback) {
} break; } break;
case Scene_Sponza: { case Scene_Sponza: {
speed = 100; speed = 100;
r.camera_pos = vec3(0,0,-2); r.camera_pos = vec3(-228,94.5,-107);
r.camera_yaw = vec2(-1.25, 0.21);
obj = sponza; obj = sponza;
} break; } break;
case Scene_Count: case Scene_Count:
@@ -686,7 +694,7 @@ main(int argc, char **argv) {
os.window_size.y = 720; os.window_size.y = 720;
os.window_resizable = 1; os.window_resizable = 1;
assert(os_init()); assert(os_init());
Font font = os_load_font(os.perm_arena, 72, "Arial", 0); Font font = os_load_font(os.perm_arena, 16, "Arial", 0);
f22 = load_obj_dump(os.perm_arena, "plane.bin"_s); f22 = load_obj_dump(os.perm_arena, "plane.bin"_s);
sponza = load_obj_dump(os.perm_arena, "sponza.bin"_s); sponza = load_obj_dump(os.perm_arena, "sponza.bin"_s);
@@ -695,7 +703,8 @@ main(int argc, char **argv) {
int screen_x = 1280; int screen_x = 1280;
int screen_y = 720; int screen_y = 720;
r.camera_pos = {0,0,-2}; r.camera_pos = vec3(-228,94.5,-107);
r.camera_yaw = vec2(-1.25, 0.21);
r.screen320 = {(U32 *)arena_push_size(os.perm_arena, screen_x*screen_y*sizeof(U32)), screen_x, screen_y}; r.screen320 = {(U32 *)arena_push_size(os.perm_arena, screen_x*screen_y*sizeof(U32)), screen_x, screen_y};
r.depth320 = (F32 *)arena_push_size(os.perm_arena, sizeof(F32) * screen_x * screen_y); r.depth320 = (F32 *)arena_push_size(os.perm_arena, sizeof(F32) * screen_x * screen_y);
@@ -709,6 +718,7 @@ main(int argc, char **argv) {
B32 ui_mouse_lock = true; B32 ui_mouse_lock = true;
while (os_game_loop()) { while (os_game_loop()) {
// FrameMark;
if (ui_mouse_lock == false) { if (ui_mouse_lock == false) {
r.camera_yaw.x += os.delta_mouse_pos.x * 0.01f; r.camera_yaw.x += os.delta_mouse_pos.x * 0.01f;
r.camera_yaw.y -= os.delta_mouse_pos.y * 0.01f; r.camera_yaw.y -= os.delta_mouse_pos.y * 0.01f;
@@ -774,7 +784,19 @@ main(int argc, char **argv) {
} }
} }
ui_end_frame(os.screen, &ui, &font); ui_end_frame(os.screen, &ui, &font);
frame_data = string_fmt(os.frame_arena, "FPS:%f dt:%f frame:%u", os.fps, os.delta_time, os.frame); frame_data = string_fmt(os.frame_arena, "FPS:%f dt:%f frame:%u camera_pos: %f %f %f camera_yaw: %f %f", os.fps, os.delta_time, os.frame,
r.camera_pos.x, r.camera_pos.y, r.camera_pos.z, r.camera_yaw.x, r.camera_yaw.y);
auto *scope = &profile_scopes[ProfileScopeName_draw_triangle];
if(scope->i != 0){
U64 total = 0;
for(int i = 0; i < scope->i; i++){
total += scope->samples[i];
}
log_info("\nTotal: %llu Hits: %llu", total, (U64)scope->i);
scope->i = 0;
}
} }
} }

View File

@@ -4,20 +4,22 @@ enum ProfileScopeName {
}; };
struct ProfileScope { struct ProfileScope {
U64 samples[5096]; U64 samples[5096*16];
S64 i; S64 i;
}; };
global ProfileScope profile_scopes[ProfileScopeName_Count]; global ProfileScope profile_scopes[ProfileScopeName_Count];
#define PROFILE_BEGIN(name) do { \ #define PROFILE_BEGIN(name) \
ProfileScope *__profile_scope = profile_scopes + ProfileScopeName_##name; \ do { \
__profile_scope->samples[__profile_scope->i] = __rdtsc(); \ ProfileScope *__profile_scope = profile_scopes + ProfileScopeName_##name; \
} while (0) __profile_scope->samples[__profile_scope->i] = __rdtsc(); \
} while (0)
#define PROFILE_END(name) do { \
ProfileScope *_profile_scope = profile_scopes + ProfileScopeName_##name; \
_profile_scope->samples[_profile_scope->i] = __rdtsc() - _profile_scope->samples[_profile_scope->i]; \
_profile_scope->i = (_profile_scope->i + 1) % 5096; \
}while (0)
#define PROFILE_END(name) \
do { \
ProfileScope *_profile_scope = profile_scopes + ProfileScopeName_##name; \
_profile_scope->samples[_profile_scope->i] = \
__rdtsc() - _profile_scope->samples[_profile_scope->i]; \
_profile_scope->i = (_profile_scope->i + 1) % 5096*16; \
} while (0)