big question for a new shader guy...

Hi all,

I’m trying to figure out how to make a shader that makes an object seem partially translucent, and blurry. I don’t want motion blur, because the object could be sitting still, I just want the edges to sort of “fuzz out” to the background.

Any ideas?

-T

Okay, here’s what I’ve come up with so far. Its a modification to the x-ray shader. Instead of fading into/out of a standard color, it fades through a texture assigned to the object. It doesn’t quite work the way I want, though.

Here’s the code

Shader "XRay" {
    Properties {
        _Color ("Tint (RGB)", Color) = (1,1,1,1)
        _RampTex ("Facing Ratio Ramp (RGB)", 2D) = "white" {}
        _MainTex ("Main texture",2D) = "white" {}
    }
    Category {
        ZWrite Off
        Tags {"Queue"="Transparent"}
        Lighting On
        SubShader {
            Pass {
            	Blend One One
	            
	            CGPROGRAM 
	            // profiles arbfp1 
	            // vertex vert
	            
	            #include "UnityCG.cginc" 
	 
				sampler2D _MainTex : register(s0);
	            struct v2f {
	                V2F_POS_FOG;
	                float4 uv : TEXCOORD0;
	                float2 uv1 :TEXCOORD1;
	            };
	            
	            v2f vert (appdata_base v) {
	                v2f o;
	                PositionFog( v.vertex, o.pos, o.fog );
	 	            o.uv1 = TRANSFORM_UV(0);

	                float3 viewDir = normalize(ObjSpaceViewDir(v.vertex));
	                
	                o.uv.x = dot(viewDir, v.normal);
	                o.uv.y = 0.5;
	                o.uv.z = 0.0;
	                o.uv.w = 1.0;
					return o;
	            }
	 			
	            ENDCG 
           		
           		SetTexture [_RampTex] {
            		constantColor[_Color] combine texture * constant
            	}
            	SetTexture [_MainTex] {
            		combine texture * previous, previous
            	}
            }
        }
    } 
}

Try it out. The problem is, even the parts that are supposed to be “solid” aren’t. Any ideas on why, or how to fix that issue?

Thanks,
-T

[/code]

I did not try your shader, but a first guess: try changing “Blend One One” to “Blend SrcAlpha OneMinusSrcAlpha”. The X-ray shader uses additive blending (possibly because the author of the effect wanted it that way), whereas I guess you want regular alpha blending.

That had an interesting effect. It makes it fade out to black where before it was transparent. I’ll keep playing around with it (I’m still learning about shader programming), but any more insights that people might have would be very much appreciated.

-T

Alright, I figured out something that works:

Shader "XRay" {
    Properties {
        _Color ("Tint (RGB)", Color) = (1,1,1,1)
        _MainTex ("Main texture",2D) = "white" {}
    }
    Category {
        ZWrite Off
        Tags {"Queue"="Transparent"}
        Lighting Off
        SubShader {
            Pass {
            	// Blend One One
	            Blend SrcAlpha OneMinusSrcAlpha
	            
	            CGPROGRAM 
	            // profiles arbfp1 
	            // vertex vert
	            //fragment frag
				//fragmentoption ARB_fog_exp2
	
	            #include "UnityCG.cginc" 
	 
				sampler2D _MainTex : register(s0);
	            struct v2f {
	                V2F_POS_FOG;
	                float2 uv1 :TEXCOORD1;
	                float3 color : COLOR0;
	                float alpha;
	            };
	            
	            v2f vert (appdata_base v) {
	                v2f o;
	                PositionFog( v.vertex, o.pos, o.fog );
	 	            o.uv1 = TRANSFORM_UV(0);
					
	                float3 viewDir = normalize(ObjSpaceViewDir(v.vertex));
	                o.alpha = dot(viewDir, v.normal) * dot(viewDir,v.normal);
	                
					return o;
	            }
	            
	            half4 frag(v2f i) : COLOR {
	            	half4 texcol = tex2D(_MainTex, i.uv1);
					return half4(texcol.rgb, i.alpha);
				}
	 			
	            ENDCG 
           
	        	SetTexture [_MainTex] {
	        		combine texture
	        	}           
            }
        }
    } 
}

Its frustrating working with a new language/paradigm…

Anyway, this gives me the fade-to-edges that I was talking about. It’s not ideal (ideally, it would just sample that part of the screen, and do a radial blur…), and it uses a fragment program, but it’s a start.

Does anyone have any insights into how to get this same effect without a fragment program?

Thanks,
-T

Okay, I’m going all the way with a grab texture, and doing a radial blur on what it gets. I know the radial blur algorithm, no problem, but I have an issue. When I compile my shader, I get a “profile does not support for statements” error. What profile does (that unity knows how to compile to)? Or do I have to un-roll the loop myself?

-T

Unity compiles to ARBVP/ARBFP profile (ARB vertex and fragment programs), roughly a shader model 2.0 equivalent of Direct3D world. They don’t support dynamic branching and Cg might not be able to unroll loops with variable number of iterations.

Doing radial blur is probably better done as an image effect, by repeatedly rendering texture onto itself, while scaling/rotating it. Similar like Motion Blur image effect does.

Okay, good to know. Thanks! How, though, do I do an image effect that only applies to the area of the screen that a particular object is on, instead of the whole screen?

That would be tricky… I don’t know.

Maybe what you actually want is something akin to a fur shader? With changing it so that there’s more intensity around the edges…

Sorry if that is already what you’re trying to do and I’m just confusing you for no good reason. Don’t have time to play with it myself right now, we’re trying to get some release out of the door… :roll:

Dude. How did I not find that thread in all my searching?! This is exactly the sort of thing that I’m looking for (or at least a GREAT starting point for it). Thank you so much! Hopefully when I start to figure out more of this stuff, I can start contributing back.

Thanks again!