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 wurstbrotrest · Jun 23, 2016 at 02:35 PM · c#texturepositioncolor

Get the color of a WebCamTexture at the click position

I need to pick the color of a WebCamTexture with a mouse click at this position and render the color to a cube. My scene consists of a quad with the script below and a cube. The quad shows the video content. The cube should get the color of the position where the quad was clicked.

However the cube always gets the color of lower left pixel of the WebCamTexture, no matter at which position of the quad I click to. The RaycastHit seems to output the right coordinates, but it seems to me the GetPixel method doesn´t use the right coordinates. I have seen multiple forum posts but none of them helps me further.

Can you please lift me up? Thanks in advance.

 using UnityEngine;
 using System.Collections;
 
 public class webcam : MonoBehaviour {
     public WebCamTexture wct;
     public GameObject cube;
 
     void Start () {
         wct = new WebCamTexture ();
         GetComponent<Renderer> ().material.mainTexture = wct;
         wct.Play ();
     }
 
     void Update () {
         if (Input.GetMouseButtonDown(0)) {
             RaycastHit hit = new RaycastHit ();
             Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
             if (Physics.Raycast(ray, out hit)){
                 Debug.Log ("Click position: " + hit.point);
     
                 Color color = wct.GetPixel ((int)hit.textureCoord.x, (int)hit.textureCoord.y);
                 Debug.Log ("Color x/y: " + color);
                 cube.GetComponent<Renderer> ().material.color = color;
             }
         }
     }
 }
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 danilonishimura · Jun 23, 2016 at 03:15 PM

Reason of your error: The raycast hit point represents the intersection point in world coordinates.

I'm assuming your quad texture fills the entire screen

1) Your world coordinates have to be converted to screen coordinates. You can use Camera.main.WorldToScreenPoint method to get your screen coordinate.

2) You need to convert the screen coordinates to a ratio. The screen point can't be used as value for the texture coordinates because screen resolutions may be different from the camera texture size. Divide both X and Y by Screen Width and Screen Height to get a 0-1 ratio:

3) Sample texture based using the ratio. You can get the correct pixel by multiplying the texture size by the ratio.

4) Get the pixel using the coordinate.

PS: The reason you're getting the last pixel is because your texture wrap mode is set to clamp, but changing it to repeat wouldn't fix your issue, It would just give you a different result.

PS2: If your camera texture doesn't fill the entire screen (UI element such as RawImage), instead of getting the ratio based on the Screen size, you would have to calculate the ratio based on the UI rect. The formula could vary based on the UI alignment and anchoring.

Comment
Add comment · Show 1 · 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 wurstbrotrest · Jun 29, 2016 at 10:33 AM 0
Share

See my reply... Problem is not entirely solved yet. Can you please explain step 2 more detailed?

avatar image
0

Answer by wurstbrotrest · Jun 24, 2016 at 04:02 PM

Thanks for your detailed answer. I tried to get through it. Step 1 works fine. At step 2 I don´t know exactly what to do.

2) You need to convert the screen coordinates to a ratio.

I added a Unity Package so that you can see what I'm doing. After step 1 I could render colors other than the lower left pixel´s color, but they were not the right colors. After step 2 the result was worse, so I commented it out (script below and in the Unity Package). By the way, my texture does not fill the whole screen. I think it might be easiest for you, me and the other readers on this thread to work with a sample scene, don´t you think so? Thanks in advance.

EDIT:

I tried the same with a movie (another Unity Package attached). Unfortunately, it´s the same effect: I do not get the right color. Someone should explain step 2 to me.

 using UnityEngine;
 using System.Collections;
 
 public class colorPicker : MonoBehaviour {
     public WebCamTexture wct;
     public GameObject cube;
     Camera cam;
 
     void Start () {
         cam = Camera.main;
         wct = new WebCamTexture ();
         GetComponent<Renderer> ().material.mainTexture = wct;
         wct.Play ();
 
     }
 
     void Update () {
         if (Input.GetMouseButtonDown(0)) {
             RaycastHit hit = new RaycastHit ();
 
             Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
             if (Physics.Raycast(ray, out hit)){
                 Debug.Log ("Click position: " + hit.point);
                 Vector3 hitpoint = hit.point;
                 Vector3 screenPos = cam.WorldToScreenPoint(hitpoint);
 
 
                 Color color = wct.GetPixel ((int)screenPos.x, (int)screenPos.y);
                 // Color color = wct.GetPixel ((int)(screenPos.x/Screen.width), (int)(screenPos.x/Screen.height));
                 Debug.Log ("Color x/y: " + color);
 
                 cube.GetComponent<Renderer> ().material.color = color;
             }
         }
     }
 }

livecolorpickerunitypackage.zip (6.5 kB)
moviecolorpickerunitypackage.zip (151.4 kB)
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 danilonishimura · Jun 29, 2016 at 02:56 PM 0
Share

Lengthier explanation of 2)

Screen point is a value between 0 and the size of your game window. If run fullscreen on a full hd monitor, it would range between 0 and 1920 in the X axis, and between 0 and 1080 in the Y axis. The Z axis would be zero.

These values are no good for texture lookup, as the camera texture will have the size of the camera resolution, not the monitor resolution. It doesn't matter if your Quad is stretched to fill the entire screen, because the sampling happens at the texture, not the quad. If your camera records at 640x480, sampling a pixel at X:900 and Y:500 would return the wrong pixel, because the texture has the maximum value of 640 for X and 480 for Y.

In order to get the approximate "correct" pixel color, you need to transform the screen point in to a ratio (a percentual) which will represent how far from the origin the pixel position is. Using scenario mentioned above, if the X screen pixel position is at zero, the ratio will be zero. If the X screen pixel position is at 1920, the ratio will be 1. If x position is 960, the ratio will be 0.5. The same rules applies for the Y axis.

 Vector2 screenRatio = new Vector2(screenPos.x / Screen.width, screenPos.y / Screen.height);

When you multiply the ratio by the camera texture size (ratio.x to the width, ratio.y to the height), you will get the approximate color of the pixel on that position. Following the example above, a 0 ratio on the X axis, will give you the zero X on the camera texture. The 1 ratio will give you 640 x, and 0.5 ratio will give you 320 x. The same applies for the Y axis.

 Color color = wct.GetPixel ( (int)(screenRatio.x * wct.width), (int)(screenRatio.y * wct.height) );

  • These code snippets not tested.

avatar image wurstbrotrest · Jun 30, 2016 at 09:40 AM 0
Share

Thanks for your detailed instructions. Basically it works now. However it only works if the texture has the same pixel ratio as the screen (in other words: The texture must fill the entire screen in order to get the right color). Unfortunately some screens have other ratios. Then you pick the wrong color. I tried to trick around with RectTransforms and colliders, but without effort. The aim is to pick the color of a video playing on a small object in the scene. Do you have the key for the final result?

This ist the script so far:

 using UnityEngine;
 using System.Collections;
 
 public class WebcamColorPicker : $$anonymous$$onoBehaviour {
     public WebCamTexture wct;
     public GameObject cube;
     Camera cam;
 
     void Start () {
         cam = Camera.main;
         wct = new WebCamTexture ();
         GetComponent<Renderer> ().material.mainTexture = wct;
         wct.Play ();
 
     }
 
     void Update () {
         if (Input.Get$$anonymous$$ouseButtonDown(0)) {
             RaycastHit hit = new RaycastHit ();
 
             Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
             if (Physics.Raycast(ray, out hit)){

                 GameObject hitobj = hit.transform.gameObject;
                 Vector3 screenPos = cam.WorldToScreenPoint(hit.point);
 
                 // map coordinates to display resolution (e. g. 1920 x 1080)
                 Debug.Log ("Click position relative to the screen size (e. g. 1920 x 1080) " + screenPos);
 
                 Vector2 screenRatio = new Vector2(screenPos.x / Screen.width, screenPos.y / Screen.height);
                 Color color = wct.GetPixel ( (int)(screenRatio.x * wct.width), (int)(screenRatio.y * wct.height) );
                 Debug.Log ("Color x/y: " + color);
                 cube.GetComponent<Renderer> ().material.color = color;
             }
         }
     }
 }
avatar image wurstbrotrest · Jul 04, 2016 at 07:38 AM 0
Share

Do you have the clue?

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

164 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

Related Questions

Color specific sections of a texture 1 Answer

How to create a texture, fill it with some color, add a text at a center and to set this texture to some object in C#? 0 Answers

Colour cubes after CombineMesh() 0 Answers

Distribute terrain in zones 3 Answers

How to make the Health bar on Enemys head not be in relation to Player(main) Camera? 2 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