Skip to content

Custom Shader Built-in Uniforms and Samplers ​

Since 2.0.0

This is the lookup page for Custom Shader Material. Names are case-sensitive and must appear both in the shader JSON and in the GLSL stage that uses them. A declaration that GLSL never reads may be optimized out during compilation.

Built-in Samplers ​

Names beginning with Sampler are hidden from Shader Settings. Photon currently handles these names:

NameGLSL typeSourceNotes
Sampler0sampler2DRenderSystem texture slot 0Conventional main-texture slot. Custom Shader Material does not select this texture itself, so it is reliable only when the active render pass explicitly set slot 0. Use a custom Texture sampler when the material must choose its own texture.
Sampler2sampler2DMinecraft light textureRead block and sky light with texelFetch(Sampler2, lightUV / 16, 0).
SamplerBlockAtlassampler2DMinecraft block atlasPhoton binds the block atlas while loading the material. Use atlas UVs.
SamplerSceneColorsampler2Dcurrent Photon render pass scene colorValid only inside an active RenderPassPipeline.
SamplerSceneDepthsampler2Dcurrent Photon render pass scene depthThis is nonlinear device depth. Use inverse matrices and viewport data when reconstructing positions.
SamplerCurvesampler2Dmaterial curve textureUp to 128 curves with 128 samples each.
SamplerGradientsampler2Dmaterial gradient textureUp to 128 gradients with 128 samples each.
Curve and Gradient configuration on Custom Shader Material
SamplerCurve and SamplerGradient are configured as material data, not ordinary PNGs.

Curves and Gradients ​

glsl
#moj_import <photon:particle_utils.glsl>

uniform sampler2D SamplerCurve;
uniform sampler2D SamplerGradient;

float strength = getCurveValue(SamplerCurve, 0, age01);
vec4 color = getGradientValue(SamplerGradient, 0, age01);

The second argument is a row in 0..127; the third is a normalized horizontal coordinate. The helper clamps x to valid texel centers. The material panel edits curve/gradient data; Photon binds the generated texture to the shader only when the JSON declares the corresponding sampler.

Scene Color and Scene Depth ​

SamplerSceneColor content
SamplerSceneColor contains scene color captured by the current render pipeline before the particle draw.
SamplerSceneDepth content
SamplerSceneDepth supports depth fade, intersections, and soft particles.

Scene samplers are snapshots of the current pipeline and do not necessarily include transparent objects drawn later. A material preview, or a draw without an active Photon render pass, has no valid scene texture.

Block Atlas ​

Minecraft block-atlas UVs
SamplerBlockAtlas expects atlas UVs, not local 0..1 UVs for one texture.

Photon Dynamic Uniforms ​

NameGLSL typeValue on each apply
U_CameraPositionvec3world position of the active Photon camera
U_InverseProjectionMatrixmat4inverse of the current RenderSystem projection matrix
U_InverseViewMatrixmat4inverse of the current RenderSystem model-view matrix
U_ViewPortvec4OpenGL viewport (x, y, width, height)

U_ViewPort Since 2.1.3.a

U_ is reserved

LDShaderHolder hides every U_ uniform, but Custom Shader Material updates only the four names above. Do not begin a custom uniform with U_: it will neither receive an automatic value nor appear in the Inspector.

Compute screen UV from fragment coordinates and the viewport:

glsl
uniform vec4 U_ViewPort;

vec2 screenUV = (gl_FragCoord.xy - U_ViewPort.xy) / U_ViewPort.zw;

Dynamic Lights ​

Since 2.2.8

A Custom Shader Material can be lit by Photon's dynamic lights. Declare the names below in the shader JSON and import photon:lit_particle.glsl in the fragment shader. The include declares them in GLSL, so do not declare them again.

When the JSON declares PhotonLightData, Photon treats all nine names as built in: it binds the frame's lights on every draw at intensity 1, hides the entries from Shader Settings, and does not save them.

NameJSON declarationGLSL typeHolds
PhotonLightDatasamplersampler2DThe frame's lights, four texels per light.
PhotonClusterGridsamplersampler2DFor each screen tile and depth slice, where its light list starts and how long it is.
PhotonClusterIndicessamplersampler2DThe light lists of all clusters.
PhotonVisibilityAtlassamplersampler2DThe shadow maps of the shadowed lights (Voxel shadows only).
PhotonClusterInfoint, count 4ivec4Tile size, tiles across, tiles down, depth slices.
PhotonClusterViewfloat, count 4vec4Near plane, slice scale, viewport origin.
LitParticleParamsfloat, count 4vec4x = 1 while lights are bound, y = intensity.
PhotonVisibilityInfoint, count 4ivec4Map size, maps per atlas row, maps this frame.
PhotonViewInversematrix4x4, count 16mat4The inverse view matrix.

Copy the JSON entries with their default values from Hand-written Shaders or from Photon's assets/photon/shaders/core/hdr_particle.json.

FunctionReturns
vec3 photon_particle_light(vec3 viewPos)The light reaching a view-space position from every direction, for billboards.
vec3 photon_surface_light(vec3 viewPos, vec3 viewNormal, float wrap)The same, with each light weighted by how squarely it falls on a unit view-space normal. A zero normal takes light from every direction; wrap above 0 lets light reach past the terminator.

Both functions are fragment-only. They return 0 in previews, while dynamic lights are off, and when no light is in view.

Minecraft ShaderInstance Uniforms ​

These standard names are recognized and populated from matching render state by ShaderInstance. Declare only what the shader needs.

NameTypical typeMeaning
ModelViewMatmat4current model-view matrix
ProjMatmat4current projection matrix
TextureMatmat4current texture matrix
ScreenSizevec2current output size
ColorModulatorvec4global color multiplier
Light0_Directionvec3first primary light direction
Light1_Directionvec3second primary light direction
FogStartfloatfog start distance
FogEndfloatfog end distance
FogColorvec4fog color
FogShapeintfog shape
GameTimefloatnormalized Minecraft game time
GlintAlphafloatglint intensity
LineWidthfloatline-rendering width
ChunkOffsetvec3chunk rendering offset; ordinary Photon particles normally do not use it

Not every Minecraft render path provides a meaningful value for every field. Particle materials most often use matrices, fog, color, screen size, and game time.

Custom Samplers and Uniforms ​

Parameters outside the built-in lists are managed by the Inspector:

json
"samplers": [
  { "name": "NoiseTexture" }
],
"uniforms": [
  { "name": "NoiseScale", "type": "float", "count": 1, "values": [4] },
  { "name": "EmissionColor", "type": "float", "count": 4, "values": [1, 0.4, 0.1, 1] }
]

NoiseTexture becomes a texture picker, NoiseScale a number, and EmissionColor an HDR color because its name contains emission. Custom values are copied to all renderer-define variants of the material and saved in the FX.

To read particle lifetime, velocity, or Java-injected data, do not invent another built-in uniform. Shader Graph uses the PhotonData/PhotonCustomData accessors; Custom Shader Material uses appended instance attributes. Both paths and their limitations are documented in Additional GPU Data.

Released under the MIT License.