Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by daddylongleggs · Sep 07, 2019 at 07:59 PM · shadertexturearrayvoxelmarching cubes

Implementing multi-texture shading with the marching cube algorithm (voxels)

I am currently developing an asteroid mining/exploration game with fully deformable, smooth voxel terrain using marching cubes. I want to implement an "element ID" system that is kind of similar to Minecraft's, as in each type of material has a unique integer ID. This is simple enough to generate, but right now I am trying to figure out a way to render it, so that each individual face represents the element its voxel is assigned to. I am currently using a triplanar shader with a texture array, and I have gotten it set up to work with pre-set texture IDs. However, I need to be able to pass in the element IDs into this shader for the entire asteroid, and this is where my limited shader knowledge runs out. So, I have two main questions:

  1. How do I get data from a 3D array in an active script to my shader, or otherwise how can I sample points from this array?

  2. Is there a better/more efficient way to do this? I thought about creating an array with only the surface vertices and their corresponding ID, but then I would have trouble sampling them correctly. I also thought about possibly bundling an extra variable in with the vertices themselves, but I don't know if this is even possible. I appreciate any ideas, thanks.

Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Pangamini · Sep 11, 2019 at 01:24 PM 0
Share

What exactly is the reason you decided to use $$anonymous$$ecraft-like IDs? I believe that $$anonymous$$inecraft does a lot of what it does to improve performance by atlasing all its textures (or at least the block textures) so the entire world uses a single material. So perhaps ins$$anonymous$$d of creating materials with an ID, you might consider having an ID inside the voxel data, and generate the mesh UVs based on that data and corresponding position in the atlas.

avatar image daddylongleggs Pangamini · Sep 12, 2019 at 12:25 AM 0
Share

That's a good question. First of all, I'm not really sure what system $$anonymous$$inecraft uses, but that was the first example that came to $$anonymous$$d, because I recently made a clone of it in js on my own engine where each voxel is stored as a single int. I am doing a very similar thing with this asteroid, but this time each voxel stores both an integer ID and a floating point density, used with the marching cubes algorithm to make it smooth and not blocky. So I'm pretty much using the system you described, except ins$$anonymous$$d of UV mapping I'm using a triplanar shading. Also, to decrease memory use, I'm storing the int ID and the float density in a single value (added together), and then separating them when I sample the density and material ID

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by BastianUrbach · Sep 08, 2019 at 03:46 PM

You can use a Texture3D instead of a 3D array. You can use material.SetTexture to pass the texture to the shader and tex3D to sample it in the shader.

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image daddylongleggs · Sep 08, 2019 at 09:39 PM 0
Share

How would I go about sampling it from the shader? I have figured out how to create the 3D texture in a script and pass it to the material, but I know very little about the shader language and I don't know exactly how to receive that input

avatar image BastianUrbach daddylongleggs · Sep 09, 2019 at 05:29 AM 1
Share

First you need to declare a uniform variable for it. Note how there is a variable of type sampler2D for each 2D texture you're using. For a 3D texture you simply declare a sampler3D variable. The variable name is what you pass to SetTexture:

sampler3D yourTexture;


Notice how there is a tex2D call somewhere in your fragment shader whenever a 2D texture is accessed. For a 3D texture you use tex3D and pass the sampler3D as well as a float3 (the equivalent of Vector3) as the "array index". The result is a color (represented by a float4 vector):

float4 m = tex3D(yourTexture, float3(x, y, z));


Note that x, y and z are in range 0 to 1, regardless of the texture resolution.

You can then access the color channels of the result as x, y, z and w or equivalently as r, g, b and a. Each component is of type float:

float mat_id = m.r;


A few more things to keep in $$anonymous$$d:

  • The range of values per texel depends on the texture format. The default one stores red, green, blue and alpha in range 0-1 with a resolution of 8 bits per channel

  • Texture3D.SetPixel only works with some texture formats

  • After using Texture3D.SetPixel, you have to call Texture3D.Apply to apply the changes

  • Texture3D.wrap$$anonymous$$ode and Texture3D.filter$$anonymous$$ode affect the result of tex3D so make sure you understand their effect

avatar image daddylongleggs BastianUrbach · Sep 10, 2019 at 10:40 PM 0
Share

Second Edit: After another quick check, I've realized that the rendering gets fixed any time I save the shader during runtime. I literally just clicked over to the shader, changed nothing, saved it, and went back to Unity, and this somehow fixed the issue. How does this work?

Edit as I'm writing this: For some reason completely unknown to me, getting rid of this divide by 200 during runtime completely fixes the issue. In fact, I can change it to anything I want and it will still work (I think this is because I set all material IDs to be the same for testing). Again, I am completely incredulous as to why this is happening.

Hmm, I did this and I've ended up spending multiple hours trying to get it to work. It seems like I can successfully pass the 3D Texture to the shader, but this is where I'm running into problems. First, I think I'm sampling from the 3d texture per pixel, which means the position I'm sampling from might be going from 0-1 within each face. I can manually set the material ID inside of the shader and get the correct texture, so I know it is a problem with the 3D Texture or sampling. I have tried every possible configuration of 0-1 scale or 0-255 scale imaginable, but each time it is only sampling from the texture at index 0. Also, another possible error point could be in the script that passes the data to the shader, because I have also experimented with passing in different ID values. The most interesting (and confusing) is that if I pass in a block ID that has been scaled between 0 and 1, "bands" of another texture appear in lines all along and within the planet. And when I make the shader sample this very finely (dividing each input vector by 200) it expands these rings and there are now three or four textures in it!

I am absolutely baffled by this, and I'm also getting frustrated since I feel like I'm banging my head against a wall...

Pictures: https://imgur.com/a/cEz$$anonymous$$G2t

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

225 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Texture2D to Texture3D 2 Answers

How to access multiple components of a component at once? 2 Answers

Shader Texture Change 3 Answers

CustomRenderTexture (RFloat) wont initialize in the same frame it is created. 0 Answers

how to solve shader/texture problem: putting white icons on colored planes 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges