This commit is contained in:
Gerard Gascón 2025-02-02 23:44:44 +01:00
commit f5c1616018
679 changed files with 188502 additions and 0 deletions

View file

@ -0,0 +1,147 @@
#include "UnityCG.cginc"
#include "UnityLightingCommon.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
struct v2f
{
float4 pos : SV_POSITION;
float3 worldPos : TEXCOORD0;
float2 uv : TEXCOORD1;
float4 posLight : TEXCOORD3;
float3 normal : NORMAL;
SHADOW_COORDS(2)
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _ShadeTex;
bool _UseShadeTex;
float4 _Color;
float4 _DarknessColor;
float _DarknessMidpoint;
float _ShadowThreshold;
float _ShadeBitDepth;
float remap(float value, float low1, float high1, float low2, float high2)
{
return low2 + (value - low1) * (high2 - low2) / (high1 - low1);
}
// Blend modes
#define multiply(a, b) a * b
#define screen(a, b) 1 - (1 - a) * (1 - b)
#define overlay(a, b) (2 * a * b) * step(0.5, a) + (1 - 2 * (1 - a) * (1 - b)) * (1 - step(0.5, a))
#define hardLight(a, b) overlay(b, a)
#define blend(a, b, mode) float3(mode(a.r, b.r), mode(a.g, b.g), mode(a.b, b.b))
float grayscale(float3 color)
{
return dot(color, float3(0.299, 0.587, 0.114));
}
float3 celShading(v2f i, float attenuation, float4 color, float4 lightColor, float3 lightDir)
{
// Shading texture
// float intensity = remap(dot(i.normal, lightDir), -1, 1, 0, 1);
// float4 shade = tex2D(_ShadeTex, float2(intensity, attenuation));
// shade = screen(shade, _DarknessColor);
float midpoint = remap(_DarknessMidpoint, 0, 1, -1, 1);
float intensity = remap(max(midpoint, dot(i.normal, lightDir)), midpoint, 1, 0, 1);
float4 shade = floor(intensity * _ShadeBitDepth) / _ShadeBitDepth;
if (_UseShadeTex)
{
intensity = remap(dot(i.normal, lightDir), -1, 1, 0, 1);
shade = tex2D(_ShadeTex, float2(intensity, attenuation));
}
shade = screen(shade, _DarknessColor);
float4 shadow = SHADOW_ATTENUATION(i);
shadow = step(_ShadowThreshold, shadow);
#if 0
shadow = screen(shadow, _DarknessColor);
#else
// Remove shadows from the opposite side from light
shadow = dot(i.normal, lightDir) < 0 ? 1 : screen(shadow, _DarknessColor);
#endif
float4 diffuse = color * shade * shadow * lightColor;
return diffuse.rgb;
}
float3 celShadingDirectional(v2f i, float4 color, float4 lightDir, float4 lightColor)
{
return celShading(i, 1, color, lightColor, lightDir.xyz);
}
float3 celShadingPoint(v2f i, float4 color, float4 lightPos, float4 lightColor)
{
float3 vertexToLight = lightPos.xyz - i.worldPos;
float3 lightDir = normalize(vertexToLight);
float sqLength = dot(vertexToLight, vertexToLight);
float attenuation = 1 / (1 + sqLength * lightPos.a);
return celShading(i, attenuation, color, lightColor, lightDir);
}
v2f vert(appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.normal = UnityObjectToWorldNormal(v.normal);
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
TRANSFER_SHADOW(o)
#if defined(DIRECTIONAL_COOKIE)
float4 posWorld = mul(unity_ObjectToWorld, v.vertex);
o.posLight = mul(unity_WorldToLight, posWorld);
#else
o.posLight = 0;
#endif
return o;
}
// https://en.wikibooks.org/wiki/GLSL_Programming/Unity/Multiple_Lights
float4 frag(v2f i) : COLOR
{
fixed4 sample = tex2D(_MainTex, i.uv);
// Light positions and attenuations
float4 lightPos[4] = {
float4(unity_4LightPosX0.x, unity_4LightPosY0.x, unity_4LightPosZ0.x, unity_4LightAtten0.x),
float4(unity_4LightPosX0.y, unity_4LightPosY0.y, unity_4LightPosZ0.y, unity_4LightAtten0.y),
float4(unity_4LightPosX0.z, unity_4LightPosY0.z, unity_4LightPosZ0.z, unity_4LightAtten0.z),
float4(unity_4LightPosX0.w, unity_4LightPosY0.w, unity_4LightPosZ0.w, unity_4LightAtten0.w),
};
// In ForwardBase pass, _WorldSpaceLightPos0 is always directional light
float3 diffuseReflection = celShadingDirectional(i, _Color, _WorldSpaceLightPos0, _LightColor0);
// for (int j = 0; j < 4; j++)
// {
// float3 d = celShadingPoint(i, _Color, lightPos[j], unity_LightColor[j], shadow);
// diffuseReflection = float3(max(diffuseReflection.r, d.r), max(diffuseReflection.g, d.g), max(diffuseReflection.b, d.b));
// }
// diffuseReflection = blend(diffuseReflection, celShadingPoint(i, _Color, lightPos[j], unity_LightColor[j], 0), max);
// diffuseReflection = max(diffuseReflection, celShadingPoint(i, _Color, lightPos[j], unity_LightColor[j], shadow));
#if defined(DIRECTIONAL_COOKIE)
float4 cookieAttenuation = tex2D(_LightTexture0, i.posLight.xy);
#else
float4 cookieAttenuation = 1;
#endif
// return cookieAttenuation;
// return float4(diffuseReflection, 1);
return float4(diffuseReflection, 1) * cookieAttenuation;
}

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4c53fe4732eb54ec9935f558ffd96b23
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,50 @@
// Upgrade NOTE: replaced '_LightMatrix0' with 'unity_WorldToLight'
Shader "Custom/Cel"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
[MaterialToggle] _UseShadeTex ("Use Shade Texture", Float) = 0
_ShadeTex ("Shade Texture", 2D) = "white" {}
_Color ("Color", Color) = (1,1,1,1)
_DarknessColor ("Darkness Color", Color) = (0.5,0.5,0.5,1)
_DarknessMidpoint ("Darkness Midpoint", Range(0, 1)) = 0.5
_ShadowThreshold ("Shadow Threshold", Range(0, 1)) = 0.5
_ShadeBitDepth ("Shade Bit Depth", Range(0, 15)) = 5
}
SubShader
{
Tags
{
"RenderType" = "Opaque"
}
Pass
{
Tags { "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#include "Cel.hlsl"
ENDCG
}
// https://en.wikibooks.org/wiki/Cg_Programming/Unity/Cookies
Pass {
Tags { "LightMode" = "ForwardAdd" }
CGPROGRAM
#pragma multi_compile_lightpass
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#include "Cel.hlsl"
ENDCG
}
UsePass "Legacy Shaders/VertexLit/SHADOWCASTER"
}
}

View file

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 6ad1e8d49c3a0400cbbe4426084594c1
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,86 @@
Shader "Custom/Clouds"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_FineDetail ("Texture", 2D) = "white" {}
_MediumDetail ("Texture", 2D) = "white" {}
_LargeDetail ("Texture", 2D) = "white" {}
}
SubShader
{
Pass
{
Name "Outline"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
// sampler2D
sampler2D _FineDetail;
sampler2D _MediumDetail;
sampler2D _LargeDetail;
float _Coverage;
float _Thickness;
float _Speed;
float _Direction;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
float remap(float value, float low1, float high1, float low2, float high2)
{
return low2 + (value - low1) * (high2 - low2) / (high1 - low1);
}
v2f vert(appdata v)
{
v2f o = { UnityObjectToClipPos(v.vertex), TRANSFORM_TEX(v.uv, _MainTex) };
return o;
}
fixed4 frag(v2f i) : SV_Target
{
float dir = remap(_Direction, 0, 360, 0, 6.28319);
float speed = _Speed / 100;
float2 uv = i.uv;
uv.x += _Time.y * speed * cos(dir);
uv.y += _Time.y * speed * sin(dir);
float fine = tex2D(_FineDetail, uv).a;
float medium = tex2D(_MediumDetail, uv).a;
float large = tex2D(_LargeDetail, uv).a;
// float alpha = large;
float alpha = fine * medium * large;
alpha = alpha > _Coverage ? 1 : alpha;
alpha = 1 - (1 - alpha) * (_Thickness);
// return float4(1, 1, 1, 1);
return float4(alpha.xxx, 1);
}
ENDCG
}
}
Fallback Off
}

View file

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 90c24f969a2a34bac8361bb427173be7
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,254 @@
#include "UnityCG.cginc"
#include "UnityLightingCommon.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
#include "HSV.hlsl"
#include "Noise.hlsl"
float _DebugLevel;
struct appdata
{
float4 vertexOS : POSITION;
};
struct v2f
{
float4 posCS : SV_POSITION;
float4 posWS : TEXCOORD0;
float4 posSS : TEXCOORD1;
float4 posLS : TEXCOORD3;
SHADOW_COORDS(2)
};
float _DepthFadeDist;
float4 _DeepColor;
float4 _ShallowColor;
float _ShadeBitDepth;
float _RefractionSpeed;
float _RefractionStrength;
float _RefractionScale;
float _RefractionDepthFix;
sampler2D _CameraDepthTexture;
sampler2D _CameraOpaqueTexture;
sampler2D _CameraMotionVectorsTexture;
float getRawDepth(float2 uv) {
return SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(uv, 0, 0));
}
float3 getScenePosWS(float2 uv)
{
// Rendering parameters
float near = _ProjectionParams.y;
float far = _ProjectionParams.z;
float2 orthoSize = unity_OrthoParams.xy;
float isOrtho = unity_OrthoParams.w;
float z = getRawDepth(uv);
float2 uvCS = uv * 2 - 1;
// Perspective
float3 rayVSPersp = mul(unity_CameraInvProjection, float4(uvCS, 1, 1) * far);
float3 posVSPersp = rayVSPersp * Linear01Depth(z);
// Orthographic
float3 rayVSOrtho = float3(uvCS * orthoSize, 0);
#if defined(UNITY_REVERSED_Z)
float depthOrtho = -lerp(far, near, z);
#else
float depthOrtho = -lerp(near, far, z);
#endif
float3 posVSOrtho = float3(rayVSOrtho.xy, depthOrtho);
// Blending
float3 posVS = lerp(posVSPersp, posVSOrtho, isOrtho);
float3 scenePosWS = mul(unity_CameraToWorld, float4(posVS.xy, -posVS.z, 1)).xyz;
// Far plane exclusion
#if !defined(EXCLUDE_FAR_PLANE)
float mask = 1;
#elif defined(UNITY_REVERSED_Z)
float mask = z > 0;
#else
float mask = z < 1;
#endif
return scenePosWS * mask;
}
v2f vert(appdata v)
{
v2f o;
o.posCS = UnityObjectToClipPos(v.vertexOS);
o.posWS = mul(unity_ObjectToWorld, v.vertexOS);
o.posSS = ComputeScreenPos(o.posCS);
#if defined(DIRECTIONAL_COOKIE)
o.posLS = mul(unity_WorldToLight, o.posWS);
#else
o.posLS = 0;
#endif
TRANSFER_SHADOW(o)
return o;
}
fixed4 frag(v2f i) : SV_Target
{
// Original UV and depth
float2 uv = i.posSS.xy / i.posSS.w;
float3 scenePosWS = getScenePosWS(uv);
float waterDepth = (i.posWS - scenePosWS).y;
float scaledWaterDepth = saturate(exp(-waterDepth / _DepthFadeDist));
if (_DebugLevel <= -1) {
float4 dbg_color;
HSVLerp_half(_DeepColor, _ShallowColor, 0.5, dbg_color);
return dbg_color;
}
if (_DebugLevel <= 0) {
return float4(1 - waterDepth.xxx, 1);
}
if (_DebugLevel <= 1) {
float dbg_depth = saturate(exp(-waterDepth / _DepthFadeDist));
return float4(dbg_depth.xxx, 1);
}
if (_DebugLevel <= 2) {
float dbg_depth = saturate(exp(-waterDepth / _DepthFadeDist));
float4 dbg_color;
HSVLerp_half(_DeepColor, _ShallowColor, dbg_depth, dbg_color);
return dbg_color;
}
if (_DebugLevel <= 3) {
float dbg_depth = saturate(exp(-waterDepth / _DepthFadeDist));
float4 dbg_color;
HSVLerp_half(_DeepColor, _ShallowColor, dbg_depth, dbg_color);
dbg_color.rgb = RGBToHSV(dbg_color.rgb);
dbg_color.yz = floor(dbg_color.yz * _ShadeBitDepth) / _ShadeBitDepth;
dbg_color.rgb = HSVToRGB(dbg_color.rgb);
return dbg_color;
}
if (_DebugLevel <= 4) {
float2 dbg_offsetXZ_WS = (Unity_GradientNoise_float(i.posWS.xz / _RefractionScale + -_Time * _RefractionSpeed, 1) * 2 - 1) * _RefractionStrength + i.posWS.xz;
float4 dbg_offsetWS = float4(dbg_offsetXZ_WS.x, i.posWS.y, dbg_offsetXZ_WS.y, 1);
float4 dbg_offsetOS = mul(unity_WorldToObject, dbg_offsetWS);
float4 dbg_offsetCS = UnityObjectToClipPos(dbg_offsetOS);
float4 dbg_offsetSS = ComputeScreenPos(dbg_offsetCS);
float2 dbg_offsetUV = dbg_offsetSS.xy / dbg_offsetSS.w;
float2 dbg_mixUV = dbg_offsetUV;
float3 dbg_mixScenePosWS = getScenePosWS(dbg_mixUV);
float dbg_mixWaterDepth = (i.posWS - dbg_mixScenePosWS).y;
float dbg_depth = saturate(exp(-dbg_mixWaterDepth / _DepthFadeDist));
float4 dbg_color;
HSVLerp_half(_DeepColor, _ShallowColor, dbg_depth, dbg_color);
dbg_color.rgb = RGBToHSV(dbg_color.rgb);
dbg_color.yz = floor(dbg_color.yz * _ShadeBitDepth) / _ShadeBitDepth;
dbg_color.rgb = HSVToRGB(dbg_color.rgb);
return dbg_color;
}
if (_DebugLevel <= 5) {
float2 dbg_offsetXZ_WS = (Unity_GradientNoise_float(i.posWS.xz / _RefractionScale + -_Time * _RefractionSpeed, 1) * 2 - 1) * _RefractionStrength + i.posWS.xz;
float4 dbg_offsetWS = float4(dbg_offsetXZ_WS.x, i.posWS.y, dbg_offsetXZ_WS.y, 1);
float4 dbg_offsetOS = mul(unity_WorldToObject, dbg_offsetWS);
float4 dbg_offsetCS = UnityObjectToClipPos(dbg_offsetOS);
float4 dbg_offsetSS = ComputeScreenPos(dbg_offsetCS);
float2 dbg_offsetUV = dbg_offsetSS.xy / dbg_offsetSS.w;
float2 dbg_mixUV = lerp(uv, dbg_offsetUV, saturate(waterDepth));
float3 dbg_mixScenePosWS = getScenePosWS(dbg_mixUV);
float dbg_mixWaterDepth = (i.posWS - dbg_mixScenePosWS).y;
float dbg_depth = saturate(exp(-dbg_mixWaterDepth / _DepthFadeDist));
float4 dbg_color;
HSVLerp_half(_DeepColor, _ShallowColor, dbg_depth, dbg_color);
dbg_color.rgb = RGBToHSV(dbg_color.rgb);
dbg_color.yz = floor(dbg_color.yz * _ShadeBitDepth) / _ShadeBitDepth;
dbg_color.rgb = HSVToRGB(dbg_color.rgb);
return dbg_color;
}
if (_DebugLevel <= 6) {
float2 dbg_offsetXZ_WS = (Unity_GradientNoise_float(i.posWS.xz / _RefractionScale + -_Time * _RefractionSpeed, 1) * 2 - 1) * _RefractionStrength + i.posWS.xz;
float4 dbg_offsetWS = float4(dbg_offsetXZ_WS.x, i.posWS.y, dbg_offsetXZ_WS.y, 1);
float4 dbg_offsetOS = mul(unity_WorldToObject, dbg_offsetWS);
float4 dbg_offsetCS = UnityObjectToClipPos(dbg_offsetOS);
float4 dbg_offsetSS = ComputeScreenPos(dbg_offsetCS);
float2 dbg_offsetUV = dbg_offsetSS.xy / dbg_offsetSS.w;
float2 dbg_mixUV = lerp(uv, dbg_offsetUV, saturate(waterDepth));
float3 dbg_mixScenePosWS = getScenePosWS(dbg_mixUV);
float dbg_mixWaterDepth = (i.posWS - dbg_mixScenePosWS).y;
float dbg_depth = saturate(exp(-dbg_mixWaterDepth / _DepthFadeDist));
// bool dbg_shouldRefract = dbg_mixWaterDepth < -1;
bool dbg_shouldRefract = smoothstep(-_RefractionDepthFix, 0, dbg_mixWaterDepth);
dbg_depth *= dbg_shouldRefract;
// return float4(dbg_shouldRefract.xxx, 1);
float4 dbg_color;
HSVLerp_half(_DeepColor, _ShallowColor, dbg_depth, dbg_color);
dbg_color.rgb = RGBToHSV(dbg_color.rgb);
dbg_color.yz = floor(dbg_color.yz * _ShadeBitDepth) / _ShadeBitDepth;
dbg_color.rgb = HSVToRGB(dbg_color.rgb);
return dbg_color;
}
// Refraction NEW (world space)
float2 offsetXZ_WS = (Unity_GradientNoise_float(i.posWS.xz / _RefractionScale + -_Time * _RefractionSpeed, 1) * 2 - 1) * _RefractionStrength + i.posWS.xz;
float4 offsetWS = float4(offsetXZ_WS.x, i.posWS.y, offsetXZ_WS.y, 1);
float4 offsetOS = mul(unity_WorldToObject, offsetWS);
float4 offsetCS = UnityObjectToClipPos(offsetOS);
float4 offsetSS = ComputeScreenPos(offsetCS);
float2 offsetUV = offsetSS.xy / offsetSS.w;
// Update UV and depth based on refraction
float2 mixUV = lerp(uv, offsetUV, saturate(waterDepth));
float3 mixScenePosWS = getScenePosWS(mixUV);
float mixWaterDepth = (i.posWS - mixScenePosWS).y;
float depth = saturate(exp(-mixWaterDepth / _DepthFadeDist));
// https://forum.unity.com/threads/weird-bug-with-the-refraction-on-my-water-shader.395727/
// https://www.reddit.com/r/godot/comments/1argztb/water_refraction_shader_mask_out_objects_above/
bool shouldRefract = smoothstep(-_RefractionDepthFix, 0, mixWaterDepth);
depth *= shouldRefract;
// Color
float4 color;
HSVLerp_half(_DeepColor, _ShallowColor, depth, color);
color.rgb = RGBToHSV(color.rgb);
color.yz = floor(color.yz * _ShadeBitDepth) / _ShadeBitDepth;
color.rgb = HSVToRGB(color.rgb);
// Shadow (NOT WORKING)
//// float4 shadow = SHADOW_ATTENUATION(i);
//// color *= shadow;
// Cookie
#if defined(DIRECTIONAL_COOKIE)
float4 cookieAttenuation = tex2D(_LightTexture0, i.posLS.xy);
#else
float4 cookieAttenuation = 1;
#endif
// If _CameraOpaqueTexture is used, the following code can be used to blend the water with the scene
// This would be preferred over using transparent shaders
//// float4 baseColor = tex2D(_CameraOpaqueTexture, uv);
//// float4 finalColor = float4(lerp(baseColor.rgb, color.rgb, color.a), 1);
//// return finalColor * cookieAttenuation;
return color * cookieAttenuation;
}

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 01ce1153aebdc4727b2d427addcf04fc
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,55 @@
Shader "Custom/DebugWater"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_DeepColor("Deep Color", Color) = (0, 0, 1, 1)
_ShallowColor("Shallow Color", Color) = (0, 1, 0, 1)
_DepthFadeDist("Depth Fade Distance", Range(0, 10)) = 1
_ShadeBitDepth ("Shade Bit Depth", Range(0, 15)) = 5
_RefractionSpeed("Refraction Speed", Range(0, 3)) = 1
_RefractionStrength("Refraction Strength", Range(0, 3)) = 1
_RefractionScale("Refraction Scale", Range(0, 3)) = 1
_RefractionDepthFix("Refraction Depth Fix", Range(0, 10)) = 1
_DebugLevel("Debug Level", Float) = 0
}
SubShader
{
Tags {
"Queue" = "Transparent"
"RenderType" = "Opaque"
"PreviewType" = "Plane"
}
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
Tags { "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#include "DebugWater.hlsl"
ENDCG
}
Pass
{
Tags { "LightMode" = "ForwardAdd" }
CGPROGRAM
#pragma multi_compile_lightpass
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#include "DebugWater.hlsl"
ENDCG
}
UsePass "Legacy Shaders/VertexLit/SHADOWCASTER"
}
}

View file

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 998209380528c40ff880075ec487feb1
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,98 @@
#include "UnityCG.cginc"
#define UNITY_INDIRECT_DRAW_ARGS IndirectDrawIndexedArgs
#include "UnityIndirect.cginc"
#include "Assets/Pixel3D/Shaders/Random.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float2 colorTexUV : TEXCOORD1;
uint instanceID : SV_InstanceID;
float depth : Depth;
float4 worldPosition : POSITION1;
SHADOW_COORDS(2)
};
struct GrassData
{
float3 position;
float2 colorTexUV;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _ColorTex;
float _AlphaCutout;
float4 _TipColor;
float _TipColorShift;
float _Scale;
float _WindSpeed;
float _WindStrength;
StructuredBuffer<GrassData> _GrassData;
float4 _Rotation;
float _MeshHeight;
float remap(float value, float low1, float high1, float low2, float high2)
{
return low2 + (value - low1) * (high2 - low2) / (high1 - low1);
}
float luma(float3 color)
{
return dot(color, float3(0.2126729, 0.7151522, 0.0721750));
}
// https://gamedev.stackexchange.com/questions/28395/
float3 rotate(float3 v, float4 quaternion)
{
float3 u = quaternion.xyz;
float s = quaternion.w;
return 2 * dot(u, v) * u + (s * s - dot(u, u)) * v + 2 * s * cross(u, v);
}
v2f vert (appdata v, uint svInstanceID : SV_InstanceID)
{
InitIndirectDrawArgs(0);
uint cmdID = GetCommandID(0);
uint instanceID = GetIndirectInstanceID(svInstanceID);
v2f o;
float offset = randValue(instanceID) * 20;
float3 localPosition = v.vertex.xyz + float3(0, _MeshHeight / 2, 0);
localPosition *= _Scale;
localPosition.x += sin((_Time.y + offset) * _WindSpeed + localPosition.y - 0.5) * _WindStrength * pow(v.uv.y, 5);
float4 worldPosition = float4(rotate(localPosition, _Rotation) + _GrassData[instanceID].position, 1);
o.worldPosition = worldPosition;
o.pos = UnityObjectToClipPos(worldPosition);
o.uv = v.uv;
o.colorTexUV = _GrassData[instanceID].colorTexUV;
o.instanceID = instanceID;
o.depth = o.pos.z;
TRANSFER_SHADOW(o)
return o;
}
float4 frag(v2f i) : SV_Target
{
float4 tex = tex2D(_MainTex, i.uv);
if (tex.a < _AlphaCutout)
discard;
float shadow = remap(step(0.75, SHADOW_ATTENUATION(i)), 0, 1, 0.5, 1);
float4 color = tex2D(_ColorTex, i.colorTexUV) * tex;
float lum = luma(color.rgb);
float lumTip = luma(_TipColor.rgb);
float4 tipColor = lerp(color, _TipColor, _TipColorShift);
return float4(lerp(color, tipColor, i.uv.y).rgb * shadow, 1);
}

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b08a6155f438342bd84d5e233d591193
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,54 @@
Shader "Custom/Grass"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_AlphaCutout("Alpha Cutout", Range(0, 1)) = 0.5
_ColorTex("Color Texture", 2D) = "white" {}
_TipColor("Tip Color", Color) = (0, 0, 0, 1)
_TipColorShift("Tip Color Shift", Range(0, 1)) = 0.2
_Scale("Scale", Range(0, 3)) = 0.5
_WindSpeed("Wind Speed", Range(0, 1)) = 0.5
_WindStrength("Wind Strength", Range(0, 1)) = 0.5
}
SubShader
{
Tags {
"RenderType" = "Transparent"
"PreviewType" = "Plane"
// "LightMode" = "ForwardBase"
}
Pass
{
Name "Grass"
Tags { "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#include "Grass.hlsl"
ENDCG
}
Pass
{
Name "GrassAdd"
Tags { "LightMode" = "ForwardAdd" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#include "Grass.hlsl"
ENDCG
}
UsePass "Legacy Shaders/VertexLit/SHADOWCASTER"
}
}

View file

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 17870fdf34cac489dae43ec7df57b0ec
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,56 @@
Shader "Custom/GrassBlending"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _GrassTex;
float _AlphaThreshold;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 color = tex2D(_MainTex, i.uv);
fixed4 grassColor = tex2D(_GrassTex, i.uv);
if (grassColor.a > _AlphaThreshold)
color.rgb = lerp(color.rgb, grassColor.rgb, grassColor.a);
return color;
}
ENDCG
}
}
}

View file

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: ca5c8e1ac59ce49209ce9d675628d119
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,58 @@
Shader "Custom/GrassReplacement"
{
SubShader
{
Tags { "RenderType" = "Opaque" }
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return 0;
}
ENDCG
}
UsePass "Legacy Shaders/VertexLit/SHADOWCASTER"
}
SubShader
{
Tags { "RenderType" = "Transparent" }
UsePass "Custom/Grass/GRASS"
UsePass "Custom/Grass/GRASSADD"
}
SubShader
{
Tags { "RenderType" = "TransparentLeaf" }
CGPROGRAM
#define GRASS_REPLACEMENT 1
ENDCG
UsePass "Custom/Leaf/LEAF"
UsePass "Custom/Leaf/LEAFADD"
}
}

View file

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: cbc7dda786c2d4ea1b999d34d37bd0e5
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,53 @@
half3 RGBToHSV(half3 In)
{
half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
half4 P = lerp(half4(In.bg, K.wz), half4(In.gb, K.xy), step(In.b, In.g));
half4 Q = lerp(half4(P.xyw, In.r), half4(In.r, P.yzx), step(P.x, In.r));
half D = Q.x - min(Q.w, Q.y);
half E = 1e-10;
return half3(abs(Q.z + (Q.w - Q.y)/(6.0 * D + E)), D / (Q.x + E), Q.x);
}
half3 HSVToRGB(half3 In)
{
half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
half3 P = abs(frac(In.xxx + K.xyz) * 6.0 - K.www);
return In.z * lerp(K.xxx, saturate(P - K.xxx), In.y);
}
void HSVLerp_half(half4 A, half4 B, half T, out half4 Out)
{
A.xyz = RGBToHSV(A.xyz);
B.xyz = RGBToHSV(B.xyz);
half t = T; // used to lerp alpha, needs to remain unchanged
half hue;
half d = B.x - A.x; // hue difference
if(A.x > B.x)
{
half temp = B.x;
B.x = A.x;
A.x = temp;
d = -d;
T = 1-T;
}
if(d > 0.5)
{
A.x = A.x + 1;
hue = (A.x + T * (B.x - A.x)) % 1;
}
if(d <= 0.5) hue = A.x + T * d;
half sat = A.y + T * (B.y - A.y);
half val = A.z + T * (B.z - A.z);
half alpha = A.w + t * (B.w - A.w);
half3 rgb = HSVToRGB(half3(hue,sat,val));
Out = half4(rgb, alpha);
}

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c4e23210d3a834f549af2b0e63b852ad
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,93 @@
#define UNITY_INDIRECT_DRAW_ARGS IndirectDrawIndexedArgs
#include "UnityCG.cginc"
#include "UnityIndirect.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
uint instanceID : SV_InstanceID;
float depth : Depth;
SHADOW_COORDS(2)
};
struct LeafData
{
float3 position;
float3 normal;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _AlphaCutout;
float4 _TipColor;
float _TipColorShift;
float _Scale;
float _WindSpeed;
float _WindStrength;
float _Extrude;
StructuredBuffer<LeafData> _LeafData;
float4 _Rotation;
float remap(float value, float low1, float high1, float low2, float high2)
{
return low2 + (value - low1) * (high2 - low2) / (high1 - low1);
}
float luma(float3 color)
{
return dot(color, float3(0.2126729, 0.7151522, 0.0721750));
}
// https://gamedev.stackexchange.com/questions/28395/
float3 rotate(float3 v, float4 quaternion)
{
float3 u = quaternion.xyz;
float s = quaternion.w;
return 2 * dot(u, v) * u + (s * s - dot(u, u)) * v + 2 * s * cross(u, v);
}
v2f vert (appdata v, uint svInstanceID : SV_InstanceID)
{
InitIndirectDrawArgs(0);
uint cmdID = GetCommandID(0);
uint instanceID = GetIndirectInstanceID(svInstanceID);
v2f o;
float3 localPosition = v.vertex.xyz;
// localPosition *= _Scale;
// localPosition.x += sin(_Time.y * _WindSpeed + localPosition.y - 0.5) * _WindStrength * pow(v.uv.y, 5);
float4 worldPosition = float4(rotate(localPosition, _Rotation) + _LeafData[instanceID].position, 1);
worldPosition.xyz += _LeafData[instanceID].normal * _Extrude;
o.pos = UnityObjectToClipPos(worldPosition);
o.uv = v.uv;
o.instanceID = instanceID;
o.depth = o.pos.z;
TRANSFER_SHADOW(o)
return o;
}
float4 frag(v2f i) : SV_Target
{
float4 tex = tex2D(_MainTex, i.uv);
if (tex.a < _AlphaCutout)
discard;
float shadow = remap(step(0.75, SHADOW_ATTENUATION(i)), 0, 1, 0.5, 1);
float4 color = float4(1, 0, 0, 1); //tex2D(_ColorTex, i.colorTexUV) * tex;
float lum = luma(color.rgb);
float lumTip = luma(_TipColor.rgb);
float4 tipColor = lerp(color, _TipColor, _TipColorShift);
return float4(lerp(color, tipColor, i.uv.y).rgb * shadow, 1);
}

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9a0054ac68c0c485796c1dd02e52c13b
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,65 @@
Shader "Custom/Leaf"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_AlphaCutout("Alpha Cutout", Range(0, 1)) = 0.5
[MaterialToggle] _UseShadeTex ("Use Shade Texture", Float) = 0
_ShadeTex ("Shade Texture", 2D) = "white" {}
_Color ("Color", Color) = (1,1,1,1)
_DarknessColor ("Darkness Color", Color) = (0.5,0.5,0.5,1)
_DarknessMidpoint ("Darkness Midpoint", Range(0, 1)) = 0.5
_ShadowThreshold ("Shadow Threshold", Range(0, 1)) = 0.5
_ShadeBitDepth ("Shade Bit Depth", Range(0, 15)) = 5
_TipColor("Tip Color", Color) = (0, 0, 0, 1)
_TipColorShift("Tip Color Shift", Range(0, 1)) = 0.2
_Scale("Scale", Range(0, 3)) = 0.5
_WindSpeed("Wind Speed", Range(0, 1)) = 0.5
_WindStrength("Wind Strength", Range(0, 1)) = 0.5
_Extrude("Extrude", Range(-5, 5)) = 0.5
}
SubShader
{
Tags {
// "RenderType" = "Opaque"
"RenderType" = "TransparentLeaf"
"PreviewType" = "Plane"
}
Pass
{
Name "Leaf"
Tags { "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
// #include "Leaf.hlsl"
#include "LeafCel.hlsl"
ENDCG
}
Pass
{
Name "LeafAdd"
Tags { "LightMode" = "ForwardAdd" }
CGPROGRAM
#pragma multi_compile_lightpass
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
// #include "Leaf.hlsl"
#include "LeafCel.hlsl"
ENDCG
}
UsePass "Legacy Shaders/VertexLit/SHADOWCASTER"
}
}

View file

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 0126846fcaefd44e18554c24cb35c4d1
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,200 @@
#define UNITY_INDIRECT_DRAW_ARGS IndirectDrawIndexedArgs
#include "UnityCG.cginc"
#include "UnityIndirect.cginc"
#include "UnityLightingCommon.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
#include "Assets/Pixel3D/Shaders/Random.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
struct v2f
{
float4 pos : SV_POSITION;
float3 worldPos : TEXCOORD0;
float2 uv : TEXCOORD1;
float4 posLight : TEXCOORD3;
float3 normal : NORMAL;
uint instanceID : SV_InstanceID;
SHADOW_COORDS(2)
};
struct LeafData
{
float3 position;
float3 normal;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _AlphaCutout;
float _Scale;
float _WindSpeed;
float _WindStrength;
float _Extrude;
sampler2D _ShadeTex;
bool _UseShadeTex;
float4 _Color;
float4 _DarknessColor;
float _DarknessMidpoint;
float _ShadowThreshold;
float _ShadeBitDepth;
StructuredBuffer<LeafData> _LeafData;
float4 _Rotation;
float remap(float value, float low1, float high1, float low2, float high2)
{
return low2 + (value - low1) * (high2 - low2) / (high1 - low1);
}
// Blend modes
#define multiply(a, b) a * b
#define screen(a, b) 1 - (1 - a) * (1 - b)
#define overlay(a, b) (2 * a * b) * step(0.5, a) + (1 - 2 * (1 - a) * (1 - b)) * (1 - step(0.5, a))
#define hardLight(a, b) overlay(b, a)
#define blend(a, b, mode) float3(mode(a.r, b.r), mode(a.g, b.g), mode(a.b, b.b))
float grayscale(float3 color)
{
return dot(color, float3(0.299, 0.587, 0.114));
}
float3 celShading(v2f i, float attenuation, float4 color, float4 lightColor, float3 lightDir)
{
// Shading texture
// float intensity = remap(dot(i.normal, lightDir), -1, 1, 0, 1);
// float4 shade = tex2D(_ShadeTex, float2(intensity, attenuation));
// shade = screen(shade, _DarknessColor);
float midpoint = remap(_DarknessMidpoint, 0, 1, -1, 1);
float intensity = remap(max(midpoint, dot(i.normal, lightDir)), midpoint, 1, 0, 1);
float4 shade = floor(intensity * _ShadeBitDepth) / _ShadeBitDepth;
if (_UseShadeTex)
{
intensity = remap(dot(i.normal, lightDir), -1, 1, 0, 1);
shade = tex2D(_ShadeTex, float2(intensity, attenuation));
}
shade = screen(shade, _DarknessColor);
// TODO: Shadow attenuation
// float4 shadow = SHADOW_ATTENUATION(i);
float4 shadow = 1;
shadow = step(_ShadowThreshold, shadow);
#if 0
shadow = screen(shadow, _DarknessColor);
#else
// Remove shadows from the opposite side from light
shadow = dot(i.normal, lightDir) < 0 ? 1 : screen(shadow, _DarknessColor);
#endif
float4 diffuse = color * shade * shadow * lightColor;
return diffuse.rgb;
}
float3 celShadingDirectional(v2f i, float4 color, float4 lightDir, float4 lightColor)
{
return celShading(i, 1, color, lightColor, lightDir.xyz);
}
float3 celShadingPoint(v2f i, float4 color, float4 lightPos, float4 lightColor)
{
float3 vertexToLight = lightPos.xyz - i.worldPos;
float3 lightDir = normalize(vertexToLight);
float sqLength = dot(vertexToLight, vertexToLight);
float attenuation = 1 / (1 + sqLength * lightPos.a);
return celShading(i, attenuation, color, lightColor, lightDir);
}
// https://gamedev.stackexchange.com/questions/28395/
float3 rotate(float3 v, float4 quaternion)
{
float3 u = quaternion.xyz;
float s = quaternion.w;
return 2 * dot(u, v) * u + (s * s - dot(u, u)) * v + 2 * s * cross(u, v);
}
v2f vert(appdata v, uint svInstanceID : SV_InstanceID)
{
InitIndirectDrawArgs(0);
uint cmdID = GetCommandID(0);
uint instanceID = GetIndirectInstanceID(svInstanceID);
float offset = randValue(instanceID) * 20;
float3 localPosition = v.vertex.xyz;
localPosition *= _Scale;
localPosition.x += sin((_Time.y + offset) * _WindSpeed + localPosition.y - 0.5) * _WindStrength * pow(v.uv.y, 5);
float4 worldPosition = float4(rotate(localPosition, _Rotation) + _LeafData[instanceID].position, 1);
// float3 normal = rotate(_LeafData[instanceID].normal, _Rotation);
float3 normal = _LeafData[instanceID].normal;
worldPosition.xyz += normal * _Extrude;
float3 vertex = mul(unity_WorldToObject, worldPosition).xyz;
v2f o;
o.pos = UnityObjectToClipPos(vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.normal = normal;
o.worldPos = worldPosition;
TRANSFER_SHADOW(o)
#if defined(DIRECTIONAL_COOKIE)
float4 posWorld = mul(unity_ObjectToWorld, worldPosition);
o.posLight = mul(unity_WorldToLight, posWorld);
#else
o.posLight = 0;
#endif
return o;
}
// https://en.wikibooks.org/wiki/GLSL_Programming/Unity/Multiple_Lights
float4 frag(v2f i) : COLOR
{
fixed4 sample = tex2D(_MainTex, i.uv);
if (sample.a < _AlphaCutout)
discard;
// return float4(i.normal, 1);
#if defined(GRASS_REPLACEMENT)
return float(0, 0, 0, 0);
#endif
// Light positions and attenuations
float4 lightPos[4] = {
float4(unity_4LightPosX0.x, unity_4LightPosY0.x, unity_4LightPosZ0.x, unity_4LightAtten0.x),
float4(unity_4LightPosX0.y, unity_4LightPosY0.y, unity_4LightPosZ0.y, unity_4LightAtten0.y),
float4(unity_4LightPosX0.z, unity_4LightPosY0.z, unity_4LightPosZ0.z, unity_4LightAtten0.z),
float4(unity_4LightPosX0.w, unity_4LightPosY0.w, unity_4LightPosZ0.w, unity_4LightAtten0.w),
};
// In ForwardBase pass, _WorldSpaceLightPos0 is always directional light
float3 diffuseReflection = celShadingDirectional(i, _Color, _WorldSpaceLightPos0, _LightColor0);
// for (int j = 0; j < 4; j++)
// {
// float3 d = celShadingPoint(i, _Color, lightPos[j], unity_LightColor[j], shadow);
// diffuseReflection = float3(max(diffuseReflection.r, d.r), max(diffuseReflection.g, d.g), max(diffuseReflection.b, d.b));
// }
// diffuseReflection = blend(diffuseReflection, celShadingPoint(i, _Color, lightPos[j], unity_LightColor[j], 0), max);
// diffuseReflection = max(diffuseReflection, celShadingPoint(i, _Color, lightPos[j], unity_LightColor[j], shadow));
#if defined(DIRECTIONAL_COOKIE)
float4 cookieAttenuation = tex2D(_LightTexture0, i.posLight.xy);
#else
float4 cookieAttenuation = 1;
#endif
// return cookieAttenuation;
// return float4(diffuseReflection, 1);
return float4(diffuseReflection, 1) * cookieAttenuation;
}

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9834a352ef7304a0e9f0353cdd01c693
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,25 @@
float2 unity_gradientNoise_dir(float2 p)
{
p = p % 289;
float x = (34 * p.x + 1) * p.x % 289 + p.y;
x = (34 * x + 1) * x % 289;
x = frac(x / 41) * 2 - 1;
return normalize(float2(x - floor(x + 0.5), abs(x) - 0.5));
}
float unity_gradientNoise(float2 p)
{
float2 ip = floor(p);
float2 fp = frac(p);
float d00 = dot(unity_gradientNoise_dir(ip), fp);
float d01 = dot(unity_gradientNoise_dir(ip + float2(0, 1)), fp - float2(0, 1));
float d10 = dot(unity_gradientNoise_dir(ip + float2(1, 0)), fp - float2(1, 0));
float d11 = dot(unity_gradientNoise_dir(ip + float2(1, 1)), fp - float2(1, 1));
fp = fp * fp * fp * (fp * (fp * 6 - 15) + 10);
return lerp(lerp(d00, d01, fp.y), lerp(d10, d11, fp.y), fp.x);
}
float2 Unity_GradientNoise_float(float2 UV, float Scale)
{
return unity_gradientNoise(UV * Scale) + 0.5;
}

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 3c744bcc3f49848e484e3b786acdd0d2
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,114 @@
Shader "Custom/Outline"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
Name "Outline"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _CameraDepthNormalsTexture;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
// o.uv = v.uv;
return o;
}
float4 sobelPass(float2 uv, float thickness)
{
float depth;
float3 normal;
DecodeDepthNormal(tex2D(_CameraDepthNormalsTexture, uv), depth, normal);
float3 offset = float3(1 / _ScreenParams.xy, 0) * thickness;
float leftDepth;
float3 leftNormal;
DecodeDepthNormal(tex2D(_CameraDepthNormalsTexture, uv - offset.xz), leftDepth, leftNormal);
float rightDepth;
float3 rightNormal;
DecodeDepthNormal(tex2D(_CameraDepthNormalsTexture, uv + offset.xz), rightDepth, rightNormal);
float upDepth;
float3 upNormal;
DecodeDepthNormal(tex2D(_CameraDepthNormalsTexture, uv + offset.zy), upDepth, upNormal);
float downDepth;
float3 downNormal;
DecodeDepthNormal(tex2D(_CameraDepthNormalsTexture, uv - offset.zy), downDepth, downNormal);
float sobelDepth = abs(leftDepth - depth) + abs(rightDepth - depth) +
abs(upDepth - depth) + abs(downDepth - depth);
float3 sobelNormal = abs(leftNormal - normal) + abs(rightNormal - normal) +
abs(upNormal - normal) + abs(downNormal - normal);
return float4(sobelNormal, sobelDepth);
}
float _OutlineWidth;
fixed4 frag (v2f i) : SV_Target
{
//float thickness = 1;
float colorShift = 0.5;
fixed4 color = tex2D(_MainTex, i.uv);
float4 sobel = sobelPass(i.uv, _OutlineWidth);
float sobelDepth = round(saturate(sobel.w * 10));
//return float4(sobelDepth.xxx, 1);
fixed4 outlineColor = lerp(color, fixed4(0, 0, 0, 1), colorShift);
float sobelNormal = round(saturate(sobel.x + sobel.y + sobel.z));
//return fixed4(sobelNormal.xxx, 1);
// return fixed4(sobelDepth, sobelNormal, 0, 1);
fixed4 inlineColor = lerp(color, fixed4(1, 1, 1, 1), colorShift);
//float totalSobel = saturate(max(sobelDepth, sobelNormal));
//return fixed4(totalSobel.xxx, 1);
// Depth overrides normal
sobelNormal = sobelDepth > 0 ? 0 : sobelNormal;
color = lerp(color, outlineColor, sobelDepth);
color = lerp(color, inlineColor, sobelNormal);
return fixed4(color.rgb, 1);
}
ENDCG
}
}
}

View file

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 302262b99b8a24b059ab70cb2c8f3679
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,161 @@
Shader "Custom/PixelPerfectOutline"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
Cull Off ZWrite Off ZTest Always
Pass
{
Name "Outline"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _CameraDepthNormalsTexture;
sampler2D _CameraDepthTexture;
float2 _ScreenSize;
float _DepthThreshold;
float _NormalThreshold;
float3 _NormalEdgeBias;
float _AngleThreshold;
float _AngleFactorScale;
bool _DebugOutline;
float4 _OutlineColor;
float4 _EdgeColor;
float _ColorShift;
#define SAMPLE_DEPTH_NORMAL(uv, name) \
float name##Depth; \
float3 name##Normal; \
DecodeDepthNormal(tex2D(_CameraDepthNormalsTexture, uv), name##Depth, name##Normal);
struct PassValue
{
float depth;
float normal;
};
float getDepthDiff(float depth, float neighborDepth)
{
return neighborDepth - depth;
return saturate(neighborDepth - depth);
}
float getNormalDiff(float3 normal, float3 neighborNormal, float depth, float neighborDepth)
{
float3 normalDiff = normal - neighborNormal;
float normalBiasDiff = dot(normalDiff, _NormalEdgeBias);
float normalIndicator = saturate(smoothstep(-0.1, 0.1, normalBiasDiff));
float depthDiff = neighborDepth - depth;
float depthIndicator = saturate(sign(depthDiff * .25 + .0025));
return (1 - dot(normal, neighborNormal)) * normalIndicator * depthIndicator;
}
// Sources:
// https://roystan.net/articles/outline-shader/
// https://www.youtube.com/watch?v=LRDpEnpWohM
// https://www.youtube.com/watch?v=jFevm02NJ5M
// https://github.com/KodyJKing/three.js/blob/outlined-pixel-example/examples/jsm/postprocessing/RenderPixelatedPass.js
PassValue edgePass(float2 uv)
{
// Convolution offset sizes
float2 offset = 1 / _ScreenSize;
// UVs for convolution sampling
float2 top = uv + offset * float2(0, 1);
float2 bottom = uv + offset * float2(0, -1);
float2 left = uv + offset * float2(-1, 0);
float2 right = uv + offset * float2(1, 0);
// Sample depth and normal
SAMPLE_DEPTH_NORMAL(uv, center);
SAMPLE_DEPTH_NORMAL(top, top);
SAMPLE_DEPTH_NORMAL(bottom, bottom);
SAMPLE_DEPTH_NORMAL(left, left);
SAMPLE_DEPTH_NORMAL(right, right);
// Calculate the angle threshold
float angle = 1 - dot(centerNormal, float3(0, 0, 1));
float angleThreshold = saturate((angle - _AngleThreshold) / (1 - _AngleThreshold));
float angleFactor = angleThreshold * _AngleFactorScale + 1;
// Calculate the depth edge
float depthDiff = 0;
depthDiff += getDepthDiff(centerDepth, topDepth);
depthDiff += getDepthDiff(centerDepth, bottomDepth);
depthDiff += getDepthDiff(centerDepth, leftDepth);
depthDiff += getDepthDiff(centerDepth, rightDepth);
float depthThreshold = _DepthThreshold * centerDepth * angleFactor;
float depth = step(depthThreshold, depthDiff);
// Calculate the normal edge
float normalDiff = 0;
normalDiff += getNormalDiff(centerNormal, topNormal, centerDepth, topDepth);
normalDiff += getNormalDiff(centerNormal, bottomNormal, centerDepth, bottomDepth);
normalDiff += getNormalDiff(centerNormal, leftNormal, centerDepth, leftDepth);
normalDiff += getNormalDiff(centerNormal, rightNormal, centerDepth, rightDepth);
float normal = step(_NormalThreshold, normalDiff);
PassValue edge = { depth, normal };
return edge;
}
v2f vert(appdata v)
{
v2f o = { UnityObjectToClipPos(v.vertex), TRANSFORM_TEX(v.uv, _MainTex) };
return o;
}
fixed4 frag(v2f i) : SV_Target
{
float4 color = tex2D(_MainTex, i.uv);
float4 outlineColor = float4(lerp(color.rgb, _OutlineColor.rgb, _OutlineColor.a), 1);
float4 edgeColor = float4(lerp(color.rgb, _EdgeColor.rgb, _EdgeColor.a), 1);
PassValue edge = edgePass(i.uv);
if (_DebugOutline) return float4(edge.depth, edge.normal, 0, 1);
// Any depth overrides normal
edge.normal = step(edge.depth, 0) * edge.normal;
color = lerp(color, outlineColor, edge.depth);
color = lerp(color, edgeColor, edge.normal);
return color;
}
ENDCG
}
}
Fallback Off
}

View file

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 51397c17ee17443279c2548fa2d0dcfc
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,32 @@
uint rng_state;
//Hash invented by Thomas Wang
void wang_hash(uint seed) {
rng_state = (seed ^ 61) ^ (seed >> 16);
rng_state *= 9;
rng_state = rng_state ^ (rng_state >> 4);
rng_state *= 0x27d4eb2d;
rng_state = rng_state ^ (rng_state >> 15);
}
//Xorshift algorithm from George Marsaglia's paper
uint rand_xorshift() {
rng_state ^= (rng_state << 13);
rng_state ^= (rng_state >> 17);
rng_state ^= (rng_state << 5);
return rng_state;
}
float randValue() {
return rand_xorshift() * (1.0 / 4294967296.0);
}
void initRand(uint seed) {
wang_hash(seed);
}
float randValue(uint seed) {
initRand(seed);
return randValue();
}

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5b23d96a89bae402b91e58a74030e949
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,149 @@
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
#include "HSV.hlsl"
#include "Noise.hlsl"
struct appdata
{
float4 vertexOS : POSITION;
};
struct v2f
{
float4 posCS : SV_POSITION;
float4 posWS : TEXCOORD0;
float4 posSS : TEXCOORD1;
float4 posLS : TEXCOORD3;
SHADOW_COORDS(2)
};
float _DepthFadeDist;
float4 _DeepColor;
float4 _ShallowColor;
float _ShadeBitDepth;
float _RefractionSpeed;
float _RefractionStrength;
float _RefractionScale;
float _RefractionDepthFix;
sampler2D _CameraDepthTexture;
sampler2D _CameraOpaqueTexture;
sampler2D _CameraMotionVectorsTexture;
float getRawDepth(float2 uv) {
return SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(uv, 0, 0));
}
float3 getScenePosWS(float2 uv)
{
// Rendering parameters
float near = _ProjectionParams.y;
float far = _ProjectionParams.z;
float2 orthoSize = unity_OrthoParams.xy;
float isOrtho = unity_OrthoParams.w;
float z = getRawDepth(uv);
float2 uvCS = uv * 2 - 1;
// Perspective
float3 rayVSPersp = mul(unity_CameraInvProjection, float4(uvCS, 1, 1) * far);
float3 posVSPersp = rayVSPersp * Linear01Depth(z);
// Orthographic
float3 rayVSOrtho = float3(uvCS * orthoSize, 0);
#if defined(UNITY_REVERSED_Z)
float depthOrtho = -lerp(far, near, z);
#else
float depthOrtho = -lerp(near, far, z);
#endif
float3 posVSOrtho = float3(rayVSOrtho.xy, depthOrtho);
// Blending
float3 posVS = lerp(posVSPersp, posVSOrtho, isOrtho);
float3 scenePosWS = mul(unity_CameraToWorld, float4(posVS.xy, -posVS.z, 1)).xyz;
// Far plane exclusion
#if !defined(EXCLUDE_FAR_PLANE)
float mask = 1;
#elif defined(UNITY_REVERSED_Z)
float mask = z > 0;
#else
float mask = z < 1;
#endif
return scenePosWS * mask;
}
v2f vert(appdata v)
{
v2f o;
o.posCS = UnityObjectToClipPos(v.vertexOS);
o.posWS = mul(unity_ObjectToWorld, v.vertexOS);
o.posSS = ComputeScreenPos(o.posCS);
#if defined(DIRECTIONAL_COOKIE)
o.posLS = mul(unity_WorldToLight, o.posWS);
#else
o.posLS = 0;
#endif
TRANSFER_SHADOW(o)
return o;
}
fixed4 frag(v2f i) : SV_Target
{
// Original UV and depth
float2 uv = i.posSS.xy / i.posSS.w;
float3 scenePosWS = getScenePosWS(uv);
float waterDepth = (i.posWS - scenePosWS).y;
// Refraction NEW (world space)
float2 offsetXZ_WS = (Unity_GradientNoise_float(i.posWS.xz / _RefractionScale + -_Time * _RefractionSpeed, 1) * 2 - 1) * _RefractionStrength + i.posWS.xz;
float4 offsetWS = float4(offsetXZ_WS.x, i.posWS.y, offsetXZ_WS.y, 1);
float4 offsetOS = mul(unity_WorldToObject, offsetWS);
float4 offsetCS = UnityObjectToClipPos(offsetOS);
float4 offsetSS = ComputeScreenPos(offsetCS);
float2 offsetUV = offsetSS.xy / offsetSS.w;
// Update UV and depth based on refraction
float2 mixUV = lerp(uv, offsetUV, saturate(waterDepth));
float3 mixScenePosWS = getScenePosWS(mixUV);
float mixWaterDepth = (i.posWS - mixScenePosWS).y;
float depth = saturate(exp(-mixWaterDepth / _DepthFadeDist));
// https://forum.unity.com/threads/weird-bug-with-the-refraction-on-my-water-shader.395727/
// https://www.reddit.com/r/godot/comments/1argztb/water_refraction_shader_mask_out_objects_above/
bool shouldRefract = smoothstep(-_RefractionDepthFix, 0, mixWaterDepth);
depth *= shouldRefract;
// Color
float4 color;
HSVLerp_half(_DeepColor, _ShallowColor, depth, color);
color.rgb = RGBToHSV(color.rgb);
color.yz = floor(color.yz * _ShadeBitDepth) / _ShadeBitDepth;
color.rgb = HSVToRGB(color.rgb);
// Shadow (NOT WORKING)
//// float4 shadow = SHADOW_ATTENUATION(i);
//// color *= shadow;
// Cookie
#if defined(DIRECTIONAL_COOKIE)
float4 cookieAttenuation = tex2D(_LightTexture0, i.posLS.xy);
#else
float4 cookieAttenuation = 1;
#endif
// If _CameraOpaqueTexture is used, the following code can be used to blend the water with the scene
// This would be preferred over using transparent shaders
//// float4 baseColor = tex2D(_CameraOpaqueTexture, uv);
//// float4 finalColor = float4(lerp(baseColor.rgb, color.rgb, color.a), 1);
//// return finalColor * cookieAttenuation;
return color * cookieAttenuation;
}

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: fd13bffaf8a99451e801028f91d6d219
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,57 @@
Shader "Custom/Water"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_DeepColor("Deep Color", Color) = (0, 0, 1, 1)
_ShallowColor("Shallow Color", Color) = (0, 1, 0, 1)
_DepthFadeDist("Depth Fade Distance", Range(0, 10)) = 1
_ShadeBitDepth ("Shade Bit Depth", Range(0, 15)) = 5
_RefractionSpeed("Refraction Speed", Range(0, 3)) = 1
_RefractionStrength("Refraction Strength", Range(0, 3)) = 1
_RefractionScale("Refraction Scale", Range(0, 3)) = 1
_RefractionDepthFix("Refraction Depth Fix", Range(0, 10)) = 1
}
SubShader
{
Tags {
"Queue" = "Transparent"
"RenderType" = "Opaque"
"PreviewType" = "Plane"
}
// ZWrite On
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
Tags { "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#include "Water.hlsl"
ENDCG
}
Pass
{
Tags { "LightMode" = "ForwardAdd" }
CGPROGRAM
#pragma multi_compile_lightpass
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#include "Water.hlsl"
ENDCG
}
UsePass "Legacy Shaders/VertexLit/SHADOWCASTER"
}
}

View file

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 5582b3353f4e043dbaa1c9b83860ee3e
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant: