I’m just starting out with Unity and I was quite surprised to find out that Unity (free version) doesn’t ship with this shader. I’m in need of a shader that uses the following texture maps:
- Diffuse
- Normal
- Ambient occlusion
- Specular
- Specular hardness/gloss map
- Specular color
I found Strumpy Shader Editor and managed to do most of these with it but I’m having trouble with the specular color map as well as the ambient occlusion. Below is the shader I made with the shader editor.
Shader "RealShader"
{
Properties
{
_diffuse("Diffuse map", 2D) = "gray" {}
_normal("Normal map", 2D) = "bump" {}
_specularhardness("Specular hardness map", 2D) = "white" {}
_specular("Specular power map", 2D) = "white" {}
}
SubShader
{
Tags
{
"Queue"="Geometry"
"IgnoreProjector"="False"
"RenderType"="Opaque"
}
Cull Back
ZWrite On
ZTest LEqual
ColorMask RGBA
Fog{
}
CGPROGRAM
#pragma surface surf BlinnPhongEditor vertex:vert
#pragma target 3.0
sampler2D _diffuse;
sampler2D _normal;
sampler2D _specularhardness;
sampler2D _specular;
struct EditorSurfaceOutput {
half3 Albedo;
half3 Normal;
half3 Emission;
half3 Gloss;
half Specular;
half Alpha;
half4 Custom;
};
inline half4 LightingBlinnPhongEditor_PrePass (EditorSurfaceOutput s, half4 light)
{
half3 spec = light.a * s.Gloss;
half4 c;
c.rgb = (s.Albedo * light.rgb + light.rgb * spec);
c.a = s.Alpha;
return c;
}
inline half4 LightingBlinnPhongEditor (EditorSurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
{
half3 h = normalize (lightDir + viewDir);
half diff = max (0, dot ( lightDir, s.Normal ));
float nh = max (0, dot (s.Normal, h));
float spec = pow (nh, s.Specular*128.0);
half4 res;
res.rgb = _LightColor0.rgb * diff;
res.w = spec * Luminance (_LightColor0.rgb);
res *= atten * 2.0;
return LightingBlinnPhongEditor_PrePass( s, res );
}
struct Input {
float2 uv_diffuse;
float2 uv_normal;
float2 uv_specularhardness;
float2 uv_specular;
};
void vert (inout appdata_full v, out Input o) {
float4 VertexOutputMaster0_0_NoInput = float4(0,0,0,0);
float4 VertexOutputMaster0_1_NoInput = float4(0,0,0,0);
float4 VertexOutputMaster0_2_NoInput = float4(0,0,0,0);
float4 VertexOutputMaster0_3_NoInput = float4(0,0,0,0);
}
void surf (Input IN, inout EditorSurfaceOutput o) {
o.Normal = float3(0.0,0.0,1.0);
o.Alpha = 1.0;
o.Albedo = 0.0;
o.Emission = 0.0;
o.Gloss = 0.0;
o.Specular = 0.0;
o.Custom = 0.0;
float4 Tex2D0=tex2D(_diffuse,(IN.uv_diffuse.xyxy).xy);
float4 Tex2D1=tex2D(_normal,(IN.uv_normal.xyxy).xy);
float4 UnpackNormal0=float4(UnpackNormal(Tex2D1).xyz, 1.0);
float4 Tex2D2=tex2D(_specularhardness,(IN.uv_specularhardness.xyxy).xy);
float4 Tex2D3=tex2D(_specular,(IN.uv_specular.xyxy).xy);
float4 Master0_2_NoInput = float4(0,0,0,0);
float4 Master0_5_NoInput = float4(1,1,1,1);
float4 Master0_7_NoInput = float4(0,0,0,0);
float4 Master0_6_NoInput = float4(1,1,1,1);
o.Albedo = Tex2D0;
o.Normal = UnpackNormal0;
o.Specular = Tex2D2;
o.Gloss = Tex2D3;
o.Normal = normalize(o.Normal);
}
ENDCG
}
Fallback "Diffuse"
}
I have no idea how I would add the ambient occlusion texture to that. It only needs to have the diffuse texture be multiplied (as in the math function) by the AO texture.
Below is a specular + specular color + normal shader I found on the forums. I would somehow need to combine the specular color part with the shader above but I have no clue how to.
Shader "Bumped Color Specular" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_Shininess ("Shininess", Range (0.03, 1)) = 0.078125
_MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
_BumpMap ("Bumpmap (RGB)", 2D) = "bump" {}
_SpecMap ("Spec map (RGB)", 2D) = "white" {}
}
Category {
Blend AppSrcAdd AppDstAdd
Fog { Color [_AddFog] }
Tags { "RenderType"="Opaque" }
SubShader {
// Ambient pass
Pass {
Name "BASE"
Tags {"LightMode" = "PixelOrNone"}
Blend AppSrcAdd AppDstAdd
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]
}
CGPROGRAM
#pragma fragment frag
#pragma fragmentoption ARB_fog_exp2
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
half4 frag (v2f_vertex_lit i) : COLOR {
return VertexLight( i, _MainTex );
}
ENDCG
}
// Pixel lights
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
float3 uvK; // xy = UV, z = specular K
float4 uv2; // bumpmap UV, specmap UV
float3 viewDirT;
float3 lightDirT;
};
uniform float4 _MainTex_ST, _BumpMap_ST, _SpecMap_ST;
uniform float _Shininess;
v2f vert (appdata_tan v)
{
v2f o;
PositionFog( v.vertex, o.pos, o.fog );
o.uvK.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
o.uvK.z = _Shininess * 128;
o.uv2.xy = TRANSFORM_TEX(v.texcoord, _BumpMap);
o.uv2.zw = TRANSFORM_TEX(v.texcoord, _SpecMap);
TANGENT_SPACE_ROTATION;
o.lightDirT = mul( rotation, ObjSpaceLightDir( v.vertex ) );
o.viewDirT = mul( rotation, ObjSpaceViewDir( v.vertex ) );
TRANSFER_VERTEX_TO_FRAGMENT(o);
return o;
}
uniform sampler2D _BumpMap;
uniform sampler2D _MainTex;
uniform sampler2D _SpecMap;
uniform float4 _LightColor0;
// Calculates Blinn-Phong (specular) lighting model
inline half4 SpecularColorLight( half3 lightDir, half3 viewDir, half3 normal, half4 color, half4 specColor, float specK, half atten )
{
#ifndef USING_DIRECTIONAL_LIGHT
lightDir = normalize(lightDir);
#endif
viewDir = normalize(viewDir);
half3 h = normalize( lightDir + viewDir );
half diffuse = dot( normal, lightDir );
float nh = saturate( dot( h, normal ) );
float spec = pow( nh, specK ) * color.a;
half4 c;
c.rgb = (color.rgb * _ModelLightColor0.rgb * diffuse + _LightColor0.rgb * specColor.rgb * spec) * (atten * 2);
c.a = _LightColor0.a * specColor.a * spec * atten; // specular passes by default put highlights to overbright
return c;
}
half4 frag (v2f i) : COLOR
{
half4 texcol = tex2D( _MainTex, i.uvK.xy );
half4 speccol = tex2D( _SpecMap, i.uv2.zw );
float3 normal = tex2D(_BumpMap, i.uv2.xy).xyz * 2.0 - 1.0;
half4 c = SpecularColorLight( i.lightDirT, i.viewDirT, normal, texcol, speccol, i.uvK.z, LIGHT_ATTENUATION(i) );
return c;
}
ENDCG
}
}
}
FallBack "Diffuse"
}
I’m essentially asking if someone who actually knows this shader script could combine the specular color to my shader and add in the ambient occlusion part.