diff options
-rw-r--r-- | gfx/shaders/cook_torrance.frag | 24 | ||||
-rw-r--r-- | gfx/src/renderer/renderer.c | 1 | ||||
-rw-r--r-- | gfx/src/util/scene.c | 64 | ||||
-rw-r--r-- | gltfview/src/game.c | 15 |
4 files changed, 71 insertions, 33 deletions
diff --git a/gfx/shaders/cook_torrance.frag b/gfx/shaders/cook_torrance.frag index 18d9d18..fcedef6 100644 --- a/gfx/shaders/cook_torrance.frag +++ b/gfx/shaders/cook_torrance.frag | |||
@@ -5,8 +5,12 @@ uniform float MetallicFactor; | |||
5 | uniform float RoughnessFactor; | 5 | uniform float RoughnessFactor; |
6 | uniform vec3 EmissiveFactor; | 6 | uniform vec3 EmissiveFactor; |
7 | 7 | ||
8 | #ifdef HAS_ALBEDO_MAP | ||
8 | uniform sampler2D BaseColorTexture; | 9 | uniform sampler2D BaseColorTexture; |
10 | #endif | ||
11 | #ifdef HAS_METALLIC_ROUGHNESS_MAP | ||
9 | uniform sampler2D MetallicRoughnessTexture; | 12 | uniform sampler2D MetallicRoughnessTexture; |
13 | #endif | ||
10 | #ifdef HAS_EMISSIVE_MAP | 14 | #ifdef HAS_EMISSIVE_MAP |
11 | uniform sampler2D EmissiveTexture; | 15 | uniform sampler2D EmissiveTexture; |
12 | #endif | 16 | #endif |
@@ -161,10 +165,22 @@ void main() | |||
161 | //float HdotV = clamp(dot(H,V), 0.0, 1.0); // Clamp to prevent black spots. | 165 | //float HdotV = clamp(dot(H,V), 0.0, 1.0); // Clamp to prevent black spots. |
162 | 166 | ||
163 | // TODO: BaseColorFactor and BaseColorTexture are vec4/rgba quantities | 167 | // TODO: BaseColorFactor and BaseColorTexture are vec4/rgba quantities |
164 | // respectively. Handle the alpha channel later. | 168 | // respectively. Handle the alpha channel. |
165 | // TODO: Other factors. | 169 | // TODO: Other factors. |
170 | #ifdef HAS_ALBEDO_MAP | ||
166 | vec3 albedo = vec3(BaseColorFactor) * texture(BaseColorTexture, Texcoord).rgb; | 171 | vec3 albedo = vec3(BaseColorFactor) * texture(BaseColorTexture, Texcoord).rgb; |
167 | vec3 metal_roughness = texture(MetallicRoughnessTexture, Texcoord).rgb; | 172 | #else |
173 | vec3 albedo = vec3(BaseColorFactor); | ||
174 | #endif | ||
175 | #ifdef HAS_METALLIC_ROUGHNESS_MAP | ||
176 | // Spec: "Its green channel contains roughness values and its blue channel | ||
177 | // contains metalness values." | ||
178 | vec2 metal_roughness | ||
179 | = vec2(MetallicFactor, RoughnessFactor) | ||
180 | * texture(MetallicRoughnessTexture, Texcoord).bg; | ||
181 | #else | ||
182 | vec2 metal_roughness = vec2(MetallicFactor, RoughnessFactor); | ||
183 | #endif | ||
168 | #ifdef HAS_EMISSIVE_MAP | 184 | #ifdef HAS_EMISSIVE_MAP |
169 | vec3 emissive = texture(EmissiveTexture, Texcoord).rgb; | 185 | vec3 emissive = texture(EmissiveTexture, Texcoord).rgb; |
170 | #else | 186 | #else |
@@ -175,8 +191,8 @@ void main() | |||
175 | #else | 191 | #else |
176 | float occlusion = 0.0; | 192 | float occlusion = 0.0; |
177 | #endif | 193 | #endif |
178 | float metallic = MetallicFactor * metal_roughness.b; | 194 | float metallic = metal_roughness.x; |
179 | float roughness = metal_roughness.g; | 195 | float roughness = metal_roughness.y; |
180 | 196 | ||
181 | // For a single light direction: | 197 | // For a single light direction: |
182 | // vec3 brdf = cook_torrance(albedo, metallic, roughness, emissive, NdotL, NdotV, NdotH, HdotV); | 198 | // vec3 brdf = cook_torrance(albedo, metallic, roughness, emissive, NdotL, NdotV, NdotH, HdotV); |
diff --git a/gfx/src/renderer/renderer.c b/gfx/src/renderer/renderer.c index 6b77ffe..3654546 100644 --- a/gfx/src/renderer/renderer.c +++ b/gfx/src/renderer/renderer.c | |||
@@ -29,6 +29,7 @@ bool renderer_make(Renderer* renderer, RenderBackend* render_backend) { | |||
29 | assert(renderer); | 29 | assert(renderer); |
30 | assert(render_backend); | 30 | assert(render_backend); |
31 | 31 | ||
32 | // TODO: Load the IBL stuff lazily. | ||
32 | if (!(renderer->ibl = gfx_make_ibl(render_backend))) { | 33 | if (!(renderer->ibl = gfx_make_ibl(render_backend))) { |
33 | renderer_destroy(renderer, render_backend); | 34 | renderer_destroy(renderer, render_backend); |
34 | return false; | 35 | return false; |
diff --git a/gfx/src/util/scene.c b/gfx/src/util/scene.c index 52812e9..35d6dd0 100644 --- a/gfx/src/util/scene.c +++ b/gfx/src/util/scene.c | |||
@@ -130,12 +130,14 @@ | |||
130 | #define UNIFORM_NORMAL_MAP "NormalMap" | 130 | #define UNIFORM_NORMAL_MAP "NormalMap" |
131 | 131 | ||
132 | // Shader compiler defines. Must match the names in shaders. | 132 | // Shader compiler defines. Must match the names in shaders. |
133 | #define DEFINE_HAS_TEXCOORDS "HAS_TEXCOORDS" | 133 | #define DEFINE_HAS_TEXCOORDS "HAS_TEXCOORDS" |
134 | #define DEFINE_HAS_NORMALS "HAS_NORMALS" | 134 | #define DEFINE_HAS_NORMALS "HAS_NORMALS" |
135 | #define DEFINE_HAS_TANGENTS "HAS_TANGENTS" | 135 | #define DEFINE_HAS_TANGENTS "HAS_TANGENTS" |
136 | #define DEFINE_HAS_NORMAL_MAP "HAS_NORMAL_MAP" | 136 | #define DEFINE_HAS_ALBEDO_MAP "HAS_ALBEDO_MAP" |
137 | #define DEFINE_HAS_OCCLUSION_MAP "HAS_OCCLUSION_MAP" | 137 | #define DEFINE_HAS_METALLIC_ROUGHNESS_MAP "HAS_METALLIC_ROUGHNESS_MAP" |
138 | #define DEFINE_HAS_EMISSIVE_MAP "HAS_EMISSIVE_MAP" | 138 | #define DEFINE_HAS_NORMAL_MAP "HAS_NORMAL_MAP" |
139 | #define DEFINE_HAS_OCCLUSION_MAP "HAS_OCCLUSION_MAP" | ||
140 | #define DEFINE_HAS_EMISSIVE_MAP "HAS_EMISSIVE_MAP" | ||
139 | 141 | ||
140 | typedef enum TextureType { | 142 | typedef enum TextureType { |
141 | BaseColorTexture, | 143 | BaseColorTexture, |
@@ -155,9 +157,11 @@ typedef struct MeshPermutation { | |||
155 | bool has_normals : 1; | 157 | bool has_normals : 1; |
156 | bool has_tangents : 1; | 158 | bool has_tangents : 1; |
157 | // Textures. | 159 | // Textures. |
158 | bool has_normal_map : 1; | 160 | bool has_albedo_map : 1; |
159 | bool has_occlusion_texture : 1; | 161 | bool has_metallic_roughness_map : 1; |
160 | bool has_emissive_texture : 1; | 162 | bool has_normal_map : 1; |
163 | bool has_occlusion_map : 1; | ||
164 | bool has_emissive_map : 1; | ||
161 | }; | 165 | }; |
162 | int32_t all; | 166 | int32_t all; |
163 | }; | 167 | }; |
@@ -179,9 +183,11 @@ static size_t make_defines( | |||
179 | check(has_texcoords, DEFINE_HAS_TEXCOORDS); | 183 | check(has_texcoords, DEFINE_HAS_TEXCOORDS); |
180 | check(has_normals, DEFINE_HAS_NORMALS); | 184 | check(has_normals, DEFINE_HAS_NORMALS); |
181 | check(has_tangents, DEFINE_HAS_TANGENTS); | 185 | check(has_tangents, DEFINE_HAS_TANGENTS); |
186 | check(has_albedo_map, DEFINE_HAS_ALBEDO_MAP); | ||
187 | check(has_metallic_roughness_map, DEFINE_HAS_METALLIC_ROUGHNESS_MAP); | ||
182 | check(has_normal_map, DEFINE_HAS_NORMAL_MAP); | 188 | check(has_normal_map, DEFINE_HAS_NORMAL_MAP); |
183 | check(has_occlusion_texture, DEFINE_HAS_OCCLUSION_MAP); | 189 | check(has_occlusion_map, DEFINE_HAS_OCCLUSION_MAP); |
184 | check(has_emissive_texture, DEFINE_HAS_EMISSIVE_MAP); | 190 | check(has_emissive_map, DEFINE_HAS_EMISSIVE_MAP); |
185 | 191 | ||
186 | return next; | 192 | return next; |
187 | } | 193 | } |
@@ -191,10 +197,11 @@ static ShaderProgram* make_shader_permutation( | |||
191 | RenderBackend* render_backend, MeshPermutation perm) { | 197 | RenderBackend* render_backend, MeshPermutation perm) { |
192 | LOGD( | 198 | LOGD( |
193 | "Compiling Cook-Torrance shader permutation: texcoords: %d, normals: " | 199 | "Compiling Cook-Torrance shader permutation: texcoords: %d, normals: " |
194 | "%d, tangents: %d, normal map: %d, AO map: %d, emissive map: %d", | 200 | "%d, tangents: %d, albedo map: %d, metallic-roughness map: %d, normal " |
201 | "map: %d, AO map: %d, emissive map: %d", | ||
195 | perm.has_texcoords, perm.has_normals, perm.has_tangents, | 202 | perm.has_texcoords, perm.has_normals, perm.has_tangents, |
196 | perm.has_normal_map, perm.has_occlusion_texture, | 203 | perm.has_albedo_map, perm.has_metallic_roughness_map, perm.has_normal_map, |
197 | perm.has_emissive_texture); | 204 | perm.has_occlusion_map, perm.has_emissive_map); |
198 | 205 | ||
199 | ShaderCompilerDefine defines[GFX_MAX_SHADER_COMPILER_DEFINES]; | 206 | ShaderCompilerDefine defines[GFX_MAX_SHADER_COMPILER_DEFINES]; |
200 | const size_t num_defines = make_defines(perm, defines); | 207 | const size_t num_defines = make_defines(perm, defines); |
@@ -436,9 +443,11 @@ static bool load_materials( | |||
436 | Material** materials) { | 443 | Material** materials) { |
437 | assert(data); | 444 | assert(data); |
438 | assert(render_backend); | 445 | assert(render_backend); |
439 | assert(load_texture_cmds); | ||
440 | assert(textures); | ||
441 | assert(materials); | 446 | assert(materials); |
447 | if (data->textures_count > 0) { | ||
448 | assert(load_texture_cmds); | ||
449 | assert(textures); | ||
450 | } | ||
442 | 451 | ||
443 | for (cgltf_size i = 0; i < data->materials_count; ++i) { | 452 | for (cgltf_size i = 0; i < data->materials_count; ++i) { |
444 | const cgltf_material* mat = &data->materials[i]; | 453 | const cgltf_material* mat = &data->materials[i]; |
@@ -446,7 +455,7 @@ static bool load_materials( | |||
446 | int next_uniform = 0; | 455 | int next_uniform = 0; |
447 | MaterialDesc desc = {0}; | 456 | MaterialDesc desc = {0}; |
448 | 457 | ||
449 | // TODO: emissive texture/factor and other material parameters. | 458 | // TODO: specular/glossiness and other material parameters. |
450 | if (mat->has_pbr_metallic_roughness) { | 459 | if (mat->has_pbr_metallic_roughness) { |
451 | const cgltf_pbr_metallic_roughness* pbr = &mat->pbr_metallic_roughness; | 460 | const cgltf_pbr_metallic_roughness* pbr = &mat->pbr_metallic_roughness; |
452 | 461 | ||
@@ -579,10 +588,17 @@ static bool load_meshes( | |||
579 | const cgltf_primitive* prim = &mesh->primitives[p]; | 588 | const cgltf_primitive* prim = &mesh->primitives[p]; |
580 | const cgltf_material* mat = prim->material; | 589 | const cgltf_material* mat = prim->material; |
581 | 590 | ||
582 | MeshPermutation perm = {0}; | 591 | MeshPermutation perm = {0}; |
583 | perm.has_normal_map = mat->normal_texture.texture != 0; | 592 | perm.has_normal_map = mat->normal_texture.texture != 0; |
584 | perm.has_occlusion_texture = mat->occlusion_texture.texture != 0; | 593 | perm.has_occlusion_map = mat->occlusion_texture.texture != 0; |
585 | perm.has_emissive_texture = mat->emissive_texture.texture != 0; | 594 | perm.has_emissive_map = mat->emissive_texture.texture != 0; |
595 | // TODO: specular/glossiness and other material parameters. | ||
596 | if (mat->has_pbr_metallic_roughness) { | ||
597 | const cgltf_pbr_metallic_roughness* pbr = &mat->pbr_metallic_roughness; | ||
598 | perm.has_albedo_map = pbr->base_color_texture.texture != 0; | ||
599 | perm.has_metallic_roughness_map = | ||
600 | pbr->metallic_roughness_texture.texture != 0; | ||
601 | } | ||
586 | 602 | ||
587 | GeometryDesc geometry_desc = { | 603 | GeometryDesc geometry_desc = { |
588 | .type = from_gltf_primitive_type(prim->type)}; | 604 | .type = from_gltf_primitive_type(prim->type)}; |
@@ -949,8 +965,10 @@ static bool load_scene( | |||
949 | goto cleanup; | 965 | goto cleanup; |
950 | } | 966 | } |
951 | 967 | ||
952 | load_textures_lazy( | 968 | if (data->textures_count > 0) { |
953 | data, render_backend, mstring_cstring(&directory), load_texture_cmds); | 969 | load_textures_lazy( |
970 | data, render_backend, mstring_cstring(&directory), load_texture_cmds); | ||
971 | } | ||
954 | 972 | ||
955 | if (!load_materials( | 973 | if (!load_materials( |
956 | data, render_backend, load_texture_cmds, textures, materials)) { | 974 | data, render_backend, load_texture_cmds, textures, materials)) { |
diff --git a/gltfview/src/game.c b/gltfview/src/game.c index 54e498b..224200d 100644 --- a/gltfview/src/game.c +++ b/gltfview/src/game.c | |||
@@ -189,8 +189,8 @@ static bool load_texture_debugger_scene(Game* game) { | |||
189 | 189 | ||
190 | bool game_new(Game* game, int argc, const char** argv) { | 190 | bool game_new(Game* game, int argc, const char** argv) { |
191 | // TODO: getopt() to implement proper argument parsing. | 191 | // TODO: getopt() to implement proper argument parsing. |
192 | const char* view_mode = argc > 1 ? argv[1] : ""; | 192 | const char* scene_filepath = argc > 1 ? argv[1] : DEFAULT_SCENE_FILE; |
193 | const char* scene_filepath = argc > 2 ? argv[2] : DEFAULT_SCENE_FILE; | 193 | const char* view_mode = argc > 2 ? argv[2] : ""; |
194 | 194 | ||
195 | game->gfx = gfx_init(); | 195 | game->gfx = gfx_init(); |
196 | if (!game->gfx) { | 196 | if (!game->gfx) { |
@@ -234,12 +234,15 @@ void game_update(Game* game, double t, double dt) { | |||
234 | usleep(1000); | 234 | usleep(1000); |
235 | game->elapsed -= 1.0; | 235 | game->elapsed -= 1.0; |
236 | } | 236 | } |
237 | Camera* camera = gfx_get_camera_camera(game->camera); | 237 | // TODO: Compute bounding boxes to then find a good orbit point and radius |
238 | // for each scene. | ||
239 | const vec3 orbit_point = vec3_make(0, 2, 0); | ||
240 | Camera* camera = gfx_get_camera_camera(game->camera); | ||
238 | spatial3_orbit( | 241 | spatial3_orbit( |
239 | &camera->spatial, vec3_make(0, 0, 0), | 242 | &camera->spatial, orbit_point, |
240 | /*radius=*/2, | 243 | /*radius=*/2.5, |
241 | /*azimuth=*/t * 0.5, /*zenith=*/0); | 244 | /*azimuth=*/t * 0.5, /*zenith=*/0); |
242 | spatial3_lookat(&camera->spatial, vec3_make(0, 0, 0)); | 245 | spatial3_lookat(&camera->spatial, orbit_point); |
243 | } | 246 | } |
244 | 247 | ||
245 | void game_render(const Game* game) { | 248 | void game_render(const Game* game) { |