• 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 crustforever · Apr 25, 2015 at 06:52 AM · uishadergraphicsshaderlabcg

How to access another sprite's texture from a 2D shader

Hello!

First of all, please treat me as a complete shader noob! This is the first experience with shaders of any kind that I have had.

Although much of the jargon is lost on me, I have managed to write two simple shaders (code below) that produce a 2D lighting effect in Unity (the materials themselves are attached to 4.6 UI Image components if that matters -- I need them to be in the UI -- so no sprite renderer component allowed).

The "Light" shader takes a grayscale image and renders it on top of 2D sprites as a light source. It does this by multiplying the existing pixel color on the screen (DstColor) by the grayscale value of the texture at that pixel and then adds that value to the existing pixel color on the screen.

That grayscale texture looks like this:

alt text

The complimentary "Lit" shader (for everything that isn't a light source) simply divides all the color values by 2. That way, where the light texture color value = 1, the lit object will have its full original color (saturation?) value. And where the color value = 0, the lit object will have half that value.

My shaders work fine for the base case application.

But then I wanted to see if I could add a rim lighting effect to the sprites affected by lighting. Here are three different gifs showing my solution in action:

alt text alt text alt text

I did this by giving the edges of the "Lit" sprites a graded alpha value, and then in my "Light" shader I blended the inverse of the on-screen alpha value (OneMinusDstAlpha) with the same 0-1 grayscale value from the light texture in a preliminary pass. The result is that the rim lighting color only gets applied to those places on the underlying sprites that have alpha values less than 1. And the amount that gets added is a function of both the light texture value and the sprite's alpha value.

The cart and its graded alpha value:

alt text alt text

It looks okay but the one big problem (and the reason I'm posting) is that I don't know of a way to get that alpha value from the "Lit" sprite without having the sprite actually show transparent edges in the scene. I want to be able to have a fully opaque sprite, then have a separate grayscale texture with which I can decide where to add this rim lighting.

But since I'm doing the addition of rim lighting in the "Light" shader I can't just pass in a texture to use.

So tl;dr - Is there a way to grab a texture from a material that you are drawing on top of? Or, is there a way to achieve this effect by adding the rim lighting in the "Lit" shader somehow?

Thanks in advance.

Here are the two shaders:

 Shader "UI Lights/Light"
 {
     Properties
     {
         _MainTex ("Light Texture", 2D) = "white" {}
         _LightColor ("Light Color", Color) = (1.0, 1.0, 1.0, 1.0)
         _LightIntensity ("Light Intensity", Range(0.0, 2.0)) = 1.0
         _RimColor ("Rim Lighting Color", Color) = (1.0, 1.0, 1.0, 1.0)
         _RimIntensity ("Rim Intensity", Range(0.0, 2.0)) = 1.0
     }
     
     SubShader
     {
         pass
         {
             Blend OneMinusDstAlpha One
             
             CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
             
             //user defined variables
             uniform sampler2D _MainTex;
             uniform float4 _RimColor;
             uniform float _RimIntensity;
             
             //in/out structs
             struct vertexInput
             {
                 float4 vertex : POSITION;
                 float2 uv_MainTex : TEXCOORD0;
             };
             struct vertexOutput
             {
                 float4 vertex : POSITION;
                 float2 uv_MainTex : TEXCOORD0;
             };
             
             //vertex
             vertexOutput vert(vertexInput v)
             {
                 vertexOutput o;
                 o.uv_MainTex = v.uv_MainTex;
                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                 return o;
             }
             
             //fragment
             float4 frag(vertexOutput i) : COLOR
             {
                 float4 lightValue = tex2D(_MainTex, i.uv_MainTex);
                 return _RimIntensity * _RimColor * lightValue;
                 
                 //DstAlpha should be 1.0 on every pixel after this point as _MainTex has alpha 1.0 everywhere
             }
             
             ENDCG
         }
         
         Pass
         {
             Blend DstColor One
             
             CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
             
             //user defined variables
             uniform sampler2D _MainTex;
             uniform float4 _LightColor;
             uniform float _LightIntensity;
             
             //in/out structs
             struct vertexInput
             {
                 float4 vertex : POSITION;
                 float2 uv_MainTex : TEXCOORD0;
             };
             struct vertexOutput
             {
                 float4 vertex : POSITION;
                 float2 uv_MainTex : TEXCOORD0;
             };
             
             //vertex
             vertexOutput vert(vertexInput v)
             {
                 vertexOutput o;
                 o.uv_MainTex = v.uv_MainTex;
                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                 return o;
             }
             
             //fragment
             float4 frag(vertexOutput i) : COLOR
             {
                 float4 lightValue = tex2D(_MainTex, i.uv_MainTex);
                 return _LightIntensity * _LightColor * lightValue;
             }
             
             ENDCG
         }
     }
 }

 Shader "UI Lights/Lit"
 {
     Properties
     {
         _MainTex ("Sprite Texture", 2D) = "white" {}
     }
     
     SubShader
     {
         Pass
         {
             Blend SrcAlpha OneMinusSrcAlpha
         
             CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
             
             //user defined variables
             uniform sampler2D _MainTex;
             
             //in/out structs
             struct vertexInput
             {
                 float4 vertex : POSITION;
                 float2 uv_MainTex : TEXCOORD0;
             };
             struct vertexOutput
             {
                 float4 vertex : POSITION;
                 float2 uv_MainTex : TEXCOORD0;
             };
             
             //vertex
             vertexOutput vert(vertexInput v)
             {
                 vertexOutput o;
                 o.uv_MainTex = v.uv_MainTex;
                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                 return o;
             }
             
             //fragment
             float4 frag(vertexOutput i) : COLOR
             {
                 float4 col = tex2D(_MainTex, i.uv_MainTex);
                 return float4(col.rgb / 2.0, col.a);
             }
             
             ENDCG
         }
     }
 }

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

0 Replies

· Add your reply
  • Sort: 

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.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

2 People are following this question.

avatar image avatar image

Related Questions

Can I see the calculation of unity_MatrixVP ? 1 Answer

How can I make my own shader include file (.cginc or .glslinc)? 2 Answers

custom Standard Shader alpha issues. 1 Answer

Can a CG shader fail to work on hardware? 1 Answer

Multiply Mode uses strange Alpha 1 Answer

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges