diff options
Diffstat (limited to 'Shaders/cloud/pbr.cginc')
| -rw-r--r-- | Shaders/cloud/pbr.cginc | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/Shaders/cloud/pbr.cginc b/Shaders/cloud/pbr.cginc new file mode 100644 index 0000000..8b7405a --- /dev/null +++ b/Shaders/cloud/pbr.cginc @@ -0,0 +1,139 @@ +#ifndef __PBR_INC__ +#define __PBR_INC__ + +#include "AutoLight.cginc" +#include "eyes_data.cginc" +#include "UnityPBSLighting.cginc" + +float _Enable_Custom_Cubemap; +UNITY_DECLARE_TEXCUBE(_Custom_Cubemap); + +sampler2D _Matcap; +float _Matcap_Str; +float _Enable_Matcap; +float _Matcap_Mode; + +UnityIndirect GetIndirect(v2f i, float3 view_dir, float smoothness) { + UnityIndirect indirect; + indirect.diffuse = 0; + indirect.specular = 0; + + #if defined(VERTEXLIGHT_ON) + indirect.diffuse = i.vertexLightColor; + #endif + + #if defined(FORWARD_BASE_PASS) + indirect.diffuse += max(0, ShadeSH9(float4(i.normal, 1))); + float3 reflect_dir = reflect(-view_dir, i.normal); + // There's a nonlinear relationship between mipmap level and roughness. + float roughness = 1 - smoothness; + roughness *= 1.7 - .7 * roughness; + float3 env_sample; + if (_Enable_Custom_Cubemap) { + env_sample = UNITY_SAMPLE_TEXCUBE_LOD( + _Custom_Cubemap, + reflect_dir, + roughness * UNITY_SPECCUBE_LOD_STEPS); + } else { + env_sample = UNITY_SAMPLE_TEXCUBE_LOD( + unity_SpecCube0, + reflect_dir, + roughness * UNITY_SPECCUBE_LOD_STEPS); + } + if (_Enable_Matcap) { + // identity: (a, b, c) and (c, c, -(a +b)) are perpendicular to each other + float3 ortho_1 = normalize(float3(view_dir.z, view_dir.z, -(view_dir.y + view_dir.x))); + float3 ortho_2 = cross(view_dir, ortho_1); + float2 matcap_uv = (float2(dot(i.normal, ortho_1), dot(i.normal, ortho_2)) + 1) * .43; + float iddx = ddx(i.uv.x); + float iddy = ddy(i.uv.y); + float3 matcap = tex2Dgrad(_Matcap, matcap_uv, iddx, iddy) * _Matcap_Str; + + int mode = round(_Matcap_Mode); + switch (mode) { + case 1: + indirect.specular = clamp(env_sample + matcap, 0, 1); + break; + case 2: + indirect.specular = clamp(env_sample * matcap, 0, 1); + break; + case 3: + indirect.specular = clamp(matcap, 0, 1); + break; + case 4: + indirect.specular = clamp(env_sample - matcap, 0, 1); + break; + } + } else { + indirect.specular = env_sample; + } + #endif + + return indirect; +} + +UnityLight GetLight(v2f i) +{ + UNITY_LIGHT_ATTENUATION(attenuation, 0, i.worldPos.xyz); + float3 light_color = _LightColor0.rgb * attenuation; + + UnityLight light; + light.color = light_color; + #if defined(POINT) || defined(POINT_COOKIE) || defined(SPOT) + light.dir = normalize(_WorldSpaceLightPos0.xyz - i.worldPos); + #else + light.dir = _WorldSpaceLightPos0.xyz; + #endif + light.ndotl = DotClamped(i.normal, light.dir); + + return light; +} + +void initNormal(inout v2f i) +{ + i.normal = normalize(i.normal); +} + +float4 light(inout v2f i, + float4 albedo, + float metallic, + float smoothness) +{ + initNormal(i); + + float3 specular_tint; + float one_minus_reflectivity; + albedo.rgb = DiffuseAndSpecularFromMetallic( + albedo, metallic, specular_tint, one_minus_reflectivity); + + float3 view_dir = normalize(_WorldSpaceCameraPos - i.worldPos); + float3 pbr = UNITY_BRDF_PBS(albedo, + specular_tint, + one_minus_reflectivity, + smoothness, + i.normal, + view_dir, + GetLight(i), + GetIndirect(i, view_dir, smoothness)).rgb; + + return float4(saturate(pbr), albedo.a); +} + +float getWorldSpaceDepth(in float4 world_pos) +{ + float4 clip_pos = mul(UNITY_MATRIX_VP, world_pos); + return LinearEyeDepth(clip_pos.z / clip_pos.w); +} + +sampler2D _CameraDepthTexture; + +// Return depth buffer at coordinate, on [0, 1]. +float getDepthBufferAt(in float4 world_pos) +{ + float4 clip_pos = mul(UNITY_MATRIX_VP, world_pos); + float4 uv = ComputeGrabScreenPos(clip_pos); + return LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv.xy / uv.w)); +} + +#endif // __PBR_INC__ + |
