Skip to content

Shader Compatibility. (For Shader Dev)

zomb_676 edited this page Aug 3, 2023 · 9 revisions

What's this?

This is a guide for shader dev who wants to make shader packs work compatible with shimmer
also, this will mention some principles about how shimmer works
Please note that all this is not the final docs, and please don't treat this as a formal version
All is still alpha

What can be made compatible?

Block/Fluid Bloom and colored Light, but all this should be done by you, the shader dev

File

shimmer which includes this ability is still work in progress
we can find a jar for a test at GitHub action on brach iris-comp
like here https://github.com/Low-Drag-MC/Shimmer/actions/runs/5726699796 and alpha version release at modrinth and curseforge, Shimmer 1.20.1-0.1.19

Attention

this article will use glsl version at least 150 and will only show the basic way
I am just a modder dev, not a shader dev. I am not good at writing fantasy shader stuff

Content

Macro

for shader dev to make code can work both under shimmer and without shimmer, shimmer will make iris
insert another macro shimmer_installed, an example usage is like this

#ifdef shimmer_installed
//code when shimmer is installed
#else
//code when shimmer is not installed
#endif

Blcok/Fluid bloom

Principle

as we all know, Minecraft introduces a type of shader called core shader
In that kind of vertex shader, we can receive all available vertex information
when render by vanilla, shimmer will patch the vertex data transformed to shader
Minecraft use in ivec2 UV2 to represent light information, the core point is at there
Minecraft only has both 16 different light levels for block light and daylight, only 8bit data is enough
so, shimmer uses some unused bit to indicate whether the vertex should be bloom or not
under sodium and iris, this works similarly

Code

gbuffers_terrain.vsh

#version 150
//in vsh
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 textureMatrix = mat4(1.0);
uniform vec3 chunkOffset;

in ivec2 vaUV2;
in vec2 vaUV0;
in vec3 vaPosition;
in vec4 vaColor;

out vec2 lmcoord;
out vec2 texcoord;
out vec4 tint;
#ifdef shimmer_installed
out float isBloom; // look at there
#endif

void main() {
	gl_Position = projectionMatrix * (modelViewMatrix * vec4(vaPosition + chunkOffset, 1.0));
	texcoord    = (textureMatrix * vec4(vaUV0, 0.0, 1.0)).xy;
	lmcoord     = vaUV2 * (1.0 / 256.0) + (1.0 / 32.0);
	tint        = vaColor;
	#ifdef shimmer_installed
	if((vaUV2.x & 0x100) != 0) {
		isBloom = 100.0;
	} else {
		isBloom = 0.0;
	}
	#endif
}

just make vaUV2.x & 0x100 !=0, and we can know if this vertex should be bloom or not

just make a simple test usage fsh
gbuffers_terrain.fsh

#version 150
#extension GL_ARB_explicit_attrib_location : enable

uniform float alphaTestRef;
uniform sampler2D gtexture;
uniform sampler2D lightmap;

in vec2 lmcoord;
in vec2 texcoord;
in vec4 tint;
#ifdef shimmer_installed
in float isBloom;
#endif
/* DRAWBUFFERS:0 */
layout(location = 0) out vec4 colortex0Out;

void main() {
	vec4 color = texture(gtexture, texcoord) * tint;
	if (color.a < alphaTestRef) discard;
	color *= texture(lightmap, lmcoord);

	colortex0Out = color;
	#ifdef shimmer_installed
	if (isBloom > 99.0) {
		colortex0Out *= vec4(1.0,0.0,0.0,0.0);
	}
	#endif
}

vanilla and sodium under vanilla and sodium

under simper test shader pack under simple test shader pack
though the visual effect is not good, we can find that all vertex should be blom is tinted red, as the code writes

Also

the code example code is not so perfect, just a principle show. For example, we can try to use some built-in glsl functions to avoid the if statement for better performance. And if you just write code my way. Please note that in vsh we set 100.0 but in fsh we check > 99.0 this is import, don't use == 100

Colored light

this is more complex, first of all, we need to use ShaderStorageBufferObject

Note

some shaderpacks may still use #version 120 for compatibility,if you don't want to change to #version 150 and above
you can use syntax like this #extension GL_ARB_shader_storage_buffer_object : require, this will help you

shaders.properties

in the shaders.properties file, we need to write things like this

iris.features.required = ssbo
bufferObject.0 = 65536
bufferObject.1 = 32
shimmer.config.lights = 0
shimmer.config.env = 1

the first three lines is for iris, you can find their wiki for the detailed explanation, just note that
you must use SSBO from 0 to the maximum you want to use, don't skip one of them, you can find a detailed explanation here
Also, the size should be at least the number written above

Then, the last two lines will been read by shimmer, the content before = is fixed, and the content after = should correspond with the SSBO index set before

SSBO buffer content

from the buffer above, we can find that shimmer will provide two SSBO, one is called lights and another is env, code can explain them more precisely

#ifdef shimmer_installed
struct Light {
  //formatted in r g b a
  vec4 color;   
  //the color's source's position, based on Minecraft's world size
  //which means if the position is easy to BlockPos, the same value you can see in f3 debug screen
  vec3 position;
  float radius;
};

//shimmer support at most 2048 light source
//note: don't read them arbitrarily, they are not initiated, we may read garbage data
layout (std140, binding = 0) buffer LightBuffer { 
  Light lights[2048];     //64MB total
};

//indicates how many lights to use, use this as an index to read lights safely
layout (std140, binding = 1) buffer EnvBuffer {
  //uv light is a concept in shimmer, we can not take care of them just use uvLightCout+nouvLightCout as an index  
  
  //this kind of light should take Minecraft's original light level into consideration  
  int uvLightCout;   //32 bytes total  
  
  //this kind of light shouldn't take Minecraft's original light level into consideration  
  int nouvLightCout;  
  
  //the camera's BlockPos, same in f3 debug screen, just for shimmer to work under vanilla and sodium  
  //you can ignore this and use uniform provided by iris  
  vec3 camPos;  
};
#endif

Example

image SSBO bind

image SSBO env info

image SSBO lights info