Files
HauntedBloodlines/Assets/Obi/Resources/ObiMaterials/URP/ParticleShaderURP.shader
2025-05-29 22:31:40 +03:00

237 lines
6.2 KiB
Plaintext

Shader "Obi/URP/Particles" {
Properties {
_Color ("Particle color", Color) = (1,1,1,1)
_RadiusScale("Radius scale",float) = 1
}
SubShader {
Tags{"RenderPipeline" = "UniversalRenderPipeline"}
Pass {
Name "ParticleFwdBase"
Tags {"Queue"="Geometry" "IgnoreProjector"="True" "RenderType"="Opaque" "LightMode" = "UniversalForward"}
Blend SrcAlpha OneMinusSrcAlpha
HLSLPROGRAM
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
#pragma multi_compile _ _SHADOWS_SOFT
#include "../ObiUtils.cginc"
#include "ObiLightingURP.cginc"
#include "../ObiEllipsoids.cginc"
float4 _Color;
float4 _LightColor0;
struct vin{
float4 vertex : POSITION;
float3 corner : NORMAL;
float4 color : COLOR;
float4 t0 : TEXCOORD0; // ellipsoid t1 vector
float4 t1 : TEXCOORD1; // ellipsoid t2 vector
float4 t2 : TEXCOORD2; // ellipsoid t3 vector
};
struct v2f
{
float4 pos : SV_POSITION;
float4 color : COLOR;
float4 mapping : TEXCOORD0;
float3 viewRay : TEXCOORD1;
float3 lightDir : TEXCOORD2;
float3 a2 : TEXCOORD3;
float3 a3 : TEXCOORD4;
};
struct fout
{
half4 color : SV_Target;
float depth : SV_Depth;
};
v2f vert(vin v)
{
float3x3 P, IP;
BuildParameterSpaceMatrices(v.t0,v.t1,v.t2,P,IP);
float3 worldPos;
float3 view;
float3 eye;
float radius = BuildEllipsoidBillboard(v.vertex,v.corner,P,IP,worldPos,view,eye);
v2f o;
o.pos = mul(UNITY_MATRIX_VP, float4(worldPos,v.vertex.w));
o.mapping = float4(v.corner.xy,1/length(eye),radius); // A[1]
o.viewRay = mul((float3x3)UNITY_MATRIX_V,view); // A[0]
o.color = v.color * _Color;
BuildAuxiliaryNormalVectors(v.vertex,worldPos,view,P,IP,o.a2,o.a3);
o.lightDir = mul((float3x3)UNITY_MATRIX_MV, ObjSpaceLightDir(v.vertex));
return o;
}
fout frag(v2f i)
{
fout fo;
fo.color = half4(0,0,0,i.color.a);
// generate sphere normals:
float3 p,n;
IntersectEllipsoid(i.viewRay,i.mapping, i.a2,i.a3, p, n);
// clip space position:
float4 pos = mul(UNITY_MATRIX_P,float4(p,1.0));
// simple lighting: ambient
half3 amb = SampleSphereAmbient(n);
// simple lighting: diffuse
float ndotl = saturate( dot( n, normalize(i.lightDir) ) );
float atten = Attenuation(p);
// final lit color:
fo.color.rgb = i.color * (_LightColor0 * ndotl * atten + amb);
// normalized device coordinates:
fo.depth = pos.z/pos.w;
// in openGL calculated depth range is <-1,1> map it to <0,1>
#if SHADER_API_OPENGL || SHADER_API_GLCORE || SHADER_API_GLES || SHADER_API_GLES3
fo.depth = 0.5 * fo.depth + 0.5;
#endif
return fo;
}
ENDHLSL
}
Pass {
Name "ShadowCaster"
Tags { "LightMode" = "ShadowCaster" }
Offset 1, 1
Fog {Mode Off}
ZWrite On ZTest LEqual
HLSLPROGRAM
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
#pragma vertex ellipsoidShadowVS
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#pragma multi_compile_shadowcaster
#include "../ObiUtils.cginc"
#include "ObiLightingURP.cginc"
#include "../ObiEllipsoids.cginc"
sampler3D _DitherMaskLOD;
float4 _Color;
struct vin{
float4 vertex : POSITION;
float3 corner : NORMAL;
float4 color : COLOR;
float4 t0 : TEXCOORD0; // ellipsoid t1 vector
float4 t1 : TEXCOORD1; // ellipsoid t2 vector
float4 t2 : TEXCOORD2; // ellipsoid t3 vector
};
struct v2f {
float4 color : COLOR;
float4 mapping : TEXCOORD0;
float3 viewRay : TEXCOORD1;
float3 lightDir : TEXCOORD2;
float3 a2 : TEXCOORD3;
float3 a3 : TEXCOORD4;
};
struct fout
{
half4 color : SV_Target;
float depth : SV_Depth;
};
v2f ellipsoidShadowVS( vin v , out float4 outpos : SV_POSITION )// clip space position output
{
float3x3 P, IP;
BuildParameterSpaceMatrices(v.t0,v.t1,v.t2,P,IP);
float3 worldPos;
float3 view;
float3 eye;
float radius = BuildEllipsoidBillboard(v.vertex,v.corner,P,IP,worldPos,view,eye);
v2f o;
outpos = mul(UNITY_MATRIX_VP, float4(worldPos,v.vertex.w));
o.mapping = float4(v.corner.xy,1/length(eye),radius); // A[1]
o.viewRay = mul((float3x3)UNITY_MATRIX_V,view); // A[0]
o.color = v.color * _Color;
BuildAuxiliaryNormalVectors(v.vertex,worldPos,view,P,IP,o.a2,o.a3);
o.lightDir = WorldSpaceLightDir(v.vertex);
return o;
}
fout frag( v2f i )
{
fout fo;
float3 p,n;
IntersectEllipsoid(i.viewRay,i.mapping,i.a2,i.a3,p, n);
// calculate world space position and normal:
float4 wnormal = mul(UNITY_MATRIX_I_V,float4(n,0));
float4 wpos = mul(UNITY_MATRIX_I_V,float4(p,1));
// calculate clip space position.
float4 clipPos = TransformWorldToHClip(ApplyShadowBias(wpos, wnormal, normalize(i.lightDir)));
#if UNITY_REVERSED_Z
clipPos.z = min(clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE);
#else
clipPos.z = max(clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE);
#endif
fo.color = clipPos.z/clipPos.w; //similar to what SHADOW_CASTER_FRAGMENT does in case there's no depth buffer.
fo.depth = clipPos.z/clipPos.w;
// in openGL calculated depth range is <-1,1> map it to <0,1>
#if SHADER_API_OPENGL || SHADER_API_GLCORE || SHADER_API_GLES || SHADER_API_GLES3
fo.depth = fo.depth*0.5+0.5;
#endif
return fo;
}
ENDHLSL
}
}
}