As the title says, I’m trying to figure out how to construct a shader that will help me manipulate objects in the scene view.
I will give some preamble, as this may lead to a useful development component.
I’m dealing with game objects that get constructed dynamicly at run-time. In order to position and manipulate them at design time in the scene view, I’m representing them with basic primitives; spheres, cubes, cylinders, …
Specifically a coin shaped cylinder with 12 spheres at the clock positions, forming a ring.
So I’m trying to make a shader that shows this setup as clearly as possible in the scene-view. Just using a simple transparent shader looks really bad on the coin. it completely fails to bring out the edges.
I have made a cG shader that illuminates each vertex according to the angle between the normal and the eye-ray. This is very useful for Scene view as it doesn’t require positioning of lights. It also allows me to distinguish front from back faces by colour.
Shader "Custom/NewShaderXX"
{
SubShader
{
Tags {
"RenderType"="Transparent"
"Queue"="Transparent"
}
LOD 200
// print pixel regardless
ZTest Always
// store depth buffer
ZWrite Off
// front and back faces
Cull Off
// additive blending
Blend One One
Pass {
CGPROGRAM
#pragma vertex myVertexShader
#pragma fragment myFragmentShader
struct VertexShaderInput
{
float4 vertex : POSITION;
float3 normal; // : NORMAL;
};
struct VertexShaderOutput {
float4 pos : POSITION;
float4 color : COLOR;
};
VertexShaderOutput myVertexShader( VertexShaderInput vertexIn )
{
//convert Object Space vertex and normal to View Space
float3 viewSpaceVertexPosition = mul(UNITY_MATRIX_MV, vertexIn.vertex).xyz;
float3 viewSpaceNormal = mul(UNITY_MATRIX_IT_MV, float4(vertexIn.normal, 0)).xyz;
// eye is on origin in viewspace (eye-space)
float3 vertToEye = - viewSpaceVertexPosition;
// theta = +1 if angle = 0, 0 if angle = 90deg, and -1 if 180deg
float cos_theta = dot(
normalize( vertToEye ),
normalize( viewSpaceNormal )
);
// if theta > 0, blue
float blueComponent = ( cos_theta >= 0 ) ? cos_theta : 0;
float redComponent = ( cos_theta < 0 ) ? -cos_theta / 4 : 0;
float4 colorOut = float4( redComponent, 0, blueComponent, 0.1 );
// - - -
VertexShaderOutput vsOut;
vsOut.pos = mul( UNITY_MATRIX_MVP, vertexIn.vertex );
vsOut.color = colorOut; // _MyColor;
return vsOut;
}
half4 myFragmentShader( VertexShaderOutput v2f_data ) : COLOR
{
return half4( v2f_data.color );
}
ENDCG
} // Pass
} // Subshader
}
I’ve set it to blend additively (One One), and set ‘Cull Off’ in order to render back faces also.
Here is the result:
It’s almost there. It’s very easy to see the hidden edges of the coin. However, I can’t figure out how to bring out the ’ coin meets sphere ’ edge.
It seems as though the sphere is getting laminated on top.
I’ve tried quite a few things, but with no success as yet.
How can I achieve the desired effect?
π