Double Sided *Material*

Hi everyone!

I really need to be able to create a double sided material.

For example one face (two tris, 1 poly) that shows the material on the reverse side of it.

I know alot of people have enquired about this, but i really can’t afford to physically have the reverse side as part of the geometry.

My actual question is, does unity support this type of material option and if so does it need to be scripted in or is there a prefab or a shader that someone has made that is able to do it

Any info regarding this would be amazing!

Many thanks

This has been asked and answered many times…a search will easily find the solution.

–Eric

If you don’t need lighting to work properly, rendering backfaces as well as front faces is easy. Check out either of these shaders:

http://www.unifycommunity.com/wiki/index.php?title=UnlitAlpha
http://www.unifycommunity.com/wiki/index.php?title=VegetationVertexLit

If you want lighting to work properly, you’ll have to use a shader that does two passes: one with backface culling and no changes to normals, and one with frontface culling and flipped normals.

1 Like

Hi eric

Thank you for your insightful response, maybe if i had spent time making four thousand and something posts i may recall a vague reference to it, but unfortunately i have just the two posts for now.

I have looked alot using the search and all i can find is information from people that don’t really seem to actually know the answer to my specific question and just describe physically making another polygon mirrored fr the solution to a two sided material.

i.e.

“I know alot of people have enquired about this, but i really can’t afford to physically have the reverse side as part of the geometry.”

if you can find a post relating to the material settings i need to use that can answer my question, you may receive a gold star.

or

you may not

either way don’t make condescending posts for the sake of it, its slightly immature, and will waste a lot of your time. Much appreciated.

But to anyone else that may be able to help, i would love some constructive feedback it will help alot as i really can not find any information relating to this and i felt posting a more specific question would be more efficient.

Many thanks

Kind regards

7 Likes

Hi Muriac,

Thank you very very much! ill look into that then, i wasn’t sure on what avenue to approach on this. But this will really help.

Thanks so much!

My post was not condescending, it was factual. If you do a search on “double-sided”, you get many relevant results. This is to your benefit, since you would have instantly gotten your answer without having to wait for a reply. Please refrain from reading negative intent into posts where there isn’t any.

–Eric

1 Like

I don’t think Eric’s response was inappropriate – this really has been asked before. And that comes up through searching.

Here am I, a complete newb, having to answer such a popular question, shame on you!!! :smile: jk
here is my code for a DoubleSided Shader mate. Not like the ones Eric posted, this one is for any model, lighted or not:

Shader "DoubleSided" {
	Properties {
		_Color ("Main Color", Color) = (1,1,1,1)
		_MainTex ("Base (RGB)", 2D) = "white" {}
		//_BumpMap ("Bump (RGB) Illumin (A)", 2D) = "bump" {}
	}
	SubShader {		
		//UsePass "Self-Illumin/VertexLit/BASE"
		//UsePass "Bumped Diffuse/PPL"
		
		// Ambient pass
		Pass {
		Name "BASE"
		Tags {"LightMode" = "PixelOrNone"}
		Color [_PPLAmbient]
		SetTexture [_BumpMap] {
			constantColor (.5,.5,.5)
			combine constant lerp (texture) previous
			}
		SetTexture [_MainTex] {
			constantColor [_Color]
			Combine texture * previous DOUBLE, texture*constant
			}
		}
	
	// Vertex lights
	Pass {
		Name "BASE"
		Tags {"LightMode" = "Vertex"}
		Material {
			Diffuse [_Color]
			Emission [_PPLAmbient]
			Shininess [_Shininess]
			Specular [_SpecColor]
			}
		SeparateSpecular On
		Lighting On
		Cull Off
		SetTexture [_BumpMap] {
			constantColor (.5,.5,.5)
			combine constant lerp (texture) previous
			}
		SetTexture [_MainTex] {
			Combine texture * previous DOUBLE, texture*primary
			}
		}
	} 
	FallBack "Diffuse", 1
}

[/code]

11 Likes

Thanks guys :smile:

This gets asked/answered so often, i think it’s worth Unity looking into providing this functionality with the standard assets package.

7 Likes

PS: What part of that shader code actually renders it double-sided?

I wish more shader source had comments in them; I feel lost trying to figure it out.

…SeparateSpecular On
Lighting On
Cull Off

Just the cull off part

Wow, so you can take any shader with Cull off, remove that line, and you get double-sided?

Seems like comments in the default shader code could cut down this problem being asked/answered so often.

Actually, is not taking that line off. It is more like:
Cull On //Don’t render “inner” faces
Cull Off // Render double-sided

1 Like

It would be EXTREMELY helpful to have a simple “on/off” button next to the shader for this function…

This is giving me shades of TGEA nauseum.

The possible arguments to Cull are actually:

Back
Front
Off

Where Back is the default.

The problem with simply turning off backface culling is that lighting won’t work properly. If you use the shader provided above on a plane, you’ll notice that both sides are always the same brightness as one another, no matter where the light source is. This is because when back faces are rendered, they use the same mesh normals as the front faces. Mesh normals are almost always calculated for front faces, and so lighting for back faces will be wrong and ugly.

It’s not a difficult problem, but it’s not as easy as just turning off culling.

1 Like

Ow, I never actually coded for it to be only back sided or fof, so I didn’t know, sorry…:frowning:

If I have time, I’ll try and make a shader that does lighting of back faces properly. Can’t promise anything for a few days, though.

First attempt only works with pixel lights that don’t have shadows:

Shader "Diffuse" {
Properties {
	_Color ("Main Color", Color) = (1,1,1,1)
	_MainTex ("Base (RGB)", 2D) = "white" {}
}

Category {
	Blend AppSrcAdd AppDstAdd
	Fog { Color [_AddFog] }
	
	SubShader {
		// Ambient pass
		Pass {
			Name "BASE"
			Tags {"LightMode" = "PixelOrNone"}
			Cull Off
			Color [_PPLAmbient]
			SetTexture [_MainTex] {constantColor [_Color] Combine texture * primary DOUBLE, texture * constant}
		}
		// Vertex lights
		// Pass { 
		// 	Name "BASE"
		// 	Tags {"LightMode" = "Vertex"}
		// 	Lighting On
		// 	Material {
		// 		Diffuse [_Color]
		// 		Emission [_PPLAmbient]
		// 	}
		// 	SetTexture [_MainTex] { constantColor [_Color] Combine texture * primary DOUBLE, texture * constant}
		// }
		// Pixel lights front
		Pass {
			Name "PPL"
			Tags { "LightMode" = "Pixel" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_builtin
#pragma fragmentoption ARB_fog_exp2
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
#include "AutoLight.cginc"

struct v2f {
	V2F_POS_FOG;
	LIGHTING_COORDS
	float2	uv;
	float3	normal;
	float3	lightDir;
};

uniform float4 _MainTex_ST;

v2f vert (appdata_base v)
{
	v2f o;
	PositionFog( v.vertex, o.pos, o.fog );
	o.normal = v.normal;
	o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
	o.lightDir = ObjSpaceLightDir( v.vertex );
	TRANSFER_VERTEX_TO_FRAGMENT(o);
	return o;
}

uniform sampler2D _MainTex;

float4 frag (v2f i) : COLOR
{
	// The eternal tradeoff: do we normalize the normal?
	//float3 normal = normalize(i.normal);
	float3 normal = i.normal;
		
	half4 texcol = tex2D( _MainTex, i.uv );
	
	return DiffuseLight( i.lightDir, normal, texcol, LIGHT_ATTENUATION(i) );
}
ENDCG
		}
			// Pixel lights back
		Pass {
			Name "PPL"
			Cull Front
			Tags { "LightMode" = "Pixel" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_builtin
#pragma fragmentoption ARB_fog_exp2
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
#include "AutoLight.cginc"

struct v2f {
	V2F_POS_FOG;
	LIGHTING_COORDS
	float2	uv;
	float3	normal;
	float3	lightDir;
};

uniform float4 _MainTex_ST;

v2f vert (appdata_base v)
{
	v2f o;
	PositionFog( v.vertex, o.pos, o.fog );
	o.normal = -v.normal;
	o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
	o.lightDir = ObjSpaceLightDir( v.vertex );
	TRANSFER_VERTEX_TO_FRAGMENT(o);
	return o;
}

uniform sampler2D _MainTex;

float4 frag (v2f i) : COLOR
{
	// The eternal tradeoff: do we normalize the normal?
	//float3 normal = normalize(i.normal);
	float3 normal = i.normal;
		
	half4 texcol = tex2D( _MainTex, i.uv );
	
	return DiffuseLight( i.lightDir, normal, texcol, LIGHT_ATTENUATION(i) );
}
ENDCG
		}
	}
}

Fallback "VertexLit", 2

}

your shader light’s direction was wrong.