rtx: use a common definition for Kusok; pass color

Also pass alpha (not used yet)
This commit is contained in:
Ivan 'provod' Avdeev 2021-09-04 12:36:30 -07:00 committed by Ivan Avdeev
parent 22e76513a4
commit c90187f57f
12 changed files with 94 additions and 62 deletions

View File

@ -1,11 +1,12 @@
## 2021-09-01, E132
- [x] rtx: ingest brdfs from ray tracing gems 2
- [x] rtx: directly select a triangle for light sampling
## 2021-09-04, E133
- [x] rtx: different sbts for opaque and alpha mask
- [x] include common headers with struct definitions from both shaders and c code
# Next
- [ ] rtx: pass alpha for transparency
- [ ] rtx: remove additive/refractive flags in favor or probability of ray continuing further instead of bouncing off
- [ ] rtx: experiment with refraction index and "refraction roughness"
- [ ] rtx: configuration that includes texture name -> pbr params mapping, etc. Global, per-map, ...
- [ ] rtx: better light culling: normal, bsp visibility, light volumes and intensity, sort by intensity, etc
- [ ] make a list of all possible materials, categorize them and figure out what to do
- orig:
@ -153,8 +154,8 @@
- [ ] studio models survive NewMap; need to compactify buffers after removing all brushes
- [ ] sometimes it gets very slow (1fps) when ran under lldb (only on stream?)
- [ ] optimize perf: cmdbuf managements and semaphores, upload to gpu, ...
- [ ] rtx: studio models should not pre-transform vertices with modelView matrix
- [ ] include common headers with struct definitions from both shaders and c code
- [ ] ? rtx: studio models should not pre-transform vertices with modelView matrix
- [ ] rtx: non-realtime unbiased mode: make "ground truth" screenshots that take 1e5 samples per pixels and seconds to produce. what for: semi-interactive material tuning, comparison w/ denoise, etc.
# Someday
- [ ] rtx: dynamic rtx/non-rtx switching breaks dynamic models
@ -411,3 +412,6 @@
## 2021-08-26, E131
- [x] rtx: material flags for kusochki
## 2021-09-01, E132
- [x] rtx: ingest brdfs from ray tracing gems 2
- [x] rtx: directly select a triangle for light sampling

View File

@ -2,8 +2,8 @@
#extension GL_EXT_nonuniform_qualifier : enable
#extension GL_GOOGLE_include_directive : require
#include "ray_common.glsl"
#include "ray_kusochki.glsl"
#include "ray_common.glsl"
layout (constant_id = 6) const uint MAX_TEXTURES = 4096;
layout (set = 0, binding = 6) uniform sampler2D textures[MAX_TEXTURES];
@ -50,6 +50,7 @@ void main() {
//ray_result.color = vec3(.5);
// FIXME compute hit pos based on barycentric coords (better precision)
vec3 hit_pos = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT;
payload.t_offset += gl_HitTEXT;
@ -73,9 +74,9 @@ void main() {
// TODO use already inverse gl_WorldToObject ?
const mat3 matWorld = mat3(gl_ObjectToWorldEXT);
const vec3 normal = normalize(transpose(inverse(matWorld)) * (n1 * (1. - bary.x - bary.y) + n2 * bary.x + n3 * bary.y));
hit_pos += normal * normal_offset_fudge;
// //C = normal * .5 + .5; break;
// FIXME there's a better way to do this
hit_pos += normal * normal_offset_fudge;
const vec2 uvs[3] = {
vertices[vi1].gl_tc,
@ -94,8 +95,11 @@ void main() {
const vec4 uv_lods = UVDerivsFromRayCone(gl_WorldRayDirectionEXT, normal, ray_cone_width, uvs, pos, matWorld);
const vec3 base_color = pow(textureGrad(textures[nonuniformEXT(tex_index)], texture_uv, uv_lods.xy, uv_lods.zw).rgb, vec3(2.));
// FIXME read alpha from texture
payload.hit_pos_t = vec4(hit_pos, gl_HitTEXT);
payload.albedo = base_color;
payload.base_color = base_color * kusochki[kusok_index].color.rgb;
payload.alpha = kusochki[kusok_index].color.a;
payload.normal = normal;
payload.emissive = kusochki[kusok_index].emissive * base_color; // TODO emissive should have a special texture
payload.roughness = kusochki[kusok_index].roughness;

View File

@ -140,7 +140,7 @@ vec3 sampleSurfaceTriangle(vec3 view_dir, MaterialProperties material, mat4x3 em
light_dist *= meters_per_unit;
// TODO sample emissive texture
return payload.albedo * evalCombinedBRDF(payload.normal, light_dir, view_dir, material) / (light_dist * light_dist);
return payload.base_color * evalCombinedBRDF(payload.normal, light_dir, view_dir, material) / (light_dist * light_dist);
}
vec3 computeLighting(vec3 view_dir, MaterialProperties material) {
@ -222,7 +222,7 @@ vec3 computeLighting(vec3 view_dir, MaterialProperties material) {
const float r2 = light_pos_r.w * light_pos_r.w;
// TODO this is a bad approximation
const float attenuation = dlight_attenuation_const / (d2 + r2 * .5);
C += payload.albedo * light_color * dot_ld_norm * attenuation;
C += payload.base_color * light_color * dot_ld_norm * attenuation;
} // for all lights
}
@ -260,12 +260,12 @@ void main() {
// Sky/envmap
if (payload.hit_pos_t.w <= 0.) {
C += throughput * payload.albedo;
C += throughput * payload.base_color;
break;
}
MaterialProperties material;
material.baseColor = payload.albedo;
material.baseColor = payload.base_color;
material.metalness = 0.f;
material.emissive = payload.emissive;
material.roughness = .1f; // FIXME payload.roughness;

View File

@ -6,8 +6,9 @@ layout(location = 0) rayPayloadInEXT RayPayload payload;
void main() {
payload.hit_pos_t = vec4(-1.);
payload.roughness = 0.;
payload.normal = vec3(0., 1., 0.);
payload.albedo = vec3(1., 0., 1.);
payload.alpha = 0.;
payload.roughness = 0.;
payload.base_color = vec3(1., 0., 1.);
payload.kusok_index = -1;
}
}

View File

@ -2,8 +2,9 @@
struct RayPayload {
float t_offset, pixel_cone_spread_angle;
vec4 hit_pos_t;
vec3 albedo;
vec3 normal;
vec3 base_color;
float alpha;
vec3 emissive;
float roughness;
int kusok_index;

View File

@ -1,6 +1,41 @@
// Common definitions for both shaders and native code
#ifndef GLSL
#define uint uint32_t
#define vec3 vec3_t
#define vec4 vec4_t
#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define PAD(x) float TOKENPASTE2(pad_, __LINE__)[x];
#else
#define PAD(x)
#endif
struct Kusok {
uint index_offset;
uint vertex_offset;
uint triangles;
// Material
uint texture;
float roughness;
uint material_flags;
PAD(2)
vec3 emissive;
PAD(1)
vec4 color;
};
#define kXVkMaterialFlagLighting (1<<0)
#define kXVkMaterialFlagAdditive (1<<1)
#define kXVkMaterialFlagRefractive (1<<2)
#define kXVkMaterialFlagAlphaTest (1<<3)
#ifndef GLSL
#undef uint
#undef vec3
#undef vec4
#undef TOKENPASTE
#undef TOKENPASTE2
#undef PAD
#endif

View File

@ -1,20 +1,9 @@
#extension GL_EXT_shader_16bit_storage : require
//#extension GL_EXT_shader_8bit_storage : require
#define GLSL
#include "ray_interop.h"
// TODO move to ray_interop
struct Kusok {
uint index_offset;
uint vertex_offset;
uint triangles;
// Material
uint texture;
float roughness;
uint material_flags;
vec3 emissive;
};
#undef GLSL
struct Vertex {
vec3 pos;

View File

@ -25,21 +25,7 @@ typedef struct vk_ray_model_s {
} debug;
} vk_ray_model_t;
typedef struct {
uint32_t index_offset;
uint32_t vertex_offset;
uint32_t triangles;
// Material parameters
uint32_t texture;
float roughness;
uint32_t material_flags;
float _padding_0[2];
vec3_t emissive;
float _padding_1[1];
} vk_kusok_data_t;
typedef struct Kusok vk_kusok_data_t;
typedef struct {
uint32_t num_kusochki;
@ -55,7 +41,7 @@ typedef struct {
matrix3x4 transform_row;
vk_ray_model_t *model;
int render_mode;
qboolean alphamask;
qboolean alpha_test;
} vk_ray_draw_model_t;
typedef struct {

View File

@ -283,10 +283,11 @@ void VK_RayModelDestroy( struct vk_ray_model_s *model ) {
}
}
void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render_model, const matrix3x4 *transform_row ) {
void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render_model, const matrix3x4 *transform_row, const vec4_t color) {
uint32_t material_flags = 0;
qboolean reflective = false;
qboolean force_emissive = false;
qboolean additive = false;
vk_ray_draw_model_t* draw_model = g_ray_model_state.frame.models + g_ray_model_state.frame.num_models;
ASSERT(vk_core.rtx);
@ -302,7 +303,7 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
{
ASSERT(model->as != VK_NULL_HANDLE);
draw_model->alphamask = false;
draw_model->alpha_test = false;
draw_model->model = model;
draw_model->render_mode = render_model->render_mode;
memcpy(draw_model->transform_row, *transform_row, sizeof(draw_model->transform_row));
@ -317,23 +318,23 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
// C = (1 - alpha) * DST + alpha * SRC (TODO is this right?)
case kRenderTransColor:
case kRenderTransTexture:
material_flags = kXVkMaterialFlagLighting | kXVkMaterialFlagRefractive;
material_flags = kXVkMaterialFlagLighting;// | kXVkMaterialFlagRefractive;
reflective = true;
draw_model->alphamask = true;
draw_model->alpha_test = true;
break;
// Additive blending: C = SRC * alpha + DST
case kRenderGlow:
case kRenderTransAdd:
material_flags = kXVkMaterialFlagAdditive;
additive = true;
force_emissive = true;
draw_model->alphamask = true;
draw_model->alpha_test = true;
break;
// Alpha test (TODO additive? mixing?)
case kRenderTransAlpha:
material_flags = kXVkMaterialFlagLighting | kXVkMaterialFlagAlphaTest;
draw_model->alphamask = true;
material_flags = kXVkMaterialFlagLighting;
draw_model->alpha_test = true;
break;
default:
@ -348,9 +349,19 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
kusok->material_flags = material_flags;
// HACK until there is proper specular
// FIXME also this erases previour roughness conditionally
// FIXME also this erases previour roughness unconditionally
if (reflective)
kusok->roughness = 0.f;
else
kusok->roughness = 1.f;
Vector4Copy(color, kusok->color);
if (additive) {
// Alpha zero means fully transparent -- no reflections, full refraction
// Together with force_emissive, this results in just adding emissive color
kusok->color[3] = 0.f;
}
if (esurf) {
VectorCopy(esurf->emissive, kusok->emissive);

View File

@ -517,7 +517,8 @@ static void drawCmdPushDraw( const render_draw_t *draw )
// Figure out whether we need to update UBO data, and upload new data if we do
// TODO generally it's not safe to do memcmp for structures comparison
if (g_render_state.current_ubo_offset == UINT32_MAX || ((g_render_state.uniform_data_set_mask & UNIFORM_UPLOADED) == 0) || memcmp(&g_render_state.current_uniform_data, &g_render_state.dirty_uniform_data, sizeof(g_render_state.current_uniform_data)) != 0) {
if (g_render_state.current_ubo_offset == UINT32_MAX || ((g_render_state.uniform_data_set_mask & UNIFORM_UPLOADED) == 0)
|| memcmp(&g_render_state.current_uniform_data, &g_render_state.dirty_uniform_data, sizeof(g_render_state.current_uniform_data)) != 0) {
uniform_data_t *ubo;
g_render_state.current_ubo_offset = allocUniform( sizeof(uniform_data_t), 16 );
if (g_render_state.current_ubo_offset == UINT32_MAX) {
@ -773,7 +774,7 @@ void VK_RenderModelDraw( vk_render_model_t* model ) {
int vertex_offset = 0;
if (g_render_state.current_frame_is_ray_traced) {
VK_RayFrameAddModel(model->ray_model, model, (const matrix3x4*)g_render_state.model);
VK_RayFrameAddModel(model->ray_model, model, (const matrix3x4*)g_render_state.model, g_render_state.dirty_uniform_data.color);
return;
}

View File

@ -471,7 +471,7 @@ static void prepareTlas( VkCommandBuffer cmdbuf ) {
inst[i] = (VkAccelerationStructureInstanceKHR){
.instanceCustomIndex = model->model->kusochki_offset,
.mask = 0xff,
.instanceShaderBindingTableRecordOffset = model->alphamask ? 1 : 0,
.instanceShaderBindingTableRecordOffset = model->alpha_test ? 1 : 0,
.flags = model->render_mode == kRenderNormal ? VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR : VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR, // TODO is render_mode a good indicator of transparency in general case?
.accelerationStructureReference = getASAddress(model->model->as), // TODO cache this addr
};

View File

@ -17,7 +17,7 @@ void VK_RayModelDestroy( struct vk_ray_model_s *model );
void VK_RayFrameBegin( void );
// TODO how to improve this render vs ray model storage/interaction?
void VK_RayFrameAddModel( struct vk_ray_model_s *model, const struct vk_render_model_s *render_model, const matrix3x4 *transform_row );
void VK_RayFrameAddModel( struct vk_ray_model_s *model, const struct vk_render_model_s *render_model, const matrix3x4 *transform_row, const vec4_t color );
typedef struct {
VkBuffer buffer;