wireframe grid shader

hi
sorry for the maybe simple question but i searched everywhere and i could not find this:

is it possibile to program a shader so that it creates infinite squared wireframe grid like in the picture?

i wouldn’t like to use a texture, but a vectorial shape…
so i was thinking about a shader

or would it better to use “draw lines” method?

thank you for any answear!

stefano

384749--13260--$wireframe_plane_163.jpg

This might help you get the results you’re looking for:
http://forum.unity3d.com/viewtopic.php?t=53268&highlight=vector

thankyou!

i did see it, but now bought it and starting experiments

ciaooo
stefano
krur.com

Yes, I know this thread is old, but at the time of writing it comes up as the top hit for a Google search of “Unity Grid Shader” and it still hasn’t received a satisfactory answer. So, for the benefit of anyone coming to this page now, here’s a purely shader-based grid renderer.

For more information on using world coordinates in shader code, see the excellent wikibook http://en.wikibooks.org/wiki/Cg_Programming/Unity/Shading_in_World_Space:

Shader "Grid" {
     
    Properties {
      _GridThickness ("Grid Thickness", Float) = 0.01
      _GridSpacing ("Grid Spacing", Float) = 10.0
      _GridColour ("Grid Colour", Color) = (0.5, 1.0, 1.0, 1.0)
      _BaseColour ("Base Colour", Color) = (0.0, 0.0, 0.0, 0.0)
    }
     
    SubShader {
      Tags { "Queue" = "Transparent" }
     
      Pass {
        ZWrite Off
        Blend SrcAlpha OneMinusSrcAlpha
     
        CGPROGRAM
     
        // Define the vertex and fragment shader functions
        #pragma vertex vert
        #pragma fragment frag
     
        // Access Shaderlab properties
        uniform float _GridThickness;
        uniform float _GridSpacing;
        uniform float4 _GridColour;
        uniform float4 _BaseColour;
     
        // Input into the vertex shader
        struct vertexInput {
            float4 vertex : POSITION;
        };

        // Output from vertex shader into fragment shader
        struct vertexOutput {
          float4 pos : SV_POSITION;
          float4 worldPos : TEXCOORD0;
        };
     
        // VERTEX SHADER
        vertexOutput vert(vertexInput input) {
          vertexOutput output;
          output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
          // Calculate the world position coordinates to pass to the fragment shader
          output.worldPos = mul(_Object2World, input.vertex);
          return output;
        }

        // FRAGMENT SHADER
        float4 frag(vertexOutput input) : COLOR {
          if (frac(input.worldPos.x/_GridSpacing) < _GridThickness || frac(input.worldPos.y/_GridSpacing) < _GridThickness) {
            return _GridColour;
          }
          else {
            return _BaseColour;
          }
        }
    ENDCG
    }
  }
}
1 Like

Nice dude, thanks!
Btw just to add that if you want to draw the grid on the ‘floor’ use the z coordinate of input.World instead of y

Lovely shader @tanoshimi, thanks!

If anyone needs a little more tweakability, I just added X Y spacing as well as an offset:

Shader "Grid" {



    Properties {

      _GridThickness ("Grid Thickness", Float) = 0.01

      _GridSpacingX ("Grid Spacing X", Float) = 1.0

      _GridSpacingY ("Grid Spacing Y", Float) = 1.0

      _GridOffsetX ("Grid Offset X", Float) = 0

      _GridOffsetY ("Grid Offset Y", Float) = 0

      _GridColour ("Grid Colour", Color) = (0.5, 1.0, 1.0, 1.0)

      _BaseColour ("Base Colour", Color) = (0.0, 0.0, 0.0, 0.0)

    }



    SubShader {

      Tags { "Queue" = "Transparent" }



      Pass {

        ZWrite Off

        Blend SrcAlpha OneMinusSrcAlpha



        CGPROGRAM



        // Define the vertex and fragment shader functions

        #pragma vertex vert

        #pragma fragment frag



        // Access Shaderlab properties

        uniform float _GridThickness;

        uniform float _GridSpacingX;

        uniform float _GridSpacingY;

        uniform float _GridOffsetX;

        uniform float _GridOffsetY;

        uniform float4 _GridColour;

        uniform float4 _BaseColour;



        // Input into the vertex shader

        struct vertexInput {

            float4 vertex : POSITION;

        };



        // Output from vertex shader into fragment shader

        struct vertexOutput {

          float4 pos : SV_POSITION;

          float4 worldPos : TEXCOORD0;

        };



        // VERTEX SHADER

        vertexOutput vert(vertexInput input) {

          vertexOutput output;

          output.pos = mul(UNITY_MATRIX_MVP, input.vertex);

          // Calculate the world position coordinates to pass to the fragment shader

          output.worldPos = mul(_Object2World, input.vertex);

          return output;

        }



        // FRAGMENT SHADER

        float4 frag(vertexOutput input) : COLOR {

          if (frac((input.worldPos.x + _GridOffsetX)/_GridSpacingX) < (_GridThickness / _GridSpacingX) ||
              frac((input.worldPos.y + _GridOffsetY)/_GridSpacingY) < (_GridThickness / _GridSpacingY)) {

            return _GridColour;

          }

          else {

            return _BaseColour;

          }

        }

    ENDCG

    }

  }

}
1 Like

Thanks for sharing the shader code.
I’m trying to use it but it results in a lot of aliasing. How can I reduce it?
Thanks

Modified from here
http://www.gamedev.net/topic/529926-terrain-contour-lines-using-pixel-shader/

Don’t know how it works realy. Just cg port.

Unity5 surface shader:

Shader "Custom/XZGrid"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
        _GridStep ("Grid size", Float) = 10
        _GridWidth ("Grid width", Float) = 1
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200
       
        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
            float3 worldPos;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;
        float _GridStep;
        float _GridWidth;
       
        void surf (Input IN, inout SurfaceOutputStandard o) {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
           
            // grid overlay
            float2 pos = IN.worldPos.xz / _GridStep;
            float2 f  = abs(frac(pos)-.5);
            float2 df = fwidth(pos) * _GridWidth;
            float2 g = smoothstep(-df ,df , f);
            float grid = 1.0 - saturate(g.x * g.y);
            c.rgb = lerp(c.rgb, float3(1,1,1), grid);
           
            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
3 Likes

I changed tanoshimi’s code to give better support for anti-aliasing, which I noticed when I tried to resize player window.

Shader “Grid” {

Properties {
_GridThickness (“Grid Thickness”, Float) = 0.01
_GridSpacing (“Grid Spacing”, Float) = 10.0
_GridColour (“Grid Colour”, Color) = (1.0, 1.0, 1.0, 1.0)
_BaseColour (“Base Colour”, Color) = (1.0, 0.0, 0.0, 0.0)
}

SubShader {
Tags { “Queue” = “Transparent” }

Pass {
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha

CGPROGRAM

// Define the vertex and fragment shader functions
#pragma vertex vert
#pragma fragment frag

// Access Shaderlab properties
uniform float _GridThickness;
uniform float _GridSpacing;
uniform float4 _GridColour;
uniform float4 _BaseColour;

// Input into the vertex shader
struct vertexInput {
float4 vertex : POSITION;
};

// Output from vertex shader into fragment shader
struct vertexOutput {
float4 pos : SV_POSITION;
float4 worldPos : TEXCOORD0;
};

// VERTEX SHADER
vertexOutput vert(vertexInput input) {
vertexOutput output;
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
// Calculate the world position coordinates to pass to the fragment shader
output.worldPos = mul(_Object2World, input.vertex);
return output;
}

// FRAGMENT SHADER
float4 frag(vertexOutput input) : COLOR {
float xfrac = frac(input.worldPos.x / _GridThickness) - 0.5;
float yfrac = frac(input.worldPos.y / _GridThickness) - 0.5;
float dist = xfrac * xfrac + yfrac * yfrac;
float strength = max(0.5 - dist, 0) * 2;
strength = pow(strength, 5);

bool xvalid = false;
bool yvalid = false;

if (input.worldPos.x > 0)
{
if (fmod(input.worldPos.x, _GridSpacing) < _GridThickness)
xvalid = true;
}
else
{
if (fmod(input.worldPos.x, _GridSpacing) < _GridThickness - _GridSpacing)
xvalid = true;
}

if (input.worldPos.y > 0)
{
if (fmod(input.worldPos.y, _GridSpacing) < _GridThickness)
yvalid = true;
}
else
{
if (fmod(input.worldPos.y, _GridSpacing) < _GridThickness - _GridSpacing)
yvalid = true;
}

if (xvalid && yvalid)
return _GridColour * strength + _BaseColour * (1.0 - strength);
else
return _BaseColour;
}
ENDCG
}
}
}

Thanks for this! It’s perfect for my prototyping needs and may carry even further forward.

Great code, works perfectly, but I adjusted it slightly so that you get a real grid pattern with cross hatching, since you code only produced lines in one direction. I’m putting it up in case some people need it and don’t know how to adjust Shader code.

Shader "Grid" {
     
    Properties {
      _GridThickness ("Grid Thickness", Float) = 0.01
      _GridSpacing ("Grid Spacing", Float) = 10.0
      _GridColour ("Grid Colour", Color) = (0.5, 0.5, 0.5, 0.5)
      _BaseColour ("Base Colour", Color) = (0.0, 0.0, 0.0, 0.0)
    }
     
    SubShader {
      Tags { "Queue" = "Transparent" }
     
      Pass {
        ZWrite Off
        Blend SrcAlpha OneMinusSrcAlpha
     
        CGPROGRAM
     
        // Define the vertex and fragment shader functions
        #pragma vertex vert
        #pragma fragment frag
     
        // Access Shaderlab properties
        uniform float _GridThickness;
        uniform float _GridSpacing;
        uniform float4 _GridColour;
        uniform float4 _BaseColour;
     
        // Input into the vertex shader
        struct vertexInput {
            float4 vertex : POSITION;
        };

        // Output from vertex shader into fragment shader
        struct vertexOutput {
          float4 pos : SV_POSITION;
          float4 worldPos : TEXCOORD0;
        };
     
        // VERTEX SHADER
        vertexOutput vert(vertexInput input) {
          vertexOutput output;
          output.pos = UnityObjectToClipPos(input.vertex);
          // Calculate the world position coordinates to pass to the fragment shader
          output.worldPos = mul(unity_ObjectToWorld, input.vertex);
          return output;
        }

        // FRAGMENT SHADER
        float4 frag(vertexOutput input) : COLOR {
          if (frac(input.worldPos.x/_GridSpacing) < _GridThickness || frac(input.worldPos.y/_GridSpacing) < _GridThickness) {
            return _GridColour;
          }
         else if (frac(input.worldPos.x/_GridSpacing) < _GridThickness || frac(input.worldPos.z/_GridSpacing) < _GridThickness) {
            return _GridColour;
         }
          else {
            return _BaseColour;
          }
        }
    ENDCG
    }
  }
}

Hate to Necro, but for @Zer0_Ph34r shader just switch up line 52: if (frac(input.worldPos.x/_GridSpacing) < _GridThickness || frac(input.worldPos.z/_GridSpacing) < _GridThickness) {

1 Like

Is there any way to make it so that the grid isn’t based off world position and instead use the object position?

The current implementation makes the grid stay “Locked” to the world, so moving objects creates a weird effect where it doesn’t seem as if the object was moving. (I just started looking into shaders for a small project)

How do you get the shader to show up in the scene view?