# Enno Games — full content > Every published page of ennogames.com as plain text. Source: https://ennogames.com ## What is GPU Grass URL: https://ennogames.com/gpu-grass/what-is-gpu-grass GPU Grass is a replacement for Unity's terrain detail system. Unity Asset Store Page While building a forest scene in Unity I found that I couldn't get the look and performance I wanted from Unity's terrain grass and decided to make my own system to use instead. What I thought would be a quick tool turned into months of research and rewrites. I finally came up with GPU Grass which I think is a very fast way to place and render good looking grass on terrain in Unity. GPU Grass doesn't have all of the features that's Unity's system does but it is much faster and in my opinion better looking. ## How it Works URL: https://ennogames.com/gpu-grass/how-it-works Masks GPU Grass places and renders objects on the GPU based on masks. 6 masks are generated per terrain. Normal Terrain Color Heightmap Slope Terrain Layer Collision Mask 3 masks are generated per object type. Placement Color Scale These masks are generated in the editor and updated when something changes. They are packed into textures and sent to the GPU.     Runtime These 3 steps happen every frame on the GPU. Step 1: Placement Positions are generated in a compute shader. GPU Grass uses either random values or blue noise to generate positions. Positions are filtered based on the placement mask. Positions are sorted into LODs. Step 2: Culling Positons are culled using the camera's frustum. Step 3: Rendering Objects are rendered using Graphics.DrawMeshInstancedIndirect Scale, rotation and other data is calculated in the shader based on masks. ## Performance URL: https://ennogames.com/gpu-grass/peformance GPU Grass is fast! GPU Grass uses very little CPU. In the demo scene on my machine GPU Grass takes 0.05ms during update and 0.021ms during late update. There are no hitches as you move around or when new grass comes into view. Everything is calculated every frame on the GPU. Because of this there are never any spikes or variances in the performance. Increasing Performance The number of objects rendered and the number of triangles have the biggest affect on performance. Here's what you can do to increase performance. Decrease density. Use blue noise instead of random. Objects are more evenly spaced when using blue noise which means you can lower density a little and still have it appear to be the same density. Decrease draw distance. It's more perforamnt to do this in the manager settings then the object settings then the LOD. Use LODs. Turn off shadows. You can do this for the whole object or per LOD. Use vertex lit intead of pixel lit. ## Features URL: https://ennogames.com/gpu-grass/features Very little cpu usage. Almost everything is done on the GPU. The demo scene takes less than 0.05ms cpu on my machine. No hitches. CPU and GPU usage is steady. There are no hitches when new things come into view. LOD system. 1 - 3 lod levels. Vertex or pixel lit per LOD level. Objects up close can be rendered pixel lit and distant objects vertex lit. Shadow settings per LOD level. Dithering. LODs fade into each other and fade out at max draw distance. Procedural placement of objects on terrain based on masks. Custom texture mask. Slope of terrain. Height of terrain. Terrain layer. Multiple terrains. Each GPU Grass manager can render objects on multiple terrains with the same settings. Wind. Max draw distance per object and LOD. Align to ground. Objects can be aligned to the terrain. Unlike most grass solutions GPU Grass does not rotate the objects but instead movies their verts up or down keeping them straight. For example grass on a slope will not be rotated. View bending. Objects can be bent away from camera. Great for top down games for first person games where the player can look down. Thin over distance. Instead of culling objects at max draw distance they can be thinned out based on distance. For example grass close to the camera can be very thick but thinner in the distance. Placement based on random or blue noise. Blue noise can be used to place objects randomly but evenly spaced which is best for grass. Color and scale based on masks. Blend bottom of objects with the color of the terrain. Independant XZ and Y scale of objects. Terrain Holes. ## Limitations URL: https://ennogames.com/gpu-grass/limitations These features may be added in the future. Hand or brush placement of objects. Placement of objects currently can only be done procedurally. Occlusion culling. GPU Grass does frustum culling only. Occlusion culling may be added in the future. Also current culling does not take shadows into account but this may also be added in the future. Shader Limitations. A single shader is provided with features that can be turned on and off. This shader is optimized for speed over quality. Normal maps are not supported. PBR shading. Intersecting objects. If you have multiple types of objects they may be placed on top of each other. Biomes. GPU Grass manager cannot blend between settings. Billboards. Transparency. Opaque or alpha test only. Editor undo. Save settings while in play mode. Non random rotation. Objects are randomly rotated around y. X and Z rotations are 0.   These are features that GPU Grass cannot do. Collision. Because everyting happens on the GPU based on masks collision cannot be generated for objects rendered with GPU Grass. The CPU does not know the position of size of objects. Shader graph. Unity's shader graph does not currently support shaders that use instancing. ## Installation URL: https://ennogames.com/gpu-grass/installation Setup Create an empty gameobject. (GameObject - Create Empty) You can also use an existing gameobject. Name your new gameobject "Gpu Grass Manger" or anything else you want. Add the "Gpu Grass Manager" componet to your gameobject. (Click "Add Component" and select "Gpu Grass Manager") Select your grass manager gameobject and in the inspector then select the "Terrains" tab and click "Add Active Terrains". This will add the active terrains in the scene to the manager. In the grass manager inspector select the "Settings" tab and make sure your camera is set in the "Main Camera" field.   Adding Grass (or other objects) Select the foliage tab in the Gpu Grass Manager inspector and the "LODs" sub-tab. Click the "add" button. Set the "mesh" and "texture" fields. Set the name for the object in the "Settings" sub-tab. Make sure the other settings are correct. Repeat steps 1 - 5 for more objects. ## Editor - Terrains URL: https://ennogames.com/gpu-grass/editor-terrains   Terrain List This is a list of terrains that GPU Grass Manager will place objects on. Add Active Terrains - Adds all active terrains in the scene to the terrain list. This will not change or settings for terrains that are already in the list. Clear - Remove all terrains from the list. Regenerate Textures - Use this button to regenerate all textures for terrains and objects. If your terrain changes you should click this button. Terrain - Assign a terrain to this field. Texture Sizes Change the size of the masks sent to the graphics card. Smaller to save memory. If you're not using a feature you can make it's texture very small. Placement Mask - Grayscale image of where objects are placed. Black means no objects will be placed there. White means the full number will be placed here. 50% gray means half as many objects will be placed there. Color Map - The color that will be applied to the objects. This map is multiplied by the objects color/texture. Use white to make it have no effect. Scale Map - Scale of placed objects. The minimum and maximum scales are set in the foliage scales tab. Black means the minimum and white the maximum. Normal/Slope Map - Normal and slope/angle of terrain. Normal is red=x, blue=y, green=z. Height/Collision Map - Height map of terrain and mask of where objects should or should not be placed based on the colliders that are in your scene. You can change the layer that is searched when looking for colliders in the settings tab. Terrain Color/Layer Map - Color of texture on terrain and layer on the terrain. Textures - Textures that will be sent to GPU. ## Editor - Foliage URL: https://ennogames.com/gpu-grass/editor-foliage   Object List List of objects that GPU Grass will render. Select one to see it's settings below. Add Remove   LODs Tab If you have multiple LODs GPU Grass will fade between them based on distance to camera. You can have one, two or three LOD levels. LOD Fade Distance - LODs can fade between each other and fade out at maximum draw distance. This changes the distance of the fading. Set to 0 to disable fading. Screen space dithering is used to fade. LOD Distance Visualizer - This is a visual representation of your LOD levels and their draw and fade distances. LOD List List of your LOD meshes. Add Duplicate Remove Rendering Type - Either vertex or pixel lit. Vertex lit is faster as lighting is only calculated for each vertex rendered. Pixel lit is more accurate. Mesh - Mesh to render. Sub Mesh Index - Sub-mesh index to render. If your mesh includes multiple meshes then you can select which one to render here. 0 renders the first mesh. Base Map - Base color and transparency map. Base Color - Color that is multiplied with base color map. Alpha Test - Alpha test is turns pixels on/off based on the base map's alpha channel. It is faster than true transparency and does not have depth sorting issues. Alpha Cutoff - Colors below this value in the base map's alpha channel will not be rendered. View Bending View bending can bend grass or objects away from the camera. This is great for top-down games or first/third person games where the player can look down at the ground. View Bending Strength - The amount that objects will be bent. Set to 0 to disable view bending. View Bending Distance - Max distance that view bending will happen. For a top-down game set to a high number. For a first or third person game this should probably be set to a few feet away from the camera. Draw Distance - The maximum distance that this LOD will be visible at. This is a percentage of "Draw Distance" in the settings tab. Cast Shadows - Toggle on/off casting of shadows. This greatly affects performance. Disabling cast shadows on higher LODs is recommended.   How Modifiers Work Objects are placed and rendered based on texture masks. Modifiers are how you change the texture masks. For example you can add a terrain slope modifier that does not render objects on steep terrain. This of modifiers as layers in Photoshop. They are combined to create one texture mask. Terrain Slope - Slope or angle of the terrain. 0 is flat terrain and 1 is 90 degrees. Noise - Simplex, perlin, celluar f1 or celluar f2 noise. This uses Unity's mathematics random package. Terrain Height - Height of terrain. Terrain Layer - Terrain layer. Random - Randomness using Unity's mathematics random package. Texture - A grayscale texture that you provide. Modifiers can be combined by setting the blend mode. These work the same way as blending modes in Photoshop. Multiply Darken Lighten Overlay Screen Soft Light Hue Saturation Lightness   Placement Tab Placement Settings Placement Type Blue Noise - Use blue noise for things like grass where you want a lot of evenly spaced objects. If you're using a high density blue noise will look fuller with less objects and be more performant. Random - Use random for objects like bushes where you want them to be randomly placed. Objects that are randomly places have a higher change of spawning inside each other. Density - Higher number creates more objects. A very low number may cause issues. Higher numbers greatly reduce performance. Use the lowest number that you are happy with. Setting a number that is too high may cause a stall which crashes Unity. Y Offset - Translates the objects up or down. Set to a negative number to bury the base of objects in the terrain. Thin Over Distance - Render less objects at far away distances. Set to 0 to render the same amount of objects up close as far away. Increase this number to make some objects fade out earlier. This Over Distance is useful for things like grass where you want a lot up close but there can be less far away. Align to Ground - Align the mesh to the terrain slope. This will not rotate the mesh but instead moves the vertices up/down based on the terrain height. Use for things like grass but not for things like rocks. Use Placement Settings from Another Foliage - If you have two meshes that you want to have the same settings you can use this so that their settings will match. For example if you want to render a tree that has two meshes, a trunk mesh and a leaves mesh then you can use this setting to render them with the same settings. Placement Modifiers - Placement modifiers create a black and white mask that is used to limit where objects are placed. See the modifiers section above for more info.   Color Tab Color Settings Default Color - Base color. Think of it as the bottom layer in photoshop. Blend with Ground - Apply the terrain's color to the bottom of objects. Use Placement Settings from Another Foliage - If you have two meshes that you want to have the same settings you can use this so that their settings will match. For example if you want to render a tree that has two meshes, a trunk mesh and a leaves mesh then you can use this setting to render them with the same settings. Color Modifiers - Color modifiers create a texture map that is applied to objects by multiplying it with object's texture and base color.   Scale Tab Scale Settings XZ Scale Range - Scale range for the x and z axis of objects. How wide should objects be. Y Scale Range - Scale range for the y axis of objects. How tall should objects be. Use Placement Settings from Another Foliage - If you have two meshes that you want to have the same settings you can use this so that their settings will match. For example if you want to render a tree that has two meshes, a trunk mesh and a leaves mesh then you can use this setting to render them with the same settings. Scale Modifiers - Scale modifiers create a grayscale map that defines the scale of objects. They use this map to lerp between the scale ranges above.   Settings Tab Enabled - Turn object on/off. This will disable rendering of the object. If you delete the object it will be slightly faster than disabling it. Name - Name of object. Can be whatever you want. Specular Specular Strength - Strength of specular lighting. Environment Strength - Strength of environment lighting. Smoothness - Smoothness of object. Translucency Strength - Amount of translucency. Environment Strength - Strength of environment contribution. Scattering Strength - Width of translucency. Sub-Surface Color - Translucency color. Draw Distance - Maximum draw distance for object. This is a multiplier of draw distance in manager settings. Wind - Amount of wind on object. Shape Normals Type Normal to use when calculating lighting. Use Terrain Normal - Use the terrain's normal for the vert normals. Use Object Normal - Use vertex normals. Away from Pivot - Use vertex position minus pivot position for normal. Up - Use a normal pointing straight up for all of the vert normals. Vertex Colors - Use vertex colors for vert normals. Red=X, Green=Y, Blue=Z. ## Editor - Settings URL: https://ennogames.com/gpu-grass/editor-settings   Settings Tab Main Camera - Camera to be used for frustum and view bending calculations. Draw Distance - Percentage of far clip plane. Other draw distance settings are a percentage of this. If you want to reduce the draw distance of all GPU Grass objects is is more performant to reduce the draw distance here rather than reducing it in each object. Collider Layer Mask - Sets the layers that GPU Grass will use to bake the collisions mask. If you want the grass to not spawn in an area create a collider and give it a layer that is set here. Mask Terrain Holes - Check to make grass not draw on terrain holes. Wind This affects all objects created by GPU Grass. Size - Size of the noise that is used to create wind. Speed - The speed at which the noise changes. Strength - The amount that the noise affects the objects. Reload Everything - Flushes and reloads everything. ## Disclaimer URL: https://ennogames.com/gpu-grass/disclaimer GPU Grass was released recently and hasn't been tested on a lot of platforms. If you find a problem please send me a message. ## Support URL: https://ennogames.com/gpu-grass/support See the contact page for ways to get in touch with me. ## Blender Geometry Nodes - Texel Density Modifier URL: https://ennogames.com/blog/blender-geometry-nodes-texel-density-modifier Published: 2023-03-10 I wanted a texel density modifer for Blender so I made one with geometry nodes. It updates in real-time as you model and is applied when exporting.     Also check out my uv unwrap modifier . They make a great combo.     How to Use Select a mesh and add a "Geometry Nodes" modifier. Select "GNTexelDensity". Set the texture size, the texel density and the UV map name. If you check the "apply modifiers" checkbox when exporting to fbx then you can export with texel density without having to apply your modifiers.     Asset Library If you use the asset library you can find it under the "Enno/uv" folder.     How to get it Grab it from Gumroad. MIT license.     If you're looking for a texel density addon I recommend Texel Density Checker. If you would like to know more about texel density check out this article by Timothy Dries. ## Blender Geometry Nodes - Auto UV Unwrap and Rotate Modifier URL: https://ennogames.com/blog/blender-geometry-nodes-auto-uv-unwrap-and-rotate-modifier Published: 2023-03-09 Geometry nodes modifier to unwrap a mesh with the option to rotate the uv islands to a world space direction. Great for things like rocks with drips where the UVs need to be vertical. This modifier combined with my uv unwrap modifier makes procedural geometry exportable without applying the modifiers, creating UVs and setting texel density each time you export. Real-time on meshes under around 10k triangles. Requires Blender version 3.5 beta or higher.     How to Use Select a mesh and add a "Geometry Nodes" modifier. Select "GNUnwrapper". Seams There are four ways to define uv seams. Sharp edges, edge angle and material border. If you select more than one then they will be combined. Sharp Edges - Use sharp edges as uv seams. If you check the "clear sharp edges" checkbox then the sharp edges that you define will be removed by the modifer so that they do not create sharp edges and are only used for uv seams. There is currently no way to get seams in geometry nodes so uv seams cannot be used. Sharp edges can be used as a work-around. Edge Angle - Use edge angle for uv seams. The edge angle is in degrees. Unfortuantly this does not work as well as Blender's smart unwrap. Smart unwrap does more than only use edge angle. Material Border - Use the border of the defined material as a uv seam. Attribute - Used an edge boolean attribute to define uv seams. Geometry nodes do not have access to uv seams. One way to get around this is to use a python script to copy the uv seams into an attribute. A script to do this can be found at https://blender.stackexchange.com/a/269344     Other Settings Limit to Material - Use this to limit which faces will be unwrapped. Unwrapping will be limited to faces with the defined material. UV Map Name - Set this to the name of the UV map attribute. Default is "UVMap".     Rotate UVs to face up in world space (or any other direction) If you want all of the uvs to be oriented in the same direction for example you are modeling walls and want drips on the walls to all be vertical then check the "Rotate UVs to World Direction" and set the "UV Rotation World Direction". Set to 0,0,1 for UVs to be vertical.     Pack UVs Use this to pack UVs into 0 - 1 space. Settings for this can be found in the Blender Docs     Asset Library If you use the asset library you can find it under the "Enno/uv" folder.     How to get it Grab it from Gumroad. MIT license.     Also check out my texel density modifier . ## Third Time is the Charm URL: https://ennogames.com/blog/third-time-is-the-charm Published: 2022-11-28 I've been doing a lot of woodworking lately. I enjoy making physical things for a change and getting away from the computer. One noticable difference between working on a computer versus on physical objects is how much harder it is to fix mistakes or iterate on a design. I've been finding that the first time I make something it is full of mistakes and design things that could be done better. The second time I make something I can usually fix most of those but it's still not perfect. The third time making something is when it finally comes out great. I recently read Build by Tony Fadell after seeing him on the Lex Fridman Podcast. In it there is a chapter titled "Three Generations" where he talks about how it usually takes three generations to get a product right. He is responsible for building the iPod, iPhone and Nest Thermostat and uses those as examples. ## Should You Switch from Maya to Blender? URL: https://ennogames.com/blog/should-you-switch-from-maya-to-blender Published: 2022-11-15 Yes. Don't even waste your time reading the rest of this blog post. Just do it. Why? I first learned Maya during college in 2000 and after 22 years using Maya I know it quite well. The idea of throwing that built up knowlage away and switching to Blender did not sound appealing to me for a long time. For years co-workers told me how much they liked it (although some warned that it was far from perfect). Finally, a few months ago I made the jump and am very glad that I did. It's hard to put into words why Blender is better. It is far from perfect. Maybe it's similar to creating an image using oil paint versus using a paint program on a computer. People create amazing images with both but what you can do using paint is vastly limited compared to using a computer. Or maybe a typewriter versus a word processor. Maya has all the tools to create games or movies and some are much better than what is currently in Blender but Blender has tools that breed creativity. Oh yeah and Blender is also open-source and free. ## Why Rust and Bevy are awesome. URL: https://ennogames.com/blog/why-rust-and-bevy-are-awesome Published: 2022-11-05 I recently stumbled upon Bevy, "a refreshingly simple data-driven game engine built in Rust)" and started making a simple game with it to check it out. Bevy is built with Rust) and uses ECS so it should be fast, probably much faster than even Unity's ECS. While I didn't finish I am totally sold on Bevy and Rust. They are awesome and I can't wait to see Bevy mature and grow. What is Rust and why is it awesome? People like Rust According to Stack Overflow's developer survey Rust has been the most loved programming language since 2016. I made sure to include C# which Unity uses. C and C++ were so far down I had to cut them off. Rust is FAST Rust is about as fast as C and C++ and maybe twice as fast as C# in this test. - .svg.png)<- Rust doesn't crash One of Rust's main benefits is being memory safe. About 70% of the bugs in Microsft products and Chrome are because of memory errors. Here's an example of one. This C code will blow up if someone enters more than 20 characters. There's no warning or error when you write it and it compiles fine. With Rust however this would not only give you an error it would probably suggest how to fix it. Another Rust feature is safe concurrency. Here's an example in C that runs with no crash but the result will be... who knows. Rust fixes this problem because of the way it handles ownership and it's borrow checker. Concurrency is much easier in Rust. There's more Not only is it possible to write a Rust program that is guarenteed to not leak memory or crash but Rust also has great tools built around it. For example it's errors messages not only tell you what's wrong but in a lot of cases teaches you how to fix it and can even fix it for you. Other features include a package manager similar to Javascript but better. It can run on just about anything even in browsers faster than Javascript by compiling to WebAssembly. Some links to learn more about Rust. Why the developers who use Rust love it so much. Tour of Rust The Rust Programming Language Book Rust by example Rust cheat sheet ## Building a Way Too Complicated Mailbox URL: https://ennogames.com/blog/building-a-way-too-complicated-mailbox Published: 2022-07-03 I moved into a new house recently and the existing mailbox was falling apart and needed to be replaced. I've also been learning about wood working and wanted to try building something a little complicated and maybe a little different. Here's the design I came up with. I wanted to do it with joinery instead of screws which meant some of the pieces had to be cut into some pretty odd shapes. My first attempt to make some of the cuts was with a japanese hand saw, some chisels and a mallet. Videos on youtube make it look so easy but trying to get straight cuts was very hard. After a lot of research I bought a Dewalt Table Saw. - <- With my new table saw I was able to straight complicated cuts pretty easily. Here are most of the pieces. Test fitting them together. I think it's going to work! Shots of gluing some pieces together. The holes in the pieces are for dowels which I used instead of screws. Next step was lots of sanding. Here's the finished post. I didn't have a piece of wood wide enough for the mailbox base so I glued two together with dowels in between. Next I sprayed it all down with some clear sealant, attached the box and numbers. Done! Until I finally saw it in the ground I was pretty worried about how it was going to look but I think it turned out great. If I did it over again I would change the design a bit. Maybe for the next house. Time to start the next project! ## Creating Clouds for Sky Fleet URL: https://ennogames.com/blog/creating-clouds-for-sky-fleet Published: 2022-06-30 Figuring out the clouds for Sky Fleet was a journey but I'm pretty happy with the final solution. Here is how it works and the many failures along the way. My first idea was to use simple meshes for the clouds. I believe I booleaned together some spheres then cleaned them up to get these shapes. They thought they looked pretty cool but knew I needed a better solution. I stumbled upon a video by Sebastian Lague on youtube about clouds that gave me some ideas. Sebastian's videos are amazing if you've never seen them. Watching this video led me down a rabbit hole of cloud rendering shaders. My attempt didn't turn out that great and I finally decided that I wanted a styalized look for the clouds. Instead of focusing on the rendering I decided to try to come up with better shapes for the clouds. In Sebastian's video he talks about using worley noise. I combined worley and simplex noise to come up with the shapes below. This gave me much better shapes for the clouds but they looked way too solid I thought. The first thing I tried was duplicating the meshes a couple times and expanding them. The inside mesh is opaque and the outer meshes are transparent. After watching more youtube videos I tried this technique and was pretty happy with the result. Looks pretty good I think but a little too crisp. After some research I found alpha-to-coverage which can be used to apply anti-aliasing to alpha test shaders. Here's how the final clouds look in the game. Since finishing Sky Fleet I got curious about clouds again and made a little cloudy planet shader. Here's another way to do fake clouds by Oakleaf Smacked together some quad-based fake #volumetric clouds in a couple of days. Ended up doing a simple depth sort to keep the quads in correct order, at 500 quads a dumb depth sort + vertex buffer reconstruction takes about 2 ms. Buffers are nice. #GameMaker #gamedev pic.twitter.com/gbaRILUs6N — Oakleaf (@Oakleaff) August 22, 2022 ## Select Faces on Object by Material in Maya URL: https://ennogames.com/blog/select-faces-on-object-by-material-in-maya Published: 2022-06-28 Selecting faces on an object in Maya by material is easy. Hold down right mouse button on the material then click "Select Objects with Material." This selects faces on all objects in the scene however. Here's a script to select faces on a single object by it's material. Select object then shift select material in hypershade then run script. ## Give each vert a random vertex color script in Maya URL: https://ennogames.com/blog/give-each-vert-a-random-vertex-color-script-in-maya Published: 2022-05-28 Here's a mel script to set the green channel to a random value. Select a mesh or meshes then run it. Change the numbers after "rand" to constrain the values. -g can be -rgb with 3 numbers after it to set all rgb channels. ## Game Programming Links URL: https://ennogames.com/blog/game-programming-links Published: 2022-03-16 Interesting links related to game programming. How to RTS Terrain Topology Algorithms Shaders Shader Tutorials by Inigo Quilez Unity Shaders Cheat Sheet Ned Makes Games' Foilage Shader From Build-In to URP - Unity URP Shader Examples by Filipe Lira URP Shader Template by Filipe Lira URP Shader Templates by Cyan Watercolor Shader for URP by Cyan Raymarched Volumetric Lighting in URP Skybox Shader by Kelvin van Hoorn Harry Alisavakis' Shaders Fast Noise Lite The Book of Shaders Clouds godot-volumetric-cloud-demo Trees Quick Procedural Bush Grass Grass Bending Camera Shake Math for Game Programmers: Juicing Your Cameras With Math Math Easings.net ## Fade Opaque Object using Dithering URL: https://ennogames.com/blog/fade-opaque-object-using-dithering Published: 2022-03-11 Dithering is an option to make an object transparent or fade in/out without using transparency. Here's a function to dither without using a texture. Here's a complete unity unlit shader that fades out over a distance. (untested) ## Random Numbers inside Unity Jobs URL: https://ennogames.com/blog/random-numbers-inside-unity-jobs Published: 2022-02-24 Unity's job system is fast but because it's multithreaded using random numbers inside a job is tricky. Here's one way to do it. ## Frustum Culling with Unity Jobs URL: https://ennogames.com/blog/frustum-culling-with-unity-jobs Published: 2022-02-11 Here's a fast way to find out which objects are visible to the camera. Use Unity's job system to test if each object's bounding box is inside the camera's frustum planes. First here's the code for the job. Here is the code to setup and run the job. ## 3D and 2D Coordinates to 1D Indexes URL: https://ennogames.com/blog/3d-and-2d-coordinates-to-1d-indexes Published: 2022-02-03 Going from coordinates to indexes and back can be very useful. For example textures store pixel info as a 1d array so if you want to sample a pixel at x and y you need to convert your coordinates to the pixel index. Here's how to turn 3d and 2d coordinates into 1d indexes. Here's how to turn the 1d indexes back into coordinates. One example where this is useful is setting pixels in a Unity Texture2D. Here's another example where going from indexes to coordinates is useful. Of course this could be made faster with texture.GetPixels() ## Bilinear vs Bicubic Interpolation and How to Get Height of Terrain in Unity from a Heightmap URL: https://ennogames.com/blog/bilinear-vs-bicubic-interpolation-and-how-to-get-height-of-terrain-in-unity-from-a-heightmap Published: 2022-02-03 Here's how to sample between pixels of a texture using bilinear interpolation and bicubic interpolation. These can be used for scaling images or sampling the value of an image in-between pixels. Bilinear averages the colors of surrounding pixels producing medium quality results. Bicubic is slower but more precise and produces smoother gradations. Bicubic example. Bilinear example If you need to get the height of Unity's terrain from only a heightmap you can use bicubic interpolation.