Search code examples
c#unity-game-engineshader

Why the shader is not working on the terrain ? It should draw a circle


I tried to learn from this tutorial : Writing Shaders In Unity

The shader code :

Shader "Custom/TerrainCircle"
{
    Properties
    {
       _MainTex("Texture", 2D) = "white" {}
       _MainColor("Main Color", Color) = (0, 1, 0)
       _CircleColor("Circle Color", Color) = (1, 0, 0)
       _Center("Center", Vector) = (0,0,0,0)
       _Radius("Radius", Range(0, 100)) = 10
       _Thickness("Thickness", Range(0, 100)) = 5
    }
        SubShader
       {
            CGPROGRAM
            #pragma surface surfaceFunc Lambert

            sampler2D _MainTex;
            fixed3 _MainColor;
            fixed3 _CircleColor;
            float3 _Center;
            float _Thickness;
            float _Radius;

            struct Input {
                float2 uv_MainTex;
                float3 worldPos;
            };

            void surfaceFunc(Input IN, inout SurfaceOutput o) {
                half4 c = tex2D(_MainTex, IN.uv_MainTex);
                float dist = distance(_Center, IN.worldPos);

                if (dist > _Radius && dist < (_Radius + _Thickness))
                    o.Albedo = _CircleColor;
                else
                    o.Albedo = c.rgb;

                o.Alpha = c.a;
            }
            ENDCG
       }
}

Then I created a Shader file with the code and a material. Added the Shader to the material. Then dragged the material to the terrain.

Two problems :

  1. When dragging the material to the terrain it put the material only on small part of the terrain on this rock in white. Why it's not applying the material over the whole terrain ?

  2. It's not showing the circle at all. Nothing is drawn. Not even close to the tutorial video in the link.

Material is not over all the terrain and the shader is not working no circle at all

I moved the terrain to the side since the rocks and cliffs are from another asset. But now I can't drag the material over the terrain. The terrain is not accepting the material at all.

The terrain is now on the side but I an't drag the material over it

Still not working not drawing the circle on the terrain. I tried with a new terrain : Terrain (1)

Added the New Material :

New Terrain but not working yet

This is the material settings :

Material settings

This is the shader settings :

Shader settings

And the shader code :

Shader "Custom/TerrainCircle"
{
    Properties
    {
       _MainTex("Texture", 2D) = "white" {}
       _MainColor("Main Color", Color) = (0, 1, 0)
       _CircleColor("Circle Color", Color) = (1, 0, 0)
       _Center("Center", Vector) = (0,0,0,0)
       _Radius("Radius", Range(0, 100)) = 10
       _Thickness("Thickness", Range(0, 100)) = 5
    }
        SubShader
       {
            CGPROGRAM
            #pragma surface surfaceFunc Lambert

            sampler2D _MainTex;
            fixed3 _MainColor;
            fixed3 _CircleColor;
            float3 _Center;
            float _Thickness;
            float _Radius;

            struct Input {
                float2 uv_MainTex;
                float3 worldPos;
            };

            void surfaceFunc(Input IN, inout SurfaceOutput o) {
                half4 c = tex2D(_MainTex, IN.uv_MainTex);
                float dist = distance(_Center, IN.worldPos);

                if (dist > _Radius && dist < (_Radius + _Thickness))
                    o.Albedo = _CircleColor;
                else
                    o.Albedo = c.rgb;

                o.Alpha = c.a;
            }
            ENDCG
       }
}

The shader type I created is : Standard Surface Shader

Solution I had to create a mono script :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExecuteInEditMode]
public class CircleOnTerrain : MonoBehaviour
{
    public Material radiusMaterial;
    public float radius = 1;
    public Color color = Color.white;
    public Color circleColor = Color.blue;
    public float thickness = 1;

    void Update()
    {
        radiusMaterial.SetVector("_Center", transform.position);
        radiusMaterial.SetFloat("_Radius", radius);
        radiusMaterial.SetColor("_MainColor", color);
        radiusMaterial.SetColor("_CircleColor", circleColor);
        radiusMaterial.SetFloat("_Thickness", thickness);
    }
}

Attached the script to a 3d cube and now it's working.


Solution

  • Add your material to the terrain like so:

    enter image description here