Hey, does anybody know how to prevent that Sprites get drawn trough Walls or Objects.
Here is an Snippet of the Code:
local pos, material, red = obj:GetForward() , Material( "sprites/light_ignorez" ), Color( 150, 0, 0, 255 )
hook.Add( "HUDPaint", "paintsprites", function()
cam.Start3D()
render.SetMaterial( material )
render.DrawSprite( pos+ obj:LocalToWorld(Vector(-91,5,31.5)), 10, 10, red )
cam.End3D()
end )
Any car mods you might see scale the sprites based on their facing and the player's aim direction using a Vector.Dot product.
How exactly does this work with Vector.Dot?
If used on 2 direction vectors ( i.e. length is 1 ), it will return a number depending on how closely the 2 directions match each other.
Basically it returns 1 if 2 vectors face same way, -1 if they are directly opposite, 0 if they are perpendicular to each other (i.e. 90 degree angle)
You want to cut off the negative values and use the rest to scale the sprite.
This is probably a wrong definition, but you can go to wikipedia for that.
taking two vectors, if they go in the same (normalized) direction, the dot product of them should just be 1.
Otherwise, if they're perpendicular to eachother (such as Ent:Forward() compared to Ent:Right() ), the dot product is 0.
And which Vectors should i use for that? The LocalPlayer():EyePos() and the Position of each sprite?
you're close. You'll want the forward direction of the players eyes, as a vector, instead of their position. Then take the sprite's inward direction toward the object's position. (Or, I suppose you could just check the object's :Forward() to keep from having to do dot products for every individual sprite)
you might want to go wiki hopping because I'm still learning glua myself.
I've made something up, but im not entirely sure if this is what you ment.
LocalPlayer():GetAimVector():DotProduct( ( Entity( 1 ):GetForward() - LocalPlayer():EyeAngles():Forward()+ Vector( 70 ) ):GetNormalized() )
And im not sure what i should do with the output?
Isn't the problem that you are drawing drawing it in HUDPaint, and also using an IgnoreZ material?
Ohh ehhm .. which Hook should i use instead?
Also i already tried using an other Material.. but i didnt thought it would fix that problem.
Do i have to make an .vmt file byself to fix that?
You could use either GM/PostDrawOpaqueRenderables or GM/PostDrawTranslucentRenderables, and a material that does not ignore the Z (depth buffer). For that you will need your own vmt, or you can find one that suits you and works good
Thanks it works perfectly now.
Still i got one Problem i don't understand ..
The Look of the Sprites change dramatically between those Hooks.
The HUDPaint Sprites look better than the Sprites from GM/PostDrawOpaqueRenderables and GM/PostDrawTranslucentRenderables.
Here are some Screenshots for Comparison:
https://files.facepunch.com/forum/upload/301280/01d295bb-f728-4e82-ab75-b83da803a02c/Screenshot_9.png
HudPaint
https://files.facepunch.com/forum/upload/301280/50c51233-7482-4e87-8525-268d5af96e33/Screenshot_10.png
PostDrawTranslucentRenderables
https://files.facepunch.com/forum/upload/301280/41d49785-b8fd-47c4-ba9b-ccb898dff87f/Screenshot_11.png
PostDrawOpaqueRenderables
Is there a Way to get the HUDPaint look without rendering through Objects and Walls?
You will need to use PostDrawTranslucentRenderables, forget about HUDPaint. You can't use a 2D rendering hook for 3D stuff (you can, but you should not unless you have a really good reason).
PostDrawOpaque does not work in this case because if you draw the lights in that hook, that means the opaque car parts get drawn, then the lights, and then translucent stuff gets drawn, thats why the glass is drawn after the lights.
This is why all mods use the method I described, making it use non ignoreZ materials will make the sprites clip with the car making them look like crap.
Moving the sprites forward so they don't clip will make it look weird from the side.
Rubat's method is the way to go. Commonly, at least for radial lights, a http://wiki.garrysmod.com/page/util/PixelVisible pixvis handle is used, but in your case you should do the dot product method. The two direction vectors he talked about as noru also suggested would be EyeVector and a reversed Car:GetForward() (* -1 if you want the back side of the car depending on its orientation of course), clamp that value in the [0,1] range and use it to multiply either the alpha and/or size of the sprite
Hmm .. okay, thanks for the Answer.
I set this up now, but i don't think it's what you exactly ment.
size = LocalPlayer():EyePos():DotProduct( ( (obj:GetForward()*(-1)) - LocalPlayer():EyePos()+ Vector( 70 ) ):GetNormalized() )
//Lights
render.DrawSprite( pos+ obj:LocalToWorld(Vector(-92,5,31.5)), size, size, red )
Not EyePos(), use EyeVector(). EyePos() gives you the position vector of the eyes in the world space, EyeVector() gives you the normalized direction vector of the player's look. It should be more like:
dotProduct = eyeVector:Dot(car:GetForward())
dotProduct = math.max(dotProduct, 0)
size = someSIze * dotProduct
alpha = someAlpha * dotProduct
That^ should work, if it doesn't then try reversing car:GetForward() or manipulating the product differently as you wish
Ohh thats actually working pretty well.
It only fades a bit late out when looking away
https://files.facepunch.com/forum/upload/301280/25da2992-d8ff-449b-aa44-ec02a501bea5/Screenshot_14.png
https://files.facepunch.com/forum/upload/301280/db352312-0448-40af-83fb-5d5464383ea7/Screenshot_8.png
https://files.facepunch.com/forum/upload/301280/845a1817-2b09-44fd-91f4-2ff3faa341f3/Screenshot_12.png
But it looks way better than with the Other Hook's, thanks for that.
I now managed to fix the Late Fading Bug, but i noticed that if i angle the Camera up or down the Sprites also fade away.. any Idea how to fix that.
For better Visualisation
https://files.facepunch.com/forum/upload/301280/98119ace-d342-423b-a301-7f89fe8b1d41/Screenshot_19.png
Too Low - fading away
https://files.facepunch.com/forum/upload/301280/3dae6d4d-f157-4e3a-8020-919f3be42e25/Screenshot_18.png
Too High - Increasing the Alpha way too much
Any Idea how fix that Problem? Maybe ignoring the Height while calculating the DotProduct?
If i had to guess it looks like your car:GetForward() is actually pointing more down than forward which is why the dotProduct value gets bigger if you look down too.
If I were you I'd (using debug render.lines) find fixed (and symmetric) positions for each of the red lamps, to give them so 'direction' bias. You can also tweak the result by manipulating your dot product such as raising it to the power of 2 (which will make it drop faster) or by subtracting a value to give it an offset, etc. Your options are really endless
Yeah i already modified the GetFoward for the earlier fading.
Maybe i could ignore the height for the DotProduct Calculation or try to modify it like you recommended.
I will try it out now maybe it will work.
There is a significant lack of example code in this thread. Here is how the sandbox Lamp does it: garrysmod/gmod_lamp.lua at master · Facepunch/garrysmod · GitHub
function ENT:DrawTranslucent()
BaseClass.DrawTranslucent( self )
-- No glow if we're not switched on!
if ( !self:GetOn() ) then return end
local LightNrm = self:GetAngles():Forward()
local ViewNormal = self:GetPos() - EyePos()
local Distance = ViewNormal:Length()
ViewNormal:Normalize()
local ViewDot = ViewNormal:Dot( LightNrm * -1 )
local LightPos = self:GetPos() + LightNrm * 5
if ( ViewDot >= 0 ) then
render.SetMaterial( matLight )
local Visibile = util.PixelVisible( LightPos, 16, self.PixVis )
if ( !Visibile ) then return end
local Size = math.Clamp( Distance * Visibile * ViewDot * 2, 64, 512 )
Distance = math.Clamp( Distance, 32, 800 )
local Alpha = math.Clamp( ( 1000 - Distance ) * Visibile * ViewDot, 0, 100 )
local Col = self:GetColor()
Col.a = Alpha
render.DrawSprite( LightPos, Size, Size, Col, Visibile * ViewDot )
render.DrawSprite( LightPos, Size * 0.4, Size * 0.4, Color( 255, 255, 255, Alpha ), Visibile * ViewDot )
end
end
Notice how instead of using EyeVector, it's using self:GetPos() - EyePos() - this vector better represents the angle at which the player is looking at the lamp.
Yeah, I felt something was off with using EyeVector, this makes a lot more sense
Exactly, and I don't think I would have thought of it myself if I didn't open that existing example. Vanilla gmod has a surprising variety of good code examples!
Too bad There's a lot of bad ones too
That works perfect.
Now the Bug with the Height of the Camera and the endless Increament/Decreasing of Alpha and Size are fixed
Here a little Code Snippet for People that may have the same Problem as i had.
eyecalc = LocalPlayer():GetPos() - EyePos()
eyecalc:Normalize()
dotProduct = eyecalc:Dot(obj:GetForward())
dotProduct = math.max(dotProduct, 0)
size = 10 * dotProduct
alpha = 500 * dotProduct
local pos, material, red, white = obj:GetForward() , Material( "sprites/light_ignorez" ), Color( 200, 0, 0, alpha ), Color( 255, 255, 255, alpha )
cam.Start3D()
render.SetMaterial( material )
render.DrawSprite( pos+ obj:LocalToWorld(Vector(0,0,0)), size, size, red )
render.DrawSprite( pos+ obj:LocalToWorld(Vector(1,1,1)), size, size, white )
Thanks for the Help.
You should put the Material(..) call outside of the function like this: gmod_lamp.lua#L9
Also, are you sure this works? LocalPlayer():GetPos() - EyePos() isn't a useful vector (it should remain constant throughout the game, unless the player is looking through a camera or something else). It should be light_pos - EyePos(), where light_pos is the position where you want to draw the sprite.
So far it works for me with the LocalPlayer():GetPos() .. the only thing thats need to be fixed right now, is
that the Sprites are rendering through Objects.
https://files.facepunch.com/forum/upload/301280/fda5df15-cbc1-49ef-b354-3bdae30deb18/Screenshot_20.png
That's why this part is in the lamp code:
local Visibile = util.PixelVisible( LightPos, 16, self.PixVis )
if ( !Visibile ) then return end
local Size = math.Clamp( Distance * Visibile * ViewDot * 2, 64, 512 )
Thanks that also works very good.
Sorry, you need to Log In to post a reply to this thread.