mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-02-09 03:34:59 +01:00
Light in the shade
- 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
This commit is contained in:
parent
495c047968
commit
b7c8604898
16 changed files with 74 additions and 50 deletions
|
@ -13,7 +13,8 @@ public enum ContextShader {
|
||||||
DEFAULT(null, $ -> {
|
DEFAULT(null, $ -> {
|
||||||
}),
|
}),
|
||||||
CRUMBLING("_FLW_CRUMBLING", program -> program.setSamplerBinding("_flw_crumblingTex", Samplers.CRUMBLING)),
|
CRUMBLING("_FLW_CRUMBLING", program -> program.setSamplerBinding("_flw_crumblingTex", Samplers.CRUMBLING)),
|
||||||
EMBEDDED("_FLW_EMBEDDED", $ -> {});
|
EMBEDDED("FLW_EMBEDDED", $ -> {
|
||||||
|
});
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final String define;
|
private final String define;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "flywheel:internal/material.glsl"
|
#include "flywheel:internal/material.glsl"
|
||||||
|
#include "flywheel:internal/api_impl.glsl"
|
||||||
#include "flywheel:internal/uniforms/uniforms.glsl"
|
#include "flywheel:internal/uniforms/uniforms.glsl"
|
||||||
|
|
||||||
in vec4 flw_vertexPos;
|
in vec4 flw_vertexPos;
|
||||||
|
|
|
@ -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);
|
|
@ -1,4 +1,5 @@
|
||||||
#include "flywheel:internal/material.glsl"
|
#include "flywheel:internal/material.glsl"
|
||||||
|
#include "flywheel:internal/api_impl.glsl"
|
||||||
#include "flywheel:internal/uniforms/uniforms.glsl"
|
#include "flywheel:internal/uniforms/uniforms.glsl"
|
||||||
|
|
||||||
out vec4 flw_vertexPos;
|
out vec4 flw_vertexPos;
|
||||||
|
|
|
@ -13,8 +13,6 @@ uniform sampler2D _flw_crumblingTex;
|
||||||
in vec2 _flw_crumblingTexCoord;
|
in vec2 _flw_crumblingTexCoord;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool _flw_embeddedLight(vec3 worldPos, out vec2 lightCoord);
|
|
||||||
|
|
||||||
flat in uint _flw_instanceID;
|
flat in uint _flw_instanceID;
|
||||||
|
|
||||||
out vec4 _flw_outputColor;
|
out vec4 _flw_outputColor;
|
||||||
|
@ -37,13 +35,6 @@ void _flw_main() {
|
||||||
flw_fragOverlay = flw_vertexOverlay;
|
flw_fragOverlay = flw_vertexOverlay;
|
||||||
flw_fragLight = flw_vertexLight;
|
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();
|
flw_materialFragment();
|
||||||
|
|
||||||
#ifdef _FLW_CRUMBLING
|
#ifdef _FLW_CRUMBLING
|
||||||
|
|
|
@ -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];
|
||||||
|
}
|
|
@ -1,25 +1,9 @@
|
||||||
#include "flywheel:internal/common.frag"
|
#include "flywheel:internal/common.frag"
|
||||||
#include "flywheel:internal/light_lut.glsl"
|
|
||||||
#include "flywheel:internal/indirect/buffer_bindings.glsl"
|
#include "flywheel:internal/indirect/buffer_bindings.glsl"
|
||||||
|
#include "flywheel:internal/indirect/light.glsl"
|
||||||
|
|
||||||
flat in uvec3 _flw_packedMaterial;
|
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() {
|
void main() {
|
||||||
_flw_uberMaterialFragmentIndex = _flw_packedMaterial.x;
|
_flw_uberMaterialFragmentIndex = _flw_packedMaterial.x;
|
||||||
_flw_unpackUint2x16(_flw_packedMaterial.y, _flw_uberCutoutIndex, _flw_uberFogIndex);
|
_flw_unpackUint2x16(_flw_packedMaterial.y, _flw_uberCutoutIndex, _flw_uberFogIndex);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "flywheel:internal/packed_material.glsl"
|
#include "flywheel:internal/packed_material.glsl"
|
||||||
#include "flywheel:internal/indirect/buffer_bindings.glsl"
|
#include "flywheel:internal/indirect/buffer_bindings.glsl"
|
||||||
#include "flywheel:internal/indirect/draw_command.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 {
|
layout(std430, binding = _FLW_TARGET_BUFFER_BINDING) restrict readonly buffer TargetBuffer {
|
||||||
uint _flw_instanceIndices[];
|
uint _flw_instanceIndices[];
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -1,19 +1,8 @@
|
||||||
#include "flywheel:internal/common.frag"
|
#include "flywheel:internal/common.frag"
|
||||||
#include "flywheel:internal/light_lut.glsl"
|
#include "flywheel:internal/instancing/light.glsl"
|
||||||
|
|
||||||
uniform uvec4 _flw_packedMaterial;
|
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() {
|
void main() {
|
||||||
_flw_uberMaterialFragmentIndex = _flw_packedMaterial.y;
|
_flw_uberMaterialFragmentIndex = _flw_packedMaterial.y;
|
||||||
_flw_unpackUint2x16(_flw_packedMaterial.z, _flw_uberCutoutIndex, _flw_uberFogIndex);
|
_flw_unpackUint2x16(_flw_packedMaterial.z, _flw_uberCutoutIndex, _flw_uberFogIndex);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "flywheel:internal/common.vert"
|
#include "flywheel:internal/common.vert"
|
||||||
#include "flywheel:internal/packed_material.glsl"
|
#include "flywheel:internal/packed_material.glsl"
|
||||||
|
#include "flywheel:internal/instancing/light.glsl"
|
||||||
|
|
||||||
uniform uvec4 _flw_packedMaterial;
|
uniform uvec4 _flw_packedMaterial;
|
||||||
uniform int _flw_baseInstance = 0;
|
uniform int _flw_baseInstance = 0;
|
||||||
|
|
|
@ -64,7 +64,21 @@ vec2 _flw_lightAt(uint sectionOffset, uvec3 blockInSectionPos) {
|
||||||
return vec2(block, sky);
|
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.
|
// 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
|
// 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.
|
// to rely on the existence neighboring sections, so don't do any extra rounding here.
|
||||||
|
@ -72,8 +86,6 @@ bool _flw_embeddedLight(vec3 worldPos, out vec2 lightCoord) {
|
||||||
|
|
||||||
uint lightSectionIndex;
|
uint lightSectionIndex;
|
||||||
if (_flw_chunkCoordToSectionIndex(blockPos >> 4, lightSectionIndex)) {
|
if (_flw_chunkCoordToSectionIndex(blockPos >> 4, lightSectionIndex)) {
|
||||||
// TODO: useful debug mode for this.
|
|
||||||
// flw_fragOverlay = ivec2(0, 3);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// The offset of the section in the light buffer.
|
// The offset of the section in the light buffer.
|
||||||
|
|
|
@ -1,2 +1,8 @@
|
||||||
void flw_materialFragment() {
|
void flw_materialFragment() {
|
||||||
|
#ifdef FLW_EMBEDDED
|
||||||
|
vec2 embeddedLight;
|
||||||
|
if (flw_light(flw_vertexPos.xyz, embeddedLight)) {
|
||||||
|
flw_fragLight = max(flw_fragLight, embeddedLight);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
7
docs/shader-api/common.glsl
Normal file
7
docs/shader-api/common.glsl
Normal file
|
@ -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);
|
|
@ -1,4 +1,5 @@
|
||||||
#include "flywheel:api/material.glsl"
|
#include "flywheel:api/material.glsl"
|
||||||
|
#include "flywheel:api/common.glsl"
|
||||||
|
|
||||||
/*const*/ vec4 flw_vertexPos;
|
/*const*/ vec4 flw_vertexPos;
|
||||||
/*const*/ vec4 flw_vertexColor;
|
/*const*/ vec4 flw_vertexColor;
|
||||||
|
@ -24,10 +25,6 @@ vec4 flw_fogFilter(vec4 color);
|
||||||
// To be implemented by discard shaders.
|
// To be implemented by discard shaders.
|
||||||
bool flw_discardPredicate(vec4 finalColor);
|
bool flw_discardPredicate(vec4 finalColor);
|
||||||
|
|
||||||
// To be implemented by the context shader.
|
|
||||||
void flw_beginFragment();
|
|
||||||
void flw_endFragment();
|
|
||||||
|
|
||||||
sampler2D flw_diffuseTex;
|
sampler2D flw_diffuseTex;
|
||||||
sampler2D flw_overlayTex;
|
sampler2D flw_overlayTex;
|
||||||
sampler2D flw_lightTex;
|
sampler2D flw_lightTex;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "flywheel:api/material.glsl"
|
#include "flywheel:api/material.glsl"
|
||||||
|
#include "flywheel:api/common.glsl"
|
||||||
|
|
||||||
vec4 flw_vertexPos;
|
vec4 flw_vertexPos;
|
||||||
vec4 flw_vertexColor;
|
vec4 flw_vertexColor;
|
||||||
|
@ -17,7 +18,3 @@ void flw_transformBoundingSphere(in FlwInstance i, inout vec3 center, inout floa
|
||||||
|
|
||||||
// To be implemented by the material vertex shader.
|
// To be implemented by the material vertex shader.
|
||||||
void flw_materialVertex();
|
void flw_materialVertex();
|
||||||
|
|
||||||
// To be implemented by the context shader.
|
|
||||||
void flw_beginVertex();
|
|
||||||
void flw_endVertex();
|
|
||||||
|
|
Loading…
Reference in a new issue