375 lines
8.7 KiB
HLSL
375 lines
8.7 KiB
HLSL
|
|
#ifndef GRASS_DEFINITIONS
|
||
|
|
#define GRASS_DEFINITIONS
|
||
|
|
|
||
|
|
// ================= PRECOMPILER HELPERS ============
|
||
|
|
#if defined(GRASS_USE_TEXTURE_ATLAS) && !defined(SIMPLE_GRASS)
|
||
|
|
#define GRASS_TEXTURE_ATLAS
|
||
|
|
#endif
|
||
|
|
|
||
|
|
// ============================== GLOBAL VARIABLES =============================
|
||
|
|
half _GlobalTargetDensityMultiplier;
|
||
|
|
|
||
|
|
// ================================== VARIABLES ================================
|
||
|
|
sampler2D _ColorMap;
|
||
|
|
half _TargetDensity;
|
||
|
|
half _DensityFalloffStart;
|
||
|
|
half _DensityFalloffScale;
|
||
|
|
half _DensityFalloffPower;
|
||
|
|
|
||
|
|
#ifdef GRASS_FALLBACK_RENDERER
|
||
|
|
int _TargetTessellation;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
half _LODStart;
|
||
|
|
half _LODEnd;
|
||
|
|
int _LODMax;
|
||
|
|
|
||
|
|
half _GrassFadeStart;
|
||
|
|
half _GrassFadeEnd;
|
||
|
|
|
||
|
|
half4 _GrassFloorColor;
|
||
|
|
sampler2D _GrassFloorColorTexture;
|
||
|
|
half _FloorColorStrength;
|
||
|
|
half _FloorColorPower;
|
||
|
|
half _FloorColorOffset;
|
||
|
|
|
||
|
|
half _BurnCutoff;
|
||
|
|
|
||
|
|
//Wind
|
||
|
|
#if defined(GRASS_CALC_GLOBAL_WIND)
|
||
|
|
half4 _WindParams;
|
||
|
|
half _WindRotation;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifdef GRASS_INTERACTION
|
||
|
|
#ifdef GRASS_RENDERTEXTURE_INTERACTION
|
||
|
|
sampler2D _GrassRenderTextureInteraction;
|
||
|
|
sampler2D _GrassRenderTextureBurn;
|
||
|
|
|
||
|
|
//This is the area the grass interaction camera is currently rendering. xy is left bottom, wz is width and height.
|
||
|
|
float4 _GrassRenderTextureArea;
|
||
|
|
#else
|
||
|
|
sampler2D _Displacement;
|
||
|
|
#endif
|
||
|
|
#endif
|
||
|
|
|
||
|
|
//Density for the geom shader. "density" is the sampled texture from _Density.
|
||
|
|
#ifdef UNIFORM_DENSITY
|
||
|
|
half4 _DensityValues;
|
||
|
|
#define DENSITY00 _DensityValues.x
|
||
|
|
#define DENSITY01 _DensityValues.y
|
||
|
|
#define DENSITY02 _DensityValues.z
|
||
|
|
#define DENSITY03 _DensityValues.w
|
||
|
|
#else
|
||
|
|
#ifndef VERTEX_DENSITY
|
||
|
|
sampler2D _DensityTexture;
|
||
|
|
#endif
|
||
|
|
#define DENSITY00 density.r
|
||
|
|
#define DENSITY01 density.g
|
||
|
|
#define DENSITY02 density.b
|
||
|
|
#define DENSITY03 density.a
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if !defined(SIMPLE_GRASS)
|
||
|
|
float _TextureCutoff;
|
||
|
|
|
||
|
|
sampler2D _GrassTex00;
|
||
|
|
#endif
|
||
|
|
#ifndef GRASS_PASS_SHADOWCASTER
|
||
|
|
half4 _Color00;
|
||
|
|
half4 _SecColor00;
|
||
|
|
half3 _SpecColor00;
|
||
|
|
half _Smoothness00;
|
||
|
|
half _Subsurface00;
|
||
|
|
#endif
|
||
|
|
half _MaxHeight00;
|
||
|
|
half _Softness00;
|
||
|
|
half _Weight00;
|
||
|
|
half _Width00;
|
||
|
|
half _MinHeight00;
|
||
|
|
half _AtlasOffset00;
|
||
|
|
#ifdef GRASS_TEXTURE_ATLAS
|
||
|
|
int _TextureAtlasWidth00;
|
||
|
|
int _TextureAtlasHeight00;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if !defined(SIMPLE_GRASS) && !defined(ONE_GRASS_TYPE)
|
||
|
|
sampler2D _GrassTex01;
|
||
|
|
#ifndef GRASS_PASS_SHADOWCASTER
|
||
|
|
half4 _Color01;
|
||
|
|
half4 _SecColor01;
|
||
|
|
half3 _SpecColor01;
|
||
|
|
half _Smoothness01;
|
||
|
|
half _Subsurface01;
|
||
|
|
#endif
|
||
|
|
half _MaxHeight01;
|
||
|
|
half _Softness01;
|
||
|
|
half _Weight01;
|
||
|
|
half _Width01;
|
||
|
|
half _MinHeight01;
|
||
|
|
half _AtlasOffset01;
|
||
|
|
#ifdef GRASS_TEXTURE_ATLAS
|
||
|
|
int _TextureAtlasWidth01;
|
||
|
|
int _TextureAtlasHeight01;
|
||
|
|
#endif
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if !defined(SIMPLE_GRASS) && !defined(ONE_GRASS_TYPE) && !defined(TWO_GRASS_TYPES)
|
||
|
|
sampler2D _GrassTex02;
|
||
|
|
#ifndef GRASS_PASS_SHADOWCASTER
|
||
|
|
half4 _Color02;
|
||
|
|
half4 _SecColor02;
|
||
|
|
half3 _SpecColor02;
|
||
|
|
half _Smoothness02;
|
||
|
|
half _Subsurface02;
|
||
|
|
#endif
|
||
|
|
half _MaxHeight02;
|
||
|
|
half _Softness02;
|
||
|
|
half _Weight02;
|
||
|
|
half _Width02;
|
||
|
|
half _MinHeight02;
|
||
|
|
half _AtlasOffset02;
|
||
|
|
#ifdef GRASS_TEXTURE_ATLAS
|
||
|
|
int _TextureAtlasWidth02;
|
||
|
|
int _TextureAtlasHeight02;
|
||
|
|
#endif
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if !defined(SIMPLE_GRASS) && !defined(ONE_GRASS_TYPE) && !defined(TWO_GRASS_TYPES) && !defined(THREE_GRASS_TYPES)
|
||
|
|
sampler2D _GrassTex03;
|
||
|
|
#ifndef GRASS_PASS_SHADOWCASTER
|
||
|
|
half4 _Color03;
|
||
|
|
half4 _SecColor03;
|
||
|
|
half3 _SpecColor03;
|
||
|
|
half _Smoothness03;
|
||
|
|
half _Subsurface03;
|
||
|
|
#endif
|
||
|
|
half _MaxHeight03;
|
||
|
|
half _Softness03;
|
||
|
|
half _Weight03;
|
||
|
|
half _Width03;
|
||
|
|
half _MinHeight03;
|
||
|
|
half _AtlasOffset03;
|
||
|
|
#ifdef GRASS_TEXTURE_ATLAS
|
||
|
|
int _TextureAtlasWidth03;
|
||
|
|
int _TextureAtlasHeight03;
|
||
|
|
#endif
|
||
|
|
#endif
|
||
|
|
|
||
|
|
half _Disorder;
|
||
|
|
|
||
|
|
//Scaling and offset for _DensityTexture
|
||
|
|
float4 _DensityTexture_ST;
|
||
|
|
|
||
|
|
// ================================= STRUCTS ===================================
|
||
|
|
struct appdata
|
||
|
|
{
|
||
|
|
float4 vertex : POSITION;
|
||
|
|
|
||
|
|
#ifdef VERTEX_DENSITY
|
||
|
|
half4 color : COLOR;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if defined(GRASS_FOLLOW_SURFACE_NORMAL) || defined(GRASS_SURFACE_NORMAL_LIGHTING) || defined(GRASS_HYBRID_NORMAL_LIGHTING)
|
||
|
|
float3 normal : NORMAL;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
float2 uv : TEXCOORD0;
|
||
|
|
//TODO: Add lightmapping, see UnityStandardCore.cginc line 303
|
||
|
|
/*float2 uv1 : TEXCOORD1;
|
||
|
|
#if defined(DYNAMICLIGHTMAP_ON) || defined(UNITY_PASS_META)
|
||
|
|
float2 uv2 : TEXCOORD2;
|
||
|
|
#endif*/
|
||
|
|
};
|
||
|
|
|
||
|
|
struct tess_appdata
|
||
|
|
{
|
||
|
|
float4 vertex : INTERNALTESSPOS;
|
||
|
|
|
||
|
|
#ifdef VERTEX_DENSITY
|
||
|
|
half4 color : COLOR;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if defined(GRASS_FOLLOW_SURFACE_NORMAL) || defined(GRASS_SURFACE_NORMAL_LIGHTING) || defined(GRASS_HYBRID_NORMAL_LIGHTING)
|
||
|
|
float3 normal : NORMAL;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
float2 uv : TEXCOORD0;
|
||
|
|
float3 cameraPos : TEXCOORD1;
|
||
|
|
|
||
|
|
#ifdef GRASS_OBJECT_MODE
|
||
|
|
float3 objectSpacePos : TEXCOORD2;
|
||
|
|
#endif
|
||
|
|
};
|
||
|
|
|
||
|
|
struct HS_CONSTANT_OUTPUT
|
||
|
|
{
|
||
|
|
half edges[3] : SV_TessFactor;
|
||
|
|
half inside : SV_InsideTessFactor;
|
||
|
|
half realTess : REALTESS;
|
||
|
|
half mTess : MEANTESS;
|
||
|
|
};
|
||
|
|
|
||
|
|
struct GS_INPUT
|
||
|
|
{
|
||
|
|
float4 position : SV_POSITION;
|
||
|
|
|
||
|
|
#ifdef VERTEX_DENSITY
|
||
|
|
half4 color : COLOR;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if defined(GRASS_FOLLOW_SURFACE_NORMAL) || defined(GRASS_SURFACE_NORMAL_LIGHTING) || defined(GRASS_HYBRID_NORMAL_LIGHTING)
|
||
|
|
float3 normal : NORMAL;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
float2 uv : TEXCOORD0;
|
||
|
|
float3 cameraPos : TEXCOORD1;
|
||
|
|
|
||
|
|
#if defined(GRASS_HEIGHT_SMOOTHING) || defined(GRASS_WIDTH_SMOOTHING) || defined(GRASS_ALPHA_SMOOTHING)
|
||
|
|
half smoothing : TANGENT2;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifdef GRASS_OBJECT_MODE
|
||
|
|
float3 objectSpacePos : TEXCOORD3;
|
||
|
|
#endif
|
||
|
|
};
|
||
|
|
|
||
|
|
struct GS_OUTPUT {
|
||
|
|
float4 vertex : SV_POSITION;
|
||
|
|
half3 normal : NORMAL;
|
||
|
|
|
||
|
|
#if defined(GRASS_HYBRID_NORMAL_LIGHTING)
|
||
|
|
half3 specularNormal : NORMAL1;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if !defined(SIMPLE_GRASS)
|
||
|
|
half2 uv : TEXCOORD0;
|
||
|
|
int texIndex : TEXCOORD1;
|
||
|
|
|
||
|
|
#ifdef GRASS_TEXTURE_ATLAS
|
||
|
|
int textureAtlasIndex : TEXCOORD2;
|
||
|
|
#endif
|
||
|
|
#endif
|
||
|
|
|
||
|
|
half4 color : COLOR;
|
||
|
|
half4 floorColor : TEXCOORD3;
|
||
|
|
};
|
||
|
|
|
||
|
|
struct FS_INPUT
|
||
|
|
{
|
||
|
|
float3 worldPos : TEXCOORD7;
|
||
|
|
|
||
|
|
half4 color : COLOR;
|
||
|
|
half4 floorColor : TEXCOORD8;
|
||
|
|
|
||
|
|
#if !defined(GRASS_PASS_SHADOWCASTER)
|
||
|
|
float4 pos : SV_POSITION;
|
||
|
|
half3 normal : NORMAL;
|
||
|
|
|
||
|
|
#if !defined GRASS_HDRP
|
||
|
|
#if defined(GRASS_HYBRID_NORMAL_LIGHTING)
|
||
|
|
half3 specularNormal : NORMAL1;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if UNITY_SHOULD_SAMPLE_SH
|
||
|
|
half3 sh : TANGENT;
|
||
|
|
#endif
|
||
|
|
SHADOW_COORDS(4)
|
||
|
|
UNITY_FOG_COORDS(5)
|
||
|
|
float4 ambientOrLightmapUV : TEXCOORD6;
|
||
|
|
#endif
|
||
|
|
#else
|
||
|
|
#if defined(GRASS_URP) || defined(GRASS_HDRP)
|
||
|
|
float4 pos : SV_POSITION;
|
||
|
|
#else
|
||
|
|
V2F_SHADOW_CASTER;
|
||
|
|
#endif
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if !defined(SIMPLE_GRASS)
|
||
|
|
half2 uv : TEXCOORD2;
|
||
|
|
int texIndex : TEXCOORD3;
|
||
|
|
|
||
|
|
#ifdef GRASS_TEXTURE_ATLAS
|
||
|
|
uint textureAtlasIndex : COLOR1;
|
||
|
|
#endif
|
||
|
|
#endif
|
||
|
|
};
|
||
|
|
|
||
|
|
struct GrassSurfaceOutput
|
||
|
|
{
|
||
|
|
half Subsurface;
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
// ========================== HELPER FUNCTIONS ==============================
|
||
|
|
//Random value from 2D value between 0 and 1
|
||
|
|
inline float rand(float2 co){
|
||
|
|
return frac(sin(dot(co.xy, float2(12.9898,78.233))) * 43758.5453);
|
||
|
|
}
|
||
|
|
|
||
|
|
#if defined(GRASS_CALC_GLOBAL_WIND)
|
||
|
|
#include "GrassWind.hlsl"
|
||
|
|
#endif
|
||
|
|
|
||
|
|
//Get the grass normal from the up direction (or bended up direction) of the grass
|
||
|
|
inline half3 getNormal(half3 up, half3 right, half3 lightDir)
|
||
|
|
{
|
||
|
|
#if defined(GRASS_RANDOM_DIR)
|
||
|
|
return normalize(cross(right, up));
|
||
|
|
#else
|
||
|
|
//Calculate everything as if the grass was perpendicular to the direction of the light,
|
||
|
|
//so rotating the camera does not affect the lighting
|
||
|
|
half3 grassSegmentRight = cross(up, lightDir);
|
||
|
|
return normalize(cross(grassSegmentRight, up));
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
inline half nextPow2(half input)
|
||
|
|
{
|
||
|
|
return pow(2, (ceil(log2(input))));
|
||
|
|
}
|
||
|
|
|
||
|
|
//Seriously expensive operation. You shouldn't use this too much. Unfortunately it's needed for the camera/renderer position.
|
||
|
|
//From http://answers.unity3d.com/questions/218333/shader-inversefloat4x4-function.html
|
||
|
|
inline float4x4 inverse(float4x4 input)
|
||
|
|
{
|
||
|
|
#define minor(a,b,c) determinant(float3x3(input.a, input.b, input.c))
|
||
|
|
//determinant(float3x3(input._22_23_23, input._32_33_34, input._42_43_44))
|
||
|
|
|
||
|
|
float4x4 cofactors = float4x4(
|
||
|
|
minor(_22_23_24, _32_33_34, _42_43_44),
|
||
|
|
-minor(_21_23_24, _31_33_34, _41_43_44),
|
||
|
|
minor(_21_22_24, _31_32_34, _41_42_44),
|
||
|
|
-minor(_21_22_23, _31_32_33, _41_42_43),
|
||
|
|
|
||
|
|
-minor(_12_13_14, _32_33_34, _42_43_44),
|
||
|
|
minor(_11_13_14, _31_33_34, _41_43_44),
|
||
|
|
-minor(_11_12_14, _31_32_34, _41_42_44),
|
||
|
|
minor(_11_12_13, _31_32_33, _41_42_43),
|
||
|
|
|
||
|
|
minor(_12_13_14, _22_23_24, _42_43_44),
|
||
|
|
-minor(_11_13_14, _21_23_24, _41_43_44),
|
||
|
|
minor(_11_12_14, _21_22_24, _41_42_44),
|
||
|
|
-minor(_11_12_13, _21_22_23, _41_42_43),
|
||
|
|
|
||
|
|
-minor(_12_13_14, _22_23_24, _32_33_34),
|
||
|
|
minor(_11_13_14, _21_23_24, _31_33_34),
|
||
|
|
-minor(_11_12_14, _21_22_24, _31_32_34),
|
||
|
|
minor(_11_12_13, _21_22_23, _31_32_33)
|
||
|
|
);
|
||
|
|
#undef minor
|
||
|
|
return transpose(cofactors) / determinant(input);
|
||
|
|
}
|
||
|
|
|
||
|
|
inline float3 getCameraPos()
|
||
|
|
{
|
||
|
|
#if defined(GRASS_PASS_SHADOWCASTER) && !defined(GRASS_RANDOM_DIR)
|
||
|
|
return mul(inverse(UNITY_MATRIX_V), float4(0, 0, 0, 1)).xyz;
|
||
|
|
#elif defined(GRASS_HDRP)
|
||
|
|
return float3(0,0,0);
|
||
|
|
#else
|
||
|
|
return _WorldSpaceCameraPos.xyz;
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
#endif
|