Hello Unity community...heh that rimes well I am wondering if there is any colored specular shader out there for Unity (specular map as colored specular texture in RGB mode not grayscale). If so i would be happy if someone could give me link for it. Also if anyone is using it i would like to know if this shader is optimised and it does not ruin performance too much, considering that it will be used on every model. Also is Strumpy Shader Editor able to use colored specular maps? Is this shader editor optimised comparing to original Unity shaders? If not of what performance drop are we talking about? Thank you for all answers in advance.
Colored specular for Unity 3.x, here. Works both in forward deferred rendering: Code (csharp): Shader "Surface/Colored Specular" { Properties { _MainTex ("Texture", 2D) = "white" {} _SpecMap ("SpecMap", 2D) = "white" {} } SubShader { Tags { "RenderType" = "Opaque" } CGPROGRAM #pragma surface surf ColoredSpecular struct MySurfaceOutput { half3 Albedo; half3 Normal; half3 Emission; half Specular; half3 GlossColor; half Alpha; }; inline half4 LightingColoredSpecular (MySurfaceOutput s, half3 lightDir, half3 viewDir, half atten) { half3 h = normalize (lightDir + viewDir); half diff = max (0, dot (s.Normal, lightDir)); float nh = max (0, dot (s.Normal, h)); float spec = pow (nh, 32.0); half3 specCol = spec * s.GlossColor; half4 c; c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * specCol) * (atten * 2); c.a = s.Alpha; return c; } inline half4 LightingColoredSpecular_PrePass (MySurfaceOutput s, half4 light) { half3 spec = light.a * s.GlossColor; half4 c; c.rgb = (s.Albedo * light.rgb + light.rgb * spec); c.a = s.Alpha + spec * _SpecColor.a; return c; } struct Input { float2 uv_MainTex; float2 uv_SpecMap; }; sampler2D _MainTex; sampler2D _SpecMap; void surf (Input IN, inout MySurfaceOutput o) { o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb * 0.3; half4 spec = tex2D (_SpecMap, IN.uv_SpecMap); o.GlossColor = spec.rgb; o.Specular = 32.0/128.0; } ENDCG } Fallback "Diffuse" } This has some things simplified (i.e. specular power is hardcoded). Should be easy to add full capabilities of built-in specular shader, just with a colored gloss map.
Thanks for help Arash, however i am not a programmer and i have no idea where do i need to put shader code to get it work or how to create shader in Unity.
Copy / paste into a new text file, then save as "ColoredSpecular.shader" then drag and drop the file into your project explorer.(unity) then create newMaterial and , into the inspector select your shader (./Surface/Colored Specular) here you are... enjoy.
The built-in BlinnPhong lighting model declares _SpecColor outside the SurfaceOutput structure, as a uniform value. This means that you have to re-write the lighting model as Aras did in order to use a texture.
This works pretty well. Am I still incorrect? Code (csharp): Shader "Bumped ColoredSpecular" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1) _Shininess ("Shininess", Range (0.03, 1)) = 0.078125 _MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {} _BumpMap ("Normalmap", 2D) = "bump" {} _SpecTex ("Spec (RGB)", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 400 CGPROGRAM #pragma surface surf BlinnPhong sampler2D _MainTex; sampler2D _BumpMap; sampler2D _SpecTex; float4 _Color; //float4 _SpecColor; float _Shininess; struct Input { float2 uv_MainTex; float2 uv_BumpMap; }; void surf (Input IN, inout SurfaceOutput o) { half4 tex = tex2D(_MainTex, IN.uv_MainTex); half4 spectex = tex2D(_SpecTex, IN.uv_MainTex); _SpecColor = spectex; o.Albedo = tex.rgb * _Color.rgb; o.Gloss = tex.a; o.Alpha = tex.a * _Color.a; o.Specular = _Shininess; o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap)); } ENDCG } FallBack "Specular" }
Nobody has not answered if this given shader from Aras is optimised ,and also does it supports normal maps?
Could someone writte or extend shader code that Aras wrotte for colored specular shader for/with normal too?
This should work: Code (csharp): Shader "Surface/Colored Specular Bumped" { Properties { _MainTex ("Texture", 2D) = "white" {} _SpecMap ("SpecMap", 2D) = "white" {} _BumpMap ("Normalmap", 2D) = "bump" {} } SubShader { Tags { "RenderType" = "Opaque" } CGPROGRAM #pragma surface surf ColoredSpecular struct MySurfaceOutput { half3 Albedo; half3 Normal; half3 Emission; half Specular; half3 GlossColor; half Alpha; }; inline half4 LightingColoredSpecular (MySurfaceOutput s, half3 lightDir, half3 viewDir, half atten) { half3 h = normalize (lightDir + viewDir); half diff = max (0, dot (s.Normal, lightDir)); float nh = max (0, dot (s.Normal, h)); float spec = pow (nh, 32.0); half3 specCol = spec * s.GlossColor; half4 c; c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * specCol) * (atten * 2); c.a = s.Alpha; return c; } inline half4 LightingColoredSpecular_PrePass (MySurfaceOutput s, half4 light) { half3 spec = light.a * s.GlossColor; half4 c; c.rgb = (s.Albedo * light.rgb + light.rgb * spec); c.a = s.Alpha + spec * _SpecColor.a; return c; } struct Input { float2 uv_MainTex; float2 uv_SpecMap; float2 uv_BumpMap; }; sampler2D _MainTex; sampler2D _SpecMap; sampler2D _BumpMap; void surf (Input IN, inout MySurfaceOutput o) { o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb * 0.3; half4 spec = tex2D (_SpecMap, IN.uv_SpecMap); o.GlossColor = spec.rgb; o.Specular = 32.0/128.0; o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap)); } ENDCG } Fallback "Diffuse" }
thanx Aras and gaustwick for this shader! and thx janpec for bring up this topic! im working on a game with alot of sci fi materials, and the default unity bump specular doesnt show the normal mapped effects well at all! this one is much better! its very similar to the Maya Blinn shader than i am used to, awesome job guys! xD
I was asked for a version of this shader that supported illumination maps, so I had a go, and added shininess and global colour parameters whilst I was there The illumination map needs to be stuck in the specular map's alpha channel. Code (csharp): Shader "Surface/Colored Specular Bumped with Illumination" { Properties { _MainTex ("Texture", 2D) = "white" {} _SpecMap ("SpecMap(RGB) Illum(A)", 2D) = "white" {} _BumpMap ("Normalmap", 2D) = "bump" {} _Shininess ("Shininess", Range (0.01, 1)) = 0.078125 _Color ("Main Color", Color) = (1,1,1,1) } SubShader { Tags { "RenderType" = "Opaque" } CGPROGRAM #pragma surface surf ColoredSpecular struct MySurfaceOutput { half3 Albedo; half3 Normal; half3 Emission; half Specular; half3 GlossColor; half Alpha; }; inline half4 LightingColoredSpecular (MySurfaceOutput s, half3 lightDir, half3 viewDir, half atten) { half3 h = normalize (lightDir + viewDir); half diff = max (0, dot (s.Normal, lightDir)); float nh = max (0, dot (s.Normal, h)); float spec = pow (nh, 32.0 * s.Specular); half3 specCol = spec * s.GlossColor; half4 c; c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * specCol) * (atten * 2); c.a = s.Alpha; return c; } inline half4 LightingColoredSpecular_PrePass (MySurfaceOutput s, half4 light) { half3 spec = light.a * s.GlossColor; half4 c; c.rgb = (s.Albedo * light.rgb + light.rgb * spec); c.a = s.Alpha + spec * _SpecColor.a; return c; } struct Input { float2 uv_MainTex; float2 uv_SpecMap; float2 uv_BumpMap; }; sampler2D _MainTex; sampler2D _SpecMap; sampler2D _BumpMap; half4 _Color; half _Shininess; void surf (Input IN, inout MySurfaceOutput o) { half3 c = tex2D (_MainTex, IN.uv_MainTex).rgb * _Color.rgb; o.Albedo = c; half4 spec = tex2D (_SpecMap, IN.uv_SpecMap); o.GlossColor = spec.rgb; o.Emission = c * spec.a; o.Specular = _Shininess; o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap)); } ENDCG } Fallback "Diffuse" } And the same shader is in the attachments.
The posted shaders are all very helpful for a school project that I am currently working on, thank you for the hard work all of you! ^^ I have one thing that is missing from these shaders that would make it perfect for me, I have another regular shader that forces two-sided rendering(turns off culling). I've made attempts at combining the two shaders however they just don't seem compatable in any way(the double sided shader uses passes, while this shader doesn't. not sure on the specifics behind each, but neither seemed to work in the other >.>). The character I'm attempting to use this on has flat geometry that can be seen from both sides(cloak/ect.) and I would love to be able to use the colored specular shader with the double sided geometry if possible.
I have been trying for the last 2-3 hours with no success, how can I add Cutout with Cull Off to this Shader that you guys have come up with? BTW this is great and I am exited to be able to use! This is what I am using, no Normals or Specularity do. Code (csharp): Shader "Transparent/Cutout/Diffuse" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {} _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5 } SubShader { Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"} LOD 200 Cull Off CGPROGRAM #pragma surface surf Lambert alphatest:_Cutoff sampler2D _MainTex; fixed4 _Color; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color; o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG } Fallback "Transparent/Cutout/VertexLit" }
Attempting to use gaustwick's Colored Specular Bumped shader that i pulled from this thread, but the object seems to be rendering much darker than when using other shaders. Is this normal? A 90% white object is rendering a very dark grey color, other than that it seems to work great. When using the shader with added illumination included, the objects renders much more like it should. Any ideas as to what is causing this, or how to fix it? Should I just edit the shader w/ illumination and remove that property?
The dark effect comes from the albedo line: o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb * 0.3; Remove the "*0.3", it doesn't belong there.
Awesome thank you! Now if only it had a 'shininess' slider or preferably another texture input for a cosine/ glossiness map, then, perfection.
This should do the trick (not tested though, but all you have to do is to add a float parameter and replace both "32" value in the shader by the parameter name. Also don't forget to declare the value as half) You can make it as a Range if you want, but that's not as good as a Float parameter since it is less precise (and equally efficient): Code (csharp): Shader "Surface/Colored Specular Bumped" { Properties { _MainTex ("Texture", 2D) = "white" {} _SpecMap ("SpecMap", 2D) = "white" {} _BumpMap ("Normalmap", 2D) = "bump" {} _Shininess ("Specular Shininess", Float) = 32 } SubShader { Tags { "RenderType" = "Opaque" } CGPROGRAM #pragma surface surf ColoredSpecular half _Shininess; struct MySurfaceOutput { half3 Albedo; half3 Normal; half3 Emission; half Specular; half3 GlossColor; half Alpha; }; inline half4 LightingColoredSpecular (MySurfaceOutput s, half3 lightDir, half3 viewDir, half atten) { half3 h = normalize (lightDir + viewDir); half diff = max (0, dot (s.Normal, lightDir)); float nh = max (0, dot (s.Normal, h)); float spec = pow (nh, _Shininess); half3 specCol = spec * s.GlossColor; half4 c; c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * specCol) * (atten * 2); c.a = s.Alpha; return c; } inline half4 LightingColoredSpecular_PrePass (MySurfaceOutput s, half4 light) { half3 spec = light.a * s.GlossColor; half4 c; c.rgb = (s.Albedo * light.rgb + light.rgb * spec); c.a = s.Alpha + spec * _SpecColor.a; return c; } struct Input { float2 uv_MainTex; float2 uv_SpecMap; float2 uv_BumpMap; }; sampler2D _MainTex; sampler2D _SpecMap; sampler2D _BumpMap; void surf (Input IN, inout MySurfaceOutput o) { o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; half4 spec = tex2D (_SpecMap, IN.uv_SpecMap); o.GlossColor = spec.rgb; o.Specular = _Shininess/128.0; o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap)); } ENDCG } Fallback "Diffuse" }
I am using the shader from aras. Thank you for that! It's exactly what I was looking for. But in one scene it works great and in another scene the whole model is black. In both scenes i'm using one directional light. Maybe the shader doesn't get the light in the second scene? How could i debug this? Are there any prerequisites to fulfil to use this shader? Edit: In the second scene the built-in diffuse shader is working.
That is great! Is there any chance to get this colored specular bumb shader with a gloss slot to control the specularity?
Just modify the shader by adding the gloss sections of a normal specular shader and that should be solved
Sorry it took so long, as always, I have been ill. This shader should cover most eventualities: Code (csharp): Shader "Surface/Colored Specular Bumped wGloss" { Properties { _MainTex ("Texture(RGB) Gloss(A)", 2D) = "white" {} _SpecMap ("SpecMap", 2D) = "white" {} _BumpMap ("Normalmap", 2D) = "bump" {} _Shininess ("Shininess", Range (0.01, 1)) = 0.078125 } SubShader { Tags { "RenderType" = "Opaque" } CGPROGRAM #pragma surface surf ColoredSpecular struct MySurfaceOutput { half3 Albedo; half3 Normal; half3 Emission; half Specular; half3 GlossColor; half Gloss; half Alpha; }; inline half4 LightingColoredSpecular (MySurfaceOutput s, half3 lightDir, half3 viewDir, half atten) { half3 h = normalize (lightDir + viewDir); half diff = max (0, dot (s.Normal, lightDir)); float nh = max (0, dot (s.Normal, h)); float spec = pow (nh, s.Specular * 128.0f) * s.Gloss; half3 specCol = spec * s.GlossColor; half4 c; c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * specCol) * (atten * 2); c.a = s.Alpha; return c; } inline half4 LightingColoredSpecular_PrePass (MySurfaceOutput s, half4 light) { half3 spec = light.a * s.GlossColor * s.Gloss; half4 c; c.rgb = (s.Albedo * light.rgb + light.rgb * spec); c.a = s.Alpha + spec * _SpecColor.a; return c; } struct Input { float2 uv_MainTex; float2 uv_SpecMap; float2 uv_BumpMap; }; sampler2D _MainTex; sampler2D _SpecMap; sampler2D _BumpMap; half _Shininess; void surf (Input IN, inout MySurfaceOutput o) { float4 diff = tex2D (_MainTex, IN.uv_MainTex); o.Albedo = diff.rgb; half4 spec = tex2D (_SpecMap, IN.uv_SpecMap); o.GlossColor = spec.rgb; o.Gloss = diff.a; o.Specular = _Shininess; o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap)); } ENDCG } Fallback "Diffuse" }
Hey All, great thread with a lot of good info. I am trying to create a shader which combines the colored spec from this thread with the TeamFortress2Shader toon shader found here http://wiki.unity3d.com/index.php/TeamFortress2Shader I've mostly got it working, but the one last thing I can't figure out is that I want to be able to control the gloss/polish/tightness of the specular highlight using a texture (namely the alpha of the specular texture) instead of a slider as it is now. Since I'm not an engineer, I don't really understand how to create/alter custom lighting models as found in these shaders, making it hard to do this! If anyone could help me out with this, I'd be hugely thankful! Code (csharp): Shader "Toon_Colored_Spec" { Properties { _RimColor ("Fresnel Color", Color) = (0.26,0.19,0.16,0.0) _RimPower ("Fresnel Power", Range(0.5,8.0)) = 3.0 _Shininess ("Polish", Range (.01, 5)) = 0.5 _MainTex ("Texture", 2D) = "white" {} _SpecMap ("Specular Color (RGB), Specular Polish (A)", 2D) = "white" {} _BumpMap ("Normalmap", 2D) = "bump" {} _Ramp ("Toon Ramp (RGB)", 2D) = "gray" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Toon #pragma target 3.0 sampler2D _SpecMap; sampler2D _MainTex; sampler2D _BumpMap; sampler2D _Ramp; float4 _Color; float4 _RimColor; float _RimPower; half _Shininess; struct ToonSurfaceOutput { half3 Albedo; half3 Normal; half3 Emission; half Specular; half3 GlossColor; half Alpha; }; inline half4 LightingToon (ToonSurfaceOutput s, half3 lightDir, half3 viewDir, half atten){ fixed3 h = normalize (lightDir + viewDir); fixed NdotL = dot(s.Normal, lightDir) * 0.5 + 0.5; fixed3 ramp = tex2D(_Ramp, float2(NdotL * atten)).rgb; float nh = max (0, dot (s.Normal, h)); float spec = pow (nh, s.GlossColor * _Shininess * 2048); half3 specCol = spec * s.GlossColor; fixed4 c; c.rgb = ((s.Albedo * ramp * _LightColor0.rgb + _LightColor0.rgb * specCol) * (atten * 2)); return c; } struct Input { float2 uv_MainTex; float2 uv_SpecMap; float2 uv_BumpMap; float3 viewDir; INTERNAL_DATA }; void surf (Input IN, inout ToonSurfaceOutput o){ half4 specTex = tex2D (_SpecMap, IN.uv_SpecMap); o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb; o.GlossColor = specTex; o.Specular = _Shininess; o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap)); half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal)); o.Emission = _RimColor.rgb * pow (rim, _RimPower); } ENDCG } Fallback "Diffuse" }
Hi Friends I am new in shader programming, I copied that shader and tried to my game, I assumes LightingColoredSpecular_PrePass method call by default at some time, I have checked with commenting this method and it;s will not gives any difference in device or editor mode. can any one describe how that method are utilised in shading language....? When I trying this shader, I also note one more thing, what ever surface i used this shader, those all surface are not able receive shadow in editor mode, but it receive shadow in Device (I am using iPad 3rd Gen with Unity 4.x) here my shader Code (csharp): Shader "Custom/Vertex Sepcular with Specular Map" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _SpecColor ("Specular Color", Color) = (0.5859375, 0.5859375, 0.5859375, 1) _Shininess ("Shininess", float) = 32 _MainTex ("Texture (RGB)", 2D) = "white" {} _BlendTex ("Detail Map (RGB), Gloss (A)" , 2D) = "white" {} _BlendDetail("Detail Tiling",vector) = (1,1,1,1) _Blend ("Blend Range",float) = 1 } SubShader { Tags { "Queue"="Geometry" "IgnoreProjector"="False" "RenderType"="Opaque"} LOD 200 CGPROGRAM #pragma surface surf ColoredSpecular //vertex:vert //finalcolor:mycolor #include "UnityCG.cginc" fixed4 _Color; sampler2D _MainTex; sampler2D _BlendTex; float _Blend; float _Shininess; float4 _BlendDetail; struct MySurfaceOutput { half3 Albedo; half3 Normal; half3 Emission; half Specular; half3 Gloss; half Alpha; }; struct Input { float2 uv_MainTex; float2 uv_BlendTex; }; //void vert (inout appdata_full v, out Input o) { //} inline half4 LightingColoredSpecular_PrePass (MySurfaceOutput s, half4 light) { half3 spec = light.a * s.Gloss; half4 c; c.rgb = (s.Albedo * light.rgb + light.rgb * spec); c.a = s.Alpha + spec * _SpecColor.a; return c; } inline half4 LightingColoredSpecular (MySurfaceOutput s, half3 lightDir, half3 viewDir, half atten) { half3 h = normalize (lightDir + viewDir); half diff = max (0, dot (s.Normal, lightDir)); float nh = max (0, dot (s.Normal, h)); float spec = pow (nh, s.Specular * 128); half3 specCol = spec * s.Gloss; half4 c; c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * specCol) * (atten * 2) * _SpecColor; c.a = s.Alpha; return c; } void surf (Input IN, inout MySurfaceOutput o) { fixed4 mt = tex2D(_MainTex, IN.uv_MainTex); float2 swapUVs = IN.uv_BlendTex ; swapUVs *= _BlendDetail.xy; fixed4 bt = tex2D(_BlendTex, swapUVs); o.Albedo = mt.rgb * (bt.rgb * _Blend) * _Color.rgb; o.Gloss = bt.a; o.Specular = _Shininess/128; } ENDCG } }
Heya! Played around with the shaders here and they work pretty well! I was wondering if it was possible to pack Diffuse, Normals AND colored Spec sprites together, without having to have 1 material per Colored Bumped Spec Sprite. I know it's possible to use the Alpha channel of the Diffuse (thus dropping any semi-transparency) as the spec values but that is only for mono-chromatic specs. How about RGB specs? How could that be done?