Skip to content

Commit

Permalink
Light in the shade
Browse files Browse the repository at this point in the history
- Expose light in the shader api
  - flw_light - for builtin smooth lighting, faster than can be
    implemented by materials alone
  - flw_lightFetch - for materials that want to go crazy, access to raw
    data
  • Loading branch information
Jozufozu committed Jul 6, 2024
1 parent 4d7982b commit aa8ee28
Show file tree
Hide file tree
Showing 16 changed files with 74 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ public enum ContextShader {
DEFAULT(null, $ -> {
}),
CRUMBLING("_FLW_CRUMBLING", program -> program.setSamplerBinding("_flw_crumblingTex", Samplers.CRUMBLING)),
EMBEDDED("_FLW_EMBEDDED", $ -> {});
EMBEDDED("FLW_EMBEDDED", $ -> {
});

@Nullable
private final String define;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "flywheel:internal/material.glsl"
#include "flywheel:internal/api_impl.glsl"
#include "flywheel:internal/uniforms/uniforms.glsl"

in vec4 flw_vertexPos;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/// Get the light at the given world position.
/// This may be interpolated for smooth lighting.
bool flw_light(vec3 worldPos, out vec2 light);

/// Fetches the light value at the given block position.
/// Returns false if the light for the given block is not available.
bool flw_lightFetch(ivec3 blockPos, out vec2 light);
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "flywheel:internal/material.glsl"
#include "flywheel:internal/api_impl.glsl"
#include "flywheel:internal/uniforms/uniforms.glsl"

out vec4 flw_vertexPos;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ uniform sampler2D _flw_crumblingTex;
in vec2 _flw_crumblingTexCoord;
#endif

bool _flw_embeddedLight(vec3 worldPos, out vec2 lightCoord);

flat in uint _flw_instanceID;

out vec4 _flw_outputColor;
Expand All @@ -37,13 +35,6 @@ void _flw_main() {
flw_fragOverlay = flw_vertexOverlay;
flw_fragLight = flw_vertexLight;

#ifdef _FLW_EMBEDDED
vec2 embeddedLight;
if (_flw_embeddedLight(flw_vertexPos.xyz, embeddedLight)) {
flw_fragLight = max(flw_fragLight, embeddedLight);
}
#endif

flw_materialFragment();

#ifdef _FLW_CRUMBLING
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "flywheel:internal/light_lut.glsl"

layout(std430, binding = _FLW_LIGHT_LUT_BINDING) restrict readonly buffer LightLut {
uint _flw_lightLut[];
};

layout(std430, binding = _FLW_LIGHT_SECTIONS_BINDING) restrict readonly buffer LightSections {
uint _flw_lightSections[];
};

uint _flw_indexLut(uint index) {
return _flw_lightLut[index];
}

uint _flw_indexLight(uint index) {
return _flw_lightSections[index];
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,9 @@
#include "flywheel:internal/common.frag"
#include "flywheel:internal/light_lut.glsl"
#include "flywheel:internal/indirect/buffer_bindings.glsl"
#include "flywheel:internal/indirect/light.glsl"

flat in uvec3 _flw_packedMaterial;

layout(std430, binding = _FLW_LIGHT_LUT_BINDING) restrict readonly buffer LightLut {
uint _flw_lightLut[];
};

layout(std430, binding = _FLW_LIGHT_SECTIONS_BINDING) restrict readonly buffer LightSections {
uint _flw_lightSections[];
};

uint _flw_indexLut(uint index) {
return _flw_lightLut[index];
}

uint _flw_indexLight(uint index) {
return _flw_lightSections[index];
}

void main() {
_flw_uberMaterialFragmentIndex = _flw_packedMaterial.x;
_flw_unpackUint2x16(_flw_packedMaterial.y, _flw_uberCutoutIndex, _flw_uberFogIndex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "flywheel:internal/packed_material.glsl"
#include "flywheel:internal/indirect/buffer_bindings.glsl"
#include "flywheel:internal/indirect/draw_command.glsl"
#include "flywheel:internal/indirect/light.glsl"

layout(std430, binding = _FLW_TARGET_BUFFER_BINDING) restrict readonly buffer TargetBuffer {
uint _flw_instanceIndices[];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "flywheel:internal/light_lut.glsl"

uniform usamplerBuffer _flw_lightLut;
uniform usamplerBuffer _flw_lightSections;

uint _flw_indexLut(uint index) {
return texelFetch(_flw_lightLut, int(index)).r;
}

uint _flw_indexLight(uint index) {
return texelFetch(_flw_lightSections, int(index)).r;
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
#include "flywheel:internal/common.frag"
#include "flywheel:internal/light_lut.glsl"
#include "flywheel:internal/instancing/light.glsl"

uniform uvec4 _flw_packedMaterial;

uniform usamplerBuffer _flw_lightLut;
uniform usamplerBuffer _flw_lightSections;

uint _flw_indexLut(uint index) {
return texelFetch(_flw_lightLut, int(index)).r;
}

uint _flw_indexLight(uint index) {
return texelFetch(_flw_lightSections, int(index)).r;
}

void main() {
_flw_uberMaterialFragmentIndex = _flw_packedMaterial.y;
_flw_unpackUint2x16(_flw_packedMaterial.z, _flw_uberCutoutIndex, _flw_uberFogIndex);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "flywheel:internal/common.vert"
#include "flywheel:internal/packed_material.glsl"
#include "flywheel:internal/instancing/light.glsl"

uniform uvec4 _flw_packedMaterial;
uniform int _flw_baseInstance = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,28 @@ vec2 _flw_lightAt(uint sectionOffset, uvec3 blockInSectionPos) {
return vec2(block, sky);
}

bool _flw_embeddedLight(vec3 worldPos, out vec2 lightCoord) {
bool flw_lightFetch(ivec3 blockPos, out vec2 lightCoord) {
uint lightSectionIndex;
if (_flw_chunkCoordToSectionIndex(blockPos >> 4, lightSectionIndex)) {
return false;
}
// The offset of the section in the light buffer.
uint sectionOffset = lightSectionIndex * _FLW_LIGHT_SECTION_SIZE_INTS;

uvec3 blockInSectionPos = (blockPos & 0xF) + 1;

lightCoord = _flw_lightAt(sectionOffset, blockInSectionPos) / 15.;
return true;
}

bool flw_light(vec3 worldPos, out vec2 lightCoord) {
// Always use the section of the block we are contained in to ensure accuracy.
// We don't want to interpolate between sections, but also we might not be able
// to rely on the existence neighboring sections, so don't do any extra rounding here.
ivec3 blockPos = ivec3(floor(worldPos));

uint lightSectionIndex;
if (_flw_chunkCoordToSectionIndex(blockPos >> 4, lightSectionIndex)) {
// TODO: useful debug mode for this.
// flw_fragOverlay = ivec2(0, 3);
return false;
}
// The offset of the section in the light buffer.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
void flw_materialFragment() {
#ifdef FLW_EMBEDDED
vec2 embeddedLight;
if (flw_light(flw_vertexPos.xyz, embeddedLight)) {
flw_fragLight = max(flw_fragLight, embeddedLight);
}
#endif
}
7 changes: 7 additions & 0 deletions docs/shader-api/common.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/// Get the light at the given world position.
/// This may be interpolated for smooth lighting.
bool flw_light(vec3 worldPos, out vec2 light);

/// Fetches the light value at the given block position.
/// Returns false if the light for the given block is not available.
bool flw_lightFetch(ivec3 blockPos, out vec2 light);
5 changes: 1 addition & 4 deletions docs/shader-api/fragment.glsl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "flywheel:api/material.glsl"
#include "flywheel:api/common.glsl"

/*const*/ vec4 flw_vertexPos;
/*const*/ vec4 flw_vertexColor;
Expand All @@ -24,10 +25,6 @@ vec4 flw_fogFilter(vec4 color);
// To be implemented by discard shaders.
bool flw_discardPredicate(vec4 finalColor);

// To be implemented by the context shader.
void flw_beginFragment();
void flw_endFragment();

sampler2D flw_diffuseTex;
sampler2D flw_overlayTex;
sampler2D flw_lightTex;
5 changes: 1 addition & 4 deletions docs/shader-api/vertex.glsl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "flywheel:api/material.glsl"
#include "flywheel:api/common.glsl"

vec4 flw_vertexPos;
vec4 flw_vertexColor;
Expand All @@ -17,7 +18,3 @@ void flw_transformBoundingSphere(in FlwInstance i, inout vec3 center, inout floa

// To be implemented by the material vertex shader.
void flw_materialVertex();

// To be implemented by the context shader.
void flw_beginVertex();
void flw_endVertex();

0 comments on commit aa8ee28

Please sign in to comment.