Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Shader "ShaderChallenge/CustomPBR"
- {
- Properties
- {
- _Albedo("Albedo", 2D) = "white" {}
- _Roughness("Roughness", Range(0, 1)) = 1.0
- _Metallic("Metallic", Range(0, 1)) = 0.0
- }
- SubShader
- {
- Pass
- {
- Tags { "LightMode" = "ForwardBase" }
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- #include "UnityStandardBRDF.cginc"
- #include "UnityStandardUtils.cginc"
- #define pi 3.14159265359
- sampler2D _Albedo;
- float _Roughness;
- float _Metallic;
- struct v2f
- {
- float4 pos : SV_POSITION;
- float3 worldPos : TEXCOORD0;
- float3 normal : TEXCOORD1;
- float2 uv : TEXCOORD2;
- };
- v2f vert(appdata_base v)
- {
- v2f o;
- o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
- // Convert vertex position to world space
- o.worldPos = mul(unity_ObjectToWorld, v.vertex);
- // Normal vector
- o.normal = UnityObjectToWorldNormal(v.normal);
- o.uv = v.texcoord;
- return o;
- }
- // Oren-Nayar
- float OrenNayar(float3 n, float3 v, float3 l)
- {
- float nl = dot(n, l);
- float nv = dot(n, v);
- float anglenl = acos(nl);
- float anglenv = acos(nv);
- float alpha = max(anglenv, anglenl);
- float beta = min(anglenv, anglenl);
- float gamma = dot(v - n * nv, l - n * nl);
- float a2 = pow(_Roughness, 2.0);
- float A = 1.0 - 0.5 * (a2 / (a2 + 0.57));
- float B = 0.45 * (a2 / (a2 + 0.09));
- float C = sin(alpha) * tan(beta);
- float result = max(0.0, nl) * (A + B * max(0.0, gamma) * C);
- return result;
- }
- float DistributionGGX(float3 n, float3 h)
- {
- float a2 = pow(_Roughness, 2.0);
- float nh = dot(n, h);
- float nh2 = pow(nh, 2.0);
- float num = a2;
- float den = (nh2 * (a2 - 1.0) + 1.0);
- den = pi * pow(den, 2.0);
- return num / den;
- }
- float GeometrySchlickGGX(float dot, float k)
- {
- float num = dot;
- float den = dot * (1.0 - k) + k;
- return num / den;
- }
- float GeometrySmith(float3 n, float3 v, float3 l)
- {
- float k = pow(_Roughness + 1.0, 2.0) / 8.0;
- float nv = DotClamped(n, v);
- float nl = DotClamped(n, l);
- float ggx1 = GeometrySchlickGGX(nv, k);
- float ggx2 = GeometrySchlickGGX(nl, k);
- return ggx1 * ggx2;
- }
- float FresnelSchlick(float3 n, float3 v, float3 albedo)
- {
- float cosTheta = dot(n, v);
- float3 F0 = 0.04;
- F0 = lerp(F0, albedo, _Metallic);
- return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
- }
- float Microfacet(float3 n, float3 h, float3 v, float3 l, float3 albedo)
- {
- float d = DistributionGGX(h, n);
- float g = GeometrySmith(n, v, l);
- float f = FresnelSchlick(n, v, albedo);
- return (d * g * f) / 4.0 * DotClamped(n, l) * DotClamped(n, v) + 0.001;
- }
- float4 frag(v2f i) : SV_TARGET
- {
- float3 lightCol = _LightColor0.rgb;
- // Normalize the normal
- float3 n = normalize(i.normal);
- // Light vector from mesh's surface
- float3 l = normalize(_WorldSpaceLightPos0.xyz);
- // Viewport(camera) vector from mesh's surface
- float3 v = normalize(_WorldSpaceCameraPos - i.worldPos.xyz);
- // Halfway vector
- float3 h = normalize(l + v);
- float3 albedo = tex2D(_Albedo, i.uv).rgb;
- float3 ambient = unity_AmbientSky;
- float3 specular = Microfacet(n, h, v, l, albedo);
- float3 diffuse = ambient + OrenNayar(n, v, l);
- diffuse *= 1.0 - _Metallic;
- float3 color = albedo * (diffuse * lightCol) + (specular * lightCol);
- return float4(color, 1.0);
- }
- ENDCG
- }
- }
- }
Add Comment
Please, Sign In to add comment