Jump to content

klepto2

Developers
  • Posts

    837
  • Joined

  • Last visited

Everything posted by klepto2

  1. local window = CreateWindow("TEST LEVEL", 0, 0, 1280, 720, displays[1], WINDOW_CENTER | WINDOW_TITLEBAR | WINDOW_FULLSCREEN)
  2. While testing the new Effect feature in the Editor i encountered a small problem with my posteffect shaders. Some of my effects use a technique called reprojection, actually this is a very basic implementation but improves the perfromance a lot. What it does, is that it uses a 4*4 Bayer filter to determine which pixel needs to be calculated based on the fragment coordinate and the current frame. If a pixel is not meant to be calculated it reads the result from the previous frame (reprojecting the current uv to the previous uv). This means over a period of 16 frames the whole buffer is calculated. Unfortunatly this is not working in the editor. I believe it might be due to the fact (correct me @Josh if i am wrong), that the editor doesn't use async rendering and the camera is not rendered in realtime. so if we can get a flag which indicates if a shader is invoked from the editor, we could disable some features (reprojection in this case) and use the pfx correctly in the editor. I will write a very basic shader which will simulate the error and attach it later here.
  3. Ok, now the ssr setting doesn't disable the sky and pfx anymore. But i can't see any ssr reflections with the current build. (Steam and Standalone) project is a clean project to test the ssr, so everything should be up to date.
  4. you can add your own IOSystem to the importer like this Assimp::AndroidJNIIOSystem *ioSystem = new Assimp::AndroidJNIIOSystem(app->activity); if ( nullptr != iosSystem ) { importer->SetIOHandler(ioSystem); } https://assimp-docs.readthedocs.io/en/latest/usage/use_the_lib.html#using-custom-io-logic-with-the-c-class-interface
  5. With the latest release, when you enable SSR on a Camera the skybox is disabled and no posteffects are rendered. both Steam and standalone.
  6. Download: VolumetricLighting0_9_5.zip This is a small but powerful posteffect with "real" VolumetricLighting for all lighttypes. It shows some basic powerful features of the UltraEngine pipeline: Performance Accesibility (you can get nearly everything in a shader at every time) The shader itself features Volumetric lighting based on the included shadowmap lookups and performs some calculations more or less like the screenspace godrays, but not depenfing on the backbuffer colors, but real shadow casting. It also features calculates only 1/16th of a buffer (plus out of scope pixels) per frame and reprojects the result of the previous buffer if possible. The shader itself is currently more or less for demonstration usage only, because there are no volumetric settings for lights available and adding these would require some kind of lua or cpp backend.
  7. When you add Posteffects in the worldsettings dialog and reorder them. they are added mlutiple times to the cameras. At first when you reorder the effects it looks correct, but if you close the dialog and refresh the perspective viewport you can see artifacts and multiplied effects, eg the godrays will get brighter and brighter. When you reopen the settings you now see the effects multiple times (multiplied by the numbers of reorders you did previosly) Before reordering: And after reordering multiple times: As an addtional request hidden in here: Expand the posteffect api with Remove and sorting capabilities. Currently you can only add the posteffects and clear all, but not remove single items.
  8. Just some small things in the world-settings: skybox/specular and diffuse are not loaded from previous maps after assigning skybox/specular and diffuse textures and reopening the world-settings, the skybox value is empty the posteffect tab is completely empty and nothing can be done in the tab except closing the window when you open the world settings dialog he first tab is selected, but the content shown is the content of the last tab opened previously (open settings ⇾ select fog⇾ close ⇾ open again ⇾ selected tab is environment, but content is the fog settings)
  9. With the latest release 0.9.5 (Build 567) it seems the lib files are damaged. Both debug and release.
  10. The scene settings is removed and is replaced with a world-settings dialog under Edit -> World Settings.
  11. This is a wierd one (at least it looks like a weird one) i have a simple scene with a terrain and a sphere. the sphere is set to a red color. In release: The result is always a white sphere but whith a correct looking terrain. In debug: sometimes the same result as in release, but sometimes the sphere gets its color (and can be changed at runtime) but then the terrain is pure black as long as the sphere is in view. #include "UltraEngine.h" #include "ComponentSystem.h" //#include "Steamworks/Steamworks.h" using namespace UltraEngine; int main(int argc, const char* argv[]) { #ifdef STEAM_API_H if (not Steamworks::Initialize()) { RuntimeError("Steamworks failed to initialize."); return 1; } #endif RegisterComponents(); auto cl = ParseCommandLine(argc, argv); //Load FreeImage plugin (optional) auto fiplugin = LoadPlugin("Plugins/FITextureLoader"); //Get the displays auto displays = GetDisplays(); //Create a window auto window = CreateWindow("Ultra Engine", 0, 0, 1280 * displays[0]->scale, 720 * displays[0]->scale, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Create a world auto world = CreateWorld(); auto camera = CreateCamera(world); camera->SetClearColor(0.125); camera->SetFov(70); camera->Move(0, 2, -8); camera->AddComponent<CameraControls>(); //Create light auto light = CreateDirectionalLight(world); light->SetRotation(45, 35, 0); light->SetColor(2); world->RecordStats(true); auto main_instance = CreateTerrain(world, 512, 512); auto sphere = CreateSphere(world, 2.0, 32); sphere->SetColor(1.0, 0.0, 0.0); //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { if(window->KeyHit(KEY_F1)) sphere->SetColor(1.0, 0.0, 0.0); if (window->KeyHit(KEY_F2)) sphere->SetColor(0.0, 1.0, 0.0); world->Update(); world->Render(framebuffer); #ifdef STEAM_API_H Steamworks::Update(); #endif } #ifdef STEAM_API_H Steamworks::Shutdown(); #endif return 0; } Above is release (everytime) /debug(not everytime) ( color can't be changed with F1/F2) the same with debug build, sometimes the color works. (then the color can be changed with F1/F2)
  12. If i remember correctly you need to modify gl_FragDepth in the fragment shader. If gl_FragDepth is not set in fragment, then the fixed function depth method will be used. Ref: https://registry.khronos.org/OpenGL-Refpages/gl4/html/gl_FragDepth.xhtml
  13. I thought the same. Take a look here: and here: For the parameters i think the object which calls the hook should be included and an extra field for custom data. The most important thing for me is that it will be possible to get the internal opengl data. (not only the texture ids, but maybe also the buffers etc) . As i posted in the first linked thread i would prefer hooks on the way BEFORE / AFTER and also one for the world update and then for the camera.
  14. Just my thought. The debug-build was mainly slower because the vulkan validation-layer kicks in and slows everything down. In Leadwerks there was also no difference between debug and release (for simple apps).
  15. As you mentioned physics: a callback into the function where the force is applied. (possibly needed for adding additional effectors like buoyancy or other forces)
  16. There are already some hooks, but to have more flexibility and abilities to add more functionality i would suggest to add things like: BEFORE_WORLD_UPDATE AFTER_WORLD_UPDATE BEFORE_CAMERA_RENDER (Used to update meshes based on the camera) AFTER_CAMERA_RENDER (Maybe to reset some states) Also some more for the render pipeline: RENDER_INIT (don't know if its the same in 0.9.5, but in < 0.9.5 the VKdevice etc was lazy initialized, so that you need to HOOK into the RENDER or TRANSFER Hook to get the data) Some more detailed Hooks into RENDER and/or TRANSFER (to add commands before the actual commands or after) thats it for now. If someone has more ideas, you can add these here.
  17. While this might not be needed for most users, and a lot can change in the Render* classes can change. It is needed to have access to have access to this classes from its highlevel counterparts. (eg: Texture -> RenderTexture) Why: More flexibility Easier to add extensions which require low level access like GLHandles or VK handles depending on the renderer Integration of third party things will be easier. I noticed that there were some kind of methods to get this data. Like the commented Ultraengine::Render::GetRenderTexture function. something like this for all Render* items would be nice.
  18. I will rebuild and refactor it as soon as the new Ultra Engine version is out, as I think there will be some kind of refactoring needed. I think most work will go into the actual Compute-Pipeline. For my current Environment (atmosphere and ocean) WIP I already have optimized a lot which might cause issues in this build, but I need time to polish it further and make it more future prove and stable.
  19. You can try this: To have fully black ambient you can try to lower the iblintensity : https://www.ultraengine.com/learn/World_SetIblIntensity?lang=cpp
  20. ok, this is a weird bug i have encountered while trying to optimze some texture generation. Sometimes a camera which is set to not render in realtime still renders in realtime. #include "UltraEngine.h" using namespace UltraEngine; int main(int argc, const char* argv[]) { //Get the displays auto displays = GetDisplays(); //Create a window auto window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); //Create a world auto world = CreateWorld(); //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Create light auto light = CreateBoxLight(world); light->SetRange(-10, 10); light->SetRotation(15, 15, 0); light->SetColor(2); //Create camera auto camera = CreateCamera(world); camera->SetClearColor(0.125); camera->SetPosition(0, 0, -3); camera->SetFov(70); //Create scenery auto box = CreateBox(world); auto cone = CreateCone(world); cone->SetPosition(1.25, 0, 0); cone->SetColor(0, 0, 1); auto sphere = CreateSphere(world); sphere->SetPosition(-1.25, 0, 0); sphere->SetColor(1, 0, 0); //Create camera and texture buffer auto texbuffer = CreateTextureBuffer(256, 256); auto cam2 = CreateCamera(world); cam2->SetClearColor(1, 1, 1); cam2->SetRenderTarget(texbuffer); cam2->SetRealtime(false); //Create material auto mtl = CreateMaterial(); auto tex = texbuffer->GetColorAttachment(); mtl->SetTexture(tex); box->SetMaterial(mtl); cone->SetMaterial(mtl); sphere->SetMaterial(mtl); //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { //Orient the texturebuffer camera //Play around with these values and restart the app, sometimes the cam2 is rendered constantly even it is not set to realtime cam2->SetPosition(0, 0, 0); cam2->Turn(0, 1, 0); cam2->Move(0, 0, -2); cam2->SetRange(0.1, 1000.0); //Press the space key to redraw the texture buffer camera // if (window->KeyHit(KEY_SPACE)) cam2->Render(); world->Update(); world->Render(framebuffer); } return 0; } Run this snippet in release mode, mutliple times. You may need to change the cam2 values (position, turn, move or range) in order too get the bug. in most cases you get the desired one time render, but (it seems randomly) you get realtime rendering sometimes as well. In my bigger project my non realtime cameras are updated all the time and i am not calling the render function at all.
  21. it might be that you need to invert the light_direction. The reason i use RGBA32 o RGBA16 is that you don't need to make any bitshifting etc. if you store a float in a RGBA32 texture the value will be the same as how you uploaded it. RGBA16 will just loose some precision, while RGBA will clamp the float to 0.0-1.0. As long as you store values between 0.0 and 1.0 the bytes to float should work the same. But is not needed with a RGBA32/16 texture. I use also texelFetch, otherwise sampling might corrupt the actual value. I simply access the data in the shader like this: vec4 data = texelFetch(texture2DSampler[configId],ivec2(0,i+1),0); cascades[i].spectrumHandle = int(data.x); cascades[i].normalHandle = int(data.y); cascades[i].size = data.z;
  22. I haven't seen this problem in my applications, of course the update might be a bit off, but i don't see flickering. But maybe its because i use WritePixel with a Float32 pixmap directly instead of a using a buffer. I have something like this: class MaterialExtensionInfo : public Object { private: shared_ptr<Pixmap> _data; shared_ptr<Texture> _dataTexture; int current_ptr = 0; public: MaterialExtensionInfo(); void Sync(); shared_ptr<Texture> GetDataTexture(); void Add(int x, int y, Vec2 value); void Add(int x, int y, Vec3 value); void Add(int x, int y, Vec4 value); void Add(int x, int y, Mat3 value); void Add(int x, int y, Mat4 value); }; MaterialExtensionInfo::MaterialExtensionInfo() { _dataTexture = CreateTexture(TEXTURE_2D, 64, 32, TEXTURE_RGBA32, {}, 1, TEXTURE_DEFAULT, TEXTUREFILTER_NEAREST); _data = CreatePixmap(64, 32, TEXTURE_RGBA32); } void MaterialExtensionInfo::Sync() { _dataTexture->SetPixels(_data); } shared_ptr<Texture> MaterialExtensionInfo::GetDataTexture() { return _dataTexture; } void MaterialExtensionInfo::Add(int x, int y, Vec2 value) { _data->WritePixel(x, y, Vec4(value.x, value.y, 0.0, 0.0)); } void MaterialExtensionInfo::Add(int x, int y, Vec3 value) { _data->WritePixel(x, y, Vec4(value.x, value.y, value.z, 0.0)); } void MaterialExtensionInfo::Add(int x, int y, Vec4 value) { _data->WritePixel(x, y, value); } void MaterialExtensionInfo::Add(int x, int y, Mat3 value) { _data->WritePixel(x, y, Vec4(value.i.x, value.i.y, value.i.z,0.0)); _data->WritePixel(x + 1, y, Vec4(value.j.x, value.j.y, value.j.z, 0.0)); _data->WritePixel(x + 2, y, Vec4(value.k.x, value.k.y, value.k.z, 0.0)); } void MaterialExtensionInfo::Add(int x, int y, Mat4 value) { _data->WritePixel(x, y, value.i); _data->WritePixel(x + 1, y, value.j); _data->WritePixel(x + 2, y, value.k); _data->WritePixel(x + 3, y, value.t); } In your case, the sun direction is already available in the shader, you don't need to pass it down like that, In ultraEngine you can always access nearly anything at anytime in the shader. This itroduces a lot of possbilities: eg calculating combined atmospheric effects for multiple suns. to iterate over all Directional Lights you can do something like this in your shader: #include "../../Base/Lighting.glsl" ... in main() ... uint n; uint lightIndex; // Global lights (affects all cells) uint lightlistpos = GetGlobalLightsReadPosition(); uint countlights = ReadLightGridValue(lightlistpos); for (n = 0; n < countlights; ++n) { ++lightlistpos; lightIndex = ReadLightGridValue(lightlistpos); int ShadowSoftness = 2; const float minlight = 0.004f; vec3 lightDir, lightPosition; vec4 shadowCoord, color; bool transparent = false; mat4 lightmatrix; uint flags, lightflags; int shadowMapID, lighttype, shadowcachemapID; float attenuation = 1.0f; dFloat d; #ifdef DOUBLE_FLOAT dvec2 lightrange, coneangles, shadowrange; #else vec2 lightrange, coneangles, shadowrange; #endif int shadowkernel; ExtractEntityInfo(lightIndex, lightmatrix, color, flags); ExtractLightInfo(lightIndex, shadowMapID, shadowcachemapID, lightrange, coneangles, shadowrange, lightflags, shadowkernel); const int falloffmode = ((lightflags & ENTITYFLAGS_LIGHT_LINEARFALLOFF) != 0) ? LIGHTFALLOFF_LINEAR : LIGHTFALLOFF_INVERSESQUARE; if ((lightflags & ENTITYFLAGS_LIGHT_STRIP) != 0) lighttype = LIGHT_STRIP; // This needs to come first because the flag is a combination of others else if ((lightflags & ENTITYFLAGS_LIGHT_BOX) != 0) lighttype = LIGHT_BOX; else if ((lightflags & ENTITYFLAGS_LIGHT_DIRECTIONAL) != 0) lighttype = LIGHT_DIRECTIONAL; else if ((lightflags & ENTITYFLAGS_LIGHT_SPOT) != 0) lighttype = LIGHT_SPOT; else lighttype = LIGHT_POINT; if(lighttype == LIGHT_DIRECTIONAL) { #ifdef DOUBLE_FLOAT lightDir = vec3(normalize(lightmatrix[2].xyz)); #else lightDir = normalize(lightmatrix[2].xyz); #endif // Do calculations, break out if needed } }
  23. Just to show a more extreme sample which i came up with (might be interesting for you as well @SpiderPig) It is a combination of multiple factors and shows multiple problems at once. Instantiating still has a memleak, not that high than then previously but still visible in this scenario Debug leads to rendertimes > 4000 ms while release is much lower but still too high in my opinion (even if you comment out the extra rendertargets and cameras) Having too many instances at the same position leads to an exception in the physicsthread Having too many instances leads to vulkan buffer size and index validation errors. #include "UltraEngine.h" #include "ComponentSystem.h" //#include "Steamworks/Steamworks.h" using namespace UltraEngine; SIZE_T PrintMemoryInfo() { auto myHandle = GetCurrentProcess(); //to fill in the process' memory usage details PROCESS_MEMORY_COUNTERS pmc; //return the usage (bytes), if I may if (GetProcessMemoryInfo(myHandle, &pmc, sizeof(pmc))) return(pmc.WorkingSetSize); else return 0; } int main(int argc, const char* argv[]) { #ifdef STEAM_API_H if (not Steamworks::Initialize()) { RuntimeError("Steamworks failed to initialize."); return 1; } #endif RegisterComponents(); auto cl = ParseCommandLine(argc, argv); //Load FreeImage plugin (optional) auto fiplugin = LoadPlugin("Plugins/FITextureLoader"); //Get the displays auto displays = GetDisplays(); //Create a window auto window = CreateWindow("Ultra Engine", 0, 0, 1280 * displays[0]->scale, 720 * displays[0]->scale, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); if (!AttachConsole(ATTACH_PARENT_PROCESS)) { if (AllocConsole()) { freopen("conin$", "r", stdin); freopen("conout$", "w", stdout); freopen("conout$", "w", stderr); } } else { auto consoleHandleOut = GetStdHandle(STD_OUTPUT_HANDLE); auto consoleHandleIn = GetStdHandle(STD_INPUT_HANDLE); auto consoleHandleErr = GetStdHandle(STD_ERROR_HANDLE); if (consoleHandleOut != INVALID_HANDLE_VALUE) { freopen("conout$", "w", stdout); setvbuf(stdout, NULL, _IONBF, 0); } if (consoleHandleIn != INVALID_HANDLE_VALUE) { freopen("conin$", "r", stdin); setvbuf(stdin, NULL, _IONBF, 0); } if (consoleHandleErr != INVALID_HANDLE_VALUE) { freopen("conout$", "w", stderr); setvbuf(stderr, NULL, _IONBF, 0); } } //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Create a world auto world = CreateWorld(); auto camera = CreateCamera(world); camera->SetClearColor(0.125); camera->SetFov(70); camera->Move(0, 2, -8); camera->AddComponent<CameraControls>(); //Create light auto light = CreateDirectionalLight(world); light->SetRotation(45, 35, 0); light->SetColor(2); auto render_target = CreateTextureBuffer(framebuffer->size.x, framebuffer->size.y); auto render_target_2 = CreateTextureBuffer(framebuffer->size.x, framebuffer->size.y); auto test_camera = CreateCamera(world); test_camera->SetRenderTarget(render_target); auto test_camera_2 = CreateCamera(world); test_camera_2->SetRenderTarget(render_target_2); camera->SetSweptCulling(true); world->RecordStats(true); int waterLevel = 20; shared_ptr<Entity> main_instance = CreateTerrain(world, 1024, 1024); auto sphere = CreateSphere(nullptr, 2.0, 32); vector<shared_ptr<Entity>> test_instances; bool set_position = true; //Set to false and it leads to a exception in the Physicsthread int step_size = 32; //Lower that and it will lead to invalid buffersize indices / size in vulkan //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { test_camera->SetMatrix(camera->GetMatrix()); test_camera->SetRange(camera->GetRange()); test_camera_2->SetRotation(camera->GetRotation() * Vec3(-1.0, 1.0, -1.0)); test_camera_2->SetPosition(camera->position.x, -camera->position.y + 2 * (waterLevel + 5.0), camera->position.z); test_camera_2->SetRange(camera->GetRange()); test_instances.clear(); for (int x = -512; x <= 512; x += step_size) for (int z = -512; z <= 512; z += step_size) { auto i = sphere->Instantiate(world); if(set_position) i->SetPosition(x, 1.0, z); i->SetColor(Vec4(1.0, 0.0, 0.0, 1.0)); test_instances.push_back(i); } world->Update(); world->Render(framebuffer); #ifdef STEAM_API_H Steamworks::Update(); #endif window->SetText("rt: " +String(world->renderstats.rendertime) + " MEM: " + String(PrintMemoryInfo() / 1024) + " kb"); } #ifdef STEAM_API_H Steamworks::Shutdown(); #endif return 0; } this is the interesting part for the multiple errors: bool set_position = true; //Set to false and it leads to a exception in the Physicsthread int step_size = 32; //Lower that and it will lead to invalid buffersize indices / size in vulkan I hope you can resolve this as it breaks the in majority very fast renderer.
  24. As the title said. In the header source, there is already a outcommented void SetClipPlane(const int index, const Plane& p); function. While this might not be needed for many people, it is a nice and simple feature. I would need it for a deifferent approach for the water renderer to support realtime reflections without ssr (while ssr is nice, it has some downsides and needs a lot of tweking to look right in larger environments.) and proper refraction without the need to modify the integrated refraction shader.
×
×
  • Create New...