Files
CartoonRPG/Assets/StixGames/GrassShader/GrassInteraction/MeshNormalRenderer.shader
Caleb Sandford deQuincey 02c4b5ab66 Adding in new packages
2025-06-05 22:59:18 +01:00

170 lines
4.6 KiB
Plaintext

Shader "Stix Games/Grass Interaction/Interaction"
{
Properties
{
_InfluenceStrength("Influence Strength", float) = 1
_NormalMap("NormalMap", 2D) = "bump" {}
_InteractionStrength("Interaction Strength", Range(0.01, 1)) = 1
_Mask("Mask", 2D) = "white" {}
_BurnColor("Burn Color", Color) = (1, 1, 1, 1)
_BurnMap("Burn Map", 2D) = "white" {}
_BurnColorStrength("Burn Color Strength", Range(0, 1)) = 0
_BurnStrength("Burn Strength", Range(0, 1)) = 0
}
SubShader
{
Tags { "Queue" = "Transparent" "DisableBatching" = "True" }
LOD 100
Cull Off
ZWrite Off
ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "InteractionFunctions.hlsl"
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float2 uv : TEXCOORD0;
float4 color : COLOR;
};
struct v2f
{
float4 vertex : SV_POSITION;
float3 pos : TEXCOORD0;
half3 tspace0 : TEXCOORD1; // tangent.x, bitangent.x, normal.x
half3 tspace1 : TEXCOORD2; // tangent.y, bitangent.y, normal.y
half3 tspace2 : TEXCOORD3; // tangent.z, bitangent.z, normal.z
float2 uv_normal : TEXCOORD4;
float2 uv_mask : TEXCOORD5;
float2 uv_burn : TEXCOORD6;
float2 screenuv : TEXCOORD7;
float4 interaction_strength: COLOR;
};
sampler2D _GrabInteraction;
sampler2D _GrabBurn;
float _InfluenceStrength;
half4 _BurnColor;
half _InteractionStrength;
sampler2D _NormalMap;
float4 _NormalMap_ST;
sampler2D _Mask;
float4 _Mask_ST;
sampler2D _BurnMap;
float4 _BurnMap_ST;
float _BurnColorStrength;
float _BurnStrength;
v2f vert(appdata v)
{
v2f o;
//Position
o.pos = mul(unity_ObjectToWorld, v.vertex);
o.vertex = UnityObjectToClipPos(v.vertex);
//Vertex color
o.interaction_strength = v.color;
//Texture coordinates
o.uv_normal = TRANSFORM_TEX(v.uv, _NormalMap);
o.uv_mask = TRANSFORM_TEX(v.uv, _Mask);
o.uv_burn = TRANSFORM_TEX(v.uv, _BurnMap);
o.screenuv = ComputeGrabScreenPos(o.vertex);
//Tangent space
half3 wNormal = UnityObjectToWorldNormal(v.normal);
half3 wTangent = UnityObjectToWorldDir(v.tangent.xyz);
// compute bitangent from cross product of normal and tangent
half tangentSign = v.tangent.w;
half3 wBitangent = cross(wNormal, wTangent) * tangentSign;
// output the tangent space matrix
o.tspace0 = half3(wTangent.x, wBitangent.x, wNormal.x);
o.tspace1 = half3(wTangent.y, wBitangent.y, wNormal.y);
o.tspace2 = half3(wTangent.z, wBitangent.z, wNormal.z);
return o;
}
struct InteractionValues
{
float4 Interaction : SV_Target0;
float4 Burn : SV_Target1;
};
InteractionValues frag(v2f i)
{
// sample the normal map, and decode from the Unity encoding
half3 tNormal = UnpackNormal(tex2D(_NormalMap, i.uv_normal));
tNormal.y *= -1;
tNormal.xy *= _InteractionStrength;
// transform normal from tangent to world space
half3 worldNormal;
worldNormal.x = dot(i.tspace0, tNormal);
worldNormal.y = dot(i.tspace1, tNormal);
worldNormal.z = dot(i.tspace2, tNormal);
worldNormal = normalize(worldNormal);
//Smooth out the border of the interaction.
float borderSmoothing = CalculateInteractionBorder(i.pos);
// Get the mask
float mask = tex2D(_Mask, i.uv_mask).r;
//Interaction
float interactionStrength = i.interaction_strength * borderSmoothing * mask;
float3 dir = normalize(worldNormal.xzy * interactionStrength + float3(0, 0, 1) * (1.0f - interactionStrength));
float newIntensity = max(_InfluenceStrength, 0) * (1.0f - dot(dir, float3(0, 0, 1)));
float4 prevCol = tex2D(_GrabInteraction, i.screenuv);
float3 prevNormal = prevCol.xyz * 2 - float3(1, 1, 1);
float prevIntensity = InverseMapIntensity(prevCol.a);
dir = normalize(dir * newIntensity + prevNormal * prevIntensity + 0.0001f * float3(0,0,1));
float newMappedIntensity = MapIntensity(prevIntensity + newIntensity);
//Calculate burn color
float burnColorStrength = _BurnColorStrength * borderSmoothing * mask;
float burnStrength = _BurnStrength * borderSmoothing * mask;
float4 burnTexture = tex2D(_BurnMap, i.uv_burn);
float3 burnColor = lerp(float3(1, 1, 1), burnTexture.rgb * _BurnColor, burnColorStrength);
float burnAmount = 1 - burnStrength * burnTexture.a;
float4 prevBurn = tex2D(_GrabBurn, i.screenuv);
InteractionValues val;
val.Interaction = float4(dir * float3(0.5f, 0.5f, 0.5f) + float3(0.5f, 0.5f, 0.5f), newMappedIntensity);
val.Burn = float4(burnColor, burnAmount) * prevBurn;
return val;
}
ENDCG
}
}
}