Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
1
Question by TobiasWeber · Feb 03 at 08:51 AM · shadertextureshadersmipmapsmipmap

How to use a shader to write to a mipmap (partial mipmap update)

Hello,
I am using a ComputeShader to write data to a RenderTexture. I need to update MipMaps after writing to the texture, as proper (updated) MipMaps are required to visualize the texture using a normal material / graphics shader.

The challenge is. The texture is very large (16k x 16k). The modification to it are small and frequent. So I need to do the job within the existing GPU texture buffers using a compute shader. Preferably I try to limit the Mipmap update to the effected region.

So my questions are:
- How to update a MipMap from a ComputeShader?
- Is there a way to directly access/write to a specific texture mipmap from a Shader? (i.e. using level, UV to index)

Many Thanks
Tobias

Comment
Add comment
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

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by BastianUrbach · Feb 03 at 04:28 PM

I don't think you can pick a mipmap level in the shader. What you can do is assign a specific mipmap level to the shader variable on the C# side:

 computeShader.SetTexture(kernel, name, renderTexture, mipmapLevel);

If you want to access all mipmaps in the shader, you need one RWTexture2D variable per mipmap.

Comment
Add comment · 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
0

Answer by TobiasWeber · Feb 03 at 05:40 PM

Thanks a lot. Yes that seems to be a promising option.

Just tricky on how to handle different texture sizes, mipmap levels. As I need to assign individual texture variables in the shader.

Follow on:
- Would it be possible to use a NativePtr to access the texture and just expect the MipMaps to be found at some index ranges behind w x h?
- Is the shader executed in sequence with respect to dimensions? Let's say, I want to use id.xy as 2D coordinates in the picture and id.z as index for the mipmap levels. Can I assume that it first iterates over id.xy before incrementing id.z to go to the next mipmap. Or do I need to invoke a separate shader call for each mipmap?

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 BastianUrbach · Feb 03 at 06:34 PM 0
Share

Would it be possible to use a NativePtr to access the texture and just expect the MipMaps to be found at some index ranges behind w x h?
If you use Texture2D.GetRawTextureData, you get the CPU-side texture memory as a NativeArray, which includes mipmaps. For example, for an 8x8 32-bit texture, the first 256 bytes are mipmap level 0, the next 64 are mipmap level 1, the next 16 are mipmap level 2 and so on. Don't confuse this with Texture.GetNativeTexturePtr(), that just gives you some graphics API struct (e.g. a VkImage on Vulkan), not the actual texture data. To a graphics API, a texture is just GPU memory and some CPU-side metadata and handle. Not all Unity textures have a CPU-side copy (RenderTextures do not) and GPU-side changes are not visible on the CPU side. To get the GPU side texture data, you have to explicitly read from the GPU, e.g. with Texture2D.ReadPixels.

Is the shader executed in sequence with respect to dimensions?
No, at least not really or reliably. It's kinda complicated. The point of GPU compute is that a lot of work is done in parallel. You can not expect that two compute shader threads are executed in any particular order, as they may well be executed at the same time. That said, I believe to the extent that the compute shader can not work in parallel (you usually have more threads than what can run in parallel), it is executed in the expected order. But that's difficult to make use of. So basically it may work under the right circumstances but that's deceptive as it may fail randomly, especially on different hardware. I think one dispatch per mipmap is the way to go.

avatar image TobiasWeber BastianUrbach · Feb 04 at 07:59 AM 0
Share

Great explanation. So using setTexture is the most promising approach for my problem. I am going to create 16 textures, one for each mipmap level on a 16k tex and use a chain of 16 indirectly dispatched kernels. I need to do the job on the GPU to avoid transfer of this huge texture and don't want to block CPU for to long. + I need to limit MipMap update to the affected zones.

Just stumbled across CustomRenderTexture. Currently I am using RenderTexture (RWTexture) + ComputeShader. May I benefit from using CustomRenderTexture in my case? I see a value of using UpdateZones, as I hope it limits the automaticMipMap generation to these areas. However the information in the docs are sparse.

Does CustomRenderTexture + UpdateZone + automaticMipMap=true limit the update of the MipMaps to the affected area?

avatar image BastianUrbach TobiasWeber · Feb 04 at 09:23 AM 0
Share

This is the first time I hear about CustomRenderTexture, I think it's a relatively new thing. Looks promising but I don't know much about it.

If you do one dispatch per mipmap then you should only need two RWTexture2D variables in the shader (read from one and write to the other) and these can point to different mipmap levels in the same texture so you don't actually need multiple textures. Basically my approach would be to use a compute shader like this:

 #pragma kernel CSMain
 
 RWTexture2D<float4> In, Out;
 uint2 Offset;
 
 [numthreads(8,8,1)]
 void CSMain (uint3 id : SV_DispatchThreadID) {
     uint2 p = (id.xy + Offset) * 2;
 
     float4 a = In[p + uint2(0, 0)];
     float4 b = In[p + uint2(0, 1)];
     float4 c = In[p + uint2(1, 0)];
     float4 d = In[p + uint2(1, 1)];
 
     Out[id.xy + Offset] = (a + b + c + d) / 4;
 }

And invoke it like this:

 void UpdateMipmaps(RenderTexture rt, int xMin, int yMin, int xMax, int yMax) {
     var groupSizeX = 8f;
     var groupSizeY = 8f;
 
     for (int i = 0; i < rt.mipmapCount - 1; i++) {
         xMin = Mathf.FloorToInt(xMin / 2f);
         yMin = Mathf.FloorToInt(yMin / 2f);
         xMax = Mathf.CeilToInt(xMax / 2f);
         yMax = Mathf.CeilToInt(yMax / 2f);
 
         var groupsX = Mathf.CeilToInt((xMax - xMin) / groupSizeX);
         var groupsY = Mathf.CeilToInt((yMax - yMin) / groupSizeY);
 
         cs.SetInts("Offset", xMin, yMin);
         cs.SetTexture(0, "In", rt, i);
         cs.SetTexture(0, "Out", rt, i + 1);
         cs.Dispatch(0, groupsX, groupsY, 1);
     }
 }

I don't know if this is the fastest way to do it though.

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

243 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 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

Changing Texture From a Point? 0 Answers

Don't load Mip 0 for certain textures based on a condition? 0 Answers

Shader: 1 Base Texture Overlaid by 1 Transparent Texture. 0 Answers

CRT/LCD screen shader (for materials) 4 Answers

Mipmap bias not Set on device with Unity 3.4 IOS project 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