Animating normals in vertex shader

Hi,

I’ve been trying to make a shader that can quickly animate some geometry deforming. And i pulled it off ::click::.

However, i am not sure if i’m correctly manipulating the normals in this entire process.

I made the mesh in max, and if i run a loop through it’s vertices in unity, all of them have (0,0,1) normal, (it’s a planar surface).

This is the bulk of the shader that does the animation:

			//vertex
			vertexOutput vert(vertexInput v){
			
				vertexOutput o;
				float speed = 50;
				float radius = 1;
				half4 newPos = v.vertex;
				half dist2 = sqrt (pow( newPos.x, 2) + pow( newPos.y, 2));
				float offset2 = sin(dist2 / radius) * radius / dist2 ;
				float timeCycle = (sin(_Time*speed)+1)/2;
//				float timeCycle = 0;
//				float timeCycle = 1;
				
				
				// vertex position
				
				newPos.x = lerp(newPos.x, newPos.x * offset2, timeCycle) ; 
				newPos.y = lerp(newPos.y, newPos.y * offset2, timeCycle) ; 
				newPos.z = lerp( 
				newPos.z, 
				-(1 - cos(dist2/radius)) * radius, 
				timeCycle);
				
				
				
				

				float3 newNormal = normalize(newPos + (0,0,radius));
				
				newNormal = (newNormal.z,newNormal.z,newNormal.z);
				//normal direction
										
//				float3 normalDirection = normalize( mul( float4( newNormal, 0.0 ), _World2Object ).xyz );

I do a few lerps, but the code is messy, i can post the entire thing when i clean it up. Basically, i came up with these equations to deform my planar surface and wrap it onto a sphere. The idea with the normals was, if my newPos forms a sphere, it has a center somewhere, if i align that center with 0,0,0, the offset newPos will give me normal vectors. That’s what i’m doing here:

float3 newNormal = normalize(newPos + (0,0,radius));

It worked… to an extent, i have vertex lighting going on in the build above. Specular highlights though come out wrong. Looking at the normals seems somewhat weird. For example, this is what i get when i output just the newNormal.z as the color output. I expected the white blob to be centered on the mesh (the mesh has it’s pivot in the dead center, and it’s sitting at world 0,0,0) and definitely expected more white. Am i doing something completely herp derp here?

This::

				float3 newNormal = normalize(newPos + (0,0,radius));

seems to follow the spherical shape ok, but it looks scaled down, but this:

//				float3 newNormal = newPos + (0,0,radius);
//				newNormal = normalize(newNormal);

Starts showing white, but it looks really wrong (i get a spiral pattern instead of a spherical approx). I’m really confused because i thought it’s basically the same thing.

Here is an interactive version, it shows better what happens with the lighting.

http://dusanbosnjak.com/test/sphereCorrect.html

I finally did it, but not the way i intended to. I wasn’t able to do the flipping of axis the way it’s supposed to be done and get it working through the shader.

Instead i rotated the object in max, in its sub object level and basically did they Y-up conversion i believe.

I fixed the shader to work on unity’s built in plane surface, and used the same shader on the new geometry.

Also, i’m under the impression that this made a world of difference:

				//temp variable for normal, not sure if it fixed it
				float4 newPos2 = newPos;
				newPos2.y += radius;
				float3 newNormal = normalize(newPos2);

than going straight up

				float3 newNormal = normalize(newPos + (0,radius,0));

I mean there is definitely difference,

I’ll try to do the z/y flip again with this in mind.