121 lines
3.0 KiB
HLSL
121 lines
3.0 KiB
HLSL
#ifndef OBIPARTICLES_INCLUDED
|
|
#define OBIPARTICLES_INCLUDED
|
|
|
|
#include "UnityCG.cginc"
|
|
#include "UnityStandardUtils.cginc"
|
|
#include "AutoLight.cginc"
|
|
|
|
float4x4 _Camera_to_World;
|
|
float4x4 _World_to_Camera;
|
|
float4x4 _InvProj;
|
|
|
|
float3 _FarCorner;
|
|
|
|
float _ThicknessCutoff;
|
|
|
|
sampler2D _MainTex;
|
|
sampler2D _Foam;
|
|
sampler2D _Thickness;
|
|
sampler2D _Normals;
|
|
sampler2D _CameraDepthTexture;
|
|
|
|
struct fout {
|
|
half4 color : COLOR;
|
|
float depth : DEPTH;
|
|
};
|
|
|
|
float3 BillboardSphereNormals(float2 texcoords)
|
|
{
|
|
float3 n;
|
|
n.xy = texcoords*2.0-1.0;
|
|
float r2 = dot(n.xy, n.xy);
|
|
clip (1 - r2); // clip pixels outside circle
|
|
n.z = sqrt(1.0 - r2);
|
|
return n;
|
|
}
|
|
|
|
float BillboardSphereThickness(float2 texcoords)
|
|
{
|
|
float2 n = texcoords*2.0-1.0;
|
|
float r2 = dot(n.xy, n.xy);
|
|
clip (1 - r2); // clip pixels outside circle
|
|
return sqrt(1.0 - r2)*2.0f*exp(-r2*2.0f);
|
|
}
|
|
|
|
half3 SampleSphereAmbient(float3 eyeNormal, float3 eyePos)
|
|
{
|
|
#if UNITY_SHOULD_SAMPLE_SH
|
|
half3 worldNormal = mul(transpose((float3x3)UNITY_MATRIX_V),eyeNormal);
|
|
half3 worldPos = mul(_Camera_to_World,half4(eyePos,1.0));
|
|
return ShadeSHPerPixel(half4(worldNormal, 1.0),half3(0,0,0),worldPos);
|
|
#else
|
|
return UNITY_LIGHTMODEL_AMBIENT;
|
|
#endif
|
|
}
|
|
|
|
float Z2EyeDepth(float z) {
|
|
if (unity_OrthoParams.w < 0.5)
|
|
return LinearEyeDepth(z);
|
|
else{
|
|
|
|
// since we're not using LinearEyeDepth in orthographic, we must reverse depth direction ourselves:
|
|
#if UNITY_REVERSED_Z
|
|
z = 1-z;
|
|
#endif
|
|
|
|
return ((_ProjectionParams.z - _ProjectionParams.y) * z + _ProjectionParams.y);
|
|
}
|
|
}
|
|
|
|
// returns eye space position from linear eye depth.
|
|
float3 EyePosFromDepth(float2 uv,float eyeDepth){
|
|
|
|
if (unity_OrthoParams.w < 0.5){
|
|
float3 ray = (float3(-0.5f,-0.5f,0) + float3(uv,-1)) * _FarCorner;
|
|
return ray * eyeDepth / _FarCorner.z;
|
|
}else{
|
|
return float3((uv-half2(0.5f,0.5f)) * _FarCorner.xy,-eyeDepth);
|
|
}
|
|
}
|
|
|
|
float SetupEyeSpaceFragment(in float2 uv, out float3 eyePos, out float3 eyeNormal)
|
|
{
|
|
float eyeZ = tex2D(_MainTex, uv).r; // we expect linear depth here.
|
|
float thickness = tex2D(_Thickness,uv).a;
|
|
|
|
if (thickness * 10 < _ThicknessCutoff)
|
|
discard;
|
|
|
|
// reconstruct eye space position/direction from frustum corner and camera depth:
|
|
eyePos = EyePosFromDepth(uv,eyeZ);
|
|
|
|
// get normal from texture:
|
|
eyeNormal = (tex2D(_Normals,uv)-0.5) * 2;
|
|
|
|
return thickness;
|
|
}
|
|
|
|
void GetWorldSpaceFragment(in float3 eyePos, in float3 eyeNormal,
|
|
out float3 worldPos, out float3 worldNormal, out float3 worldView)
|
|
{
|
|
// Get world space position, normal and view direction:
|
|
worldPos = mul(_Camera_to_World,half4(eyePos,1)).xyz;
|
|
worldNormal = mul((float3x3)_Camera_to_World,eyeNormal);
|
|
worldView = normalize(UnityWorldSpaceViewDir(worldPos.xyz));
|
|
}
|
|
|
|
void OutputFragmentDepth(in float3 eyePos, inout fout fo)
|
|
{
|
|
float4 clipPos = mul(unity_CameraProjection,float4(eyePos,1));
|
|
fo.depth = clipPos.z/clipPos.w;
|
|
|
|
fo.depth = 0.5*fo.depth + 0.5;
|
|
|
|
// DX11 and some other APIs make use of reverse zbuffer since 5.5. Must inverse value before outputting.
|
|
#if UNITY_REVERSED_Z
|
|
fo.depth = 1-fo.depth;
|
|
#endif
|
|
}
|
|
|
|
#endif
|