init
This commit is contained in:
commit
f5c1616018
679 changed files with 188502 additions and 0 deletions
147
Assets/Pixel3D/Shaders/Cel.hlsl
Normal file
147
Assets/Pixel3D/Shaders/Cel.hlsl
Normal 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;
|
||||
}
|
7
Assets/Pixel3D/Shaders/Cel.hlsl.meta
Normal file
7
Assets/Pixel3D/Shaders/Cel.hlsl.meta
Normal file
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4c53fe4732eb54ec9935f558ffd96b23
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
50
Assets/Pixel3D/Shaders/Cel.shader
Normal file
50
Assets/Pixel3D/Shaders/Cel.shader
Normal 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"
|
||||
}
|
||||
}
|
9
Assets/Pixel3D/Shaders/Cel.shader.meta
Normal file
9
Assets/Pixel3D/Shaders/Cel.shader.meta
Normal file
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6ad1e8d49c3a0400cbbe4426084594c1
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
86
Assets/Pixel3D/Shaders/Clouds.shader
Normal file
86
Assets/Pixel3D/Shaders/Clouds.shader
Normal 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
|
||||
}
|
9
Assets/Pixel3D/Shaders/Clouds.shader.meta
Normal file
9
Assets/Pixel3D/Shaders/Clouds.shader.meta
Normal file
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 90c24f969a2a34bac8361bb427173be7
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
254
Assets/Pixel3D/Shaders/DebugWater.hlsl
Normal file
254
Assets/Pixel3D/Shaders/DebugWater.hlsl
Normal 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;
|
||||
}
|
7
Assets/Pixel3D/Shaders/DebugWater.hlsl.meta
Normal file
7
Assets/Pixel3D/Shaders/DebugWater.hlsl.meta
Normal file
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 01ce1153aebdc4727b2d427addcf04fc
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
55
Assets/Pixel3D/Shaders/DebugWater.shader
Normal file
55
Assets/Pixel3D/Shaders/DebugWater.shader
Normal 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"
|
||||
}
|
||||
}
|
9
Assets/Pixel3D/Shaders/DebugWater.shader.meta
Normal file
9
Assets/Pixel3D/Shaders/DebugWater.shader.meta
Normal file
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 998209380528c40ff880075ec487feb1
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
98
Assets/Pixel3D/Shaders/Grass.hlsl
Normal file
98
Assets/Pixel3D/Shaders/Grass.hlsl
Normal 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);
|
||||
}
|
7
Assets/Pixel3D/Shaders/Grass.hlsl.meta
Normal file
7
Assets/Pixel3D/Shaders/Grass.hlsl.meta
Normal file
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b08a6155f438342bd84d5e233d591193
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
54
Assets/Pixel3D/Shaders/Grass.shader
Normal file
54
Assets/Pixel3D/Shaders/Grass.shader
Normal 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"
|
||||
}
|
||||
}
|
9
Assets/Pixel3D/Shaders/Grass.shader.meta
Normal file
9
Assets/Pixel3D/Shaders/Grass.shader.meta
Normal file
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 17870fdf34cac489dae43ec7df57b0ec
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
56
Assets/Pixel3D/Shaders/GrassBlending.shader
Normal file
56
Assets/Pixel3D/Shaders/GrassBlending.shader
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
9
Assets/Pixel3D/Shaders/GrassBlending.shader.meta
Normal file
9
Assets/Pixel3D/Shaders/GrassBlending.shader.meta
Normal file
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ca5c8e1ac59ce49209ce9d675628d119
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
58
Assets/Pixel3D/Shaders/GrassReplacement.shader
Normal file
58
Assets/Pixel3D/Shaders/GrassReplacement.shader
Normal 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"
|
||||
}
|
||||
}
|
9
Assets/Pixel3D/Shaders/GrassReplacement.shader.meta
Normal file
9
Assets/Pixel3D/Shaders/GrassReplacement.shader.meta
Normal file
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cbc7dda786c2d4ea1b999d34d37bd0e5
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
53
Assets/Pixel3D/Shaders/HSV.hlsl
Normal file
53
Assets/Pixel3D/Shaders/HSV.hlsl
Normal 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);
|
||||
}
|
7
Assets/Pixel3D/Shaders/HSV.hlsl.meta
Normal file
7
Assets/Pixel3D/Shaders/HSV.hlsl.meta
Normal file
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c4e23210d3a834f549af2b0e63b852ad
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
93
Assets/Pixel3D/Shaders/Leaf.hlsl
Normal file
93
Assets/Pixel3D/Shaders/Leaf.hlsl
Normal 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);
|
||||
}
|
7
Assets/Pixel3D/Shaders/Leaf.hlsl.meta
Normal file
7
Assets/Pixel3D/Shaders/Leaf.hlsl.meta
Normal file
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9a0054ac68c0c485796c1dd02e52c13b
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
65
Assets/Pixel3D/Shaders/Leaf.shader
Normal file
65
Assets/Pixel3D/Shaders/Leaf.shader
Normal 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"
|
||||
}
|
||||
}
|
9
Assets/Pixel3D/Shaders/Leaf.shader.meta
Normal file
9
Assets/Pixel3D/Shaders/Leaf.shader.meta
Normal file
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0126846fcaefd44e18554c24cb35c4d1
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
200
Assets/Pixel3D/Shaders/LeafCel.hlsl
Normal file
200
Assets/Pixel3D/Shaders/LeafCel.hlsl
Normal 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;
|
||||
}
|
7
Assets/Pixel3D/Shaders/LeafCel.hlsl.meta
Normal file
7
Assets/Pixel3D/Shaders/LeafCel.hlsl.meta
Normal file
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9834a352ef7304a0e9f0353cdd01c693
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
25
Assets/Pixel3D/Shaders/Noise.hlsl
Normal file
25
Assets/Pixel3D/Shaders/Noise.hlsl
Normal 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;
|
||||
}
|
7
Assets/Pixel3D/Shaders/Noise.hlsl.meta
Normal file
7
Assets/Pixel3D/Shaders/Noise.hlsl.meta
Normal file
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3c744bcc3f49848e484e3b786acdd0d2
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
114
Assets/Pixel3D/Shaders/Outline.shader
Normal file
114
Assets/Pixel3D/Shaders/Outline.shader
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
9
Assets/Pixel3D/Shaders/Outline.shader.meta
Normal file
9
Assets/Pixel3D/Shaders/Outline.shader.meta
Normal file
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 302262b99b8a24b059ab70cb2c8f3679
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
161
Assets/Pixel3D/Shaders/PixelPerfectOutline.shader
Normal file
161
Assets/Pixel3D/Shaders/PixelPerfectOutline.shader
Normal 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
|
||||
}
|
9
Assets/Pixel3D/Shaders/PixelPerfectOutline.shader.meta
Normal file
9
Assets/Pixel3D/Shaders/PixelPerfectOutline.shader.meta
Normal file
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 51397c17ee17443279c2548fa2d0dcfc
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
32
Assets/Pixel3D/Shaders/Random.cginc
Normal file
32
Assets/Pixel3D/Shaders/Random.cginc
Normal 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();
|
||||
}
|
7
Assets/Pixel3D/Shaders/Random.cginc.meta
Normal file
7
Assets/Pixel3D/Shaders/Random.cginc.meta
Normal file
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5b23d96a89bae402b91e58a74030e949
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
149
Assets/Pixel3D/Shaders/Water.hlsl
Normal file
149
Assets/Pixel3D/Shaders/Water.hlsl
Normal 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;
|
||||
}
|
7
Assets/Pixel3D/Shaders/Water.hlsl.meta
Normal file
7
Assets/Pixel3D/Shaders/Water.hlsl.meta
Normal file
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fd13bffaf8a99451e801028f91d6d219
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
57
Assets/Pixel3D/Shaders/Water.shader
Normal file
57
Assets/Pixel3D/Shaders/Water.shader
Normal 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"
|
||||
}
|
||||
}
|
9
Assets/Pixel3D/Shaders/Water.shader.meta
Normal file
9
Assets/Pixel3D/Shaders/Water.shader.meta
Normal file
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5582b3353f4e043dbaa1c9b83860ee3e
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue