zed-ar-headfree-passthrough/Assets/ZED/SDK/Helpers/Shaders/Lighting/ZED_Lighting.cginc

164 lines
No EOL
5 KiB
HLSL

//======= Copyright (c) Stereolabs Corporation, All rights reserved. ===============
#if !defined(ZED_LIGHTING)
#define ZED_LIGHTING
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "UnityPBSLighting.cginc"
#include "AutoLight.cginc"
/******************************************************************/
/************** Point lights information **************************/
/******************************************************************/
struct ZED_PointLight{
float4 color;
float range;
float3 position;
};
/******************************************************************/
/************** Spot lights information **************************/
/******************************************************************/
struct ZED_SpotLight{
float4 color;
float3 position;
float4 direction;
float4 params;// angle, intensity, 1/range, cone interior
};
sampler2D _NormalsTex;
uniform float4 _CameraRotationQuat;
#if defined(ZED_SPOT_LIGHT_DECLARATION)
StructuredBuffer<ZED_SpotLight> spotLights;
int numberSpotLights;
#endif
#if defined(ZED_POINT_LIGHT_DECLARATION)
StructuredBuffer<ZED_PointLight> pointLights;
int numberPointLights;
#endif
//FallOff the light
float FallOff(float dist, float inverseRange, float coeff) {
return lerp( 1.0, ( 1.0 - pow( dist * inverseRange * inverseRange, coeff ) ), 1 );
}
#define ZED_WORLD_DIR(index) float3 worldDirection : TEXCOORD##index;
#define ZED_TRANSFER_WORLD_DIR(o) o.worldDirection = mul(unity_ObjectToWorld, v.vertex).xyz - _WorldSpaceCameraPos;
#define GET_XYZ(o, z, world) world = (o.worldDirection/ o.pos.w) * z + _WorldSpaceCameraPos;
float _Metallic;
// Create a point light or spot light to be used per Unity
UnityLight CreateLight (float3 pos, float4 color, float3 worldPos, float3 normal) {
UnityLight light;
light.dir = pos;
light.color = color;
light.ndotl = DotClamped(normal, light.dir);
return light;
}
//Compute the light for all light
#if defined(ZED_SPOT_LIGHT_DECLARATION) || defined(ZED_POINT_LIGHT_DECLARATION)
half4 computeLighting(float3 albedo, float3 normals, float3 worldPos, float alpha) {
fixed3 worldViewDir = normalize(UnityWorldSpaceViewDir(worldPos));
#ifdef UNITY_COMPILER_HLSL
SurfaceOutputStandard o = (SurfaceOutputStandard)0;
#else
SurfaceOutputStandard o;
#endif
o.Albedo.rgb = albedo;
o.Emission = 0.0;
o.Alpha = 1.0;
o.Occlusion = 1.0;
o.Metallic = _Metallic;
o.Normal.rgb = mul((float3x3)unity_CameraToWorld, normals);
float3 specularTint;
float oneMinusReflectivity;
o.Albedo.rgb = DiffuseAndSpecularFromMetallic(
albedo, o.Metallic, specularTint, oneMinusReflectivity
);
float4 c = 0;
// Setup lighting environment
UnityGI gi;
UNITY_INITIALIZE_OUTPUT(UnityGI, gi);
gi.indirect.diffuse = 0;
gi.indirect.specular = 0;
int indexPointLights = 0;
//For the point light
#if defined(ZED_POINT_LIGHT_DECLARATION)
UNITY_LOOP
for (indexPointLights = 0; indexPointLights < numberPointLights; indexPointLights++) {
float3 lightVec = pointLights[indexPointLights].position - worldPos;
if (pointLights[indexPointLights].range - length(lightVec) < 0) {
continue;
}
float att = FallOff(dot(lightVec, lightVec), 1 / pointLights[indexPointLights].range, 0.2);
float v = dot(lightVec, float3(o.Normal.x, o.Normal.y, o.Normal.z));
//Remove light from backward
//UNITY_BRANCH
if (dot(lightVec, float3(o.Normal.x, o.Normal.y, o.Normal.z)) <= 0.0) {
continue;
}
UnityLight p = CreateLight(lightVec, pointLights[indexPointLights].color*att*alpha, worldPos, o.Normal.rgb);
gi.light = p;
c += UNITY_BRDF_PBS(o.Albedo.rgb, specularTint, oneMinusReflectivity, 0, o.Normal.rgb, normalize(_WorldSpaceCameraPos - worldPos), p, gi.indirect);
c.a = 1.0;
}
#endif
c.a = 1.0;
//For the spot light
#if defined(ZED_SPOT_LIGHT_DECLARATION)
int indexSpotLights = 0;
UNITY_LOOP
for (indexSpotLights = 0; indexSpotLights < numberSpotLights; indexSpotLights++) {
float3 lightVec = spotLights[indexSpotLights].position - worldPos;
float att = FallOff(dot(lightVec, lightVec), spotLights[indexSpotLights].params.z, 0.8);
float3 dirSpotToWorld = -lightVec;
float dotDirectionWorld = dot(normalize(dirSpotToWorld), spotLights[indexSpotLights].direction.xyz);
float angleWorld = degrees(acos(dotDirectionWorld));
float angleMax = spotLights[indexSpotLights].params.x / 2.0;
UNITY_BRANCH
if (dotDirectionWorld < 0 || dotDirectionWorld < spotLights[indexSpotLights].direction.w) {
continue;
}
else {
float angleP = angleMax*(1 - spotLights[indexSpotLights].params.w);
UNITY_BRANCH
if (angleP < angleWorld && angleWorld < angleMax) {
att *= (angleMax - angleWorld) / (angleMax - angleP);
}
}
att = saturate(att);
UnityLight p = CreateLight(lightVec, (spotLights[indexSpotLights].color)*att*alpha, worldPos, o.Normal.rgb);
gi.light = p;
c += UNITY_BRDF_PBS(o.Albedo.rgb, specularTint, oneMinusReflectivity, 1, o.Normal.rgb, normalize(_WorldSpaceCameraPos - worldPos), p, gi.indirect);
c.a = 1.0;
}
#endif
return c;
}
#endif
#endif