I am trying to combine two shaders for my point cloud mesh. 1st shader is a geometry shader which has 1 texture and a way to control the point size.
2nd shader blends multiple textures based on the height of point in the mesh. I am very very new to shader coding and would like to combine the two.
If i literally copy paste them both into one file, then blending does not work. I would like to blend the textures and control the point cloud size.
I am very lost and would really appreciate any help.
1st Shader
Shader "Custom/TerrainShaderAll"{
Properties{
_DeepWater("DeepWater", 2D) = "white" {}
_ShallowWater("ShallowWater", 2D) = "white" {}
_Sand("Sand", 2D) = "white" {}
_Grass("Grass", 2D) = "white"{}
_Tree("Tree", 2D) = "white" {}
_Rock("Rock", 2D) = "white" {}
_Snow("Snow", 2D) = "white" {}
_e1("e1", 2D) = "white" {}
_e2("e2", 2D) = "white" {}
_e3("e3", 2D) = "white" {}
_WaterLevel("Water Level", Float) = 0
_LayerSize("LayerSize", Float) = 20
_BlendRange("BlendRange", Range(0,1.5)) = 0.1
}
Subshader{
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _DeepWater;
uniform sampler2D _ShallowWater;
uniform sampler2D _Sand;
uniform sampler2D _Grass;
uniform sampler2D _Tree;
uniform sampler2D _Rock;
uniform sampler2D _Snow;
uniform sampler2D _e1;
uniform sampler2D _e2;
uniform sampler2D _e3;
uniform float _WaterLevel;
uniform float _LayerSize;
uniform float _BlendRange;
struct fragmentInput {
float4 pos : SV_POSITION;
float4 texcoord : TEXCOORD0;
float4 blend: COLOR;
};
fragmentInput vert(appdata_base v)
{
float NumOfTextures = 10;
fragmentInput o;
o.pos = UnityObjectToClipPos(v.vertex);
o.texcoord = v.texcoord;
float MinValue = _WaterLevel - (NumOfTextures - 1) * _LayerSize;
float MaxValue = (_WaterLevel + _LayerSize);
float Blend = MaxValue - v.vertex.z;
Blend = clamp(Blend / (NumOfTextures * _LayerSize), 0, 1);
o.blend.xyz = 0;
o.blend.w = Blend;
return o;
}
inline float CalculateBlend(float TextureFloat)
{
return 1 - clamp((1 - TextureFloat) / _BlendRange, 0, 1);
}
inline float4 DoBlending(float TextureID, float TextureFloat, fixed4 BaseTexture, fixed4 BlendTexture)
{
float Blend = CalculateBlend(clamp(TextureFloat - TextureID, 0, 1));
return lerp(BaseTexture, BlendTexture, Blend);
}
float4 frag(fragmentInput i) : COLOR0
{
float NumOfTextures = 10;
float TextureFloat = i.blend.w * NumOfTextures;
if (TextureFloat < 1)
{
fixed4 DeepWaterColor = tex2D(_DeepWater, i.texcoord);
fixed4 ShallowWaterColor = tex2D(_ShallowWater, i.texcoord);
return DoBlending(0, TextureFloat, DeepWaterColor, ShallowWaterColor);
}
if (TextureFloat < 2)
{
fixed4 ShallowWaterColor = tex2D(_ShallowWater, i.texcoord);
fixed4 SandColor = tex2D(_Sand, i.texcoord);
return DoBlending(1, TextureFloat, ShallowWaterColor, SandColor);
}
if (TextureFloat < 3)
{
fixed4 SandColor = tex2D(_Sand, i.texcoord);
fixed4 GrassColor = tex2D(_Grass, i.texcoord);
return DoBlending(2, TextureFloat, SandColor, GrassColor);
}
if (TextureFloat < 4)
{
fixed4 GrassColor = tex2D(_Grass, i.texcoord);
fixed4 TreeColor = tex2D(_Tree, i.texcoord);
return DoBlending(3, TextureFloat, GrassColor, TreeColor);
}
if (TextureFloat < 5)
{
fixed4 TreeColor = tex2D(_Tree, i.texcoord);
fixed4 RockColor = tex2D(_Rock, i.texcoord);
return DoBlending(4, TextureFloat, TreeColor, RockColor);
}
if (TextureFloat < 6)
{
fixed4 RockColor = tex2D(_Rock, i.texcoord);
fixed4 SnowColor = tex2D(_Snow, i.texcoord);
return DoBlending(5, TextureFloat, RockColor, SnowColor);
}
if (TextureFloat < 7)
{
fixed4 SnowColor = tex2D(_Snow, i.texcoord);
fixed4 e1Color = tex2D(_e1, i.texcoord);
return DoBlending(6, TextureFloat, SnowColor, e1Color);
}
if (TextureFloat < 8)
{
fixed4 e1Color = tex2D(_e1, i.texcoord);
fixed4 e2Color = tex2D(_e2, i.texcoord);
return DoBlending(7, TextureFloat, e1Color, e2Color);
}
if (TextureFloat < 9)
{
fixed4 e2Color = tex2D(_e2, i.texcoord);
fixed4 e3Color = tex2D(_e3, i.texcoord);
return DoBlending(8, TextureFloat, e2Color, e3Color);
}
fixed4 e3Color = tex2D(_e3, i.texcoord);
return e3Color;
fixed4 DeepWaterColor = tex2D(_DeepWater, i.texcoord);
fixed4 ShallowWaterColor = tex2D(_ShallowWater, i.texcoord);
return lerp(DeepWaterColor, ShallowWaterColor, i.blend.w);
}
ENDCG
}
}
FallBack "Diffuse"
}
2nd Shader
Shader "Custom/PointCloudGeom" {
Properties {
[NoScaleOffset]_MainTex ("Texture", 2D) = "white" {}
[NoScaleOffset]_UVMap ("UV", 2D) = "white" {}
_PointSize("Point Size", Float) = 4.0
_Color ("PointCloud Color", Color) = (1, 1, 1, 1)
[Toggle(USE_DISTANCE)]_UseDistance ("Scale by distance?", float) = 0
}
SubShader
{
Cull Off
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma geometry geom
#pragma fragment frag
#pragma shader_feature USE_DISTANCE
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
float _PointSize;
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_TexelSize;
sampler2D _UVMap;
float4 _UVMap_TexelSize;
struct g2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
[maxvertexcount(4)]
void geom(point v2f i[1], inout TriangleStream<g2f> triStream)
{
g2f o;
float4 v = i[0].vertex;
v.y = -v.y;
// TODO: interpolate uvs on quad
float2 uv = i[0].uv;
float2 p = _PointSize * 0.001;
p.y *= _ScreenParams.x / _ScreenParams.y;
o.vertex = UnityObjectToClipPos(v);
#ifdef USE_DISTANCE
o.vertex += float4(-p.x, p.y, 0, 0);
#else
o.vertex += float4(-p.x, p.y, 0, 0) * o.vertex.w;
#endif
o.uv = uv;
triStream.Append(o);
o.vertex = UnityObjectToClipPos(v);
#ifdef USE_DISTANCE
o.vertex += float4(-p.x, -p.y, 0, 0);
#else
o.vertex += float4(-p.x, -p.y, 0, 0) * o.vertex.w;
#endif
o.uv = uv;
triStream.Append(o);
o.vertex = UnityObjectToClipPos(v);
#ifdef USE_DISTANCE
o.vertex += float4(p.x, p.y, 0, 0);
#else
o.vertex += float4(p.x, p.y, 0, 0) * o.vertex.w;
#endif
o.uv = uv;
triStream.Append(o);
o.vertex = UnityObjectToClipPos(v);
#ifdef USE_DISTANCE
o.vertex += float4(p.x, -p.y, 0, 0);
#else
o.vertex += float4(p.x, -p.y, 0, 0) * o.vertex.w;
#endif
o.uv = uv;
triStream.Append(o);
}
v2f vert (appdata v)
{
v2f o;
o.vertex = v.vertex;
o.uv = v.uv;
return o;
}
fixed4 frag (g2f i) : SV_Target
{
float2 uv = tex2D(_UVMap, i.uv);
if(any(uv <= 0 || uv >= 1))
discard;
// offset to pixel center
uv += 0.5 * _MainTex_TexelSize.xy;
return tex2D(_MainTex, uv) * _Color;
}
ENDCG
}
}
If i literally copy paste them both into one file
Yeah, that's not how programming works. Each shader has avert
function and afrag
function. You need to combine the math in these to do what you want at each vertex and each pixel. The second shader also has a geom function, but the first doesn't. Good luck. - Draco18s no longer trusts SEvert
controls position andfrag
controls color? would I be correct in saying that? and I cannot have two verts and frags blocks in the same shader file? or is there an execution order? - Anurag Tiwarigeom
.vert
is more for vertex color (where complex color calculations are done once per vertex, then each pixel is computed based on effective its barycenter and the 3 verts). Recommended reading: one two - Draco18s no longer trusts SEgeom
controls position,vert
andfrag
control color. and can target SV_Target or Color0 or Color1? color(texture
) is what im after. - Anurag TiwariRecommended reading: one two
great suggestions thank you - Anurag Tiwari