Hi there,
for those who want to know how to collect shadow on transparent materials here is a start:
Shader "Custom/transparentwithshadow"
{
Properties
{
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
_BumpMap ("Bump Map", 2D) = "white" {}
_Shininess ("Shininess", Float) = 1
_Parallax ("Main Color", Float) = 1
}
SubShader
{
Tags {
"Queue"="AlphaTest"
"IgnoreProjector"="True"
"RenderType"="Transparent"
}
Alphatest Greater 0 ZWrite Off ColorMask RGB
/* surface debug info:
vertex modifier: 'vert'
stuff performed in tangent space
*/
/* surface debug info:
vertex modifier: 'vert'
stuff performed in tangent space*/
CGPROGRAM
#pragma surface surf BlinnPhong alpha vertex:vert fullforwardshadows approxview
#pragma target 3.0
#pragma debug
half _Shininess;
sampler2D _MainTex;
float4 _Color;
sampler2D _BumpMap;
//sampler2D _ParallaxMap;
float _Parallax;
struct v2f {
V2F_SHADOW_CASTER;
float2 uv : TEXCOORD1;
};
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
//float3 viewDir;
};
v2f vert (inout appdata_full v) {
v2f o;
return o;
}
void surf (Input IN, inout SurfaceOutput o) {
// Comment the next 4 following lines to get a standard bumped rendering
// [Without Parallax usage]
//half h = tex2D (_ParallaxMap, IN.uv_BumpMap).w;
//float2 offset = ParallaxOffset (h, _Parallax, IN.viewDir);
//IN.uv_MainTex += offset;
//IN.uv_BumpMap += offset;
fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = tex.rgb * _Color.rgb;
o.Gloss = tex.a;
o.Alpha = tex.a * _Color.a;
//clip(o.Alpha - _Cutoff);
o.Specular = _Shininess;
o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
}
ENDCG
}
}
here is an example:
Now the problem is we are limited with surface shaders (in fact I want to use geometry shader with alpha and receive shadow on it).
A trail is to use #pragma debug to see from what the surface shader is generated. It gives me this:
Pass {
Name "FORWARD"
Tags { "LightMode" = "ForwardBase" }
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert_surf
#pragma fragment frag_surf
#pragma multi_compile_fwdbase
#pragma target 3.0
#include "HLSLSupport.cginc"
#include "UnityShaderVariables.cginc"
#define UNITY_PASS_FORWARDBASE
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
#define INTERNAL_DATA
#define WorldReflectionVector(data,normal) data.worldRefl
#define WorldNormalVector(data,normal) normal
#line 1
#line 33
//#pragma surface surf BlinnPhong alpha vertex:vert fullforwardshadows approxview
#pragma target 3.0
#pragma debug
half _Shininess;
sampler2D _MainTex;
float4 _Color;
sampler2D _BumpMap;
//sampler2D _ParallaxMap;
float _Parallax;
struct v2f {
V2F_SHADOW_CASTER;
float2 uv : TEXCOORD1;
};
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
//float3 viewDir;
};
v2f vert (inout appdata_full v) {
v2f o;
return o;
}
void surf (Input IN, inout SurfaceOutput o) {
// Comment the next 4 following lines to get a standard bumped rendering
// [Without Parallax usage]
//half h = tex2D (_ParallaxMap, IN.uv_BumpMap).w;
//float2 offset = ParallaxOffset (h, _Parallax, IN.viewDir);
//IN.uv_MainTex += offset;
//IN.uv_BumpMap += offset;
fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = tex.rgb * _Color.rgb;
o.Gloss = tex.a;
o.Alpha = tex.a * _Color.a;
//clip(o.Alpha - _Cutoff);
o.Specular = _Shininess;
o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
}
#ifdef LIGHTMAP_OFF
struct v2f_surf {
float4 pos : SV_POSITION;
float4 pack0 : TEXCOORD0;
fixed3 lightDir : TEXCOORD1;
fixed3 vlight : TEXCOORD2;
fixed3 viewDir : TEXCOORD3;
LIGHTING_COORDS(4,5)
};
#endif
#ifndef LIGHTMAP_OFF
struct v2f_surf {
float4 pos : SV_POSITION;
float4 pack0 : TEXCOORD0;
float2 lmap : TEXCOORD1;
#ifndef DIRLIGHTMAP_OFF
fixed3 viewDir : TEXCOORD2;
LIGHTING_COORDS(3,4)
#else
LIGHTING_COORDS(2,3)
#endif
};
#endif
#ifndef LIGHTMAP_OFF
float4 unity_LightmapST;
#endif
float4 _MainTex_ST;
float4 _BumpMap_ST;
v2f_surf vert_surf (appdata_full v) {
v2f_surf o;
vert (v);
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.pack0.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
o.pack0.zw = TRANSFORM_TEX(v.texcoord, _BumpMap);
#ifndef LIGHTMAP_OFF
o.lmap.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
#endif
float3 worldN = mul((float3x3)_Object2World, SCALED_NORMAL);
TANGENT_SPACE_ROTATION;
float3 lightDir = mul (rotation, ObjSpaceLightDir(v.vertex));
#ifdef LIGHTMAP_OFF
o.lightDir = lightDir;
#endif
#if defined (LIGHTMAP_OFF) || !defined (DIRLIGHTMAP_OFF)
float3 viewDirForLight = mul (rotation, ObjSpaceViewDir(v.vertex));
o.viewDir = normalize(viewDirForLight);
#endif
#ifdef LIGHTMAP_OFF
float3 shlight = ShadeSH9 (float4(worldN,1.0));
o.vlight = shlight;
#ifdef VERTEXLIGHT_ON
float3 worldPos = mul(_Object2World, v.vertex).xyz;
o.vlight += Shade4PointLights (
unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb,
unity_4LightAtten0, worldPos, worldN );
#endif // VERTEXLIGHT_ON
#endif // LIGHTMAP_OFF
TRANSFER_VERTEX_TO_FRAGMENT(o);
return o;
}
#ifndef LIGHTMAP_OFF
sampler2D unity_Lightmap;
#ifndef DIRLIGHTMAP_OFF
sampler2D unity_LightmapInd;
#endif
#endif
fixed4 frag_surf (v2f_surf IN) : COLOR {
#ifdef UNITY_COMPILER_HLSL
Input surfIN = (Input)0;
#else
Input surfIN;
#endif
surfIN.uv_MainTex = IN.pack0.xy;
surfIN.uv_BumpMap = IN.pack0.zw;
#ifdef UNITY_COMPILER_HLSL
SurfaceOutput o = (SurfaceOutput)0;
#else
SurfaceOutput o;
#endif
o.Albedo = 0.0;
o.Emission = 0.0;
o.Specular = 0.0;
o.Alpha = 0.0;
o.Gloss = 0.0;
surf (surfIN, o);
fixed atten = LIGHT_ATTENUATION(IN);
fixed4 c = 0;
#ifdef LIGHTMAP_OFF
c = LightingBlinnPhong (o, IN.lightDir, IN.viewDir, atten);
#endif // LIGHTMAP_OFF || DIRLIGHTMAP_OFF
#ifdef LIGHTMAP_OFF
c.rgb += o.Albedo * IN.vlight;
#endif // LIGHTMAP_OFF
#ifndef LIGHTMAP_OFF
#ifndef DIRLIGHTMAP_OFF
half3 specColor;
fixed4 lmtex = tex2D(unity_Lightmap, IN.lmap.xy);
fixed4 lmIndTex = tex2D(unity_LightmapInd, IN.lmap.xy);
half3 lm = LightingBlinnPhong_DirLightmap(o, lmtex, lmIndTex, IN.viewDir, 1, specColor).rgb;
c.rgb += specColor;
#else // !DIRLIGHTMAP_OFF
fixed4 lmtex = tex2D(unity_Lightmap, IN.lmap.xy);
fixed3 lm = DecodeLightmap (lmtex);
#endif // !DIRLIGHTMAP_OFF
#ifdef SHADOWS_SCREEN
#if (defined(SHADER_API_GLES) || defined(SHADER_API_GLES3)) defined(SHADER_API_MOBILE)
c.rgb += o.Albedo * min(lm, atten*2);
#else
c.rgb += o.Albedo * max(min(lm,(atten*2)*lmtex.rgb), lm*atten);
#endif
#else // SHADOWS_SCREEN
c.rgb += o.Albedo * lm;
#endif // SHADOWS_SCREEN
c.a = o.Alpha;
#endif // LIGHTMAP_OFF
c.a = o.Alpha;
return c;
}
ENDCG
}
but no shadow, I even tried to add a shadow blend pass:
// Shadow Pass : Adding the shadows (from Directional Light)
// by blending the light attenuation
Pass {
Blend SrcAlpha OneMinusSrcAlpha
Name "ShadowPass"
Tags {"LightMode" = "ForwardBase"}
CGPROGRAM
#pragma exclude_renderers d3d11 xbox360
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#pragma fragmentoption ARB_fog_exp2
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
#include "AutoLight.cginc"
struct v2f {
float2 uv_MainTex : TEXCOORD1;
float4 pos : SV_POSITION;
LIGHTING_COORDS(3,4)
float3 lightDir;
};
float4 _MainTex_ST;
sampler2D _MainTex;
float4 _Color;
float _ShadowIntensity;
v2f vert (appdata_full v)
{
v2f o;
o.uv_MainTex = TRANSFORM_TEX(v.texcoord, _MainTex);
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.lightDir = ObjSpaceLightDir( v.vertex );
TRANSFER_VERTEX_TO_FRAGMENT(o);
return o;
}
float4 frag (v2f i) : COLOR
{
float atten = LIGHT_ATTENUATION(i);
half4 c;
c.rgb = 0;
c.a = (1-atten) * _ShadowIntensity * (tex2D(_MainTex, i.uv_MainTex).a);
return c ;
}
ENDCG
}
But no way, I can’t have the same result from the surface Shader. Any idea why?