ExtendedShader
Before reading this page, make sure you understand Minecraft Core Shader.
Photon2 and LDLib2 extend vanilla shaders with ExtendedShader, adding:
- Geometry shader (attach) support
- Extra samplers and uniforms
π¦ How to Use
ExtendedShader JSON is almost the same as Vanilla.
Hereβs an example using Texture Material.
{
    "vertex": "photon:particle",
    /*
        "geometry": "<namespace>:<name>.gsh" // (1)
    */
    "fragment": "photon:hdr_particle",
    "samplers": [
        { "name": "Sampler2" },
        // custom samplers
        { "name": "Texture" }
    ],
    "uniforms": [
        { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1] },
        { "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1] },
        { "name": "ColorModulator", "type": "float", "count": 4, "values": [1,1,1,1] },
        { "name": "FogStart", "type": "float", "count": 1, "values": [0.0] },
        { "name": "FogEnd", "type": "float", "count": 1, "values": [1.0] },
        { "name": "FogColor", "type": "float", "count": 4, "values": [0,0,0,0] },
        { "name": "FogShape", "type": "int", "count": 1, "values": [0] },
        // custom uniforms
        { "name": "DiscardThreshold", "type": "float", "count": 1, "values": [0.01] },
        { "name": "HDR", "type": "float", "count": 4, "values": [0,0,0,1] },
        { "name": "HDRMode", "type": "int", "count": 1, "values": [0] }
    ]
}
- Attach geometry shader if needed.
// have to use 330+
#version 330 core
#moj_import <fog.glsl>
// Photon2 vertex helper
#moj_import <photon:particle.glsl> 
uniform sampler2D Sampler2;
uniform mat4 ModelViewMat;
uniform mat4 ProjMat;
uniform int FogShape;
out float vertexDistance;
out vec2 texCoord0;
out vec4 vertexColor;
void main() {
    ParticleData data = getParticleData();
    gl_Position = ProjMat * ModelViewMat * vec4(data.Position, 1.0);
    vertexDistance = fog_distance(data.Position, FogShape);
    texCoord0 = data.UV;
    vertexColor = data.Color * texelFetch(Sampler2, data.LightUV / 16, 0);
}
#version 150
#moj_import <fog.glsl>
uniform sampler2D Texture;
uniform vec4 ColorModulator;
uniform float FogStart;
uniform float FogEnd;
uniform vec4 FogColor;
uniform float DiscardThreshold;
uniform vec4 HDR;
uniform int HDRMode;
uniform float Bits;
in float vertexDistance;
in vec2 texCoord0;
in vec4 vertexColor;
out vec4 fragColor;
void main() {
    float bits = max(Bits, 1.0);
    vec2 uv = (floor(texCoord0 * bits) + 0.5) / bits;
    vec4 color = texture(Texture, uv) * vertexColor * ColorModulator;
    if (color.a < DiscardThreshold) discard;
    if (HDRMode == 0) {
        color.rgb += HDR.a * HDR.rgb;
    } else {
        color.rgb *= HDR.a * HDR.rgb;
    }
    fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor);
}
Difference from vanilla particle shader:
- In vsh, use#moj_import <photon:particle.glsl>andgetParticleData()to fetch vertex data.
- In fsh, added HDR color output.
π― Handle Vertex Data
Different FX objects and renderer settings (e.g., GPU Instance, Additional GPU Data) can change vertex type and layout.
Photon2 provides a helper library that, through macros, automatically parses and converts input vertex data into an accessible format.
More info: Vertex Format
// Requires GLSL version 330+
#version 330 core
/*
struct ParticleData {
    vec3 Position;
    vec4 Color;
    vec2 UV;
    ivec2 LightUV;
    vec3 Normal;
};
ParticleData getParticleData() {
    // (1)
}
*/
void main() {
    ParticleData data = getParticleData();
    vec3 position = data.Position;
    vec4 color = data.Color;
    vec2 uv = data.UV;
    ivec2 lightUV = data.LightUV;
    vec3 normal = data.Normal;
}
- Internal Implementation, check Vertex Format for details.
Implementation Details
In vertex shader:
- Ensure #versionis 330 or higher.
- Import Photon2 vertex library: #moj_import <photon:particle.glsl>
- Access data via getParticleData()β no need to handle internal layouts manually.
- Photon2 supports passing extra GPU vertex data (e.g., particle lifetime, velocity). See: Additional GPU Data
π¨ Extended Samplers
Photon2 provides extra built-in samplers beyond vanilla. When declared in JSON, these samplers wonβt appear in the Inspector.
| Sampler Name | Description | Preview | 
|---|---|---|
| Sampler2 | Light Map |  | 
| SamplerSceneColor | World Color |  | 
| SamplerSceneDepth | World Depth |  | 
| SamplerCurve | Curve Sampler | - | 
| SamplerGradient | Gradient Sampler | - | 
π SamplerCurve / SamplerGradient
Special samplers, active only if a Curve or Gradient is assigned. Photon2 encodes them into a 128Γ128 texture for sampling in shader.
#moj_import <photon:particle_utils.glsl>
/* internal implementation
const float INV_TEX_SIZE = 1.0 / 128.0;
const float MAX_U = 1.0 - 0.5 * INV_TEX_SIZE;
float getCurveValue(sampler2D curveTexture, int curveIndex, float x) {
    return texture(curveTexture, vec2(clamp(x, 0.0, MAX_U), (float(curveIndex) + 0.5) * INV_TEX_SIZE)).r;
}
vec4 getGradientValue(sampler2D gradientTexture, int gradientIndex, float x) {
    return texture(gradientTexture, vec2(clamp(x, 0.0, MAX_U), (float(gradientIndex) + 0.5) * INV_TEX_SIZE));
}
*/
uniform sampler2D SamplerCurve;
uniform sampler2D SamplerGradient;
void main() {
    float value = getCurveValue(SamplerCurve, 0, x);
    vec4 color = getGradientValue(SamplerGradient, 0, x);
}
Use:
- Import helpers:
- Call getCurveValue()andgetGradientValue()to retrieve values.
π Extended Uniforms
Photon2 adds more built-in uniforms on top of vanilla core shaders.
π Vanilla Built-in Uniforms
| Name | Type | Description | 
|---|---|---|
| ModelViewMat | mat4 | Model-view matrix | 
| ProjMat | mat4 | Orthographic projection matrix (width=window, height=window, near=0.1, far=1000) | 
| ScreenSize | vec2 | Framebuffer width & height (pixels) | 
| ColorModulator | vec4 | Final color multiplier | 
| FogColor | vec4 | Fog color & density (alpha = density) | 
| FogStart | float | Fog start distance | 
| FogEnd | float | Fog end distance | 
| FogShape | int | Fog mode | 
| GameTime | float | Normalized day time (0β1, loops every 20min) | 
| GlintAlpha | float | Glint strength (0β1) | 
π Photon2 Built-in Uniforms
| Name | Type | Description | 
|---|---|---|
| U_CameraPosition | vec3 | Camera world position | 
| U_InverseProjectionMatrix | mat4 | Precomputed inverse ProjMat | 
| U_InverseViewMatrix | mat4 | Precomputed inverse ModelViewMat | 
