Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question How to make terrain shader dynamic?

Discussion in 'Shaders' started by lee3072, Jul 28, 2022.

  1. lee3072

    lee3072

    Joined:
    Jun 11, 2021
    Posts:
    5
    I tried to download the Nature/Terrain/Diffuse Shader and add some custom components to it.
    However, I found out that the terrain shader is rendered only when the application is started.
    Is there any way to make this shader updated every frame?
     
  2. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,690
    There's no such thing as a "dynamic" shader, and there's no need to "update a shader" every frame, so I have no idea what you mean. Shaders (being programs that run on the gpu to determine how objects look when rendered) are executed whenever the object that uses them is rendered, which usually means every frame.

    Can you describe your problem in more detail?
     
  3. lee3072

    lee3072

    Joined:
    Jun 11, 2021
    Posts:
    5
    I was trying to modify the vertex position relative to the user position,
    and was successful on materials and shaders for regular objects.
    However, when I downloaded the terrain shader example and modified it,
    I found out that the rendering only occurs at the beginning of the application.
    It does not get updated as I update the material variables in the c# script.
     
  4. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,690
    There's no difference between materials for "regular" objects and terrain. I took a toon terrain surface shader I found online, slapped a vertex shader on it that inflates vertices along their normal direction, and updated the inflation amount every frame at runtime using this simple script:

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class ModifyTerrain : MonoBehaviour
    5. {
    6.     public float amount = 0;
    7.  
    8.     MaterialPropertyBlock pb;
    9.     Terrain terrain;
    10.  
    11.     private void Awake()
    12.     {
    13.         pb = new MaterialPropertyBlock();
    14.         terrain = GetComponent<Terrain>();
    15.     }
    16.  
    17.     // Update is called once per frame
    18.     void Update()
    19.     {
    20.         terrain.GetSplatMaterialPropertyBlock(pb);
    21.         pb.SetFloat("_Inflation", amount);
    22.         terrain.SetSplatMaterialPropertyBlock(pb);
    23.     }
    24. }
    25.  
    The material is just a basic terrain material with this bit added as the vertex shader:

    Code (CSharp):
    1. float _Inflation;
    2.  
    3. void vert (inout appdata_full v) {
    4.     v.vertex.xyz += v.normal * _Inflation;
    5. }
    Here's the resulting "chubby" terrain: