My First Shader - TV signal YPbPr

Hi all,

I am currently working on a shader that will simulate issues with a connection on the back of a TV, more descriptively the Y, Pr, and Pb signals on the TV. This is my first unity shader. I have done some basic shaders for Renderman by pixar for CG work but this is my first unity shader so I am sure to have some questions.

Basically before I start writing it I worked out the math based on Equations on Wikipedia and I have some questions about accessing data for the shader in unity:

First the Math
What I would like to do is take an RBGA texture, convert it to YPrPb then back with eather the PrPb switched or one missing.

The equation for Y is : Y = 0.2126 R + 0.7152 G + 0.0722 B

Then I can solve for Pb and Pr
Pr = Y-R
Pb = Y-B

now converting back I solve for R and B first:
R=Y+Pr
B=Y+Pb

Then solving for G is a bit more tricky

G = Y-(.2126 R)-( 0.0722 B) / .7152

With the RGB Values I can manipulate the picture on the TV based on the inputs. Is this math correct?

My second question is can I access data from a game object in unity from within my shader and if so how?

Thanks Everyone!
James

Hi, I guess there is a sign error, the equations should be:

Pr = R - Y
Pb = B - Y

But the equations for R and B are correct. However, you are missing parentheses in the last equation:

G = (Y-(.2126 R)-( 0.0722 B)) / .7152

I’m not sure how the second question is related to the first, but you would define shader properties ( Unity - Manual: ShaderLab: defining material properties ) and set them via Material.SetVector and related functions (Unity - Scripting API: Material.SetVector ) to the data of specific game objects.

Hey Martin,

Thanks for the math and the shader help! I will take a crack at it. I am trying to simulate what would happen to the picture on a HDTV if you remove or mix up one the composite cables. I will post the results once I get it written.

James

Hey Thank you for helping a new comer to writing shaders for unity. I am trying to find out how to access the red, green, and blue component of a texture I am bringing in. I cannot find it out in the reference. Could you point me to where I can find out how to access the RGB components of the image that I am reading in?

Thanks

You should probably read the Cg Tutorial.

I was able to figure out how to access the different properties and replicated composite input issues. Thanks for your help!
I had no idea that writing shaders in unity would be this straight forward! If some reason somone wants to replicate manipulating an RGB signal for a YPbPr input here is the code, though I don’t think that is super common ; )

Shader "Custom/TVSignal" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_Color ("Main Color", Color) = (1,1,1,1)
		_PbStrangth("Pb Override", Range(0, 1.0)) = 1.0 //Overrides used to manipulate connections
		_PrStrangth("Pr Override", Range(0, 1.0)) = 1.0
		_Switch("Switch", Range(0, 1.0)) = 0 // used to switch Pb and Pr Cables
		
	}
	  SubShader {
     Tags { "RenderType" = "Opaque" }
        
        CGPROGRAM
		 #pragma surface surf Lambert
		sampler2D _MainTex;	
		fixed4 _Color;
		float _PbStrangth;
		float _PrStrangth;
		float _Switch;
				
		 struct Input {

		 float2 uv_MainTex;
		 };
        
         void surf (Input IN, inout SurfaceOutput o) {
        
        
         float _Pr;
		 float _Pb;
		 float _Y;
		 float _R;
		 float _G;
		 float _B;
		 float _Hold;
        
        
        //Extract RGB values
          fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
         _R = c.r;
         _G = c.g;
         _B = c.b;
         
         //calculate Y, Pb, Pr
         _Y = (.2126 * _R) + (.7152 * _G) + (.0722 * _B);
         
         //create Pr and Pb values then multiply by there strength to sim removed input
        _Pr = (_R - _Y) * _PrStrangth;
        _Pb = (_B - _Y) * _PbStrangth;
        
        //If the inputs are switched
        if(_Switch == 1) {
        _Hold = _Pr;
        _Pr = _Pb;
        _Pb = _Hold;
        }
         
        //Get new RGB Values
        _R = _Y + _Pr;
		_B = _Y + _Pb;
        
        _G = (_Y-(.2126*_R)-(0.0722*_B)) / .7152;
        
        
        c.r = _R;
        c.g = _G;
        c.b = _B;
         
          o.Albedo = c.rgb;
          o.Emission = c.rgb;
      }
      ENDCG
    } 
    Fallback "Diffuse"
  }