Quake3World.com Forums
     Programming Discussion
        Made Q3A's gibs look crazy.

Post new topicReply to topic
Login | Profile | | FAQ | Search | IRC

Print view Previous topic | Next topic 
Topic Starter Topic: Made Q3A's gibs look crazy.

The Afflicted
The Afflicted
Joined: 21 Apr 2005
Posts: 503
PostPosted: 09-19-2017 07:38 PM           Profile Send private message  E-mail  Edit post Reply with quote

Make sure you play it in some higher quality mode so you actually see the blood. Looks way better. The gibs were always my least favorite part of Q3 and Q4.


Cool #9
Cool #9
Joined: 01 Dec 2000
Posts: 41812
PostPosted: 09-19-2017 11:18 PM           Profile   Send private message  E-mail  Edit post Reply with quote

In EntityPlus I changed the marks on walls setting from an on/off boolean into a duration setting so the player can choose to have bullet marks and blood splatters remain visible longer. Add that to this and you can truly paint the walls red.


The Afflicted
The Afflicted
Joined: 21 Apr 2005
Posts: 503
PostPosted: 09-26-2017 03:31 PM           Profile Send private message  E-mail  Edit post Reply with quote

Cool. I'd be pretty cool if I could make better blood splatters, too. They always looked really ugly to me. I might mess with the rocket explosion next and make it way more random, though.

Any idea how to raise the limit of local entities so that they don't disappear when others spawn like that?


Cool #9
Cool #9
Joined: 01 Dec 2000
Posts: 41812
PostPosted: 09-28-2017 12:26 AM           Profile   Send private message  E-mail  Edit post Reply with quote

I think you'll need to edit such limits in the engine code itself and I'm not sure how hardwired everything is.


The Afflicted
The Afflicted
Joined: 21 Apr 2005
Posts: 503
PostPosted: 10-02-2017 03:03 PM           Profile Send private message  E-mail  Edit post Reply with quote

Hmmm. Yeah, I tried using r_maxpolys 1,000,000 and that hasn't done anything. Look at how fucked this railtrail is:


Joined: 19 Sep 2012
Posts: 60
PostPosted: 10-03-2017 02:07 PM           Profile Send private message  E-mail  Edit post Reply with quote

Afaik, r_maxpolys has absolutely nothing to do with your problem, be careful if you edit rendering related things if you dont know exactly what to do!
If I do understand you right, your problem has to do with the maximum number of local entities that can be drawn -> MAX_LOCAL_ENTITIES (in code / cgame / cg_localents.c ).
So the next thing you probably want to try will be to raise the limit to say 1000000 MAX_LOCAL_ENTITIES ;)
Unfortunately the maximum you can have is 786 afaik (WITHOUT RENDERER CHANGES). See here: https://github.com/etlegacy/etlegacy/bl ... ents.c#L41 (this is because Wolfenstein-Enemy Territory has more MAX_LOCAL_ENTITIES than Q3).
Please note in-game you don't really will note any difference between 512 or 768 MAX_LOCAL_ENTITIES, but increasing it from 512 to 786 should be fine!

If you really want more you have to push the limits inside the renderer, but I don't know any idtech3 renderer that pushed this limit (without the exeption of Spearmint, but there it is to enable the splitscreen feature and it was done via increased rendering commands, and drawsurf bit packing or something, iirc).

Alternate method: Try to decouple sprites from models for example. I mean make for example all models local entities (e.g.: 768 pieces of gibs/shells/etc.) and use particles for all the sprites (impact marks/blood trails/smoke etc.), and only spawn both types if they are close enough to really see them (this easily saves hundreds of local entities and particles). Like, if the smoke or spark is 500 meters away, nobody can see it, so don't even spawn/draw it, you know. Just think about firing a chaingun, every single bullet shell is a local entity -> 10 players simultaneous fring 50 chaingun bullets = 500 shells = 500 local entities!). Well, thats technically not 100% correct, but I think you know what I mean.
This alternate method also has it's own drawbacks. Although the particles can be increased easier (iirc the current max is 1024 but 4096 and even more is also possible), they currently don't work as expected, as long as you use Quake3's 1.32 code!
Here at the forums are still guys (experts) that blame ioquake3, but here you can see why ioquake3 is the better choice to use, because in ioquake3 the particle system was fixed: https://github.com/ioquake/ioq3/commit/ ... 34fa7298b8 in plain 1.32 code particles don't work as expected!
BTW, technically particles behave the same, as soon as there are too much, they vanish, and aren't drawn! Second, as far as I understand Return to Castle Wolfenstein added 'trail junks' where a trail of smoke is considered as ONE entity, not as much entities as it consists. This will also reduce the amount of local entities.

These are only some thoughts, and a basic overview, I will not guarantee that everything is correct what I said, but at least it will help you a bit, hopefully!


The Afflicted
The Afflicted
Joined: 21 Apr 2005
Posts: 503
PostPosted: 10-03-2017 08:59 PM           Profile Send private message  E-mail  Edit post Reply with quote

Cool, I upped the max polys TO 768 and this was the result:

I was considering making modifications to the railtrail code so that it deteched smoke puffs that were too close, but I didn't even really change the amount of objects in the rail trail. I just turned cg_oldrail off, then changed the asset used, and replaced the old rail beam with the lightning beam, and set cg_railtrailtime to something like 50ms.

My main goal is to make the Q3 effects look as realistic as possible without actually adding any new assets. I replaced effects from the sg, mg, and plasma too, and they look WAAAY better. The size of plasma projectiles are randomized, so they flicker. MG bullets emit randomized small lights when hitting surfaces, and the duration is about 100ms, instead of whatever ridiculously large number they were before.

I also replaced the default rocket launcher with something much nicer using randomized particle effects, but I won't show it since it's not 100% done. They actually look really, really nice imho. Way better than the default rocket launcher effects, imho, which are nostalgic, but never made any real sense. I actually really want to make like a smoke entity list, so that if you shoot rockets or rails past any smoke, they'll all get pushed away from the oncoming projectile, or explosion. That'd be sweet.

Thanks for the super technical reply. I don't really know about the renderer at all. I've been trying to mess with it for my VR mod (https://www.youtube.com/watch?v=ua75r1zfuzg&t=14s), but I haven't figured out how to get warping right. I don't know anything about image buffers or anything like that. :(

Btw, are you working on an ET project? If you are, and are looking for someone to mess with default effects, let me know. I'm also fully competent in character creation, though my interests have always been in getting a really good IK and animation system set up with Q3A movement speed. I enjoy character art, but am more in love with making art look really really nice using code.

Here's the new railtrail code:

void CG_RailTrail (clientInfo_t *ci, vec3_t start, vec3_t end) {
   vec3_t axis[36], move, move2, next_move, vec, temp;
   float  len;
   int    i, j, skip;

   float groupRand;
   localEntity_t *le;
   refEntity_t   *re;

   float scaleRand;
   float posOffs;
   float posRand;
   float colRand;
   int randomize;
   int randomizeRadius;
   int randomizeDistance;
   int randomizeMaxDist;
   int lastRandDist;
   int shift;
   float lerp;
   float oldScale;
   float oldDist;
   float scale;

#define RADIUS   4
#define ROTATION 1
#define SPACING  5

   oldScale = 0;
   shift = 0;
   start[2] -4;
   VectorCopy (start, move);
   VectorSubtract (end, start, vec);
   len = VectorNormalize (vec);
   PerpendicularVector(temp, vec);

   for (i = 0 ; i < 36; i++) {
      RotatePointAroundVector(axis[i], vec, temp, i * 10);//banshee 2.4 was 10

   le = CG_AllocLocalEntity();
   re = &le->refEntity;

   le->leType = LE_FADE_RGB;
   le->startTime = cg.time;
   le->endTime = cg.time + cg_railTrailTime.value;
   le->lifeRate = 1.0 / (le->endTime - le->startTime);

   re->shaderTime = cg.time / 1000.0f;
   re->reType = RT_RAIL_CORE;
   //re->customShader = cgs.media.railCoreShader;
   re->customShader = cgs.media.lightningShader;

   VectorCopy(start, re->origin);
   VectorCopy(end, re->oldorigin);

   re->shaderRGBA[0] = ci->color1[0] * 255;
    re->shaderRGBA[1] = ci->color1[1] * 255;
    re->shaderRGBA[2] = ci->color1[2] * 255;
    re->shaderRGBA[3] = 255;

   le->color[0] = ci->color1[0] * 0.75;
   le->color[1] = ci->color1[1] * 0.75;
   le->color[2] = ci->color1[2] * 0.75;
   le->color[3] = 1.0f;

   AxisClear( re->axis );

   VectorMA(move, 20, vec, move);
   VectorCopy(move, next_move);
   VectorScale (vec, SPACING, vec);

   if (cg_oldRail.integer != 0) {
      // nudge down a bit so it isn't exactly in center
      re->origin[2] -= 8;
      re->oldorigin[2] -= 8;
   skip = -1;

   lastRandDist = 0;
   randomizeMaxDist = 750;
   randomizeDistance = rand() % randomizeMaxDist;

   j = 18;
   //Com_Printf("%f\n", len);
   //Com_Printf("%i\n", ((((int)len)-(((int)len) % SPACING)) / SPACING));
   //Com_Printf("%i\n\n", (((int)len) % SPACING));
    for (i = 0; i < len; i += SPACING) {
      if (i != skip) {

            lastRandDist = i;
            randomizeDistance = (rand() % randomizeMaxDist) + lastRandDist;

            //randomizeDistance = 0;
            if(randomizeDistance > len){
               randomizeDistance = (int)len;

            shift = rand() % 360;
            //Com_Printf("%i\n", randomizeDistance);

         skip = i + SPACING;
         le = CG_AllocLocalEntity();
            re = &le->refEntity;
            le->leFlags = LEF_PUFF_DONT_SCALE;
         le->leType = LE_MOVE_SCALE_FADE;
            le->startTime = cg.time;
            le->endTime = cg.time + (i>>1) + fabs((crandom() * 2000)) + 2000;
            le->lifeRate = 1.0 / (le->endTime - le->startTime);

         //posOffs = 0;
         //randomize = 0;
         posOffs = 1;
         randomize = 1;
         if(randomize == 1){
            scaleRand = 1;
            posRand = 1;
            colRand = 1;
         } else {
            scaleRand = 0;
            posRand = 0;
            colRand = 0;

         scaleRand = 1;

         //shift = 0;

         scale = 30;
         scale = fabs(( (.1 * sinf(DEG2RAD(i+shift)) * .25) + sinf(DEG2RAD((i/10) + shift)))) * scale;

         oldScale = LerpPositionTemp(oldScale, scale, .75);
         //Com_Printf("%f\n", (oldScale/40)-.5);

            re->shaderTime = cg.time / 1000.0f;
            re->reType = RT_SPRITE;
            re->radius = ( scaleRand * (crandom() * 1.5) * oldScale) + 10;
         re->rotation = rand() % 360;

         re->customShader = cgs.media.shotgunSmokePuffShader;

            //re->shaderRGBA[0] = ci->color2[0] * 255;
            //re->shaderRGBA[1] = ci->color2[1] * 255;
            //re->shaderRGBA[2] = ci->color2[2] * 255;

         le->radius = 100;

         groupRand = crandom();
            re->shaderRGBA[0] = (colRand  * (groupRand * 50)) +155;
            re->shaderRGBA[1] = (colRand  * (groupRand * 50)) +155;
            re->shaderRGBA[2] = (colRand  * (groupRand * 50)) +155;
            re->shaderRGBA[3] = 255;

            //le->color[0] = ci->color2[0] * 0.75;
            //le->color[1] = ci->color2[1] * 0.75;
            //le->color[2] = ci->color2[2] * 0.75;

            le->color[0] = 0.75;
            le->color[1] = 0.75;
            le->color[2] = 0.75;

            //le->color[3] = (colRand * (fabs(crandom() * .5 )-.75)) + 1;
            //le->color[3] = .75;
            le->color[3] = 1;

            le->pos.trType = TR_LINEAR;
            le->pos.trTime = cg.time;

         VectorCopy( move, move2);
            VectorMA(move2, RADIUS * ((oldScale/30) -.5) , axis[j], move2);
            VectorCopy(move2, le->pos.trBase);
            le->pos.trDelta[0] = axis[j][0]* ((oldScale /40) * posOffs * 50) ;
            le->pos.trDelta[1] = axis[j][1]* ((oldScale /40) * posOffs * 50) ;
            le->pos.trDelta[2] = axis[j][2]* ((oldScale /40) * posOffs * 50)  + 10;


        VectorAdd (move, vec, move);

        j = j + ROTATION < 36 ? j + ROTATION : (j + ROTATION) % 36;


The Afflicted
The Afflicted
Joined: 21 Apr 2005
Posts: 503
PostPosted: 10-06-2017 02:06 PM           Profile Send private message  E-mail  Edit post Reply with quote

Made a short video with some Megadeath's 'The Punishment Due' playing in the backround. That song is insane. Wtf. (it's loud as fuck)

Quake3World.com | Forum Index | Programming Discussion

Post new topic Reply to topic

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group