Files
CartoonRPG/Assets/StixGames/GrassShader/GrassDefinitionsAndFunctions.hlsl

375 lines
8.7 KiB
HLSL
Raw Normal View History

2025-06-05 22:59:18 +01:00
#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