shader RGB colour based on y-value vertex

Hello all,

I'm looking for a shader that gives me the looks of a GEO application like arcgis or global mapper. Shader should colour a mesh based on the y-position of the vertices. Unfortunately I have minimal experience with programming.

Does anyone know where i can find this kind of shader or how to make it ?

Preferably it should also be able to show the wireframe of the mesh at the same time and take into account vertex tangents like common GEO hill shaders do (steep is darker).

Kind regards,

Frans

3 Answers

3

You could try this one. It shows 4 different colors based on the world position of the vertexes plus a water level color which all can be adjusted in the inspector or by script (colors and height level). The normals are used to calculate the slope or hill shading (steeper is darker) which can be faded with the last input value. A wireframe mode is not (yet) implemented.

Use Material.SetColor and Material.SetFloat to change the input values by script.

Switch off any light sources and disable fog for best results.

Shader "Global-Mapper" {
Properties {
    _PeakColor ("PeakColor", Color) = (0.8,0.9,0.9,1)   
    _PeakLevel ("PeakLevel", Float) = 300
    _Level3Color ("Level3Color", Color) = (0.75,0.53,0,1)
    _Level3 ("Level3", Float) = 200
    _Level2Color ("Level2Color", Color) = (0.69,0.63,0.31,1)
    _Level2 ("Level2", Float) = 100
    _Level1Color ("Level1Color", Color) = (0.65,0.86,0.63,1)
    _WaterLevel ("WaterLevel", Float) = 0
    _WaterColor ("WaterColor", Color) = (0.37,0.78,0.92,1)
    _Slope ("Slope Fader", Range (0,1)) = 0
}
SubShader {
    Tags { "RenderType" = "Opaque" }
    Fog { Mode Off }
    Tags { "LightMode" = "Always" }
    CGPROGRAM
    #pragma surface surf Lambert vertex:vert
    struct Input {
        float3 customColor;
        float3 worldPos;
    };
    void vert (inout appdata_full v, out Input o) {
        o.customColor = abs(v.normal.y);
    }
    float _PeakLevel;
    float4 _PeakColor;
    float _Level3;
    float4 _Level3Color;
    float _Level2;
    float4 _Level2Color;
    float _Level1;
    float4 _Level1Color;
    float _Slope;
    float _WaterLevel;
    float4 _WaterColor;
    void surf (Input IN, inout SurfaceOutput o) {
        if (IN.worldPos.y >= _PeakLevel)
            o.Albedo = _PeakColor;
        if (IN.worldPos.y <= _PeakLevel)
            o.Albedo = lerp(_Level3Color, _PeakColor, (IN.worldPos.y - _Level3)/(_PeakLevel - _Level3));
        if (IN.worldPos.y <= _Level3)
            o.Albedo = lerp(_Level2Color, _Level3Color, (IN.worldPos.y - _Level2)/(_Level3 - _Level2));
        if (IN.worldPos.y <= _Level2)
            o.Albedo = lerp(_Level1Color, _Level2Color, (IN.worldPos.y - _WaterLevel)/(_Level2 - _WaterLevel));
        if (IN.worldPos.y <= _WaterLevel)
            o.Albedo = _WaterColor;
        o.Albedo *= saturate(IN.customColor + _Slope);          
    }
    ENDCG
}
Fallback "Diffuse"
}

And yes, it is my first shader :-)

Any comments / improvements are welcome.

That is spectacular!

the shader

Very nice, I've been trying to do that as well but I wasn't half as successful as you!

Hi efge,

Exactly what I was looking for. Very good for a first shader.

Ethernal thanks

Frans