1 | #include "SkyPreetham.h"
|
---|
2 | //#include <rendering/effect/FEffect.h>
|
---|
3 | //#include <rendering/FVertexbuffer.h>
|
---|
4 |
|
---|
5 |
|
---|
6 |
|
---|
7 |
|
---|
8 | using namespace CHCDemoEngine;
|
---|
9 |
|
---|
10 |
|
---|
11 | SkyPreetham::SkyPreetham():
|
---|
12 | mEffect(NULL),
|
---|
13 | mTurbidity(4.0),
|
---|
14 | mSunEffect(NULL),
|
---|
15 | mSunTexture(NULL),
|
---|
16 | mSunQuad(NULL)
|
---|
17 | {
|
---|
18 | mEffect = D().getScene().getEffect("../effects/sky_preetham.fx");
|
---|
19 |
|
---|
20 | mVertexBuffer = D().getScene().getVertexBuffer("../models/sky.vbo");
|
---|
21 |
|
---|
22 | mSunEffect = D().getScene().getEffect("../effects/sky_sun.fx");
|
---|
23 | mSunTexture = D().getScene().getTexture2D("../textures/sky_sun.png");
|
---|
24 |
|
---|
25 | createSunQuad();
|
---|
26 | }
|
---|
27 |
|
---|
28 |
|
---|
29 | SkyPreetham::~SkyPreetham()
|
---|
30 | {
|
---|
31 | FDelete(mSunQuad);
|
---|
32 | }
|
---|
33 |
|
---|
34 |
|
---|
35 |
|
---|
36 | void SkyPreetham::Compute()
|
---|
37 | {
|
---|
38 |
|
---|
39 | FVector2 sun_theta;
|
---|
40 | FVector3 l_dir = D().getScene().getLight().getDirection();
|
---|
41 | mTurbidity = D().getScene().getLight().getTurbitity();
|
---|
42 |
|
---|
43 | sun_theta.x = acos(l_dir.y);
|
---|
44 | sun_theta.y = cos( sun_theta.x ) * cos( sun_theta.x );
|
---|
45 |
|
---|
46 |
|
---|
47 | #define CBQ(X) ((X) * (X) * (X))
|
---|
48 | #define SQR(X) ((X) * (X))
|
---|
49 |
|
---|
50 | const double PI = (double)3.1415926535897932;
|
---|
51 |
|
---|
52 | FVector3 zenithColor;
|
---|
53 |
|
---|
54 | zenithColor.x = ( 0.00165f * CBQ(sun_theta.x) - 0.00374f * SQR(sun_theta.x) +
|
---|
55 | 0.00208f * sun_theta.x + 0.0f) * SQR(mTurbidity) +
|
---|
56 | (-0.02902f * CBQ(sun_theta.x) + 0.06377f * SQR(sun_theta.x) -
|
---|
57 | 0.03202f * sun_theta.x + 0.00394f) * mTurbidity +
|
---|
58 | ( 0.11693f * CBQ(sun_theta.x) - 0.21196f * SQR(sun_theta.x) +
|
---|
59 | 0.06052f * sun_theta.x + 0.25885f);
|
---|
60 |
|
---|
61 | zenithColor.y = ( 0.00275f * CBQ(sun_theta.x) - 0.00610f * SQR(sun_theta.x) +
|
---|
62 | 0.00316f * sun_theta.x + 0.0f) * SQR(mTurbidity) +
|
---|
63 | (-0.04214f * CBQ(sun_theta.x) + 0.08970f * SQR(sun_theta.x) -
|
---|
64 | 0.04153f * sun_theta.x + 0.00515f) * mTurbidity +
|
---|
65 | ( 0.15346f * CBQ(sun_theta.x) - 0.26756f * SQR(sun_theta.x) +
|
---|
66 | 0.06669f * sun_theta.x + 0.26688f);
|
---|
67 |
|
---|
68 | zenithColor.z = (float)((4.0453f * mTurbidity - 4.9710f) *
|
---|
69 | tan((4.0f / 9.0f - mTurbidity / 120.0f) * (PI - 2.0f * sun_theta.x)) -
|
---|
70 | 0.2155f * mTurbidity + 2.4192f);
|
---|
71 | // convert kcd/m² to cd/m²
|
---|
72 | zenithColor.z *= 1000;
|
---|
73 |
|
---|
74 | double ABCDE_x[5], ABCDE_y[5], ABCDE_Y[5];
|
---|
75 |
|
---|
76 | ABCDE_x[0] = -0.01925 * mTurbidity - 0.25922;
|
---|
77 | ABCDE_x[1] = -0.06651 * mTurbidity + 0.00081;
|
---|
78 | ABCDE_x[2] = -0.00041 * mTurbidity + 0.21247;
|
---|
79 | ABCDE_x[3] = -0.06409 * mTurbidity - 0.89887;
|
---|
80 | ABCDE_x[4] = -0.00325 * mTurbidity + 0.04517;
|
---|
81 |
|
---|
82 | ABCDE_y[0] = -0.01669 * mTurbidity - 0.26078;
|
---|
83 | ABCDE_y[1] = -0.09495 * mTurbidity + 0.00921;
|
---|
84 | ABCDE_y[2] = -0.00792 * mTurbidity + 0.21023;
|
---|
85 | ABCDE_y[3] = -0.04405 * mTurbidity - 1.65369;
|
---|
86 | ABCDE_y[4] = -0.01092 * mTurbidity + 0.05291;
|
---|
87 |
|
---|
88 | ABCDE_Y[0] = 0.17872 * mTurbidity - 1.46303;
|
---|
89 | ABCDE_Y[1] = -0.35540 * mTurbidity + 0.42749;
|
---|
90 | ABCDE_Y[2] = -0.02266 * mTurbidity + 5.32505;
|
---|
91 | ABCDE_Y[3] = 0.12064 * mTurbidity - 2.57705;
|
---|
92 | ABCDE_Y[4] = -0.06696 * mTurbidity + 0.37027;
|
---|
93 |
|
---|
94 |
|
---|
95 | F().getRenderDevice().setDefaultDepthStencilMode(FRenderDevice::DEPTHSTENCIL_TEST_NO_OVERWRITE);
|
---|
96 |
|
---|
97 | // Move skybox with camera.
|
---|
98 | mPosition = D().getScene().getCamera().getPosition();
|
---|
99 |
|
---|
100 | mPosition.y -= 2.0;
|
---|
101 |
|
---|
102 | setTransform();
|
---|
103 |
|
---|
104 | mEffect->setVariableVector3("LightDirection", D().getScene().getLight().getDirection());
|
---|
105 | mEffect->setVariableVector2("ThetaSun", sun_theta);
|
---|
106 | mEffect->setVariableVector3("ZenithColor", zenithColor);
|
---|
107 | mEffect->setVariableVector3("AColor",FVector3((FFloat)ABCDE_x[0], (FFloat)ABCDE_y[0], (FFloat)ABCDE_Y[0]));
|
---|
108 | mEffect->setVariableVector3("BColor",FVector3((FFloat)ABCDE_x[1], (FFloat)ABCDE_y[1], (FFloat)ABCDE_Y[1]));
|
---|
109 | mEffect->setVariableVector3("CColor",FVector3((FFloat)ABCDE_x[2], (FFloat)ABCDE_y[2], (FFloat)ABCDE_Y[2]));
|
---|
110 | mEffect->setVariableVector3("DColor",FVector3((FFloat)ABCDE_x[3], (FFloat)ABCDE_y[3], (FFloat)ABCDE_Y[3]));
|
---|
111 | mEffect->setVariableVector3("EColor",FVector3((FFloat)ABCDE_x[4], (FFloat)ABCDE_y[4], (FFloat)ABCDE_Y[4]));
|
---|
112 |
|
---|
113 |
|
---|
114 | mEffect->activate();
|
---|
115 |
|
---|
116 | F().getRenderDevice().setDefaultPolygonMode(true, FRenderDevice::CULL_NONE);
|
---|
117 |
|
---|
118 | // Render sky dome.
|
---|
119 | mVertexBuffer->render();
|
---|
120 |
|
---|
121 | // Render additively blended sun disc.
|
---|
122 | renderSunDisk();
|
---|
123 |
|
---|
124 | F().getRenderDevice().setDefaultPolygonMode(true, FRenderDevice::CULL_BACKFACES);
|
---|
125 |
|
---|
126 |
|
---|
127 | F().getRenderDevice().setDefaultDepthStencilMode(FRenderDevice::DEPTHSTENCIL_TEST_AND_OVERWRITE);
|
---|
128 | }
|
---|
129 |
|
---|
130 |
|
---|
131 | void SkyPreetham::renderSunDisk()
|
---|
132 | {
|
---|
133 | F().getRenderDevice().setDefaultBlendingMode(FRenderDevice::BLENDING_ADDITIVE);
|
---|
134 |
|
---|
135 | // Set world matrix to sun disc position.
|
---|
136 | FMatrix4 sunposition;
|
---|
137 | sunposition.translate(D().getScene().getCamera().getPosition());
|
---|
138 | sunposition.rotateAroundY(-D().getScene().getLight().getHorizontalOrientation() + 90.0f);
|
---|
139 | sunposition.rotateAroundX(-D().getScene().getLight().getVerticalOrientation());
|
---|
140 | F().getRenderDevice().getTransform().setWorldMatrix(sunposition);
|
---|
141 |
|
---|
142 | FVector3 lightdirection = D().getScene().getLight().getDirection();
|
---|
143 | FFloat size = 0.5f + (1.0f - lightdirection.y) * 0.5f;
|
---|
144 |
|
---|
145 | mSunEffect->setVariableVector3("LightDiffuseColor", D().getScene().getLight().getDiffuseColor());
|
---|
146 | mSunEffect->setVariableFloat("SunSize", size);
|
---|
147 | mSunEffect->setVariableTexture2D("SunTexture", mSunTexture);
|
---|
148 |
|
---|
149 | mSunEffect->activate();
|
---|
150 |
|
---|
151 | mSunQuad->render();
|
---|
152 |
|
---|
153 | mSunEffect->deactivate();
|
---|
154 |
|
---|
155 | F().getRenderDevice().setDefaultBlendingMode(FRenderDevice::BLENDING_NONE);
|
---|
156 | }
|
---|
157 |
|
---|
158 |
|
---|
159 | void SkyPreetham::createSunQuad()
|
---|
160 | {
|
---|
161 | mSunQuad = new FVertexBuffer();
|
---|
162 | mSunQuad->setupPrimitiveType(FVertexBuffer::PRIMITIVES_TRIANGLES);
|
---|
163 | mSunQuad->setupVertexFormat(3, 0, 0, true);
|
---|
164 | mSunQuad->setupTexCoordSet(0, 2);
|
---|
165 | mSunQuad->setVertexBufferSize(4, 6);
|
---|
166 |
|
---|
167 | mSunQuad->setVertexPosition(0, FVector3(-0.1f, 0.1f, 1.0f));
|
---|
168 | mSunQuad->setVertexPosition(1, FVector3( 0.1f, 0.1f, 1.0f));
|
---|
169 | mSunQuad->setVertexPosition(2, FVector3(-0.1f, -0.1f, 1.0f));
|
---|
170 | mSunQuad->setVertexPosition(3, FVector3( 0.1f, -0.1f, 1.0f));
|
---|
171 | mSunQuad->setVertexTexCoord(0, 0, FVector2(0.0f, 0.0f));
|
---|
172 | mSunQuad->setVertexTexCoord(1, 0, FVector2(1.0f, 0.0f));
|
---|
173 | mSunQuad->setVertexTexCoord(2, 0, FVector2(0.0f, 1.0f));
|
---|
174 | mSunQuad->setVertexTexCoord(3, 0, FVector2(1.0f, 1.0f));
|
---|
175 |
|
---|
176 | mSunQuad->setIndex(0, 0);
|
---|
177 | mSunQuad->setIndex(1, 1);
|
---|
178 | mSunQuad->setIndex(2, 2);
|
---|
179 | mSunQuad->setIndex(3, 2);
|
---|
180 | mSunQuad->setIndex(4, 1);
|
---|
181 | mSunQuad->setIndex(5, 3);
|
---|
182 | } |
---|