GQ_Communicate/GQ_TongXin/Assets/Obi/Resources/ObiMaterials/ObiParticles.cginc

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