Skin Shader for U3, need help with converting.

Hi guys;

I haven’t posted in a while, I’m working day and night on my game, and improving as I go through. Unity’s user community is just fascinating, I never really had to ask for anything, the answers are already there or I could improvise on proven solutions to fix my own problems only this time it concerns shaders. I don’t know anything about writing or modifying shaders so I just had to ask;

There’s this fantastic shader at the Unify site, and it’s a pixel shader. I cannot convert it into a surface shader… :frowning:

I’ve tried my best converting it but with no luck, and have really no other option but to bother you guys :p…
Can anyone help me update this shader? I guess it would do the entire community some good as well?

Thanks in advance;

ScarletSnake

By the way, for anyone who was following my project, I believe you’re going to like what you’re going to see in the following months :).

I’ve been messing with the Node Shader editor and I believe I’ve created a shader somewhat similar to the skin shader in 2.6. Take a look:

If you guys are interested I’ll post in on the Unify Shaders page, along with the necessary images and sgraph for future modifications.

Anyone interested in helping me finalize this shader? It’s not complete.

Is there anyone besides me who’s interesed in the future of this shader? Or is there an upcoming release of the skin shader that I’m unaware of? I guess the part I’m having trouble is with the clamped wrap ramp texture, anyone lend a hand?

Hey there,
I just found your post while looking for the same thing. Although I’d even be happy about a updated/converted version of the original SkinShader http://www.unifycommunity.com/wiki/index.php?title=SkinShader.

Did you succeed in rewriting the shader?

Cheers,
Hatschupp

Have you tried posting on either of the Node based shader editor pages? Your right, this deserves some real attention. That Unreal shader is well made.

Hi there,
I’m currently working on an adaptation of this Skin shader for Unity 3. But since I’m not a shader expert, I would need some help!

Here is my current code for the Skin Bumped Specular:

Shader "Skin/Bumped Specular for Unity 3" {
Properties {
	_Color ("Main Color", Color) = (1,1,1,1)
	_SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
	_Shininess ("Shininess", Range (0.01, 1)) = 0.078125
	_MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
	_BumpMap ("Bump (RGB)", 2D) = "white" {}
	_RimTex ("Rim ramp (RGB) Fresnel ramp (A)", 2D) = " grey" {}
	_WrapTex ("Wrap ramp (RGBA)", 2D) = "grey" {}
}
 
SubShader {
	Tags { "RenderType" = "Opaque" }
        
CGPROGRAM
#pragma surface surf BumpSpecSkin
#include "UnityCG.cginc"

uniform float4 _Color;
uniform float _Shininess;
uniform sampler2D _MainTex;
uniform sampler2D _WrapTex;
uniform sampler2D _RimTex;
uniform sampler2D _BumpMap;

half4 LightingBumpSpecSkin (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) {
	// rim factor (rim ramp texture should be set to clamp mode, and not repeat mode)
	float rimf = dot(s.Normal, viewDir);
	half4 rim = tex2D (_RimTex, rimf.xx);
	
	half3 h = normalize( lightDir + viewDir );
	
	// This is "wrap diffuse" lighting.
	// What we do here is to calculate the color, then look up the wrap coloring ramp so you can tint things properly
	half diffusePos = dot(s.Normal, lightDir) * 0.5 + 0.5;
	half4 diffuse = tex2D (_WrapTex, diffusePos.xx);
	diffuse.rgb *= rim.rgb * 4;
	
	float nh = saturate( dot( h, s.Normal ) );
	float spec = pow( nh, s.Specular ) * s.Gloss;

	half4 c;
	c.rgb = (s.Albedo * _LightColor0.rgb * diffuse + _SpecColor.rgb * spec * rim.a) * (atten * 2);
	// specular passes by default put highlights to overbright
	c.a = _SpecColor.a * spec * atten;
	
	half3 ambient = s.Albedo * (UNITY_LIGHTMODEL_AMBIENT.rgb * 2 * rim.rgb);

	return 0.5*(half4( ambient, 1.0) + c) * _Color ; // additive blending, then mult blending with _Color
}

struct Input {
	float2 uv_MainTex;
	float2 uv_BumpMap;
};

void surf (Input IN, inout SurfaceOutput o) {
	half4 texcol = tex2D( _MainTex, IN.uv_MainTex);	
	o.Albedo = texcol.rgb;
	o.Gloss = texcol.a;
	o.Specular = _Shininess * 128;
	o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
}

ENDCG

}


Fallback " Glossy", 0
 
}

It’s working fine for me, but I’m not sure the results are similar to the Skin Shader 2 for Unity 2.6…
Any feedback would be greatly appreciated!

Edit: there’s an updated version below!

The shader only supports Directional light shadow makes!

Yes, you’re right pgomid3000. I should have mention that, from the Unity 3.1 manual:

“Forward rendering path supports only one directional shadow casting light.”

I would be interested in an update skin shader from the version 2 that was on the unifycommunity.com site. Contact me if you have an example.

OK, here’s a new version with some minor changes: I’ve removed the 0.5 factor and the ambient part (back of objects were too bright), and also I changed the way light and diffuse affect specular (because there were a wrong specular reflection at the back of the objects).

Shader "Skin for Unity 3/Bumped Specular" {
Properties {
	_Color ("Main Color", Color) = (1,1,1,1)
	_SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
	_Shininess ("Shininess", Range (0.01, 1)) = 0.078125
	_MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
	_BumpMap ("Bump (RGB)", 2D) = "bump" {}
	_RimTex ("Rim ramp (RGB) Fresnel ramp (A)", 2D) = " grey" {}
	_WrapTex ("Wrap ramp (RGBA)", 2D) = "black" {}
}
 
SubShader {
	Tags { "RenderType" = "Opaque" }
    LOD 400
    
CGPROGRAM
#pragma surface surf BumpSpecSkin

uniform float4 _Color;
uniform float _Shininess;
uniform sampler2D _MainTex;
uniform sampler2D _WrapTex;
uniform sampler2D _RimTex;
uniform sampler2D _BumpMap;

half4 LightingBumpSpecSkin (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) {
	// rim factor
	float rimf = dot(s.Normal, viewDir);
	half4 rim = tex2D (_RimTex, rimf.xx);
	
	half3 h = normalize( lightDir + viewDir );
	
	// This is "wrap diffuse" lighting.
	// What we do here is to calculate the color, then look up the wrap coloring ramp so you can tint things properly
	half diffusePos = dot(s.Normal, lightDir) * 0.5 + 0.5;
	half4 diffuse = tex2D (_WrapTex, diffusePos.xx);
	diffuse.rgb *= rim.rgb * 4;
	
	float nh = saturate( dot( h, s.Normal ) );
	float spec = pow( nh, s.Specular ) * s.Gloss;

	half4 c;
	c.rgb = (s.Albedo + _SpecColor.rgb * spec * rim.a) * diffuse * (atten * 2) * _LightColor0.rgb;
	// specular passes by default put highlights to overbright
	c.a =  _LightColor0.a * _SpecColor.a * spec * atten;
	
	return c * _Color;
}

struct Input {
	float2 uv_MainTex;
	float2 uv_BumpMap;
};

void surf (Input IN, inout SurfaceOutput o) {
	half4 texcol = tex2D( _MainTex, IN.uv_MainTex);	
	o.Albedo = texcol.rgb;
	o.Gloss = texcol.a;
	o.Specular = _Shininess * 128;
	o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
}

ENDCG

}

And now some nice images using the great model from Infinite, 3D Head Scan by Lee Perry-Smith (http://www.ir-ltd.net/blog/).

The model on the left is rendered with a classic Bumped Specular shader, while the right model is rendered using the skin shader:

Front directional light

Left directional light

Light from below

Directional light with soft shadows

Thank you bournifle.
That will be useful.

And here is the unity package I built for the previous post images:

http://dl.dropbox.com/u/12552166/Unity/SkinShader%20for%20Unity%203/SkinProjectForUnity3.unitypackage

Import it and open the scene in SkinProject/Scenes.

Important note: if you make your own rim and wrap ramps, set the Wrap mode to “Clamp” instead of “Repeat” in the inspector.
Also, right of rim ramp should be a 64 grey (see here for an explanation).

@elias_t: you’re welcome!

Hi;

Because of technical issues I haven’t been able to view this page properly, but now that I have, I’ve downloaded the shader and voila!

Obviously, the one on the left is bournifle’s shader and the one on the right is the standard bumped specular. And yes, that’s my face.
Thanks a bunch bournifle! This was the essential shader for my game, and I’m sure you’ve helped many others by releasing it.

Cheers;

ScarletSnake

Oh, and by the way, pics dont have shadows, I’m still working with the free version of Unity.

Really nice work on that shader. Scarletsnake nice work on yourself model and texture , but the bumped specular model seem to have specular map with some artifacs in it or some seams. Or did you possibly add reflection on it?

Yeah, It’s because of the bump maps, you are right there are artifacts in it, the model texture were originally created for use exclusively with the 2.0 skin shader, so that some parts are more aggressive in terms of bump-mapping, when they are brought down to just bumped specular you do get unwanted details here and there, the head model itself is just 1500polys, so that may be the issue as well :). Something else that’s worth mentioning here is that the lighting was built specifically to give my unsuccessul skin shader attempt a boost, I’m going to have to re-light everything now.

Edit: Here’s with some new lighting:

I’m using reflective bumped specular for the eyes with a generic cubemap, while we’re on the subject of realistic human rendering, anyone have any other ideas to get better, or more realistic eyes on characters?

Nice work scarletsnake! Glad the shader was useful to you!

Unfortunately, I’ve encountered some problems with this shader when using shadows… I don’t know if it’s a bug or not… I’m going to start a new thread about that in the coming days.

With new lighting skin looks even better.

Great work guys!!!

BUT I have noticed at small problem with the shadow on the new skin shader!!

… the shadows on your skin shader seem to be “jagged/poligonized” compared to the traditional bumped map shader!!!

See image for “visual explanation” (the model on the left is the one with the new skin shader applied)

Yes slidingcarlos, I’ve noticed this problem too… :frowning:

IMHO the reason is that this shader is lighting the back of the objects, where there should be only shadow… (hence revealing some optimizations in the shadow computation ?)

I don’t know how to solve this problem… is it a bug or are we missing something ?