void WorldRenderer::CreateShadowMap(const corgi::CameraInterface& camera, fplbase::Renderer& renderer, World* world) { float shadow_map_resolution = static_cast<float>( world->config->rendering_config()->shadow_map_resolution()); float shadow_map_zoom = world->config->rendering_config()->shadow_map_zoom(); float shadow_map_offset = world->config->rendering_config()->shadow_map_offset(); vec3 light_position = LoadVec3(world->config->rendering_config()->light_position()); SetLightPosition(light_position); light_camera_.set_viewport_angle(kShadowMapViewportAngle / shadow_map_zoom); light_camera_.set_viewport_resolution( vec2(shadow_map_resolution, shadow_map_resolution)); vec3 light_camera_focus = camera.position() + camera.facing() * shadow_map_offset; light_camera_focus.z() = 0; vec3 light_facing = light_camera_focus - light_camera_.position(); light_camera_.set_facing(light_facing.Normalized()); // Shadow map needs to be cleared to near-white, since that's // the maximum (furthest) depth. shadow_map_.SetAsRenderTarget(); renderer.ClearFrameBuffer(kShadowMapClearColor); renderer.SetCulling(fplbase::Renderer::kCullBack); depth_shader_->Set(renderer); // Generate the shadow map: // TODO - modify this so that shadowcast is its own render pass for (int pass = 0; pass < corgi::RenderPass_Count; pass++) { world->render_mesh_component.RenderPass(pass, light_camera_, renderer, depth_shader_); } }
void WorldRenderer::CreateShadowMap(const corgi::CameraInterface &camera, fplbase::Renderer &renderer, World *world) { PushDebugMarker("CreateShadowMap"); PushDebugMarker("Setup"); float shadow_map_resolution = static_cast<float>( world->config->rendering_config()->shadow_map_resolution()); float shadow_map_zoom = world->config->rendering_config()->shadow_map_zoom(); float shadow_map_offset = world->config->rendering_config()->shadow_map_offset(); LightComponent *light_component = world->entity_manager.GetComponent<LightComponent>(); const EntityRef &main_light_entity = light_component->begin()->entity; const TransformData *light_transform = world->entity_manager.GetComponentData<TransformData>(main_light_entity); vec3 light_position = light_transform->position; SetLightPosition(light_position); float viewport_angle = world->config->rendering_config()->shadow_map_viewport_angle() * kDegreesToRadians; light_camera_.set_viewport_angle(viewport_angle / shadow_map_zoom); light_camera_.set_viewport_resolution( vec2(shadow_map_resolution, shadow_map_resolution)); vec3 light_camera_focus = camera.position() + camera.facing() * shadow_map_offset; light_camera_focus.z = 0; vec3 light_facing = light_camera_focus - light_camera_.position(); light_camera_.set_facing(light_facing.Normalized()); // Shadow map needs to be cleared to near-white, since that's // the maximum (furthest) depth. shadow_map_.SetAsRenderTarget(); renderer.ClearFrameBuffer(kShadowMapClearColor); renderer.SetCulling(fplbase::kCullingModeBack); depth_shader_->Set(renderer); depth_skinned_shader_->Set(renderer); // Generate the shadow map: // TODO - modify this so that shadowcast is its own render pass PopDebugMarker(); // Setup for (int pass = 0; pass < corgi::RenderPass_Count; pass++) { PushDebugMarker("RenderPass"); world->render_mesh_component.RenderPass(pass, light_camera_, renderer, ShaderIndex_Depth); PopDebugMarker(); } fplbase::RenderTarget::ScreenRenderTarget(renderer).SetAsRenderTarget(); PopDebugMarker(); // CreateShadowMap }
void WorldRenderer::RenderWorld(const corgi::CameraInterface& camera, fplbase::Renderer& renderer, World* world) { mat4 camera_transform = camera.GetTransformMatrix(); renderer.set_color(mathfu::kOnes4f); renderer.DepthTest(true); renderer.set_model_view_projection(camera_transform); assert(textured_shadowed_shader_); textured_shadowed_shader_->SetUniform("view_projection", camera_transform); textured_shadowed_shader_->SetUniform("light_view_projection", light_camera_.GetTransformMatrix()); textured_shadowed_shader_->SetUniform( "shadow_intensity", world->config->rendering_config()->shadow_intensity()); float shadow_intensity = world->config->rendering_config()->shadow_intensity(); float ambient_intensity = 1.0f - shadow_intensity; vec4 ambient = vec4(ambient_intensity, ambient_intensity, ambient_intensity, 1.0f); float diffuse_intensity = shadow_intensity; vec4 diffuse = vec4(diffuse_intensity, diffuse_intensity, diffuse_intensity, 1.0f); textured_lit_cutout_shader_->SetUniform("ambient_material", ambient); textured_lit_cutout_shader_->SetUniform("diffuse_material", diffuse); textured_lit_shader_->SetUniform("ambient_material", ambient); textured_lit_shader_->SetUniform("diffuse_material", diffuse); textured_lit_bank_shader_->SetUniform("ambient_material", ambient); textured_lit_bank_shader_->SetUniform("diffuse_material", diffuse); textured_skinned_lit_shader_->SetUniform("ambient_material", ambient); textured_skinned_lit_shader_->SetUniform("diffuse_material", diffuse); float texture_repeats = world->config->river_config()->texture_repeats(); float river_offset = world->river_component.river_offset(); river_shader_->SetUniform("river_offset", river_offset); river_shader_->SetUniform("texture_repeats", texture_repeats); SetFogUniforms(textured_shadowed_shader_, world); SetFogUniforms(textured_lit_shader_, world); SetFogUniforms(textured_lit_bank_shader_, world); SetFogUniforms(textured_skinned_lit_shader_, world); shadow_map_.BindAsTexture(kShadowMapTextureID); if (!world->skip_rendermesh_rendering) { for (int pass = 0; pass < corgi::RenderPass_Count; pass++) { world->render_mesh_component.RenderPass(pass, camera, renderer); } } if (world->draw_debug_physics) { world->physics_component.DebugDrawWorld(&renderer, camera_transform); } }
// Draw the shadow map in the world, so we can see it. void WorldRenderer::DebugShowShadowMap(const corgi::CameraInterface& camera, fplbase::Renderer& renderer) { fplbase::RenderTarget::ScreenRenderTarget(renderer).SetAsRenderTarget(); static const mat4 kDebugTextureWorldTransform = mat4::FromScaleVector(mathfu::vec3(10.0f, 10.0f, 10.0f)); const mat4 mvp = camera.GetTransformMatrix() * kDebugTextureWorldTransform; const mat4 world_matrix_inverse = kDebugTextureWorldTransform.Inverse(); renderer.set_camera_pos(world_matrix_inverse * camera.position()); renderer.set_light_pos(world_matrix_inverse * light_camera_.position()); renderer.set_model_view_projection(mvp); renderer.set_color(vec4(1.0f, 1.0f, 1.0f, 1.0f)); shadow_map_.BindAsTexture(0); textured_shader_->Set(renderer); // Render a large quad in the world, with the shadowmap texture on it: fplbase::Mesh::RenderAAQuadAlongX(vec3(0.0f, 0.0f, 0.0f), vec3(10.0f, 0.0f, 10.0f), vec2(1.0f, 0.0f), vec2(0.0f, 1.0f)); }
bool EditorController::GetMouseWorldRay(const corgi::CameraInterface& camera, const vec2i& screen_size, vec3* near, vec3* far) const { float fov_y_tan = 2 * tan(camera.viewport_angle() * 0.5f); float fov_x_tan = fov_y_tan * camera.viewport_resolution().x() / camera.viewport_resolution().y(); vec2 pointer = vec2(fov_x_tan, -fov_y_tan) * (GetPointer() / vec2(screen_size) - vec2(0.5f, 0.5f)); // pointer goes from (-tan(FOVx)/2, tan(FOVy)/2) to (tan(FOVx)/2, // -tan(FOVy)/2) (upper right to lower left); 0,0 is center of screen. vec3 forward = camera.facing().Normalized(); vec3 up = camera.up().Normalized(); vec3 right = vec3::CrossProduct(forward, up).Normalized(); up = vec3::CrossProduct(right, forward).Normalized(); *near = camera.position(); *far = camera.position() + forward + up * pointer.y() + right * pointer.x(); return true; }
void WorldRenderer::RenderWorld(const corgi::CameraInterface &camera, fplbase::Renderer &renderer, World *world) { PushDebugMarker("Render World"); PushDebugMarker("Scene Setup"); if (world->RenderingOptionsDirty()) { RefreshGlobalShaderDefines(world); } mat4 camera_transform = camera.GetTransformMatrix(); renderer.set_color(mathfu::kOnes4f); renderer.SetDepthFunction(fplbase::kDepthFunctionLess); renderer.set_model_view_projection(camera_transform); float texture_repeats = world->CurrentLevel()->river_config()->texture_repeats(); float river_offset = world->river_component.river_offset(); if (world->RenderingOptionEnabled(kShadowEffect)) { world->asset_manager->ForEachShaderWithDefine( kDefinesText[kShadowEffect], [&](fplbase::Shader *shader) { shader->SetUniform("view_projection", camera_transform); shader->SetUniform("light_view_projection", light_camera_.GetTransformMatrix()); }); } world->asset_manager->ForEachShaderWithDefine( "WATER", [&](fplbase::Shader *shader) { shader->SetUniform("river_offset", river_offset); shader->SetUniform("texture_repeats", texture_repeats); }); world->asset_manager->ForEachShaderWithDefine( kDefinesText[kPhongShading], [&](fplbase::Shader *shader) { SetLightingUniforms(shader, world); }); world->asset_manager->ForEachShaderWithDefine( "FOG_EFFECT", [&](fplbase::Shader *shader) { SetFogUniforms(shader, world); }); shadow_map_.BindAsTexture(kShadowMapTextureID); PopDebugMarker(); // Scene Setup if (!world->skip_rendermesh_rendering) { for (int pass = 0; pass < corgi::RenderPass_Count; pass++) { PushDebugMarker("RenderPass"); world->render_mesh_component.RenderPass(pass, camera, renderer); PopDebugMarker(); } } if (world->draw_debug_physics) { PushDebugMarker("Debug Draw World"); world->physics_component.DebugDrawWorld(&renderer, camera_transform); PopDebugMarker(); } PushDebugMarker("Text"); world->render_3d_text_component.RenderAllEntities(camera); PopDebugMarker(); PopDebugMarker(); // Render World }