Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
Administrator
Administrator
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »SlinDev« (21.03.2015, 15:52)
Quellcode |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
Matrix Camera::MakeShadowSplit(Camera *camera, Light *light, float near, float far) { //Get camera frustum extends to be covered by the split Vector3 nearcenter = camera->ToWorld(Vector3(0.0f, 0.0f, near)); Vector3 farcorner1 = camera->ToWorld(Vector3(1.0f, 1.0f, far)); Vector3 farcorner2 = camera->ToWorld(Vector3(-1.0f, -1.0f, far)); Vector3 farcenter = (farcorner1+farcorner2)*0.5f; Vector3 center = (nearcenter+farcenter)*0.5f; //Calculate the size of a pixel in world units float dist = center.GetDistance(farcorner1); Vector3 pixelsize = Vector3(Vector2(dist*2.0f), 1.0f)/Vector3(_frame.width, _frame.height, 1.0f); //Place the light camera 500 units above the splits center Vector3 pos = center-light->GetForward()*500.0f; //Transform the position to light space Matrix rot = light->GetWorldRotation().GetRotationMatrix(); pos = rot.GetInverse()*pos; //Snap to the pixel grid pos /= pixelsize; pos.x = floorf(pos.x); pos.y = floorf(pos.y); pos.z = floorf(pos.z); pos *= pixelsize; //Transform back and place the camera there pos = rot*pos; SetPosition(pos); //Set the light camera frustum _clipFar = 500.0f + dist * 2.0f; _orthoLeft = -dist; _orthoRight = dist; _orthoBottom = -dist; _orthoTop = dist; //Update the projection matrix _dirtyProjection = true; UpdateProjection(); //Return the resulting matrix Matrix projview = _projectionMatrix * GetWorldTransform().GetInverse(); return projview; } |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
void DirectionalLight::Render(ID3D11DeviceContext* DeviceContext, Camera_t* Camera, DOUBLE3 Direction, RenderFunction_t RenderFunction){ DeviceContext->RSSetViewports(1, &Viewport); float CameraNear = Camera->GetNear(), CameraFar = Camera->GetFar(), FoV_rad=Camera->GetFoVRadians(), ViewRatio=Camera->GetViewRatio(); double LengthPerUnit = 1.0 / (pow(2, NumTextures) - 1) * (CameraFar-CameraNear); uint64_t CurrentDistance = 0; //0 to (2^NumTextures)-1 DOUBLE3 CameraUp = Camera->GetUpVector(), CameraRight = Camera->GetRightVector(); DOUBLE3 CameraPosition = Camera->GetPosition(); DOUBLE3 CameraDirection = Camera->GetDirection(); double LightAngleY, LightAngleZ; double LightLength = Direction.Length(); LightAngleY = acos(Direction.z / Direction.Length()); LightAngleZ = (Direction.y > 0) ? atan(Direction.x / Direction.y) + 3*M_PI_2 : ( (Direction.y < 0) ? atan(Direction.x / Direction.y) + M_PI_2 : (Direction.x > 0 ? 0 : M_PI) ); XMMATRIX RotationMatrix = XMMatrixMultiply(XMMatrixRotationY(LightAngleY), XMMatrixRotationZ(LightAngleZ)); XMMATRIX RotationInverse = XMMatrixMultiply(XMMatrixRotationZ(-LightAngleZ), XMMatrixRotationY(-LightAngleY)); for (unsigned int i = 0; i < NumTextures; ++i){ uint64_t CurrentSize = (uint64_t)pow(2, i); DeviceContext->ClearDepthStencilView(DepthStencilViews[i], D3D11_CLEAR_DEPTH, 1.0f, 0); DeviceContext->OMSetRenderTargets(0, 0, DepthStencilViews[i]); Frustum LightViewFrustum; double CurrentNear = CurrentDistance*LengthPerUnit + CameraNear; double CurrentFar = (CurrentDistance + CurrentSize)*LengthPerUnit + CameraNear; DOUBLE3 NearCenter = CameraPosition + CurrentNear * CameraDirection; DOUBLE3 FarCenter = CameraPosition + CurrentFar * CameraDirection; double NearHeight2 = tan(FoV_rad / 2) * CurrentNear; double FarHeight2 = tan(FoV_rad / 2) * CurrentFar; double NearWidth2 = NearHeight2 * ViewRatio; double FarWidth2 = FarHeight2 * ViewRatio; XMFLOAT3 Edges[8]; Edges[0] = FarCenter + (FarHeight2) * CameraUp - (FarWidth2) * CameraRight; Edges[1] = FarCenter + (FarHeight2) * CameraUp + (FarWidth2) * CameraRight; Edges[2] = FarCenter - (FarHeight2) * CameraUp - (FarWidth2) * CameraRight; Edges[3] = FarCenter - (FarHeight2) * CameraUp + (FarWidth2) * CameraRight; Edges[4] = NearCenter + (NearHeight2)* CameraUp - (NearWidth2)* CameraRight; Edges[5] = NearCenter + (NearHeight2)* CameraUp + (NearWidth2)* CameraRight; Edges[6] = NearCenter - (NearHeight2)* CameraUp - (NearWidth2)* CameraRight; Edges[7] = NearCenter - (NearHeight2)* CameraUp + (NearWidth2)* CameraRight; XMFLOAT3 Test; DOUBLE3 Min(std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()), Max(-std::numeric_limits<double>::infinity(), -std::numeric_limits<double>::infinity(), -std::numeric_limits<double>::infinity()); for (int j = 0; j < 8; ++j){ XMStoreFloat3(&Test, XMVector3TransformCoord(XMLoadFloat3(&Edges[j]), RotationInverse)); if (Min.x > Test.x){ Min.x = Test.x; } if (Max.x < Test.x){ Max.x = Test.x; } if (Min.y > Test.y){ Min.y = Test.y; } if (Max.y < Test.y){ Max.y = Test.y; } if (Min.z > Test.z){ Min.z = Test.z; } if (Max.z < Test.z){ Max.z = Test.z; } } XMFLOAT3 FocusPosition((Max.x + Min.x) / 2, (Max.y + Min.y) / 2, Max.z + 0.5f); XMStoreFloat3(&FocusPosition, XMVector3TransformCoord(XMLoadFloat3(&FocusPosition), RotationMatrix)); XMFLOAT3 LightPosition = DOUBLE3(FocusPosition) - Distance*Direction; XMFLOAT3 Up(0.0f,1.0f,0.0f); XMStoreFloat3(&Up, XMVector3TransformCoord(XMLoadFloat3(&Up), RotationMatrix)); XMMATRIX ViewMatrix = XMMatrixLookAtLH(XMLoadFloat3(&LightPosition), XMLoadFloat3(&FocusPosition), XMLoadFloat3(&Up)), ProjectionMatrix = XMMatrixOrthographicLH((Max.x - Min.x)*1.05, (Max.y - Min.y)*1.05, 0, Distance); ViewProjectionMatricesT[i] = XMMatrixTranspose(XMMatrixMultiply(ViewMatrix, ProjectionMatrix)); LightViewFrustum.Update(Distance, ViewMatrix, ProjectionMatrix); RenderFunction(DeviceContext, &LightViewFrustum, ViewProjectionMatricesT[i]); CurrentDistance += CurrentSize; } } |
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Magogan« (22.03.2015, 16:21)
Werbeanzeige