31 const glm::vec4 border = glm::vec4(1);
40 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
41 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
42 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, glm::value_ptr(border));
51 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
52 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
53 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, glm::value_ptr(border));
78 SCREEN_VERT,
sizeof(SCREEN_VERT),
79 BLUR_FRAG,
sizeof(BLUR_FRAG));
102 const glm::vec4 p[8] = {
103 glm::vec4(-1.0f, -1.0f, -1.0f, 1.0f),
104 glm::vec4(-1.0f, -1.0f, 1.0f, 1.0f),
106 glm::vec4(-1.0f, 1.0f, -1.0f, 1.0f),
107 glm::vec4(-1.0f, 1.0f, 1.0f, 1.0f),
109 glm::vec4(1.0f, -1.0f, -1.0f, 1.0f),
110 glm::vec4(1.0f, -1.0f, 1.0f, 1.0f),
112 glm::vec4(1.0f, 1.0f, -1.0f, 1.0f),
113 glm::vec4(1.0f, 1.0f, 1.0f, 1.0f),
116 const glm::mat4 invProj = glm::inverse(proj);
118 std::array<glm::vec4, 8> corners;
119 for (
int i = 0; i < 8; i++)
122 corners[i] = invProj * p[i];
123 corners[i] /= corners[i].w;
131 glm::vec3 lightUp = glm::vec3(0, 1, 0);
132 if (glm::length(glm::cross(lightUp, lightDir)) == 0.f)
134 lightUp = glm::vec3(0, 0, 1);
136 glm::mat4 lightView = glm::lookAt(glm::vec3(0), -lightDir, lightUp);
143 glm::mat4 cameraView,
144 glm::mat4 cameraProj)
147 lightView * glm::vec4{lowerBound[0], lowerBound[1], lowerBound[2], 1},
148 lightView * glm::vec4{lowerBound[0], lowerBound[1], upperBound[2], 1},
149 lightView * glm::vec4{lowerBound[0], upperBound[1], lowerBound[2], 1},
150 lightView * glm::vec4{lowerBound[0], upperBound[1], upperBound[2], 1},
151 lightView * glm::vec4{upperBound[0], lowerBound[1], lowerBound[2], 1},
152 lightView * glm::vec4{upperBound[0], lowerBound[1], upperBound[2], 1},
153 lightView * glm::vec4{upperBound[0], upperBound[1], lowerBound[2], 1},
154 lightView * glm::vec4{upperBound[0], upperBound[1], upperBound[2], 1},
157 glm::vec4 bmin = p[0];
158 glm::vec4 bmax = p[0];
159 for (
int i = 1; i < 8; i++)
161 bmin = glm::min(bmin, p[i]);
162 bmax = glm::max(bmax, p[i]);
167 glm::mat4 tm = lightView * glm::inverse(cameraView);
169 glm::vec4 fbmin = tm * corners[0];
170 glm::vec4 fbmax = tm * corners[0];
171 for (
int i = 1; i < 8; i++)
173 glm::vec4 c = tm * corners[i];
174 fbmin = glm::min(fbmin, c);
175 fbmax = glm::max(fbmax, c);
178 bmin.x = glm::max(bmin.x, fbmin.x);
179 bmin.y = glm::max(bmin.y, fbmin.y);
180 bmax.x = glm::min(bmax.x, fbmax.x);
181 bmax.y = glm::min(bmax.y, fbmax.y);
183 float cx = (bmin.x + bmax.x) * 0.5;
184 float cy = (bmin.y + bmax.y) * 0.5;
185 float d = glm::max(bmax.y - bmin.y, bmax.x - bmin.x) * 0.5f;
187 glm::mat4 lightProj = glm::ortho(cx - d, cx + d, cy - d, cy + d, -bmax.z, -bmin.z);
214 scene->getLowerBound(),
215 scene->getUpperBound(),
220 class DrawShadow :
public Action
223 void process(
Node* node)
override
229 if (m && m->isVisible()) {
238 action.params.transforms.view = lightView;
239 action.params.transforms.proj = lightProj;
241 action.params.width = this->
size;
242 action.params.height = this->
size;
244 scene->traverseForward(&action);
247 glDisable(GL_DEPTH_TEST);
261 glEnable(GL_DEPTH_TEST);
269 shadow.transform = lightProj * lightView * glm::inverse(rparams.
transforms.
view);