-
Notifications
You must be signed in to change notification settings - Fork 40
Quick Start Tutorial
This tutorial will walk you through writing a shader that makes stone (or some other block you choose) have an animated bluish glow! It won't teach you GLSL or much about the details, but you'll get a rough idea of what is involved and where to start.
For this tutorial, you'll be using a resource pack. There are other ways to associate shaders with blocks, but this way requires no Java development.
You'll need Minecraft instance that includes Fabric Loader, Fabric API and Canvas 1.0 or later. In the folder where Minecraft runs, open the resourcepacks
folder and create a new sub folder named shaderpack
. (It can be any name, we're just using that name for the tutorial.)
In the shaderpack
folder, use a text editor to create a filed named pack.mcmeta
with these contents:
{
"pack": {
"pack_format": 5,
"description": "Canvas shader tutorial pack"
}
}
Within the shaderpack
folder create the following subfolders:
assets/minecraft/materials
assets/minecraft/shaders/material
assets/minecraft/materialmaps/block
Start Minecraft and confirm shaderpack
is now in the list of available resource packs and then load it. Because it is empty, loading it will not have any effect.
For this effect, we need a vertex shader and a fragment shader.
The vertex shader collects information from incoming quad vertices and makes it available to the fragment shader, usually via "varying" variables. (Yes, I know, all variables are varying, aren't they? It's just how OpenGL names things. You get used to it.)
Create tutorial.vert
with the code below and place it in assets/minecraft/shaders/material
:
#include canvas:shaders/api/vertex.glsl
#include canvas:shaders/lib/face.glsl
// sends noise coordinates from the vertex shader
varying vec2 v_noise_uv;
// The name of this method is special - Canvas will call it for each vertex associated with your shader
void cv_startVertex(inout cv_VertexData data) {
// 2D noise coordinates are derived from world geometry using a Canvas library function
v_noise_uv = cv_faceUv(data.vertex.xyz, data.normal);
}
The fragment shader modifies individual pixels or sub pixels (the "fragments") before they are drawn to the screen. This is where we will do most of the work for this effect.
Create tutorial.frag
with the code below and place it in assets/minecraft/shaders/material
:
#include canvas:shaders/api/fragment.glsl
#include canvas:shaders/lib/math.glsl
#include canvas:shaders/api/world.glsl
// holds our noise coordinates from the vertex shader
varying vec2 v_noise_uv;
// The name of this method is special - Canvas will call it for each fragment associated with your shader
void cv_startFragment(inout cv_FragmentData fragData) {
// modify appearance where stone texture is lighter in color
if (cv_luminance(fragData.spriteColor.rgb) > 0.5) {
// get a time value we can use for animation
float time = cv_renderSeconds();
// use an animated noise function to mix a pastel blue/red color
float color_weight = cv_noise2dt(v_noise_uv * 2.0, time);
// mix 'em up!
vec4 highlight = mix(vec4(1.0, 0.7, 1.0, 1.0), vec4(0.7, 1.0, 1.0, 1.0), color_weight);
// call animated noise function with noise coordinates scaled and shifted
float blend_weight = cv_noise2dt(v_noise_uv * 4.0 - 16.0, time * 2.0);
// mix with the stone texture colors
fragData.spriteColor = mix(fragData.spriteColor, highlight, blend_weight);
// make these fragments fully lit
fragData.emissivity = 1.0;
fragData.ao = false;
fragData.diffuse = false;
}
}