- Joined
- Jan 2, 2020
- Messages
- 1,414
This is a simple outline shader to learn how to make your own shaders in a simple way.
You'll need to only add your own graphics, it should be a 256x256 png with one or more masked sprites on it.
[CODE title="Shader code"]// -------------------------------------------------------------------------------------------------
// Cheat Sheet of Cerberus-X's Shaders (GLES2 GLSL)
// -----------------------------------
// Scalars
// -------
// bool bb;
// int ii;
// float ff;
// Boolean vectors (2-4 dimensional)
// ---------------
// bvec2 bv;
// bvec3 another;
// bvec4 wow;
// Integer vectors (2-4 dimensional)
// ---------------
// ivec2 iv;
// ivec3 iva;
// ivec4 ivaaa;
// Float vectors (2-4 dimensional)
// -------------
// vec2 v;
// vec3 secondVec;
// vec4 thirdVec;
// Floating point Matrixes
// mat2 m;
// mat3 mm;
// mat4 mmm;
// Almost all math operators work on both float and int data types but not in the same expression.
// Vector algebra operations require that the operands be of the same size.
// EXAMPLES :
//
// ALL VALID
float a = 3.0 * 0.7;
int b = 10 * 7;
ivec3 d = ivec3(1,2,3);
vec3 c = vec3(1.0, 2.0, 3.0);
//
// NOT VALID IN GLES2 as there's no int in GLES2 (there's floor though)
// b = int(10.0 * 0.7);
// -------------------------------------------------------------------------------------------------
uniform sampler2D ColorTexture;
uniform sampler2D ColorTexture2;
void shader(){
// -------------------------------------------------------------------------------------------------
// Get coordinate
vec2 uv=(b3d_ClipPosition.st/b3d_ClipPosition.w)*0.5+0.5;
// Read pixel
vec4 color=texture2D(ColorTexture,uv).rgba;
// Calculate outline
vec2 step = vec2(1.0 / 256.0, 1.0 / 256.0); // thickness
vec4 right = texture2D(ColorTexture, vec2(uv.x + step.x, uv.y));
vec4 left = texture2D(ColorTexture, vec2(uv.x - step.x, uv.y));
vec4 up = texture2D(ColorTexture, vec2(uv.x, uv.y + step.y));
vec4 down = texture2D(ColorTexture, vec2(uv.x, uv.y - step.y));
vec4 acc = right + left + up + down;
if (acc.a > 0.0) acc.a = 1.0;
acc.rgb = vec3(0.5 * acc.a,0.5 * acc.a,0.5 * acc.a); // outline colour
color = (acc * (1.0 - color.a)) + (color * color.a);
// Write pixel
b3d_FragColor = color * color;
// -------------------------------------------------------------------------------------------------
}[/CODE]
This is an example of result. This sprite has an outline from the start.
What you need to know is that the gray outline is the result of the shader!
(To get your colours right without any kind of shadow effect you might want to change
b3d_FragColor = color * color ; to just b3d_FragColor = color; in the shader)
You'll need to only add your own graphics, it should be a 256x256 png with one or more masked sprites on it.
Cerberus:
Import mojo2
Function Main()
New MyApp
End
Class MyApp Extends App
Global image2:Image
Global imagecanvas2:Canvas
Field sourceImage : Image
Field sourceImage2 : Image
Field targetImage : Image
Field canvas : Canvas
Field effect : ShaderEffect
Method OnCreate()
sourceImage = Image.Load("graphics.png",0,0,0) ' You need to provide a 256x256, one with masked sprites is ideal
sourceImage2 = Image.Load("graphics2.png",0,0,0) ' This one is not used in this particular shader
targetImage = New Image(sourceImage.Width,sourceImage.Height)
effect = New ShaderEffect
canvas = New Canvas
image2=New Image(256,256,0,0,0)
imagecanvas2=New Canvas(image2)
SetUpdateRate 0
End
Method OnRender()
canvas.Clear 0, 0.5, 1, 1
effect.Render sourceImage, sourceImage2,image2
canvas.DrawRect 0,0, 256*2,256*2,image2,0,0,256,256
canvas.Flush
End
End
Class myShader Extends Shader
Method New()
Build(LoadString("shader.glsl"))
End
Method OnInitMaterial:Void(material:Material)
material.SetTexture "ColorTexture",Texture.White()
material.SetTexture "ColorTexture2",Texture.White()
material.SetScalar "EffectLevel",1
End
Function Instance:myShader()
If Not _instance _instance=New myShader
Return _instance
End
Private
Global _instance:myShader
End
Class ShaderEffect
Private
Global _canvas:Canvas
Field _material:Material
Method New()
If Not _canvas _canvas=New Canvas
_material=New Material(myShader.Instance())
End
Method SetLevel:Void(level:Float)
_material.SetScalar "EffectLevel",level
End
Method Render:Void(source:Image,source2:Image,target:Image)
_material.SetTexture "ColorTexture",source.Material.ColorTexture
_material.SetTexture "ColorTexture2",source2.Material.ColorTexture
_canvas.Clear 0, 0, 0, 0
_canvas.SetRenderTarget target
_canvas.SetViewport 0,0,target.Width,target.Height
_canvas.SetProjection2d 0,target.Width,0,target.Height
_canvas.DrawRect 0,0,target.Width,target.Height,_material
_canvas.Flush
End
End
[CODE title="Shader code"]// -------------------------------------------------------------------------------------------------
// Cheat Sheet of Cerberus-X's Shaders (GLES2 GLSL)
// -----------------------------------
// Scalars
// -------
// bool bb;
// int ii;
// float ff;
// Boolean vectors (2-4 dimensional)
// ---------------
// bvec2 bv;
// bvec3 another;
// bvec4 wow;
// Integer vectors (2-4 dimensional)
// ---------------
// ivec2 iv;
// ivec3 iva;
// ivec4 ivaaa;
// Float vectors (2-4 dimensional)
// -------------
// vec2 v;
// vec3 secondVec;
// vec4 thirdVec;
// Floating point Matrixes
// mat2 m;
// mat3 mm;
// mat4 mmm;
// Almost all math operators work on both float and int data types but not in the same expression.
// Vector algebra operations require that the operands be of the same size.
// EXAMPLES :
//
// ALL VALID
float a = 3.0 * 0.7;
int b = 10 * 7;
ivec3 d = ivec3(1,2,3);
vec3 c = vec3(1.0, 2.0, 3.0);
//
// NOT VALID IN GLES2 as there's no int in GLES2 (there's floor though)
// b = int(10.0 * 0.7);
// -------------------------------------------------------------------------------------------------
uniform sampler2D ColorTexture;
uniform sampler2D ColorTexture2;
void shader(){
// -------------------------------------------------------------------------------------------------
// Get coordinate
vec2 uv=(b3d_ClipPosition.st/b3d_ClipPosition.w)*0.5+0.5;
// Read pixel
vec4 color=texture2D(ColorTexture,uv).rgba;
// Calculate outline
vec2 step = vec2(1.0 / 256.0, 1.0 / 256.0); // thickness
vec4 right = texture2D(ColorTexture, vec2(uv.x + step.x, uv.y));
vec4 left = texture2D(ColorTexture, vec2(uv.x - step.x, uv.y));
vec4 up = texture2D(ColorTexture, vec2(uv.x, uv.y + step.y));
vec4 down = texture2D(ColorTexture, vec2(uv.x, uv.y - step.y));
vec4 acc = right + left + up + down;
if (acc.a > 0.0) acc.a = 1.0;
acc.rgb = vec3(0.5 * acc.a,0.5 * acc.a,0.5 * acc.a); // outline colour
color = (acc * (1.0 - color.a)) + (color * color.a);
// Write pixel
b3d_FragColor = color * color;
// -------------------------------------------------------------------------------------------------
}[/CODE]
This is an example of result. This sprite has an outline from the start.
What you need to know is that the gray outline is the result of the shader!
(To get your colours right without any kind of shadow effect you might want to change
b3d_FragColor = color * color ; to just b3d_FragColor = color; in the shader)
Attachments
Last edited: