Jump to content

All Activity

This stream auto-updates

  1. Past hour
  2. Here is a basic skeleton for a downloader. The idea is to have one system with multiple content providers that can be plugged in to download assets from other sources. local extension = {} extension.providers = {} function extension:Initialize() local sidepanelwidth = 280 local x = 4 local y = 4 extension.window = CreateWindow("Asset Library", 0, 0, 1024, 768, program.window, WINDOW_HIDDEN | WINDOW_TITLEBAR | WINDOW_CENTER | WINDOW_RESIZABLE) extension.ui = CreateInterface(extension.window) extension.treeview = CreateTreeView(x, y, sidepanelwidth, extension.ui.background.size.y - y * 2, extension.ui.background) extension.treeview:SetLayout(1,0,1,1) extension.panel = CreatePanel(x + sidepanelwidth + 4, y, extension.ui.background.size.x - sidepanelwidth - 4 - 2 * x, extension.ui.background.size.y - 2 * y, extension.ui.background, PANEL_BORDER) extension.panel:SetLayout(1,1,1,1) --extension.panel:SetColor(extension.panel:GetColor(WIDGETCOLOR_SUNKEN)) extension.panel:SetColor(0,0,0,1) --Set DPI scale if needed if program.window.display.scale ~= 1 then local scale = program.window.display.scale local pos = extension.window.position local size = extension.window.size extension.window:SetShape(pos.x, pos.y, size.x * scale, size.y * scale) extension.ui:SetScale(scale) end ListenEvent(EVENT_WINDOWCLOSE, extension.window, extension.ProcessEvent, extension) ListenEvent(EVENT_WINDOWSIZE, extension.window, extension.ProcessEvent, extension) local s = FetchUrl("https://ambientcg.com/api/v2/categories_json") local t = LoadTable(s) local n local groups = {} for n = 1, #t do local name = t[n].categoryName local group = t[n].defaultDataTypeId if groups[group] == nil then groups[group] = {} end groups[group][name] = t --extension.treeview.root:AddNode(name) end local k,v local base = extension.treeview.root:AddNode("AmbientCG") for k,v in pairs(groups) do local node = base:AddNode(k) local k2, v2 for k2, v2 in pairs(v) do node:AddNode(k2) end end base:Expand() end function extension.ProcessEvent(event, extension) if event.id == EVENT_WIDGETACTION then if event.source == extension.menuitem then if extension.window == nil then extension:Initialize() end extension.window:SetHidden(false) extension.window:Activate() return false end elseif event.id == EVENT_WINDOWCLOSE then if event.source == extension.window then program.window:Activate() extension.window:SetHidden(true) return false end end end local submenu = program.menu:FindChild("Scripting") if submenu == nil then Print("Error: Could not find script menu") return end extension.menuitem = CreateMenu("Asset Library", submenu) ListenEvent(EVENT_WIDGETACTION, extension.menuitem, extension.ProcessEvent, extension) --Add a content provider local t = {} function t:GetCategories() end table.insert(extension.providers, t)
  3. Well, that's the maximum I thought would be necessary. The GPU will have to allocate a buffer equal to the number of LODs times the number of instances of the model that exist in the world, times four, which I guess is not that much memory. I could probably support more but four seems like a nice number. The culling routine might also have to iterate through the number of LODs for each instance in order to be dynamically uniform.
  4. So I should plan and start building with 4 lods 'now'?
  5. Today
  6. Get download links and preview images for a single item: https://ambientcg.com/api/v2/full_json?type=Material&sort=Popular&limit=10&include=downloadData%2CpreviewData&offset=0&id=Bricks092
  7. Get all files in a category, with downloads and preview images: https://ambientcg.com/api/v2/full_json?type=Material&sort=Popular&limit=10&include=downloadData%2CpreviewData&offset=0&category=Bricks
  8. This gets the categories: https://ambientcg.com/api/v2/categories_json
  9. We've come a long way since November...
  10. The engine supports up to four LODs. It will be important to enforce this when we move culling over the a compute shader, because the data layouts have to be very strict.
  11. Recently I came across a problem where HDRI images I loaded and converted into cube maps looked simultaneously too bright and too dark. I found that a simple linear to sRGB conversion made the images look as I would expect. I have read about sRGB and linear color spaces before, but for some reason this time it just clicked and I understood. Maybe since I am not longer dealing with low-level Vulkan nonsense, I have extra mental capacity to spend on more high-level concepts like this. In any case, I find this stuff is usually not explained very well and I want to show you how it works, in simple terms everyone can understand. The basic idea of sRGB color space is that the way we perceive lightness in an image is wrong. Look at the gradient below. The change in the left-most 25% of the image looks much greater than the change in the right-most 25%, but it's not: A long time ago, photography folks all agreed that these types of gradients look wrong. You will often see this referred to as crushed blacks, the opposite of overexposed bright colors, and it's usually considered to be a bad thing: In 1996 HP and Microsoft came up with an equation that makes a gradient that looks "right". This is called sRGB color space, and it just shifts the darker tones to the right with a simple equation. The resulting gradient below looks more "balanced", even though it's really unbalanced: The only problem is that since these colors are no longer linear, all our nice neat color math is no longer valid. Multiplying two colors together like we do for lighting won't produce the right result because the colors have all been shifted to the right by varying amounts. The solution is to convert all colors from sRGB to linear, perform your color math like lighting, and then shift the result back from linear to sRGB. Fortunately you don't have to modify your textures and colors, because sRGB is considered the "correct" value that we want to see, and linear color space is a temporary intermediary used for math. We can convert between these color spaces in a shader with the code below. const float GAMMA = 2.2; const float INV_GAMMA = 1.0 / GAMMA; vec3 linearTosRGB(vec3 color) { return pow(color, vec3(INV_GAMMA)); } vec3 sRGBToLinear(vec3 srgbIn) { return vec3(pow(srgbIn.xyz, vec3(GAMMA))); } What this technique basically does is it reallocates precision away from the bright colors, which we do not have as accurate perception of, and gives it to the dark colors, which we can see between more easily. With standard linear color a simple scene looks both dull and heavily contrasted: The same scene comes to life when colors are converted from sRGB to linear before lighting, and then transformed back for the final color. We can clearly see a blue tint from the PBR environment map mixed with the orange color, and the dark gray colors have much more definition now. I don't even understand how something can be blue and orange at the same time, but I can clearly see a blue reflection from the sky in the image below. Overall this makes it easier for lights to illuminate dark areas without requiring extremely bright lights with strong contrast, and the PBR lighting is more strongly visible in colored objects. This update is available now on the beta branch, in the standalone and Steam versions of Ultra Engine. I used the Lua code below to create the gradient images. You can paste this into a Lua file and run it by selecting the Script > Run Script item in the main menu, or you can just paste this into the console and press enter, and it will run: local pixmap = CreatePixmap(256, 16) --Write linear gradient for x = 0, pixmap.size.x - 1 do for y = 0, pixmap.size.y - 1 do pixmap:WritePixel(x, y, Rgba(x, x, x, 255)) end end pixmap:Save(GetPath(PATH_DESKTOP).."/lineargradient.png") --Convert to sRGB pixmap = pixmap:sRgbToLinear() pixmap:Save(GetPath(PATH_DESKTOP).."/srgbgradient.png") I hope this explanation helps you to understand what sRGB and linear color spaces actually do and how this feature makes your games look better. It's actually a very straightforward concept that for some reason is poorly explained in most articles I have seen.
  12. And here is how to retrieve the contents of a Github repository: https://api.github.com/repos/ultraengine/documentation/contents/CPP
  13. Okay, so I found that the LOD models contain extra hierarchy. This is bad because the editor can't correlate which limb matches which. Maybe I can improve this, but the easiest solution is to collapse the models first. Once I did this, the LODs loaded and saved with no problems. I generated a convex decomposition collider and that seemed to work fine. veoneio.zip (This model contains one additional LOD.) When importing large numbers (about 100) of complex models, I had the best results writing a script that automated the process. You can call Collapse() and AddLod() in a script and use the Scripts > Run Script menu item to execute it.
  14. Sneak Peak - UAGC - gets a more realistic map UAGC next mount - Flying Creatures
  15. In the editor, the mesh initially has no collider, I drag it to the editor, and then the mesh that is in the assets, I set a collider. But the mesh that is in the editor, the instantiated one shows the collider, but it does not react to the collision physics.
  16. When and how is this done? In code or in the editor?
  17. I found this: "prefab": { "path": "Models/Prefabs/ModuleA.pfb" }, The prefab tries to load itself. The solution is I need to break the prefabs when a prefab is saved, although I have no idea how you created this one. Unity needs nested prefabs because they treat FBX files as a collection of meshes to assemble prefabs from. Our model format supports a lot of information, and I think nested prefabs might not be needed in Ultra.
  18. Josh, I discovered the bug, when the mesh is put on the stage without previously assigning a collider, and then the mesh is assigned a collider, the collider although visually seen in the map editor, is not reacting to the physics.
  19. I will need to download the model in order to test it.
  20. Oh, okay. The newer build solves a problem some models had, but it was a long time ago and I don't remember what the issue was.
  21. No this is straight media from Sketchup Warehouse
  22. This, in the Leadwerks tools, there are two.
  23. Yesterday
  24. The one in the current build of Leadwerks? It's the same one Ultra uses. I just tried it and it crashed.
  1. Load more activity
×
×
  • Create New...