- Home /
SetTextureOffset Shader code
I'm new to Shader code. I'm using a ChromaKey shader to remove the black color from this John Travolta sprite sheet. And I'm using an Animate Texture Sheet script to cycle through the sprite sheet positions.
The Animate Texture Sheet script works fine with unity's built in "Particles/Additive" Shader, but it does not with this ChromaKey shader. SetTextureOffset doesn't affect it, which leads me to believe the shader is missing something that would allow offset of the UVs.
The end goal is to animate real green screen footage to place 2D hologram audience members into our 3D spectator sport game.
Inspector Settings - Shader
Threshhold: 0.0039, Slope: 0, Color: (5,4,5, 255) Texture: <http://imgur.com/a/OgUvQ>
Inspector Settings - Script
Columns: 8, Rows: 8, FPS: 15
Does anyone see the problem? Here is the code:
Shader
Shader"Custom/ChromaKey" {
Properties{
_MainTex("Base (RGB)", 2D) = "white" {}
_thresh("Threshold", Range(0, 16)) = 0.65
_slope("Slope", Range(0, 1)) = 0.63
_keyingColor("KeyColour", Color) = (1,1,1,1)
}
SubShader{
Tags{ "Queue" = "Transparent""IgnoreProjector" = "True""RenderType" = "Transparent" }
LOD 100
Lighting Off
ZWrite Off
AlphaTest Off
Blend SrcAlpha OneMinusSrcAlpha
Pass{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
sampler2D _MainTex;
float3 _keyingColor;
float _thresh; //0.8
float _slope; //0.2
#include "UnityCG.cginc"
float4 frag(v2f_img i) : COLOR{
float3 input_color = tex2D(_MainTex,i.uv).rgb;
float d = abs(length(abs(_keyingColor.rgb - input_color.rgb)));
float edge0 = _thresh*(1 - _slope);
float alpha = smoothstep(edge0,_thresh,d);
return float4(input_color,alpha);
}
ENDCG
}
}
FallBack"Unlit/Texture"
}
Texture Sheet Script
using UnityEngine;
using System.Collections;
public class AnimateTextureSheet : MonoBehaviour
{
public int columns = 2;
public int rows = 2;
public float framesPerSecond = 10f;
//the current frame to display
private int index = 0;
private Vector2 spriteSize;
private Renderer renderer;
void Start()
{
renderer = GetComponent<Renderer>();
StartCoroutine(updateTiling());
//set the tile size of the texture (in UV units), based on the rows and columns
spriteSize = new Vector2(1f / columns, 1f / rows);
renderer.materials[0].SetTextureScale("_MainTex", spriteSize);
}
private IEnumerator updateTiling()
{
renderer.materials[0].SetTextureOffset("_MainTex", Vector2.zero);
while (true)
{
//move to the next index
float xOffset = (columns -1) - (index % columns);
float yOffset = ((index / columns) % rows);
Vector2 offset = new Vector2(xOffset * spriteSize.x, //x index
(yOffset * spriteSize.y)); //y index
renderer.materials[0].SetTextureOffset("_MainTex", offset);
index++;
yield return new WaitForSeconds(1f/framesPerSecond);
}
}
}
Answer by Namey5 · Oct 18, 2016 at 06:22 AM
You're absolutely right about the shader not supporting texture offsets. Whilst it is a default in surface shaders, you have to do it manually in vertex/fragment shaders, however the UnityCG include has a macro for this specific purpose.
Shader"Custom/ChromaKey" {
Properties{
_MainTex("Base (RGB)", 2D) = "white" {}
_thresh("Threshold", Range(0, 16)) = 0.65
_slope("Slope", Range(0, 1)) = 0.63
_keyingColor("KeyColour", Color) = (1,1,1,1)
}
SubShader{
Tags{ "Queue" = "Transparent""IgnoreProjector" = "True""RenderType" = "Transparent" }
LOD 100
Lighting Off
ZWrite Off
AlphaTest Off
Blend SrcAlpha OneMinusSrcAlpha
Pass{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
sampler2D _MainTex;
float4 _MainTex_ST;
float3 _keyingColor;
float _thresh; //0.8
float _slope; //0.2
#include "UnityCG.cginc"
float4 frag(v2f_img i) : COLOR{
float2 uv = TRANSFORM_TEX (i.uv, _MainTex);
float3 input_color = tex2D(_MainTex, uv).rgb;
float d = abs(length(abs(_keyingColor.rgb - input_color.rgb)));
float edge0 = _thresh*(1 - _slope);
float alpha = smoothstep(edge0,_thresh,d);
return float4(input_color,alpha);
}
ENDCG
}
}
FallBack"Unlit/Texture"
}
That should work.
So I just add float4 _$$anonymous$$ainTex_ST; ... float2 uv = TRANSFOR$$anonymous$$TEX (i.uv, $$anonymous$$ainTex);
It didn't work when I just added those but when I copy/pasted it worked. What else did you change?
$$anonymous$$ake sure that in your texture declaration you are using that variable rather than the input.
//Use:
float3 input_color = tex2D(_$$anonymous$$ainTex, uv).rgb;
//Ins$$anonymous$$d of:
float3 input_color = tex2D(_$$anonymous$$ainTex, i.uv).rgb;
Your answer
Follow this Question
Related Questions
Animated Texture based on Movement 0 Answers
How do I add multiple spritesheet/emission maps to Master Node in the Shader Editor? 0 Answers
How to get Terrain to respect shader offset 0 Answers
Scrolling Texture scrolls both maps. Only want single map to scroll? 0 Answers
Vertex Offset Shader deforming verts but not the rendered mesh 0 Answers