vk: rt: convert more engine-supplied colors from sRGB to linear

- model.color
- vertex_color
This commit is contained in:
Ivan Avdeev 2023-10-10 11:56:42 -04:00
parent 4fa614d35b
commit fadde2ea0d
8 changed files with 43 additions and 22 deletions

View File

@ -49,7 +49,7 @@ void readNormals(ivec2 uv, out vec3 geometry_normal, out vec3 shading_normal) {
} }
bool getHit(vec3 origin, vec3 direction, inout RayPayloadPrimary payload, int test_val) { bool getHit(vec3 origin, vec3 direction, inout RayPayloadPrimary payload) {
rayQueryEXT rq; rayQueryEXT rq;
const uint flags = 0 const uint flags = 0
//| gl_RayFlagsCullFrontFacingTrianglesEXT //| gl_RayFlagsCullFrontFacingTrianglesEXT
@ -84,7 +84,7 @@ bool getHit(vec3 origin, vec3 direction, inout RayPayloadPrimary payload, int te
if (rayQueryGetIntersectionTypeEXT(rq, true) != gl_RayQueryCommittedIntersectionTriangleEXT) if (rayQueryGetIntersectionTypeEXT(rq, true) != gl_RayQueryCommittedIntersectionTriangleEXT)
return false; return false;
primaryRayHit(rq, payload, test_val); primaryRayHit(rq, payload);
//L = rayQueryGetIntersectionTEXT(rq, true); //L = rayQueryGetIntersectionTEXT(rq, true);
return true; return true;
} }
@ -150,8 +150,7 @@ void computeBounce(ivec2 pix, vec3 direction, out vec3 diffuse, out vec3 specula
payload.base_color_a = vec4(0.); payload.base_color_a = vec4(0.);
payload.emissive = vec4(0.); payload.emissive = vec4(0.);
const vec3 pos = imageLoad(position_t, pix).xyz + geometry_normal * ray_normal_fudge; const vec3 pos = imageLoad(position_t, pix).xyz + geometry_normal * ray_normal_fudge;
const ivec2 res = ivec2(imageSize(out_indirect_diffuse)) / INDIRECT_SCALE; if (!getHit(pos, bounce_direction, payload))
if (!getHit(pos, bounce_direction, payload, (pix.x < res.x / 2) ? 0 : 1))
return; return;
throughput *= payload.base_color_a.rgb; throughput *= payload.base_color_a.rgb;

View File

@ -202,6 +202,25 @@ void main() {
imageStore(out_dest, pix, vec4(LINEARtoSRGB(imageLoad(DEBUG_TEXTURE, pix).rgb), 0.)); return; imageStore(out_dest, pix, vec4(LINEARtoSRGB(imageLoad(DEBUG_TEXTURE, pix).rgb), 0.)); return;
#endif #endif
/*
if (pix.x < res.x / 4) {
imageStore(out_dest, pix, vec4(imageLoad(base_color_a, pix).rgb, 0.)); return;
} else if (pix.x < res.x / 2) {
imageStore(out_dest, pix, vec4(LINEARtoSRGB(imageLoad(emissive, pix).rgb), 0.)); return;
} else if (pix.x < res.x * 3 / 4) {
imageStore(out_dest, pix, vec4(LINEARtoSRGB(fract(
imageLoad(light_poly_diffuse, pix).rgb
+ imageLoad(light_poly_specular, pix).rgb
+ imageLoad(light_point_diffuse, pix).rgb
+ imageLoad(light_point_specular, pix).rgb
)), 0.)); return;
} else {
imageStore(out_dest, pix, vec4(LINEARtoSRGB(
imageLoad(indirect_diffuse, pix / INDIRECT_SCALE).rgb
+ imageLoad(indirect_specular, pix / INDIRECT_SCALE).rgb
), 0.)); return;
}*/
//imageStore(out_dest, pix, vec4(fract(imageLoad(position_t, pix).rgb/10.), 0.)); return; //imageStore(out_dest, pix, vec4(fract(imageLoad(position_t, pix).rgb/10.), 0.)); return;
//imageStore(out_dest, pix, vec4(fract(imageLoad(geometry_prev_position, pix).rgb/50.), 0.)); return; //imageStore(out_dest, pix, vec4(fract(imageLoad(geometry_prev_position, pix).rgb/50.), 0.)); return;

View File

@ -103,7 +103,7 @@ void main() {
if (rayQueryGetIntersectionTypeEXT(rq, true) == gl_RayQueryCommittedIntersectionTriangleEXT) { if (rayQueryGetIntersectionTypeEXT(rq, true) == gl_RayQueryCommittedIntersectionTriangleEXT) {
//debug_geometry_index = rayQueryGetIntersectionGeometryIndexEXT(rq, true); //debug_geometry_index = rayQueryGetIntersectionGeometryIndexEXT(rq, true);
//debug_geometry_index = rayQueryGetIntersectionPrimitiveIndexEXT(rq, true); //debug_geometry_index = rayQueryGetIntersectionPrimitiveIndexEXT(rq, true);
primaryRayHit(rq, payload, (pix.x < res.x / 2) ? 0 : 1); primaryRayHit(rq, payload);
L = rayQueryGetIntersectionTEXT(rq, true); L = rayQueryGetIntersectionTEXT(rq, true);
} else { } else {
// Draw skybox when nothing is hit // Draw skybox when nothing is hit

View File

@ -20,7 +20,7 @@ vec4 sampleTexture(uint tex_index, vec2 uv, vec4 uv_lods) {
#endif #endif
} }
void primaryRayHit(rayQueryEXT rq, inout RayPayloadPrimary payload, int test_value) { void primaryRayHit(rayQueryEXT rq, inout RayPayloadPrimary payload) {
Geometry geom = readHitGeometry(rq, ubo.ubo.ray_cone_width, rayQueryGetIntersectionBarycentricsEXT(rq, true)); Geometry geom = readHitGeometry(rq, ubo.ubo.ray_cone_width, rayQueryGetIntersectionBarycentricsEXT(rq, true));
const float hitT = rayQueryGetIntersectionTEXT(rq, true); //gl_HitTEXT; const float hitT = rayQueryGetIntersectionTEXT(rq, true); //gl_HitTEXT;
const vec3 rayDirection = rayQueryGetWorldRayDirectionEXT(rq); //gl_WorldRayDirectionEXT const vec3 rayDirection = rayQueryGetWorldRayDirectionEXT(rq); //gl_WorldRayDirectionEXT
@ -99,18 +99,7 @@ void primaryRayHit(rayQueryEXT rq, inout RayPayloadPrimary payload, int test_val
const int model_index = rayQueryGetIntersectionInstanceIdEXT(rq, true); const int model_index = rayQueryGetIntersectionInstanceIdEXT(rq, true);
const ModelHeader model = getModelHeader(model_index); const ModelHeader model = getModelHeader(model_index);
const vec4 color = model.color * kusok.material.base_color;
//#define TEST_COLORS_GAMMA
#ifdef TEST_COLORS_GAMMA
// FIXME:
// - should material.base_color (which we control) be linear or sRGB?
// - is model.color linear or sRGB? It's a value from the engine, which implies sRGB. Can we convert it once in the native code?
const vec4 color = test_value == 0
? SRGBtoLINEAR(model.color) * kusok.material.base_color
: model.color * kusok.material.base_color;
#else
const vec4 color = SRGBtoLINEAR(model.color) * kusok.material.base_color;
#endif
payload.base_color_a *= color; payload.base_color_a *= color;
payload.emissive.rgb *= color.rgb; payload.emissive.rgb *= color.rgb;

View File

@ -53,7 +53,7 @@ void traceSimpleBlending(vec3 pos, vec3 dir, float L, inout vec3 emissive, inout
const vec4 texture_color = texture(textures[nonuniformEXT(kusok.material.tex_base_color)], geom.uv); const vec4 texture_color = texture(textures[nonuniformEXT(kusok.material.tex_base_color)], geom.uv);
const vec4 mm_color = model.color * kusok.material.base_color; const vec4 mm_color = model.color * kusok.material.base_color;
float alpha = mm_color.a * texture_color.a * geom.vertex_color.a; float alpha = mm_color.a * texture_color.a * geom.vertex_color.a;
vec3 color = mm_color.rgb * texture_color.rgb * geom.vertex_color.rgb * alpha; vec3 color = mm_color.rgb * texture_color.rgb * SRGBtoLINEAR(geom.vertex_color.rgb) * alpha;
if (model.mode == MATERIAL_MODE_BLEND_GLOW) { if (model.mode == MATERIAL_MODE_BLEND_GLOW) {
// Glow is additive + small overshoot // Glow is additive + small overshoot

View File

@ -298,6 +298,20 @@ rt_draw_instance_t *getDrawInstance(void) {
return g_ray_model_state.frame.instances + (g_ray_model_state.frame.instances_count++); return g_ray_model_state.frame.instances + (g_ray_model_state.frame.instances_count++);
} }
static float sRGBtoLinearScalar(const float sRGB) {
// IEC 61966-2-1:1999
const float linearLow = sRGB / 12.92f;
const float linearHigh = powf((sRGB + 0.055f) / 1.055f, 2.4f);
return sRGB <= 0.04045f ? linearLow : linearHigh;
}
static void sRGBtoLinearVec4(const vec4_t in, vec4_t out) {
out[0] = sRGBtoLinearScalar(in[0]);
out[1] = sRGBtoLinearScalar(in[1]);
out[2] = sRGBtoLinearScalar(in[2]);
out[3] = in[3];
}
void RT_FrameAddModel( struct rt_model_s *model, rt_frame_add_model_t args ) { void RT_FrameAddModel( struct rt_model_s *model, rt_frame_add_model_t args ) {
if (!model || !model->blas) if (!model || !model->blas)
return; return;
@ -329,7 +343,7 @@ void RT_FrameAddModel( struct rt_model_s *model, rt_frame_add_model_t args ) {
draw_instance->blas_addr = model->blas_addr; draw_instance->blas_addr = model->blas_addr;
draw_instance->kusochki_offset = kusochki_offset; draw_instance->kusochki_offset = kusochki_offset;
draw_instance->material_mode = args.material_mode; draw_instance->material_mode = args.material_mode;
Vector4Copy(*args.color, draw_instance->color); sRGBtoLinearVec4(*args.color_srgb, draw_instance->color);
Matrix3x4_Copy(draw_instance->transform_row, args.transform); Matrix3x4_Copy(draw_instance->transform_row, args.transform);
Matrix4x4_Copy(draw_instance->prev_transform_row, args.prev_transform); Matrix4x4_Copy(draw_instance->prev_transform_row, args.prev_transform);
} }

View File

@ -784,7 +784,7 @@ void R_RenderModelDraw(const vk_render_model_t *model, r_model_draw_t args) {
.material_mode = args.material_mode, .material_mode = args.material_mode,
.transform = (const matrix3x4*)args.transform, .transform = (const matrix3x4*)args.transform,
.prev_transform = (const matrix3x4*)args.prev_transform, .prev_transform = (const matrix3x4*)args.prev_transform,
.color = args.color, .color_srgb = args.color,
.dynamic_polylights = model->dynamic_polylights, .dynamic_polylights = model->dynamic_polylights,
.dynamic_polylights_count = model->dynamic_polylights_count, .dynamic_polylights_count = model->dynamic_polylights_count,
.override = { .override = {

View File

@ -58,7 +58,7 @@ qboolean RT_ModelUpdateMaterials(struct rt_model_s *model, const struct vk_rende
typedef struct { typedef struct {
int material_mode; int material_mode;
const matrix3x4 *transform, *prev_transform; const matrix3x4 *transform, *prev_transform;
const vec4_t *color; const vec4_t *color_srgb;
struct rt_light_add_polygon_s *dynamic_polylights; struct rt_light_add_polygon_s *dynamic_polylights;
int dynamic_polylights_count; int dynamic_polylights_count;