Make shader Specular Only

I’m trying to make a shader specular only with bumps and everything to fake the light reflection on water. I’ve been using particles to fake the color of the water and the soft edges so I want the whole shader to be invisible except for the specular.

Here’s what the shader looks like now, which is pretty much just a modified AlphaBumpedSpec basic shader in Unity :

Shader "Water/CustomWaterShader" {
Properties {
	_Color ("Main Color", Color) = (1,1,1,1)
	_SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 0)
	_Shininess ("Shininess", Range (0.01, 1)) = 0.078125
	_MainTex ("Base (RGB) TransGloss (A)", 2D) = "white" {}
	_BumpMap ("Normalmap", 2D) = "bump" {}
	_BumpMap2 ("Normalmap", 2D) = "bump" {}
}

SubShader {
	Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
	LOD 400
	
	
CGPROGRAM
#pragma surface surf BlinnPhong alpha

sampler2D _MainTex;
sampler2D _BumpMap;
sampler2D _BumpMap2;
fixed4 _Color;
half _Shininess;

struct Input {
	float2 uv_MainTex;
	float2 uv_BumpMap;
	float2 uv_BumpMap2;
};

void surf (Input IN, inout SurfaceOutput o) {
	fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
	o.Albedo = tex.rgb * _Color.rgb;
	o.Alpha = tex.a * _Color.a;
	o.Gloss = 50;
	o.Specular = _Shininess;
	o.Normal = UnpackNormal(tex2D(_BumpMap , IN.uv_BumpMap)/2 + tex2D(_BumpMap2 , IN.uv_BumpMap2)/2);
}
ENDCG
}

FallBack "Transparent/VertexLit"
}

So, is there an easy way to change this shader into a specular only shader?

1 Answer

1

You can achieve a transparency effect by using GrabPass to grab what the camera rendered before that object. Your full shader should look something like this:

Shader "Water/CustomWaterShader" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 0)
_Shininess ("Shininess", Range (0.01, 1)) = 0.078125
_MainTex ("Base (RGB) TransGloss (A)", 2D) = "white" {}
_BumpMap ("Normalmap", 2D) = "bump" {}
_BumpMap2 ("Normalmap", 2D) = "bump" {}
}
 
SubShader {
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
LOD 400
GrabPass{"_ScreenTex"}
 
CGPROGRAM
#pragma surface surf BlinnPhong alpha
 
sampler2D _MainTex;
sampler2D _BumpMap;
sampler2D _ScreenTex;
sampler2D _BumpMap2;
fixed4 _Color;
half _Shininess;
 
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
float2 uv_BumpMap2;
float4 screenPos;
};
 
void surf (Input IN, inout SurfaceOutput o) {
fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
fixed4 bg = tex2D(_ScreenTex,IN.screenPos.xy/IN.screenPos.w);
o.Albedo = bg.rgb*tex.rgb * _Color.rgb;
o.Alpha = bg.a*tex.a * _Color.a;
o.Gloss = 50;
o.Specular = _Shininess;
o.Normal = UnpackNormal(tex2D(_BumpMap , IN.uv_BumpMap)/2 + tex2D(_BumpMap2 , IN.uv_BumpMap2)/2);
}
ENDCG
}
 
FallBack "Transparent/VertexLit"
}

Feel free to change o.Albedo = bg.rgb*tex.rgb * _Color.rgb; to whatever suits you best.

The spec works like a charm! But I can see a copy of whats under my water plane kind of sliding on the texture. It's hard to explain and screenshots wont do it should I send you an executable?

I think the vertical UV of the screenTex might be inverted or something because when I move horizontaly it almost looks fine, but vertically the texture just starts sliding. I have no idea how it works though.

That's pretty strange. The shader seems to work fine on my end, minus some weirdness that doesn't really make it look like water. Could you take a bunch of screenshots regardless of whether you think they'll help or not?

Here are some screenshots, sorry for the wait. http://imageshack.us/a/img194/9171/v4ks.jpg http://imageshack.us/a/img541/3407/7js4.jpg http://imageshack.us/a/img19/7259/ehjw.jpg http://imageshack.us/a/img15/451/l0pb.jpg http://imageshack.us/a/img10/6238/kqk5.jpg http://imageshack.us/a/img46/9686/zgbe.jpg I removed the particles faking the water because its more visible when they're not there. It kinda makes a reflection of whats under the water and slides it on the texture, making it really wierd.

I'm pretty sure it shows what my camera looks at, but upside down.