#Realtime spot lighting on custom shader

1 messages · Page 1 of 1 (latest)

civic flare
#

Hi @vocal gate

vocal gate
#

howdy

#

so what shader are you using as a base?

civic flare
#

just give me a second^^

vocal gate
#

and you mentioned your on the built in pipeline?

civic flare
#

this one

civic flare
vocal gate
#

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

civic flare
#

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

vocal gate
#

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

vocal gate
#

do you want shadow support?

civic flare
#

not Im not gonna use shadow caster pass

vocal gate
#

so the light won't be casting shadows? well that makes things alot easier

civic flare
#

as it will not work with single pass

#

as far i know

civic flare
#

only the light will be enough

vocal gate
#

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?

civic flare
#

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

vocal gate
#

just sounds like the way he was calculating lighting was wrong

civic flare
#

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?

civic flare
#

that looks like torch light

vocal gate
#

eh I will try, but I'll give you the general rundown

civic flare
#

and controlling it over the object according the torchlight's position

civic flare
vocal gate
#

last question for me though

#

is the lighting to be done per pixel? or per vertex?

civic flare
#

it's per pixel, (i know here it gets more complex)

vocal gate
#

nah that doesn't make it that much more complicated

civic flare
#

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

vocal gate
#
  1. 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
  2. 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
  3. 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

civic flare
#

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.

civic flare
#

@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?

civic flare
vocal gate
#

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;
civic flare
#

thank u again, i'm gonna try this out now...

vocal gate
#

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

civic flare
vocal gate
#

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

#

so heres the modified shader

civic flare
vocal gate
#

commented the parts that I changed/added

vocal gate
#

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

civic flare
#

@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

civic flare
# vocal gate

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...

vocal gate
#

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

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?

vocal gate
#

It would help if you showed screenshots

civic flare
#

@vocal gate sorry for late reply....here are screenshots with video clip of both the cases

vocal gate
#

I have no clue what the heck is even going on here

civic flare
#

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

#

this is what i did, even i don't know if it was right, but it went well, so i kept it

vocal gate
#

well just scrap all of that

#

go back to what I sent

civic flare
#

leave all these...i know those are nothing more than mess...

vocal gate
#

calculating a spot light is not too different than a point light as I mentioned

civic flare
vocal gate
#

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

civic flare
#

@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....

vocal gate
#

huh odd, when I modified the shader none of that behavior was there with my testing

#

could it be with your C# scripting perhaps?

civic flare
#

this is what i think too...can you give your c# script...did you use it?

vocal gate
#

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

civic flare
#

alright...i should check it again then...

civic flare
vocal gate
#

just trying to help

civic flare
civic flare
civic flare
#

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

civic flare
#

@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...

vocal gate
civic flare
#

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)

vocal gate
#

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

civic flare
#

Yes, Im gonna make a build with this and test it this night

vocal gate
#

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

civic flare
#

i'll inform you soon 'bout the TEST result

civic flare
#

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❤️

civic flare
#

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

#

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?