Ink n Paint material

I’ve been trying to figure out how to port the ink n paint material shader of 3ds max to unity3D so I could get outlines according to smoothing groups, but didn’t succeed. I tried edge detection and it worked partially since it messes up as the model moves away from the camera.

Can you help me out with this please? This is what I’m aiming for basically
http://developer.download.nvidia.com/shaderlibrary/webpages/screenshots/shaders/scene_lineDraw.html

Have you tried the “Toon Shader” that’s included in the Standard Assets?

Yup. But that doesn’t draw the outlines according to smoothing groups.

Bump

The shader you have given the link doesnt draw lines according to smoothing groups either.

oh so any idea of such a shader?

whether you have to get on with the mentioned cartoon shader, or you need a full screen sobel edge shader.

ah yes sobel edge shader could work. Can anyone create that shader please?

Edit : or atleast port this one

http://dl.dropbox.com/u/3791129/SobelEdgeDetection.fx

Well, here is my try, but it only renders black and white aaand somehow borked:

Shader "Hidden/SobelEdge" {
Properties {
	_MainTex ("Base (RGB)", 2D) = "white" {}
}

SubShader {
	Pass {
		ZTest Always Cull Off ZWrite Off
		Fog { Mode off }
				
		CGPROGRAM
			#pragma vertex vert_img
			#pragma fragment frag
			#pragma fragmentoption ARB_precision_hint_fastest 
			#include "UnityCG.cginc"

			uniform sampler2D _MainTex;
			uniform float4 _MainTex_TexelSize;
			float threshold = 0.7;

			float4 frag (v2f_img i) : COLOR {
				float s00 = tex2D(_MainTex, i.uv + _MainTex_TexelSize * float2(-1, -1)).r;
				float s01 = tex2D(_MainTex, i.uv + _MainTex_TexelSize * float2( 0, -1)).r;
				float s02 = tex2D(_MainTex, i.uv + _MainTex_TexelSize * float2( 1, -1)).r;
				float s10 = tex2D(_MainTex, i.uv + _MainTex_TexelSize * float2(-1, 0)).r;
				float s12 = tex2D(_MainTex, i.uv + _MainTex_TexelSize * float2( 1, 0)).r;
				float s20 = tex2D(_MainTex, i.uv + _MainTex_TexelSize * float2(-1, 1)).r;
				float s21 = tex2D(_MainTex, i.uv + _MainTex_TexelSize * float2( 0, 1)).r;
				float s22 = tex2D(_MainTex, i.uv + _MainTex_TexelSize * float2( 1, 1)).r;
				
				float sobelX = s00 + 2 * s10 + s20 - s02 - 2 * s12 - s22;
				float sobelY = s00 + 2 * s01 + s02 - s20 - 2 * s21 - s22;
				
				float edgeSqr = (sobelX * sobelX + sobelY * sobelY);
				
				float4 result = edgeSqr;
				//result  *= 1.0 - ((edgeSqr > threshold) * threshold);
				return result;
			}
		ENDCG

	}
}

Fallback off

}

hmm its close to what I wish to achieve, but I definetely need more colors. Another method which I could think of is having edgeDetectnormal effect to the camera and have the edge width vary according to the distance from the camera. The problem with this approach is that the edgeDetectnormal script has a relatively large lower limit for edge width which looks bad when viewed from far off. Here is a pic of what I mean

http://dl.dropbox.com/u/3791129/edgedetectresults.png
(Near|Far)

If you have Pro (which would be needed for image effects anyway), why not just use the Edge Detect Effect Normals image effect?

I just mentioned the problem with Edge Detect Effect Normals in my previous post. The lowest edge width still looks bad when the model is viewed from a little far off distance.

Sorry - it didn’t register that edge detect normal effect you were talking about was the one in image effects. I obviously shouldn’t post on the first day of a new course of antibiotics :frowning:

Edit: it was the settings I was using.

To apologise for that mistake, I ported SobelEdgeDetection.fx into an image effect for you:)

491303–17270–$SobelEffect.unitypackage (2.92 KB)

Thanks Gaustwick :smile:

While the SobelEdgeDetection works really nice, there are some shortcomings with this approach as well.

  1. The edges are thicker in certain areas than they need to be.
  2. The color information is lost and everything is rendered in black and white.

In the shader I posted, I mixed the Sobel Effect back with the colour information - doesn’t it show up on your system? I certainly agree about the edges though :slight_smile:

nope the outlines just get color of the material. The rest is black colored.

Here’s a new version. It includes a second effect called InvertedSobelEffect, which is probably closer to what you’re looking for. (In full colour!)

491898–17287–$SobelEffect.unitypackage (3.53 KB)

Ah yes. Pretty much there. However still some lines are missing.

I need a shader that is able to outline the hard edges, which arise due to difference in smoothing groups.

How I’ve set up my smoothing groups in 3dsmax : http://dl.dropbox.com/u/3791129/Results/smoothinggroups.png

The outlines that show up using Ink n Paint material : http://dl.dropbox.com/u/3791129/Results/outline.png

The result I desire using this approach ( no textures ) : http://dl.dropbox.com/u/3791129/Results/colored.png

Try this one. It does the Sobel Effect with depth values. Again, you’ll want the inverted one. Unfortunately, this requires a PS3.0 capable card that can do depth textures.

492083–17302–$SobelEffect.unitypackage (5.04 KB)