#Realtime spot lighting on custom shader
1 messages · Page 1 of 1 (latest)
just give me a second^^
and you mentioned your on the built in pipeline?
Unity Built in Shaders. Contribute to TwoTailsGames/Unity-Built-in-Shaders development by creating an account on GitHub.
this one
yes and im doing it for mobile
awesome, makes things easier. Hate dealing with the other pipelines
and thankfully the shader there is a fragment shader
how much shader experience do you have?
because I won't be able to give a step by step tutorial, but I can give a general overview of what you need to do
to be honest I lack in depth knowledge on it , but I just know some basics like surface shader vertex shaders , how expensive they are etc
that will suffice
well anyhow yes by default as you've recongized, in the built in pipeline when it comes to realtime lights, they only show up in the ForwardBase/Add pass
and in the ForwardBase pass only has a directional light, and in the add pass, its your point/spot lights
if I remember correctly anyway
now it is possible to use both baked lighting + realtime lighting (as a matter of fact that is pretty much how 95% of games have been handling their lighting)
now I have to ask though
yeah , i know it
do you want shadow support?
not Im not gonna use shadow caster pass
so the light won't be casting shadows? well that makes things alot easier
yeah
only the light will be enough
well as I said previously, if its only a single light that is always on you can actually just pass in the values manually to the shaders
pass in fields like SpotAngle, light position, intensity, color, etc.
and then calculate lighting by hand in the fragment shader all in that singular pass
what kind of light is it though? a spot light or a point light?
spot light , once my younger brother tried to have a custom round mask with the so called spot light position , cone and direction , but that failed, like when the torch come closer to the object , the round white mask gets bigger
and when far from the object it gets smaller, which is actually opposite in real life
just sounds like the way he was calculating lighting was wrong
Im sorry , actually my younger brother was studying a lot with shader since we needed this system, today he is out from home. I will soon provide him the guidelines you've given me here . He will work on it . Im sorry but if he wants a bit more to know regarding this, will you respond here if you are free that time?
yeah , he was just using a mask texture
that looks like torch light
eh I will try, but I'll give you the general rundown
and controlling it over the object according the torchlight's position
sure , any thing will be informative for us
it's per pixel, (i know here it gets more complex)
nah that doesn't make it that much more complicated
i see , as far i know vertex shader offers 4 extra lights along with directional lights, so i thought it's easy to achieve but vertex lights actually so creepy and glitchy on the mesh
though it's less cpu intensive
but i actually need pixel lights
- create some variables in the shader so that you can pass in properties of the pointlight (position, range, intensity, color), these will have to be set by a script so that it aligns with the actual light source in the scene
- in the vertex function you will need to calculate a world position vector so you can compute where the light actually is, and do attenuation/distance
- in the fragment shader, which is per pixel, is where you do your shading. Using the world position calculated in the vertex shader, you compute the position of the light, then from there calculate the distance/attenuation/direction, and once you have direction you can do an ndotl (normal dot light direction) multiplied by light color/intensity/attenuation
for #2 I have a resource that might help
in the fragment function, the "world position" will be vector_worldPosition
just follow the logic in how its calculated and you can use the code there
the code here is in glsl and not in unity but the language and steps are similar to what you would need to do to properly compute point lighting
amazing !! we'll try this in the project and inform you the result soon. I've at least found the hope on my night scene
Thanks a lot for the in depth descriptions, Cant thank you enough just in words sir.
tomorrow, me and my brother will deeply try on your given methods , I hope this time we'll get it.
@vocal gate alright now when i am trying to implement this, i have found some problems.....
1.i can't figure out how to implement the fade out portion...i mean light fades out near its dead end..
other problems are clear in this video...if any object is in front, even then the object behind is having that effect....the last one is transition from one object to another, you see how it looks? can you help me with those problems?
here are the scripts
looking at it
well I can see why its a hard cutoff, because your are literally just doing an if check. If something is in the light then it recieves the full intensity of the light, and if its not inside the light range it recieves no light.
so the attenuation here is not being calculated correctly (but you do have the right idea from what I see)
in addition to that there is no ndotl (normal dot lighting) term computed what so ever that I mentioned earlier
all you are doing is just a distance check, and if any fragment or pixel is within the radius of this "light" it will recieve the torch light
not accounting for surface normals or anything, which is why any objects within the light appear to glow even if the light is behind them
to calculate attenuation correctly
you just simply take the distance
and divide by 1
float attenuation = 1.0f / dist; //linear fallof
or
float attenuation = 1.0f / (dist * dist); //inverse square falloff
with that you can remove the entire if block that was created
this...
if(dist < 2)
{
output = col * i.diffuse + _TorchTint;
}
else
{
output = col * i.diffuse;
}
gets replaced with
float pointLightAttenuation = 1.0f / dist; //linear fallof
float3 pointLight = i.diffuse.rgb * _TorchTint.rgb * pointLightAttenuation;
output = col * i.diffuse + pointLight;
thank u again, i'm gonna try this out now...
just decided to finish the shader for you
I'll send it in a second but here
so this is what you had before
your attenuation was in a sense "correct" but the way you did it was you checked with an if block if the distance was past a certain radius, and if it was it was black, and if it wasn't then it was inside the light
so replacing it with a more proper term like I demonstrated
here
this is really great...i got your point
so it looks much better but still not right because of that issue you described earlier, that being that objects that are in front of the light will be lit when they shouldn't be. This is that normal dot light or NdotL term that I mentioned earlier
and its the most crucial part for calculating light
and in order to do that you need to calculate a direction vector to the light source
and in addition to that also, use the surface normal
and once you have those 2 you can do the shading calculation
and that makes it look as it should
and just to compare really quick to a regular unity shader
it matches
I made the intensity of this example light a bit brighter here just so you can see it more clearly
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
so heres the modified shader
that is what i just wanted to mention right now...how should i calculate that n dot l, i mean, the way i am doing this are definitely wrong
commented the parts that I changed/added
NdotL is shorthand for Normal Direction dot Light Direction
dot being a dot product in math terms
so dot(term1, term2)
but its dotting two directional terms
and note that they are directions
not positions
direction and position are not the same thing
Normal Direction is basically the direction of the surface on an object
so you have a mesh here, the cyan lines stick out are the normal direction of the mesh
worldNormal in your shader is the normal direction vector which you already calculated
the only think missing was the light direction, and the way you calculate light direction for different light types is different
for a directional light its easy, because its an infinite "sun light" that will light an entire scene
its in the name as well, "directional" light
light that comes from one single direction regardless of position
with a point light its a little more complicated because the direction varies depending on where the light source is placed
so you need to have a "world position" vector, which is the position of a pixel in "world space"
and in the shader that is calculated by just subtracting the light position by that world space
and then normalizing it after (because direction vectors need to be in -1..1 value range)
once you have those terms
then you do a dot product
all of this logic summarized is basically this
we want the surface of a light to darken the more it faces away from the light source
so that is what nDotL is
with the attenuation thing that I showed you how to calculate, that handles POSITIONALLY how dark or bright a surface gets from the light source, and the second term is calculating how bright/dark a surface gets whether its FACING the light source or not
and that should be it
@vocal gate thanks for your great in-depth explanation...it helps me a lot as i am still beginner in shader coding...
i will check it out and will probably bother you again if any difficulty arrives
did you use that torchManager script that i gave you? if you did can you show me what did you put in the references? regarding the result, yours one and my one is not matching...
i am getting something like this...
A spot light is essentially a point light
The only thing you need to extra is just add an angle calculation
So you have the attenuation with position
Then shading with normal and light direction
And then you just need to add to the attenuation an angle calculation
This is a compute shader from a larger graphics project, but if you read through the code you’ll find the section where I calculate lighting for a spot light, so you can use and get what you need from that @civic flare
thank you @vocal gate, i will try this out...
i wanted spot light type, so i did dot(worldnormal, torchDir)...i calculated the torchdir by getting the torch.transform.forward value...but it looks weird.....anyway @vocal gate... why doesn't this work out properly?
It would help if you showed screenshots
@vocal gate sorry for late reply....here are screenshots with video clip of both the cases
previously you did the first line....where the opacity wasn't being affected if the light was moved back and forth...so i added the line so that...
i guess i should give you another video clip
i am not good at explaining
@vocal gate first case...
this is what i did, even i don't know if it was right, but it went well, so i kept it
leave all these...i know those are nothing more than mess...
calculating a spot light is not too different than a point light as I mentioned
yeah i did it
this is the only key thing that needs to be done for spotlights
you still need the forward vector of the spotlight
so thats important
but you use it to calculate the angle attenuation
the "cone" of the spotlight if that makes sense
@vocal gate i should've told you before...but i am getting this from what you gave....the wall in the left is not getting the light properly...and it behaves weirdly....
huh odd, when I modified the shader none of that behavior was there with my testing
could it be with your C# scripting perhaps?
this is what i think too...can you give your c# script...did you use it?
I never made a C# script, only the shader
the shader worked fine
only things that could be going wrong is either 1. the C# script you have is flawed, or 2. your not using the actual original shader I sent by accident
all the C# needs to do is just simply pass the values of the light to the material
nothing more really
passing in position, color, angle, range, and the forward vector
alright...i should check it again then...
i am really ashamed to bother you this much
just trying to help
well, your compute shader script really helped a lot...now the angle and cone shape is working perfectly....
and indeed, the problem was created by my c# script, i misunderstood something...
you're awesome!
I've never thought this 4 -5 monthish problem will ever be solved in such a smooth and educative way, I've learned a lot more in this progress
@vocal gate still stuck at a point...i calculated the spotlightAngle from your compute shader script...but i can't use it to get final output properly....first of all i am not getting the texture as you multiplied the output with a vector with 0 rgb value ....when i turn the rgb value to 1, it becomes too bright.... secondly when i add the spotlight calculation the light becomes too bright and doesn't reveal the texture...and if i multiply this, i get only the cone part...rest part of the objkect is totally dark....here's my script at this point..please don't mind..i would be great if you check this out a bit when you are free...
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
man, you're the best!!! it's working just as i wanted...i can't thank u enough with just words...
will it be at least more performant than legacy/diffuse shader of unity which also supports lightmap and realtime lights at same time? I guess yes, because that cost more pass than one.
But I was curious if there is any more scope for any noticeable optimization in it or not as Im going to target this game for mobile)
there are some things you can do to tidy up certain things in the shader
I'll show one real quick but honestly if I were you I would make sure to run the shader on the device you are trying to test it on to see how well it performs
optimizing things can become a slipperly slope, especially if you are trying to do it ahead of time
only optimize what you need because chances are something that you think might be a problem, then turns out not be one in practice
Yes, Im gonna make a build with this and test it this night
you're right
but go ahead and test it out
beyond that though that shader should suffice now to do what you need
its all in one pass, no additional passes will be created
i'll inform you soon 'bout the TEST result
it works just fine !
I get stable 60 fps without the screen recorder on my 6 years old samsung A10
It's great !!! ^^
now im just gonna implement this system on my vegetation shader and 2 others , which I'll be using in my whole game .
I've got all these solutions through you , I've never ever imagined such day will come in my life ever 😇 🥳
I'll be so glad to mention you in my game in a big name when it's complete. thanks a lot Sir❤️
Hi @vocal gate
sorry for the @, but I have a good feeling that you can easily fix a shader related issue that Im trying to achieve
we also can achieve a great thing for the cheapest shadow on mobile without any projector or any realtime light
you can see the explanation for a bit from here and in the end of the page, there is the whole shader provided
Often when doing VFX you want stuff to stick to the floor. Even when that floor is uneven. Or decals to make existing geometry more interresting, or you want blob shadows on uneven floor, or some other use-cases in the same direction.
(note: I used the free “Nature Starter Kit 2” from the Unity Asset store throughout this tutorial)
Unity has t...
it works in built in RP where it's so hard to achieve any decal system,
I have implemented this, and using a blackish texture, I have got an ambientlike fake shadow under the player
which is projected even on non-plain surfaces
I have also easily implemented fake caustics on the ditch, by just rolling the offset value in that shader in the runtime using a bluish noisy texture
everything was so alright that I slept with joy, but later I have discovered one thing, that The objects where the decal object can be projected, must be assigned with a shader that has a shadowcaster pass
like on the ground, which was using a regular diffuse shader, The fake shadows, caustics etc fancy things were visible, but as soon as I have changed the shader of the ground into a single pass fragment shader which doest have shadow caster pass, all the shadows and caustics etc are gone from the ground
so the only difference I have figured out is the presence of shadow caster pass on the object Where decal is supposed to be projected
The thing I wanted to have is the indenpendency from the shadow caster pass
as im trying to make the game for mobile, I cant afford more than one pass on my shaders
can you give it a try to remove the shadowcaster pass dependency from it?