Unity 5 Custom Terrian Shader appears blurry.
I created this shader on based on Unity's Legacy Shader, everything works as intended but the textures appear blurry as soon as I replace the terrain with this shader. I tried changing the import settings of the textures and I also tried changing base distance property. From what I have noticed the base distance property of terrain settings had no effect when I was using this custom shader. I tried to use a script to change it during runtime but there's still no effect.
Shader "Normal /LegacyDiffuseRadius" {
Properties{
_Color("Main Color", Color) = (1,1,1,1)
_MainTex("Base (RGB)", 2D) = "white" {}
//Radius
_Center("Center", Vector) = (0,0,0,0)
_Radius("Radius", Float) = 0.5
_RadiusColor("Radius Color", Color) = (1,0,0,1)
_RadiusWidth("Radius Width", Float) = 2
}
SubShader{
Tags{ "RenderType" = "Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Lambert
#pragma surface surf Standard fullforwardshadows
#pragma target 3.0
sampler2D _MainTex;
fixed4 _Color;
//Radius
float3 _Center;
float _Radius;
fixed4 _RadiusColor;
float _RadiusWidth;
struct Input {
float2 uv_MainTex;
float3 worldPos;
};
void surf(Input IN, inout SurfaceOutput o) {
fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
float d = distance(_Center, IN.worldPos);
if (d > _Radius && d < _Radius + _RadiusWidth)
o.Albedo = _RadiusColor;
else
o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
Fallback "Legacy Shaders/VertexLit"
}
Answer by Namey5 · Apr 11, 2017 at 06:09 AM
You can't implicitly use a normal shader with the terrain. It works, but texturing is handled differently for terrains. In Unity, and in general, terrains use 'splat maps'; basically a collection of textures and masks allowing for multiple textures to be applied at once, as well as generating mip maps for the whole terrain. If you don't account for these factors, it will automatically use the highest mip map available, which is why your terrain is blurry. If you want to see an actual terrain shader, you can download the built in shaders and modify Unity's own.
Thank you for your reply. I did figure that out later and I tried to implement the same feature with Nature/Terrain/Diffuse. For some reason I am unable to use StructInput while I use the #include "TerrainSplatmapCommon.cginc". I am very new to shader program$$anonymous$$g and I am just using the trial and error method to implement this. I looked for various tutorials and questions regarding the Struct Input being an error and I couldn't find a possible solution. If you have any idea regarding this could you please point me in the right direction?
In what sense can't you use it?
If you can't define it (i.e. write "struct Input {...};"), chances are it's already been created. "include" files are simply just parts of the shader written in another file, which you can then import into multiple shaders to keep from having to write everything again. As such, Unity might already be using this 'struct' in their own shader, and so you can just remove it from your own shader.
If you are referencing the struct in the surface declaration (i.e. "void surf (Input IN...") and there is an error, chances are Unity's default shader uses a different name for their input struct. Rather than "Input" it might be "TerrainInput" (don't actually know what it would be called). If you want to find the struct they use, navigate to the "Includes" folder in the included shaders you downloaded, and open "TerrainSplatmapCommon.cginc" and browse through it until you find a struct. If there are multiple structs, try all of them starting from the bottom up (easier to do that than explain what each struct is used for), replacing "Input IN" in your shader with "[Actual struct name] IN".
Shader "Nature/Terrain/Diffuse" {
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] _$$anonymous$$ainTex ("Base$$anonymous$$ap (RGB)", 2D) = "white" {}
[HideInInspector] _Color ("$$anonymous$$ain Color", Color) = (1,1,1,1)
}
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;
fixed4 mixedDiffuse;
Splatmap$$anonymous$$ix(IN, splat_control, weight, mixedDiffuse, o.Normal);
o.Albedo = mixedDiffuse.rgb;
o.Alpha = weight;
}
ENDCG
Category {
Tags {
"Queue" = "Geometry-99"
"RenderType" = "Opaque"
}
// TODO: Seems like "#pragma target 3.0 _TERRAIN_NOR$$anonymous$$AL_$$anonymous$$AP" 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
CGPROGRA$$anonymous$$
#pragma target 3.0
#pragma multi_compile __ _TERRAIN_NOR$$anonymous$$AL_$$anonymous$$AP
ENDCG
}
SubShader { // for sm2.0 targets
CGPROGRA$$anonymous$$
ENDCG
}
}
Dependency "AddPassShader" = "Hidden/TerrainEngine/Splatmap/Diffuse-AddPass"
Dependency "Base$$anonymous$$apShader" = "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"
}
Your answer
Follow this Question
Related Questions
Shader breaks on device. 0 Answers
[SOLVED] undeclared identifier X in custom function in shader graph 0 Answers
After upgrading to version 5.3.4f1, my terrain shader no longer works 0 Answers
Shader blurs only one shader 0 Answers
About blur shader 0 Answers