Пример #1
0
void RenderManager::LightWorld(const glm::mat4& viewMatrix, const glm::mat4& viewProjectionMatrix, bool lightVolumes) {
    std::vector<Video::Light> lights;

    Video::AxisAlignedBoundingBox aabb(glm::vec3(2.f, 2.f, 2.f), glm::vec3(0.f, 0.f, 0.f), glm::vec3(-1.0f, -1.0f, -1.0f), glm::vec3(1.0f, 1.0f, 1.0f));

    // Add all directional lights.
    for (Component::DirectionalLight* directionalLight : directionalLights.GetAll()) {
        if (directionalLight->IsKilled() || !directionalLight->entity->IsEnabled())
            continue;

        Entity* lightEntity = directionalLight->entity;
        glm::vec4 direction(glm::vec4(lightEntity->GetDirection(), 0.f));
        Video::Light light;
        light.position = viewMatrix * -direction;
        light.intensities = directionalLight->color;
        light.attenuation = 1.f;
        light.ambientCoefficient = directionalLight->ambientCoefficient;
        light.coneAngle = 0.f;
        light.direction = glm::vec3(0.f, 0.f, 0.f);
        light.shadow = 0.f;
        light.distance = 0.f;
        lights.push_back(light);
    }

    // Add all spot lights.
    for (Component::SpotLight* spotLight : spotLights.GetAll()) {
        if (spotLight->IsKilled() || !spotLight->entity->IsEnabled())
            continue;

        Entity* lightEntity = spotLight->entity;
        glm::mat4 modelMat = glm::translate(glm::mat4(), lightEntity->GetWorldPosition()) * glm::scale(glm::mat4(), glm::vec3(1.f, 1.f, 1.f) * spotLight->distance);

        // TMPTODO
        Video::Frustum frustum(viewProjectionMatrix * modelMat);
        if (frustum.Collide(aabb)) {
            if (lightVolumes)
                Managers().debugDrawingManager->AddSphere(lightEntity->GetWorldPosition(), spotLight->distance, glm::vec3(1.0f, 1.0f, 1.0f));

            glm::vec4 direction(viewMatrix * glm::vec4(lightEntity->GetDirection(), 0.f));
            glm::mat4 modelMatrix(lightEntity->GetModelMatrix());
            Video::Light light;
            light.position = viewMatrix * (glm::vec4(glm::vec3(modelMatrix[3][0], modelMatrix[3][1], modelMatrix[3][2]), 1.0));
            light.intensities = spotLight->color * spotLight->intensity;
            light.attenuation = spotLight->attenuation;
            light.ambientCoefficient = spotLight->ambientCoefficient;
            light.coneAngle = spotLight->coneAngle;
            light.direction = glm::vec3(direction);
            light.shadow = spotLight->shadow ? 1.f : 0.f;
            light.distance = spotLight->distance;
            lights.push_back(light);
        }
    }

    // Add all point lights.
    for (Component::PointLight* pointLight : pointLights.GetAll()) {
        if (pointLight->IsKilled() || !pointLight->entity->IsEnabled())
            continue;

        Entity* lightEntity = pointLight->entity;
        glm::mat4 modelMat = glm::translate(glm::mat4(), lightEntity->GetWorldPosition()) * glm::scale(glm::mat4(), glm::vec3(1.f, 1.f, 1.f) * pointLight->distance);

        Video::Frustum frustum(viewProjectionMatrix * modelMat);
        if (frustum.Collide(aabb)) {
            if (lightVolumes)
                Managers().debugDrawingManager->AddSphere(lightEntity->GetWorldPosition(), pointLight->distance, glm::vec3(1.0f, 1.0f, 1.0f));

            glm::mat4 modelMatrix(lightEntity->GetModelMatrix());
            Video::Light light;
            light.position = viewMatrix * (glm::vec4(glm::vec3(modelMatrix[3][0], modelMatrix[3][1], modelMatrix[3][2]), 1.0));
            light.intensities = pointLight->color * pointLight->intensity;
            light.attenuation = pointLight->attenuation;
            light.ambientCoefficient = 0.f;
            light.coneAngle = 180.f;
            light.direction = glm::vec3(1.f, 0.f, 0.f);
            light.shadow = 0.f;
            light.distance = pointLight->distance;
            lights.push_back(light);
        }
    }

    lightCount = lights.size();

    // Update light buffer.
    renderer->SetLights(lights);
}
Пример #2
0
void RenderManager::RenderWorldEntities(World& world, const glm::mat4& viewMatrix, const glm::mat4& projectionMatrix, Video::RenderSurface* renderSurface, bool lighting, float cameraNear, float cameraFar, bool lightVolumes) {
    // Render from camera.
    glm::mat4 lightViewMatrix;
    glm::mat4 lightProjection;

    for (Component::SpotLight* spotLight : spotLights.GetAll()) {
        if (spotLight->IsKilled() || !spotLight->entity->IsEnabled())
            continue;

        if (spotLight->shadow) {
            Entity* lightEntity = spotLight->entity;
            lightViewMatrix = glm::inverse(lightEntity->GetModelMatrix());
            lightProjection = glm::perspective(glm::radians(2.f * spotLight->coneAngle), 1.0f, 0.01f, spotLight->distance);
        }
    }

    // Camera matrices.
    const glm::mat4 viewProjectionMatrix = projectionMatrix * viewMatrix;
    const std::vector<Mesh*>& meshComponents = meshes.GetAll();
    const std::vector<AnimationController*>& controllerComponents = animationControllers.GetAll();

    // Render shadows maps.
    {
        VIDEO_ERROR_CHECK("Render shadow meshes");
        PROFILE("Render shadow meshes");
        GPUPROFILE("Render shadow meshes", Video::Query::Type::TIME_ELAPSED);
        {
            GPUPROFILE("Render shadow meshes", Video::Query::Type::SAMPLES_PASSED);

            // Static meshes.
            renderer->PrepareStaticShadowRendering(lightViewMatrix, lightProjection, shadowPass->GetShadowID(), shadowPass->GetShadowMapSize(), shadowPass->GetDepthMapFbo());
            for (Mesh* mesh : meshComponents) {
                Entity* entity = mesh->entity;
                if (entity->IsKilled() || !entity->IsEnabled())
                    continue;

                if (mesh->geometry && mesh->geometry->GetIndexCount() != 0 && mesh->geometry->GetType() == Video::Geometry::Geometry3D::STATIC)
                    renderer->ShadowRenderStaticMesh(mesh->geometry, lightViewMatrix, lightProjection, entity->GetModelMatrix());
            }
            // Skin meshes.
            renderer->PrepareSkinShadowRendering(lightViewMatrix, lightProjection, shadowPass->GetShadowID(), shadowPass->GetShadowMapSize(), shadowPass->GetDepthMapFbo());
            for (AnimationController* controller : controllerComponents) {
                Entity* entity = controller->entity;
                if (entity->IsKilled() || !entity->IsEnabled())
                    continue;

                Mesh* mesh = entity->GetComponent<Mesh>();
                if (mesh && mesh->geometry && mesh->geometry->GetIndexCount() != 0 && mesh->geometry->GetType() == Video::Geometry::Geometry3D::SKIN)
                    renderer->ShadowRenderSkinMesh(mesh->geometry, lightViewMatrix, lightProjection, entity->GetModelMatrix(), controller->bones);
            }
        }
    }

    // Render z-pass meshes.
    renderer->StartRendering(renderSurface);
    renderSurface->GetDepthFrameBuffer()->BindWrite();
    {
        VIDEO_ERROR_CHECK("Render z-pass meshes");
        PROFILE("Render z-pass meshes");
        GPUPROFILE("Render z-pass meshes", Video::Query::Type::TIME_ELAPSED);
        {
            GPUPROFILE("Render z-pass meshes", Video::Query::Type::SAMPLES_PASSED);

            // Static meshes.
            renderer->PrepareStaticMeshDepthRendering(viewMatrix, projectionMatrix);
            for (Mesh* mesh : meshComponents) {
                Entity* entity = mesh->entity;
                if (entity->IsKilled() || !entity->IsEnabled())
                    continue;

                if (mesh->geometry && mesh->geometry->GetIndexCount() != 0 && mesh->geometry->GetType() == Video::Geometry::Geometry3D::STATIC)
                    if (entity->GetComponent<Material>() != nullptr)
                        renderer->DepthRenderStaticMesh(mesh->geometry, viewMatrix, projectionMatrix, entity->GetModelMatrix());
            }

            // Skin meshes.
            renderer->PrepareSkinMeshDepthRendering(viewMatrix, projectionMatrix);
            for (AnimationController* controller : controllerComponents) {
                Entity* entity = controller->entity;
                if (entity->IsKilled() || !entity->IsEnabled())
                    continue;

                Mesh* mesh = entity->GetComponent<Mesh>();
                if (mesh && mesh->geometry && mesh->geometry->GetIndexCount() != 0 && mesh->geometry->GetType() == Video::Geometry::Geometry3D::SKIN)
                    if (entity->GetComponent<Material>() != nullptr)
                        renderer->DepthRenderSkinMesh(mesh->geometry, viewMatrix, projectionMatrix, entity->GetModelMatrix(), controller->bones);
            }
        }
    }
    renderSurface->GetDepthFrameBuffer()->Unbind();

    // Lights.
    {
        VIDEO_ERROR_CHECK("Update lights");
        PROFILE("Update lights");
        GPUPROFILE("Update lights", Video::Query::Type::TIME_ELAPSED);

        if (lighting)
            // Cull lights and update light list.
            LightWorld(viewMatrix, viewProjectionMatrix, lightVolumes);
        else
            // Use full ambient light and ignore lights in the scene.
            LightAmbient();
    }

    // Render meshes.
    renderSurface->GetShadingFrameBuffer()->BindWrite();
    {
        VIDEO_ERROR_CHECK("Render meshes");
        PROFILE("Render meshes");
        GPUPROFILE("Render meshes", Video::Query::Type::TIME_ELAPSED);

        // Static meshes.
        {
            VIDEO_ERROR_CHECK("Static meshes");
            PROFILE("Static meshes");
            GPUPROFILE("Static meshes", Video::Query::Type::TIME_ELAPSED);
            {
                GPUPROFILE("Static meshes", Video::Query::Type::SAMPLES_PASSED);
                renderer->PrepareStaticMeshRendering(viewMatrix, projectionMatrix, cameraNear, cameraFar);
                for (Mesh* mesh : meshComponents) {
                    Entity* entity = mesh->entity;
                    if (entity->IsKilled() || !entity->IsEnabled())
                        continue;

                    if (mesh->geometry && mesh->geometry->GetIndexCount() != 0 && mesh->geometry->GetType() == Video::Geometry::Geometry3D::STATIC) {
                        Material* material = entity->GetComponent<Material>();
                        if (material != nullptr)
                            renderer->RenderStaticMesh(mesh->geometry, material->albedo->GetTexture(), material->normal->GetTexture(), material->metallic->GetTexture(), material->roughness->GetTexture(), entity->GetModelMatrix());
                    }
                }
            }
        }

        // Skin meshes.
        {
            VIDEO_ERROR_CHECK("Skin meshes");
            PROFILE("Skin meshes");
            GPUPROFILE("Skin meshes", Video::Query::Type::TIME_ELAPSED);
            {
                GPUPROFILE("Skin meshes", Video::Query::Type::SAMPLES_PASSED);
                renderer->PrepareSkinMeshRendering(viewMatrix, projectionMatrix, cameraNear, cameraFar);
                for (AnimationController* controller : controllerComponents) {
                    Entity* entity = controller->entity;
                    if (entity->IsKilled() || !entity->IsEnabled())
                        continue;

                    Mesh* mesh = entity->GetComponent<Mesh>();
                    if (mesh && mesh->geometry && mesh->geometry->GetIndexCount() != 0 && mesh->geometry->GetType() == Video::Geometry::Geometry3D::SKIN) {
                        Material* material = entity->GetComponent<Material>();
                        if (material)
                            renderer->RenderSkinMesh(mesh->geometry, material->albedo->GetTexture(), material->normal->GetTexture(), material->metallic->GetTexture(), material->roughness->GetTexture(), entity->GetModelMatrix(), controller->bones);
                    }
                }
            }
        }
    }
    renderSurface->GetShadingFrameBuffer()->Unbind();
}