Josh Posted March 27, 2023 Share Posted March 27, 2023 This shows how to render specific objects to another texture and display an outline around them: #include "UltraEngine.h" #include "ComponentSystem.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 a camera auto camera = CreateCamera(world); camera->SetClearColor(0.125); camera->SetFov(70); camera->SetPosition(0, 0, -3); //Create a light auto light = CreateBoxLight(world); light->SetRotation(35, 45, 0); light->SetRange(-10, 10); //Create a box auto box = CreateBox(world); //Entity component system auto actor = CreateActor(box); auto component = actor->AddComponent<Mover>(); component->rotation.y = 45; //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ //Render to texture box->SetRenderLayers(1 + 2); auto cam2 = CreateCamera(world); cam2->SetClearColor(0, 0, 0, 0); cam2->SetRenderLayers(2); cam2->SetFov(camera->GetFov()); cam2->SetMatrix(camera->matrix); cam2->AddPostEffect(LoadPostEffect("Shaders/PostEffects/Outline.json")); auto sz = framebuffer->GetSize(); auto texbuffer = CreateTextureBuffer(sz.x, sz.y); cam2->SetRenderTarget(texbuffer); //Display overlay auto sprite = CreateSprite(world, sz.x, sz.y); sprite->SetColor(0, 1, 1, 1); sprite->SetRenderLayers(4); auto mtl = CreateMaterial(); sprite->SetMaterial(mtl); mtl->SetTransparent(true); mtl->SetTexture(texbuffer->GetColorAttachment()); auto cam3 = CreateCamera(world, PROJECTION_ORTHOGRAPHIC); cam3->SetClearMode(CLEAR_DEPTH); cam3->SetRenderLayers(4); cam3->SetPosition(sz.x * 0.5f, sz.y * 0.5f, 0); //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { world->Update(); world->Render(framebuffer); } return 0; } 1 3 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Dreikblack Posted May 21, 2023 Share Posted May 21, 2023 How to change outline thickness? Tried to change m and pixelsize in Outline.frag but nothing changed (tried rebuild solution and Compile Shaders.bat). Also i wonder how to outline not whole brush but only one face of it. Quote Link to comment Share on other sites More sharing options...
Dreikblack Posted May 21, 2023 Share Posted May 21, 2023 Solved thickness issue. Made a dedicated .bat for outline shader and this time a shader was recompiled. In Outline.frag m var defines pixel thickness for outline. Quote Link to comment Share on other sites More sharing options...
Dreikblack Posted May 21, 2023 Share Posted May 21, 2023 For few outline colors at same time all elements should be recreated? I mean maybe camera can be seted for few render layers or something like that. I think i might need 4 color at same time Quote Link to comment Share on other sites More sharing options...
Josh Posted May 21, 2023 Author Share Posted May 21, 2023 I think you would want to render the outlined objects each to a separate camera using the render layers feature to control what appears where, and then have a transparent sprite for each one that gets drawn in the final 2D camera. 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Dreikblack Posted May 24, 2023 Share Posted May 24, 2023 Outlines drops FPS a lot, noticed only now Difference is crazy between 2 and 3 outlines already - from 230-240 to 120-130. RTX 2070, 2K screen res. Can anything be done about that (in my code or in the engine later) or i should limit my self by 2 outlines? #include "UltraEngine.h" #include "Components/Mover.hpp" using namespace UltraEngine; enum OUTLINE_TYPE { OUTLINE_RENDER_LAYER = 4, OUTLINE_MOVEMENT = 8, OUTLINE_TARGET_MOVEMENT = 16, OUTLINE_ACTION = 32, OUTLINE_SELECTABLE_UNIT = 64, OUTLINE_SELECTED_UNIT = 128, OUTLINE_ENEMY = 256 }; int main(int argc, const char* argv[]) { //Get the displays auto displays = GetDisplays(); //Create a window auto window = CreateWindow("Ultra Engine", 0, 0, displays[0]->GetSize().width, displays[0]->GetSize().height, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR | WINDOW_FULLSCREEN); //Create a world auto world = CreateWorld(); //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Create a camera auto camera = CreateCamera(world); camera->SetClearColor(0.125); camera->SetFov(70); camera->SetPosition(3, 0, -5); //Create a light auto light = CreateBoxLight(world); light->SetRotation(35, 45, 0); light->SetRange(-10, 10); auto gameScene = CreateScene(); //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ std::vector<Vec4> outlineColors; outlineColors.push_back(Vec4(0.1f, 0.6f, 0.6f, 1)); outlineColors.push_back(Vec4(0.1f, 0.3f, 1.0f, 1)); outlineColors.push_back(Vec4(0.5f, 0.8f, 0.1f, 1)); outlineColors.push_back(Vec4(0.1f, 0.6f, 0.1f, 1)); outlineColors.push_back(Vec4(0.1f, 1.0f, 0.1f, 1)); outlineColors.push_back(Vec4(0.8f, 0.1f, 0.1f, 1)); auto sz = framebuffer->GetSize(); for (int i = 0; i < outlineColors.size(); i++) { auto renderToTextureCamera = CreateCamera(world); renderToTextureCamera->SetClearColor(0, 0, 0, 0); renderToTextureCamera->SetRenderLayers(OUTLINE_MOVEMENT << i); renderToTextureCamera->SetFov(camera->GetFov()); renderToTextureCamera->SetMatrix(camera->matrix); renderToTextureCamera->AddPostEffect(LoadPostEffect("Shaders/PostEffects/Outline.json")); auto texbuffer = CreateTextureBuffer(sz.x, sz.y); renderToTextureCamera->SetRenderTarget(texbuffer); gameScene->AddEntity(renderToTextureCamera); //Display overlay auto displayOverlaySprite = CreateSprite(world, sz.x, sz.y); displayOverlaySprite->SetColor(outlineColors[i]); displayOverlaySprite->SetRenderLayers(OUTLINE_RENDER_LAYER); auto displayOverlayMaterial = CreateMaterial(); displayOverlayMaterial->SetTransparent(true); displayOverlayMaterial->SetTexture(texbuffer->GetColorAttachment()); displayOverlaySprite->SetMaterial(displayOverlayMaterial); gameScene->AddEntity(displayOverlaySprite); //Box auto box = CreateBox(world); box->SetPosition(i, 0, 0); box->SetRenderLayers(1 + (OUTLINE_MOVEMENT << i)); gameScene->AddEntity(box); } auto overlayCamera = CreateCamera(world, PROJECTION_ORTHOGRAPHIC); overlayCamera->SetClearMode(CLEAR_DEPTH); overlayCamera->SetRenderLayers(OUTLINE_RENDER_LAYER); overlayCamera->SetPosition(sz.x * 0.5f, sz.y * 0.5f, 0); gameScene->AddEntity(overlayCamera); //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { world->Update(); world->Render(framebuffer); } return 0; } Quote Link to comment Share on other sites More sharing options...
Josh Posted May 24, 2023 Author Share Posted May 24, 2023 The shader does a lot of texture lookups. If you increased the thickness, it will be even more. The current implementation could be improved by downsampling either the depth buffer or maybe a first-pass color texture, with linear filtering. This could be used as a preliminary rough check in the final subpass, because if the value of a texture read is non-zero, it means there is some highlighted pixels in that area. 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Dreikblack Posted May 24, 2023 Share Posted May 24, 2023 (edited) 1 hour ago, Josh said: The current implementation could be improved by downsampling either the depth buffer or maybe a first-pass color texture, with linear filtering. tbh i have no idea how to do this since i don't know much about graphic programing, especially in Vulkan. Anyway it's looks shader is not what degrades perfomance. Removed AddPostEffect() - same low fps. Just realized you probably meant Outline.json and not frag Anyway this did not helped. "buffers": [ { "size": [0.5, 0.5] } ], Edited May 24, 2023 by Dreikblack Quote Link to comment Share on other sites More sharing options...
Josh Posted May 24, 2023 Author Share Posted May 24, 2023 Yeah, I think it is actually mostly the full-screen transparent blend that is being drawn seven times. I tried combining all the passes into a single texture buffer. You would still need to change the color for each pass somehow, but currently this does not draw anything when I run it: #include "UltraEngine.h" using namespace UltraEngine; enum OUTLINE_TYPE { OUTLINE_RENDER_LAYER = 4, OUTLINE_MOVEMENT = 8, OUTLINE_TARGET_MOVEMENT = 16, OUTLINE_ACTION = 32, OUTLINE_SELECTABLE_UNIT = 64, OUTLINE_SELECTED_UNIT = 128, OUTLINE_ENEMY = 256 }; int main(int argc, const char* argv[]) { //Get the displays auto displays = GetDisplays(); //Create a window auto window = CreateWindow("Ultra Engine", 0, 0, displays[0]->GetSize().width, displays[0]->GetSize().height, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR | WINDOW_FULLSCREEN); //Create a world auto world = CreateWorld(); //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Create a camera auto camera = CreateCamera(world); camera->SetClearColor(0.125); camera->SetFov(70); camera->SetPosition(3, 0, -5); //Create a light auto light = CreateBoxLight(world); light->SetRotation(35, 45, 0); light->SetRange(-10, 10); auto gameScene = CreateScene(); //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ std::vector<Vec4> outlineColors; outlineColors.push_back(Vec4(0.1f, 0.6f, 0.6f, 1)); outlineColors.push_back(Vec4(0.1f, 0.3f, 1.0f, 1)); outlineColors.push_back(Vec4(0.5f, 0.8f, 0.1f, 1)); outlineColors.push_back(Vec4(0.1f, 0.6f, 0.1f, 1)); outlineColors.push_back(Vec4(0.1f, 1.0f, 0.1f, 1)); outlineColors.push_back(Vec4(0.8f, 0.1f, 0.1f, 1)); auto sz = framebuffer->GetSize(); auto texbuffer = CreateTextureBuffer(sz.x, sz.y); //Display overlay auto displayOverlaySprite = CreateSprite(world, sz.x, sz.y); displayOverlaySprite->SetRenderLayers(OUTLINE_RENDER_LAYER); auto displayOverlayMaterial = CreateMaterial(); displayOverlayMaterial->SetTransparent(true); displayOverlayMaterial->SetTexture(texbuffer->GetColorAttachment()); displayOverlaySprite->SetMaterial(displayOverlayMaterial); gameScene->AddEntity(displayOverlaySprite); for (int i = 0; i < outlineColors.size(); i++) { auto renderToTextureCamera = CreateCamera(world); renderToTextureCamera->SetClearColor(0, 0, 0, 0); if (i > 0) renderToTextureCamera->SetClearMode(ClearMode(0)); renderToTextureCamera->SetRenderLayers(OUTLINE_MOVEMENT << i); renderToTextureCamera->SetFov(camera->GetFov()); renderToTextureCamera->SetMatrix(camera->matrix); renderToTextureCamera->AddPostEffect(LoadPostEffect("Shaders/PostEffects/Outline.json")); renderToTextureCamera->SetRenderTarget(texbuffer); gameScene->AddEntity(renderToTextureCamera); //Box auto box = CreateBox(world); box->SetPosition(i, 0, 0); box->SetRenderLayers(1 + (OUTLINE_MOVEMENT << i)); gameScene->AddEntity(box); } auto overlayCamera = CreateCamera(world, PROJECTION_ORTHOGRAPHIC); overlayCamera->SetClearMode(CLEAR_DEPTH); overlayCamera->SetRenderLayers(OUTLINE_RENDER_LAYER); overlayCamera->SetPosition(sz.x * 0.5f, sz.y * 0.5f, 0); gameScene->AddEntity(overlayCamera); //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { world->Update(); world->Render(framebuffer, false); } return 0; } Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Dreikblack Posted May 24, 2023 Share Posted May 24, 2023 23 minutes ago, Josh said: I tried combining all the passes into a single texture buffer. You would still need to change the color for each pass somehow Not really sure how to do it and i still have 70 fps with single texture buffer. For a test i hide cameras in cycle (renderToTextureCamera->SetHidden(true)) and got 700 fps. Quote Link to comment Share on other sites More sharing options...
Dreikblack Posted May 24, 2023 Share Posted May 24, 2023 Did another test - cameras on but removed Outline: 500 fps. Tried again for testing first example with 1 outline - 500 fps. No outlnies - 2000 fps D: Quote Link to comment Share on other sites More sharing options...
Josh Posted May 24, 2023 Author Share Posted May 24, 2023 It would probably be best to create another object for each outlined object, set it to use the unlit shader family, and in the post effect use the object's color as the color written into the texture buffer. Then you can have multiple colors in a single pass. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Dreikblack Posted May 24, 2023 Share Posted May 24, 2023 20 minutes ago, Josh said: in the post effect use the object's color as the color written into the texture buffer Do you mean Outline.frag by post effect in this context? Sorry, I'm not quite follow you Is whole set from signle outline (cameras, buffer. sprite etc.) still needed for this? Quote Link to comment Share on other sites More sharing options...
Josh Posted May 24, 2023 Author Share Posted May 24, 2023 Right now the color is controlled by setting the color of the overlay sprite. I am saying that instead it could be controlled in the outline shader, by getting the color that was rendered and using that instead of just writing vec4(1,1,1,1) like it currently does. 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Dreikblack Posted May 24, 2023 Share Posted May 24, 2023 On 5/24/2023 at 4:28 PM, Josh said: getting the color that was rendered and using that instead I just don't know how to get this color in .frag. Trying this but nothing happens: #version 450 #extension GL_GOOGLE_include_directive : enable #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_multiview : enable #include "../Base/PushConstants.glsl" #include "../Base/CameraInfo.glsl" #include "../Base/TextureArrays.glsl" #include "../Utilities/Dither.glsl" layout(location = 0) in vec2 texCoords; layout(location = 0) out vec4 outColor; const vec4 SelectionColor = vec4(1,1,1,1); void main() { outColor = SelectionColor; outColor.a = 0.0f; float depth = texture(texture2DSampler[PostEffectTexture0], texCoords.xy).r; vec4 c; bool sel; //Handle selected objects if (depth < 1.0f) { const int m = 3; vec2 pixelsize = 1.0f / BufferSize; for (int x = -m; x <= m; ++x) { for (int y = -m; y <= m; ++y) { if (x == 0 && y == 0) continue; float neighbor = texture(texture2DSampler[PostEffectTexture0], texCoords.xy + pixelsize * vec2(x, y)).r; if (neighbor == 1.0f) { outColor = texture(texture2DSampler[PostEffectTexture0], texCoords.xy); return; } } } } } #include "UltraEngine.h" #include "Components/Mover.hpp" 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, displays[0]->GetSize().width, displays[0]->GetSize().height, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR | WINDOW_FULLSCREEN); //Create a world auto world = CreateWorld(); //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Create a camera auto camera = CreateCamera(world); camera->SetClearColor(0.125); camera->SetFov(70); camera->SetPosition(0, 0, -3); //Create a light auto light = CreateBoxLight(world); light->SetRotation(35, 45, 0); light->SetRange(-10, 10); //Create a box auto box = CreateBox(world); box->SetColor(0.5f, 0.5f, 0); auto outlineBox = CreateBox(world); outlineBox->SetColor(0, 0, 1); auto material = CreateMaterial(); auto unlitShader = LoadShaderFamily("Shaders/Unlit.json"); material->SetShaderFamily(unlitShader); outlineBox->SetMaterial(material); //Entity component system auto component = box->AddComponent<Mover>(); component->rotationspeed.y = 45; auto component2 = outlineBox->AddComponent<Mover>(); component2->rotationspeed.y = 45; //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ //Render to texture outlineBox->SetRenderLayers(1 + 2); auto cam2 = CreateCamera(world); cam2->SetClearColor(0, 0, 0, 0); cam2->SetRenderLayers(2); cam2->SetFov(camera->GetFov()); cam2->SetMatrix(camera->matrix); cam2->AddPostEffect(LoadPostEffect("Shaders/PostEffects/Outline.json")); auto sz = framebuffer->GetSize(); auto texbuffer = CreateTextureBuffer(sz.x, sz.y); cam2->SetRenderTarget(texbuffer); ////Display overlay auto sprite = CreateSprite(world, sz.x, sz.y); // sprite->SetColor(0, 1, 1, 1); sprite->SetRenderLayers(4); auto mtl = CreateMaterial(); sprite->SetMaterial(mtl); mtl->SetTransparent(true); mtl->SetTexture(texbuffer->GetColorAttachment()); auto cam3 = CreateCamera(world, PROJECTION_ORTHOGRAPHIC); cam3->SetClearMode(CLEAR_DEPTH); cam3->SetRenderLayers(4); cam3->SetPosition(sz.x * 0.5f, sz.y * 0.5f, 0); //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { world->Update(); world->Render(framebuffer, false); } return 0; } Quote Link to comment Share on other sites More sharing options...
Josh Posted May 24, 2023 Author Share Posted May 24, 2023 In outline.json, I think if you add the previous pass into the samplers it will be available in slot 1 (PostEffectTexture1): "samplers": ["DEPTH", "PREVPASS"], Have not actually tried it. 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Dreikblack Posted May 25, 2023 Share Posted May 25, 2023 Still no outline with main.cpp above: { "postEffect": { "subpasses": [ { "samplers": [ "DEPTH", "PREVPASS"], "shader": { "float32": { "fragment": "Shaders/Outline.frag.spv" } } } ] } } #version 450 #extension GL_GOOGLE_include_directive : enable #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_multiview : enable #include "../Base/PushConstants.glsl" #include "../Base/CameraInfo.glsl" #include "../Base/TextureArrays.glsl" #include "../Utilities/Dither.glsl" layout(location = 0) in vec2 texCoords; layout(location = 0) out vec4 outColor; void main() { outColor = texture(texture2DSampler[PostEffectTexture1], texCoords.xy); outColor.a = 0.0f; float depth = texture(texture2DSampler[PostEffectTexture0], texCoords.xy).r; vec4 c; bool sel; //Handle selected objects if (depth < 1.0f) { const int m = 3; vec2 pixelsize = 1.0f / BufferSize; for (int x = -m; x <= m; ++x) { for (int y = -m; y <= m; ++y) { if (x == 0 && y == 0) continue; float neighbor = texture(texture2DSampler[PostEffectTexture0], texCoords.xy + pixelsize * vec2(x, y)).r; if (neighbor == 1.0f) { outColor = texture(texture2DSampler[PostEffectTexture1], texCoords.xy); return; } } } } } Quote Link to comment Share on other sites More sharing options...
Dreikblack Posted May 26, 2023 Share Posted May 26, 2023 Damn, it was correct .frag this time - i just had few mistakes in a code. #include "UltraEngine.h" #include "Components/Mover.hpp" 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, displays[0]->GetSize().width, displays[0]->GetSize().height, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR | WINDOW_FULLSCREEN); //Create a world auto world = CreateWorld(); //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Create a camera auto camera = CreateCamera(world); camera->SetClearColor(0.125); camera->SetFov(70); camera->SetPosition(0, 0, -3); //Create a light auto light = CreateBoxLight(world); light->SetRotation(35, 45, 0); light->SetRange(-10, 10); //Create a box auto box = CreateBox(world); box->SetColor(1, 0, 0); auto outlineBox = CreateBox(world); outlineBox->SetColor(0, 1, 0); auto material = CreateMaterial(); auto unlitShader = LoadShaderFamily("Shaders/Unlit.json"); material->SetShaderFamily(unlitShader); outlineBox->SetMaterial(material); //Create a box2 auto box2 = CreateBox(world); box2->SetColor(1, 0, 0); auto outlineBox2 = CreateBox(world); outlineBox2->SetColor(0, 0, 1); auto material2 = CreateMaterial(); auto unlitShader2 = LoadShaderFamily("Shaders/Unlit.json"); material2->SetShaderFamily(unlitShader); outlineBox2->SetMaterial(material); outlineBox2->SetPosition(2, 0, 0); box2->SetPosition(2, 0, 0); //Entity component system auto component = box->AddComponent<Mover>(); component->rotationspeed.y = 45; auto outlineComponent = outlineBox->AddComponent<Mover>(); outlineComponent->rotationspeed.y = 45; auto component2 = box2->AddComponent<Mover>(); component2->rotationspeed.y = 45; auto outlineComponent2 = outlineBox2->AddComponent<Mover>(); outlineComponent2->rotationspeed.y = 45; //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ //Render to texture outlineBox->SetRenderLayers(2); outlineBox2->SetRenderLayers(2); auto cam2 = CreateCamera(world); cam2->SetClearColor(0, 0, 0, 0); cam2->SetRenderLayers(2); cam2->SetFov(camera->GetFov()); cam2->SetMatrix(camera->matrix); cam2->AddPostEffect(LoadPostEffect("Shaders/PostEffects/Outline.json")); auto sz = framebuffer->GetSize(); auto texbuffer = CreateTextureBuffer(sz.x, sz.y); cam2->SetRenderTarget(texbuffer); ////Display overlay auto sprite = CreateSprite(world, sz.x, sz.y); sprite->SetRenderLayers(4); auto mtl = CreateMaterial(); sprite->SetMaterial(mtl); mtl->SetTransparent(true); mtl->SetTexture(texbuffer->GetColorAttachment()); auto cam3 = CreateCamera(world, PROJECTION_ORTHOGRAPHIC); cam3->SetClearMode(CLEAR_DEPTH); cam3->SetRenderLayers(4); cam3->SetPosition(sz.x * 0.5f, sz.y * 0.5f, 0); //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { world->Update(); world->Render(framebuffer, false); } return 0; } 1 Quote Link to comment Share on other sites More sharing options...
Dreikblack Posted May 26, 2023 Share Posted May 26, 2023 I have a new problem with this implementation- can't see outline of first object if it's above another one. It's crucial for cases when selected (and outlined) unit stays on outlined tiles (which shows where can unit go to) (also i used to outline avaiable tile under cursor with another color ad can't see it now as well) outlineBox2->SetPosition(0.5f, 0.5f, 0); box2->SetPosition(0.5f, 0.5f, 0); Quote Link to comment Share on other sites More sharing options...
Josh Posted May 26, 2023 Author Share Posted May 26, 2023 That makes sense, because the drawing is being combined into one depth buffer. So I guess you have to choose. Maybe this isn't the best effect to use in your game. 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Dreikblack Posted May 26, 2023 Share Posted May 26, 2023 Ok, thanks. I will try something else instead of outlines for tiles then. Quote Link to comment Share on other sites More sharing options...
Dreikblack Posted May 29, 2023 Share Posted May 29, 2023 Replaced tile outlines with brushed. Better perfomance and i think it's looks better. But even one camera outline still degrade perfomance significantly and i wonder how to do proper downsampling for outline. I don't know what am i doing wrong in Outline.json for that: { "postEffect": { "buffers": [ { "size": [ 0.25, 0.25 ] } ], "subpasses": [ { "samplers": [ "DEPTH", "PREVPASS" ], "shader": { "float32": { "fragment": "Shaders/Outline.frag.spv" } } } ] } } 1 Quote Link to comment Share on other sites More sharing options...
Josh Posted May 30, 2023 Author Share Posted May 30, 2023 I don't know if my downsampling idea is even a good one. It doesn't look like the shader itself is the bottleneck. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Dreikblack Posted December 21, 2023 Share Posted December 21, 2023 Does not work anymore in latest dev beta branch: #include "UltraEngine.h" #include "ComponentSystem.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, 1200, 800, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); //Create a world auto world = CreateWorld(); //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Create a camera auto camera = CreateCamera(world); camera->SetClearColor(0.125); camera->SetFov(70); camera->SetPosition(0, 0, -3); //Create a light auto light = CreateBoxLight(world); light->SetRotation(35, 45, 0); light->SetRange(-10, 10); //Create a box auto box = CreateBox(world); box->SetColor(1, 0, 0); auto outlineBox = CreateBox(world); outlineBox->SetColor(0, 1, 0); auto material = CreateMaterial(); auto unlitShader = LoadShaderFamily("Shaders/Unlit.fam"); material->SetShaderFamily(unlitShader); outlineBox->SetMaterial(material); //Create a box2 auto box2 = CreateBox(world); box2->SetColor(1, 0, 0); auto outlineBox2 = CreateBox(world); outlineBox2->SetColor(0, 0, 1); auto material2 = CreateMaterial(); auto unlitShader2 = LoadShaderFamily("Shaders/Unlit.fam"); material2->SetShaderFamily(unlitShader); outlineBox2->SetMaterial(material); outlineBox2->SetPosition(2, 0, 0); box2->SetPosition(2, 0, 0); //Entity component system auto component = box->AddComponent<Mover>(); component->rotationspeed.y = 45; auto outlineComponent = outlineBox->AddComponent<Mover>(); outlineComponent->rotationspeed.y = 45; auto component2 = box2->AddComponent<Mover>(); component2->rotationspeed.y = 45; auto outlineComponent2 = outlineBox2->AddComponent<Mover>(); outlineComponent2->rotationspeed.y = 45; //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ //Render to texture outlineBox->SetRenderLayers(2); outlineBox2->SetRenderLayers(2); auto cam2 = CreateCamera(world); cam2->SetClearColor(0, 0, 0, 0); cam2->SetRenderLayers(2); cam2->SetFov(camera->GetFov()); cam2->SetMatrix(camera->matrix); cam2->AddPostEffect(LoadPostEffect("Shaders/Outline.fx")); auto sz = framebuffer->GetSize(); auto texbuffer = CreateTextureBuffer(sz.x, sz.y); cam2->SetRenderTarget(texbuffer); ////Display overlay auto sprite = CreateSprite(world, sz.x, sz.y); sprite->SetRenderLayers(4); auto mtl = CreateMaterial(); sprite->SetMaterial(mtl); mtl->SetTransparent(true); mtl->SetTexture(texbuffer->GetColorAttachment()); auto cam3 = CreateCamera(world, PROJECTION_ORTHOGRAPHIC); cam3->SetClearMode(CLEAR_DEPTH); cam3->SetRenderLayers(4); cam3->SetPosition(sz.x * 0.5f, sz.y * 0.5f, 0); //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { world->Update(); world->Render(framebuffer, false); } return 0; } #version 450 #extension GL_GOOGLE_include_directive : enable #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_multiview : enable #include "../Base/PushConstants.glsl" #include "../Base/CameraInfo.glsl" #include "../Base/TextureArrays.glsl" #include "../Utilities/Dither.glsl" layout(location = 0) in vec2 texCoords; layout(location = 0) out vec4 outColor; void main() { outColor = texture(texture2DSampler[PostEffectTextureID1], texCoords.xy); outColor.a = 0.0f; float depth = texture(texture2DSampler[PostEffectTextureID0], texCoords.xy).r; //Handle selected objects if (depth < 1.0f) { const int m = 4; vec2 pixelsize = 1.0f / BufferSize; for (int x = -m; x <= m; ++x) { for (int y = -m; y <= m; ++y) { if (x == 0 && y == 0) continue; float neighbor = texture(texture2DSampler[PostEffectTextureID0], texCoords.xy + pixelsize * vec2(x, y)).r; if (neighbor == 1.0f) { outColor = texture(texture2DSampler[PostEffectTextureID1], texCoords.xy); return; } } } } } Quote Link to comment Share on other sites More sharing options...
Josh Posted December 21, 2023 Author Share Posted December 21, 2023 Will try to check this out today. Please remind me if I become forgetful. 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.