Search Unity

Shader for highlighting on mouse over, multiple shaders or property on shader?

Discussion in 'Shaders' started by brainwipe, May 22, 2018.

  1. brainwipe

    brainwipe

    Joined:
    Aug 21, 2017
    Posts:
    78
    I am creating a building game where players can pick up and drop buildings. I am using 2018.1 shader graph. When I move the mouse over (I use Raycast), I want the building to have a glowing edge (Fresnel on emission). I do not want any other properties of the building's material to change.

    When not selected, the building is using
    LightweightPipeline/Standard (Simple Lighting)
    and I have set the material base color for each material on the objects. When I programmatically switch shader, then the colors stored in the material are not passed over to the new shader.

    I was hoping that I could access the material property "Color" as used in Standard (Simple Lighting) but it appears that the properties of shaders are globally unique and when I create a blackboard property, it creates a new global property rather than reusing an existing one by convention.

    Rather than switching between shaders, should I be looking to use one shader and then blackboard properties to switch effects on or off? I've found a few sources that recommend that switching is better but I am trying to share shaders between lots of building objects and I do not want to duplicate them.

    Should I manually copy the colours from one shader to another using
    GetColor(...)
    and
    SetColor(...)
    ?

    Thanks in advance for your help.
     
  2. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328
    Here is example of simple outline shader with internal switch, with C# logic:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class outline : MonoBehaviour
    6. {
    7.     public GameObject[] game_object;
    8.    
    9.     void Update ()
    10.     {
    11.         RaycastHit hit;
    12.         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    13.         if ( Physics.Raycast (ray,out hit,100.0f))
    14.         {
    15.             for (int i=0;i<game_object.Length;i++)
    16.             {
    17.                 if (hit.transform.gameObject.name==game_object[i].name)
    18.                 {
    19.                     game_object[i].GetComponent<Renderer>().material.SetFloat("_enable",1.0f);
    20.                 }
    21.                 else
    22.                 {
    23.                     game_object[i].GetComponent<Renderer>().material.SetFloat("_enable",0.0f);                  
    24.                 }
    25.             }
    26.         }
    27.         else
    28.         {
    29.             for (int i=0;i<game_object.Length;i++)
    30.             {
    31.                 game_object[i].GetComponent<Renderer>().material.SetFloat("_enable",0.0f);                  
    32.             }          
    33.         }
    34.     }
    35. }
    Code (CSharp):
    1.  
    2. //https://github.com/przemyslawzaworski/Unity3D-CG-programming
    3. Shader "Outline"
    4. {
    5.     Properties
    6.     {
    7.         _Color ("Mesh color", Color) = (0,0,1,1)
    8.         [Toggle] _enable("Outline enable", Float) = 1
    9.         _outline_thickness ("Outline thickness", Float ) = 0.05
    10.         _outline_color ("Outline color", Color) = (0,0,0,1)
    11.     }
    12.     SubShader
    13.     {
    14.         Tags {"RenderType"="Opaque"}
    15.         Pass
    16.         {
    17.             Name "Outline"
    18.             Cull Front  
    19.             CGPROGRAM
    20.             #pragma vertex vertex_shader
    21.             #pragma fragment pixel_shader
    22.             #pragma target 3.0
    23.            
    24.             float _outline_thickness,_enable;
    25.             float4 _outline_color;
    26.                            
    27.             float4 vertex_shader (float4 vertex:POSITION,float3 normal:NORMAL):SV_POSITION
    28.             {
    29.                 return UnityObjectToClipPos(float4(vertex.xyz+normal*_outline_thickness,1));
    30.             }
    31.            
    32.             float4 pixel_shader(float4 vertex:SV_POSITION):COLOR
    33.             {
    34.                 if (_enable==1)
    35.                 {
    36.                     return float4(_outline_color.rgb,0);
    37.                 }
    38.                 else
    39.                 {
    40.                     discard;
    41.                     return 0;
    42.                 }                      
    43.             }        
    44.             ENDCG
    45.         }
    46.        
    47.         Pass
    48.         {
    49.             Name "FORWARD"
    50.             Tags {"LightMode"="ForwardBase"}
    51.             CGPROGRAM
    52.             #pragma vertex vertex_shader
    53.             #pragma fragment pixel_shader
    54.             #pragma target 3.0
    55.                
    56.             float4 _Color;
    57.                                                
    58.             float4 vertex_shader (float4 vertex:POSITION):SV_POSITION
    59.             {
    60.                 return UnityObjectToClipPos(vertex);
    61.             }
    62.                
    63.             float4 pixel_shader(float4 vertex:SV_POSITION):COLOR
    64.             {
    65.                 return _Color;
    66.             }
    67.             ENDCG
    68.         }
    69.     }
    70. }
     
    Honorsoft and Deleted User like this.
  3. brainwipe

    brainwipe

    Joined:
    Aug 21, 2017
    Posts:
    78
    Thank you for taking the time to reply but this does not answer my question. Firstly, I'm not coding the shaders, I'm using Shader Graph in 2018.1. Also, I don't see how this answers my problem of automatically setting the colour in the shader given the material properties.
     
  4. iamvideep

    iamvideep

    Joined:
    Oct 27, 2017
    Posts:
    118
    What I understand that you just want to change the color between shaders? Do you also want to code the glowing effect? Or the glow is already there?
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,339
    This is the real problem. It's something many people have requested Unity change (or allow users to override) so that you can actually have a property named "_Color" (which would match the Simple Lighting shader's color value). I believe they're working on it, and there might even be a preview branch that has it working, but until it's really out, yes, you'll likely need to use Get/SetColor() calls to copy the color value, and any other values you wish to copy.