fix model transparency detection

main
Dominik Madarász 2024-09-02 19:48:15 +02:00
parent b94145daca
commit dfcb0877ca
14 changed files with 42825 additions and 42719 deletions

View File

@ -109,7 +109,7 @@ int main(int argc, char** argv) {
enum {
POINT, SPOT, DIR, ALL
};
static unsigned mode = SPOT;
static unsigned mode = ALL;
if (!ui_active()) {
if (input_down(KEY_1)) mode = POINT;

View File

@ -11,6 +11,26 @@ Ni 1.500000
d 1.000000
illum 2
newmtl Material.001
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
illum 2
map_Kd fence_PNG28.png
map_d fence_PNG28.png
newmtl Material.002
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 0.266667
illum 9
map_Kd Transparent glass seamless texture 1.png
newmtl floor
Ns 10.000005
Ka 1.000000 1.000000 1.000000

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

View File

@ -1,15 +1,5 @@
#ifndef BRDF_GLSL
#define BRDF_GLSL
#ifdef SHADING_PBR
#include "utils.glsl"
#define USE_BRUTEFORCE_IRRADIANCE false // Samples irradiance from tex_skysphere when enabled.
#define USE_WRAPAROUND_SPECULAR true // Makes silhouettes more reflective to avoid black pixels.
#define USE_SPECULAR_AO_ATTENUATION true // Dampens IBL specular ambient with AO if enabled.
#define USE_NORMAL_VARIATION_TO_ROUGHNESS true // Increases roughness if normal map has variation and was minified.
#define BOOST_LIGHTING 2.00f // Multiplies analytic light's color with this constant because otherwise they look really pathetic.
#define BOOST_SPECULAR 1.50f
struct ColorMap
{
@ -30,6 +20,18 @@ uniform ColorMap map_emissive; uniform sampler2D map_emissive_tex;
#define sample_colormap(ColorMap_, uv_) \
(ColorMap_.has_tex ? texture( ColorMap_##_tex, uv_ ) : ColorMap_.color)
#ifdef SHADING_PBR
#include "utils.glsl"
#define USE_BRUTEFORCE_IRRADIANCE false // Samples irradiance from tex_skysphere when enabled.
#define USE_WRAPAROUND_SPECULAR true // Makes silhouettes more reflective to avoid black pixels.
#define USE_SPECULAR_AO_ATTENUATION true // Dampens IBL specular ambient with AO if enabled.
#define USE_NORMAL_VARIATION_TO_ROUGHNESS true // Increases roughness if normal map has variation and was minified.
#define BOOST_LIGHTING 2.00f // Multiplies analytic light's color with this constant because otherwise they look really pathetic.
#define BOOST_SPECULAR 1.50f
uniform float skysphere_rotation; /// set:0
uniform float skysphere_mip_count;
uniform float exposure; /// set:1

View File

@ -15,12 +15,14 @@ uniform int shadow_window_size;
const float bias_modifier[NUM_SHADOW_CASCADES] = float[NUM_SHADOW_CASCADES](1.0, 6.0, 9.0, 16.0);
// const float bias_modifier[NUM_SHADOW_CASCADES] = float[NUM_SHADOW_CASCADES](0.95, 0.35, 0.20, 0.15);
vec2 shadow_vsm_variance(vec3 dir, int light_index, float distance, float min_variance, float variance_transition) {
vec2 shadow_vsm_variance(vec3 dir, int light_index, float distance, float min_variance, float variance_transition, out float alpha) {
// Calculate the variance
vec2 moments = texture(shadowMap[light_index], dir).rg;
vec3 sampledValue = texture(shadowMap[light_index], dir).rgb;
vec2 moments = sampledValue.rg;
alpha = 1.0;//sampledValue.b;
float variance = max(moments.y - (moments.x * moments.x), min_variance);
float d = distance - moments.x;
return vec2(linstep(variance_transition, 1.0, variance / (variance + d * d)), moments.x);
return (vec2(linstep(variance_transition, 1.0, variance / (variance + d * d)), moments.x));
}
float shadow_vsm(float distance, vec3 dir, int light_index, float min_variance, float variance_transition, float shadow_softness_raw, float penumbra_size) {
@ -52,13 +54,14 @@ float shadow_vsm(float distance, vec3 dir, int light_index, float min_variance,
vec3 offset_dir = tangent * offsets.r + bitangent * offsets.g;
sc.xyz = dir.xyz + offset_dir * texelSize;
vec2 variance = shadow_vsm_variance(sc.xyz, light_index, distance, min_variance, variance_transition);
ofs_sum += min(max(step(distance, variance.y), variance.x), 1.0);
float alpha;
vec2 variance = shadow_vsm_variance(sc.xyz, light_index, distance, min_variance, variance_transition, alpha);
ofs_sum += min(max(step(distance*alpha, variance.y), variance.x), 1.0);
offset_dir = tangent * offsets.b + bitangent * offsets.a;
sc.xyz = dir.xyz + offset_dir * texelSize;
variance = shadow_vsm_variance(sc.xyz, light_index, distance, min_variance, variance_transition);
ofs_sum += min(max(step(distance, variance.y), variance.x), 1.0);
variance = shadow_vsm_variance(sc.xyz, light_index, distance, min_variance, variance_transition, alpha);
ofs_sum += min(max(step(distance*alpha, variance.y), variance.x), 1.0);
}
float shadow_sum = ofs_sum / 8.0;
@ -70,13 +73,14 @@ float shadow_vsm(float distance, vec3 dir, int light_index, float min_variance,
vec3 offset_dir = tangent * offsets.r + bitangent * offsets.g;
sc.xyz = dir.xyz + offset_dir * texelSize;
vec2 variance = shadow_vsm_variance(sc.xyz, light_index, distance, min_variance, variance_transition);
ofs_sum += min(max(step(distance, variance.y), variance.x), 1.0);
float alpha;
vec2 variance = shadow_vsm_variance(sc.xyz, light_index, distance, min_variance, variance_transition, alpha);
ofs_sum += min(max(step(distance*alpha, variance.y), variance.x), 1.0);
offset_dir = tangent * offsets.b + bitangent * offsets.a;
sc.xyz = dir.xyz + offset_dir * texelSize;
variance = shadow_vsm_variance(sc.xyz, light_index, distance, min_variance, variance_transition);
ofs_sum += min(max(step(distance, variance.y), variance.x), 1.0);
variance = shadow_vsm_variance(sc.xyz, light_index, distance, min_variance, variance_transition, alpha);
ofs_sum += min(max(step(distance*alpha, variance.y), variance.x), 1.0);
}
shadow_sum = ofs_sum / (samples_div2 * 2.0);
@ -94,11 +98,12 @@ float shadow_vsm(float distance, vec3 dir, int light_index, float min_variance,
return shadow_sum;//min(max(step(distance, moments.x), shadow_sum), 1.0);
}
float shadowmap_cascade_sample(vec2 sc, int cascade_index, float blend_factor) {
float s1 = texture(shadowMap2D[cascade_index], sc).r;
float shadowmap_cascade_sample(vec2 sc, int cascade_index, float blend_factor, out float alpha) {
vec2 s1 = texture(shadowMap2D[cascade_index], sc).rg;
// float s2 = texture(shadowMap2D[cascade_index + 1], sc).r;
// return mix(s1, s2, blend_factor);
return s1;
alpha = 1.0;//s1.g;
return s1.r;
}
float shadow_csm(float distance, vec3 lightDir, int light_index, float shadow_bias, float normal_bias, float shadow_softness) {
@ -170,12 +175,13 @@ float shadow_csm(float distance, vec3 lightDir, int light_index, float shadow_bi
ofs_coord.x = i;
vec4 offsets = texelFetch(shadow_offsets, ofs_coord, 0) * shadow_softness;
sc.xy = projCoords.xy + offsets.rg * texelSize;
float csmDepth = shadowmap_cascade_sample(sc.xy, cascade_index, blend_factor);
ofs_sum += currentDepth - bias > csmDepth ? 1.0 : 0.0;
float alpha;
float csmDepth = shadowmap_cascade_sample(sc.xy, cascade_index, blend_factor, alpha);
ofs_sum += currentDepth - bias > csmDepth ? alpha : 0.0;
sc.xy = projCoords.xy + offsets.ba * texelSize;
csmDepth = shadowmap_cascade_sample(sc.xy, cascade_index, blend_factor);
ofs_sum += currentDepth - bias > csmDepth ? 1.0 : 0.0;
csmDepth = shadowmap_cascade_sample(sc.xy, cascade_index, blend_factor, alpha);
ofs_sum += currentDepth - bias > csmDepth ? alpha : 0.0;
}
float shadow_sum = ofs_sum / 8.0;
@ -185,12 +191,13 @@ float shadow_csm(float distance, vec3 lightDir, int light_index, float shadow_bi
ofs_coord.x = i;
vec4 offsets = texelFetch(shadow_offsets, ofs_coord, 0) * shadow_softness;
sc.xy = projCoords.xy + offsets.rg * texelSize;
float csmDepth = shadowmap_cascade_sample(sc.xy, cascade_index, blend_factor);
ofs_sum += currentDepth - bias > csmDepth ? 1.0 : 0.0;
float alpha;
float csmDepth = shadowmap_cascade_sample(sc.xy, cascade_index, blend_factor, alpha);
ofs_sum += currentDepth - bias > csmDepth ? alpha : 0.0;
sc.xy = projCoords.xy + offsets.ba * texelSize;
csmDepth = shadowmap_cascade_sample(sc.xy, cascade_index, blend_factor);
ofs_sum += currentDepth - bias > csmDepth ? 1.0 : 0.0;
csmDepth = shadowmap_cascade_sample(sc.xy, cascade_index, blend_factor, alpha);
ofs_sum += currentDepth - bias > csmDepth ? alpha : 0.0;
}
shadow_sum = ofs_sum / (samples_div2 * 2.0);

View File

@ -18,6 +18,21 @@ struct surface_t {
float alpha;
};
vec4 get_diffuse_map() {
vec4 result;
if (map_albedo.has_tex) {
result = sample_colormap(map_albedo, v_texcoord);
} else if (map_diffuse.has_tex) {
result = sample_colormap(map_diffuse, v_texcoord);
} else if(u_textured) {
result = texture(u_texture2d, v_texcoord);
} else {
result = u_diffuse;
}
result.a *= u_global_alpha*u_global_opacity;
return result;
}
surface_t surface() {
surface_t s;

View File

@ -7,6 +7,7 @@ void main() {
if (do_lightmap())
return;
surface_t surf = surface();
fragcolor = surf.fragcolor;
fragcolor.rgb = do_fog(fragcolor.rgb);

View File

@ -1,12 +1,18 @@
in vec3 v_position;
out vec4 fragcolor;
const int SHADOW_VSM = 0;
const int SHADOW_CSM = 1;
uniform int shadow_technique;
#include "model_fs.glsl"
#include "surface.glsl"
void main() {
vec4 diffuse = get_diffuse_map();
diffuse.a *= u_global_alpha*u_global_opacity;
if (diffuse.a < 0.1)
discard;
if (shadow_technique == SHADOW_VSM) {
float depth = length(v_position) / 200;
@ -16,9 +22,9 @@ void main() {
float dx = dFdx(depth);
float dy = dFdy(depth);
moment2 += 0.25*(dx*dx+dy*dy);
fragcolor = vec4( moment1, moment2, 0.0, 1.0);
fragcolor = vec4( moment1, moment2, /* diffuse.a */ 0.0, 1.0);
}
else if (shadow_technique == SHADOW_CSM) {
fragcolor = vec4(vec3(gl_FragCoord.z), 1.0);
fragcolor = vec4(gl_FragCoord.z, /* diffuse.a */ 0.0, 0.0, 1.0);
}
}

View File

@ -383914,10 +383914,10 @@ void shadowmap_end(shadowmap_t *s) {
// Per-light resources
for (int i = 0; i < MAX_LIGHTS; i++) {
if (s->maps[i].shadow_technique == SHADOW_VSM) {
// VSM cubemap texture (GL_RG32F)
// VSM cubemap texture (GL_RGB32F)
s->vram_usage_vsm += 6 * s->vsm_texture_width * s->vsm_texture_width * 8;
} else if (s->maps[i].shadow_technique == SHADOW_CSM) {
// CSM textures (GL_R16F)
// CSM textures (GL_RG16F)
s->vram_usage_csm += NUM_SHADOW_CASCADES * s->csm_texture_width * s->csm_texture_width * 2;
}
}
@ -386587,6 +386587,7 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
q->textures = q->textures ? q->textures : CALLOC(hdr->num_meshes * 8, sizeof(GLuint)); // up to 8 textures per mesh
q->colormaps = q->colormaps ? q->colormaps : CALLOC(hdr->num_meshes * 8, sizeof(vec4)); // up to 8 colormaps per mesh
texture_t tex = {0};
GLuint *out = q->textures;
const char *str = hdr->ofs_text ? (char *)&q->buf[hdr->ofs_text] : "";
@ -386627,7 +386628,8 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
array(char) embedded_texture = base64_decode(material_embedded_texture, strlen(material_embedded_texture));
//printf("%s %d\n", material_embedded_texture, array_count(embedded_texture));
//hexdump(embedded_texture, array_count(embedded_texture));
*out = texture_compressed_from_mem( embedded_texture, array_count(embedded_texture), flags ).id;
tex = texture_compressed_from_mem( embedded_texture, array_count(embedded_texture), flags );
*out = tex.id;
array_free(embedded_texture);
}
@ -386655,7 +386657,8 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
material_name = va("%s", &str[m->material]);
char* plus = strrchr(material_name, '+');
if (plus) { strcpy_safe(plus, file_ext(material_name)); }
*out = texture_compressed(material_name, flags).id;
tex = texture_compressed(material_name, flags);
*out = tex.id;
}
// else try right token
if (*out == invalid) {
@ -386663,12 +386666,14 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
char* plus = strrchr(material_name, '+'), *slash = strrchr(material_name, '/');
if (plus) {
strcpy_safe(slash ? slash + 1 : material_name, plus + 1);
*out = texture_compressed(material_name, flags).id;
tex = texture_compressed(material_name, flags);
*out = tex.id;
}
}
// else last resort
if (*out == invalid) {
*out = texture_compressed(material_name, flags).id; // needed?
tex = texture_compressed(material_name, flags);
*out = tex.id; // needed?
}
}
@ -386677,7 +386682,8 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
} else {
PRINTF("warn: material[%d] not found: %s\n", i, &str[m->material]);
PRINTF("warn: using placeholder material[%d]=texture_checker\n", i);
*out = texture_checker().id; // placeholder
tex = texture_checker();
*out = tex.id; // placeholder
}
inscribe_tex:;
@ -386691,7 +386697,8 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
// initialise basic texture layer
mt.layer[MATERIAL_CHANNEL_DIFFUSE].map.color = material_color_hex ? material_color : vec4(1,1,1,1);
mt.layer[MATERIAL_CHANNEL_DIFFUSE].map.texture = CALLOC(1, sizeof(texture_t));
mt.layer[MATERIAL_CHANNEL_DIFFUSE].map.texture->id = *out++;
*mt.layer[MATERIAL_CHANNEL_DIFFUSE].map.texture = tex;
out++;
array_push(model->materials, mt);
}
@ -386781,7 +386788,7 @@ void model_set_renderstates(model_t *m) {
csm_shadow_rs->blend_dst = GL_ONE_MINUS_SRC_ALPHA;
csm_shadow_rs->depth_test_enabled = true;
csm_shadow_rs->depth_write_enabled = true;
csm_shadow_rs->cull_face_enabled = 1;
csm_shadow_rs->cull_face_enabled = 0;
csm_shadow_rs->cull_face_mode = GL_BACK;
csm_shadow_rs->front_face = GL_CW;
csm_shadow_rs->depth_clamp_enabled = 1;
@ -386794,7 +386801,7 @@ void model_set_renderstates(model_t *m) {
vsm_shadow_rs->blend_dst = GL_ONE_MINUS_SRC_ALPHA;
vsm_shadow_rs->depth_test_enabled = true;
vsm_shadow_rs->depth_write_enabled = true;
vsm_shadow_rs->cull_face_enabled = 1;
vsm_shadow_rs->cull_face_enabled = 0;
vsm_shadow_rs->cull_face_mode = GL_BACK;
vsm_shadow_rs->front_face = GL_CW;
vsm_shadow_rs->depth_clamp_enabled = 1;
@ -387123,7 +387130,7 @@ bool model_has_transparency_mesh(model_t m, int mesh) {
if (m.flags & MODEL_TRANSPARENT) {
return true;
}
if (m.materials[mesh].layer[0].map.color.a < 1 || (m.materials[mesh].layer[0].map.texture && m.materials[mesh].layer[0].map.texture->transparent)) {
if (m.materials[mesh].layer[MATERIAL_CHANNEL_DIFFUSE].map.color.a < 1 || (m.materials[mesh].layer[MATERIAL_CHANNEL_DIFFUSE].map.texture && m.materials[mesh].layer[MATERIAL_CHANNEL_DIFFUSE].map.texture->transparent)) {
return true;
}
if (m.shading == SHADING_PBR && (m.materials[mesh].layer[MATERIAL_CHANNEL_ALBEDO].map.color.a < 1 || (m.materials[mesh].layer[MATERIAL_CHANNEL_ALBEDO].map.texture && m.materials[mesh].layer[MATERIAL_CHANNEL_ALBEDO].map.texture->transparent))){
@ -387277,26 +387284,26 @@ void model_draw_call(model_t m, int shader, int pass, vec3 cam_pos, mat44 model_
rs = &m.rs[rs_idx];
renderstate_apply(rs);
}
if (rs_idx < RENDER_PASS_SHADOW_BEGIN || rs_idx > RENDER_PASS_SHADOW_END) {
if (m.shading != SHADING_PBR) {
shader_texture_unit("u_texture2d", q->textures[i], texture_unit());
shader_texture("u_lightmap", m.lightmap);
if (m.shading != SHADING_PBR) {
shader_texture_unit("u_texture2d", q->textures[i], texture_unit());
shader_texture("u_lightmap", m.lightmap);
int loc;
if ((loc = glGetUniformLocation(shader, "u_textured")) >= 0) {
bool textured = !!q->textures[i] && q->textures[i] != texture_checker().id; // m.materials[i].layer[0].texture != texture_checker().id;
glUniform1i(loc, textured ? GL_TRUE : GL_FALSE);
if ((loc = glGetUniformLocation(shader, "u_diffuse")) >= 0) {
glUniform4f(loc, m.materials[i].layer[0].map.color.r, m.materials[i].layer[0].map.color.g, m.materials[i].layer[0].map.color.b, m.materials[i].layer[0].map.color.a);
}
int loc;
if ((loc = glGetUniformLocation(shader, "u_textured")) >= 0) {
bool textured = !!q->textures[i] && q->textures[i] != texture_checker().id; // m.materials[i].layer[0].texture != texture_checker().id;
glUniform1i(loc, textured ? GL_TRUE : GL_FALSE);
if ((loc = glGetUniformLocation(shader, "u_diffuse")) >= 0) {
glUniform4f(loc, m.materials[i].layer[0].map.color.r, m.materials[i].layer[0].map.color.g, m.materials[i].layer[0].map.color.b, m.materials[i].layer[0].map.color.a);
}
}
} else {
const material_t *material = &m.materials[i];
shader_colormap_model_internal( "map_diffuse.color", "map_diffuse.has_tex", "map_diffuse_tex", material->layer[MATERIAL_CHANNEL_DIFFUSE].map );
} else {
const material_t *material = &m.materials[i];
shader_colormap_model_internal( "map_diffuse.color", "map_diffuse.has_tex", "map_diffuse_tex", material->layer[MATERIAL_CHANNEL_DIFFUSE].map );
shader_colormap_model_internal( "map_albedo.color", "map_albedo.has_tex", "map_albedo_tex", material->layer[MATERIAL_CHANNEL_ALBEDO].map );
if (rs_idx < RENDER_PASS_SHADOW_BEGIN || rs_idx > RENDER_PASS_SHADOW_END) {
shader_colormap_model_internal( "map_normals.color", "map_normals.has_tex", "map_normals_tex", material->layer[MATERIAL_CHANNEL_NORMALS].map );
shader_colormap_model_internal( "map_specular.color", "map_specular.has_tex", "map_specular_tex", material->layer[MATERIAL_CHANNEL_SPECULAR].map );
shader_colormap_model_internal( "map_albedo.color", "map_albedo.has_tex", "map_albedo_tex", material->layer[MATERIAL_CHANNEL_ALBEDO].map );
shader_colormap_model_internal( "map_roughness.color", "map_roughness.has_tex", "map_roughness_tex", material->layer[MATERIAL_CHANNEL_ROUGHNESS].map );
shader_colormap_model_internal( "map_metallic.color", "map_metallic.has_tex", "map_metallic_tex", material->layer[MATERIAL_CHANNEL_METALLIC].map );
shader_colormap_model_internal( "map_ao.color", "map_ao.has_tex", "map_ao_tex", material->layer[MATERIAL_CHANNEL_AO].map );

View File

@ -2094,10 +2094,10 @@ void shadowmap_end(shadowmap_t *s) {
// Per-light resources
for (int i = 0; i < MAX_LIGHTS; i++) {
if (s->maps[i].shadow_technique == SHADOW_VSM) {
// VSM cubemap texture (GL_RG32F)
// VSM cubemap texture (GL_RGB32F)
s->vram_usage_vsm += 6 * s->vsm_texture_width * s->vsm_texture_width * 8;
} else if (s->maps[i].shadow_technique == SHADOW_CSM) {
// CSM textures (GL_R16F)
// CSM textures (GL_RG16F)
s->vram_usage_csm += NUM_SHADOW_CASCADES * s->csm_texture_width * s->csm_texture_width * 2;
}
}
@ -4767,6 +4767,7 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
q->textures = q->textures ? q->textures : CALLOC(hdr->num_meshes * 8, sizeof(GLuint)); // up to 8 textures per mesh
q->colormaps = q->colormaps ? q->colormaps : CALLOC(hdr->num_meshes * 8, sizeof(vec4)); // up to 8 colormaps per mesh
texture_t tex = {0};
GLuint *out = q->textures;
const char *str = hdr->ofs_text ? (char *)&q->buf[hdr->ofs_text] : "";
@ -4807,7 +4808,8 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
array(char) embedded_texture = base64_decode(material_embedded_texture, strlen(material_embedded_texture));
//printf("%s %d\n", material_embedded_texture, array_count(embedded_texture));
//hexdump(embedded_texture, array_count(embedded_texture));
*out = texture_compressed_from_mem( embedded_texture, array_count(embedded_texture), flags ).id;
tex = texture_compressed_from_mem( embedded_texture, array_count(embedded_texture), flags );
*out = tex.id;
array_free(embedded_texture);
}
@ -4835,7 +4837,8 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
material_name = va("%s", &str[m->material]);
char* plus = strrchr(material_name, '+');
if (plus) { strcpy_safe(plus, file_ext(material_name)); }
*out = texture_compressed(material_name, flags).id;
tex = texture_compressed(material_name, flags);
*out = tex.id;
}
// else try right token
if (*out == invalid) {
@ -4843,12 +4846,14 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
char* plus = strrchr(material_name, '+'), *slash = strrchr(material_name, '/');
if (plus) {
strcpy_safe(slash ? slash + 1 : material_name, plus + 1);
*out = texture_compressed(material_name, flags).id;
tex = texture_compressed(material_name, flags);
*out = tex.id;
}
}
// else last resort
if (*out == invalid) {
*out = texture_compressed(material_name, flags).id; // needed?
tex = texture_compressed(material_name, flags);
*out = tex.id; // needed?
}
}
@ -4857,7 +4862,8 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
} else {
PRINTF("warn: material[%d] not found: %s\n", i, &str[m->material]);
PRINTF("warn: using placeholder material[%d]=texture_checker\n", i);
*out = texture_checker().id; // placeholder
tex = texture_checker();
*out = tex.id; // placeholder
}
inscribe_tex:;
@ -4871,7 +4877,8 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
// initialise basic texture layer
mt.layer[MATERIAL_CHANNEL_DIFFUSE].map.color = material_color_hex ? material_color : vec4(1,1,1,1);
mt.layer[MATERIAL_CHANNEL_DIFFUSE].map.texture = CALLOC(1, sizeof(texture_t));
mt.layer[MATERIAL_CHANNEL_DIFFUSE].map.texture->id = *out++;
*mt.layer[MATERIAL_CHANNEL_DIFFUSE].map.texture = tex;
out++;
array_push(model->materials, mt);
}
@ -4961,7 +4968,7 @@ void model_set_renderstates(model_t *m) {
csm_shadow_rs->blend_dst = GL_ONE_MINUS_SRC_ALPHA;
csm_shadow_rs->depth_test_enabled = true;
csm_shadow_rs->depth_write_enabled = true;
csm_shadow_rs->cull_face_enabled = 1;
csm_shadow_rs->cull_face_enabled = 0;
csm_shadow_rs->cull_face_mode = GL_BACK;
csm_shadow_rs->front_face = GL_CW;
csm_shadow_rs->depth_clamp_enabled = 1;
@ -4974,7 +4981,7 @@ void model_set_renderstates(model_t *m) {
vsm_shadow_rs->blend_dst = GL_ONE_MINUS_SRC_ALPHA;
vsm_shadow_rs->depth_test_enabled = true;
vsm_shadow_rs->depth_write_enabled = true;
vsm_shadow_rs->cull_face_enabled = 1;
vsm_shadow_rs->cull_face_enabled = 0;
vsm_shadow_rs->cull_face_mode = GL_BACK;
vsm_shadow_rs->front_face = GL_CW;
vsm_shadow_rs->depth_clamp_enabled = 1;
@ -5303,7 +5310,7 @@ bool model_has_transparency_mesh(model_t m, int mesh) {
if (m.flags & MODEL_TRANSPARENT) {
return true;
}
if (m.materials[mesh].layer[0].map.color.a < 1 || (m.materials[mesh].layer[0].map.texture && m.materials[mesh].layer[0].map.texture->transparent)) {
if (m.materials[mesh].layer[MATERIAL_CHANNEL_DIFFUSE].map.color.a < 1 || (m.materials[mesh].layer[MATERIAL_CHANNEL_DIFFUSE].map.texture && m.materials[mesh].layer[MATERIAL_CHANNEL_DIFFUSE].map.texture->transparent)) {
return true;
}
if (m.shading == SHADING_PBR && (m.materials[mesh].layer[MATERIAL_CHANNEL_ALBEDO].map.color.a < 1 || (m.materials[mesh].layer[MATERIAL_CHANNEL_ALBEDO].map.texture && m.materials[mesh].layer[MATERIAL_CHANNEL_ALBEDO].map.texture->transparent))){
@ -5457,26 +5464,26 @@ void model_draw_call(model_t m, int shader, int pass, vec3 cam_pos, mat44 model_
rs = &m.rs[rs_idx];
renderstate_apply(rs);
}
if (rs_idx < RENDER_PASS_SHADOW_BEGIN || rs_idx > RENDER_PASS_SHADOW_END) {
if (m.shading != SHADING_PBR) {
shader_texture_unit("u_texture2d", q->textures[i], texture_unit());
shader_texture("u_lightmap", m.lightmap);
if (m.shading != SHADING_PBR) {
shader_texture_unit("u_texture2d", q->textures[i], texture_unit());
shader_texture("u_lightmap", m.lightmap);
int loc;
if ((loc = glGetUniformLocation(shader, "u_textured")) >= 0) {
bool textured = !!q->textures[i] && q->textures[i] != texture_checker().id; // m.materials[i].layer[0].texture != texture_checker().id;
glUniform1i(loc, textured ? GL_TRUE : GL_FALSE);
if ((loc = glGetUniformLocation(shader, "u_diffuse")) >= 0) {
glUniform4f(loc, m.materials[i].layer[0].map.color.r, m.materials[i].layer[0].map.color.g, m.materials[i].layer[0].map.color.b, m.materials[i].layer[0].map.color.a);
}
int loc;
if ((loc = glGetUniformLocation(shader, "u_textured")) >= 0) {
bool textured = !!q->textures[i] && q->textures[i] != texture_checker().id; // m.materials[i].layer[0].texture != texture_checker().id;
glUniform1i(loc, textured ? GL_TRUE : GL_FALSE);
if ((loc = glGetUniformLocation(shader, "u_diffuse")) >= 0) {
glUniform4f(loc, m.materials[i].layer[0].map.color.r, m.materials[i].layer[0].map.color.g, m.materials[i].layer[0].map.color.b, m.materials[i].layer[0].map.color.a);
}
}
} else {
const material_t *material = &m.materials[i];
shader_colormap_model_internal( "map_diffuse.color", "map_diffuse.has_tex", "map_diffuse_tex", material->layer[MATERIAL_CHANNEL_DIFFUSE].map );
} else {
const material_t *material = &m.materials[i];
shader_colormap_model_internal( "map_diffuse.color", "map_diffuse.has_tex", "map_diffuse_tex", material->layer[MATERIAL_CHANNEL_DIFFUSE].map );
shader_colormap_model_internal( "map_albedo.color", "map_albedo.has_tex", "map_albedo_tex", material->layer[MATERIAL_CHANNEL_ALBEDO].map );
if (rs_idx < RENDER_PASS_SHADOW_BEGIN || rs_idx > RENDER_PASS_SHADOW_END) {
shader_colormap_model_internal( "map_normals.color", "map_normals.has_tex", "map_normals_tex", material->layer[MATERIAL_CHANNEL_NORMALS].map );
shader_colormap_model_internal( "map_specular.color", "map_specular.has_tex", "map_specular_tex", material->layer[MATERIAL_CHANNEL_SPECULAR].map );
shader_colormap_model_internal( "map_albedo.color", "map_albedo.has_tex", "map_albedo_tex", material->layer[MATERIAL_CHANNEL_ALBEDO].map );
shader_colormap_model_internal( "map_roughness.color", "map_roughness.has_tex", "map_roughness_tex", material->layer[MATERIAL_CHANNEL_ROUGHNESS].map );
shader_colormap_model_internal( "map_metallic.color", "map_metallic.has_tex", "map_metallic_tex", material->layer[MATERIAL_CHANNEL_METALLIC].map );
shader_colormap_model_internal( "map_ao.color", "map_ao.has_tex", "map_ao_tex", material->layer[MATERIAL_CHANNEL_AO].map );

View File

@ -18948,10 +18948,10 @@ void shadowmap_end(shadowmap_t *s) {
// Per-light resources
for (int i = 0; i < MAX_LIGHTS; i++) {
if (s->maps[i].shadow_technique == SHADOW_VSM) {
// VSM cubemap texture (GL_RG32F)
// VSM cubemap texture (GL_RGB32F)
s->vram_usage_vsm += 6 * s->vsm_texture_width * s->vsm_texture_width * 8;
} else if (s->maps[i].shadow_technique == SHADOW_CSM) {
// CSM textures (GL_R16F)
// CSM textures (GL_RG16F)
s->vram_usage_csm += NUM_SHADOW_CASCADES * s->csm_texture_width * s->csm_texture_width * 2;
}
}
@ -21621,6 +21621,7 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
q->textures = q->textures ? q->textures : CALLOC(hdr->num_meshes * 8, sizeof(GLuint)); // up to 8 textures per mesh
q->colormaps = q->colormaps ? q->colormaps : CALLOC(hdr->num_meshes * 8, sizeof(vec4)); // up to 8 colormaps per mesh
texture_t tex = {0};
GLuint *out = q->textures;
const char *str = hdr->ofs_text ? (char *)&q->buf[hdr->ofs_text] : "";
@ -21661,7 +21662,8 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
array(char) embedded_texture = base64_decode(material_embedded_texture, strlen(material_embedded_texture));
//printf("%s %d\n", material_embedded_texture, array_count(embedded_texture));
//hexdump(embedded_texture, array_count(embedded_texture));
*out = texture_compressed_from_mem( embedded_texture, array_count(embedded_texture), flags ).id;
tex = texture_compressed_from_mem( embedded_texture, array_count(embedded_texture), flags );
*out = tex.id;
array_free(embedded_texture);
}
@ -21689,7 +21691,8 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
material_name = va("%s", &str[m->material]);
char* plus = strrchr(material_name, '+');
if (plus) { strcpy_safe(plus, file_ext(material_name)); }
*out = texture_compressed(material_name, flags).id;
tex = texture_compressed(material_name, flags);
*out = tex.id;
}
// else try right token
if (*out == invalid) {
@ -21697,12 +21700,14 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
char* plus = strrchr(material_name, '+'), *slash = strrchr(material_name, '/');
if (plus) {
strcpy_safe(slash ? slash + 1 : material_name, plus + 1);
*out = texture_compressed(material_name, flags).id;
tex = texture_compressed(material_name, flags);
*out = tex.id;
}
}
// else last resort
if (*out == invalid) {
*out = texture_compressed(material_name, flags).id; // needed?
tex = texture_compressed(material_name, flags);
*out = tex.id; // needed?
}
}
@ -21711,7 +21716,8 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
} else {
PRINTF("warn: material[%d] not found: %s\n", i, &str[m->material]);
PRINTF("warn: using placeholder material[%d]=texture_checker\n", i);
*out = texture_checker().id; // placeholder
tex = texture_checker();
*out = tex.id; // placeholder
}
inscribe_tex:;
@ -21725,7 +21731,8 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
// initialise basic texture layer
mt.layer[MATERIAL_CHANNEL_DIFFUSE].map.color = material_color_hex ? material_color : vec4(1,1,1,1);
mt.layer[MATERIAL_CHANNEL_DIFFUSE].map.texture = CALLOC(1, sizeof(texture_t));
mt.layer[MATERIAL_CHANNEL_DIFFUSE].map.texture->id = *out++;
*mt.layer[MATERIAL_CHANNEL_DIFFUSE].map.texture = tex;
out++;
array_push(model->materials, mt);
}
@ -21815,7 +21822,7 @@ void model_set_renderstates(model_t *m) {
csm_shadow_rs->blend_dst = GL_ONE_MINUS_SRC_ALPHA;
csm_shadow_rs->depth_test_enabled = true;
csm_shadow_rs->depth_write_enabled = true;
csm_shadow_rs->cull_face_enabled = 1;
csm_shadow_rs->cull_face_enabled = 0;
csm_shadow_rs->cull_face_mode = GL_BACK;
csm_shadow_rs->front_face = GL_CW;
csm_shadow_rs->depth_clamp_enabled = 1;
@ -21828,7 +21835,7 @@ void model_set_renderstates(model_t *m) {
vsm_shadow_rs->blend_dst = GL_ONE_MINUS_SRC_ALPHA;
vsm_shadow_rs->depth_test_enabled = true;
vsm_shadow_rs->depth_write_enabled = true;
vsm_shadow_rs->cull_face_enabled = 1;
vsm_shadow_rs->cull_face_enabled = 0;
vsm_shadow_rs->cull_face_mode = GL_BACK;
vsm_shadow_rs->front_face = GL_CW;
vsm_shadow_rs->depth_clamp_enabled = 1;
@ -22157,7 +22164,7 @@ bool model_has_transparency_mesh(model_t m, int mesh) {
if (m.flags & MODEL_TRANSPARENT) {
return true;
}
if (m.materials[mesh].layer[0].map.color.a < 1 || (m.materials[mesh].layer[0].map.texture && m.materials[mesh].layer[0].map.texture->transparent)) {
if (m.materials[mesh].layer[MATERIAL_CHANNEL_DIFFUSE].map.color.a < 1 || (m.materials[mesh].layer[MATERIAL_CHANNEL_DIFFUSE].map.texture && m.materials[mesh].layer[MATERIAL_CHANNEL_DIFFUSE].map.texture->transparent)) {
return true;
}
if (m.shading == SHADING_PBR && (m.materials[mesh].layer[MATERIAL_CHANNEL_ALBEDO].map.color.a < 1 || (m.materials[mesh].layer[MATERIAL_CHANNEL_ALBEDO].map.texture && m.materials[mesh].layer[MATERIAL_CHANNEL_ALBEDO].map.texture->transparent))){
@ -22311,26 +22318,26 @@ void model_draw_call(model_t m, int shader, int pass, vec3 cam_pos, mat44 model_
rs = &m.rs[rs_idx];
renderstate_apply(rs);
}
if (rs_idx < RENDER_PASS_SHADOW_BEGIN || rs_idx > RENDER_PASS_SHADOW_END) {
if (m.shading != SHADING_PBR) {
shader_texture_unit("u_texture2d", q->textures[i], texture_unit());
shader_texture("u_lightmap", m.lightmap);
if (m.shading != SHADING_PBR) {
shader_texture_unit("u_texture2d", q->textures[i], texture_unit());
shader_texture("u_lightmap", m.lightmap);
int loc;
if ((loc = glGetUniformLocation(shader, "u_textured")) >= 0) {
bool textured = !!q->textures[i] && q->textures[i] != texture_checker().id; // m.materials[i].layer[0].texture != texture_checker().id;
glUniform1i(loc, textured ? GL_TRUE : GL_FALSE);
if ((loc = glGetUniformLocation(shader, "u_diffuse")) >= 0) {
glUniform4f(loc, m.materials[i].layer[0].map.color.r, m.materials[i].layer[0].map.color.g, m.materials[i].layer[0].map.color.b, m.materials[i].layer[0].map.color.a);
}
int loc;
if ((loc = glGetUniformLocation(shader, "u_textured")) >= 0) {
bool textured = !!q->textures[i] && q->textures[i] != texture_checker().id; // m.materials[i].layer[0].texture != texture_checker().id;
glUniform1i(loc, textured ? GL_TRUE : GL_FALSE);
if ((loc = glGetUniformLocation(shader, "u_diffuse")) >= 0) {
glUniform4f(loc, m.materials[i].layer[0].map.color.r, m.materials[i].layer[0].map.color.g, m.materials[i].layer[0].map.color.b, m.materials[i].layer[0].map.color.a);
}
}
} else {
const material_t *material = &m.materials[i];
shader_colormap_model_internal( "map_diffuse.color", "map_diffuse.has_tex", "map_diffuse_tex", material->layer[MATERIAL_CHANNEL_DIFFUSE].map );
} else {
const material_t *material = &m.materials[i];
shader_colormap_model_internal( "map_diffuse.color", "map_diffuse.has_tex", "map_diffuse_tex", material->layer[MATERIAL_CHANNEL_DIFFUSE].map );
shader_colormap_model_internal( "map_albedo.color", "map_albedo.has_tex", "map_albedo_tex", material->layer[MATERIAL_CHANNEL_ALBEDO].map );
if (rs_idx < RENDER_PASS_SHADOW_BEGIN || rs_idx > RENDER_PASS_SHADOW_END) {
shader_colormap_model_internal( "map_normals.color", "map_normals.has_tex", "map_normals_tex", material->layer[MATERIAL_CHANNEL_NORMALS].map );
shader_colormap_model_internal( "map_specular.color", "map_specular.has_tex", "map_specular_tex", material->layer[MATERIAL_CHANNEL_SPECULAR].map );
shader_colormap_model_internal( "map_albedo.color", "map_albedo.has_tex", "map_albedo_tex", material->layer[MATERIAL_CHANNEL_ALBEDO].map );
shader_colormap_model_internal( "map_roughness.color", "map_roughness.has_tex", "map_roughness_tex", material->layer[MATERIAL_CHANNEL_ROUGHNESS].map );
shader_colormap_model_internal( "map_metallic.color", "map_metallic.has_tex", "map_metallic_tex", material->layer[MATERIAL_CHANNEL_METALLIC].map );
shader_colormap_model_internal( "map_ao.color", "map_ao.has_tex", "map_ao_tex", material->layer[MATERIAL_CHANNEL_AO].map );