DrawMeshNow() manually setup lights in edit mode

when using Graphics.DrawMeshNow(), it seems to usually use scene lights (or the scene camera if lighting is turned off), but it sometimes decides to use only the ambient. How can I manually set the light(s) for the material to use?

Edit: this is in edit mode, drawing into an editor window

Okay, tried to recreate the bug got a working implementation instead, because I’m awesome.

After rereading your last comment I strongly suspect that the issue is with you calling drawmesh OnPostrender. This will work for DrawMeshNow since it just paints on the screen but if we call DrawMesh we’d be submitting the mesh INSIDE Render(), which could lead to all kinds of unholy. We’re supposed to submit the mesh BEFORE Render(), so call DrawMesh in the Update function. You will need [ExecuteInEditorMode] to make the update function run in Editormode.

My Implementation:

EditorWindow called CameraViewer which renders the texture.

	if( camera != null )
	{
		camera.targetTexture = renderTexture; //set render texture
		camera.Render(); //render
		camera.targetTexture=null; // we set the targettexture to null after rendering so that the camera also render in normal view, instead of just to a texture
		if( liveUpdate ){Repaint();} // we have to always call this so the editorwindo gets actually  painted, alternatively use:  editorWindow.autoRepaintOnSceneChange = true; 
	}

Then I have a GameObject “EditorCamera” which has a disabled camera attached to it. You can handle it’s visibilty with the .hide flag. To decide what gets shown and what doesn’t I use Layers, I have a Layer “Editor” for stuff that only the EditorCamera should render and Cullingmasks set accordingly.

Then I have a DrawMeshTest script/component that actually draws the mesh, I have it attached to the Editorcamera but you could attach it to wherever you like. Note that it gets the mesh and material from a gameObject “test” in the scene and uses .sharedMesh and .sharedMaterial to read instead of .mesh and .material. .shared is only to be used for readaccess else we end up changing assets permanently. The debugger says that the mesh will leak if we dont use .shared. Also notice [ExecuteInEditMode]

using UnityEngine;
using System.Collections;


[ExecuteInEditMode]   //this is important!!!
public class DrawMeshTest : MonoBehaviour {
	
	public Mesh amesh;
	
	public Material amaterial;
	public int alayer;
	public Vector3 position;
	// Use this for initialization
	void Start () {
		alayer =  LayerMask.NameToLayer("Editor");
		position=new Vector3(0,0,0);
    	amesh = GameObject.Find("test").GetComponent<MeshFilter>().sharedMesh;
        amaterial = GameObject.Find ("test").GetComponent<MeshFilter>().renderer.sharedMaterial;
		
	}
	
	// Update is called once per frame
	void Update () {
	Graphics.DrawMesh(amesh, position, Quaternion.identity, amaterial,alayer);
	

	}
}

Hope that helps, learned a lot on this one, let me know if it works out.

Use DrawMesh instead, read the documentation, they write about this.

I now have it working well enough, although not exactly how I wanted. After looking through schaddemm’s code and SSE source, it seems like my problem with DrawMesh was the order and where it was called from.

My implementation:

EditorWindow:

void OnFocus() {
	//Find or create/initialize camera object, attach script
	//Camera is created with HideFlags.DontSave and the cullingMask set to a layer I reserved for editor-only stuff
	//Remove and re-add methods to callback delegate in the script
}

void Update() {
	InternalEditorUtility.SetCustomLighting(lights, ambientColor); //This is public in 4.0.1, not sure about others, SSE used reflection to get it
	RenderObjects();
	camera.Render();
	InternalEditorUtility.RemoveCustomLighting();
}

void RenderObjects() {
	// A bunch of calls to Graphics.DrawMesh()
}

void OnGUI() {
	EditorGUI.DrawPreviewTexture(location, renderTexture);
}

void ManualHandles() {
	// Called from the delegate on the script attached to the camera
	// Necessary because using Handles outside of OnGUI crashes because Event.current is null
	// Draws meshes using DrawMeshNow and lines using GL
}

Script attached to camera:

void OnRenderObject () {
	if (onRenderObjects != null && Camera.current == camera) {
		onRenderObjects(); //Delegate with no arguments
	}
}

DrawMeshNow is still not using my custom lighting, but that could be because nothing is setting it for the shader before drawing (and drawing a mesh to set lighting wont let me have a camera with culling mask set to nothing)