content/hifi-content/brosche/WordPotato/SpritesheetNew.fs
2022-02-13 21:50:01 +01:00

126 lines
No EOL
4.3 KiB
GLSL

/**
Spritesheet Shader
Made By Matti 'Menithal' Lahtinen
Released under Creative Commons Attribution
OI 29/5/2017
This simple shader allows you to create a looping animated sheet within High Fidelity
or any other software that supports a Fragment Shader of the similar type.
**/
// These are defined as floats, because apparently high fidelity userdata json, still gets parsed as floats (as JS Only has Numbers),
// so if they were ints, the configuration parameters would be completely skipped. Very very annoying.
// Sprite sheet rows
uniform float uRows = 3.0;
// Sprite sheet columns
uniform float uColumns = 4.0;
// Default FPS the sprite sheet would be played back at.
uniform float uFps = 5.0;
// Frame definition
/*
Frames are defined by Rows So, forexample the above default values would be a sheet with 2 rows and 2 columns.
The frames would be as:
------------
| 0 | 1 | 2 | 3 |
-------------
| 4 | 5 | 6 | 7 |
-------------
| 8 | 9 |10 |11 |
-------------
*/
// The starting frame. If this is larger than lastFrame, it becomes same as lastFrame
uniform float uStartFrame = 0.0;
// The ending frame. If this is negative, then this is the same as the total size. If smaller than startFrame, its same as it.
uniform float uEndFrame = -1.0;
// shine of the value. set from 0-255
uniform float uShine = 1.0;
// Emit, 0-1;
uniform float uEmit = 1.0;
// Since shaders don't support alpha mapping, this is used
uniform float uAlphaCutoff = 0.5;
// Experimental Feature: Adjusts the cutoff, so you can put the shader on a Sphere.
uniform float uZCutOff = -0.49;
// This is what HiFidelity calls on shader call
float getProceduralColors( inout vec3 diffuse, inout vec3 specular, inout float shininess )
{
// This makes sure only the very front of the entity (supports only boxes) gets used, everything else gets distacted (-z is front in hifi)
// _position is basically the very position of the current pixel fragment thats being rendered.
if (_position.z > uZCutOff) {
discard;
}
// gets the position of the current pixel fragment
vec3 position = _position.xyz;
// Converts the uRows into an integers. This wouldnt normally be needed
int _uRows = int(uRows);
int _uColumns = int(uColumns);
int _uStartFrame = int(uStartFrame);
// Calculates total amount of frames
int _total = _uRows * _uColumns;
// By default sets the total as the lastFrame
int _uEndFrame = _total;
// But if customizable LastFrame is something different from default -1, lets do some logic.
if (uEndFrame > -1) {
if (_uEndFrame < _uStartFrame) {
_uEndFrame = _uStartFrame;
} else if (uEndFrame < _total ){
_uEndFrame = int(uEndFrame+1);
}
}
// Defiine a starting texture
int _startFrameOffset = 0;
float uCurrentPosition = 0;
// If starting frame is different from 0, do some offsets
if( _uStartFrame > 0) {
uCurrentPosition = mod(iGlobalTime*uFps, _uEndFrame - _uStartFrame) + _uStartFrame;
} else if (_uStartFrame < _uEndFrame) {
// startFrame is smaller than last frame, then
uCurrentPosition = mod(iGlobalTime*uFps, _uEndFrame - _uStartFrame);
} else {
// if startFrame is greated than the endFrame, but not -1, then use startFrame as current Position
uCurrentPosition = _uStartFrame;
}
// Make sure position is int for the next steps
int _currentPos = int(uCurrentPosition);
// Calculate position by
/*
row = floor (position / columns)
column = position % columns
*/
int currentRow = int(_currentPos / _uColumns);
int currentColumn = int(mod(_currentPos, _uColumns));
/*
Move to center, and then use the calculated column and row for the fragment pixel
*/
position.x -= currentColumn + 0.5;
position.y -= currentRow + 0.5;
/*
Grab the texture from the iChannel0 Sampler, and make it into a texture, with the position being calculated from the row and the column and the current pixel.
*/
vec4 iTexture = texture(iChannel0, -position.xy / vec2(_uColumns,_uRows)).rgba;
/*
If the alpha for the position is less than contrast value, then discard it
*/
if ( iTexture.a < uAlphaCutoff ) {
discard;
}
/*
Now applying the fragments color, shine, and returning the emit;
*/
diffuse = iTexture.rgb;
shininess = uShine;
return uEmit;
}