Unity - Vertex light ignored by static objects (lightmapped) - unity3d

Vertex lights work fine on dynamic objects, but the second I make them static and bake lightmaps they're ignored.
I've tried changing to different "lightmodes" within the shader, but none has worked. Lightmode "ForwardBase" seems to really mess up, even though I would assume its the one to use given its description on https://docs.unity3d.com/Manual/SL-PassTags.html
Any suggestions would be very appreciated :)

My understanding of the question at hand
As I understand, when you bake a lightmap, the only light source that will change the light of the baked objects is a pixel light. But you would like to make it work with a vertex light.
I'm still not entirely sure whether you mean that the light simply won't bake into the baked map in the first place, or whether it cannot affect the light level of the object after it has been baked.
In any case, I did some searching.
Possible solution/explanation 1
When I searched I came across this tool and description.
https://assetstore.unity.com/packages/vfx/shaders/vertex-lit-shader-baked-shadows-realtime-light-75977
By default, using Unity’s built-in shader Mobile/VertexLit lighting
works only as either baked or realtime but you cannot display a
realtime light on a baked surface. This shader allows a baked surface
to also receive realtime lighting.
Note that the tool is free.
Possible solution/explanation 2
I also came across this tutorial: https://catlikecoding.com/unity/tutorials/rendering/part-16/
Where the author writes
When lightmaps are used, Unity will never include vertex lights. Their
keywords are mutually exclusive. So we don't need a variant with both
VERTEXLIGHT_ON and LIGHTMAP_ON at the same time.
Lastly please note that these solutions seem to be developed at earlier versions of Unity. Newer solutions more appropriate may exist.
Hope this helps you.

Related

Unity - how to provide diffuse lighting

I have a simple scene of the interior of a house (less roof). It does not in any way need to look realistic, just to be geometrically correct, therefore the walls and furnishings and fittings are simply constructed from primitive objects - cubes and cylinders etc.
The layout is fine, the problem is the lighting - very black shadows. The scene has the standard single directional light source.
What I need to do is provide overall diffuse lighting - equivalent to an overcast day.
I should point out that I am pretty much a novice on all this - lighting, shaders etc, though I have been reading a lot.
From what I read it appears that this is controlled by shaders, shaders being attached to materials, materials being applied to the objects. However, it doesn't seem to make much sense to me. Surely, a shader, if part of the object by virtue of being attached to the material, can only deal with how light might be reflected off the surface - but the light has to get there first.
Therefore, there must be a way of providing an overall diffuse light in the first place?
Or have I got this completely wrong? How does one get rid of the blackness on the non-illuminated side of an object? So far the only way I have found is to make the surface emit light, ie glow a bit, which surely must not be right.
Your general understanding of how this all works is correct. One way to look at it object request rendering, looks up the material, the material binds shader to a set of parameters. The shader then gets executed, once per light in the scene that affects it (this is simplyfying things but we'll get to that in a bit). This is why lights are expensive (in forward rendering that is), until optimizations start to kick in, this means rendering the scene n times.
So yes, you could just add a constatnt factor in the shader, to achieve the effect of 'ambient' or 'diffuse' lighting. But that shader, in order to support all the features like reflectivity etc, would have to be crazy complicated.
Fortunately, with unity we also get a middle layer called Standard Shader, which does pretty much all of the math underneath, and releases you from the necessity for writing shader code.
For a gentle, diffused look, you definitely want to look at baked Indirect Illumination features of Unity, maybe even lit everything with area lights only.
Its probably also a good idea to looki into light probe groups. They work with spherical harmonics, encoding only the low frequency components of the lighting data, effectively only using slow changing factors like general direction of the light.
Finaly look into reflection probes (and skyboxes while at it), theres few good free HDR probes available that will emit light into your scene (when baking lightmaps and baking lightprobes), enabling surprising realism, compared to default unity skybox.
If you don't want harsh directional light, just disable it (although it's often useful to know what is your strongest light source in your sene - even if its a skybox with some clouds, i would probably keep a scene light just to know faster if anything goes wrong

Unity light baking - How to manage mixed lighting

I have a pretty large scene, where I have 1 directional light (sun) set to mixed.
I mainly used realtime lighting during development in order to save time.
Now before release I want to bake, to improve performance for my users.
My questions are
Is there any rule of thumb for any of the values in light-settings?
which objects should I set to static (I set everything that doesnt move to static) and is something wrong if my bake takes 3-4 hours?
Should I use realtime GI since I have mixed lighting, or is Baked GI enough?
I use fairly high settings for my final bake because I want it to looks nice, and I bake everything that doesnt move in the scene (thousands of objects). While it does take hours, the light map size ends up at around 60mb after compression, which doesnt seem bad.
My settings are like the image below, except I've increased:
Direct samples: 200
Indirect samples: 1000
Resolution: 24
Parameters: Default High
The reason for increasing these values is simply because my objects did not look good in a bake with any lower settings.
I want to bake, to improve performance
Notes:
Baking usually improves visuals.
But this creates a lot of textures, so it may lower performance.
Using ONLY the baked lights, it's basically unlit - very good performance.
Mixed means you bake the indirect lights (because without realtime raytracing you won't have indirect lighting*) and still use realtime lights for some things like hard shadows.
If you don't want to rotate the directional light (sun) or move point lights around, there is no use in baking the realtime GI.
[*] : We can fake some realtime GI / soft indirect lighting by pre-baking this. So "Realtime GI" allows you to rotate the Directional Light (Sun) or even move lights around, but not objects. And you need to bake it, usually including some light-probes. So "realtime" doesn't mean it's bake-less. And it's not the same as real raytracing.
Duration:
Using 2018.3 or 2019.1 (not sure) you can try the GPU Lightmapper (preview) - it is a lot faster. However using CPU 3-4 hours is quite normal to me.
Static?
Marking things as static is always good for performance, but you can also mark non-static things as "Lightmap-static" if you want movable houses to be pre-baked for example.
Lightmap Debug Mode:
The reason for increasing these values is simply because my objects did not look good
In Scene view, you can select a "Lightmap" mode (not sure how it's called).
It displays basic chess/checker texture on all objects with lightmap-UVs. Use this view to scale lightmap UVs to increase details on close objects for example.
edit:
Mixed Lighting - Performance?
This will bake the light for all static (or at least lightmap-static) objects in the scene. During runtime, lighting is not computed for the static ones anymore.
At least that's what the Manual says:
Selecting the ‘Mixed’ baking mode, GameObjects marked as static will still include this light in their Baked GI lightmaps. However, unlike lights marked as ‘Baked’, Mixed lights will still contribute realtime, direct light to non-static GameObjects within your scene.
I just tested:
"Baked" - After Baking, rotating the sun didn't affect the scene until rebake.
"Mixed" - I can rotate the sun and affect shadows. Note: "static" objects still get some indirect light (reflecting from the surroundings) while non-static objects are not baked, and therefore completely black on the side which is not facing the sun.
The Lighting tab says
Mixed lights provide realtime direct lighting. Indirect lighting gets baked into lightmaps and light probes. [...]
Performance:
This is hard to answer without a test, as I am only relying on theoretical facts, and maybe assumptions.
I would say the Mixed Light mode is just to have better visuals (indirect lighting). This is precomputed, but the textures still need to be multiplied/added to the pixel lighting in the shader - this costs a bit performance.
And the direct light is still computed in realtime - so if I understood the docs correctly, Mixed is always worse than only realtime lighting in terms of performance.
But: If your sun doesn't even move - you can use it in "baked" mode instead of "mixed" - this will bake shadows to texture and save the calculation at runtime. This is the only option that for sure is better in performance. I'm not 100% sure about the mixed mode.
And realtime lights will still affect them. A torch for example.
However your non-static player will not get the sunlight lighting/shadow because it cannot be baked. You could try using an unlit shader on him, and add a fake shadow under it. Or you place a point light above it to fake the sun.

How can I use baked lighting on sprites? / How to light up a large area in 2D?

I'm having trouble figuring out how to light up large area(s) of sprites in Unity 2D. My previous knowledge on Unity's lighting is zero.
I first tried using a large amount of point lights and using the "Sprites/Diffuse" material, but about only five would actually render at a time, so I guess there's a limit on that.
Then I tried putting in an area light. That didn't do anything, so that's when I started doing research about baked lighting on sprites (and baked lighting in general). I found stuff like this but I couldn't get it to work either because it's outdated or because I don't know what I'm doing. Other answers I've come across seem to assume that the reader knows anything about lighting in Unity in the first place which, to be honest, I don't. Unity's documentation website had some information on it, but no tutorials that go into how to set up baked lighting.
I've tried a bunch of different combinations of materials (like using the "Standard" shader for the sprites instead of "Sprites/Diffuse", emission, ect.) and I enabled "Baked Global Illumination" in Lighting>Settings.
If baked lighting isn't possible on sprites (or isn't worth the trouble), what are the alternatives?
Edit: I made sure not to have the lights pointing the wrong direction, and I do realise that Unity2D is just like painting onto a piece of paper in Unity3D. I was able to get point lights to work, but only a few at a time. I don't need to do the entire screen at once, I need to do a large specific area at once.
some tips...
working with sprites your in 2d... when you add a light, switch to 3d mode, and rotate to make sure your light is pointed at your objects, and oriented so as not to be on the same plane, or level with them, as this will cast all the light behind them.
if your trying to light up everything on the screen(in camera) attach an area light to the camera at the cameras position, point it where the camera points, and then in the inspector on the right, you can change its variables. intensity, range, width, height etc.
Emissive Texture:
https://www.youtube.com/watch?v=oa6kW5HhRd4
For some reason, I never even thought about going into the asset store. I found this for free, and it looks like it will work: Light2D.

Need Forward rendering for fog, but Deferred rendering to keep out light

So I've hit a bit of an oddball in my project. I'm creating a horror scene. To support the atmosphere I've used Unity's lighting component fog. For my camera to see this fog, I need it to be on Forward rendering. However, I'm creating a hallway with different rooms and lights, and these lights seem to shine through my wall objects when forward rendering is off. Something I can fix by using deferred rendering instead (But then there's no fog).
It feels weird I'm in a position where I have to choose between the two and can't have it both ways. I tried messing around with some of the Legacy rendering, but no dice. All lights have a shadow strength of 1, and walls even have additional "Shadows only" walls, just to be sure nothing gets through.
It should be mentioned that I'm using one plane for all rooms (Not prefabs, one BIG object) if that has any impact at all.
Anyone experienced similar issues who has any workarounds?
If anyone runs into a similar issue, it's important to have different planes for different rooms. I was using 1 plane for the whole level, which caused this lighting bug to occur.
I had a similar problem... i solved with:
Set my camera rendering path with deferred
camera component
and set the component post process layer (asset)
post process layer

Lighting an instantiated prefab, baked versus realtime

I'm generating a dungeon out of prefabs which means I design a room, save it in the resource folder and instantiate it at a random position with a random rotation while the game is running.
The problem I have is the lighting.
Because of the above mentioned generation process it has to be dynamic but it doesn't seem to work. Below you can see the comparison between a baked and realtime rendered room:
Baked (I also don't know where these strange lighting borders (on the walls), which are looking like someone painted the light with watercolors are coming from):
Realtime:
As you can see, the realtime room doesn't seem to reflect light in any way.
These are my lighting settings:
And this is my 'sun':
What am I doing wrong?
Your lighting settings have Ambient Light set to 0- with realtime lighting, this means nothing that can directly see the source of a light will be lit at all. The screenshot with baked lighting looks different because it has a baked lightmap.
If you're trying to get the real-time lighting to look exactly like the baked, soyy, but Unity refuses to bake lightmaps at runtime. The closest you can probably get is by setting your Ambient Light to a color and its intensity above zero. Playing around with Light Probes probably won't be much good, since you need to light an entire room in a vacuum.
An alternate solution, depending on how well you know Unity, would be to Frankenstein together different scenes, which is mentioned briefly in Unity's Intro to Global Illumination, though I can't find it anywhere else.
Relevant links:
Baked Lightmaps: http://docs.unity3d.com/Manual/GIIntro.html
Light Probes: http://docs.unity3d.com/Manual/LightProbes.html
Ambient Light: http://docs.unity3d.com/Manual/GlobalIllumination.html