コード例 #1
0
float4 CShadowHandler::GetShadowProjectionScales(CCamera* cam, const float3& projDir) {
	float4 projScales;
	float2 projRadius;

	// NOTE:
	//   the xy-scaling factors from CalcMinMaxView do not change linearly
	//   or smoothly with camera movements, creating visible artefacts (eg.
	//   large jumps in shadow resolution)
	//
	//   therefore, EITHER use "fixed" scaling values such that the entire
	//   map barely fits into the sun's frustum (by pretending it is embedded
	//   in a sphere and taking its diameter), OR variable scaling such that
	//   everything that can be seen by the camera maximally fills the sun's
	//   frustum (choice of projection-style is left to the user and can be
	//   changed at run-time)
	//
	//   the first option means larger maps will have more blurred/aliased
	//   shadows if the depth buffer is kept at the same size, but no (map)
	//   geometry is ever omitted
	//
	//   the second option means shadows have higher average resolution, but
	//   become less sharp as the viewing volume increases (through eg.camera
	//   rotations) and geometry can be omitted in some cases
	//
	// NOTE:
	//   when DynamicSun is enabled, the orbit is always circular in the xz
	//   plane, instead of elliptical when the map has an aspect-ratio != 1
	//
	switch (shadowProMode) {
		case SHADOWPROMODE_CAM_CENTER: {
			projScales.x = GetOrthoProjectedFrustumRadius(cam, projMidPos[2]);
		} break;
		case SHADOWPROMODE_MAP_CENTER: {
			projScales.x = GetOrthoProjectedMapRadius(projDir, projMidPos[2]);
		} break;
		case SHADOWPROMODE_MIX_CAMMAP: {
			projRadius.x = GetOrthoProjectedFrustumRadius(cam, projMidPos[0]);
			projRadius.y = GetOrthoProjectedMapRadius(projDir, projMidPos[1]);
			projScales.x = std::min(projRadius.x, projRadius.y);

			// pick the center position (0 or 1) for which radius is smallest
			projMidPos[2] = projMidPos[projRadius.x >= projRadius.y];
		} break;
	}

	projScales.y = projScales.x;
	projScales.z = globalRendering->zNear;
	projScales.w = globalRendering->viewRange;
	return (shadowProjScales = projScales);
}
コード例 #2
0
ファイル: ShadowHandler.cpp プロジェクト: Finkky/spring
float CShadowHandler::GetShadowProjectionRadius(CCamera* cam, float3& proPos, const float3& proDir) const {
	float radius = 1.0f;

	switch (shadowProMode) {
		case SHADOWPROMODE_CAM_CENTER: {
			radius = GetOrthoProjectedFrustumRadius(cam, proPos);
		} break;
		case SHADOWPROMODE_MAP_CENTER: {
			radius = GetOrthoProjectedMapRadius(proDir, proPos);
		} break;
		case SHADOWPROMODE_MIX_CAMMAP: {
			static float3 opfPos;
			static float3 opmPos;

			const float opfRad = GetOrthoProjectedFrustumRadius(cam, opfPos);
			const float opmRad = GetOrthoProjectedMapRadius(proDir, opmPos);

			if (opfRad <= opmRad) { radius = opfRad; proPos = opfPos; }
			if (opmRad <= opfRad) { radius = opmRad; proPos = opmPos; }
		} break;
	}

	return radius;
}
コード例 #3
0
ファイル: ShadowHandler.cpp プロジェクト: azotlikid/spring
void CShadowHandler::CreateShadows()
{
	fb.Bind();

	glDisable(GL_BLEND);
	glDisable(GL_LIGHTING);
	glDisable(GL_ALPHA_TEST);
	glDisable(GL_TEXTURE_2D);

	glShadeModel(GL_FLAT);
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
	glDepthMask(GL_TRUE);
	glEnable(GL_DEPTH_TEST);

	glViewport(0, 0, shadowMapSize, shadowMapSize);

	// glClearColor(0, 0, 0, 0);
	// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClear(GL_DEPTH_BUFFER_BIT);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0, 1, 0, 1, 0, -1);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();


	const ISkyLight* L = sky->GetLight();

	// sun direction is in world-space, invert it
	sunDirZ = -L->GetLightDir();
	sunDirX = (sunDirZ.cross(UpVector)).ANormalize();
	sunDirY = (sunDirX.cross(sunDirZ)).ANormalize();

	SetShadowMapSizeFactors();

	// NOTE:
	//     the xy-scaling factors from CalcMinMaxView do not change linearly
	//     or smoothly with camera movements, creating visible artefacts (eg.
	//     large jumps in shadow resolution)
	//
	//     therefore, EITHER use "fixed" scaling values such that the entire
	//     map barely fits into the sun's frustum (by pretending it is embedded
	//     in a sphere and taking its diameter), OR variable scaling such that
	//     everything that can be seen by the camera maximally fills the sun's
	//     frustum (choice of projection-style is left to the user and can be
	//     changed at run-time)
	//
	//     the first option means larger maps will have more blurred/aliased
	//     shadows if the depth buffer is kept at the same size, but no (map)
	//     geometry is ever omitted
	//
	//     the second option means shadows have higher average resolution, but
	//     become less sharp as the viewing volume increases (through eg.camera
	//     rotations) and geometry can be omitted in some cases
	//
	// NOTE:
	//     when DynamicSun is enabled, the orbit is always circular in the xz
	//     plane, instead of elliptical when the map has an aspect-ratio != 1
	//
	const float xyScale =
		(shadowProMode == SHADOWPROMODE_CAM_CENTER)? GetOrthoProjectedFrustumRadius(camera, centerPos):
		(shadowProMode == SHADOWPROMODE_MAP_CENTER)? GetOrthoProjectedMapRadius(-sunDirZ, centerPos):
		1.0f;
	const float xScale = xyScale;
	const float yScale = xyScale;
	const float zScale = globalRendering->viewRange;

	shadowMatrix[ 0] = sunDirX.x / xScale;
	shadowMatrix[ 1] = sunDirY.x / yScale;
	shadowMatrix[ 2] = sunDirZ.x / zScale;

	shadowMatrix[ 4] = sunDirX.y / xScale;
	shadowMatrix[ 5] = sunDirY.y / yScale;
	shadowMatrix[ 6] = sunDirZ.y / zScale;

	shadowMatrix[ 8] = sunDirX.z / xScale;
	shadowMatrix[ 9] = sunDirY.z / yScale;
	shadowMatrix[10] = sunDirZ.z / zScale;

	// rotate the target position into sun-space for the translation
	shadowMatrix[12] = (-sunDirX.dot(centerPos) / xScale);
	shadowMatrix[13] = (-sunDirY.dot(centerPos) / yScale);
	shadowMatrix[14] = (-sunDirZ.dot(centerPos) / zScale) + 0.5f;

	glLoadMatrixf(shadowMatrix.m);

	// set the shadow-parameter registers
	// NOTE: so long as any part of Spring rendering still uses
	// ARB programs at run-time, these lines can not be removed
	// (all ARB programs share the same environment)
	glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 16, shadowTexProjCenter.x, shadowTexProjCenter.y, 0.0f, 0.0f);
	glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 17, shadowTexProjCenter.z, shadowTexProjCenter.z, 0.0f, 0.0f);
	glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 18, shadowTexProjCenter.w, shadowTexProjCenter.w, 0.0f, 0.0f);

	if (globalRendering->haveGLSL) {
		for (int i = 0; i < SHADOWGEN_PROGRAM_LAST; i++) {
			shadowGenProgs[i]->Enable();
			shadowGenProgs[i]->SetUniform4fv(0, &shadowTexProjCenter.x);
			shadowGenProgs[i]->Disable();
		}
	}

	if (L->GetLightIntensity() > 0.0f) {
		// move view into sun-space
		const float3 oldup = camera->up;

		camera->right = sunDirX;
		camera->up = sunDirY;

		DrawShadowPasses();

		camera->up = oldup;
	}

	glShadeModel(GL_SMOOTH);
	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

	// we do this later to save render context switches (this is one of the slowest opengl operations!)
	// fb.Unbind();
	// glViewport(globalRendering->viewPosX,0,globalRendering->viewSizeX,globalRendering->viewSizeY);
}