Skip to content

Commit 9b82dae

Browse files
authored
Proper Ambient Light (scp-fs2open#6849)
* Remove ambient handling from amin / decal pass * Add ambient light to deferred pass * Make decals work and fix double insignia rendering * Fix decal vertex shader * render insignias as decals * Cleanup of old insignia stuff * Move insignia post-processing to model load * perform envmap lighting in deferred shader * Remove Envmapping from main shader * Fix MSVC warning * exclude def_files from clang tidy
1 parent 86622e1 commit 9b82dae

31 files changed

Lines changed: 399 additions & 481 deletions

ci/linux/clang_tidy.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@ git diff -U0 --no-color "$BASE_COMMIT..$2" | \
2626
-extra-arg="-DWITH_VULKAN" \
2727
-extra-arg="-DVULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1" \
2828
-extra-arg="-DVK_NO_PROTOTYPES" \
29-
-regex '(code(?!((\/graphics\/shaders\/compiled)|(\/globalincs\/windebug)))|freespace2|qtfred|test\/src|build|tools)\/.*\.(cpp|h)' \
29+
-regex '(code(?!((\/graphics\/shaders\/compiled)|(\/globalincs\/windebug)|(\/def_files\/data)))|freespace2|qtfred|test\/src|build|tools)\/.*\.(cpp|h)' \
3030
-clang-tidy-binary /usr/bin/clang-tidy-16 -j$(nproc) -export-fixes "$(pwd)/clang-fixes.yaml"

code/decals/decals.cpp

Lines changed: 91 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -181,66 +181,52 @@ void parse_decals_table(const char* filename) {
181181
}
182182
}
183183

184-
struct Decal {
185-
int definition_handle = -1;
186-
object_h object;
187-
int orig_obj_type = OBJ_NONE;
188-
int submodel = -1;
189-
190-
float creation_time = -1.0f; //!< The mission time at which this decal was created
191-
float lifetime = -1.0f; //!< The time this decal is active. When negative it never expires
192-
193-
vec3d position = vmd_zero_vector;
194-
vec3d scale;
195-
matrix orientation = vmd_identity_matrix;
184+
Decal::Decal() {
185+
vm_vec_make(&scale, 1.f, 1.f, 1.f);
186+
}
196187

197-
Decal() {
198-
vm_vec_make(&scale, 1.f, 1.f, 1.f);
188+
bool Decal::isValid() const {
189+
if (!object.isValid()) {
190+
return false;
191+
}
192+
if (object.objp()->flags[Object::Object_Flags::Should_be_dead]) {
193+
return false;
199194
}
200195

201-
bool isValid() const {
202-
if (!object.isValid()) {
203-
return false;
204-
}
205-
if (object.objp()->flags[Object::Object_Flags::Should_be_dead]) {
206-
return false;
207-
}
196+
if (orig_obj_type != object.objp()->type) {
197+
mprintf(("Decal object type for object %d has changed from %s to %s. Please let m!m know about this\n",
198+
object.objnum, Object_type_names[orig_obj_type], Object_type_names[object.objp()->type]));
199+
return false;
200+
}
208201

209-
if (orig_obj_type != object.objp()->type) {
210-
mprintf(("Decal object type for object %d has changed from %s to %s. Please let m!m know about this\n",
211-
object.objnum, Object_type_names[orig_obj_type], Object_type_names[object.objp()->type]));
202+
if (lifetime > 0.0f) {
203+
if (f2fl(Missiontime) >= creation_time + lifetime) {
204+
// Decal has expired
212205
return false;
213206
}
207+
}
214208

215-
if (lifetime > 0.0f) {
216-
if (f2fl(Missiontime) >= creation_time + lifetime) {
217-
// Decal has expired
218-
return false;
219-
}
220-
}
221-
222-
auto objp = object.objp();
223-
if (objp->type == OBJ_SHIP) {
224-
auto shipp = &Ships[objp->instance];
225-
auto model_instance = model_get_instance(shipp->model_instance_num);
209+
auto objp = object.objp();
210+
if (objp->type == OBJ_SHIP) {
211+
auto shipp = &Ships[objp->instance];
212+
auto model_instance = model_get_instance(shipp->model_instance_num);
226213

227-
Assertion(submodel >= 0 && submodel < object_get_model(objp)->n_models,
228-
"Invalid submodel number detected!");
229-
auto smi = &model_instance->submodel[submodel];
214+
Assertion(submodel >= 0 && submodel < object_get_model(objp)->n_models,
215+
"Invalid submodel number detected!");
216+
auto smi = &model_instance->submodel[submodel];
230217

231-
if (smi->blown_off) {
232-
return false;
233-
}
234-
} else {
235-
Assertion(false, "Only ships are currently supported for decals!");
218+
if (smi->blown_off) {
236219
return false;
237220
}
238-
239-
return true;
221+
} else {
222+
Assertion(false, "Only ships are currently supported for decals!");
223+
return false;
240224
}
241-
};
242225

243-
SCP_vector<Decal> active_decals;
226+
return true;
227+
}
228+
229+
SCP_vector<Decal> active_decals, active_single_frame_decals;
244230

245231
bool required_string_if_new(const char* token, bool new_entry) {
246232
if (!new_entry) {
@@ -374,7 +360,7 @@ void initializeMission() {
374360
const float DECAL_ANGLE_CUTOFF = fl_radians(45.f);
375361
const float DECAL_ANGLE_FADE_START = fl_radians(30.f);
376362

377-
static matrix4 getDecalTransform(Decal& decal, float alpha) {
363+
static matrix4 getDecalTransform(const Decal& decal, float alpha) {
378364
Assertion(decal.object.objp()->type == OBJ_SHIP, "Only ships are currently supported for decals!");
379365

380366
auto objp = decal.object.objp();
@@ -418,6 +404,51 @@ static matrix4 getDecalTransform(Decal& decal, float alpha) {
418404
return mat4;
419405
}
420406

407+
inline static void renderDecal(graphics::decal_draw_list& draw_list, const Decal& decal) {
408+
auto mission_time = f2fl(Missiontime);
409+
410+
int diffuse_bm = -1;
411+
int glow_bm = -1;
412+
int normal_bm = -1;
413+
414+
auto decal_time = mission_time - decal.creation_time;
415+
auto progress = decal_time / decal.lifetime;
416+
417+
float alpha = 1.0f;
418+
if (progress > 0.8) {
419+
// Fade the decal out for the last 20% of its lifetime
420+
alpha = 1.0f - smoothstep(0.8f, 1.0f, progress);
421+
}
422+
423+
if (std::holds_alternative<int>(decal.definition_handle)) {
424+
int definition_handle = std::get<int>(decal.definition_handle);
425+
Assertion(definition_handle >= 0 && definition_handle < (int) DecalDefinitions.size(),
426+
"Invalid decal handle detected!");
427+
auto &decalDef = DecalDefinitions[definition_handle];
428+
429+
if (decalDef.getDiffuseBitmap() >= 0) {
430+
diffuse_bm = decalDef.getDiffuseBitmap()
431+
+
432+
bm_get_anim_frame(decalDef.getDiffuseBitmap(), decal_time, 0.0f, decalDef.isDiffuseLooping());
433+
}
434+
435+
if (decalDef.getGlowBitmap() >= 0) {
436+
glow_bm = decalDef.getGlowBitmap()
437+
+ bm_get_anim_frame(decalDef.getGlowBitmap(), decal_time, 0.0f, decalDef.isGlowLooping());
438+
}
439+
440+
if (decalDef.getNormalBitmap() >= 0) {
441+
normal_bm = decalDef.getNormalBitmap()
442+
+ bm_get_anim_frame(decalDef.getNormalBitmap(), decal_time, 0.0f, decalDef.isNormalLooping());
443+
}
444+
}
445+
else {
446+
std::tie(diffuse_bm, glow_bm, normal_bm) = std::get<std::tuple<int, int, int>>(decal.definition_handle);
447+
}
448+
449+
draw_list.add_decal(diffuse_bm, glow_bm, normal_bm, decal_time, getDecalTransform(decal, alpha));
450+
}
451+
421452
void renderAll() {
422453
if (!Decal_system_active || !Decal_option_active || !gr_is_capable(gr_capability::CAPABILITY_INSTANCED_RENDERING)) {
423454
return;
@@ -442,51 +473,21 @@ void renderAll() {
442473
++iter;
443474
}
444475

445-
if (active_decals.empty()) {
476+
if (active_decals.empty() && active_single_frame_decals.empty()) {
446477
return;
447478
}
448479

449-
auto mission_time = f2fl(Missiontime);
450-
451-
graphics::decal_draw_list draw_list;
452-
for (auto& decal : active_decals) {
453-
454-
Assertion(decal.definition_handle >= 0 && decal.definition_handle < (int)DecalDefinitions.size(),
455-
"Invalid decal handle detected!");
456-
auto& decalDef = DecalDefinitions[decal.definition_handle];
457480

458-
int diffuse_bm = -1;
459-
int glow_bm = -1;
460-
int normal_bm = -1;
461481

462-
auto decal_time = mission_time - decal.creation_time;
463-
auto progress = decal_time / decal.lifetime;
464-
465-
float alpha = 1.0f;
466-
if (progress > 0.8) {
467-
// Fade the decal out for the last 20% of its lifetime
468-
alpha = 1.0f - smoothstep(0.8f, 1.0f, progress);
469-
}
470-
471-
if (decalDef.getDiffuseBitmap() >= 0) {
472-
diffuse_bm = decalDef.getDiffuseBitmap()
473-
+ bm_get_anim_frame(decalDef.getDiffuseBitmap(), decal_time, 0.0f, decalDef.isDiffuseLooping());
474-
}
475-
476-
if (decalDef.getGlowBitmap() >= 0) {
477-
glow_bm = decalDef.getGlowBitmap()
478-
+ bm_get_anim_frame(decalDef.getGlowBitmap(), decal_time, 0.0f, decalDef.isGlowLooping());
479-
}
480-
481-
if (decalDef.getNormalBitmap() >= 0) {
482-
normal_bm = decalDef.getNormalBitmap()
483-
+ bm_get_anim_frame(decalDef.getNormalBitmap(), decal_time, 0.0f, decalDef.isNormalLooping());
484-
}
485-
486-
draw_list.add_decal(diffuse_bm, glow_bm, normal_bm, decal_time, getDecalTransform(decal, alpha));
487-
}
482+
graphics::decal_draw_list draw_list;
483+
for (auto& decal : active_decals)
484+
renderDecal(draw_list, decal);
485+
for (auto& decal : active_single_frame_decals)
486+
renderDecal(draw_list, decal);
488487

489488
draw_list.render();
489+
490+
active_single_frame_decals.clear();
490491
}
491492

492493
void addDecal(creation_info& info, const object* host, int submodel, const vec3d& local_pos, const matrix& local_orient) {
@@ -531,4 +532,8 @@ void addDecal(creation_info& info, const object* host, int submodel, const vec3d
531532
active_decals.push_back(newDecal);
532533
}
533534

535+
void addSingleFrameDecal(Decal&& info) {
536+
active_single_frame_decals.push_back(info);
537+
}
538+
534539
}

code/decals/decals.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,25 @@ class DecalDefinition {
5050
bool isNormalLooping() const;
5151
};
5252

53+
struct Decal {
54+
//DecalDefinition idx vs immediate diffuse/glow/normal
55+
std::variant<int, std::tuple<int, int, int>> definition_handle = -1;
56+
object_h object;
57+
int orig_obj_type = OBJ_NONE;
58+
int submodel = -1;
59+
60+
float creation_time = -1.0f; //!< The mission time at which this decal was created
61+
float lifetime = -1.0f; //!< The time this decal is active. When negative it never expires
62+
63+
vec3d position = vmd_zero_vector;
64+
vec3d scale;
65+
matrix orientation = vmd_identity_matrix;
66+
67+
Decal();
68+
69+
bool isValid() const;
70+
};
71+
5372
extern SCP_vector<DecalDefinition> DecalDefinitions;
5473
extern bool Decal_system_active;
5574
extern bool Decal_option_active;
@@ -139,4 +158,6 @@ void addDecal(creation_info& info,
139158
const vec3d& local_pos,
140159
const matrix& local_orient);
141160

161+
void addSingleFrameDecal(Decal&& info);
162+
142163
}

code/def_files/data/effects/decal-f.sdr

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@ layout (std140) uniform decalGlobalData {
2929
mat4 invViewMatrix;
3030
mat4 invProjMatrix;
3131

32-
vec3 ambientLight;
33-
float pad0;
34-
3532
vec2 viewportSize;
3633
};
3734

@@ -135,16 +132,6 @@ void main() {
135132
// Additive blending
136133
diffuse_out = vec4(color.rgb * alpha, 1.0);
137134
}
138-
139-
// The main model shader applies ambient lighting by drawing the ambient part of the texture into the emissive
140-
// texture. We do the same here to make sure the decal material is applied correctly
141-
if (glow_blend_mode == 0) {
142-
// Normal alpha blending
143-
emissive_out = vec4(color.rgb * ambientLight, color.a * alpha);
144-
} else {
145-
// Additive blending
146-
emissive_out = vec4(alpha * color.rgb * ambientLight, 1.0);
147-
}
148135
}
149136

150137
if (glow_index >= 0) {

code/def_files/data/effects/decal-v.sdr

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ layout (std140) uniform decalGlobalData {
1414
mat4 invViewMatrix;
1515
mat4 invProjMatrix;
1616

17-
vec3 ambientLight;
18-
float pad0;
19-
2017
vec2 viewportSize;
2118
};
2219

@@ -40,6 +37,6 @@ void main() {
4037
modelMatrix[2][3] = 0.0;
4138

4239
invModelMatrix = inverse(modelMatrix);
43-
decalDirection = mat3(viewMatrix) * vec3(modelMatrix[0][2], modelMatrix[1][2], modelMatrix[2][2]);
40+
decalDirection = mat3(viewMatrix) * modelMatrix[2].xyz;
4441
gl_Position = projMatrix * viewMatrix * modelMatrix * vertPosition;
4542
}

code/def_files/data/effects/deferred-clear-f.sdr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ out vec4 fragOut5;
77
void main()
88
{
99
fragOut0 = vec4(0.0, 0.0, 0.0, 1.0); // color
10-
fragOut1 = vec4(0.0, 0.0, -1000000.0, 1.0); // position
10+
fragOut1 = vec4(0.0, 0.0, -1000000.0, 0.0); // position
1111
fragOut2 = vec4(0.0, 0.0, 0.0, 1.0); // normal
1212
fragOut3 = vec4(0.0, 0.0, 0.0, 0.0); // specular
1313
fragOut4 = vec4(0.0, 0.0, 0.0, 1.0); // emissive

0 commit comments

Comments
 (0)