int Trace(float *p, float *v, int k) { if( k > MAX_STEPS ) { return -1; } int con = Intersect(p, v); if(con == -1) { return con; //nothing } else if(con < -1) { return con; //light source } else if (con >=0 ) // is object { Normal(con); Reflect(v); Phong(v, con); for(int i=0; i<3; i++) { color[i] += inters_c[i];; } Trace (inter, ref, k+1); } return 0; }
PS_Output PS(PS_Input In) { PS_Output Out; float z = (In.ViewPos.z - NearFarPlane.x)/(NearFarPlane.y - NearFarPlane.x); float3 n = normalize(In.Normal); Out.Color0.a = WeightFunc(z, In.Color.a) * In.Color.a; Out.Color0.xyz = Phong(0.0, 0.0, In.ViewPos, n, In.Color.xyz) * Out.Color0.a; Out.Color1 = 1.0 - In.Color.a; return Out; }
void hwPhongShader::init_Phong_texture ( void ) // // Description: // Set up a cube map for Phong lookup // { GLubyte * texture_data; // Always release the old texture id before getting a // new one. if (phong_map_id != 0) glDeleteTextures( 1, &phong_map_id ); glGenTextures ( 1, &phong_map_id ); glEnable ( GL_TEXTURE_CUBE_MAP_EXT ); glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 ); glPixelStorei ( GL_UNPACK_ROW_LENGTH, 0 ); glBindTexture ( GL_TEXTURE_CUBE_MAP_EXT, phong_map_id ); texture_data = new GLubyte[3*PHONG_TEXTURE_RES*PHONG_TEXTURE_RES]; for ( int face=0 ; face<6 ; face++ ) { int index = 0; for ( int j=0 ; j<PHONG_TEXTURE_RES ; j++ ) { double t = 2*double(j)/(PHONG_TEXTURE_RES - 1) - 1; // -1 to 1 for ( int i=0 ; i<PHONG_TEXTURE_RES ; i++ ) { double s = 2*double(i)/(PHONG_TEXTURE_RES - 1) - 1; // -1 to 1 double x = 0.0, y = 0.0, z = 0.0; cubeToDir ( face, s, t, x, y, z ); MFloatVector intensity = Phong ( z ); texture_data[index++] = (int)(255*intensity[0]); texture_data[index++] = (int)(255*intensity[1]); texture_data[index++] = (int)(255*intensity[2]); } } glTexImage2D ( faceTarget[face], 0, GL_RGB, PHONG_TEXTURE_RES, PHONG_TEXTURE_RES, 0, GL_RGB, GL_UNSIGNED_BYTE, texture_data ); } glDisable ( GL_TEXTURE_CUBE_MAP_EXT ); delete [] texture_data; // Make sure to mark attributes "clean". mAttributesChanged = false; }
glm::vec3 Model::getColor(const SRay &m_ray, glm::vec3 out_point, glm::vec3 normal, glm::vec2 mintex) { SRay my_ray = convert_ray(m_ray); glm::vec3 light_pos = m_scene.get_LigthPos(); light_pos = ApplyMat4(T, light_pos); glm::vec3 tmnormal = ApplyMat4(Tdir, normal); if (glm::dot(tmnormal, light_pos - out_point) < 0) { normal = -normal; } glm::vec3 loc_pos = ApplyMat4(Tinv, out_point); glm::vec3 ps_color = m_textures[0]->getPixel(mintex[0], mintex[1]); glm::vec3 mycolor = Phong(loc_pos, normal, light_pos, my_ray.m_start, ps_color); /*float cos_psi = glm::dot(glm::normalize(light_pos - dmin), glm::normalize(normal)); mycolor = ps_color * cos_psi; if (cos_psi < 0) { mycolor = shade_coeff; }*/ //glm::vec3 mycolor = ps_color; float xa = 1.0f; float ya = coeff_spec; if ( m_scene.LightTrace(out_point)) { //fprintf(stderr, "Can see light\n"); xa = coeff_diff; } else { mycolor = shade_coeff; } glm::vec3 specc = glm::vec3(0, 0, 0); if (m_type != DIFFUSE_MODEL && m_ray.level_id < MAX_DEPTH) { SRay ray2; ray2.level_id = m_ray.level_id + 1; ray2.m_start = out_point; glm::vec3 tnorm = ApplyMat4(Tdir, normal); ray2.m_dir = glm::reflect(glm::normalize(out_point - m_ray.m_start), tnorm); specc = m_scene.TraceRay(ray2); } glm::vec3 res = xa * mycolor + ya * specc; return res; }
int Trace(point p, vector v, int step, float *pixelcolor) { float normal_vector[3]; float reflected_vector[3]; float inter[3]; int objectype; if (step > MAXstep) { return -1; // wykonano wystarczająco zagłębień rekurencji } int status; status = Intersect(p, v, inter, &objectype); if (status >= 0) { NormalandReflected(status, v, normal_vector, reflected_vector, inter, objectype); // wektor normalny do powierzchni // obliczenie kierunku promienia odbitego w punkcie q; Phong(status, v, normal_vector, inter, pixelcolor, objectype); //oblicza oświetlenie lokalne wg modelu Phonga Trace(inter, reflected_vector, step + 1, pixelcolor); } return status; }
void Game::start() { int width = 800; int height = 600; // context creation this->context = new Context(); this->context->initialize(4, 3); this->context->createWindow(width, height, 1, "ZPG", false, false, true); this->context->setKeyCallback([](GLFWwindow* window, int key, int scan, int action, int modifier) { InputController::getInstance().onKeyCallback(window, key, scan, action, modifier); }); this->context->setMousePositionCallback([](GLFWwindow* window, double x, double y) { InputController::getInstance().onMouseMoveCallback(window, x, y); }); this->context->setMouseScrollCallback([](GLFWwindow* window, double xOffset, double yOffset) { InputController::getInstance().onMouseScrollCallback(window, xOffset, yOffset); }); this->context->setMouseButtonCallback([](GLFWwindow* window, int button, int action, int modifier) { InputController::getInstance().onMouseButtonCallback(window, button, action, modifier); }); this->context->setWindowSizeCallback([](GLFWwindow* window, int width, int height) { Game::getInstance().onWindowSizeCallback(window, width, height); }); this->context->setShowMouseCursor(false); this->context->setDepthTest(true); this->context->setDepthFunc(GL_LEQUAL); this->context->setStencilTest(true); this->context->setStencilMask(0xFF); this->context->setStencilFunc(GL_ALWAYS, 1, 0xFF); this->context->setStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); this->context->setCulling(true); this->context->setBlending(true); this->context->setBlendingFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); this->screenQuad = new ScreenQuad(); // manager preload AudioManager::getInstance().initialize(); TextureManager::getInstance().preloadTextures(); ModelManager::getInstance().preloadModels(); FontManager::getInstance().initialize(width, height); ShaderLoader::getInstance().addCodeMapping("#LIGHT_DEFINITIONS", FileHelper::loadFile("Shaders/Headers/light_definitions.frag")); ShaderLoader::getInstance().addCodeMapping("#PHONG_CALCULATIONS", FileHelper::loadFile("Shaders/Headers/phong_calculations.frag")); ProgramManager::getInstance().preloadPrograms(); Program program = ProgramManager::getInstance().get(ProgramManager::PROGRAM_MODEL); ProgramManager::getInstance().use(ProgramManager::PROGRAM_MODEL); FramebufferManager::getInstance().preloadFramebuffers(); // initial object spawn Camera* cameraScript = new Camera(new CameraController(10.0f), glm::vec3(0.0f, 0.0f, -1.0f), 45.0f, 4.0f / 3.0f, 0.1f, 1000.0f); this->camera = new GameObject(cameraScript, nullptr, new BasicPhysicsComponent(false, new SphereBoundingBox(1.0f))); this->camera->getTransform().setPosition(glm::vec3(0.0f, 0.0f, 8.0f)); this->camera->getTags().set(Tag::Camera); this->scene.add(this->camera); ProgramManager::getInstance().observeCamera(cameraScript); // objects float distance = 3.0f; GameObject* cube = new GameObject(nullptr, new ModelRenderComponent(ModelManager::getInstance().get(ModelManager::MODEL_CUBE), Color::Blue)); this->scene.add(cube); cube->getTransform().setPosition(glm::vec3(distance, 0.0f, 0.0f)); cube = new GameObject(nullptr, new ModelRenderComponent(ModelManager::getInstance().get(ModelManager::MODEL_CUBE), Color::Red)); this->scene.add(cube); cube->getTransform().setPosition(glm::vec3(-distance, 0.0f, 0.0f)); cube = new GameObject(nullptr, new ModelRenderComponent(ModelManager::getInstance().get(ModelManager::MODEL_CUBE), Color::Green)); this->scene.add(cube); cube->getTransform().setPosition(glm::vec3(0.0f, distance, 0.0f)); cube = new GameObject(nullptr, new ModelRenderComponent(ModelManager::getInstance().get(ModelManager::MODEL_CUBE), Color::Yellow)); this->scene.add(cube); cube->getTransform().setPosition(glm::vec3(0.0f, -distance, 0.0f)); // lights DirectionalLight *dirLight = new DirectionalLight(glm::vec3(10.0f, 10.0f, 10.0f), Phong(Color::White * 0.001f, Color::White, Color::White * 0.1f)); GameObject* light = new GameObject(new LightComponent(dirLight, "directionalLight")); light->getTags().set(Tag::Light); this->scene.add(light); GeometryObject planeGeometry(VERTICES_PLANE, 2 * sizeof(glm::vec3), 6); planeGeometry.setAttributePositionNormal(); GeometryObject cubeGeometry(VERTICES_CUBE, sizeof(glm::vec3), 36); cubeGeometry.setAttributePosition(); PointLight* pointLight = new PointLight(Attenuation::ATT_DISTANCE_LONG, Phong(Color::White * 0.1f, Color::White, Color::White)); light = new GameObject( new LightComponent(pointLight, "pointLights", 0), new SimpleConstantRenderer(cubeGeometry, ProgramManager::PROGRAM_GEOMETRY_CONSTANT, Color::White) ); light->getTransform().setPosition(glm::vec3(0.0f, 0.0f, 0.0f)); light->getTags().set(Tag::Light); this->scene.add(light); program.setUniform1i("pointLightCount", 1); SpotLight* spotLight = new SpotLight(glm::vec3(0.0f, 0.0f, -1.0f), 12.5f, 17.5f, Attenuation::ATT_DISTANCE_LONG, dirLight->phong); GameObject* spotLightObj = new GameObject(new LightComponent(spotLight, "spotLight")); spotLightObj->getTags().set(Tag::Light); this->scene.add(spotLightObj); GameObject* floor = new GameObject(nullptr, new SimpleConstantRenderer(planeGeometry, ProgramManager::PROGRAM_MODEL, Color::Purple)); floor->getTransform().setScale(glm::vec3(10.0f)); floor->getTransform().setPosition(glm::vec3(0.0f, -5.0f, 0.0f)); this->scene.add(floor); // skybox const std::string skyboxPath = "Resources/Textures/skybox/"; std::vector<Image> skyboxFaces; skyboxFaces.push_back(Image(skyboxPath + "right.jpg")); skyboxFaces.push_back(Image(skyboxPath + "left.jpg")); skyboxFaces.push_back(Image(skyboxPath + "top.jpg")); skyboxFaces.push_back(Image(skyboxPath + "bottom.jpg")); skyboxFaces.push_back(Image(skyboxPath + "back.jpg")); skyboxFaces.push_back(Image(skyboxPath + "front.jpg")); Cubemap skyboxCubemap; skyboxCubemap.allocate(); skyboxCubemap.set2DImages(skyboxFaces); GameObject* skybox = new GameObject(nullptr, new SkyboxRenderer(skyboxCubemap)); this->scene.add(skybox); GameObject* crossHair = new GameObject(nullptr, new SpriteRenderer(TextureManager::TEXTURE_CROSSHAIR)); crossHair->getTransform().setScale(glm::vec3(50.0f, 50.0f, 1.0f)); this->scene.add(crossHair); Timer timer(0.01f); Timer switchTimer(0.05f); context->loop([&](Context& context) // physics { //this->physicsHandler.simulate(this->scene.getObjectManager().getObjects(), this->scene.getObjectManager().getObjectCount(), Context::getFixedDeltaTime()); }, [&](Context& context) // render { float delta = context.getDeltaTime(); timer.update(delta); switchTimer.update(delta); FramebufferManager::getInstance().get(FramebufferManager::FRAMEBUFFER_POSTPROCESS).bind(); RenderUtils::clearColor(0.0f, 0.0f, 0.0f, 1.0f); RenderUtils::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); context.setDepthTest(true); spotLight->direction = cameraScript->getFront(); spotLightObj->getTransform().setPosition(camera->getTransform().getPosition()); crossHair->getTransform().setPosition(glm::vec3(context.getWindowWidth() / 2.0f, context.getWindowHeight() / 2.0f, 0.0f)); this->scene.update(); this->scene.draw(); GLchar byte; glReadPixels(context.getWindowWidth() / 2, context.getWindowHeight() / 2, 1, 1, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, &byte); // stencil value at the center this->screenQuad->drawScreen(context); if (timer.resetIfReady()) { FontManager::getInstance().renderText("FPS: " + std::to_string(round(1.0f / delta)), 10.0f, height - 20.0f, 0.5f, glm::vec3(1.0f, 1.0f, 0.0f)); } if (InputController::getInstance().isButtonPressed(GLFW_KEY_ESCAPE)) { context.closeWindow(); } else if (InputController::getInstance().isButtonPressed(GLFW_KEY_SPACE) && switchTimer.resetIfReady()) { // switch render strategy } InputController::getInstance().afterUpdate(); this->scene.updateFrameEnd(); }); // resource disposal this->screenQuad->dispose(); delete this->screenQuad; this->scene.dispose(); ProgramManager::getInstance().dispose(); ModelManager::getInstance().dispose(); TextureManager::getInstance().dispose(); FramebufferManager::getInstance().dispose(); AudioManager::getInstance().dispose(); FontManager::getInstance().dispose(); context->terminate(); }
// TODO METHOD INCOMPLETE Color Renderer::trace(int depth, const Ray &ray, bool isTracingLights) { Color acc = Color(0,0,0); IntersectData data; for(int k = 0; k < scene.objects.size(); k++) { IntersectType type = scene.objects[k]->intersect(ray, &data); if(type == HIT) { if(data.t > EPSILON) { data.nearestObject = scene.objects[k]; } else { type = MISS; } } } if(data.nearestObject == NULL) { // No intersect. Stop. return Color(0,0,0); } else { bool isLight = data.nearestObject->material->isLight; if(isLight && isTracingLights) { return Color(1,1,1); } if(isLight && !isTracingLights) { // Is Light. Stop. Point3 point = ray.position + data.t * ray.direction; Vector3 normal = data.nearestObject->getNormalAt(point); float dot = ray.direction * normal; dot = dot < 0 ? -dot : dot; dot = 1; acc.r = 1.f * dot; acc.g = 1.f * dot; acc.b = 1.f * dot; return acc; } if(!isLight && isTracingLights) { // Light is blocked. Stop. return Color(0,0,0); } if(depth == 0) { //// Reached Limit. Stop. //Point3 point = ray.position + data.t * ray.direction; //Vector3 normal = data.nearestObject->getNormalAt(point); //float dot = ray.direction * normal; //dot = dot < 0 ? -dot : dot; //dot = 1.0; //Color color = data.nearestObject->material->color; //color.r *= dot; //color.g *= dot; //color.b *= dot; //return color; //illuminateMATTE(); acc = Color(1,0,0); /////////float dot = ray.direction * normal; /////////dot = dot < 0 ? -dot : dot; /////////color.r *= dot; /////////color.b *= dot; /////////color.g *= dot; ///////// /////////acc = blendSoftLight(color, acc); } // Add object properties to light arriving at point. MaterialType materialType = data.nearestObject->material->getType(); // Trace lights if(materialType != MIRROR) { for(int i = 0; i < scene.lights.size(); i++) { Point3 objectPoint = ray.position + data.t * ray.direction; Vector3 objectNormal = data.nearestObject->getNormalAt(objectPoint); Object *lightObject = scene.lights[i]; Ray lightRay; lightRay.position = objectPoint; lightRay.direction = (lightObject->position - lightRay.position).normalize(); Color lightColor = trace(depth - 1, lightRay, true); // TODO: try inverting lightRay.direction float lightDot = lightRay.direction * objectNormal; lightDot = lightDot < 0 ? -lightDot : lightDot; acc.r += lightColor.r / (float)scene.lights.size() * lightDot; acc.g += lightColor.g / (float)scene.lights.size() * lightDot; acc.b += lightColor.b / (float)scene.lights.size() * lightDot; } } if(materialType == MIRROR) { // // TODO Point3 point = ray.position + data.t * ray.direction; Vector3 normal = data.nearestObject->getNormalAt(point); Ray reflectionRay; reflectionRay.position = point; reflectionRay.direction = ray.direction - 2 * (ray.direction * normal) * normal; float dot = ray.direction * normal; dot = dot < 0 ? -dot : dot; Color reflection = trace(depth - 1, reflectionRay, false); MirrorMaterial *m = dynamic_cast<MirrorMaterial*>(data.nearestObject->material); acc.r = dot * (reflection.r * m->reflectivity + m->color.r * (1.0 - m->reflectivity)); acc.g = dot * (reflection.g * m->reflectivity + m->color.g * (1.0 - m->reflectivity)); acc.b = dot * (reflection.b * m->reflectivity + m->color.b * (1.0 - m->reflectivity)); } if(materialType == GLASS) { // // TODO // Ray reflectionRay; // Ray refractionRay; // IntersectionTree *reflectionBranch; // IntersectionTree *refractionBranch; // Color temp1 = trace(depth - 1, reflectionRay, reflectionBranch); // Color temp2 = trace(depth - 1, refractionRay, refractionBranch); } if(materialType == MATTE) { if(data.nearestObject->material->getType() == MATTE) { for(int i = 0; i < scene.lights.size(); i++) { Color color = data.nearestObject->material->color; Point3 point = ray.position + data.t * ray.direction; Vector3 N = data.nearestObject->getNormalAt(point); Vector3 L = (scene.lights[0]->position - point).normalize(); Vector3 V = (point - ray.position).normalize(); Vector3 H = (L + V).normalize(); Vector3 R = 2.0 * N * (N * L) - L; MatteMaterial *m = dynamic_cast<MatteMaterial*>(data.nearestObject->material); acc = Phong(*m, N*L, R*V); } } // TODO //Color color = data.nearestObject->material->color; //Point3 point = ray.position + data.t * ray.direction; //Vector3 normal = data.nearestObject->getNormalAt(point); /////////float dot = ray.direction * normal; /////////dot = dot < 0 ? -dot : dot; /////////color.r *= dot; /////////color.b *= dot; /////////color.g *= dot; /////////acc = blendSoftLight(color, acc); } } return acc; }