Legacy:Sobiwan/Developer Journal

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to navigation Jump to search

Laser Glow

Brainstormed an idea to create a fake glow for a big laser in UT.

The idea

  • This particular laser is a vertical tube.
  • The glow should always be drawn on the left, right, top and bottom sides of the laser.

Using particles

  • create a particle system
  • the particles traverse the edge of vertical tube laser
  • the particles can animate positions and color
  • this would look cool
  • it would still need to always face the viewer
  • perhaps position the particle

I noticed shockbeam.uc uses particles.

Foxpaw: If you just make a big sprite, you should be able to get the effect you described with less overhead than the methods described above. Just place an actor, set itt's DrawType to DT_Sprite, and assign an appropriate texture to it's Texture variable. You can set the drawscale3d of it if you need to stretch it as well. I believe (but have not tested) that this would be compatible with all types of materials too, if you wanted to use some texpanners or something to make the glow a bit more dynamic.

Sobiwan: I failed to mention that I already tried that. :) A sprite always displays straight on (as it should), so as soon as I tilted my view, the perspective of the laser tube skewed (as it should) but the fake glow spite did not. I need the glow sheet to skew on Z but not on X and Y. This is only because its a vertical laser. If it were horizontal or angular, I would have to try something else.

Foxpaw: I'm not sure I'm visualizing the same thing. Is this laser the same width from every angle or is it like a flat type of laser? Can you upload an image of what it looks like and what effect you are trying to get?

Sobiwan: I can upload an image. I still havent figured out how to describe this easily even though its a simple thing. Its the typical laser effect in sci-fi films. I dont have an image, but for the moment, here is a top down ASCII art description of what I want to accomplish:

-O-

  • laser core (the white hot center) is a tube (the O)
  • laser core is vertical (it originates from a machine)
  • I'd like to add a glow fringe around the core, viewable from any angle
  • Faking it in UT is tricky because:
    • there is no 'glow fringe' script
    • particles surrounding the tube are implemented through an external uscript that I havent analyzed
    • a single sheet works (the - above), but only from one angle
  • I'd like the sheet to always face the player so the fake glow effect is never lost
  • I want to avoid using 'volumetric' sheets because volumetrics look tacky

Foxpaw: So you want the flat planar "glow" to always face the player? It sounds like a sprite would work but I'll take your word for it that it didn't. :P If you want to get all fancy about it you could make a flat mesh with the glow on it, and have it track the local players rotation. Alternatively, (this would use more processing power), you COULD surround the laser with zone portals and assign the zone some distance fog.

Sobiwan: Sprite didnt work even though it always faces the viewer. As you say, I want the flat mesh (sheet) to always face the player... except that performs perspective skewing. :)

Sobiwan: UnrealScript Vector Maths has a ton of useful nuggets for player view positions, etc that relates here, so I'm sticking it in this journal for future reference.

I also did a little test with Slick Willy's particle system found in Houroces' DM-Axxon. I shot a bunch of particles with the ADSR ball texture straight down really fast. It looked OK, but you could still tell it was a bunch of sprites, even with a white cylindrical nonsolid core in the middle. The stream isnt perfect either; there are some occasioanl gaps, so I guess the uscript is calling a random function. I'll eventually be able to dissect uscript, but at this point I dunno.

One thing I couldnt figure out is why textureloop lighting emitting from the nonsolid worked in Ued2 but not in UT.

Sobiwan: Wait a sec.. you said flat mesh. Silly moi! Of course; that might behave differently than a brush. I'll look into that.

Foxpaw: You should be keep the mesh always facing you by something like SetRotation( Rotator( Location - Player.Location ) ); Player of course would have to point to the local playerpawn, but I don't remember how to go about finding which pawn is the local playerpawn in UT.

Sobiwan: Thanks FoxPaw! I was just learning about rotators at WOD and came to the same conclusion. In it, the author says:

Like vectors, (Rotators are) also structs with three float components: pitch, yaw, and roll. These three values are angles that can describe any rotational direction in 3D space. Pitch is up and down, yaw is side to side, and roll is...

So if I control the Yaw to always be straight on to the viewer and the pivot point on the mesh is set in the center of the laser, it should always face the viewer. Only problem with my approach is it would only work for vertical lasers. It would be nice if it worked for lasers on any vector angle.

Sobiwan: Rather than draw the laser and its glow as a brush or mesh, what if I could define the start and end points of the laser with an actor and let the script draw the core and glow between the start and end points? For that matter, it would be similar to the pulse rifle in alt mode...

Only problem with this approach is actors are slower than 3D BSP or meshes unless someone can tell me otherwise.

Foxpaw: Meshes are actors. In UT2003 there are "staticmeshactors" which are a stripped down version of actor so they don't use as much resources, but in UT meshes are just actors that don't do anything.

Having said that, I don't believe that there is a feasable way to have an actor draw something like that. You can have actors draw onto the screen in PostRender, but it will be drawn over top of any BSP and whatnot that should be in front of it. That's why generally it's only good for things like the HUD which always overlaps the level. The pulse rifle in alt-fire mode is actually a beam-shaped volumetric mesh, which you've already indicated you don't want to use. :P

Have you considered having a cylindrical brush around your laser that has it's faces flagged as transparent? I don't know if that would get the effect you were going for, but maybe it would.

Alternatively, you could stick with the scripted actor idea like I mentioned. It is quite possible to have an actor pivot around only one axis to face you. There's three ways that you could feasably do that. 1 way would be to use Quaternions. Another way would be to set the actor's bRotateToDesired to true, set the actors rotationrate around one axis really high, and then set the desiredrotation to always face the player using the script I mentioned above. This will cause it to rotate around only one axis, but you will need to set that axis in the editor. You can set bDirectional to true on it as well to help you line up the axis. The third way is to use a coordinate rotation to strip off two of the axes, but I can't remember the script for that off the top of my head. My mod uses it to determine the direction that turrets should rotate, so I know it can be done that way. The other two methods should also work quite well. My personal recommendation would be to use #2, because it would be very low-impact on the processor (though all of these are miniscule compared to the amount of processing the graphics does, so you won't notice any drop in framerate either way.

Sobiwan: Didnt know pulse rifle was volumetric, so we'll toss that out. :)

I tried a transparent cylinder for the glow around the core cylinder. I also made it fog. Problem with both of those is the edge of the cylinder is a hard line and I want a soft gradient outward from the core cylinder. No mesh can do that... except for the the mesh sheet you mentioned.

I'll read up on how the items in your previous paragraph works because they are currently beyond my understanding. I do appreciate your sharing knowledge; its giving me a direction to go in.

Sobiwan: Graphics demonstration time:

@[email protected] 2 mesh vertical laser glow

This shows a white 'laser core' cylinder in the center with 2 non-collidable meshes on each side with a glow texture. Problems with this is the top and bottom need to glow too. It would look tacky with objects colluding the top and bottom, let alone residing in open space.

@[email protected] 4 mesh vertical laser glow

The glow on the top and bottom are desirable. Only way I can figure is to add 2 more meshes with glow textures on them.

@[email protected] 2 mesh skewed laser glow

Again, the top and bottom are missing, but note that the mesh sheets skew with the laser cylinder.

@[email protected] 4 mesh skewed laser glow

With the top and bottom added and skewed, it looks great!

@[email protected] 4 mesh skewed laser glow colluded

But wait! As soon as an object is drawn in front of it, the bottom glow is colluded! Arrrg!

@[email protected] 4 mesh skewed laser glow correct

The holy grail: making the meshes drawn in front of colluding objects. Dont tell me this can only be done internally in 3D cards with Transform & Lighting! There must be a way to do this in Unreal!

Foxpaw: So does that mean that you want the glow to be visible as long as the beam is? Kind of like how coronas in UT2003 can be overlapped partially by geometry and still be shown?

Mychaeel: Use Canvas.DrawActor in PostRender.

Foxpaw: I don't think it's quite that simple, I doubt he wants the whole square glow to be shown if you can only see a sliver of the beam. I think you'd probrably have to compute what parts of the beam are visible, then trace out that shape on the canvas.

Sobiwan: Thanks! Yes, it would be similar to corona. I didnt consider what would happen if an object were to partially collude the left or right side, in which case Foxpaw would be right: the overlap glow would have to extend partially past the occluding object's top and bottom edge. Another sheet, methinks.

Foxpaw: Hmm, if I'm thinking what you're thinking, there may be a way to do it ut it would be fairly expensive in terms of processor cycles. You COULD make a scripted raytracing thingy for the beam, but that would involve numerous traces every frame, which might have an impact on framerate.

Sobiwan: I dont want to use a trace for the glow edge if I can help it. The glow is really a 2D effect on the camera lens after the 3D scene has been rendered. Maybe this is what PostRender does? Im still learning it.

Examples of a glow

Found a website that shows images of what I want to accomplish:

http://graphics.stanford.edu/courses/cs348b-competition/cs348b-03/glare/

Notice the glow doesnt clip away; rather its transparency (and color?) fades around an object as the object occludes the glow and light source. This is the effect I want.

If the glow actor was tagged with the name of the geometry object (the laser), the engine could handle occlusion, leaving the glow actor' function to make a larger outline of the object and render the effect from the outline to the object. Only problem with this is how to handle faded glow from objects occluding the light source.

Foxpaw: What if you just used actual coronas? Would that work?

Sobiwan: I dont think it would because a corona is just drawing a sprite; sprites dont skew perspective; it has to be a mesh or an outline rendered after the scene. Incidentally, someone said the Tesla laser in Operation Na Pali does what I want, so I am checking that.

Foxpaw: I just finished playing it actually, I don't believe that's what you're looking for. What I was thinking about the corona is instead of having a single corona, you could put a bunch of lights at small intervals along the laser, each with it's own circular corona. The coronas could then blend together to form a bar-ish shape. Not sure if you could get that to work like you want it to or not.

Sobiwan: You are right; Na Pali does not have the laser I want. It uses the pulse laser rifle method: volumetric brush. :( However, its code could be useful, so I'll keep it around. Stacking coronas is a good idea; its similar to the particle sprayer emitting sprites method I tried earlier... except the coronas wouldn't move.

Sobiwan: I've tracked down the function drawactor in Canvas (UT), but postrender is not a subclass of canvas, so I dont understand how that is supposed to work. I've scoured through the WIKI, all the script subsites at planetunreal, the forums... I just dont get it. Please help.

Wormbo: PostRender() is a function in several classes, e.g. HUD. That function's parameter is a Canvas object you can use to draw stuff on the screen.

Sobiwan: I see that PostRender() is in Console, Weapon, Pawn, HUD, and Mutator, but I dont think thats where this effect belongs. Its an actor, but there is no PostRender function in Actor; I can only guess its not in any actor subclasses either. This must be so easy that I dont understand. :(

BTW, thanks for defining the params on Drawactor. ClearZ sounds like it will override occlusion nicely.

Sobiwan: Knowing that both the glow and laser core must be non solids, I have to make it one object if they are to touch edges. So how can I make the glow width to be independently user configurable, but the laser core to automatically determine its length when it hits a solid or semi-solid?

Foxpaw: Unfortunately, you can't scale meshes non-uniformly in UT, so if you make the beam longer dynamically like that, it will get proportionally wider too. Also, if one or both is going to be an actor, the non-solid thing doesn't apply. Actors don't use CSG geometry so the concept of solid/non-solid/semi-solid does not apply to them.

Sobiwan: Krikes, I shoulda known meshes dont have the same CSG rules applied.

Variable Type: Object

I've been dissecting laserbeam.uc from Operation Na Pali as it is similar to what I want and I hit a brick wall. even after conferring with WIKI. The class flow for this is: Actor -> Projectile -> TeslaBolt -> LaserBeam.

<uscript> var PlasmaCap BackWallEffect; //defined in laserbeam var PlasmaCap WallEffect; //defined in Teslabeam </uscript>

If I'm reading this right, BackWallEffect and WallEffect are object variables of PlasmaCap, but I dont see where PlasmaCap is defined. Can anyone help clarify? I can post all the code if necessary.

Shockbeam may be The Answer

Upon looking at Shockbeam, I found it is a mesh that appears to use a texture on vertex as a particle. It looks good, it has a glow edge, it can even animate. Only problem is objects in front occlude it, preventing the glow to spill in front (per the image). Arrgg!