- Home /
Add Smoothness value to a Shader
This is the Unity Standard Terrain Shader source code, I'm trying to add a smoothness value so I can change the entire terrain smoothness via script, this to make the terrain look's wet, I try this but it give me an error. What can be? Thanks.
Shader "Nature/Terrain" {
Properties {
[HideInInspector] _Control ("Control (RGBA)", 2D) = "red" {}
[HideInInspector] _Splat3 ("Layer 3 (A)", 2D) = "white" {}
[HideInInspector] _Splat2 ("Layer 2 (B)", 2D) = "white" {}
[HideInInspector] _Splat1 ("Layer 1 (G)", 2D) = "white" {}
[HideInInspector] _Splat0 ("Layer 0 (R)", 2D) = "white" {}
[HideInInspector] _Normal3 ("Normal 3 (A)", 2D) = "bump" {}
[HideInInspector] _Normal2 ("Normal 2 (B)", 2D) = "bump" {}
[HideInInspector] _Normal1 ("Normal 1 (G)", 2D) = "bump" {}
[HideInInspector] _Normal0 ("Normal 0 (R)", 2D) = "bump" {}
// used in fallback on old cards & base map
[HideInInspector] _MainTex ("BaseMap (RGB)", 2D) = "white" {}
[HideInInspector] _Color ("Main Color", Color) = (1,1,1,1)
_Glossiness ("Smoothness", Range(0,1)) = 0.5 // NEW LINE
}
CGINCLUDE
#pragma surface surf Lambert vertex:SplatmapVert finalcolor:SplatmapFinalColor finalprepass:SplatmapFinalPrepass finalgbuffer:SplatmapFinalGBuffer noinstancing
#pragma multi_compile_fog
#include "TerrainSplatmapCommon.cginc"
void surf(Input IN, inout SurfaceOutput o)
{
half4 splat_control;
half weight;
half _Glossiness; // NEW LINE
fixed4 mixedDiffuse;
SplatmapMix(IN, splat_control, weight, mixedDiffuse, o.Normal);
o.Albedo = mixedDiffuse.rgb;
o.Alpha = weight;
o.Smoothness = _Glossiness; // NEW LINE
}
ENDCG
Category {
Tags {
"Queue" = "Geometry-99"
"RenderType" = "Opaque"
}
// TODO: Seems like "#pragma target 3.0 _TERRAIN_NORMAL_MAP" can't fallback correctly on less capable devices?
// Use two sub-shaders to simulate different features for different targets and still fallback correctly.
SubShader { // for sm3.0+ targets
CGPROGRAM
#pragma target 3.0
#pragma multi_compile __ _TERRAIN_NORMAL_MAP
ENDCG
}
SubShader { // for sm2.0 targets
CGPROGRAM
ENDCG
}
}
Dependency "AddPassShader" = "Hidden/TerrainEngine/Splatmap/Diffuse-AddPass"
Dependency "BaseMapShader" = "Diffuse"
Dependency "Details0" = "Hidden/TerrainEngine/Details/Vertexlit"
Dependency "Details1" = "Hidden/TerrainEngine/Details/WavingDoublePass"
Dependency "Details2" = "Hidden/TerrainEngine/Details/BillboardWavingDoublePass"
Dependency "Tree0" = "Hidden/TerrainEngine/BillboardTree"
Fallback "Diffuse"
}
Answer by Namey5 · Jul 21, 2021 at 12:18 AM
You need to define the shader property as a uniform outside of the surface function itself;
#include "TerrainSplatmapCommon.cginc"
half _Glossiness; // NEW LINE
void surf(Input IN, inout SurfaceOutput o)
{
half4 splat_control;
half weight;
fixed4 mixedDiffuse;
SplatmapMix(IN, splat_control, weight, mixedDiffuse, o.Normal);
o.Albedo = mixedDiffuse.rgb;
o.Alpha = weight;
o.Smoothness = _Glossiness; // NEW LINE
}
This may not work the way you expect though - in order for terrains to support the number of textures they do, the shader itself is split into multiple passes; each additional pass will use the "AddPassShader" listed at the bottom.
I already know that i need to define the property as uniform to modify it but that's it's not my problem i'm asking if is there a way to add a glossiness value to the unity standard terrain shader. I marked the new properties that give me an error with //NEW LINE Thanks.
If you look closer at my answer you'll notice the definition of the _Glossiness variable has moved. You had originally defined it as a local variable within the surface function, meaning not only will it not register with the material property as it isn't a uniform but it will also throw errors as you are using the local variable without initialising it.
Yes thanks but the problem is not on the variable, it's in the SurfaceOutput that dosen't have a property called Smoothness.
Your answer
