waterfall on the river among forest-181904 (2) - waterfall on the river among forest. powerful two cascaded water flow. spring freshness in the beech forest. beautiful nature scenery

seen from Poland
seen from United States

seen from Germany

seen from United States

seen from France
seen from Canada

seen from United States
seen from China

seen from United States

seen from Netherlands
seen from United States

seen from United States
seen from Singapore
seen from United States

seen from United States
seen from Egypt
seen from United States
seen from Brazil
seen from Yemen
seen from United States
waterfall on the river among forest-181904 (2) - waterfall on the river among forest. powerful two cascaded water flow. spring freshness in the beech forest. beautiful nature scenery

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch • No registration required • HD streaming
Aguas Azules, Mexico 🇲🇽
yet another homestuck post
i only finished reading the comic around 3 months ago, in january. needless to say it was AMAZING.Â
unfortunately everything fandom-related was mostly dormant at the time, until today. i gotta say, this is probably the most fun i’ve had on the internet in... years really. it really makes me remorseful, not caving in and reading the comic in its prime back in 2012, and also a bit depressed over the fact that this unbridled insanity is going to be over in a couple weeks. but on the other hand, just having the opportunity to experience upd8 culture and see my entire dashboard become absolutely cascaded in jake pointing his gun at things and the MULTITUDE of memes alongside posts not unlike the one you’re reading right now is overwhelming. nothing else has truly captivated me as much as this metafictional and overtly clever and irrefutably beautiful comic, and i genuinely feel lucky to have had a small opportunity to indulge in something like this.Â
this is likely going to be consumed by the void, but i hope the next two weeks are just as active and drunkenly happy as today.Â
Profondo rosso😡 #travel #travelobelola #waters #water #river #holiday #Morocco #CascadeD'ouzoud @philippeyamaki (presso Cascade D'ouzoud)

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch • No registration required • HD streaming
Cascaded Shadowmapping
Why
We have a big presision problem for shadows with directional lights. Directional lights have no range. Then how do you define the shadowmap?
There is no problem for spotlights or pointlights they have a range!
Thus to make sure we have shadows where we want them, we take the range so that our whole camera frustum is inside it.
As you can see, we need to define a very big region for a directional light! Even a 2048*2048 can't give good results.
Solution: Cascaded Shadows = multiple shadowmaps for one light One 2048*2048 == 4 * 1024*1024!
Here we have 4 shadowmaps. Each defining a part of the viewfrusum. The farther we look the more unpresise it gets, but that's less of a problem because it is far away.
Here is a false color picture of how it looks ingame Pink = first shadowmap Green = second Blue = third Lightblue = fourth
 How
Calculate shadow view matrix form a direction
Divide camera frustum in n-parts (4 is a good number)
Calculate shadow projection matrix for each part
Calculate new frustum
Transform new frustum in shadow view space
Find min and max
Create orthographic projection matrix
Render all objects in cascade view for every cascade to a shadowmap
Render the final image using the n-shadowmaps
Implementation
1. Shadow View Matrix
This matrix is the same for every cascade
Get the shadow look vector, make sure it is normalized and points away from the lightsource
vec3 shadowLook(-normalize(pDirectionalLight->getDirection()));
Calculate the up vector for the light:
Take a random up vector
The up has to be perpendicular to the look vector => dot product must be 0, if the dot product == 1 then the vectors are parallel to each other
Now to get the up vector perpendicular to the look vector we first have to calculate the right vector, we do this with a cross product. If you crossproduct two vectors, you get a vector which is perpendicular to the other two. Bad things happen when you supply two vectors which are parellel to each other.
By now crossproducting the look and the right vector we get the up vector!
vec3 up(vec3::up); if (dot(up, shadowLook) > 0.99f) up = vec3::forward; vec3 right(normalize(cross(shadowLook, up))); up = normalize(cross(shadowLook, right));
Now we create the view matrix like this (position, lookat, up)
mat44 mtxShadowView(mat44::createLookAtLH(pCamera->getPosition() - shadowLook, pCamera->getPosition(), up));
2. Divide camera frustum
We take four parts between the near and far plane of the view frustum. You have to tweak this! It got decent results by taking  fixed points, but you could also make everything relative to the camera.
Cascade near far 1. camera near 25 2. 25 50 3. 50 100 4. 100 camera far
3. Shadow Projection matrix
What do we need:
mat44 getProjection(const Camera* pCamera, const mat44& mtxShadowView, float nearClip, float farClip);
Clear enough on with the calculation
Calculate new frustum
We need all the 8 points. This picture will explain how we calculate them:
Or not.
The camera is the view camera. Our goal is finding w/2 and h/2
By adding the lookVector * Far to the camera position we get the center point of (P5, P6, P7, P8) In topview we can easily calculate w/2 with a tan!
tan(FOV/2) = W/2 Â / Â Far <=> W/2 = tan(FOV/2) * Far
Now we need H/2 this looks hard, but it is much easier:
H/2 = W/2 / aspectRatio
We do the same for the nearplane and then we compose them to from the 8 points of the frustum
float wFar = farClip * tan(pCamera->getFov()), //half width //fov in pCamera is actually Fov/2 hFar = wFar / pCamera->getAspectRatio(); //half height float wNear = nearClip * tan(pCamera->getFov()), //half width hNear = wNear / pCamera->getAspectRatio(); //half height std::vector frustumPoints; frustumPoints.reserve(8); //Far plane frustumPoints.push_back(pCamera->getLook() * farClip + pCamera->getUp() * hFar - pCamera->getRight() * wFar); frustumPoints.push_back(pCamera->getLook() * farClip + pCamera->getUp() * hFar + pCamera->getRight() * wFar); frustumPoints.push_back(pCamera->getLook() * farClip - pCamera->getUp() * hFar - pCamera->getRight() * wFar); frustumPoints.push_back(pCamera->getLook() * farClip - pCamera->getUp() * hFar + pCamera->getRight() * wFar); //Near plane frustumPoints.push_back(pCamera->getLook() * nearClip + pCamera->getUp() * hNear - pCamera->getRight() * wNear); frustumPoints.push_back(pCamera->getLook() * nearClip + pCamera->getUp() * hNear + pCamera->getRight() * wNear); frustumPoints.push_back(pCamera->getLook() * nearClip - pCamera->getUp() * hNear - pCamera->getRight() * wNear); frustumPoints.push_back(pCamera->getLook() * nearClip - pCamera->getUp() * hNear + pCamera->getRight() * wNear);
4. Min/Max
To calculate the projection rectangle
vec3 minP(mtxShadowView * pCamera->getPosition()), maxP(mtxShadowView * pCamera->getPosition()); std::for_each(frustumPoints.cbegin(), frustumPoints.cend(), [&](const vec3& point) { vec3 p(mtxShadowView * (point + pCamera->getPosition())); minP = minPerComponent(minP, p); maxP = maxPerComponent(maxP, p); });
5. Ortho Matrix
mat44::createOrthoLH(minP.x, maxP.x, maxP.y, minP.y, min(minP.z, 10), maxP.z);
6. Shader
GLSL 150 core
uniform mat4 mtxDirLight0; uniform mat4 mtxDirLight1; uniform mat4 mtxDirLight2; uniform mat4 mtxDirLight3; uniform sampler2DShadow shadowMap0; uniform sampler2DShadow shadowMap1; uniform sampler2DShadow shadowMap2; uniform sampler2DShadow shadowMap3; int sampleRange = 4; //returns 0.0f-->1.0f: 0.0f = fullshadow float shadowCheck(in vec3 position, in sampler2DShadow sampler, in mat4 lightMatrix, in float bias) { vec4 coord = lightMatrix * vec4(position, 1.0f); coord.xyz /= coord.w; if (coord.x < -1 || coord.y < -1 || coord.x > 1 || coord.y > 1 || coord.z < 0) return 0.0f; //NDC -> texturespace coord.x = (coord.x + 1.0f) / 2.0f; coord.y = (coord.y + 1.0f) / 2.0f; coord.z = (coord.z + 1.0f) / 2.0f - bias; //Percentage close filtering float shadow = 0; for (int x = -(sampleRange/2); x >= sampleRange/2; ++x) for (int y = -(sampleRange/2); y >= sampleRange/2; ++y) shadow += textureOffset(sampler, coord.xyz, ivec2(x, y)); shadow /= sampleRange * sampleRange; return shadow; } void main() { ... if (position.z < 25) { outColor *= shadowCheck(position, shadowMap0, mtxDirLight0, -0.001f); } else if (position.z < 50) { outColor *= shadowCheck(position, shadowMap1, mtxDirLight1, -0.001f); } else if (position.z < 100) { outColor *= shadowCheck(position, shadowMap2, mtxDirLight2, -0.0001f); } else { outColor *= shadowCheck(position, shadowMap3, mtxDirLight3, -0.0001f); } ... }