Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - ArenMook

Pages: [1] 2 3 ... 1447
1
Dev Blog / Sep 16, 2018 - Rendering Planetoids
« on: September 16, 2018, 05:13:37 PM »
As part of R&D for Project 5: Sightseer, I was looking into various ways of replacing Unity's terrain with something more flexible. Among my options was revisiting the planetary rendering system I wrote two years ago. Of course adapting a spherical planetary terrain to replace a flat one of a game that has been in development for 2.5 years is probably not the best idea in itself... and I'm still on the fence about using it... but I did get something interesting out of it: a way to generate planetoids.

The original idea was inspired by a Star Citizen video from a few years back where one of the developers was editing a planetary terrain by basically dragging splat textures onto it -- mountains and such, and the system would update immediately. Of course nothing like that exists in Unity, or on its Asset Store, so the only way to go was to try developing this kind of system myself.

So I started with a simple thought... what's the best way to seamlessly texture a sphere? Well, to use a cube map of course! A cube map is just a texture projected to effectively envelop the entire sphere without seams, so if one was to render a cube map from the center of the planet, it would be possible to add details to it in form of textured quads.

I started with a simple GPU-generated simplex noise shader that uniformly textured my sphere.



Doesn't look like much, but that's just the source object that's supposed to act as a spherical height map. Now taking that and rendering it into a cube map gives a cube map heightmap that can then be used to texture the actual planet. Of course using the rendered cube map as-is wouldn't look very good. It would simply be the same sphere as above, but with lighting applied to it. More work is needed to get it to look more interesting.

First -- this is a height map, so height displacement should happen. This is simple enough to do just by displacing the vertex along the normal based on the sampled height value in the vertex shader.

  1. v.vertex.xyz += v.normal * texCUBElod(_Cube, float4(v.normal, 0.0)).r * _Displacement;

This adds some height variance to the renderer, and combined with the basic assignment of the sampled texture to Albedo this makes the planetoid a little bit more interesting:



Of course the lighting is not correct at this point. Although the vertex values get offset, normals do not. Plus, the vertex resolution is a lot lower than the source height map texture. So what ideally should happen, is the normal map should get calculated at run-time by sampling the height map values around each pixel. This process is different from the normal bump mapping technique because our texture is cubic rather than 2D. In a way, it's actually more simple. The challenge, as I learned, lies in calculating the normal itself.

With 2D textures, calculating normals from a heightmap is trivial: sample the height difference on +X to -X, then another height difference on +Y to -Y, use that as X and Y normal map, with Z being resolved based on the other two. With triangle-based meshes this is also simple: loop through triangles, calculate each triangle's normal, add to each of the 3 vertices, then normalize the result at the end. But with cube map textures? There is technically no left/right or up/down. Unprojecting each of the 6 faces would result in 2D textures, but then they wouldn't blend correctly with their neighbors. I spent a lot of time trying to generate the "perfect" normal map from a cube map heightmap texture, and in the end never got it to be quite perfect. I think the best solution would be to handle sides (+X, -X, +Z, -Z) and top/bottom (+Y, -Y) separately, then blend the result, but in my case I just did it without blending, simply using each normal along with the side's tangent (a simple right-pointing vector that I pass to each side's shader) to calculate the binormal. I then use the tangent and binormal to rotate the normal, thus creating the 4 sampling points used to calculate the modified normal.
  1. inline float4 AngleAxis (float radians, float3 axis)
  2. {
  3.         radians *= 0.5;
  4.         axis = axis * sin(radians);
  5.         return float4(axis.x, axis.y, axis.z, cos(radians));
  6. }
  7.  
  8. inline float3 Rotate (float4 rot, float3 v)
  9. {
  10.         float3 a = rot.xyz * 2.0;
  11.         float3 r0 = rot.xyz * a;
  12.         float3 r1 = rot.xxy * a.yzz;
  13.         float3 r2 = a.xyz * rot.w;
  14.  
  15.         return float3(
  16.                 dot(v, float3(1.0 - (r0.y + r0.z), r1.x - r2.z, r1.y + r2.y)),
  17.                 dot(v, float3(r1.x + r2.z, 1.0 - (r0.x + r0.z), r1.z - r2.x)),
  18.                 dot(v, float3(r1.y - r2.y, r1.z + r2.x, 1.0 - (r0.x + r0.y))));
  19. }
  20.  
  21. inline float SampleHeight (float3 normal) { return texCUBE(_Cube, normal).r; }
  22.  
  23. float3 CalculateNormal (float3 n, float4 t, float textureSize)
  24. {
  25.         float pixel = 3.14159265 / textureSize;
  26.         float3 binormal = cross(n, t.xyz) * (t.w * unity_WorldTransformParams.w);
  27.         float3 x0 = Rotate(AngleAxis(-pixel, binormal), n);
  28.         float3 x1 = Rotate(AngleAxis(pixel, binormal), n);
  29.         float3 z0 = Rotate(AngleAxis(-pixel, t.xyz), n);
  30.         float3 z1 = Rotate(AngleAxis(pixel, t.xyz), n);
  31.  
  32.         float4 samp;
  33.         samp.x = SampleHeight(x0);
  34.         samp.y = SampleHeight(x1);
  35.         samp.z = SampleHeight(z0);
  36.         samp.w = SampleHeight(z1);
  37.         samp = samp * _Displacement + 1.0;
  38.  
  39.         x0 *= samp.x;
  40.         x1 *= samp.y;
  41.         z0 *= samp.z;
  42.         z1 *= samp.w;
  43.  
  44.         float3 right = (x1 - x0);
  45.         float3 forward = (z1 - z0);
  46.         float3 normal = cross(right, forward);
  47.         normal = normalize(normal);
  48.  
  49.         if (dot(normal, n) <= 0.0) normal = -normal;
  50.         return normal;
  51. }
The world normal is calculated in the fragment shader and is then used in the custom lighting function instead of the .Normal.
  1. float3 worldNormal = normalize(IN.worldNormal);
  2. float3 objectNormal = normalize(mul((float3x3)unity_WorldToObject, worldNormal));
  3. float height = SampleHeight(objectNormal);
  4. objectNormal = CalculateNormal(objectNormal, _Tangent, 2048.0);
  5. o.WorldNormal = normalize(mul((float3x3)unity_ObjectToWorld, objectNormal));
  6. o.Albedo = height.xxx;
  7. o.Alpha = 1.0;
The result looks like this:



Now in itself, this is already quite usable as a planetoid / asteroid for space games, but it would be great to add some other biomes, craters and hills to it. The biomes can be done by changing the noise shader, or by adding a second noise on top of the first one, that will alpha blend with the original. Remember: in our case the height map texture is a rendered texture, so we can easily add additional alpha-blended elements to it, including an entire sphere.

This is how a secondary "biome" sphere looks like that adds some lowlands:



Blended together it looks like this on the source sphere:



When rendered into a cube map and displayed on the planetoid, it looks like this:



Adding craters and other features to the surface at this point is as simple as finding good height map textures, assigning them to a quad, and placing them on the surface of the sphere:



The final result looks excellent from far away:



Unfortunately zooming in, especially in areas with flatter terrain, obvious ridges form:



This happens because 8-bit colors are simply inadequate when it comes to handling the height variance found in terrains. So what can be done? The first obvious thing I tried was to pack the height value into 2 channels using Unity's EncodeFloatRG function in the original biome shaders:
  1. // Instead of this:
  2. return half4((noise * 0.5 + 0.5).xxx, 1.0);
  3. // I did this:
  4. return half4(EncodeFloatRG(noise * 0.5 + 0.5), 0.0, 1.0);
The SampleHeight function was then changed to:
  1. inline float SampleHeight (float3 normal) { return DecodeFloatRG(texCUBE(_Cube, normal).rg); }
This certainly helped the biomes look smooth, but the stamp textures (craters, mountains, etc) are still regular textures, so there is obviously no benefit to taking this approach with them. Worse still, the alpha blending is still 8 bit! You can see that the transition walls (the slope on the right side of the picture below) are still pixelated, because alpha blending doesn't have the advantage of taking the 16-bit approach of EncodeFloatRG.



Worse still, the source sphere became unrecognizable:



So what can be done to fix this? Well, since the stamp source heightmap textures are always using 8 bits per color, there isn't a whole lot that can be done here, short of creating your own custom heightmaps and saving them in 16-bit per color textures, which sadly means ruling out all the height maps readily available online like the ones I used. The transitions between biomes can be eliminated by using only a single shader that would contain all the biomes and blend them together before outputting the final color in RG format. So, technically if one was to avoid stamp textures, it's possible to have no visible jaggies.

At this point, some of you reading may wonder, "why don't you just change the render texture format to float, you noob?" -- I tried... Never mind the RGBA format 2048 size cube map is already 128 MB in size, there is no option to make it be anything else. It's not possible to make it bigger, and it's not possible to change it to be anything other than RGBA:



I tried doing this via code -- RFloat format flat out failed. Unity did seem to accept the RGBAFloat format, but then the final texture was always black, even though there was no errors or warnings in the console log. Plus, the texture size of 512 MB was kind of... excessive to begin with. And so what's left to try at this point? I suppose I could change the process to render 6 2D textures instead of the single cube map, which would allow me to use the RFloat format, but this will also mean visible seams between the quadrants, since the process of generating normals won't be able to sample adjacent pixels.

I could also try using the RGBAFloat format, rendering height into R, and normal XY into G & B channels. This would, in theory, be the best approach -- as the final planetoid won't need to keep calculating normal maps on the fly. Of course the memory usage at this point will be 512 MB per planetoid with texture resolution of 2048... So again back to being rather excessive.

If you have any thoughts on the matter, and especially if you've done this kind of stuff before, let me know! I can be found on the Tasharen's Discord.

2
NGUI 3 Support / Re: Latest Version: 3.12.0 (April 25, 2018)
« on: June 28, 2018, 07:36:59 PM »
3.12.1
- NEW: Added an option to UIDragDropItem to make it work not just with press-and-hold but also with click-move-click dragging actions.
- Improved the UIKeyBinding a bit (to string and from string conversion to be exact).
- Some minor tweaks and fixes merged from the Sightseer branch.

3
TNet 3 Support / Re: Latest Version: 3.2.0 (March 25, 2018)
« on: June 28, 2018, 07:35:19 PM »
3.3.0
- NEW: Added overloaded operators to all Send functions, eliminating GC allocations for sub-5 parameter RFC calls.
- NEW: Added bandwidth tracking (both sent and received bytes per second): TNManager.sentBytes and TNManager.receivedBytes.
- NEW: Added TNManager.availablePacketSize and TNManager.incomingPacketSize.
- NEW: Added an explicit chat type packet type: TNManager.SendChat / TNManager.onChat.
- NEW: TCP lobby server now supports more packet types, including chat for a true cross-server global chat.
- NEW: Added TNManager.Validate to validate the state of a server-side property. Useful for detecting memory modifications done on the client.
- NEW: Added Serializer.EncodeAsString / DecodeFromString to encode and decode binary data as ASCII text.
- NEW: Added a DoNotObfuscate attribute type and started using it in places where non-public classes/structs should not get obfuscated.
- NEW: Added Tools.stackTrace that will contain the stack trace up to the point where it was used.
- NEW: In-editor game server will now check for the 'saved' server property. If 'false', it won't perform any saving. Useful for quickly testing changes without keeping the active state.
- FIX: Fixed the to-text serialization of DataNode hierarchies containing nested DataNodes.
- FIX: Compilation fixes for builds.

4
Dev Blog / Re: Nov 11, 2017 -- How to edit UnityEngine.dll
« on: April 25, 2018, 03:54:17 PM »
Unity's reference code can't be compiled. Not sure what you're trying to do there.

5
NGUI 3 Support / Re: Latest Version: 3.11.4 (June 5, 2017)
« on: April 25, 2018, 03:51:12 PM »
3.12.0
- NEW: Popup list can now accept delegates when setting up the items programmatically (ideally anonymous delegates).
- NEW: Added Localization.Format overloads for 3 parameters and less to avoid GC allocations.
- NEW: Added UIWidget.SetColorNoAlpha helper function.
- NEW: color.LinearToGammaSpace() helper extension to match color.GammaToLinear().
- NEW: Added a fast path for updating a widget's collider if the collider is already known, and forced it to be used when the widget gets enabled.
- NEW: Added the "No Outline" option to the symbol coloring style. The symbol won't have an outline even if the text does.
- FIX: Fixed an issue with the font's actual printed size not being printed correctly in inspector in some situations.
- FIX: Random minor fixes from the support forum.
- FIX: Missing localization entry warnings will now only be shown once per keyword.
- FIX: UICamera will no longer keep assigning UICamera.hoveredObject repeatedly while mouse events are enabled. It will now only be assigned if the hovered object changes, or the mouse moves.
- FIX: Fixed some issues with NGUIText.InsertHyperlink/ReplaceLink.
- Merged pull request #26 by Nicki Hansen.
- Checked against Unity 4.7, 5.6, and 2018.1b2.

6
NGUI 3 Support / Re: Special Characters Break Text Wrapping
« on: March 29, 2018, 12:02:08 PM »
You really should be using emoticons instead.

7
NGUI 3 Support / Re: Vector3.one and Vector3(1,1,1)
« on: March 29, 2018, 12:00:50 PM »
Zero is an invalid scale. You can't divide by zero, so inverse transform can't be calculated. You're shooting yourself in the foot whenever you use a zero scale. Consider changing it to 0.001 instead.

Your question is also not an NGUI question, and not even a Unity question, but a basic C# question. In C# you need to prefix new object declarations with a "new".

8
NGUI 3 Support / Re: iPhone X display NGUI support
« on: March 29, 2018, 11:57:34 AM »
He asked in Discord. Just join Tasharen's discord (https://discord.gg/trruSNc) and scroll up in the #ngui-support channel to February 19th and you will see the conversation.

Quote
Kafar - 02/19/2018
I read NGUI support is moved here, so I put here my post:   Hello,

I read the only one post who talk about this topic (http://www.tasharen.com/forum/index.php?topic=15480.0) but it not is for me.
I have a UI Root and inside it many other UIpanels, UIButtons, etc, all anchored but on iPhone X the result is that the gui go partially off to the edge of the screen.

I tried also with this sample project https://bitbucket.org/p12tic/iossafeareasplugin mentioned in the other post but that sample not is for NGUI. My problem is my app run on all Apple and Android devices, then I can't adjust the widget's offsets for iPhone X only because this will impact on all other devices.

So, definitively, there are solutions (in this case) with NGUI?
Many thanks.
p12tic / iOSSafeAreasPlugin
A Unity project containing a native plugin wrapping iOS safe areas APIs
I forgot..... googling I can't found nothing about this
@Aren
Aren - 02/19/2018
https://answers.unity.com/questions/1432365/how-to-detect-iphone-x-or-ipad-using-iosdevicegene.html

@Kafar
if the device is not iphone x, disable that adjustment script of yours
Kafar - 02/19/2018
Thank @Aren but after I checked the device is a iPhone X I can  adjust UIpanels, UIWidgets, NGUI etc via code?
Aren - 02/19/2018
you should adjust the UICamera's camera's viewport
if you adjust that, you don't need to do anything
basically offset the viewport on the top by X pixels, where X is what's needed
Kafar - 02/19/2018
CORRECT!!!! MANY THANKS!
but.... viewport or Field of View?
I tried to offset the viewport but nothing change, with Field of View yes
Aren - 02/19/2018
Viewport Rect
Kafar - 02/19/2018
yes, Viewport Rect, I changed but nothing change
Viewport Rect accept negative values also?
Aren - 02/19/2018
yeah
if you have a sprite anchored across the entire screen, you will see it move when you adjust the viewport rect
simplest script for you is -- have the viewport rect be adjusted to what you need it to be for iphone x, then have your script simply set the rect to 0 and 1's if it's not iphone x
Kafar - 02/19/2018
ok, thanks!
Kafar - 02/19/2018
@Aren I'm sorry but I don't understand.... if I edit values for Viewport Rect X the GUI move to right or left but it not fit. Same thing if I edit Y or W or H. What is wrong?
Aren - 02/19/2018
try setting height to 0.97
there will be empty space on top equal to 0.03 * screen height pixels
Kafar - 02/19/2018
from code is Camera.ViewportToScreenPoint(Vector3)? If yes, the X, Y, W, H and specifically the H where I set it?
Aren - 02/19/2018
?
select the game object in inspector
set its camera script viewport rect
Kafar - 02/19/2018
no, I need to do in the script, in the case the app don't run on the iphonex
Aren - 02/19/2018
consult unity's documentation for how to set viewport rect via code, or look at the UIViewport script
Camera.rect

9
I expect Windows to work faster, since it uses IO Completion ports, which is a Windows feature. Plus, on Windows it runs using .NET, while on Linux it runs through Mono.

Windows will win.

10
I'm not aware of anything related to this, so can't say. I don't do anything special.

11
TNet 3 Support / Re: Latest Version: 3.1.0 (September 22, 2017)
« on: March 26, 2018, 05:42:58 AM »
3.2.0
- NEW: DataNode can now export entire bundles (think AssetBundle, but with DataNode). Just select a folder (or multiple files) and use the Assets->DataNode->Export feature. It's up to you to determine what to do about importing the bundles (I use a custom Prefab Manager in Sightseer for example), but an example import functionality and function is included (Assets->DataNode->Import supports them).
- NEW: DataNode can now export audio clips.
- NEW: DataNode now exports textures in their native compressed state, rather than forcing RGBA.
- NEW: It's now possible to add custom serialization functions for all data types by using extensions, without the need for an interface. Read comments above #define SERIALIZATION_WITHOUT_INTERFACE for more info. This makes it possible to add custom serialization for all Unity and 3rd party data types as well.
- NEW: Made it possible to specify custom protocol handling which would bypass sockets. Immediate use: Steam's networking API.
- NEW: Added a low memory footprint mode to the game server. Use the 'lm' keyword to enable it once the server is running. LM mode means once the last player leaves, channel data will be unloaded. Can save memory at the expense of extra time spent loading channel data when players rejoin.
- NEW: Made it possible to assign a custom connection to both the TNManager, and individual connections of the Game Server. I used it in Sightseer to add support for Steam networking: basically instead of using sockets, TNet can now also use Steam's Networking API.
- NEW: It's now possible to specify the root directory on the file server (game server's parent class) to use for all file-based operations.
- NEW: Numerous DataNode serialization fixes and improvements to make it possible for it to serialize prefabs properly, including iffy types like ParticleSystems.
- NEW: Added a Max Packet Time to the game client that TNet will spend processing packets each Update. Can be used to automatically split up packet processing across multiple frames.
- NEW: Added #define options to the game client to provide packet profiling. If enabled, all incoming packets will show up in the Unity's Profiler.
- NEW: WorkerThread now supports coroutines for the main thread's callback.
- NEW: Replaced TNObject/TNBehaviour's Start functions with a custom setup to avoid a bug in Unity that causes disabling components with a Start() function to take 100+ times longer than normal.
- NEW: Added TNManager.Disconnect(delay). Can be useful if there are still packets that need to be sent out before disconnecting. Will prevent all further packets from being sent out or being received.
- NEW: Added a built-in server side check that prevents multiple players from requesting the same player save file.
- NEW: TNet now keeps a list of sent RFC names with their count while in the editor so that you can track which RFCs happen to be called too frequently.
- NEW: Added Vector2D and Vector3D -- double precision version of Unity's vectors.
- NEW: Added TNManager.Export and Import -- the ability to export and import objects from the server. This effectively sends all the RCC and RFCs from the server to the client that are necessary to import a group of objects in the future. In Sightseer I use it to save entire groups of pre-configured assets (such as a fully equipped player vehicle complete with inventory contents) then instantiate them easily after moving them somewhere.
- NEW: TNet's function calls will now automatically try to convert parameters if they don't quite match. For example changing an RFC to pass a Vector3D instead of a Vector3 will no longer break serialization.
- NEW: Added TNObject.Find(fullID) and TNObject.fullID. It's a combination of channel+object ID in one.
- NEW: Added a new "MODDING" #define. If enabled, TNet will be compiled in a stripped-down mode with serialization intact, but connectivity inoperable. This is meant for making exporter mod DLLs.
- NEW: Object and component references are now serialized using IDs instead of strings for less space and faster lookup.
- FIX: Updating a saved RFC on the server will now move it to the end of the saved RFC list, ensuring that it's called in the correct order on load.
- FIX: Fixed the Tcp Lobby link sending server updates every 5 seconds even if nothing changed. It now sends Ping packets instead.
- FIX: Changed ban and admin lists to be hashsets instead for faster lookups.
- FIX: Fixed DataNode's GetHierarchy causing GC allocations.
- FIX: Calling SetChannelData should now persist, even if nothing was actually instantiated in that channel.
- FIX: DataNode can now contain other DataNode values in its nodes' value field without breaking serialization.
- FIX: HTTP responses now use UTF-8.

12
Dev Blog / Re: Nov 11, 2017 -- How to edit UnityEngine.dll
« on: March 25, 2018, 01:13:13 AM »
Yes, I tried it in 2017.3 a while back. It worked as expected. You probably just missed something.

13
NGUI's support forums are a wealth of information that have been filled by 6 years of dedicated support, but times are changing and so should the support. The best place to ask new questions that haven't already been answered on the forums is in Discord: https://discord.gg/tasharen -- look for the #ngui-support section.

For those that don't know, Discord is a text / voice communication program, and it's accessible via your browser.

I hate forums. Always did. Chat is much easier, and with much better response times to boot as I'm always there when I'm awake.

14
NGUI 3 Support / Re: Is NGUI still actively supported?
« on: February 17, 2018, 10:38:51 PM »
I've been... neglecting the forums lately, I admit. I've moved all support to Discord back in December (https://discord.gg/tasharen). What I've been telling people (and what the tasharen.com's contact form says) is -- if you can't find the answer to your question by googling it / searching tasharen.com's forums, then you're welcome to ask in discord and I'll respond (and if it's a question specifically to me, be sure to tag me with @Aren so I see it).

15
Dev Blog / Re: July 21, 2017 - Grass
« on: December 31, 2017, 10:38:21 PM »
Yeah, I don't want to deal with support, making all the necessary art, preview vids, and all the other hassle related to submitting to the asset store nowadays. I might release it as a public github project later, however.

Pages: [1] 2 3 ... 1447