Unwrapping mesh geometry in a shader?

Hello, I’m trying to unwrap a mesh according to its UV coordinates from a vertex shader and display it in screen space. I can’t quite figure out why what I’m doing isn’t working out. I apply it to a sphere and i just see nothing in the viewport. On occasion it will simply crash Unity. Any ideas?

Shader "Custom/UnwrapShader" {
	Properties {
	}
	SubShader {
		Pass {
			CGPROGRAM

			#pragma vertex vert_main
			#pragma fragment frag_main
			#include "UnityCG.cginc"
		
			struct Output_Struct {
	    		        float4 position : POSITION;
	    		        float2 texcoord : TEXCOORD0;
			};	
			
			struct Vertex_Struct {
				float4 vertex : POSITION;
				float2 texcoord : TEXCOORD0;
			};
	
			Output_Struct vert_main (Vertex_Struct v) {
	    		        Output_Struct OUT;

				OUT.position.xy = v.texcoord.xy * 2.0 - 1;
				OUT.position.z = 0.0;
				OUT.position.w = 1.0;
				
				return OUT;
			}
			
			float4 frag_main (Output_Struct OUT) : COLOR {
				return float4(1,1,0,1);
			}
	
			ENDCG
    	}
	}
	FallBack "Diffuse"
}

Try this?

Shader "Custom/UnwrapShader" {
	SubShader {
		Tags { "RenderType"="Opaque" }
		Pass
		{
			CGPROGRAM
				#pragma vertex vert
				#pragma fragment frag
				#pragma fragmentoption ARB_precision_hint_fastest
				
				#include "UnityCG.cginc"
				
				struct v2f
				{
					float4	pos : SV_POSITION;
				}; 

				v2f vert (appdata_base v)
				{
					v2f o;
					v.vertex = float4(v.texcoord.xy, 0.0, 1.0);
					o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
					return o;
				}

				float4 frag(v2f i) : COLOR
				{
					return float4(1,1,0,1);
				}
			ENDCG
		}
	} 
	FallBack Off
}

try this, for scr space:

Or try multiplication with this, for obj space:
o.pos = mul(UNITY_MATRIX_MVP, sPos);

This one did it! Thanks so much!

what do you plan to do with this?

My guess, Skin Shader

I was hoping that I could use it to render out a projected texture (either a unity projector, or using my own custom texture projection matrix) directly onto a texture map. I’ve got a bit of a ways to go with that though. My general idea was that I would render the model unwrapped using this vertex shader, to a RenderTexture using this as a replacement shader.

Any ideas if this sounds insane?

So why does multiplying by UNITY_MATRIX_IT_MV make this work exactly? I was under the impression that uvs were stored from 0-1 and that we needed to return values in clip space which is from -1 to 1? Why do I need to multiply by this matrix?

And for the record, this only works when I have my camera rotated at an precise angle which is fine, but is there a way to make it so that it is always facing the camera? Just to satisfy my curiosity. The solution you posted should work fine for my needs.

It seems that if I take what I originally had, and just be sure to set the w component to that of the vertex, then it does just fill my screen which was what I was hoping for. So that makes a bit more sense to me now.

Output_Struct vert_main (Vertex_Struct v) {
	    		Output_Struct OUT;

				OUT.position.xy = v.texcoord.xy * 2.0 - 1.0;
				OUT.position.z = 0;
				OUT.position.w = v.vertex.w;
				
				OUT.texcoord = v.texcoord;
				
				return OUT;
			}
1 Like

Hi, I was just looking into the same thing and found this:

When using the shader included in that link, it unwraps the mesh and shows it in screen space.
What I am missing is how I would project something (a shadow fe.) onto this mesh and have it displayed the same way.
so I can grab the projection (flattened to the uv layout) to be used on the mesh as a texture.
Because right now my projection is shown around the invisible object which mesh is displayed stretched on screen.

The image shows mesh in its unwrapped form (red) and an invisible object in scene view with a shadow from a box projected onto the object (via a script on wiki for projected character shadows)

I assume Jacktang is your alias in unity answers :slight_smile: then what I have found is probably your own solution.

I guess to unwrap the shadow the projector shader would have to mysteriously modified to show the outcome of the projection on screen.

Do you think it is possible?

bump