- Home /
Shader Transparency issues
I've slightly modified this shader (video) (git repo) to achieve echolocation in my game. I've gotten it to work really well, but the only issue is it lacks transparency.
The shader functions like this (excluding the distortion - that's handled separately and has no effect on the shader)
I've tried following this answer to add transparency to the shader, but the results are not what I'm looking for.
Here's an image describing my issue:
This shader uses a distance variable to control how the echolocation rendering moves outward from the player. How can I fix these issues? Any and all help is appreciated! I'm pretty clueless when it comes to shaders, but I really need transparency in my game.
Here's a diff between the two shader versions below to save you some time. Here's my non-transparent shader code:
Shader "My/Normal/AlphaPulseShader" {
Properties{
_MainTex ("Base (RGB) Trans (A)", 2D) = "blue" {}
_BumpMap ("Normalmap", 2D) = "bump" {}
_EmissionMap ("Emission Map", 2D) = "black" {}
_Color ("Color", Color) = (1,0,0,1)
_PDistance ("PulseDistance", Float) = 0
_PFadeDistance ("FadeDistance", Float) = 10
_PEdgeSoftness ("EdgeSoftness", Float) = 5
_Origin ("PulseOrigin", Vector) = (0, 0, 0, 0)
_RimColor ("Rim Color", Color) = (1,1,1,1)
_RimPower ("Rim Power", Range(0.5, 8.0)) = 1.059702
[Toggle(USE_RIM)]_RimOn ("Rim On", Int) = 0.0
_EmissionMultiplier ("Emission Multiplier", Range(-10,10)) = 1.0
}
SubShader{
Tags{ "RenderType"="Opaque" }
LOD 200
CGPROGRAM
//LIGHTING
#include "AutoLight.cginc"
// define finalcolor and vertex programs:
#pragma surface surf Lambert finalcolor:mycolor// alpha
#pragma shader_feature USE_RIM
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
float2 uv_EmissionMap;
float3 worldPos;
float3 viewDir;
half alpha;
};
fixed4 _Color;
sampler2D _MainTex;
sampler2D _BumpMap;
sampler2D _EmissionMap;
half _PDistance;
half _PFadeDistance;
half _PEdgeSoftness;
float4 _Origin;
float4 _RimColor;
float _RimPower;
float _RimOn;
float _EmissionMultiplier;
void mycolor (Input IN, SurfaceOutput o, inout fixed4 color) {
// set the vertex color alpha to the value calculated:
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
color.a = c.a;
half dis;
half interval;
half origin;
dis = sqrt (pow ((IN.worldPos.x - _Origin.x),2) + pow ((IN.worldPos.y - _Origin.y), 2) + pow ((IN.worldPos.z - _Origin.z), 2));
if (dis >= _PDistance)
{
color.rgb = color.rgb * (1 - saturate (abs (_PDistance - dis) / _PEdgeSoftness));
}
else
{
color.rgb = color.rgb * (1 - saturate (abs (_PDistance - dis) / _PFadeDistance));
}
}
void surf (Input IN, inout SurfaceOutput o) {
// simply copy the corresponding texture element color:
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// o.Alpha = tex2D(_MainTex,IN.uv_MainTex).a;
o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
// half rim = 1.0 - saturate(dot(normalize(IN.viewDir), o.Normal));
#ifdef USE_RIM
half rim = 1.0 - saturate (dot (normalize (IN.viewDir), o.Normal));
o.Emission = _RimColor.rgb * pow (rim, _RimPower) + _EmissionMultiplier * tex2D (_EmissionMap, IN.uv_EmissionMap);
#else
o.Emission = _EmissionMultiplier * tex2D (_EmissionMap, IN.uv_EmissionMap);
#endif
}
ENDCG
}
// Fallback "Diffuse"
Fallback "VertexLit"
}
And here is my modified shader code for transparency:
Shader "My/Normal/AlphaPulseShader" {
Properties{
_MainTex ("Color (RGB) Alpha (A)", 2D) = "white" {}
_BumpMap ("Normalmap", 2D) = "bump" {}
_EmissionMap ("Emission Map", 2D) = "black" {}
_Color ("Color", Color) = (1,0,0,1)
_PDistance ("PulseDistance", Float) = 0
_PFadeDistance ("FadeDistance", Float) = 10
_PEdgeSoftness ("EdgeSoftness", Float) = 5
_Origin ("PulseOrigin", Vector) = (0, 0, 0, 0)
_RimColor ("Rim Color", Color) = (1,1,1,1)
_RimPower ("Rim Power", Range(0.5, 8.0)) = 1.059702
[Toggle(USE_RIM)]_RimOn ("Rim On", Int) = 0.0
_EmissionMultiplier ("Emission Multiplier", Range(-10,10)) = 1.0
}
SubShader{
Tags{ "Queue"="Transparent" "RenderType"="Transparent" }
LOD 200
CGPROGRAM
//LIGHTING
#include "AutoLight.cginc"
// define finalcolor and vertex programs:
#pragma surface surf Lambert finalcolor:mycolor alpha //check this out
#pragma shader_feature USE_RIM
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
float2 uv_EmissionMap;
float3 worldPos;
float3 viewDir;
half alpha;
};
fixed4 _Color;
sampler2D _MainTex;
sampler2D _BumpMap;
sampler2D _EmissionMap;
half _PDistance;
half _PFadeDistance;
half _PEdgeSoftness;
float4 _Origin;
float4 _RimColor;
float _RimPower;
float _RimOn;
float _EmissionMultiplier;
void mycolor (Input IN, SurfaceOutput o, inout fixed4 color) {
// set the vertex color alpha to the value calculated:
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
color.a = c.a;
half dis;
half interval;
half origin;
dis = sqrt (pow ((IN.worldPos.x - _Origin.x),2) + pow ((IN.worldPos.y - _Origin.y), 2) + pow ((IN.worldPos.z - _Origin.z), 2));
if (dis >= _PDistance)
{
color.rgb = color.rgb * (1 - saturate (abs (_PDistance - dis) / _PEdgeSoftness));
}
else
{
color.rgb = color.rgb * (1 - saturate (abs (_PDistance - dis) / _PFadeDistance));
}
}
void surf (Input IN, inout SurfaceOutput o) {
// simply copy the corresponding texture element color:
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Alpha = tex2D(_MainTex,IN.uv_MainTex).a;
o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
// half rim = 1.0 - saturate(dot(normalize(IN.viewDir), o.Normal));
#ifdef USE_RIM
half rim = 1.0 - saturate (dot (normalize (IN.viewDir), o.Normal));
o.Emission = _RimColor.rgb * pow (rim, _RimPower) + _EmissionMultiplier * tex2D (_EmissionMap, IN.uv_EmissionMap);
#else
o.Emission = _EmissionMultiplier * tex2D (_EmissionMap, IN.uv_EmissionMap);
#endif
}
ENDCG
}
// Fallback "Diffuse"
Fallback "VertexLit"
}
Answer by Buckslice · Dec 15, 2017 at 10:30 PM
I am not sure how the shader is supposed to look, but I tested it out in an empty scene and was able to have it be transparent by changing the alpha of the color field. Maybe try saying alpha:blend in your surface shader. Also you could try saying ZWrite Off below the LOD200 line. Here is the unity doc on surface shaders about halfway down is section on alpha blending with a bunch of options. Hope this helps!
FIX: The problem was this transparent shader was being used on everything, including the large opaque background root tunnel thing which ended up getting drawn over everything. The solution was to make the background root use the opaque version of the shader so it is properly rendered first in the opaque queue while other transparent walls and doors and such get the new transparent version of shader.
I updated the description with a GIF of how it looks, it uses a couple other scripts to modify the Distance in the shader.
I tried the ZWrite Off to no avail. Please excuse me for being a doofus but I can't figure out how to actually apply that alpha:blend. I keep getting the following error wherever I put it:
Shader error in '$$anonymous$$y/Normal/AlphaPulseShader': Unexpected token ':'. Expected one of: ',' ';' at line XXX
#pragma surface surf Lambert finalcolor:mycolor alpha
Ins$$anonymous$$d of this line
#pragma surface surf Lambert finalcolor:mycolor alpha:blend
try this line
thanks! Unfortunately I tried that, along with all the other optional parameters in that surface shaders doc and none of them helped the problem :(
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Simplest Unlit Instanced shader - how to enable switching it on/off (with AlphaTest)? 0 Answers
Rendering transparent objects back to back (HDRP Lit shader) 0 Answers
Tree Creator Shader will not fade 0 Answers
How to make terrain partially transparent (lower opacity) 1 Answer