Hello, I have a shader that colors objects dependent on y coordinate. This part is working, but I want to be able to specify transparancy through a parameter settable in Unity script. However I cannot even set a static transparancy: My code looks like this: Shader"Custom/HeightDependentTint3Colors" { Properties { _MainTex ("Base(RGB)", 2D) = "white" {} _Normal ("Normal(A)", 2D) = "bump" {} _HeightMin ("HeightMin", Float) = -1 middle ("HeightMiddle", Float) = -1 _HeightMax ("HeightMax", Float) = 1 _ColorMin ("TintColorAtMin", Color) = (0,0,0,1) _ColorMiddle ("TintColorAtMid", Color) = (1,1,0,1) _ColorMax ("TintColorAtMax", Color) = (1,1,1,1) } SubShader { Tags { "RenderType"="Opaque" } CGPROGRAM #pragmasurfacesurfLambert #pragmatarget3.0 sampler2D _MainTex; sampler2D _Normal; fixed4 _ColorMin; fixed4 _ColorMiddle; fixed4 _ColorMax; float _HeightMin; float _HeightMax; float middle; struct Input { float2 uv_MainTex; float2 uv_NormalMap; float3 worldPos; }; void surf (Input IN, inout SurfaceOutput o) { half4 c; float h; fixed4 tintColor; //heightofthepixelto treat float height = IN.worldPos.y; //createthetwo colors fixed4 colorTop, colorBottom; float hTop = height - middle, hBottom = middle - height; colorTop = lerp(_ColorMiddle.rgba, _ColorMax.rgba, hTop / (_HeightMax - middle)); colorBottom = lerp(_ColorMiddle.rgba, _ColorMin.rgba, hBottom / (middle - _HeightMin)); if(height>middle) tintColor = colorTop; else tintColor = colorBottom; c = tex2D (_MainTex, IN.uv_MainTex); o.Albedo = c.rgb * tintColor.rgb * .8; o.Alpha = 0.5; o.Normal = UnpackNormal (tex2D (_Normal, IN.uv_NormalMap)); } ENDCG } Fallback"Diffuse" }
By default all shaders are opaque, or more specifically they don't have a blend mode. To enable transparency you'll need to set the blend mode you wish to use. https://docs.unity3d.com/Manual/SL-Blend.html Surface shaders (shaders that use #pragma surface) have some additional oddities that have to be dealt with. By default not only are they opaque, but they forcibly override the alpha value to 1.0. You can also set the blend mode in surface shaders without using the Blend command. http://docs.unity3d.com/Manual/SL-SurfaceShaders.html So, for the most basic case if you want a surface shader that uses alpha blending you can change your #pragma surface line to this: #pragma surface surf Lambert alpha However if you want to be able to switch between doing alpha blending and not (across the whole shader) you'll need to use the blend command above with the blend ops set as shader properties, along with "keepalpha" on the #pragma surface line, as well as change the queue and turn off ZWrite. For an example of this you might want to download the built in shader source files and look at how the Standard shader editor works. It does all of the things you want. There's also been several posts talking about how it's done on this forum. http://forum.unity3d.com/threads/change-standard-shader-render-mode-in-runtime.318815/
Hello bgolus, Thank you very much for your extensive reply. For the first implementation, your comment about #pragma surface surf Lambert alpha does exactly what I want it to do. I will however also go over the other mentioned resources in order to gain further insights about how things work inside. Do you have a link that explains shader parameters, i.e. I want to set alpha per object that uses this shader.