I wana a real glass shader.It should contain transpanrency and reflection. I tried use build-in transpancy shader but it have no reflection. Somebody help me.
Do you mean Reflection, as in a mirror effect, or Refraction, as in the bending of light as it passes through the lens...?
what I mean reflection is fake reflection using cubemap.If you can combine with refration,that's perfect.
It's often very simple to combine different shaders to get the effect you want. In this case, for example, take the Reflective/VertexLit shader and add a couple of lines from the Alpha/VertexLit shader. Namely, replace Code (csharp): Blend AppSrcAdd AppDstAdd with Code (csharp): Blend SrcAlpha OneMinusSrcAlpha Then add a line in the category which says Code (csharp): Tags {Queue=Transparent} Then give it a new name (like Reflective/VertexLitTransparent) and there ya go. --Eric
I followed Erich's instructions and built my first custom shader ;-) Very nice... although I do find a lot of the code (and the compiler warnings) incomprehensible. I also wasn't able to extend this approach to create a diffuse or shiny (vs. vertexlit) equivalent. The corresponding shaders seem to refer to named passes from other shaders ...
Me too, although you shouldn't get any compiler warnings. Are you using the Unity 2.0 shader source? --Eric
I thought I was (using 2.0 shader sources). Edit: yes I was. I get something like: // vertex vert should be #pragma vertex vert (I made the recommended change and Very Bad Things happened...)
Are you really really sure? There isn't any of the "//vertex vert" syntax in the 2.0 shaders anymore. This is what I have: Code (csharp): Shader "Reflective/VertexLitTransparent" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _SpecColor ("Spec Color", Color) = (1,1,1,1) _Shininess ("Shininess", Range (0.03, 1)) = 0.7 _ReflectColor ("Reflection Color", Color) = (1,1,1,0.5) _MainTex ("Base (RGB) RefStrength (A)", 2D) = "white" {} _Cube ("Reflection Cubemap", Cube) = "_Skybox" { TexGen CubeReflect } } Category { Blend SrcAlpha OneMinusSrcAlpha Fog { Color [_AddFog] } Tags {Queue=Transparent} // ------------------------------------------------------------------ // ARB fragment program SubShader { // First pass does reflection cubemap Pass { Name "BASE" Tags {"LightMode" = "Always"} CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma fragmentoption ARB_fog_exp2 #pragma fragmentoption ARB_precision_hint_fastest #include "UnityCG.cginc" struct v2f { V2F_POS_FOG; float2 uv : TEXCOORD0; float3 I : TEXCOORD1; }; uniform float4 _MainTex_ST; v2f vert(appdata_tan v) { v2f o; PositionFog( v.vertex, o.pos, o.fog ); o.uv = TRANSFORM_TEX(v.texcoord,_MainTex); // calculate object space reflection vector float3 viewDir = ObjSpaceViewDir( v.vertex ); float3 I = reflect( -viewDir, v.normal ); // transform to world space reflection vector o.I = mul( (float3x3)_Object2World, I ); return o; } uniform sampler2D _MainTex; uniform samplerCUBE _Cube; uniform float4 _ReflectColor; half4 frag (v2f i) : COLOR { half4 texcol = tex2D (_MainTex, i.uv); half4 reflcol = texCUBE( _Cube, i.I ); reflcol *= texcol.a; return reflcol * _ReflectColor; } ENDCG } // Second pass adds vertex lighting Pass { Lighting On Material { Diffuse [_Color] Emission [_PPLAmbient] Specular [_SpecColor] Shininess [_Shininess] } SeparateSpecular On CGPROGRAM #pragma fragment frag #pragma fragmentoption ARB_fog_exp2 #pragma fragmentoption ARB_precision_hint_fastest #include "UnityCG.cginc" struct v2f { float2 uv : TEXCOORD0; float4 diff : COLOR0; float4 spec : COLOR1; }; uniform sampler2D _MainTex : register(s0); uniform float4 _ReflectColor; uniform float4 _SpecColor; half4 frag (v2f i) : COLOR { half4 temp = tex2D (_MainTex, i.uv); half4 c; c.xyz = (temp.xyz * i.diff.xyz + temp.w * i.spec.xyz ) * 2; c.w = temp.w * (i.diff.w + Luminance(i.spec.xyz) * _SpecColor.a); return c; } ENDCG SetTexture[_MainTex] {} } } // ------------------------------------------------------------------ // Radeon 9000 SubShader { // First pass does reflection cubemap Pass { Name "BASE" Tags {"LightMode" = "Always"} CGPROGRAM #pragma vertex vert #include "UnityCG.cginc" struct v2f { V2F_POS_FOG; float2 uv : TEXCOORD0; float3 I : TEXCOORD1; }; uniform float4 _MainTex_ST; v2f vert(appdata_tan v) { v2f o; PositionFog( v.vertex, o.pos, o.fog ); o.uv = TRANSFORM_TEX(v.texcoord,_MainTex); // calculate object space reflection vector float3 viewDir = ObjSpaceViewDir( v.vertex ); float3 I = reflect( -viewDir, v.normal ); // transform to world space reflection vector o.I = mul( (float3x3)_Object2World, I ); return o; } ENDCG Program "" { SubProgram { Local 0, [_ReflectColor] "!!ATIfs1.0 StartConstants; CONSTANT c0 = program.local[0]; EndConstants; StartOutputPass; SampleMap r0, t0.str; SampleMap r1, t1.str; MUL r1, r1, r0.a; MUL r0, r1, c0; EndPass; " } } SetTexture [_MainTex] {combine texture} SetTexture [_Cube] {combine texture} } // Second pass adds vertex lighting Pass { Material { Diffuse [_Color] Ambient [_Color] Shininess [_Shininess] Specular [_SpecColor] Emission [_Emission] } Lighting On SeparateSpecular On SetTexture [_MainTex] { constantColor [_Color] Combine texture * previous DOUBLE, texture * constant } } } // ------------------------------------------------------------------ // Old cards SubShader { Pass { Name "BASE" Tags {"LightMode" = "Always"} Material { Diffuse [_Color] Ambient (1,1,1,1) Shininess [_Shininess] Specular [_SpecColor] } Lighting On SeparateSpecular on SetTexture [_MainTex] { combine texture * primary DOUBLE, texture * primary } SetTexture [_Cube] { combine texture * previous alpha + previous, previous } } } } // Fallback for cards that don't do cubemapping FallBack "VertexLit", 1 } To make a diffuse variation, you'd use that as the base, like so: Code (csharp): Shader "Reflective/DiffuseTransparent" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _ReflectColor ("Reflection Color", Color) = (1,1,1,0.5) _MainTex ("Base (RGB) RefStrength (A)", 2D) = "white" {} _Cube ("Reflection Cubemap", Cube) = "_Skybox" { TexGen CubeReflect } } SubShader { UsePass "Reflective/VertexLitTransparent/BASE" UsePass "Diffuse/PPL" } FallBack "Reflective/VertexLitTransparent", 1 }
The screenshot shows the vertexlit variant in operation (it's the cube of "ice"). Here's my shader (very slightly modified version of above suggestion; I copied the properties across from the Reflective/Glossy shader code for consistency and to make sure I hadn't messed up something): Code (csharp): Shader "Transparent/ReflectiveVertexLit" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1) _Shininess ("Shininess", Range (0.01, 1)) = 0.078125 _ReflectColor ("Reflection Color", Color) = (1,1,1,0.5) _MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {} _Cube ("Reflection Cubemap", Cube) = "_Skybox" { TexGen CubeReflect } } Category { Tags {Queue=Transparent} Blend AppSrcAdd OneMinusSrcAlpha Fog { Color [_AddFog] } // ------------------------------------------------------------------ // ARB fragment program SubShader { // First pass does reflection cubemap Pass { Name "BASE" Tags {"LightMode" = "Always"} CGPROGRAM // profiles arbfp1 // fragment frag // fragmentoption ARB_fog_exp2 // fragmentoption ARB_precision_hint_fastest // vertex vert #include "UnityCG.cginc" struct v2f { V2F_POS_FOG; float2 uv : TEXCOORD0; float3 I : TEXCOORD1; }; v2f vert(appdata_tan v) { v2f o; PositionFog( v.vertex, o.pos, o.fog ); o.uv = TRANSFORM_UV(0); // calculate object space reflection vector float3 viewDir = ObjSpaceViewDir( v.vertex ); float3 I = reflect( -viewDir, v.normal ); // transform to world space reflection vector o.I = mul( (float3x3)_Object2World, I ); return o; } uniform sampler2D _MainTex : register(s0); uniform samplerCUBE _Cube : register(s1); uniform float4 _ReflectColor; half4 frag (v2f i) : COLOR { half4 texcol = tex2D (_MainTex, i.uv); half4 reflcol = texCUBE( _Cube, i.I ); reflcol *= texcol.a; return reflcol * _ReflectColor; } ENDCG SetTexture[_MainTex] {combine texture} SetTexture[_Cube] {combine texture} } // Second pass adds vertex lighting Pass { Lighting On Material { Diffuse [_Color] Emission [_PPLAmbient] Specular [_SpecColor] Shininess [_Shininess] } SeparateSpecular On CGPROGRAM // profiles arbfp1 // fragment frag // fragmentoption ARB_fog_exp2 // fragmentoption ARB_precision_hint_fastest #include "UnityCG.cginc" struct v2f { float2 uv : TEXCOORD0; float4 diff : COLOR0; float4 spec : COLOR1; }; uniform sampler2D _MainTex : register(s0); uniform float4 _ReflectColor; uniform float4 _SpecColor; half4 frag (v2f i) : COLOR { half4 temp = tex2D (_MainTex, i.uv); half4 c; c.xyz = (temp.xyz * i.diff.xyz + temp.w * i.spec.xyz ) * 2; c.w = temp.w * (i.diff.w + Luminance(i.spec.xyz) * _SpecColor.a); return c; } ENDCG SetTexture[_MainTex] {combine texture} } } // ------------------------------------------------------------------ // Radeon 9000 SubShader { // First pass does reflection cubemap Pass { Name "BASE" Tags {"LightMode" = "Always"} CGPROGRAM // vertex vert #include "UnityCG.cginc" struct v2f { V2F_POS_FOG; float2 uv : TEXCOORD0; float3 I : TEXCOORD1; }; v2f vert(appdata_tan v) { v2f o; PositionFog( v.vertex, o.pos, o.fog ); o.uv = TRANSFORM_UV(0); // calculate object space reflection vector float3 viewDir = ObjSpaceViewDir( v.vertex ); float3 I = reflect( -viewDir, v.normal ); // transform to world space reflection vector o.I = mul( (float3x3)_Object2World, I ); return o; } ENDCG Program "" { SubProgram { Local 0, [_ReflectColor] "!!ATIfs1.0 StartConstants; CONSTANT c0 = program.local[0]; EndConstants; StartOutputPass; SampleMap r0, t0.str; SampleMap r1, t1.str; MUL r1, r1, r0.a; MUL r0, r1, c0; EndPass; " } } SetTexture [_MainTex] {combine texture} SetTexture [_Cube] {combine texture} } // Second pass adds vertex lighting Pass { Material { Diffuse [_Color] Ambient [_Color] Shininess [_Shininess] Specular [_SpecColor] Emission [_Emission] } Lighting On SeperateSpecular On SetTexture [_MainTex] { constantColor [_Color] Combine texture * previous DOUBLE, texture * constant } } } // ------------------------------------------------------------------ // Old cards SubShader { Pass { Name "BASE" Tags {"LightMode" = "Always"} Material { Diffuse [_Color] Ambient (1,1,1,1) Shininess [_Shininess] Specular [_SpecColor] } Lighting On SeparateSpecular on SetTexture [_MainTex] { combine texture * primary DOUBLE } SetTexture [_Cube] { combine texture * previous alpha + previous Matrix [_Reflection] } } } } // Fallback for cards that don't do cubemapping FallBack " VertexLit", 1 } And here's my per pixel lit glossy version: Code (csharp): Shader "Transparent/ReflectiveGlossy" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1) _Shininess ("Shininess", Range (0.01, 1)) = 0.078125 _ReflectColor ("Reflection Color", Color) = (1,1,1,0.5) _MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {} _Cube ("Reflection Cubemap", Cube) = "_Skybox" { TexGen CubeReflect } } SubShader { UsePass "Transparent/ReflectiveVertexLit/BASE" UsePass " Glossy/PPL" } FallBack "Transparent/ReflectiveVertexLit", 1 } Here's where I'm confused: 1) The alpha of the main color affects the brightness of the shader but not its transparency (more transparent => brighter ...?!) 2) The glossy version looks VERY different (much darker) so that I suspect I've done something terribly wrong. The main difference seems to be that it doesn't get the mysterious brightness boost from the alpha (they look the same if the main color is 100% opaque). I'd love to get this right since it's a pretty gorgeous effect.
Aha! Looks like the Unity 2 shaders archive is named "builtin shaders.zip" but expands to produce "Unity Builtin Shaders" while the 1.6.2 archive expands to create "Builtin Shaders" which is what confused me. So my compiler warning is gone, but all the other weirdness remains. Edit: for the nonce, I can get nice results out of the Reflective/TransparentVertexLit shader built as per Erich's suggestion, even though its behavior doesn't make sense to me ... so I guess I'll live with that.
Glad you got it sorted (more or less)...I don't know enough about shaders to suggest any ways to change the behavior, alas. --Eric
Dude, I modified your code a bit and I think I got what you where looking for. First, I set the _ReflectColor alpha to the given cubemap texture, than I multiplied the ObjSpaceViewDir to about a third of the given vertex calculation.. worked fine for me: Code (csharp): Shader "Transparent/ReflectiveVertexLit" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1) _Shininess ("Shininess", Range (0.01, 1)) = 0.078125 _ReflectColor ("Reflection Color", Color) = (1,1,1,0.5) _MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {} _Cube ("Reflection Cubemap", Cube) = "_Skybox" { TexGen CubeReflect } } Category { //Tags {Queue=Transparent} Blend AppSrcAdd OneMinusSrcAlpha Fog { Color [_AddFog] } // ------------------------------------------------------------------ // ARB fragment program SubShader { // First pass does reflection cubemap Pass { Name "BASE" Tags {"LightMode" = "Always"} CGPROGRAM // profiles arbfp1 // fragment frag // fragmentoption ARB_fog_exp2 // fragmentoption ARB_precision_hint_fastest // vertex vert #include "UnityCG.cginc" struct v2f { V2F_POS_FOG; float2 uv : TEXCOORD0; float3 I : TEXCOORD1; }; v2f vert(appdata_tan v) { v2f o; PositionFog( v.vertex, o.pos, o.fog ); o.uv = TRANSFORM_UV(0); // calculate object space reflection vector float3 viewDir = ObjSpaceViewDir( v.vertex * 0.3 ); float3 I = reflect( -viewDir, v.normal ); // transform to world space reflection vector o.I = mul( (float3x3) _Object2World, I ); return o; } uniform sampler2D _MainTex : register(s0); uniform samplerCUBE _Cube : register(s1); uniform float4 _ReflectColor; half4 frag (v2f i) : COLOR { half4 texcol = tex2D (_MainTex, i.uv); half4 reflcol = texCUBE( _Cube, i.I ); reflcol *= texcol.a; return reflcol * _ReflectColor * _ReflectColor.a; } ENDCG SetTexture[_MainTex] {combine texture} SetTexture[_Cube] {combine texture} } // Second pass adds vertex lighting Pass { Lighting On Material { Diffuse [_Color] Emission [_PPLAmbient] Specular [_SpecColor] Shininess [_Shininess] } SeparateSpecular On CGPROGRAM // profiles arbfp1 // fragment frag // fragmentoption ARB_fog_exp2 // fragmentoption ARB_precision_hint_fastest #include "UnityCG.cginc" struct v2f { float2 uv : TEXCOORD0; float4 diff : COLOR0; float4 spec : COLOR1; }; uniform sampler2D _MainTex : register(s0); uniform float4 _ReflectColor; uniform float4 _SpecColor; half4 frag (v2f i) : COLOR { half4 temp = tex2D (_MainTex, i.uv); half4 c; c.xyz = (temp.xyz * i.diff.xyz + temp.w * i.spec.xyz ) * 2; c.w = temp.w * (i.diff.w + Luminance(i.spec.xyz) * _SpecColor.a); return c; } ENDCG SetTexture[_MainTex] {combine texture} } } // ------------------------------------------------------------------ // Radeon 9000 SubShader { // First pass does reflection cubemap Pass { Name "BASE" Tags {"LightMode" = "Always"} CGPROGRAM // vertex vert #include "UnityCG.cginc" struct v2f { V2F_POS_FOG; float2 uv : TEXCOORD1; float3 I : TEXCOORD0; }; v2f vert(appdata_tan v) { v2f o; PositionFog( v.vertex, o.pos, o.fog ); o.uv = TRANSFORM_UV(0); // calculate object space reflection vector float3 viewDir = ObjSpaceViewDir( v.vertex * 0.3); float3 I = reflect( -viewDir, v.normal ); // transform to world space reflection vector o.I = mul( (float3x3)_Object2World, I ); return o; } ENDCG Program "" { SubProgram { Local 0, [_ReflectColor] "!!ATIfs1.0 StartConstants; CONSTANT c0 = program.local[0]; EndConstants; StartOutputPass; SampleMap r0, t0.str; SampleMap r1, t1.str; MUL r1, r1, r0.a; MUL r0, r1, c0; EndPass; " } } SetTexture [_MainTex] {combine texture} SetTexture [_Cube] {combine texture} } // Second pass adds vertex lighting Pass { Material { Diffuse [_Color] Ambient [_Color] Shininess [_Shininess] Specular [_SpecColor] Emission [_Emission] } Lighting On SeperateSpecular On SetTexture [_MainTex] { constantColor [_Color] Combine texture * previous DOUBLE, texture * constant } } } // ------------------------------------------------------------------ // Old cards SubShader { Pass { Name "BASE" Tags {"LightMode" = "Always"} Material { Diffuse [_Color] Ambient (1,1,1,1) Shininess [_Shininess] Specular [_SpecColor] } Lighting On SeparateSpecular on SetTexture [_MainTex] { combine texture * primary DOUBLE } SetTexture [_Cube] { combine texture * previous alpha + previous Matrix [_Reflection] } } } } // Fallback for cards that don't do cubemapping FallBack " VertexLit", 1 }
Hi all, has anyone modified this to work with 3.1? I'm getting several errors (and haven't got a clue what to do about them ) thanks
When I tried dnishimura's version on Unity 3.1 I received the following error: Code (csharp): Shader warning in 'Transparent/ReflectiveVertexLit': Compiling shaders to OpenGL ES 2.0 requires both vertex and fragment programs at line 85
Hi, It's been a while since I last posted here. Here's the current version of this same shader. It's a lot cleaner and is working on Unity 3.4.0f5 Code (csharp): Shader "Transparent/Glass" { Properties { _Color ("Color", Color) = (1,1,1,1) _SpecColor ("Specular Color", Color) = (1,1,1,1) _Shininess ("Specular Falloff", Range (0.01, 1)) = 0.7 _ReflectColor ("Reflection Color", Color) = (1,1,1,0.5) _MainTex ("Main Texture", 2D) = "white" {} _Cube ("Reflection Cubemap", Cube) = "_Skybox" { TexGen CubeReflect } } Category { Tags {"Queue"="Transparent"} SubShader { Pass { Cull Off ZWrite Off ZTest Less Lighting On SeparateSpecular On Blend SrcAlpha OneMinusSrcAlpha AlphaTest Greater 0.01 Material { Diffuse [_Color] Ambient [_Color] Shininess [_Shininess] Specular [_SpecColor] } //Reflection SetTexture [_Cube] { ConstantColor [_ReflectColor] combine texture * constant alpha, texture Matrix [_Cube] } //Reflection illumination SetTexture [_Cube] { ConstantColor [_ReflectColor] combine constant * constant alpha - previous, previous Matrix [_Cube] } //Texture SetTexture [_MainTex] { ConstantColor [_Color] combine texture +- previous, constant } //Texture illumination SetTexture [_MainTex] { ConstantColor (1,1,1,0.5) combine previous * primary double , previous } } }//End of Subshader Fallback "Diffuse" }//End of Category }//End of Shader
Hey, I am using this shader that you wrote. It works fine but it is not very transparent. In you last code, which line can I change to make the shader more transparent?
Hey guys, I tried using dnishimura's shader but got some strange results. The cubemap texture was inverted and it was aligning with the camera. I haven't gotten any errors and I'm new to this so i'm not quite sure what to modify in the code.
If you're looking for a glass shader with dynamic reflections, there's one on the Wiki: http://wiki.unity3d.com/index.php/SurfaceReflection It requires Unity Pro, though.
Updated version working on Unity 4.3 Code (csharp): Shader "TransparentReflection" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _ReflectColor ("Reflection Color", Color) = (1,1,1,0.5) _MainTex ("Base (RGB) RefStrength (A)", 2D) = "white" {} _Cube ("Reflection Cubemap", Cube) = "_Skybox" { TexGen CubeReflect } } SubShader { LOD 300 Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"} CGPROGRAM #pragma surface surf Lambert alpha sampler2D _MainTex; samplerCUBE _Cube; fixed4 _Color; fixed4 _ReflectColor; struct Input { float2 uv_MainTex; float3 worldRefl; }; void surf (Input IN, inout SurfaceOutput o) { fixed4 tex = tex2D(_MainTex, IN.uv_MainTex); fixed4 c = tex * _Color; o.Albedo = c.rgb; o.Alpha = c.a; fixed4 reflcol = texCUBE (_Cube, IN.worldRefl); reflcol *= tex.a; o.Emission = reflcol.rgb * _ReflectColor.rgb; o.Alpha = reflcol.a * _ReflectColor.a; } ENDCG } FallBack "Reflective/VertexLit" }
Hello guys, I got a very good effect with this shader combined to a cubemap, can I use this final shader that you have been posted for my commercial videogame? Please answer, thank you
Hello guys, your shader is realy good, but a problem is the shadow which it produced shows very deep, how to make the shadow fade? In addition, in my observation, if the reflection of glass is bright than the object behind the glass, then the transparency will be low, and vice versa. So I changed the code "o.Alpha = reflcol.a * _ReflectColor.a" as "1- reflcol.a - _ReflectColor.a" , and it looks better.
Hello guys, your shader is realy good, but a problem is the shadow which it produced shows very deep, how to make the shadow fade? In addition, in my observation, if the reflection of glass is bright than the object behind the glass, then the transparency will be low, and vice versa. So I changed the code "o.Alpha = reflcol.a * _ReflectColor.a" as "1- reflcol.a - _ReflectColor.a" , and it looks better.