LightmappedGeneric + IMesh

Duplicate of this thread, but noone answered there, let’s try again.
This video proves that it is possible.

How does one draw a Mesh with LightmappedGeneric shader?

I tried the following:

  • Create and cache an IMesh object
  • Initialize it using mesh.* functions, including 2 UV channels (one for the texture, one for the lightmap)
  • Create a LightmappedGeneric material
  • Create a rendertarget to use as lightmap texture using GetRenderTargetEx() with the following parameters: “testlightmap”, 16, 16, RT_SIZE_NO_CHANGE, MATERIAL_RT_DEPTH_NONE, 0, CREATERENDERTARGETFLAGS_AUTOMIPMAP, IMAGE_FORMAT_RGBA8888

Render the mesh:

  • render.SetMaterial( LightmappedMat )
  • render.SetLightmapTexture( LightmapRT )
  • MyMesh:Draw()

But it just doesn’t draw the mesh this way. If I change the shader to VertexLitGeneric everything is alright.

P.S. I’m asking anyone who knows how to do it to share some information. When I will find out how it’s done I will create an in-depth article on gmod wiki to make it clear for everyone. Thanks.

I got it to work a few years back for a Q3 map renderer, but I don’t remember the specifics sorry. The API might have changed in the meantime aswell.

You can find the source code for my project here.

Apologies for the code quality, this was the last thing I coded just before burning out of gmod.

Thanks a lot! I will try to get it to work and share the solution for this ASAP.

You have to pass a material to the Mesh() function (preferably the one you intend to render with). This will create the mesh with the correct vertex format, which will allow it to store the extra UV channel.

Just know I’ll be closely following this thread for results OP, interested as well

Oh, this actually makes a lot of sense, I wonder how I never thought about that. I can not test it now but I will share the results of checking this version when I’m back home. Something tells me that’s what caused the issue.

So, I’m finally back home and I have positive results now

Thanks again, Jcw87, you were absolutely right. My mistake was not passing the material to Mesh() function since I thought it’s not really neccessary

Here’s the code I used for my testing and in-game looks of it:



-- LightmappedGeneric material that we'll use for our mesh
local meshMat = Material( "concrete/concretefloor001a" )

-- Mesh vertices (notice that it's not MeshVertex structure format, just something similar)
-- Notice that we have 2 UV coordinates channels, one for texture, one for lightmap
local meshVertices = {

	{ pos = Vector( 0, 0, 0 ), u0 = 0, v0 = 0, u1 = 0, v1 = 0, n = Vector( 1, 0, 0 ) },
	{ pos = Vector( 0, 100, 0 ), u0 = 1, v0 = 0, u1 = 3, v1 = 0, n = Vector( 1, 0, 0 ) },
	{ pos = Vector( 0, 100, -100 ), u0 = 1, v0 = 1, u1 = 3, v1 = 3, n = Vector( 1, 0, 0 ) },
	{ pos = Vector( 0, 0, -100 ), u0 = 0, v0 = 1, u1 = 0, v1 = 3, n = Vector( 1, 0, 0 ) },
}

-- Run this command while ingame to create the mesh at map origin
concommand.Add( "meshtest", function()

	-- Creating a render target to be used as lightmap texture
	meshLightmap = GetRenderTarget( "test_mesh_lightmap", 128, 128, false )

	-- Filling the lightmap texture with some stuff for visualization
	render.PushRenderTarget( meshLightmap )

		cam.Start2D()

			-- Resetting lightmap to be monotone gray
			render.Clear( 128, 128, 128, 255 )

			-- Drawing a dark rectangle
			render.SetColorMaterial()
			surface.SetDrawColor( 80, 80, 80, 255 )
			surface.DrawRect( 32, 32, 64, 64 )

			-- And some color text, why not! Lightmaps support RGB color
			draw.SimpleText( "This is lightmap", "DermaDefault", 64, 64, Color( 255, 0, 0, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )

		cam.End2D()

	render.PopRenderTarget()

	-- Creating the mesh. Don't forget to pass the material you're gonna use with it!
	-- Shader of the material defines some features of the mesh, vertex structure
	-- specifically (LightmappedGeneric requires each vertex to store 2 UV channels,
	-- for instance. This is important in this case)
	myTestMesh = Mesh( meshMat )

	-- Creating the mesh
	mesh.Begin( myTestMesh, MATERIAL_QUADS, 1 )

		for i, vertex in pairs( meshVertices ) do

			mesh.Position( vertex.pos )

			-- Texture coordinates go to channel 0
			mesh.TexCoord( 0, vertex.u0, vertex.v0 )

			-- Lightmap texture coordinates go to channel 1
			mesh.TexCoord( 1, vertex.u1, vertex.v1 )

			mesh.Normal( vertex.n )
			mesh.AdvanceVertex()
		end

	mesh.End()
end )

hook.Add( "PostDrawOpaqueRenderables", "LightmappedMeshTest", function()

	if myTestMesh and myTestMesh ~= NULL then

		render.SetMaterial( meshMat )
		render.SetLightmapTexture( meshLightmap )

		myTestMesh:Draw()
	end
end )


[editline]1st September 2017[/editline]

Added an example to the wiki

Good job.

Now if only there was a way to have these meshes work with projected textures…