Home Technical Talk

Struggling to bake local position to vertex color in MAXscript / MCP for blendshapes in Unity

polycounter lvl 8
Offline / Send Message
comomomo polycounter lvl 8
Hi all! 

I'm working on getting a script together in 3ds MAX that bakes local space positions into vertex colors for easy blendshapes in Unity. This is all inspired by the Naughty Dog talk which describes similar processes you can find here: http://www.gdcvault.com/play/1024103/Technical-Art-Techniques-of-Naughty

Things have been going alright in my adventure so far but I'm struggling to cleanly store the vertex positions in colors in MAX specifically. In Unity I can quickly colorize them in C# because I'm pretty competent in Unity's libraries but I'm really struggling to reproduce something so clean in Max Creation Graph.

Here's the Unity shader in action on a capsule I colorized then skewed in C# code. 


My current graph in 3ds MAX looks like this:

I'm using an empty input and the Trimesh has its colors remapped with the function ColorVertices(mesh, vertexToColorFunc). This produces a messy output I've also seen using this script: http://www.scriptspot.com/3ds-max/scripts/position-to-vertexcolor Which I'm pretty sure looks messy because its remapping the mesh id channel to the vertex color.

Result


Here's what a messy colored object looks like in Unity with the same shader as the above capsule. 



How can I fix this so that the colors turn out as cleanly as they do in my Unity scene? + Has anyone attempted to bake local positions to colors a different way with success in the past? 

Thanks for reading! :~) 

I'm also curious if anyone has attempted something like this: https://vimeo.com/207832662 that moves from 3ds MAX to Unity.  

Replies

  • monster
    Offline / Send Message
    monster polycounter
    That's a cool technique from GDC! I haven't really dug into it myself.

    Your MCG and script from ScriptSpot technically both work. But the vertex colors needs to be normalized into 0-1 UV space. In the screenshot attached the big teapot is like yours, and i used the script from ScriptSpot to generate the colors. For the little teapot, I fit the size into a 1x1x1 box, Reset Xforms, and then ran the script. Notice it looks smoother like your Unity capsule.
  • comomomo
    Offline / Send Message
    comomomo polycounter lvl 8
    @monster Thank you!! I'll give this a go when I get home :blush:
  • comomomo
    Offline / Send Message
    comomomo polycounter lvl 8


    It's getting there! I think negative values are getting cut off right now I'm not sure why. This is a sphere.
  • Shive
    Offline / Send Message
    Shive polycounter lvl 2
    If you have max 2017 available you can also try the data channel modififer. Slapped together a quicke example here:

    I am not sure if the Colors are correct for use in Unity, but the normalize give you some options to handle that i think.
  • comomomo
    Offline / Send Message
    comomomo polycounter lvl 8
    @Shive thanks for sharing! I found the XYZ space operator did the best job of capturing the original form but it's still imperfect. Right now the model is coming out half of the size it should be in Unity. I believe it's because of the bounding box since sphere's dont have the same issue. Is there a way to modify the bounding box or multiply by it in the stack? 


  • Noors
    Offline / Send Message
    Noors greentooth
    Interesting. Yeah it's squashed because your vertex color is normalized while the bounding box is not cubic.
    But still you'd need to scale in Unity to get the desired size no ? Because here it's 1*1*1 right ?

    -Either you scale the object in max/unity to get the correct bounding box ratio at the end.

    -Or in Max you scale your vertex color data so it fits in a 1*1*1 cube while keeping proportions.

    I dont own max 2017 but you can access vertex color through unwrap.
    I dont think you can edit the bounding box size to be cubic, it just always fits your mesh so here's a trick :
    -Create a cube that fits your teapot.
    -Convert to poly
    -Attach teapot and cube.
    -Apply an unwrap.
    -In the unwrap, switch to vertex Color Channel -> abandon
    (new channel creates normalized data of your mesh by default, pivot is at 0.5 0.5 0.5)
    -Collapse
    -Delete the cube faces.

    Should be good then.





  • comomomo
    Offline / Send Message
    comomomo polycounter lvl 8
    @Noors That seems to be on the right track! I'm having some scaling issues importing into Unity though. Is there a way to get the box to more perfectly fit an object or ensure that that object is 1x1x1?  
  • Noors
    Offline / Send Message
    Noors greentooth
    Mmh i'm not sure. The pivot will be at the center of the bouding box and not at the original place.

    Also if i only scale scale, object i guess i have to invert ratio. You can uncomment scale object to test it. What are roughly the scale values you have to put in unity so the teapot looks ok ?
    (
    	obj = $
    
    	bb_max = obj.max
    	bb_min = obj.min	
    	bb_length = #(bb_max.x - bb_min.x , bb_max.y - bb_min.y, bb_max.z - bb_min.z)
    
    	max_length = amax bb_length
    	max_index = finditem bb_length max_length
    
    	--create a cube fitting obj
    	myBox = Box length:max_length width:max_length height:max_length
    	myBox.pivot = myBox.center
    	myBox.pos = obj.center
    
    /*
    	--scale object
    	case of
    	(
    		max_index == 1 : scale obj [ 1 , (bb_length[2]/bb_length[1]) , (bb_length[3]/bb_length[1]) ]
    		max_index == 2 : scale obj [ (bb_length[1]/bb_length[2]) , 1, (bb_length[3]/bb_length[2]) ]
    		max_index == 3 : scale obj [ (bb_length[1]/bb_length[3]) , (bb_length[2]/bb_length[3]) , 1 ]
    	)
    */
    )<br>
  • comomomo
    Offline / Send Message
    comomomo polycounter lvl 8
    // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
    
    Shader "Custom/VertexColorBlendshape" {
    	Properties{
    		_Color("Main Color", Color) = (0.5, 0.5, 0.5, 1)
    		_MainTex("Base (RGB) Gloss (A)", 2D) = "white" {}
    		_Deformation("Deformation", Range(0.00, 1)) = 0
    	}
    
    		SubShader{
    		Tags{ "Queue" = "Geometry"
    		"IgnoreProjector" = "True"
    		"RenderType" = "Geometry"
    	}
    		LOD 400
    		CGPROGRAM
    #pragma surface surf BlinnPhong vertex:vert
    #include "UnityCG.cginc"
    
    	sampler2D _MainTex;
    	float4 _Color;
    	float _Deformation;
    
    	struct Input {
    		float2 uv_MainTex;
    		float4 color : COLOR;
    	};
    
    	void vert(inout appdata_full v)
    	{
    		//3ds max flip vertex to rbga to account for difference 
    		float3 colorToPosition = v.color.rgb;
    		colorToPosition.r = 1 - colorToPosition.r;
    		colorToPosition.g = colorToPosition.g;
    		colorToPosition.b = colorToPosition.b;
    
    		float centerOffset = .5;
    		float scale = 2;
    
    		v.vertex.xyz = lerp(v.vertex.xyz, (colorToPosition - centerOffset) * scale, _Deformation);
    	}
    
    	void surf(Input IN, inout SurfaceOutput o) {
    		half4 tex = tex2D(_MainTex, IN.uv_MainTex);
    		half4 c = IN.color;
    		o.Albedo = c.rgb;
    		o.Alpha = 1;
    	}
    	ENDCG
    	}
    }<br>
    Here's my current shadercode for anyone interested it still doesn't work perfectly and I'd really love to get rid of the scale variable in the vertex code. Ideally though that would be on the MAX side of things.
     
    @Noors Thank you so much for the script!! I wasn't totally sure how to get the rest of the Max script working when I uncommented the code I got an error: 

    -- Error occurred in anonymous codeblock; filename: *******\vertexposcolor.ms; position: 411; line: 17
    -- Syntax error: at ==, expected :
    --  In line: max_index == 1

    Here's a lil editor snippet from current test objects. Note that the teapot still shrinks even with the same bounding box as its vertex colors. The Torus Knot seems to be behaving a little bit nicer but that difference still could have something to do with my magic scale number. :'~) 




  • cptSwing
    Offline / Send Message
    cptSwing polycounter lvl 11
    What is this magic? (the gdc link is members-only I guess)
  • comomomo
    Offline / Send Message
    comomomo polycounter lvl 8
    @cptSwing I hope it goes public at some point its full of crazy stuff. They use textures to animate distant crowds super efficiently using something like this:  and store pivot points in vertex colors as well to deform grass / foliage more realistically. 
  • comomomo
    Offline / Send Message
    comomomo polycounter lvl 8
    Holy crap!! Someone made a script for storing vertex animations in textures for 3ds MAX!! 

    https://github.com/apras/Unity-VertexTextureFetchAnimation
Sign In or Register to comment.