1 | #include "SunColor.h"
|
---|
2 | #include "Vector3.h"
|
---|
3 | #include "common.h"
|
---|
4 |
|
---|
5 |
|
---|
6 | using namespace CHCDemoEngine;
|
---|
7 | using namespace std;
|
---|
8 |
|
---|
9 |
|
---|
10 | inline float CBQ(float x)
|
---|
11 | {
|
---|
12 | return x * x * x;
|
---|
13 | }
|
---|
14 |
|
---|
15 |
|
---|
16 | inline float SQR(float x)
|
---|
17 | {
|
---|
18 | return x * x ;
|
---|
19 | }
|
---|
20 |
|
---|
21 |
|
---|
22 | void SunColor::Compute(const Vector3 &sunDir, Vector3 &ambient, Vector3 &diffuse) const
|
---|
23 | {
|
---|
24 | const float turbidity = 3.0f;
|
---|
25 |
|
---|
26 | // sunDir is sun direction
|
---|
27 | // ambient color: shadow color
|
---|
28 | // diffuse color: sun color
|
---|
29 |
|
---|
30 | float sun_theta[2];
|
---|
31 |
|
---|
32 | sun_theta[0] = acos(sunDir.z);
|
---|
33 |
|
---|
34 | const float cos_theta = cos(sun_theta[0]);
|
---|
35 | sun_theta[1] = cos_theta * cos_theta;
|
---|
36 |
|
---|
37 | Vector3 zenithColor;
|
---|
38 |
|
---|
39 | zenithColor.x = ( 0.00165f * CBQ(sun_theta[0]) - 0.00374f * SQR(sun_theta[0]) + 0.00208f * sun_theta[0] + 0.0f) * SQR(turbidity) +
|
---|
40 | (-0.02902f * CBQ(sun_theta[0]) + 0.06377f * SQR(sun_theta[0]) - 0.03202f * sun_theta[0] + 0.00394f) * turbidity +
|
---|
41 | ( 0.11693f * CBQ(sun_theta[0]) - 0.21196f * SQR(sun_theta[0]) + 0.06052f * sun_theta[0] + 0.25885f);
|
---|
42 |
|
---|
43 | zenithColor.y = (0.00275f * CBQ(sun_theta[0]) - 0.00610f * SQR(sun_theta[0]) + 0.00316f * sun_theta[0] + 0.0f) * SQR(turbidity) +
|
---|
44 | (-0.04214f * CBQ(sun_theta[0]) + 0.08970f * SQR(sun_theta[0]) - 0.04153f * sun_theta[0] + 0.00515f) * turbidity +
|
---|
45 | ( 0.15346f * CBQ(sun_theta[0]) - 0.26756f * SQR(sun_theta[0]) + 0.06669f * sun_theta[0] + 0.26688f);
|
---|
46 |
|
---|
47 | zenithColor.z = (float)((4.0453f * turbidity - 4.9710f) * tan((4.0f / 9.0f - turbidity / 120.0f) *
|
---|
48 | (M_PI - 2.0f * sun_theta[0])) - 0.2155f * turbidity + 2.4192f);
|
---|
49 |
|
---|
50 | // convert kcd/m² to cd/m²
|
---|
51 | zenithColor.z *= 1000.0f;
|
---|
52 |
|
---|
53 | ambient = zenithColor;
|
---|
54 |
|
---|
55 | Vector3 zenith_XYZ;
|
---|
56 |
|
---|
57 | zenith_XYZ.x = (ambient.x / ambient.y) * ambient.z;
|
---|
58 | zenith_XYZ.y = ambient.z;
|
---|
59 | zenith_XYZ.z = ((1.0f - ambient.x - ambient.y) / ambient.y) * ambient.z;
|
---|
60 |
|
---|
61 | ambient.x = 3.240479f * zenith_XYZ.x - 1.537150f * zenith_XYZ.y - 0.498535f * zenith_XYZ.z;
|
---|
62 | ambient.y = -0.969256f * zenith_XYZ.x + 1.875992f * zenith_XYZ.y + 0.041556f * zenith_XYZ.z;
|
---|
63 | ambient.z = 0.055648f * zenith_XYZ.x - 0.204043f * zenith_XYZ.y + 1.057311f * zenith_XYZ.z;
|
---|
64 |
|
---|
65 | // downscale ambient color
|
---|
66 | ambient *= 5e-5f;
|
---|
67 |
|
---|
68 | // simulate the sun intensity by modulating the ambient term.
|
---|
69 | ambient *= (1.0f - 0.9f * DotProd(sunDir, Vector3::UNIT_Z()));
|
---|
70 | ambient += Vector3(0.2f);
|
---|
71 |
|
---|
72 | float ABCDE_x[5], ABCDE_y[5], ABCDE_Y[5];
|
---|
73 |
|
---|
74 | ABCDE_x[0] = -0.01925f * turbidity - 0.25922f;
|
---|
75 | ABCDE_x[1] = -0.06651f * turbidity + 0.00081f;
|
---|
76 | ABCDE_x[2] = -0.00041f * turbidity + 0.21247f;
|
---|
77 | ABCDE_x[3] = -0.06409f * turbidity - 0.89887f;
|
---|
78 | ABCDE_x[4] = -0.00325f * turbidity + 0.04517f;
|
---|
79 |
|
---|
80 | ABCDE_y[0] = -0.01669f * turbidity - 0.26078f;
|
---|
81 | ABCDE_y[1] = -0.09495f * turbidity + 0.00921f;
|
---|
82 | ABCDE_y[2] = -0.00792f * turbidity + 0.21023f;
|
---|
83 | ABCDE_y[3] = -0.04405f * turbidity - 1.65369f;
|
---|
84 | ABCDE_y[4] = -0.01092f * turbidity + 0.05291f;
|
---|
85 |
|
---|
86 | ABCDE_Y[0] = 0.17872f * turbidity - 1.46303f;
|
---|
87 | ABCDE_Y[1] = -0.35540f * turbidity + 0.42749f;
|
---|
88 | ABCDE_Y[2] = -0.02266f * turbidity + 5.32505f;
|
---|
89 | ABCDE_Y[3] = 0.12064f * turbidity - 2.57705f;
|
---|
90 | ABCDE_Y[4] = -0.06696f * turbidity + 0.37027f;
|
---|
91 |
|
---|
92 | Vector3 num;
|
---|
93 |
|
---|
94 | num.x = (1.0f + ABCDE_x[0] * exp( ABCDE_x[1] / sunDir.z )) * (1.0f + ABCDE_x[2])+ ABCDE_x[4];
|
---|
95 | num.y = (1.0f + ABCDE_y[0] * exp( ABCDE_y[1] / sunDir.z )) * (1.0f + ABCDE_y[2])+ ABCDE_y[4];
|
---|
96 | num.z = (1.0f + ABCDE_Y[0] * exp( ABCDE_Y[1] / sunDir.z )) * (1.0f + ABCDE_Y[2])+ ABCDE_Y[4];
|
---|
97 |
|
---|
98 |
|
---|
99 | Vector3 den;
|
---|
100 |
|
---|
101 | den.x = (1.0f + ABCDE_x[0] * exp( ABCDE_x[1] )) * (1.0f + ABCDE_x[2] * exp( ABCDE_x[3] * sun_theta[0] ) + ABCDE_x[4] * sun_theta[1]);
|
---|
102 | den.y = (1.0f + ABCDE_y[0] * exp( ABCDE_y[1] )) * (1.0f + ABCDE_y[2] * exp( ABCDE_y[3] * sun_theta[0]) + ABCDE_y[4] * sun_theta[1]);
|
---|
103 | den.z = (1.0f + ABCDE_Y[0] * exp( ABCDE_Y[1] )) * (1.0f + ABCDE_Y[2] * exp( ABCDE_Y[3] * sun_theta[0] ) + ABCDE_Y[4] * sun_theta[1]);
|
---|
104 |
|
---|
105 |
|
---|
106 | Vector3 xyY = (num / den) * zenithColor;
|
---|
107 |
|
---|
108 | Vector3 XYZ;
|
---|
109 |
|
---|
110 | XYZ.x = (xyY.x / xyY.y) * xyY.z;
|
---|
111 | XYZ.y = xyY.z;
|
---|
112 | XYZ.z = ((1.0f - xyY.x - xyY.y) / xyY.y) * xyY.z;
|
---|
113 |
|
---|
114 |
|
---|
115 | Vector3 color;
|
---|
116 | color.x = 3.240479f*XYZ.x -1.537150f*XYZ.y-0.498535f*XYZ.z;
|
---|
117 | color.y = -0.969256f*XYZ.x +1.875992f*XYZ.y +0.041556f*XYZ.z;
|
---|
118 | color.z = 0.055648f*XYZ.x -0.204043f*XYZ.y +1.057311f*XYZ.z;
|
---|
119 |
|
---|
120 | // Calculate final sun diffuse color.
|
---|
121 | diffuse = color * 0.00017f;
|
---|
122 | } |
---|