rtx: add scalar parameters for material overrides, fix #238

This commit is contained in:
Ivan Avdeev 2021-12-01 10:32:32 -08:00
parent 5917fff727
commit f70f5bfe82
6 changed files with 78 additions and 52 deletions

View File

@ -83,6 +83,7 @@ void main() {
vec3 sample_geometry_normal, sample_shading_normal;
readNormals(p, sample_geometry_normal, sample_shading_normal);
// FIXME also filter by depth, (kusok index?), etc
if ( dot(sample_geometry_normal, geometry_normal) < .99 )
continue;

View File

@ -73,12 +73,13 @@ void main() {
const int instance_kusochki_offset = gl_InstanceCustomIndexEXT;
const int kusok_index = instance_kusochki_offset + gl_GeometryIndexEXT;
const Kusok kusok = kusochki[kusok_index];
const uint first_index_offset = kusochki[kusok_index].index_offset + gl_PrimitiveID * 3;
const uint first_index_offset = kusok.index_offset + gl_PrimitiveID * 3;
const uint vi1 = uint(indices[first_index_offset+0]) + kusochki[kusok_index].vertex_offset;
const uint vi2 = uint(indices[first_index_offset+1]) + kusochki[kusok_index].vertex_offset;
const uint vi3 = uint(indices[first_index_offset+2]) + kusochki[kusok_index].vertex_offset;
const uint vi1 = uint(indices[first_index_offset+0]) + kusok.vertex_offset;
const uint vi2 = uint(indices[first_index_offset+1]) + kusok.vertex_offset;
const uint vi3 = uint(indices[first_index_offset+2]) + kusok.vertex_offset;
const vec3 pos[3] = {
gl_ObjectToWorldEXT * vec4(vertices[vi1].pos, 1.),
@ -89,7 +90,7 @@ void main() {
const vec3 hit_pos = pos[0] * (1. - bary.x - bary.y) + pos[1] * bary.x + pos[2] * bary.y;
//const vec3 hit_pos = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT
const uint tex_base_color = kusochki[kusok_index].tex_base_color;
const uint tex_base_color = kusok.tex_base_color;
if ((tex_base_color & KUSOK_MATERIAL_FLAG_SKYBOX) != 0) {
payload.hit_pos_t = vec4(hit_pos, gl_HitTEXT);
payload.base_color = vec3(0.);
@ -120,7 +121,7 @@ void main() {
};
const vec2 texture_uv_stationary = vertices[vi1].gl_tc * (1. - bary.x - bary.y) + vertices[vi2].gl_tc * bary.x + vertices[vi3].gl_tc * bary.y;
const vec2 texture_uv = texture_uv_stationary + push_constants.time * kusochki[kusok_index].uv_speed;
const vec2 texture_uv = texture_uv_stationary + push_constants.time * kusok.uv_speed;
const vec3 real_geom_normal = normalize(cross(pos[2]-pos[0], pos[1]-pos[0]));
const float geom_normal_sign = sign(dot(real_geom_normal, -gl_WorldRayDirectionEXT));
@ -138,7 +139,7 @@ void main() {
/* const vec3 base_color = tex_color.rgb; */
normal *= geom_normal_sign;
const uint tex_normal = kusochki[kusok_index].tex_normalmap;
const uint tex_normal = kusok.tex_normalmap;
vec3 T = baryMix(vertices[vi1].tangent, vertices[vi2].tangent, vertices[vi3].tangent, bary);
if (tex_normal > 0 && dot(T,T) > .5) {
T = normalize(normalTransformMat * T);
@ -152,14 +153,15 @@ void main() {
// FIXME read alpha from texture
payload.hit_pos_t = vec4(hit_pos + geom_normal * normal_offset_fudge, gl_HitTEXT);
payload.base_color = base_color * kusochki[kusok_index].color.rgb;
payload.transmissiveness = (1. - tex_color.a * kusochki[kusok_index].color.a);
payload.base_color = base_color * kusok.color.rgb;
payload.transmissiveness = (1. - tex_color.a * kusok.color.a);
payload.normal = normal;
payload.geometry_normal = geom_normal;
payload.emissive = kusochki[kusok_index].emissive * base_color; // TODO emissive should have a special texture
payload.emissive = kusok.emissive * base_color; // TODO emissive should have a special texture
payload.kusok_index = kusok_index;
payload.roughness = sampleTexture(kusochki[kusok_index].tex_roughness, texture_uv, uv_lods).r;
payload.metalness = sampleTexture(kusochki[kusok_index].tex_metalness, texture_uv, uv_lods).r;
payload.roughness = (kusok.tex_roughness > 0) ? sampleTexture(kusok.tex_roughness, texture_uv, uv_lods).r : kusok.roughness;
payload.metalness = (kusok.tex_metalness > 0) ? sampleTexture(kusok.tex_metalness, texture_uv, uv_lods).r : kusok.metalness;
payload.material_index = tex_index;
//payload.debug = vec4(texture_uv, uv_lods);

View File

@ -50,9 +50,13 @@ struct Kusok {
vec3 emissive;
uint tex_roughness;
vec2 uv_speed; // for conveyors
vec2 uv_speed; // for conveyors; TODO this can definitely be done in software more efficiently (there only a handful of these per map)
uint tex_metalness;
uint tex_normalmap;
float roughness;
float metalness;
PAD(2)
};
struct PointLight {

View File

@ -5,6 +5,19 @@
#include <stdio.h>
static const xvk_material_t k_default_material = {
.tex_base_color = -1,
.tex_metalness = 0,
.tex_roughness = 0,
.tex_normalmap = 0,
.metalness = 0.f,
.roughness = 1.f,
.base_color = { 1.f, 1.f, 1.f },
.set = false,
};
static struct {
xvk_material_t materials[MAX_TEXTURES];
} g_materials;
@ -50,7 +63,7 @@ static void loadMaterialsFromFile( const char *filename ) {
.base_color = -1,
.metalness = tglob.blackTexture,
.roughness = tglob.whiteTexture,
.normalmap = 0,
.tex_normalmap = 0,
};
int current_material_index = -1;
qboolean force_reload = false;
@ -75,20 +88,15 @@ static void loadMaterialsFromFile( const char *filename ) {
break;
if (key[0] == '{') {
current_material = (xvk_material_t){
.base_color = -1,
.metalness = tglob.blackTexture,
.roughness = tglob.whiteTexture,
.normalmap = 0,
};
current_material = k_default_material;
force_reload = false;
continue;
}
if (key[0] == '}') {
if (current_material_index >= 0) {
if (current_material.base_color == -1)
current_material.base_color = current_material_index;
if (current_material.tex_base_color == -1)
current_material.tex_base_color = current_material_index;
g_materials.materials[current_material_index] = current_material;
g_materials.materials[current_material_index].set = true;
}
@ -105,16 +113,21 @@ static void loadMaterialsFromFile( const char *filename ) {
force_reload = Q_atoi(value) != 0;
} else {
char texture_path[256];
int *tex_id_dest;
int tex_id = -1;
int *tex_id_dest = NULL;
if (Q_stricmp(key, "basecolor_map") == 0) {
tex_id_dest = &current_material.base_color;
tex_id_dest = &current_material.tex_base_color;
} else if (Q_stricmp(key, "normal_map") == 0) {
tex_id_dest = &current_material.normalmap;
tex_id_dest = &current_material.tex_normalmap;
} else if (Q_stricmp(key, "metal_map") == 0) {
tex_id_dest = &current_material.metalness;
tex_id_dest = &current_material.tex_metalness;
} else if (Q_stricmp(key, "roughness_map") == 0) {
tex_id_dest = &current_material.roughness;
tex_id_dest = &current_material.tex_roughness;
} else if (Q_stricmp(key, "roughness") == 0) {
sscanf(value, "%f", &current_material.roughness);
} else if (Q_stricmp(key, "metalness") == 0) {
sscanf(value, "%f", &current_material.metalness);
} else if (Q_stricmp(key, "base_color") == 0) {
sscanf(value, "%f %f %f", &current_material.base_color[0], &current_material.base_color[1], &current_material.base_color[2]);
} else {
gEngine.Con_Printf(S_ERROR "Unknown material key %s\n", key);
continue;
@ -128,13 +141,15 @@ static void loadMaterialsFromFile( const char *filename ) {
Q_snprintf(texture_path, sizeof(texture_path), "%.*s%s", (int)(path_end - path_begin), path_begin, value);
}
tex_id = loadTexture(texture_path, force_reload);
if (tex_id < 0) {
gEngine.Con_Printf(S_ERROR "Failed to load texture \"%s\" for key \"%s\"\n", value, key);
continue;
}
if (tex_id_dest) {
const int tex_id = loadTexture(texture_path, force_reload);
if (tex_id < 0) {
gEngine.Con_Printf(S_ERROR "Failed to load texture \"%s\" for key \"%s\"\n", value, key);
continue;
}
*tex_id_dest = tex_id;
*tex_id_dest = tex_id;
}
}
}
@ -156,17 +171,10 @@ void XVK_ReloadMaterials( void ) {
for (int i = 0; i < MAX_TEXTURES; ++i) {
xvk_material_t *const mat = g_materials.materials + i;
const vk_texture_t *const tex = findTexture( i );
*mat = k_default_material;
if (!tex) {
mat->base_color = -1;
break;
}
mat->base_color = i;
mat->metalness = tglob.blackTexture;
mat->roughness = tglob.whiteTexture;
mat->normalmap = 0;
mat->set = false;
if (tex)
mat->tex_base_color = i;
}
loadMaterialsFromFile( "pbr/materials.mat" );

View File

@ -3,10 +3,15 @@
#include "xash3d_types.h"
typedef struct {
int base_color;
int roughness;
int metalness;
int normalmap;
int tex_base_color;
int tex_roughness;
int tex_metalness;
int tex_normalmap;
vec3_t base_color;
float roughness;
float metalness;
qboolean set;
} xvk_material_t;

View File

@ -372,10 +372,13 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
if (!render_model->static_map)
VK_LightsAddEmissiveSurface( geom, transform_row, false );
kusok->tex_base_color = mat->base_color;
kusok->tex_roughness = mat->roughness;
kusok->tex_metalness = mat->metalness;
kusok->tex_normalmap = mat->normalmap;
kusok->tex_base_color = mat->tex_base_color;
kusok->tex_roughness = mat->tex_roughness;
kusok->tex_metalness = mat->tex_metalness;
kusok->tex_normalmap = mat->tex_normalmap;
kusok->roughness = mat->roughness;
kusok->metalness = mat->metalness;
// HACK until there is a proper mechanism for patching materials, see https://github.com/w23/xash3d-fwgs/issues/213
// FIXME also this erases previous roughness unconditionally
@ -390,6 +393,9 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
}
Vector4Copy(color, kusok->color);
kusok->color[0] *= mat->base_color[0];
kusok->color[1] *= mat->base_color[1];
kusok->color[2] *= mat->base_color[2];
if (geom->material == kXVkMaterialEmissive) {
VectorCopy( geom->emissive, kusok->emissive );