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 /
This question was closed Jun 04, 2018 at 09:20 AM by Maxence_Marchand for the following reason:

The question is answered, right answer was accepted

avatar image
0
Question by Maxence_Marchand · May 15, 2018 at 09:29 AM · shadercolorsimulationvertex shaderrealistic

Can I get the whitest point of an image within a shader, and use it for white balancing the image?

I need to write an automatic white balance shader for a project, and for it to work, I need the whitest point of the image. I already tried to copy the RenderTexture into a Texture2D, but I got down to 7 FPS, since I'm doing this for every rendered image. I have to do this for every rendred image since it is a realtime realistic camera simulation, and performances are an important aspect of the project. I thought using the shader's properties to do so, and getting the white point in the C# using GetFloat after browsing the whole image, and sending it to the shader for the balancing in another pass, but since the RGB values needed change in the vertex shader, I have no way to keep the modified property and send it to the C# script, as the modified value stays on the GPU.

This question might be confusing, and I apologize for that.

Thanks in advance for your answers.

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 NoDumbQuestion · May 15, 2018 at 09:37 AM 1
Share

You cannot get whitest points in shader but you can get image that represent where the whitest point is like this.

You can see in the image that the center point is pure black. That work the same for texture. If you amplify the entire image RGB color you can get an image that only have the whitest point and any other color will be black.

To do that you have to make a custom shader which can be quite complicated.

avatar image Maxence_Marchand NoDumbQuestion · May 15, 2018 at 10:39 AM 0
Share

I see... I'll try to find a way for the automatic white balance later, I'll focus on pre-deter$$anonymous$$ed white balance settings, which are quite easy to do. Thanks for your answer :)

1 Reply

  • Sort: 
avatar image
1
Best Answer

Answer by Maxence_Marchand · May 16, 2018 at 11:17 AM

Well, found a way to do it, without a significant loss of performances, and it's quite easy. You need to copy the RenderTexture into a Texture2D, then create a Color32 array that you fill with GetPixels32, and you navigate through this array. Here's a code example of how to do it :

 RenderTexture.active = src;
 tex.ReadPixels(new Rect(0, 0, src.width, src.height), 0, 0);
 Color32[] col = tex.GetPixels32();
 int counter = -1;
 for (int i = 0; i < w; i++) {
     for (int j = 0; j < h; j++) {
         counter++;
         if (((float)(col[counter].r + col[counter].g + col[counter].b) / 3.0f) > average) {
             r = col[counter].r;
             g = col[counter].g;
             b = col[counter].b;
             average = (col[counter].r + col[counter].g + col[counter].b) /3.0f;
         }
     }

With r, g and b being bytes initialiazed to 0 in the Start() method, and w and h being the width and height of the image. Since GetPixels32 returns a 1D array, I used a counter to get the index, and in my case it's not important to get the pixel coordinates. There is a better way to get the index of the pixel in the array, but for my use, this (really bad) method is fine. Of course, this will take more time as the image gets bigger, but for my use, it's acceptable, I hope this can help people.

With this method, I lost around 5-8 frames per second.

Comment
Add comment · Show 3 · 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 Bunny83 · Jun 04, 2018 at 10:24 AM 2
Share

This solution has an error. In line 2 only the blue channel get divided by 3. So the resulting value in "average" is much larger than the actual average. Also there are serveral simplifications you can do:

 Color32[] col = tex.GetPixels32();
 int maxVal = 0;
 Color32 maxColor;
 foreach (Color32 c in col)
 {
     int v = c.r + c.g + c.b;
     if (v > maxVal) {
         maxColor = c;
         maxVal = v;
 }

There's no need to divide by 3 as the relative size will be the same. Also the conversion to float is also unnecessary as we can just work with an int value. There's no byte + operator so the 3 bytes are automatically cast to int.

avatar image Maxence_Marchand Bunny83 · Jun 04, 2018 at 10:30 AM 0
Share

That's right, I haven't noticed XD Anyway, I went with another method, ins$$anonymous$$d of finding the whitest point, I compute the lu$$anonymous$$ance, and compare it, it's way more efficient this way.

Anyway, thanks for pointing out that little mistake ^^

avatar image Bunny83 Maxence_Marchand · Jun 04, 2018 at 11:18 AM 0
Share

If you use one of the conversions over here you may still use integer sums. Just muliply the channels by the corresponding integer coefficients: 299*R + 587*G + 114*B Since R,G and B are max 255 the resulting values perfectly fit into an integer since the max value is (1000 255 == 255000) in this case. Even if you use the first option it would just be a magnitude higher (10000 255)

Follow this Question

Answers Answers and Comments

131 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

Related Questions

How do I adapt this vertex manipulation shader so that my object (point cloud) keeps its original colouring? 0 Answers

Material doesn't have a color property '_Color' 4 Answers

Vertex displacement shader not working 2 Answers

Rendering only specific colors? Color filter? 1 Answer

Realistic metalic on mobile 0 Answers


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