Color Renderer::rayTraceRecursive(Shape* scene, Ray& ray, Lights& lights, int maxReflect) { IntersectResult result; scene->Intersect(ray, &result); if (result.geometry) { Material* pMaterial = result.geometry->material; float reflectiveness = pMaterial->reflectiveness; Color color(0, 0, 0); std::mt19937 eng(4029349); std::uniform_real_distribution<float> fraction_dist; for (int i = 0; i < lights.size(); i++) { Light* pLight = lights[i]; Color c; if (!pLight->shadow) { //no shadow Vector3dF incidenceNormal = pLight->incidenceNormal(result.position); c = pMaterial->Sample(ray, result.position, result.normal, incidenceNormal); } else if (pLight->softshadow) { Vector3dF incidenceCenter = pLight->incidence(result.position); Vector3dF incidenceNormal = incidenceCenter.Normalize(); Vector3dF rayNormal(-incidenceCenter.y, incidenceCenter.x, 0); rayNormal = rayNormal.Normalize(); float disToLight = 0; if (pLight->lightType == LightType_Point) { disToLight = (dynamic_cast<PointLight*>(pLight)->pos - result.position).Length(); } int hitTimes = 0; int raysPerFan = pLight->shadowrays / 4; for (int quadrant = 0; quadrant < 4; quadrant++) { for (int r = 0; r < raysPerFan; r++) { float angle = quadrant * 90.0f + fraction_dist(eng) * 90.f; float dis = fraction_dist(eng) * pLight->radius; //printf("<%.1f, %.1f> ", angle, dis); Vector3dF d = rayNormal.rotate(incidenceNormal, PI * angle / 180.f); Ray shadowrays(result.position, (-incidenceCenter) + d * dis); shadowrays.d = shadowrays.d.Normalize(); IntersectResult _result; scene->Intersect(shadowrays, &_result); if (_result.geometry) { if (disToLight && _result.distance >= disToLight) { continue; } hitTimes++; } } //printf("\n"); } //printf("\n"); c = pMaterial->Sample(ray, result.position, result.normal, incidenceNormal); if (hitTimes > 0) { //printf("%d\n", hitTimes); float black_ratio = hitTimes / (float)pLight->shadowrays; //c = c * ( 1.0f - black_ratio) + Color::Black * black_ratio; c = c.Modulate(Color::White * (1.0f - black_ratio)); c = c.clamp(); } } else { //normal shadow Vector3dF incidenceNormal = pLight->incidenceNormal(result.position); //Is this light visible Ray shadowrays(result.position, -incidenceNormal); IntersectResult _result; scene->Intersect(shadowrays, &_result); bool canSample = true; if (_result.geometry) { if (pLight->lightType == LightType_Point) { float disToLight = (dynamic_cast<PointLight*>(pLight)->pos - result.position).Length(); if (disToLight >= _result.distance) { canSample = false; c = Color::Black; } } else if (pLight->lightType == LightType_Direction) { canSample = false; c = Color::Black; } } if(canSample){ c = pMaterial->Sample(ray, result.position, result.normal, incidenceNormal); } } color = color + c; } color = Color(color * (1.0f - reflectiveness)); if (reflectiveness > 0 && maxReflect > 0) { Vector3dF r = Vector3dF(result.normal * (-2 * (result.normal.Dot(ray.d))) + ray.d); Ray new_ray(result.position, r); Color reflectedColor = rayTraceRecursive(scene, new_ray, lights, maxReflect - 1); assert(reflectedColor.r() >= 0 && reflectedColor.g() >= 0 && reflectedColor.b() >= 0); color = color + reflectedColor * reflectiveness; } return color; } else return Color::Black; }
void DotSceneLoader::processLight(TiXmlElement *XMLNode, SceneNode *pParent) { // Process attributes String name = getAttrib(XMLNode, "name"); String id = getAttrib(XMLNode, "id"); // Create the light Light *pLight = mSceneMgr->createLight(name); if(pParent) pParent->attachObject(pLight); String sValue = getAttrib(XMLNode, "type"); if(sValue == "point") pLight->setType(Light::LT_POINT); else if(sValue == "directional") pLight->setType(Light::LT_DIRECTIONAL); else if(sValue == "spot") pLight->setType(Light::LT_SPOTLIGHT); else if(sValue == "radPoint") pLight->setType(Light::LT_POINT); pLight->setVisible(getAttribBool(XMLNode, "visible", true)); pLight->setCastShadows(getAttribBool(XMLNode, "castShadows", true)); TiXmlElement *pElement; // Process position (?) pElement = XMLNode->FirstChildElement("position"); if(pElement) pLight->setPosition(parseVector3(pElement)); // Process normal (?) pElement = XMLNode->FirstChildElement("normal"); if(pElement) pLight->setDirection(parseVector3(pElement)); // Process colourDiffuse (?) pElement = XMLNode->FirstChildElement("colourDiffuse"); if(pElement) pLight->setDiffuseColour(parseColour(pElement)); // Process colourSpecular (?) pElement = XMLNode->FirstChildElement("colourSpecular"); if(pElement) pLight->setSpecularColour(parseColour(pElement)); // Process lightRange (?) pElement = XMLNode->FirstChildElement("lightRange"); if(pElement) processLightRange(pElement, pLight); // Process lightAttenuation (?) pElement = XMLNode->FirstChildElement("lightAttenuation"); if(pElement) processLightAttenuation(pElement, pLight); // Process userDataReference (?) pElement = XMLNode->FirstChildElement("userDataReference"); if(pElement) ;//processUserDataReference(pElement, pLight); }
// single frame code int ClientGame::runGameFrame() { // Frame Start --------------------------------------------------------- float gameTimeBetweenFrames = m_hTimer.getObject<Timer>()->TickAndGetTimeDeltaInSeconds(); // time spent in ios before resuming this thread float gameThreadPreDrawFrameTime = 0; float gameThreadDrawFrameTime = 0; float gameThreadDrawWaitFrameTime = 0; // cache root scene node pointer RootSceneNode *proot = RootSceneNode::Instance(); //Start Logging events for this frame if requested if(m_pContext->getLog()->m_activateOnNextFrame) { m_pContext->getLog()->m_isActivated = true; m_pContext->getLog()->m_activateOnNextFrame = false; } // CLOSED_WINDOW event will be pushed into global event queue if user closes window after this call m_pContext->getApplication()->processOSEventsIntoGlobalEventQueue(); //Create Physics Events { Handle hphysStartEvent("EVENT", sizeof(Event_PHYSICS_START)); Event_PHYSICS_START *physStartEvent = new(hphysStartEvent) Event_PHYSICS_START ; physStartEvent->m_frameTime = m_frameTime; Events::EventQueueManager::Instance()->add(hphysStartEvent, Events::QT_GENERAL); } // Create UPDATE event { Handle hupdateEvent("EVENT", sizeof(Event_UPDATE)); Event_UPDATE *updateEvent = new(hupdateEvent) Event_UPDATE ; updateEvent->m_frameTime = m_frameTime; //Push UPDATE event onto general queue Events::EventQueueManager::Instance()->add(hupdateEvent, Events::QT_GENERAL); } // Create SCENE_GRAPH_UPDATE event { Handle hsgUpdateEvent("EVENT", sizeof(Event_SCENE_GRAPH_UPDATE)); Event_SCENE_GRAPH_UPDATE *sgUpdateEvent = new(hsgUpdateEvent) Event_SCENE_GRAPH_UPDATE ; sgUpdateEvent->m_frameTime = m_frameTime; //Push event into general queue Events::EventQueueManager::Instance()->add(hsgUpdateEvent, Events::QT_GENERAL); } //Assign camera Handle hCam = CameraManager::Instance()->getActiveCameraHandle(); CameraSceneNode *pcam = CameraManager::Instance()->getActiveCamera()->getCamSceneNode(); // Push Event_CALCULATE_TRANSFORMATIONS { Handle hctevt("EVENT", sizeof(Event_CALCULATE_TRANSFORMATIONS)); /*Event_CALCULATE_TRANSFORMATIONS *ctevt = */ new(hctevt) Event_CALCULATE_TRANSFORMATIONS ; Events::EventQueueManager::Instance()->add(hctevt, Events::QT_GENERAL); } // Process general events (Draw, Update, Calculate transformations...) Handle gqh = Events::EventQueueManager::Instance()->getEventQueueHandle("general"); while (!gqh.getObject<Events::EventQueue>()->empty()) { Events::Event *pGeneralEvt = gqh.getObject<Events::EventQueue>()->getFront(); // this code is in process of conversion to new event style // first use new method then old (switch) if (Event_UPDATE::GetClassId() == pGeneralEvt->getClassId()) { // UPDATE // Update game objects m_pContext->getGameObjectManager()->handleEvent(pGeneralEvt); } else if (Event_CALCULATE_TRANSFORMATIONS::GetClassId() == pGeneralEvt->getClassId()) { // for all scene objects to calculate their absolute (world) transformations // for skins to calculate their matrix palettes proot->handleEvent(pGeneralEvt); //SkyVolume::Instance()->handleEvent(pGeneralEvt); // Generate Drawing Events // Push Event_PRE_GATHER_DRAWCALLS { Handle hctevt("EVENT", sizeof(Event_PRE_GATHER_DRAWCALLS)); Event_PRE_GATHER_DRAWCALLS *ctevt = new(hctevt) Event_PRE_GATHER_DRAWCALLS ; PE::Events::EventQueueManager::Instance()->add(hctevt, Events::QT_GENERAL); ctevt->m_projectionViewTransform = pcam->m_viewToProjectedTransform * pcam->m_worldToViewTransform; ctevt->m_eyePos = pcam->m_worldTransform.getPos(); } { Handle hdrawZOnlyEvt("EVENT", sizeof(Event_GATHER_DRAWCALLS_Z_ONLY)); Event_GATHER_DRAWCALLS_Z_ONLY *drawZOnlyEvt = new(hdrawZOnlyEvt) Event_GATHER_DRAWCALLS_Z_ONLY ; drawZOnlyEvt->m_pZOnlyDrawListOverride = 0; RootSceneNode *pRoot = RootSceneNode::Instance(); if (pRoot->m_lights.m_size) { PrimitiveTypes::Bool foundShadower = false; for(PrimitiveTypes::UInt32 i=0; i<(pRoot->m_lights.m_size); i++){ Light *pLight = pRoot->m_lights[i].getObject<Light>(); if(pLight->castsShadow()){ drawZOnlyEvt->m_projectionViewTransform = (pLight->m_viewToProjectedTransform * pLight->m_worldToViewTransform); drawZOnlyEvt->m_eyePos = pLight->m_base.getPos(); foundShadower=true; break; } if(!foundShadower){ drawZOnlyEvt->m_projectionViewTransform = pcam->m_viewToProjectedTransform * pcam->m_worldToViewTransform; drawZOnlyEvt->m_eyePos = pcam->m_worldTransform.getPos(); } } } else { drawZOnlyEvt->m_projectionViewTransform = pcam->m_viewToProjectedTransform * pcam->m_worldToViewTransform; drawZOnlyEvt->m_eyePos = pcam->m_worldTransform.getPos(); } drawZOnlyEvt->m_parentWorldTransform.loadIdentity(); Events::EventQueueManager::Instance()->add(hdrawZOnlyEvt); } // After the transformations are done. We can put a DRAW event in the queue // Push DRAW event into message queue because camera has updated transformations { Handle hdrawEvt("EVENT", sizeof(Event_GATHER_DRAWCALLS)); Event_GATHER_DRAWCALLS *drawEvt = new(hdrawEvt) Event_GATHER_DRAWCALLS(m_pContext->m_gameThreadThreadOwnershipMask) ; drawEvt->m_frameTime = m_frameTime; drawEvt->m_gameTime = m_gameTime; drawEvt->m_drawOrder = EffectDrawOrder::First; //Camera *pcam = hcam.getObject<Camera>(); drawEvt->m_projectionViewTransform = pcam->m_viewToProjectedTransform * pcam->m_worldToViewTransform; drawEvt->m_eyePos = pcam->m_worldTransform.getPos(); drawEvt->m_projectionTransform = pcam->m_viewToProjectedTransform; drawEvt->m_eyeDir = pcam->m_worldTransform.getN(); drawEvt->m_parentWorldTransform.loadIdentity(); drawEvt->m_viewInvTransform = pcam->m_worldToViewTransform.inverse(); //Commented out by Mac because I'm pretty sure this does nothing but am afraid to delete it... static bool setCameraAsLightSource = false; RootSceneNode *pRoot = RootSceneNode::Instance(); if (setCameraAsLightSource && pRoot->m_lights.m_size) { Light *pLight = pRoot->m_lights[0].getObject<Light>(); drawEvt->m_projectionViewTransform = (pLight->m_viewToProjectedTransform * pLight->m_worldToViewTransform); drawEvt->m_eyePos = pLight->m_base.getPos(); } Events::EventQueueManager::Instance()->add(hdrawEvt); } { Handle hphysicsEndEvt("EVENT", sizeof(Event_PHYSICS_END)); /*Event_PHYSICS_END *physicsEndEvt = */ new(hphysicsEndEvt) Event_PHYSICS_END ; Events::EventQueueManager::Instance()->add(hphysicsEndEvt); } } else if (Event_PRE_GATHER_DRAWCALLS::GetClassId() == pGeneralEvt->getClassId()) { proot->handleEvent(pGeneralEvt); } else if (Event_GATHER_DRAWCALLS::GetClassId() == pGeneralEvt->getClassId() || Event_GATHER_DRAWCALLS_Z_ONLY::GetClassId() == pGeneralEvt->getClassId()) { bool zOnly = Event_GATHER_DRAWCALLS_Z_ONLY::GetClassId() == pGeneralEvt->getClassId(); Event_GATHER_DRAWCALLS *pDrawEvent = NULL; Event_GATHER_DRAWCALLS_Z_ONLY *pDrawZOnlyEvent = NULL; if (zOnly) { pDrawZOnlyEvent = (Event_GATHER_DRAWCALLS_Z_ONLY *)(pGeneralEvt); DrawList::ZOnlyInstance()->reset(); } else { pDrawEvent = (Event_GATHER_DRAWCALLS *)(pGeneralEvt); DrawList::Instance()->reset(); } if (pDrawEvent) EffectManager::Instance()->m_currentViewProjMatrix = pDrawEvent->m_projectionViewTransform; // Draw 1st order proot->handleEvent(pGeneralEvt); // for non z only we do several draw order passes if (pDrawEvent) { /* // Manual draw pass pDrawEvent->m_drawOrder = EffectDrawOrder::Manual; // Draw SkyVolume //SkyVolume::Instance()->handleEvent(pGeneralEvt); */ EffectManager::Instance()->m_doMotionBlur = true; // Draw Last order pDrawEvent->m_drawOrder = EffectDrawOrder::Last; proot->handleEvent(pGeneralEvt); } // this code will make sure draw thread know we are done // only do it for DRAW event since is last draw event // and in case we don't do multithreading, we just execute the draw thread function if (!zOnly) { gameThreadPreDrawFrameTime = m_hTimer.getObject<Timer>()->TickAndGetTimeDeltaInSeconds(); static bool s_RenderOnGameThread = false; // if this is true, render thread will never wake up #if PYENGINE_2_0_MULTI_THREADED g_drawThreadLock.lock(); // wait till previous draw is finished //PEINFO("Game thread got g_drawThreadLock\n"); #endif // this thread now can have control of rendering context for a little bit // we will pass down this variable to different functions to let them know that we have both contexts m_pContext->getGPUScreen()->AcquireRenderContextOwnership(m_pContext->m_gameThreadThreadOwnershipMask); gameThreadDrawWaitFrameTime = m_hTimer.getObject<Timer>()->TickAndGetTimeDeltaInSeconds(); #if PE_ENABLE_GPU_PROFILING // finalize results of gpu profiling. we want to do it in this thread to avoid race condition // since we are accessing debug renderer. Profiling::Profiler::Instance()->finalize(Profiling::Group_DrawCalls); Profiling::Profiler::Instance()->finalize(Profiling::Group_DrawThread); #endif PE::IRenderer::checkForErrors(""); // send this event to objects so that they have ability to work with graphics resources // since this thread has ownership of dx thread Event_PRE_RENDER_needsRC preRenderEvt(m_pContext->m_gameThreadThreadOwnershipMask); m_pContext->getGameObjectManager()->handleEvent(&preRenderEvt); proot->handleEvent(&preRenderEvt); PE::IRenderer::checkForErrors(""); //FPS { float fps = (1.0f/m_frameTime); sprintf(PEString::s_buf, "%.2f FPS", fps); DebugRenderer::Instance()->createTextMesh( PEString::s_buf, true, false, false, false, 0, Vector3(.75f, .05f, 0), 1.0f, m_pContext->m_gameThreadThreadOwnershipMask); } PE::IRenderer::checkForErrors(""); //LUA Command Server, Server PE::GameContext *pServer = &PE::Components::ServerGame::s_context; { sprintf(PEString::s_buf, "Lua Command Receiver Ports: Client: %d Server: %d", m_pContext->getLuaCommandServerPort(), pServer->getLuaEnvironment() ? pServer->getLuaCommandServerPort():0); DebugRenderer::Instance()->createTextMesh( PEString::s_buf, true, false, false, false, 0, Vector3(.0f, .05f, 0), 1.0f, m_pContext->m_gameThreadThreadOwnershipMask); } PE::IRenderer::checkForErrors(""); if (pServer->getLuaEnvironment()) // check if server context was initialized { ServerNetworkManager *pServerNetw = (ServerNetworkManager*)(pServer->getNetworkManager()); pServerNetw->debugRender(m_pContext->m_gameThreadThreadOwnershipMask, 0, .1f); } PE::IRenderer::checkForErrors(""); { ClientNetworkManager* pClientNetworkManager = (ClientNetworkManager* )(m_pContext->getNetworkManager()); pClientNetworkManager->debugRender(m_pContext->m_gameThreadThreadOwnershipMask, 0.5f, .1f); } PE::IRenderer::checkForErrors(""); //gameplay timer { sprintf(PEString::s_buf, "GT frame wait:%.3f pre-draw:%.3f+render wait:%.3f+render:%.3f+post-render:%.3f = %.3f sec\n", m_gameTimeBetweenFrames, m_gameThreadPreDrawFrameTime, m_gameThreadDrawWaitFrameTime, m_gameThreadDrawFrameTime, m_gameThreadPostDrawFrameTime, m_frameTime); DebugRenderer::Instance()->createTextMesh( PEString::s_buf, true, false, false, false, 0, Vector3(.0f, .075f, 0), 1.0f, m_pContext->m_gameThreadThreadOwnershipMask); } //debug draw root and grid DebugRenderer::Instance()->createRootLineMesh();// send event while the array is on the stack // call this to potentially generate meshes that were scheduled in debug draw of lines DebugRenderer::Instance()->postPreDraw(m_pContext->m_gameThreadThreadOwnershipMask); PE::IRenderer::checkForErrors(""); // done synchronization, give RC back m_pContext->getGPUScreen()->ReleaseRenderContextOwnership(m_pContext->m_gameThreadThreadOwnershipMask); DrawList::swap(); #if PYENGINE_2_0_MULTI_THREADED if (!s_RenderOnGameThread) // this variable will dynamically keep other thread waiting g_drawThreadCanStart = true; else runDrawThreadSingleFrame(*m_pContext); // tun on game thread //PEINFO("Game thread releasing g_drawThreadLock\n"); g_drawThreadLock.unlock(); // release render thread lock g_drawCanStartCV.signal(); #else runDrawThreadSingleFrame(*m_pContext); #endif gameThreadDrawFrameTime = m_hTimer.getObject<Timer>()->TickAndGetTimeDeltaInSeconds(); } } else if (Event_FLY_CAMERA::GetClassId() == pGeneralEvt->getClassId()) { Event_FLY_CAMERA *pRealEvent = (Event_FLY_CAMERA *)(pGeneralEvt); pcam->m_base.moveForward(pRealEvent->m_relativeMove.getZ()); pcam->m_base.moveRight(pRealEvent->m_relativeMove.getX()); pcam->m_base.moveUp(pRealEvent->m_relativeMove.getY()); } else if (Event_ROTATE_CAMERA::GetClassId() == pGeneralEvt->getClassId()) { Event_ROTATE_CAMERA *pRealEvent = (Event_ROTATE_CAMERA *)(pGeneralEvt); pcam->m_base.turnUp(pRealEvent->m_relativeRotate.getY()); pcam->m_base.turnAboutAxis(-pRealEvent->m_relativeRotate.getX(), RootSceneNode::Instance()->m_worldTransform.getV()); } else if (Event_CLOSED_WINDOW::GetClassId() == pGeneralEvt->getClassId()) { m_runGame = false; break; } else if (Event_SCENE_GRAPH_UPDATE::GetClassId() == pGeneralEvt->getClassId()) { // this event is meant for scene graph proot->handleEvent(pGeneralEvt); } else if (Event_PHYSICS_END::GetClassId() == pGeneralEvt->getClassId()) { #ifdef PYENGINE_USE_PHYSX // Try fetching data here.. if not available yet, set some flag, so tht on next PHYSICS_START we dont run simulate runPhysXSim = Physics::GetResults(); #endif } else if (Event_PHYSICS_START::GetClassId() == pGeneralEvt->getClassId()) { #ifdef PYENGINE_USE_PHYSX Physics::UpdateControllers(); Physics::UpdateKinematics(); Physics::UpdateForceFields(frameTime); // Update Simulation Physics::Update(frameTime); // game object's event handlers will synch back to physx actors in this call GameObjectManager::Instance()->handleEvent(pGeneralEvt); #endif } #ifdef PYENGINE_USE_PHYSX else if (Event_PHYSICS_COLLISION::GetClassId() == pGeneralEvt->getClassId()) { GameObjectManager::Instance()->handleEvent(pGeneralEvt); } #endif else { // unknown event // pass it to both game object manager and scene graph m_pContext->getGameObjectManager()->handleEvent(pGeneralEvt); proot->handleEvent(pGeneralEvt); } // end of old event style handling gqh.getObject<Events::EventQueue>()->destroyFront(); } // Events are destoryed by destroyFront() but this is called every frame just in case gqh.getObject<Events::EventQueue>()->destroy(); // End of frame -------------------------------------------------------- // add memory defragmentation here // after this all pointers must be recalculated from handles //Stop logging events for this frame if was requested to log in this frame m_pContext->getLog()->m_isActivated = false; float gameThreadPostDrawFrameTime = m_hTimer.getObject<Timer>()->TickAndGetTimeDeltaInSeconds(); m_frameTime = gameTimeBetweenFrames + gameThreadPreDrawFrameTime + gameThreadDrawWaitFrameTime + gameThreadDrawFrameTime + gameThreadPostDrawFrameTime; if (m_frameTime > 10.0f) m_frameTime = 0.1f; m_gameTimeBetweenFrames = gameTimeBetweenFrames; m_gameThreadPreDrawFrameTime = gameThreadPreDrawFrameTime; m_gameThreadDrawWaitFrameTime = gameThreadDrawWaitFrameTime; m_gameThreadDrawFrameTime = gameThreadDrawFrameTime; m_gameThreadPostDrawFrameTime = gameThreadPostDrawFrameTime; m_gameTime += m_frameTime; if (!m_runGame) { PE::GameContext *pServer = &PE::Components::ServerGame::s_context; if (pServer->getGame()) { ((ServerGame *)(pServer->getGame()))->m_runGame = false; } // this is the last iteration of game thread, wait for all other threads to be done with current frame #if PYENGINE_2_0_MULTI_THREADED g_drawThreadLock.lock(); // wait till previous draw is finished g_drawThreadShouldExit = true; g_drawThreadLock.unlock(); // release render thread lock // wake up render thread g_drawCanStartCV.signal(); while (!g_drawThreadExited) { //wait until the draw thread exits } #endif } m_pContext->getApplication()->exit(); // this will close the window return 0; }
void execute() const { _light->off(); }
void SignedDistanceFieldText::CreateScene() { ResourceCache* cache = GetSubsystem<ResourceCache>(); scene_ = new Scene(context_); // Create the Octree component to the scene. This is required before adding any drawable components, or else nothing will // show up. The default octree volume will be from (-1000, -1000, -1000) to (1000, 1000, 1000) in world coordinates; it // is also legal to place objects outside the volume but their visibility can then not be checked in a hierarchically // optimizing manner scene_->CreateComponent<Octree>(); // Create a child scene node (at world origin) and a StaticModel component into it. Set the StaticModel to show a simple // plane mesh with a "stone" material. Note that naming the scene nodes is optional. Scale the scene node larger // (100 x 100 world units) Node* planeNode = scene_->CreateChild("Plane"); planeNode->SetScale(Vector3(100.0f, 1.0f, 100.0f)); StaticModel* planeObject = planeNode->CreateComponent<StaticModel>(); planeObject->SetModel(cache->GetResource<Model>("Models/Plane.mdl")); planeObject->SetMaterial(cache->GetResource<Material>("Materials/StoneTiled.xml")); // Create a directional light to the world so that we can see something. The light scene node's orientation controls the // light direction; we will use the SetDirection() function which calculates the orientation from a forward direction vector. // The light will use default settings (white light, no shadows) Node* lightNode = scene_->CreateChild("DirectionalLight"); lightNode->SetDirection(Vector3(0.6f, -1.0f, 0.8f)); // The direction vector does not need to be normalized Light* light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_DIRECTIONAL); // Create more StaticModel objects to the scene, randomly positioned, rotated and scaled. For rotation, we construct a // quaternion from Euler angles where the Y angle (rotation about the Y axis) is randomized. The mushroom model contains // LOD levels, so the StaticModel component will automatically select the LOD level according to the view distance (you'll // see the model get simpler as it moves further away). Finally, rendering a large number of the same object with the // same material allows instancing to be used, if the GPU supports it. This reduces the amount of CPU work in rendering the // scene. const unsigned NUM_OBJECTS = 200; for (unsigned i = 0; i < NUM_OBJECTS; ++i) { Node* mushroomNode = scene_->CreateChild("Mushroom"); mushroomNode->SetPosition(Vector3(Random(90.0f) - 45.0f, 0.0f, Random(90.0f) - 45.0f)); mushroomNode->SetScale(0.5f + Random(2.0f)); StaticModel* mushroomObject = mushroomNode->CreateComponent<StaticModel>(); mushroomObject->SetModel(cache->GetResource<Model>("Models/Mushroom.mdl")); mushroomObject->SetMaterial(cache->GetResource<Material>("Materials/Mushroom.xml")); Node* mushroomTitleNode = mushroomNode->CreateChild("MushroomTitle"); mushroomTitleNode->SetPosition(Vector3(0.0f, 1.2f, 0.0f)); Text3D* mushroomTitleText = mushroomTitleNode->CreateComponent<Text3D>(); mushroomTitleText->SetText("Mushroom " + String(i)); mushroomTitleText->SetFont(cache->GetResource<Font>("Fonts/BlueHighway.sdf"), 24); mushroomTitleText->SetColor(Color::RED); if (i % 3 == 1) { mushroomTitleText->SetColor(Color::GREEN); mushroomTitleText->SetTextEffect(TE_SHADOW); mushroomTitleText->SetEffectColor(Color(0.5f, 0.5f, 0.5f)); } else if (i % 3 == 2) { mushroomTitleText->SetColor(Color::YELLOW); mushroomTitleText->SetTextEffect(TE_STROKE); mushroomTitleText->SetEffectColor(Color(0.5f, 0.5f, 0.5f)); } mushroomTitleText->SetAlignment(HA_CENTER, VA_CENTER); } // Create a scene node for the camera, which we will move around // The camera will use default settings (1000 far clip distance, 45 degrees FOV, set aspect ratio automatically) cameraNode_ = scene_->CreateChild("Camera"); cameraNode_->CreateComponent<Camera>(); // Set an initial position for the camera scene node above the plane cameraNode_->SetPosition(Vector3(0.0f, 5.0f, 0.0f)); }
void TextureLitMaterial::render(GameObject* pGameObject, Camera* pCamera) { if (!_diffuseTexture) return; _shader->use(); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, _diffuseTexture->getId()); glUniform1i (_diffMapLoc, 0); glUniform1f(_diffuseTilingLoc, _diffuseTiling); if (normalMap) { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, _normalMapTexture->getId()); glUniform1i (_normalMapLoc, 1); glUniform1f(_normalTilingLoc, _normalTiling); } if (specularMap) { glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, _specularMapTexture->getId()); glUniform1i (_specMapLoc, 2); glUniform1f(_specularTilingLoc, _specularTiling); } if (Renderer::getShadowDepthMapFar()) { glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, Renderer::getShadowDepthMapFar()); glUniform1i (_depthMapLocFar, 3); } if (Renderer::getShadowDepthMapFar()) { glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_2D, Renderer::getShadowDepthMapNear()); glUniform1i (_depthMapLocNear, 4); } if (Renderer::getShadowDepthMapMid()) { glActiveTexture(GL_TEXTURE5); glBindTexture(GL_TEXTURE_2D, Renderer::getShadowDepthMapMid()); glUniform1i (_depthMapLocMid, 5); } glUniform1f(_matSmoothLoc, _smoothness); glUniform1f(_matShineLoc, _shininess); glUniform1f(_matAmbLoc, _ambient); glUniform1f(_hasNormMapLoc, normalMap); glUniform1f(_hasSpecMapLoc, specularMap); //pass in light data int index = 0; DualLinkList<Light> list = Light::GetLightList(); DualLinkNode<Light>* cn = list.startNode; //GLfloat near_plane = 1.0f, far_plane = 25.0f; while(cn!=NULL && index < MGE_MAX_LIGHTS) { Light* light = (Light*)cn; if(!light->IsActive())//do not render with inactive lights { cn = cn->nextNode; continue; } string indexString ="LightArray[" + std::to_string(index) + "]"; GLuint loc; int lightType = light->getType(); if (lightType == MGE_LIGHT_DIRECTIONAL) { loc = _shader->getUniformLocation(indexString + ".type"); glUniform1i(loc,lightType); loc = _shader->getUniformLocation(indexString + ".color"); glUniform3fv(loc,1,glm::value_ptr(light->getColor())); loc = _shader->getUniformLocation(indexString + ".direction"); glUniform3fv(loc,1,glm::value_ptr(light->getDirection())); //loc = _shader->getUniformLocation(indexString + ".position"); //glUniform3fv(loc,1,glm::value_ptr(light->getLocalPosition())); glm::mat4 lightProjection, lightView; lightView = Light::GetDirectionalViewMatrix(); glm::mat4 lightSpaceMatrix; lightProjection = Renderer::GetFarShadowOrtho(); lightSpaceMatrix = lightProjection * lightView; glUniformMatrix4fv(_lightMatLocFar, 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix)); lightProjection = Renderer::GetNearShadowOrtho(); lightSpaceMatrix = lightProjection * lightView; glUniformMatrix4fv(_lightMatLocNear, 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix)); lightProjection = Renderer::GetMidShadowOrtho(); lightSpaceMatrix = lightProjection * lightView; glUniformMatrix4fv(_lightMatLocMid, 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix)); ++index; } else if ((!pGameObject->ignoreNonDirLights) && lightType == MGE_LIGHT_POINT) { glm::vec3 lightPos = light->getWorldPosition(); float dist = glm::distance(lightPos, pGameObject->getWorldPosition()); if(dist > light->getFalloff() + pGameObject->GetRenderBound().radius) { cn = cn->nextNode; continue; } loc = _shader->getUniformLocation(indexString + ".type"); glUniform1i(loc,lightType); loc = _shader->getUniformLocation(indexString + ".color"); glUniform3fv(loc,1,glm::value_ptr(light->getColor())); loc = _shader->getUniformLocation(indexString + ".position"); glUniform3fv(loc,1,glm::value_ptr(lightPos)); loc = _shader->getUniformLocation(indexString + ".attenuation"); glUniform3fv(loc,1,glm::value_ptr(light->getAttenuation())); ++index; } //++index; cn = cn->nextNode; } glUniform1i(_shader->getUniformLocation("lightCount"),index); //set view pos glUniform3fv(_viewPosLoc, 1, glm::value_ptr(pCamera->getWorldPosition())); //color glUniform4fv(_colorLoc,1,glm::value_ptr(color)); //pass in all MVP matrices separately glUniformMatrix4fv ( _projMatLoc, 1, GL_FALSE, glm::value_ptr(pCamera->getProjection())); glUniformMatrix4fv ( _viewMatLoc, 1, GL_FALSE, glm::value_ptr(pCamera->getView())); glUniformMatrix4fv ( _modelMatLoc, 1, GL_FALSE, glm::value_ptr(pGameObject->getWorldTransform())); //now inform mesh of where to stream its data pGameObject->getMesh()->streamToOpenGL(0, 1, 2, 3); //glGetError(); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); }
int main(){ try{ ILogger::Init(); Settings::Call().Parse(); ResourceManager::Call().AddPath("Data/shaders", "Shader"); ResourceManager::Call().AddPath("Data/textures", "Image"); { Window myWindow; Image Crate; Texture CrateTexture; Text FPSText, MousePosText; Clock FrameClock, FpsClock; Input myInput; myInput.Init(myWindow); Renderer& myRenderer = Renderer::Call(); myRenderer.Init(myWindow); Crate.LoadFromFile("crate.jpg"); CrateTexture.LoadFromImage(Crate); Light l; l.SetPosition(Vector3F(1,3,1.5)); l.SetDiffuse(Color(1.f,1.f,1.f)); l.SetRange(8); Shader ColorShader; ColorShader.Compile("shaderColor.vs", "shaderColor.fs"); ColorShader.Bind(); ColorShader.SendColor("ambientColor", myRenderer.GetSpecifications().mAmbientColor); ColorShader.SendFloat("constantAtt", l.GetAttenuationConstant()); ColorShader.SendFloat("linearAtt", l.GetAttenuationLinear()); ColorShader.SendFloat("quadraticAtt", l.GetAttenuationQuadratic()); ColorShader.SendFloat("range", l.GetRange()); ColorShader.SendVector3("lightPosition", l.GetPosition()); ColorShader.SendColor("lightColor", l.GetDiffuse()); ColorShader.UnBind(); Object obj1; obj1.MakeCube("cube", ColorShader); obj1.GetMaterial().mAmbient = Color(0.f, 0.08f, 0.08f); obj1.GetMaterial().mDiffuse = Color(0.f, 0.8f, 0.8f); obj1.GetMaterial().mSpecular = Color(0.0f, 0.5f, 0.5f); obj1.GetMaterial().mShininess = 50.f; Camera cam; cam.LookAt(Vector3F(0.5f,0,1), Vector3F(-2.5f,2,4)); FPSText.SetSize(12); FPSText.SetPosition(10,10); MousePosText.SetSize(12); MousePosText.SetPosition(10,22); while(myWindow.IsOpened()){ ElapsedTime = FrameClock.GetElapsedTime(); FrameClock.Reset(); if(FpsClock.GetElapsedTime() > 1.f){ FPSText.SetText(String(1.f/ElapsedTime)); FpsClock.Reset(); } while(myInput.GetEvent()){ if(myInput.GetEventType() == sf::Event::Closed) myWindow.Close(); if(myInput.IsKeyHit(Space)) if(!paused){ paused = true; FrameClock.Pause(); }else{ paused = false; FrameClock.Resume(); } } MousePosText.SetText(String("X : ")+myInput.GetMouseX()+" Y : "+myInput.GetMouseY()); MousePosText.Draw(); FPSText.Draw(); obj1.Draw(); myRenderer.BeginScene(myRenderer.GetSpecifications().mAmbientColor); myRenderer.Render(); myRenderer.EndScene(); } } }catch(Exception e){ std::cout << e.what() << std::endl; system("PAUSE"); } Renderer::Kill(); ResourceManager::Kill(); Settings::Kill(); ILogger::Kill(); #ifdef _DEBUG MemoryManager::Kill(); #endif return 0; }
void setCurrentStateAsBaseValue(void) { setAsBaseValue(mLight->getSpecularColour()); }
void setValue(const Vector4& val) { mLight->setAttenuation(val.x, val.y, val.z, val.w); }
void setValue(const ColourValue& val) { mLight->setSpecularColour(val); }
void applyDeltaValue(const ColourValue& val) { setValue(mLight->getSpecularColour() + val); }
void setCurrentStateAsBaseValue(void) { setAsBaseValue(mLight->getDiffuseColour()); }
void applyDeltaValue(const ColourValue& val) { setValue(mLight->getDiffuseColour() + val); }
void setValue(const ColourValue& val) { mLight->setDiffuseColour(val); }
void setCurrentStateAsBaseValue(void) { setAsBaseValue(mLight->getSpotlightFalloff()); }
void applyDeltaValue(const Vector4& val) { setValue(mLight->getAs4DVector() + val); }
//----------------------------------------------------------------------- MovableObject* LightFactory::createInstanceImpl( const String& name, const NameValuePairList* params) { Light* light = OGRE_NEW Light(name); if(params) { NameValuePairList::const_iterator ni; // Setting the light type first before any property specific to a certain light type if ((ni = params->find("type")) != params->end()) { if (ni->second == "point") light->setType(Light::LT_POINT); else if (ni->second == "directional") light->setType(Light::LT_DIRECTIONAL); else if (ni->second == "spotlight") light->setType(Light::LT_SPOTLIGHT); else OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid light type '" + ni->second + "'.", "LightFactory::createInstance"); } // Common properties if ((ni = params->find("position")) != params->end()) light->setPosition(StringConverter::parseVector3(ni->second)); if ((ni = params->find("direction")) != params->end()) light->setDirection(StringConverter::parseVector3(ni->second)); if ((ni = params->find("diffuseColour")) != params->end()) light->setDiffuseColour(StringConverter::parseColourValue(ni->second)); if ((ni = params->find("specularColour")) != params->end()) light->setSpecularColour(StringConverter::parseColourValue(ni->second)); if ((ni = params->find("attenuation")) != params->end()) { Vector4 attenuation = StringConverter::parseVector4(ni->second); light->setAttenuation(attenuation.x, attenuation.y, attenuation.z, attenuation.w); } if ((ni = params->find("castShadows")) != params->end()) light->setCastShadows(StringConverter::parseBool(ni->second)); if ((ni = params->find("visible")) != params->end()) light->setVisible(StringConverter::parseBool(ni->second)); if ((ni = params->find("powerScale")) != params->end()) light->setPowerScale(StringConverter::parseReal(ni->second)); if ((ni = params->find("shadowFarDistance")) != params->end()) light->setShadowFarDistance(StringConverter::parseReal(ni->second)); // Spotlight properties if ((ni = params->find("spotlightInner")) != params->end()) light->setSpotlightInnerAngle(StringConverter::parseAngle(ni->second)); if ((ni = params->find("spotlightOuter")) != params->end()) light->setSpotlightOuterAngle(StringConverter::parseAngle(ni->second)); if ((ni = params->find("spotlightFalloff")) != params->end()) light->setSpotlightFalloff(StringConverter::parseReal(ni->second)); } return light; }
void setCurrentStateAsBaseValue(void) { setAsBaseValue(mLight->getAs4DVector()); }
void TextureShader::render(RenderState* rstate, RenderData* render_data, Material* material) { Mesh* mesh = render_data->mesh(); Texture* texture = material->getTexture("main_texture"); glm::vec3 color = material->getVec3("color"); float opacity = material->getFloat("opacity"); glm::vec4 material_ambient_color = material->getVec4("ambient_color"); glm::vec4 material_diffuse_color = material->getVec4("diffuse_color"); glm::vec4 material_specular_color = material->getVec4("specular_color"); float material_specular_exponent = material->getFloat("specular_exponent"); if (texture->getTarget() != GL_TEXTURE_2D) { std::string error = "TextureShader::render : texture with wrong target."; throw error; } bool use_light = false; Light* light; if (render_data->light_enabled()) { light = render_data->light(); if (light->enabled()) { use_light = true; } } mesh->generateVAO(); if (use_light) { GL(glUseProgram(program_light_->id())); } else { GL(glUseProgram(program_no_light_->id())); } GL(glActiveTexture (GL_TEXTURE0)); GL(glBindTexture(texture->getTarget(), texture->getId())); if (use_light) { glm::vec3 light_position = light->getVec3("world_position"); glm::vec4 light_ambient_intensity = light->getVec4("ambient_intensity"); glm::vec4 light_diffuse_intensity = light->getVec4("diffuse_intensity"); glm::vec4 light_specular_intensity = light->getVec4( "specular_intensity"); glUniformMatrix4fv(u_mvp_, 1, GL_FALSE, glm::value_ptr(rstate->uniforms.u_mvp)); glUniformMatrix4fv(u_mv_, 1, GL_FALSE, glm::value_ptr(rstate->uniforms.u_mv)); glUniformMatrix4fv(u_mv_it_, 1, GL_FALSE, glm::value_ptr(rstate->uniforms.u_mv_it)); glUniform3f(u_light_pos_, light_position.x, light_position.y, light_position.z); glUniform1i(u_texture_, 0); glUniform3f(u_color_, color.r, color.g, color.b); glUniform1f(u_opacity_, opacity); glUniform4f(u_material_ambient_color_, material_ambient_color.r, material_ambient_color.g, material_ambient_color.b, material_ambient_color.a); glUniform4f(u_material_diffuse_color_, material_diffuse_color.r, material_diffuse_color.g, material_diffuse_color.b, material_diffuse_color.a); glUniform4f(u_material_specular_color_, material_specular_color.r, material_specular_color.g, material_specular_color.b, material_specular_color.a); glUniform1f(u_material_specular_exponent_, material_specular_exponent); glUniform4f(u_light_ambient_intensity_, light_ambient_intensity.r, light_ambient_intensity.g, light_ambient_intensity.b, light_ambient_intensity.a); glUniform4f(u_light_diffuse_intensity_, light_diffuse_intensity.r, light_diffuse_intensity.g, light_diffuse_intensity.b, light_diffuse_intensity.a); glUniform4f(u_light_specular_intensity_, light_specular_intensity.r, light_specular_intensity.g, light_specular_intensity.b, light_specular_intensity.a); glBindVertexArray(mesh->getVAOId()); } else { glUniformMatrix4fv(u_mvp_no_light_, 1, GL_FALSE, glm::value_ptr(rstate->uniforms.u_mvp)); glUniform1i(u_texture_no_light_, 0); glUniform3f(u_color_no_light_, color.r, color.g, color.b); glUniform1f(u_opacity_no_light_, opacity); glBindVertexArray(mesh->getVAOId()); } GL(glDrawElements(render_data->draw_mode(), mesh->indices().size(), GL_UNSIGNED_SHORT, 0)); GL(glBindVertexArray(0)); checkGlError("TextureShader::render"); }
void setValue(Real val) { mLight->setSpotlightOuterAngle(Radian(val)); }
SampledSpectrum PathTracingRenderer::Job::contribution(const Scene &scene, const WavelengthSamples &initWLs, const Ray &initRay, IndependentLightPathSampler &pathSampler, ArenaAllocator &mem) const { WavelengthSamples wls = initWLs; Ray ray = initRay; SurfacePoint surfPt; SampledSpectrum alpha = SampledSpectrum::One; float initY = alpha.importance(wls.selectedLambda); SampledSpectrumSum sp(SampledSpectrum::Zero); uint32_t pathLength = 0; Intersection isect; if (!scene.intersect(ray, &isect)) return SampledSpectrum::Zero; isect.getSurfacePoint(&surfPt); Vector3D dirOut_sn = surfPt.shadingFrame.toLocal(-ray.dir); if (surfPt.isEmitting()) { EDF* edf = surfPt.createEDF(wls, mem); SampledSpectrum Le = surfPt.emittance(wls) * edf->evaluate(EDFQuery(), dirOut_sn); sp += alpha * Le; } if (surfPt.atInfinity) return sp; while (true) { ++pathLength; if (pathLength >= 100) break; Normal3D gNorm_sn = surfPt.shadingFrame.toLocal(surfPt.gNormal); BSDF* bsdf = surfPt.createBSDF(wls, mem); BSDFQuery fsQuery(dirOut_sn, gNorm_sn, wls.selectedLambda); // Next Event Estimation (explicit light sampling) if (bsdf->hasNonDelta()) { float lightProb; Light light; scene.selectLight(pathSampler.getLightSelectionSample(), &light, &lightProb); SLRAssert(!std::isnan(lightProb) && !std::isinf(lightProb), "lightProb: unexpected value detected: %f", lightProb); LightPosQuery lpQuery(ray.time, wls); LightPosQueryResult lpResult; SampledSpectrum M = light.sample(lpQuery, pathSampler.getLightPosSample(), &lpResult); SLRAssert(!std::isnan(lpResult.areaPDF)/* && !std::isinf(xpResult.areaPDF)*/, "areaPDF: unexpected value detected: %f", lpResult.areaPDF); if (scene.testVisibility(surfPt, lpResult.surfPt, ray.time)) { float dist2; Vector3D shadowDir = lpResult.surfPt.getDirectionFrom(surfPt.p, &dist2); Vector3D shadowDir_l = lpResult.surfPt.shadingFrame.toLocal(-shadowDir); Vector3D shadowDir_sn = surfPt.shadingFrame.toLocal(shadowDir); EDF* edf = lpResult.surfPt.createEDF(wls, mem); SampledSpectrum Le = M * edf->evaluate(EDFQuery(), shadowDir_l); float lightPDF = lightProb * lpResult.areaPDF; SLRAssert(!Le.hasNaN() && !Le.hasInf(), "Le: unexpected value detected: %s", Le.toString().c_str()); SampledSpectrum fs = bsdf->evaluate(fsQuery, shadowDir_sn); float cosLight = absDot(-shadowDir, lpResult.surfPt.gNormal); float bsdfPDF = bsdf->evaluatePDF(fsQuery, shadowDir_sn) * cosLight / dist2; float MISWeight = 1.0f; if (!lpResult.posType.isDelta() && !std::isinf(lpResult.areaPDF)) MISWeight = (lightPDF * lightPDF) / (lightPDF * lightPDF + bsdfPDF * bsdfPDF); SLRAssert(MISWeight <= 1.0f, "Invalid MIS weight: %g", MISWeight); float G = absDot(shadowDir_sn, gNorm_sn) * cosLight / dist2; sp += alpha * Le * fs * (G * MISWeight / lightPDF); SLRAssert(!std::isnan(G) && !std::isinf(G), "G: unexpected value detected: %f", G); } } // get a next direction by sampling BSDF. BSDFQueryResult fsResult; SampledSpectrum fs = bsdf->sample(fsQuery, pathSampler.getBSDFSample(), &fsResult); if (fs == SampledSpectrum::Zero || fsResult.dirPDF == 0.0f) break; if (fsResult.dirType.isDispersive()) { fsResult.dirPDF /= WavelengthSamples::NumComponents; wls.flags |= WavelengthSamples::LambdaIsSelected; } alpha *= fs * absDot(fsResult.dir_sn, gNorm_sn) / fsResult.dirPDF; SLRAssert(!alpha.hasInf() && !alpha.hasNaN(), "alpha: %s\nlength: %u, cos: %g, dirPDF: %g", alpha.toString().c_str(), pathLength, absDot(fsResult.dir_sn, gNorm_sn), fsResult.dirPDF); Vector3D dirIn = surfPt.shadingFrame.fromLocal(fsResult.dir_sn); ray = Ray(surfPt.p, dirIn, ray.time, Ray::Epsilon); // find a next intersection point. isect = Intersection(); if (!scene.intersect(ray, &isect)) break; isect.getSurfacePoint(&surfPt); dirOut_sn = surfPt.shadingFrame.toLocal(-ray.dir); // implicit light sampling if (surfPt.isEmitting()) { float bsdfPDF = fsResult.dirPDF; EDF* edf = surfPt.createEDF(wls, mem); SampledSpectrum Le = surfPt.emittance(wls) * edf->evaluate(EDFQuery(), dirOut_sn); float lightProb = scene.evaluateProb(Light(isect.obj)); float dist2 = surfPt.getSquaredDistance(ray.org); float lightPDF = lightProb * surfPt.evaluateAreaPDF() * dist2 / absDot(ray.dir, surfPt.gNormal); SLRAssert(!Le.hasNaN() && !Le.hasInf(), "Le: unexpected value detected: %s", Le.toString().c_str()); SLRAssert(!std::isnan(lightPDF)/* && !std::isinf(lightPDF)*/, "lightPDF: unexpected value detected: %f", lightPDF); float MISWeight = 1.0f; if (!fsResult.dirType.isDelta()) MISWeight = (bsdfPDF * bsdfPDF) / (lightPDF * lightPDF + bsdfPDF * bsdfPDF); SLRAssert(MISWeight <= 1.0f, "Invalid MIS weight: %g", MISWeight); sp += alpha * Le * MISWeight; } if (surfPt.atInfinity) break; // Russian roulette float continueProb = std::min(alpha.importance(wls.selectedLambda) / initY, 1.0f); if (pathSampler.getPathTerminationSample() < continueProb) alpha /= continueProb; else break; } return sp; }
void applyDeltaValue(Real val) { setValue(mLight->getSpotlightOuterAngle().valueRadians() + val); }
void undo() const { _light->on(); }
void setCurrentStateAsBaseValue(void) { setAsBaseValue(mLight->getSpotlightOuterAngle().valueRadians()); }
void TerrainShader::LoadLight(Light& light, float ambientLight) { LoadVector(location_lightPosition, light.GetPosition()); LoadVector(location_lightColor, light.GetColor()); LoadFloat(location_ambientLight, ambientLight); }
void setValue(Real val) { mLight->setSpotlightFalloff(val); }
void LoadLight(TiXmlElement *element) { Light *light = NULL; // name const char* name = element->Attribute("name"); printf("Light ["); if ( name ) printf("%s",name); printf("]"); // type const char* type = element->Attribute("type"); if ( type ) { if ( COMPARE(type,"ambient") ) { printf(" - Ambient\n"); AmbientLight *l = new AmbientLight(); light = l; for ( TiXmlElement *child = element->FirstChildElement(); child!=NULL; child = child->NextSiblingElement() ) { if ( COMPARE( child->Value(), "intensity" ) ) { Color c(1,1,1); ReadColor( child, c ); l->SetIntensity(c); printf(" intensity %f %f %f\n",c.r,c.g,c.b); } } } else if ( COMPARE(type,"direct") ) { printf(" - Direct\n"); DirectLight *l = new DirectLight(); light = l; for ( TiXmlElement *child = element->FirstChildElement(); child!=NULL; child = child->NextSiblingElement() ) { if ( COMPARE( child->Value(), "intensity" ) ) { Color c(1,1,1); ReadColor( child, c ); l->SetIntensity(c); printf(" intensity %f %f %f\n",c.r,c.g,c.b); } else if ( COMPARE( child->Value(), "direction" ) ) { Point3 v(1,1,1); ReadVector( child, v ); l->SetDirection(v); printf(" direction %f %f %f\n",v.x,v.y,v.z); } } } else if ( COMPARE(type,"point") ) { printf(" - Point\n"); PointLight *l = new PointLight(); light = l; for ( TiXmlElement *child = element->FirstChildElement(); child!=NULL; child = child->NextSiblingElement() ) { if ( COMPARE( child->Value(), "intensity" ) ) { Color c(1,1,1); ReadColor( child, c ); l->SetIntensity(c); printf(" intensity %f %f %f\n",c.r,c.g,c.b); } else if ( COMPARE( child->Value(), "position" ) ) { Point3 v(0,0,0); ReadVector( child, v ); l->SetPosition(v); printf(" position %f %f %f\n",v.x,v.y,v.z); } } } else { printf(" - UNKNOWN\n"); } } if ( light ) { light->SetName(name); lights.push_back(light); } }
void applyDeltaValue(Real val) { setValue(mLight->getSpotlightFalloff() + val); }
void IGIIntegrator::Preprocess(const Scene *scene, const Camera *camera, const Renderer *renderer) { if (scene->lights.size() == 0) return; MemoryArena arena; RNG rng; // Compute samples for emitted rays from lights vector<float> lightNum(nLightPaths * nLightSets); vector<float> lightSampPos(2 * nLightPaths * nLightSets, 0.f); vector<float> lightSampComp(nLightPaths * nLightSets, 0.f); vector<float> lightSampDir(2 * nLightPaths * nLightSets, 0.f); LDShuffleScrambled1D(nLightPaths, nLightSets, &lightNum[0], rng); LDShuffleScrambled2D(nLightPaths, nLightSets, &lightSampPos[0], rng); LDShuffleScrambled1D(nLightPaths, nLightSets, &lightSampComp[0], rng); LDShuffleScrambled2D(nLightPaths, nLightSets, &lightSampDir[0], rng); // Precompute information for light sampling densities Distribution1D *lightDistribution = ComputeLightSamplingCDF(scene); for (u_int s = 0; s < nLightSets; ++s) { for (u_int i = 0; i < nLightPaths; ++i) { // Follow path _i_ from light to create virtual lights int sampOffset = s*nLightPaths + i; // Choose light source to trace virtual light path from float lightPdf; int ln = lightDistribution->SampleDiscrete(lightNum[sampOffset], &lightPdf); Light *light = scene->lights[ln]; // Sample ray leaving light source for virtual light path RayDifferential ray; float pdf; LightSample ls(lightSampPos[2*sampOffset], lightSampPos[2*sampOffset+1], lightSampComp[sampOffset]); Normal Nl; Spectrum alpha = light->Sample_L(scene, ls, lightSampDir[2*sampOffset], lightSampDir[2*sampOffset+1], camera->shutterOpen, &ray, &Nl, &pdf); if (pdf == 0.f || alpha.IsBlack()) continue; alpha /= pdf * lightPdf; Intersection isect; while (scene->Intersect(ray, &isect) && !alpha.IsBlack()) { // Create virtual light and sample new ray for path alpha *= renderer->Transmittance(scene, RayDifferential(ray), NULL, arena, &rng); Vector wo = -ray.d; BSDF *bsdf = isect.GetBSDF(ray, arena); // Create virtual light at ray intersection point const int sqrtRhoSamples = 6; float rhoSamples[2*sqrtRhoSamples*sqrtRhoSamples]; StratifiedSample2D(rhoSamples, sqrtRhoSamples, sqrtRhoSamples, rng); Spectrum contrib = alpha * bsdf->rho(wo, sqrtRhoSamples*sqrtRhoSamples, rhoSamples) / M_PI; virtualLights[s].push_back(VirtualLight(isect.dg.p, isect.dg.nn, contrib, isect.rayEpsilon)); // Sample new ray direction and update weight for virtual light path Vector wi; float pdf; BSDFSample bsdfSample(rng); Spectrum fr = bsdf->Sample_f(wo, &wi, bsdfSample, &pdf); if (fr.IsBlack() || pdf == 0.f) break; Spectrum contribScale = fr * AbsDot(wi, bsdf->dgShading.nn) / pdf; // Possibly terminate virtual light path with Russian roulette float rrProb = min(1.f, contribScale.y()); if (rng.RandomFloat() > rrProb) break; alpha *= contribScale / rrProb; ray = RayDifferential(isect.dg.p, wi, ray, isect.rayEpsilon); } arena.FreeAll(); } } delete lightDistribution; }
void DockScatterPlot::device_changed(OpticalDevice* pDevice, int iReason) { _pDevice=pDevice; if( (iReason!=LIGHT_OFF_AXIS_CHANGED) && (iReason!=OPTICAL_DEVICE_CHANGED) && (iReason!=NEW_OPTICAL_DEVICE) ) return; _bBlockSignals=true; double dPercentField=-1; if(!pDevice->get_parameter("showLightOffAxis",dPercentField)) dPercentField=0.; assert(dPercentField>=0); assert(dPercentField<=100); m_ui->hsImageFieldPos->setValue((int)dPercentField); if(iReason==NEW_OPTICAL_DEVICE) { m_ui->hsImageFieldPos->blockSignals(true); m_ui->hsImageFieldPos->setValue((int)dPercentField); m_ui->hsImageFieldPos->blockSignals(false); } QGraphicsScene* scene=m_ui->graphicsView->scene(); scene->clear(); Light light; double dTiltDegree=dPercentField*pDevice->half_field_of_view()/100.; pDevice->compute_light(&light,pDevice->nb_surface()-1, dTiltDegree,NB_POINTS_SCATTER_PLOT,NB_POINTS_SCATTER_PLOT); bool bIsInfinite=light.is_image_infinite(); bool bIsValid=light.is_valid(); double dPsfDiameter=light.spot_size(); double dCenterX,dCenterY; double dPerfectAiryRadius=light.airy_radius(); double dLfro=light.spot_vs_airy(); double dFD=light.get_FD(); if( (pDevice->nb_surface()==0) || (!bIsValid) ) { m_ui->hsImageFieldPos->setValue(0); m_ui->qlPsfDiameter->setText("n/a"); m_ui->qlFD->setText("n/a"); m_ui->qlPerfectAiry->setText("n/a"); m_ui->qlLFro->setText("n/a"); _bBlockSignals=false; return; } //draw photons scatter plot ScatterPlot* sp=new ScatterPlot; sp->setZValue(10); int iNbPhoton=light.nb_photon(); for (int i=0;i<iNbPhoton;i++) { Photon& rP=light.get_photon(i); if (rP.is_valid()) { double dX,dY; if(bIsInfinite) { dX=rP.anglex; dY=rP.angley; sp->addPoint(-dY,dX,light.get_visual_color(rP.lambda())); } else { dX=rP.x; dY=rP.y; sp->addPoint(-dY,dX,light.get_visual_color(rP.lambda())); } assert(!isnan(dX)); assert(!isnan(dY)); } } if(bIsInfinite) { m_ui->qlPsfDiameter->setText(QString::number(dPsfDiameter,'g',3)+" deg"); m_ui->qlFD->setText("n/a"); m_ui->qlFD->setToolTip("Non applicable in infinite_image mode"); m_ui->qlPerfectAiry->setText(QString::number(dPerfectAiryRadius*2,'g',3)+" deg"); m_ui->qlLFro->setText(QString::number(dLfro,'g',3)); m_ui->qlVignetting->setText(QString::number(light.vignetting(),'f',1)+" %"); } else { m_ui->qlPsfDiameter->setText(QString::number(dPsfDiameter*1000.,'g',3)+" µm"); m_ui->qlFD->setText(QString::number(dFD,'g',3)); m_ui->qlFD->setToolTip(QString::number(dFD)); m_ui->qlPerfectAiry->setText(QString::number(dPerfectAiryRadius*2.*1000.,'g',3)+" µm"); m_ui->qlLFro->setText(QString::number(dLfro,'g',3)); m_ui->qlVignetting->setText(QString::number(light.vignetting(),'f',1)+" %"); } //draw bounding circle light.get_spot_center(dCenterY,dCenterX); dCenterX=-dCenterX; QPen qp; qp.setCosmetic(true); scene->addItem(sp); QGraphicsItem * pEllipse=scene->addEllipse((dCenterX-dPerfectAiryRadius),(dCenterY-dPerfectAiryRadius),dPerfectAiryRadius*2.,dPerfectAiryRadius*2.,qp); pEllipse->setZValue(20); QRectF rsp=sp->boundingRect(); QRectF rellipse((dCenterX-dPerfectAiryRadius),(dCenterY-dPerfectAiryRadius),dPerfectAiryRadius*2.,dPerfectAiryRadius*2.); QRectF rtotal= rsp | rellipse; enlarge(rtotal,1.1); scene->setSceneRect(rtotal); m_ui->graphicsView->fitInView(rtotal,Qt::KeepAspectRatio); _bBlockSignals=false; }