View difference between Paste ID: 6ZpQGgpP and 1Qj6brgs
SHOW: | | - or go back to the newest paste.
1
analytic
2
3
::begin parameters
4
color Diffuse 1 0 0
5
color Specular 1 1 1
6
float DiffuseScale 0 1 0.5
7
float SpecularScale 0 1 .028
8
float Roughness 0.00005 2 0.2
9
float Roughness2 0.00005 2 0.2
10
float Retroreflective 0 1 0
11
bool FullFresnel 0 1 0
12
bool isotropic 1
13
::end parameters
14
15
::begin shader
16
17
//Thanks to Chris_F for starting ideas.
18
// Cook-Torrance, GGX distribution (bastardised with ashikhman shirley), Smith geometry, qualitative Oren-Nayar diffuse.
19
20
float saturate(float x) { return clamp(x,0,1); }
21
22
vec3 Fresnel(float CosTheta, vec3 Ks)
23
{
24
	CosTheta = min(CosTheta, 0.99999999999999999);
25
	vec3 n2 = (1.0 + sqrt(Ks)) / (1.0 - sqrt(Ks));
26
	vec3 SinTheta = vec3(sqrt(1 - CosTheta * CosTheta));
27
28
	vec3 SinThetaT = SinTheta / n2;
29
	vec3 CosThetaT = sqrt(1 - SinThetaT * SinThetaT);
30
31
	vec3 n2CosThetaT = n2 * CosThetaT;
32
	vec3 n2CosTheta = n2 * CosTheta;
33
34
	vec3 RsSqrt = (CosTheta - n2CosThetaT) / (CosTheta + n2CosThetaT);
35
	vec3 Rs = RsSqrt * RsSqrt;
36
37
	vec3 RpSqrt = (n2CosTheta - CosThetaT) / (n2CosTheta + CosThetaT);
38
	vec3 Rp = RpSqrt * RpSqrt;
39
40
	return (Rs + Rp) / 2;
41
}
42
43
vec3 BRDF( vec3 L, vec3 V, vec3 N, vec3 X, vec3 Y )
44
{
45
//vec3 temp = L; L = V; V = temp;
46
	float PI = 3.14159265358979323846;
47
	vec3 Kd = Diffuse * DiffuseScale;
48
	vec3 Ks = Specular * SpecularScale;
49
50
	vec3 H = normalize(L + V);
51
	float NdotL = clamp(dot(N, L), 0, 1);
52
	float NdotV = dot(N, V);
53
	float NdotH = dot(N, H);
54
	float LdotV = dot(L, V);
55
	float VdotH = dot(V, H);
56
	float LdotH = dot(L, H);
57
	float HdotX = dot(H,X);
58
	float HdotY = dot(H,Y);
59
		
60
	float m1 = 1/Roughness;
61
	float m2 = 1/Roughness2;
62
	float M = isotropic ? Roughness : (1-(NdotH*NdotH)) / ( m1*HdotX*HdotX + m2*HdotY*HdotY );
63
	float M_2 = isotropic ? M * M : M* min(Roughness, Roughness2);
64
	
65
	NdotH = mix( mix( NdotH, max(NdotH,LdotV), saturate(Retroreflective*2) ), LdotV, saturate(Retroreflective*2-1) );
66
	
67
	float NdotL_2 = NdotL * NdotL;
68
	float NdotV_2 = NdotV * NdotV;
69
	float NdotH_2 = NdotH * NdotH;
70
	float OneMinusNdotL_2 = 1.0 - NdotL_2;
71
	float OneMinusNdotV_2 = 1.0 - NdotV_2;
72
73
	vec3 Fd = 1.0 - Ks;
74
75
	float gamma = clamp(dot(V - N * NdotV, L - N * NdotL), 0, 1);
76
	float A = 1.0 - 0.5 * (M_2 / (M_2 + 0.33));
77
	float B = 0.45 * (M_2 / (M_2 + 0.09));
78
	float C = sqrt(OneMinusNdotL_2 * OneMinusNdotV_2) / max(NdotL, NdotV);
79
80
	vec3 Rd = Kd * Fd * (A + B * gamma * C) * 1/PI;
81
	
82
	float ggxDenom = NdotH_2 * (M_2 + (1-NdotH_2)/NdotH_2);
83
	float D = M/ggxDenom;
84
	D = D*D/PI;
85
	D *= isotropic ? 1 : min(m1,m2)/max(m1,m2);
86
	
87
	vec3 Fs;
88
	if( FullFresnel )
89
		Fs = Fresnel(NdotV, Ks);
90
	else
91
		Fs = Ks + Fd * pow(1-LdotH, 5);
92
93
	float G1_1 = 1.0 + sqrt(1.0 + M_2 * (OneMinusNdotL_2 / NdotL_2));
94
	float G1_2 = 1.0 + sqrt(1.0 + M_2 * (OneMinusNdotV_2 / NdotV_2));
95
	float G = ((2/G1_1) * (2/G1_2))/(4 * NdotV * NdotL);
96
	
97
	vec3 Rs = Fs * D * G;
98
	
99
	return vec3(Rd + Rs);
100
}
101
102
::end shader