Jump to content

reepblue

Developers
  • Posts

    2,510
  • Joined

  • Last visited

Everything posted by reepblue

  1. I've been having issues with Vsync as of lately. Strangely when I load a map, it'll run at 60fps with vsync. Then when I reload it, the framerate tanks to 20, until you change the vsync setting to off, then on again, and it'll run at 60 again. Maybe I should upload the project so Josh can take a look at it as I would really like vsync to work as expected, and not turn the game into a slide show.
  2. reepblue

    Environment Probes

    I really hope you go forward with this. Although I've created my own system, I'd be nice to have it an official feature. I also didn't do a real world test (Full playable map with gameplay, etc), so I expect something to pop up with it. (I always do!) Anyway, glad to see you're looking into this and I can't wait to hear more on this.
  3. Visual Studio 2013/2015 Notepad Notepad++ Google Chrome Paint.Net Adobe Photoshop Adobe Illustrator Blender Goldwave Audacity Windows Media Player And I use an outdated version of MediaMonkey so I can listen to music while I work.
  4. With the recent popular substance shader by Shadmar, more talk and focus has been about cubemap reflections surfaced in the community. Reflections in Leadwerks were done in the past with the SSLR post process shader which made all surfaces reflect the world in real time. However, it had the following problems: It was applied to ALL materials in the scene. If you had a material that wouldn't normally reflect such as concrete or wood, the shader would still effect those materials. Basically, the texture artist had little control. The post process shader needed to be first on the list, and some people didn't understand that. You could adjust the reflections by the model's alpha color. But if you had any shader that relied on the alpha mask for map blending or something else, you're out of luck! The reflections distorted based on camera angle, and not really great for in-game action. Like everything OpenGL, there is/was a chance it wouldn't work well with AMD gpus. This was all we had until in February, Mattline1 posted a blog on his PBR system, which included a block of code that built a world cubemap and swapped the cubemap texture with it. Thankfully, he uploaded is source code so anyone who has the professional edition could download his code and have a look. While his implementation is very nice, it has the following design flaws for a typical Leadwerks user. You needed to use only the PBR shader. Normal Leadwerks shaders didn't render well. Needed a Post process effect to adjust the gamma of the scene. Weeks later, Shadmar uploaded his version of a Substance/PBR shader which allowed users to still use their existing shaders, and gave artists more to work. Since it's a shader, and not a full implementation like Matt's, it didn't have the world reflection system. I've been busy with a lot of Source engine work, but seeing how much interest this is getting lately, I decided to take a few days off and see if I can make my own cubemap system. The Implementation A disclaimer, this is not a full "How-To" as you'll need to add it to how your application, and it'll most likely do things differently than how I have my application set up. First, we need to figure out how we are gonna get a world cubemap to a texture. While it's not the most "next-gen" way of doing this, I decided to base my system off of the Source engine because, well I know how it works, and it's pretty simple. It goes like this: Mapper places a env_cubemap entity near a shinny surface. (Any material set to use cubemaps.) Mapper compiles and runs the engine. Mapper than types "buildcubemaps" into the console. For each env_cubemap entity, 6 "pictures" are taken (up, down, left, right, forward, and back). than those textures are saved within the bsp. The map restarts, and the surface will use the near by cubemap texture. Great, that seems very straight forward, and we can remove steps 2 and 3 as there is no compling in Leadwerks, and everything should just work. The first thing we need is a 3D point in the world that'll act as our env_cubemap. class Cubemap : public Pivot { public: Cubemap(Vec3 pos = NULL); //lua virtual ~Cubemap() {} ... ... ... }; We build off of the pivot class because we want this to actually exist in our world, not be a "puppeteer" for a pivot entity. We also have the position being set in the constructor as the only way to get our custom entity into the world is by a lua script. Using ToLua++ we can make a script that we can attach to a pivot/sprite. function Script:Start() local n = Cubemap:new(self.entity:GetPosition(true)) self.entity:Hide() end This script will spawn our cubemap entity at our editor placed pivot, then hide the editor placed pivot. Basically, we swap the entities during level load. This cubemap entity job is to search for near by entites, (Which I currently have set to it's aabb radius + a range float) then change it's surface material with a copy of what it had, only with a different cubemap texture. Early in development, I just have the entity fix the cubemap texture to the current world's skybox to make sure that this would work. void Cubemap::SetReflectionTextureToSkybox(Leadwerks::Surface* surf) { if (WORLD == NULL) { return; } if (WORLD->skyboxpath == "") { return; } if (!surf) { return; } Material* mat = surf->GetMaterial(); if (!mat) { return; } // Make this faster, if there is any indication of a surface not using the substance shader, abort the cubemap application! // If there is no cubemap assigned, then we can skip this object. if (mat->GetTexture(6) == nullptr) return; // if the metal value is 0, we can skip. int matspecmetalness = mat->GetColor(COLOR_SPECULAR).w; if (matspecmetalness == 0 ) return; Material* copy = (Material*)mat->Copy(); if (copy != NULL) { Texture* cubeTexture = Texture::Load(WORLD->skyboxpath); copy->SetTexture(cubeTexture, 6); surf->SetMaterial(copy); cubeTexture->Release(); copy->Release(); } } Before we go into building the world cubemaps, we need to add this to the entity's header. This will make it so we can pass a texture to the entity: Texture* SavedMap; Texture* GetCubemap() { return SavedMap; } Now to the cubemap factory, which on map load will find all of our cubemap entites, do the texture building or each entity, Set SavedMap to the new cubemap texture, then tell the cubemap entity to look for near by entities so it can do it's replacement job. Thankfully, all the yucky stuff has been done by Matt, so I just needed to cut the stuff I didn't need, and make it handle multiple level loads and disconnects to work with my worldmanager class. Here's a few snip of this process. bool CubemapFactory::initialize() { Release(); ... ... ... int i = 0; do { if (WORLD->GetEntity(i)->GetKeyValue("cubemap", "0") == "1") { Cubemap* pCubemap = dynamic_cast<Cubemap*>(WORLD->GetEntity(i)); if (pCubemap != NULL) { // Build the cubemap cubeTexture = Leadwerks::Texture::CubeMap( reflectionResolution, reflectionResolution, Leadwerks::Texture::RGBA, Leadwerks::Texture::Mipmaps ); cubeTexture->BuildMipmaps(); Leadwerks::OpenGL2Texture* gl2cubeTexture = dynamic_cast<Leadwerks::OpenGL2Texture*>(cubeTexture); glActiveTexture(gl2cubeTexture->GetGLTarget()); glBindTexture(GL_TEXTURE_CUBE_MAP, gl2cubeTexture->gltexturehandle); glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); glGenerateMipmap(GL_TEXTURE_CUBE_MAP); // Apply it! GenerateReflection(pCubemap->GetPosition()); //<-- generate first reflection texture GenerateReflection(pCubemap->GetPosition()); //<-- use initial texture to generate correct texture if (cubeTexture != nullptr) { pCubemap->SavedMap = cubeTexture; } // Tell the cubemap to look for near by entities, and replace it's cubemap texture with cubeTexture pCubemap->SearchForEntites(); cubeTexture->Release(); } } i++; } while (i < WORLD->CountEntities()); ... ... ... CubemapFactory::init = true; } GenerateReflection() is pretty much the same as Matt's PBR project. That function actually does the "camera work", and saves the result in a Texture. This is done on the fly during level transition. Skipping Dynamic Objects There is just one problem however. Everything is being rendered when the cubemaps are being built. So any enemies, or move-able objects will be baked into a reflection. To fix this, we need to have all objects that can move (Mostly have mass) be hidden, and then re-shown after we've finished the building of cubemaps. Pretty much. #define S_NULL "" #define ON "1" void ShowMoveables(Entity* entity) { if (entity != NULL) { if (entity->Hidden() == true && entity->GetKeyValue("hide_for_cubemap", S_NULL) == ON) { entity->Show(); entity->AddForce(Vec3(0, 0, 0)); // <-Wake me! entity->SetKeyValue("hide_for_cubemap", S_NULL); } } } void HideMoveables(Entity* entity) { if (entity != NULL) { // Things to look for ar entites with the mass > 0, or have their shadow mode non static! if (entity->GetMass() == 0 || entity->GetShadowMode() == Light::Static) return; // Only hide the non-hidden! if (entity->Hidden() == false) { entity->SetKeyValue("hide_for_cubemap", ON); entity->Hide(); } } } void MapHook(Entity* entity, Object* extra) { // For cubemap generation, we don't want anything that's set to move to be built in with our cubemaps. HideMoveables(entity); } bool WorldManager::Connect(std::string pMapname) { ... if (Map::Load(pMapname, &MapHook) == false) return false; ... return true; } //-------------------------------------- // For cubemap building! //-------------------------------------- void WorldManager::MakeMoveablesVisible() { vector<Entity*>::iterator iter = entities.begin(); for (iter; iter != entities.end(); iter++) { Entity* entity = *iter; ShowMoveables(entity); } } Then back in the initialize function of our cubemap factory before we return true. // Lastly, redraw moveables! worldmanager.MakeMoveablesVisible(); And now anything that has mass, or has it's ShadowMode set to Dynamic will not be baked into the reflection! Cleaning up To make it so that this can work with multiple level loads and when the game "disconnects" (Not in a map), we need to reset everything. Cubemap factory: void CubemapFactory::Render() { if (WORLD != NULL || worldmanager.IsConnected() == true) { if (!CubemapFactory::init) { CubemapFactory::initialize(); } WORLD->Render(); } } void CubemapFactory::Release() { System::Print("Clearing Cubemaps!"); CubemapFactory::init = false; if (cubeTexture != NULL) { cubeTexture->Release(); } CubemapFactory::currentContext = nullptr; CubemapFactory::reflectionCamera = nullptr; CubemapFactory::cubeBuffer = nullptr; CubemapFactory::cubeTexture = nullptr; } And instead of calling world->Clear in my world manager, I instead call this function: void WorldManager::ClearWorld() { CubemapFactory::Release(); world->Clear(); } Calling CubemapFactory::Release() may not be necessary as it's called everytime the factory is initialized, but it doesn't hurt to be safe! Conclusion It was a ride getting this to work correctly. I'm still not happy about how the cubemaps look for near by entities, but it's better than what we have now, which is nothing, Apperently, Josh is concidering this as a engine feature so all of this work might just be temp until he adds it in, which hopefully will be smoother and less error prone! But what we have a system that works like this: Engine loads a map, world created, etc. A map hook hides any entities that has mass or a dynamic shadow mode. Cubemap Factory takes it's "pictures" much like Source does when buildcubemaps is executed. Each cubemap texture is given to the right Cubemap entity, then released. The cubemap looks for near by entites and swaps the model surface's default cubemap with the one it got from the factory. Cubemap factory tells the world manager to re-show the entities it hid. Things continue as normal. So that's it! Thanks for reading!
  5. What you have is great, but this video came to me when I saw the map reflection in the floor. If you are gonna do this, maybe make it it's own shader file perhaps.
  6. Source engine like cubemap generation!
  7. Funny, Last night I've just did the hellish part of generating cubemaps during level load with modding Matt's PBR code. I was gonna write a blog entry when I was done. I just need to correct the cubemap pivot's search distance for surfaces.
  8. I just got the time to play with it, and man, I'm glad that this just model shaders (and the light edits) and doesn't need any post processing on top of it. Excellent work, Always gonna have this installed in my projects from now on. Thank you for doing this. EDIT: Seems the only issue I came across was that materials using the shader are not effected by light sources. (They seem self lit.) EDIT2: Seems that bug is only effected on shinny surfaces (like the metal surfaces.) You can adjust the brightness of the 'shinny' entity to accommodate for the light issue.
  9. Very nice, really looking forward to this. I really hope things like this attracts more artists to the community. Can't wait, looking forward to it.
  10. It could work if it was possible to do a one time build on command, but the save function is commented out in the library. The next best thing is to do what you suggested way back, and then do something to tell the shader to use that cubemap instead.
  11. Amazing Shadmar! Integrate Matt's cubemap building code for accurate cubemaps and this will be perfect!
  12. I did this with the newer build up above, but I'll add it to this version in due time. Thanks for reminding me.
  13. reepblue

    Scripted Behavior

    I really hope that the template system will get an update reflecting these changes. It'd be nice if someone want's to make a game completely in C++ can just clone the necessary files to get the engine to run, rather also cloning a bunch of scripts and assets that they're mostly not gonna use. This benefits both sides, as new users get to make games using the flowgraph and pre-made scripts, while advanced/experienced users have the option to start with a clean slate, and not have the project manager keep copying over files they don't need/want. I can go in-depth with a suggestion thread about this another time.
  14. Nothing should hit the player if SetPickInfo is 0. but I can see in cases where you want things to shoot at you. Yeah, the way you'd go around this is make a collision type that hits everything but the player, and have your pick function use that.
  15. reepblue

    Scripted Behavior

    Would also be cool if the camera followed the player/object like they do in Portal. Glad Jazzoyna did this already, so the battle is half over. I've made an actual laser sprite if you want it. I'm pretty sure you can use the turret model that's already on the workshop and include it in the SDK. I've made a custom phys file for that as well. Was gonna make HL2 styled turrets until I got pulled aways to do other stuff.
  16. Curious. If you place this dll in with your game exe, will the issue magically go away? I'm on a Nvidia GPU so I can't test it myself. Dll is from an old CCC driver before AMD started breaking OpenGL support.
  17. I'm hoping Vulkan will make Leadwerks run and behave the same on both brand of cards. Then again, it's up to their drivers so...
  18. What's the upsides of moving to Vulkan than if it's "slower". Obviously, the benefits out weighs the costs for you to consider it. Although, these enhancements might not help with the game development, it might attract new users/get more people interested in Leadwerks. People can be weird.
  19. @Mattline1 I have messed with the template system before, if you need help, PM me l although you'd probably get it setup yourself as it's very straight forward. Also, Did you try messed with the spec values for the gloss value?
  20. I like that in that "review" they gave it a positive rating despite what they said. Something that kind of needs to be addressed is the generic upload errors with the workshop. I pretty much gave up on updating the Vectronic Demo at this point. I have no idea if my upload speed has something to do with it or not. As always, I'm looking forward to the updates. Interested to see how networking will work.
  21. Hi, I've been wondering this for a while; is it possible to change the AppDataPath for your game using the professional edition? I commented out where it makes the default settings cfg, but it dumps the log under AppData/Leadwerks by default. I'm asking if there is a way to set it so the log file dumps within the root game folder, or maybe move the entire DataPath to the user's Documents folder, much like the editor does now. Thanks in advance.
  22. You can argue that the game is under fair use due to the entire project being a parody. I'm no lawyer, but if you really want to go forward, I'd look into the loop holes within the copyright system. You might still get clams, but if you've done your homework, you should be fine,
  23. I'd be cool if there was a bool flag in the cfg to turn this notification off. This way, if you're using a C++ project, you don't have to take time to update the game, then rebuild your executable.
  24. Something I don't like about the template structure is that there is no skeleton template (That has nothing but the cpps/h/projects, the dlls, and shaders. I mean, you can hand make projects, but you'll be pressing "No" alot when it asks to update your project. the template tree should be skeleton -> common -> (Template). If you package your game, no one will be able to edit the lua files, as they'll be encrypted. But I'm gonna say this now, it's a lot easier to code your game objects in lua than C++. I only really recommend doing your application handling (window, context, map loading, etc) in C++. But that's just how I use the engine, everyone uses it differently it seems.
×
×
  • Create New...