Vertexlit gone after lightmapping

Hi there,

I have been having problems with lightmaps (using Beast) since I started using it seriously. First, there is the unresolved problem with the batching (see this post: http://forum.unity3d.com/threads/78850-Why-does-lightmapping-stop-dynamic-batching-from-working?highlight=lightmap+batching ) and now I have another weird problem with the Vertexlit shaders. First, Im using the shader Mobile/Diffuse. If I put a cube with 4 points lights around it and a directional light, all the lights illuminates perfectly it using vertex (as expected). Those lights, except the directional, are configured as “RealTime only”. As soon as I launch Beast, and the lightmap process is over, the vertexlit lights are gone. If I remove the lightmap they come back.
I have tried with all the default shaders and the effect is always the same: if you put a Beast lighmap you will loose vertex lights, only per-pixel light works. This has no sense. Anyone has info about this?

Thanks in advance

I have read this post (http://forum.unity3d.com/threads/74504-Lightmapping-in-iOS-VFX-Lighting) but the answer is not there.

Is the cube lightmapped in the above scenario? If so then it will no longer receive realtime lighting (the 4 point lights) after the lightmaps are baked. An object can’t be realtime lit and lightmapped at the same time unless you’re using dual lightmaps.

Thx for the reply. Yes the cube is lightmapped and I’m using single lightmaps (I’m on iOS). The cube STILL receive per-pixel lights after been baked (if I use a per-pixel lighting shader, like the standar diffuse), but the per-vertex lights don’t work. I have also tried with the no-mobile vertexlit shaders with same results: No per-vertex lighting

Yeah, the limitation Ethan talked about only affects VertexLit shaders. A vertex lit object, once lightmapped, does not receive any realtime lighting. We kind of chose this by design; using vertex lit almost always means “I want to run this as fast as possible” that’s why we opted for no lighting once it’s lightmapped.

Per-pixel lit shaders, once lightmapped, are affected by non-lightmapped lights.

Thanks both :wink:

Maybe you can help me with this problem with lightmapping and static batching (it’s from another post that got lost)

"…, Im using static batching, all meshes are marked as static and all have the same material. Now the tricky part: If the lightmapper only generates one texture for all the objects they are batched correctly. BUT, if it generates more than one, the batching don’t work as spected. This are the numbers for 100 objects with same material (just planes) with one directional light and diffuse shader:
Without lightmap: 1 Draw, 100 batched
With 1 lightmap: 1 Draw 100 batched
With 2 lightmaps: 18 draws, 86 batched
With 3 lightmaps: 26 draws, 82 batched
An so on…
"

Hi, Aras,

It is possible to enable force-processing of vertex shaders on lightmapped objects? Via shader instruction or by any other means?

Because it’s is nice of you to take care of us by making lightmapped scenes fast by omitting vertex lighting, but wouldn’t it be a lot better to give us a chioce?

It is perfectly normal to use any lighting with any mapping if one knows that his target will be able to process it.
Imagine how good would games look if they utilized both beast lightmapping and vertex lighting (in the dark areas, for example).
Vertex lighting is extremely cheap, and you know it better than any one else, so…

Please, advise.

Cheers.

forwardbase should do it I think

Sorry, I forgot to mention that I’m an iOS developer. Won’t work on iOS this way.

Never mind. I’ve modified the standard Vertex Lit shader to multiply the resulting pass by PRIMARY and then add PREVIOUS as an albedo while still keeping the number of draw calls at 2.
Now anything can be vertex lit even with the lightmap on.
Cheers.

Can you please provide this shader? Thanks!

I’d like to see that shader too. Please :slight_smile:

Yes bump please supply this shader

For any one interested I coded such a shader…

I added one extra combine to use the color as the ambient light from the render settings. So if you don’t need it delete it.

These are the lines:

SetTexture [_MainTex] {
constantColor [_Color]
combine previous*constant DOUBLE
}

you have to feed the ambient light through code though.

And while it works very good on desktop it is very slow on some mobile devices.

//change the _Color to use the Ambient light !!!!

Shader "VertexLit_Lightmap" {

Properties {
	_Color ("Main Color", Color) = (1,1,1,1)
	//_Specular ("Specular", Color) = (1,1,1,1)
	//_Shininess ("Shininess", Color) = (1,1,1,1)
	//_Emission ("Emission", Color) = (1,1,1,1)
	_MainTex ("Base (RGB)", 2D) = "white" {}
}

// 2/3 texture stage GPUs
SubShader {
	Tags { "RenderType"="Opaque" }
	LOD 100
	
	// Non-lightmapped
	Pass {
		Tags { "LightMode" = "Vertex" }

		Material {
			Diffuse [_Color]
			//Specular [_Specular]
			//Shininess [_Shininess]
			//Emission [_Color]
		} 
		Lighting On
		//SeparateSpecular On
		SetTexture [_MainTex] {
			Combine texture * primary DOUBLE, texture * primary
		} 
	}
	
	// Lightmapped, encoded as dLDR
	Pass {
		Tags { "LightMode" = "VertexLM" }
		Lighting On
		
		BindChannels {
			Bind "Vertex", vertex
			Bind "normal", normal
			Bind "texcoord1", texcoord0 // lightmap uses 2nd uv
			Bind "texcoord", texcoord1 // main uses 1st uv
		}

		Material {
			Diffuse [_Color]
			//Specular [_Specular]
			//Shininess [_Shininess]
			//Emission [_Color]
		}
		
		SetTexture [unity_Lightmap] {
			matrix [unity_LightmapMatrix]
			constantColor (1,1,1,1)
			combine texture * constant
		}
		SetTexture [unity_Lightmap] {
			combine previous + primary
		}
		SetTexture [_MainTex] {
			combine texture * previous, texture * primary
		}
		
		SetTexture [_MainTex] {
			constantColor [_Color]
			combine previous*constant DOUBLE
		}
		
		SetTexture [_MainTex] {
			combine previous+primary
		}
		
		
	}
	
	// Lightmapped, encoded as RGBM
	Pass {
		Tags { "LightMode" = "VertexLMRGBM" }
		Lighting On
		
		//Blend SrcColor	SrcColor
		
		BindChannels {
			Bind "Vertex", vertex
			Bind "normal", normal
			Bind "texcoord1", texcoord0 // lightmap uses 2nd uv
			Bind "texcoord", texcoord1 // main uses 1st uv
		}

		Material {
			Diffuse [_Color]
			//Specular [_Specular]
			//Shininess [_Shininess]
			//Emission [_Emission]
		}
		
		SetTexture [unity_Lightmap] {
			matrix [unity_LightmapMatrix]
			combine texture * texture alpha DOUBLE 
		}
		SetTexture [unity_Lightmap] {
			combine previous + primary 
		}
		SetTexture [_MainTex] {
			combine texture * previous 
		}
		
		SetTexture [_MainTex] {
			constantColor [_Color]
			combine previous*constant  QUAD
		}

		SetTexture [_MainTex] {
			constantColor [_Color]
			combine previous+primary
		}
				
	}

	

}


}

3 years on from the creation of this thread, mobile GPUs are a fair bit faster, but per-pixel/pass-per-light still isn’t viable for most mobile developers - still needing to support at least the iPhone 4S. It’d still be nice to be able to real-time vertex lighting on lightmapped objects - even if it’s just for a couple of effects - such as the occasional flickering light or big explosion

Has anyone figured out a solution? - when I last tried messing with shaders, it seemed that the vertex light parameters simply don’t get set for lightmapped objects, so custom shaders won’t help much (unless you do your own lighting entirely, which isn’t ideal)

It is possible to trick Unity into thinking that lightmapped meshes aren’t lightmapped, and are regular meshes with two UV sets?, so the lighting won’t be disabled?

Bump.

If think it’s heavily disappointing, for same reasons as bluescrn. It seems that when LIGHTMAP_ON keyword is enabled, runtime will simply ignore VERTEXLIGHT_ON, even if present.

Does anyone have a workaround for this?

Our current workaround is to use a set of entirely custom shaders which always calculate 4 per-vertex diffuse-only point lights.

It does the job, but it’s not the greatest solution, as we have to manage the lights/shader parameters ourselves, and are limited to 4 global lights (rather than the 4 closest/most important lights per-object). But these lights are purely for special effects at the moment, rather than a fundamental part of the game’s lighting.

Exactly what I came with in my project, but because of the pain of having to manage these lights yourself, it’s hardly a workaround.

How do you calculate attenuation for these lights, i.e. the equivalent of unity_4LightAtten0? I use the inverted square of each light’s range, but I’m not entirely sure whether that’s what Unity is doing.

We still really need the ability to enable vertex light information without additional passes and without hacky solutions like suggested towards the end of this thread. Surely shaders can provide this information, since they do when lightmaps aren’t being used, so why is it so difficult to introduce a feature that allows us to enable receiving vertex light information when lightmaps are present?

There are still important scenarios for being able to use vertex lights on objects that are lightmapped. One of the most important being adding some realtime lighting without performance penalty in forward rendering.

Unless I’m misguided then this is still an important unsolved issue 7 years after the original post. What can be done? When, if ever, can we expect the ability to do this?