Unity shader pixel manipulation - unity3d

I'm studying shaders in unity and I'm trying to achieve the below image. But I can't seem to make my code produce my target output. My end goal is to divide the whole image depending on the size of my array. Any idea how to correct my code?
Target output:
Code:Shader "Custom/PassArray"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags {"Queue"="Transparent"}
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform float4 _Test [3];
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex;
fixed4 frag (v2f i) : SV_Target
{
fixed4 col;
_Test[0] = fixed4(0,0,1,1);
_Test[1] = fixed4(1,0,0,1);
_Test[2] = fixed4(0,1,0,1);
//Test1: This code block produces output1 image.
int index = round(i.uv.x*_Test.Length);
col = _Test[index];
//Test2: This codeblocks outputs pure green.
//if(i.uv.x < 1/3){
// col = _Test[0];
//}
//else if(i.uv.x < 2/3){
// col = _Test[1];
//}
//else if(i.uv.x < 3/3){
// col = _Test[2];
//}
return col;
}
ENDCG
}
}
}
Actual output:
If I understood it correctly, it's giving me black pixels because of the max i.uv.x is 1. Thus making the index 3 (based on the computation i.uv.x/_Test.Length). But I don't have index 3 in my array though.

Change round to floor. Because you're rounding, values greater than 2.5 get rounded to 3. As you probably know, an array of 3 elements has no index 3, hence the black bar.

I've figured it out. Here's the updated code for anyone who may find it useful. I changed the formula from int index = round(i.uv.x_Test.Length); to int index = ceil(i.uv.x/1_Test.Length)-1;
Shader "Custom/PassArray"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags {"Queue"="Transparent"}
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform float4 _Test [3];
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float4 color : COLOR;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float4 color : COLOR;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex;
fixed4 frag (v2f i) : SV_Target
{
fixed4 col;
_Test[0] = fixed4(0,0,1,1);
_Test[1] = fixed4(1,0,0,1);
_Test[2] = fixed4(0,1,0,1);
//Test1:
int index = ceil(i.uv.x/1*_Test.Length)-1;
col = _Test[index];
return col;
}
ENDCG
}
}
}

Related

Space curvature bending in Unity3D as Post Effect/Image Effect

I'm trying to archieve a chilindrical effect like this on Unity3D:
But every solution is using material based shader, sadly I must have a Post Process effect or an Image Effect, for these reasons:
One map out of 30 needs to use this effect and there are many materials that are shared between them...
Every solution is vertex based. I've done some experiments but I have models with different polygon count, this means that the effect would create visual artifacts (but this can by fixed by editing the 3d models eventually).
I'm at an advanced stage of development.
Do you think it's possible to create a simple effect (even a fake one) that moves the pixels downwards/upwards based on the distance to the camera? (I assume I need to use the depth map)
I've tried very hard but I had no success, the effect doesn't do anything or just won't compile :(
This is the best I could come up with, the grayscale in the frag method is only to check if the shader is working, but once I define the Vert function the grayscale disappears and the shader does nothing.
Shader "Hidden/Custom/WorldCurvature"
{
HLSLINCLUDE
#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/StdLib.hlsl"
TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
float _Bend;
struct Attributes
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct Varyings
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
float4 Frag(Varyings i) : SV_Target
{
float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord);
float luminance = dot(color.rgb, float3(0.2126729, 0.7151522, 0.0721750));
color.rgb = lerp(color.rgb, luminance.xxx, _Bend.xxx);
return color;
}
Varyings Vert(Attributes v)
{
Varyings o;
float4 vv = mul(unity_ObjectToWorld, v.vertex );
vv.xyz -= _WorldSpaceCameraPos.xyz;
vv = float4( 0.0f, (vv.x * vv.x) * - _Bend, 0.0f, 0.0f );
v.vertex += mul(unity_WorldToCamera, vv);
o.vertex = mul(unity_WorldToCamera, vv);
o.texcoord = v.texcoord;
return o;
}
ENDHLSL
SubShader
{
Cull Off ZWrite Off ZTest Always
Pass
{
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
ENDHLSL
}
}
}
I've done another experiment but I think it would only work in a 2D environment, here the image stops once I activate the image effect:
Shader "Hidden/Custom/CylinderImageEffect" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
}
SubShader {
Cull Off ZWrite Off ZTest Always
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert( appdata_img v )
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord.xy;
return o;
}
sampler2D _MainTex;
fixed4 frag (v2f i) : SV_Target {
i.uv.x = 1 - acos(i.uv.x * 2 - 1) / 3.14159265;
return tex2D(_MainTex, i.uv);
}
ENDCG
}
}
}

Invalid subscript in unity shader

Im pretty new to shader coding but I made this one by grouping 2 unlit shaders
When I try to make this shader, which is meant to create an outline and let me interpolate 2 textures unity tells me that there is this error: invalid subscript `vertex´ at line 61
Ive tried some things but i dont get this shader to work properly, if someone knows what do i have to do id be so thankful
Shader "Unlit/Combined"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_SecondaryTex("Secondary Texture", 2D) = "white" {}
_LerpValue("Transition float", Range(0,1)) = 0.5
_OutlineColor("Outline color", color) = (0,0,0,1)
_OutlineWidth("Outline width", Range(1.0,5.0)) = 1.01
}
SubShader
{
Tags { "RenderType" = "Opaque" "Queue" = "Transparent"}
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
//float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 outvertex : SV_POSITION;
float4 pos : POSITION;
float3 normal : NORMAL;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _SecondaryTex;
float4 _SecondaryTex_ST;
float _LerpValue;
float _OutlineWidth;
float4 _OutlineColor;
v2f vert(appdata v)
{
v2f o;
v.vertex.xyz *= _OutlineWidth;
o.outvertex = UnityObjectToClipPos(v.vertex);
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
// sample the texture
fixed4 col = lerp(tex2D(_MainTex, i.uv),tex2D(_SecondaryTex, i.uv), _LerpValue);
return col;
return _OutlineColor;
}
ENDCG
}
Pass//Normal render
{
ZWrite On
Material
{
Diffuse[_Color]
Ambient[_Color]
}
Lighting On
SetTexture[_MainTex]
{
ConstantColor[_Color]
}
SetTexture[_MainTex]
{
Combine previous * primary DOUBLE
}
}
}
}
The line that has a problem is line 61:
v.vertex.xyz *= _OutlineWidth;
If you look at the type that v is declared as, its declared as appdata:
v2f vert(appdata v)
If you look at the definition of appdata:
struct appdata
{
//float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
You'll see that it does not have a vertex property, only uv and normal.
So the line that's an issue should be changed to one of those, probably normal as you're trying to modify a 3-value property of it (and uv only has xy).
v.normal.xyz *= _OutlineWidth;
Alternatively you can modify appdata to have a vertex property by uncommenteing the commented out vertex:
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
Or by removing line 61, depending on what you're trying to do.

Merging 2 shaders in Unity using CG programming and Shaderlab

I want to merge the functionality of these two shaders for Unity.
First shader is main shader that adds a glitch hologram effect.
The Second shader is making a surface texture flimmer for added visual effect.
I am trying to merge my versions of the code, alternatively different passes that allows me to implement both features on same material, if possible.
I have tried shaderpass function, but cannot make it work.
Is it possible to do?
1st shadercode
Shader "Custom/Cool Hologram Original"
{
Properties
{
//This program takes an existing shader script and builds upon it, by adding the features :
//Tintcolor - allowing for manipulation of colors
//Transparency - Changing opaque in tags to transparency so that the model becomes transparent
//Properties allow defining public manipulative variables
_MainTex ("AlbedoTexture", 2D) = "white" {} //braces are useless leftover braces no longer needed according to Unity developer
_TintColor("Tint Color", Color) = (1,1,1,1) //Public variable appearing in inspector
_Transparency("Transparency", Range(0.0,0.5)) = 0.25
_CutoutTresh("Cutout Threshold", Range(0.0,1.0)) = 0.2
_Distance("Distance", Float) = 1
_Amplitude("Amplitude", Float) = 1
_Speed("Speed", Float) = 1
_Amount("Amount", Range(0.0,1.0)) = 1
}
//The actual shader program
SubShader
{
Tags {"Queue"="Transparent" "RenderType"="Transparent" } //Added queue and transparent elements because order matters (see render order queu tag)
LOD 100 //LOD means level of details and used for when player is close or far away
ZWrite Off //This is related to culling and depth testing, controlling if something is written to depth buffer. Zwrite off is for transparent objects
Blend SrcAlpha OneMinusSrcAlpha //See blend factors in unity doc. It is about render order and how they should blend
Pass //A pass can be made for each type of situation, like Virtual Reality etc
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc" //Shaders does not use inheritance, it has got monobehaviour instead, so it must be defined as #included
struct appdata //Structs are objects with 2 objects each. appdata is passed in to v2f vert as argument
{
float4 vertex : POSITION; //Variable with 4 floating point numbers x,y,z,w. POSITION is a semantic binding telling where it is to be used
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION; //SV_Position corresponds to screen position in Unity
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _TintColor;
float _Transparency;
float _CutoutThresh;
float _Distance;
float _Amplitude;
float _Speed;
float _Amount;
v2f vert (appdata v)
{
v2f o;
v.vertex.x += sin(_Time.y * _Speed + v.vertex.y * _Amplitude) * _Distance * _Amount; //Allows sinusoidal movement to vertices in object space b4 translation to clip
o.vertex = UnityObjectToClipPos(v.vertex); //See learnopengl.com to see 5 spaces: local space, world space, view space, clip space, screen space
o.uv = TRANSFORM_TEX(v.uv, _MainTex); //Taking uv data from model and data from maintexture (see the shader texture in inspector)
return o; //Returns struct after it has been build in coordinate system, it will then be passed to fragment function
}
fixed4 frag (v2f i) : SV_Target //Takes in v2f struct calling it i and then bind it to render target, which is frame buffer for screen
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv) + _TintColor; //fixed 4 col is color. Can be fixed rgbA for 3 colors and an alpha channel. tex2D reads in colors from maintex and struct data from i
col.a = _Transparency; //The colors are what actually drawed in this feature with tex3D
clip(col.r - _CutoutThresh); //Not drawing pixels with certain amount of red color
return col;
}
ENDCG
}
}
}
2nd shadercode
Shader "Custom/Offset 1"
{
Properties {
_MainTex ("Texture", 2D) = "white" {}
_ScrollSpeeds ("Scroll Speeds", vector) = (0, -3, 0, 0)
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
// Declare our new parameter here so it's visible to the CG shader
float4 _ScrollSpeeds;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
// Shift the uvs over time.
o.uv += _ScrollSpeeds * _Time.x;
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
3rd shadercode
Shader "Custom/Combined"
{
Properties
{
_MainTex ("AlbedoTexture", 2D) = "white" {}
_HoloColor("Hologram Color", Color) = (1,1,1,1)
_Transparency("Transparency", Range(0.0,0.5)) = 0.25
_CutoutTresh("Cutout Threshold", Range(0.0,1.0)) = 0.2
_Distance("Distance", Float) = 1
_Amplitude("Amplitude", Float) = 1
_Speed("Speed", Float) = 1
_ScrollSpeeds("Scroll Speeds", vector) = (0,-3,0,0) //added from offset shader
_Amount("Amount", Range(0.0,1.0)) = 1
}
SubShader {
Tags {"Queue"="Transparent" "RenderType"="Transparent" }
LOD 100
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f {
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1) //added from offset shader
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _HoloColor;
float4 _ScrollSpeeds;
float _Transparency;
float _CutoutThresh;
float _Distance;
float _Amplitude;
float _Speed;
float _Amount;
v2f vert (appdata v)
{
v2f o;
v.vertex.x += sin(_Time.y * _Speed + v.vertex.y * _Amplitude) * _Distance * _Amount;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.uv += _ScrollSpeeds * _Time.x; //Added from offset shader
UNITY_TRANSFER_FOG(o,o.vertex); //added from offset shader
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv) + _HoloColor;
col.a = _Transparency;
clip(col.r - _CutoutThresh);
UNITY_APPLY_FOG(i.fogCoord, col); //Added from offset shader
return col;
}
ENDCG
}
}
Fallback "Diffuse"
}

Error on scroll texture shader based on Alan Zucconi's book

Using unity 5.5 and Alan Zucconi's book I'm getting " incorrect number of arguments to numeric-type constructor"
shader source added as reccommended:
Shader "book/scroller"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_ScrollXSpeed ("x scroll speed", Range(0,10)) = 2
_ScrollYSpeed("Y scroll speed", Range(0,10)) = 2
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
fixed _ScrollXSpeed;
fixed _ScrollYSpeed;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed2 scrolledUV = i.uv;
fixed2 xScrolledValue = _ScrollXSpeed * _Time;
fixed2 yScrolledValue = _ScrollYSpeed * _Time;
scrolledUV += fixed2 (xScrolledValue, yScrolledValue);
fixed4 col = tex2D(_MainTex, scrolledUV);
return col;
}
ENDCG
}
}
}
Error shows at following line:
scrolledUV += fixed2 (xSCrolledValue, ySCrolledValue);
What is wrong with it?
Reason for the error:
You are creating fixed2-variable and giving it two fixed2 values as parameters, should be floats instead.
Here is a fixed version:
fixed xScrolledValue = _ScrollXSpeed * _Time;
fixed yScrolledValue = _ScrollYSpeed * _Time;
scrolledUV += fixed2 (xScrolledValue, yScrolledValue);

vert: function return value missing semantics

I am just trying to running this code from unity site
Shader "UnityExample/Vertex and Fragment/3-Behind Bars" {
SubShader{
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct vertOut{
float4 pos: SV_POSITION;
float4 scrPos;
};
vertOut vert(appdata_base v){
vertOut o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.scrPos = ComputeScreenPos(o.pos);
return o;
}
fixed4 frag(vertOut i) : SV_Target{
float2 wcoord = (i.scrPos.xy/i.scrPos.w);
fixed4 color;
if(fmod(20.0 * wcoord.x,2.0)<1.0){
color = fixed4(wcoord.xy,0.0,1.0);
} else{
color = fixed4(0.3,0.3,0.3,1.0);
}
return color;
}
ENDCG
}
}
}
This code is showing me an error on this line
vertOut vert(appdata_base v)
vert: function return value missing semantics
I am using unity 4.6
Semantics is missing for scrPos.
float4 scrPos : TEXCOORD0;