mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-14 08:16:13 +01:00
Pixel perfect
- Do embedded lighting in the fragment shader - Fix light coord being saturated
This commit is contained in:
parent
51224d618f
commit
6cd30b8164
6 changed files with 102 additions and 97 deletions
|
@ -13,6 +13,10 @@ uniform sampler2D _flw_crumblingTex;
|
||||||
in vec2 _flw_crumblingTexCoord;
|
in vec2 _flw_crumblingTexCoord;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _FLW_EMBEDDED
|
||||||
|
bool _flw_embeddedLight(vec3 worldPos, out vec2 lightCoord);
|
||||||
|
#endif
|
||||||
|
|
||||||
flat in uint _flw_instanceID;
|
flat in uint _flw_instanceID;
|
||||||
|
|
||||||
out vec4 _flw_outputColor;
|
out vec4 _flw_outputColor;
|
||||||
|
@ -35,6 +39,13 @@ 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
|
||||||
|
|
|
@ -69,8 +69,6 @@ vec2 getCrumblingTexCoord() {
|
||||||
#ifdef _FLW_EMBEDDED
|
#ifdef _FLW_EMBEDDED
|
||||||
uniform mat4 _flw_modelMatrix;
|
uniform mat4 _flw_modelMatrix;
|
||||||
uniform mat3 _flw_normalMatrix;
|
uniform mat3 _flw_normalMatrix;
|
||||||
|
|
||||||
bool _flw_embeddedLight(vec3 worldPos, out vec2 lightCoord);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
flat out uint _flw_instanceID;
|
flat out uint _flw_instanceID;
|
||||||
|
@ -87,11 +85,6 @@ void _flw_main(in FlwInstance instance, in uint stableInstanceID) {
|
||||||
#ifdef _FLW_EMBEDDED
|
#ifdef _FLW_EMBEDDED
|
||||||
flw_vertexPos = _flw_modelMatrix * flw_vertexPos;
|
flw_vertexPos = _flw_modelMatrix * flw_vertexPos;
|
||||||
flw_vertexNormal = _flw_normalMatrix * flw_vertexNormal;
|
flw_vertexNormal = _flw_normalMatrix * flw_vertexNormal;
|
||||||
|
|
||||||
vec2 embeddedLight;
|
|
||||||
if (_flw_embeddedLight(flw_vertexPos.xyz, embeddedLight)) {
|
|
||||||
flw_vertexLight = max(flw_vertexLight, embeddedLight);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
flw_vertexNormal = normalize(flw_vertexNormal);
|
flw_vertexNormal = normalize(flw_vertexNormal);
|
||||||
|
|
|
@ -1,7 +1,92 @@
|
||||||
#include "flywheel:internal/common.frag"
|
#include "flywheel:internal/common.frag"
|
||||||
|
#include "flywheel:internal/indirect/buffer_bindings.glsl"
|
||||||
|
|
||||||
flat in uvec3 _flw_packedMaterial;
|
flat in uvec3 _flw_packedMaterial;
|
||||||
|
|
||||||
|
#ifdef _FLW_EMBEDDED
|
||||||
|
|
||||||
|
layout(std430, binding = _FLW_EMBEDDING_LUT_BINDING) restrict readonly buffer EmbeddingLut {
|
||||||
|
uint _flw_embeddingLut[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint _FLW_LIGHT_SECTION_SIZE_BYTES = 18 * 18 * 18;
|
||||||
|
const uint _FLW_LIGHT_SECTION_SIZE_INTS = _FLW_LIGHT_SECTION_SIZE_BYTES / 4;
|
||||||
|
|
||||||
|
layout(std430, binding = _FLW_EMBEDDING_LIGHT_BINDING) restrict readonly buffer LightSections {
|
||||||
|
uint _flw_lightSections[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Find the index for the next step in the LUT.
|
||||||
|
/// @param base The base index in the LUT, should point to the start of a coordinate span.
|
||||||
|
/// @param coord The coordinate to look for.
|
||||||
|
/// @param next Output. The index of the next step in the LUT.
|
||||||
|
/// @return true if the coordinate is not in the span.
|
||||||
|
bool _flw_nextLut(uint base, int coord, out uint next) {
|
||||||
|
// The base coordinate.
|
||||||
|
int start = int(_flw_embeddingLut[base]);
|
||||||
|
// The width of the coordinate span.
|
||||||
|
uint size = _flw_embeddingLut[base + 1];
|
||||||
|
|
||||||
|
// Index of the coordinate in the span.
|
||||||
|
int i = coord - start;
|
||||||
|
|
||||||
|
if (i < 0 || i >= size) {
|
||||||
|
// We missed.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
next = _flw_embeddingLut[base + 2 + i];
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _flw_chunkCoordToSectionIndex(ivec3 sectionPos, out uint index) {
|
||||||
|
uint y;
|
||||||
|
if (_flw_nextLut(0, sectionPos.x, y)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint z;
|
||||||
|
if (_flw_nextLut(y, sectionPos.y, z)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return _flw_nextLut(z, sectionPos.z, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 _flw_lightAt(uint sectionOffset, uvec3 blockInSectionPos) {
|
||||||
|
uint byteOffset = blockInSectionPos.x + blockInSectionPos.z * 18u + blockInSectionPos.y * 18u * 18u;
|
||||||
|
|
||||||
|
uint uintOffset = byteOffset >> 2u;
|
||||||
|
uint bitOffset = (byteOffset & 3u) << 3;
|
||||||
|
|
||||||
|
uint raw = _flw_lightSections[sectionOffset + uintOffset];
|
||||||
|
uint block = (raw >> bitOffset) & 0xFu;
|
||||||
|
uint sky = (raw >> (bitOffset + 4u)) & 0xFu;
|
||||||
|
|
||||||
|
return vec2(block / 15., sky / 15.);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _flw_embeddedLight(vec3 worldPos, out vec2 lightCoord) {
|
||||||
|
ivec3 blockPos = ivec3(floor(worldPos));
|
||||||
|
|
||||||
|
ivec3 sectionPos = blockPos >> 4;
|
||||||
|
uvec3 blockInSectionPos = (blockPos & 0xF) + 1;
|
||||||
|
|
||||||
|
uint lightSectionIndex;
|
||||||
|
if (_flw_chunkCoordToSectionIndex(sectionPos, lightSectionIndex)) {
|
||||||
|
// TODO: useful debug mode for this.
|
||||||
|
// flw_fragOverlay = ivec2(0, 3);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint sectionOffset = lightSectionIndex * _FLW_LIGHT_SECTION_SIZE_INTS;
|
||||||
|
|
||||||
|
lightCoord = _flw_lightAt(sectionOffset, blockInSectionPos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -11,90 +11,6 @@ layout(std430, binding = _FLW_DRAW_BUFFER_BINDING) restrict readonly buffer Draw
|
||||||
MeshDrawCommand _flw_drawCommands[];
|
MeshDrawCommand _flw_drawCommands[];
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _FLW_EMBEDDED
|
|
||||||
|
|
||||||
layout(std430, binding = _FLW_EMBEDDING_LUT_BINDING) restrict readonly buffer EmbeddingLut {
|
|
||||||
uint _flw_embeddingLut[];
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint _FLW_LIGHT_SECTION_SIZE_BYTES = 18 * 18 * 18;
|
|
||||||
const uint _FLW_LIGHT_SECTION_SIZE_INTS = _FLW_LIGHT_SECTION_SIZE_BYTES / 4;
|
|
||||||
|
|
||||||
layout(std430, binding = _FLW_EMBEDDING_LIGHT_BINDING) restrict readonly buffer LightSections {
|
|
||||||
uint _flw_lightSections[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Find the index for the next step in the LUT.
|
|
||||||
/// @param base The base index in the LUT, should point to the start of a coordinate span.
|
|
||||||
/// @param coord The coordinate to look for.
|
|
||||||
/// @param next Output. The index of the next step in the LUT.
|
|
||||||
/// @return true if the coordinate is not in the span.
|
|
||||||
bool _flw_nextLut(uint base, int coord, out uint next) {
|
|
||||||
// The base coordinate.
|
|
||||||
int start = int(_flw_embeddingLut[base]);
|
|
||||||
// The width of the coordinate span.
|
|
||||||
uint size = _flw_embeddingLut[base + 1];
|
|
||||||
|
|
||||||
// Index of the coordinate in the span.
|
|
||||||
int i = coord - start;
|
|
||||||
|
|
||||||
if (i < 0 || i >= size) {
|
|
||||||
// We missed.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
next = _flw_embeddingLut[base + 2 + i];
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _flw_chunkCoordToSectionIndex(ivec3 sectionPos, out uint index) {
|
|
||||||
uint y;
|
|
||||||
if (_flw_nextLut(0, sectionPos.x, y)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint z;
|
|
||||||
if (_flw_nextLut(y, sectionPos.y, z)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return _flw_nextLut(z, sectionPos.z, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 _flw_lightAt(uint sectionOffset, uvec3 blockInSectionPos) {
|
|
||||||
uint byteOffset = blockInSectionPos.x + blockInSectionPos.z * 18u + blockInSectionPos.y * 18u * 18u;
|
|
||||||
|
|
||||||
uint uintOffset = byteOffset >> 2u;
|
|
||||||
uint bitOffset = (byteOffset & 3u) << 3;
|
|
||||||
|
|
||||||
uint raw = _flw_lightSections[sectionOffset + uintOffset];
|
|
||||||
uint block = (raw >> bitOffset) & 0xFu;
|
|
||||||
uint sky = (raw >> (bitOffset + 4u)) & 0xFu;
|
|
||||||
|
|
||||||
return vec2(block, sky);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _flw_embeddedLight(vec3 worldPos, out vec2 lightCoord) {
|
|
||||||
ivec3 blockPos = ivec3(floor(worldPos));
|
|
||||||
|
|
||||||
ivec3 sectionPos = blockPos >> 4;
|
|
||||||
uvec3 blockInSectionPos = (blockPos & 0xF) + 1;
|
|
||||||
|
|
||||||
uint lightSectionIndex;
|
|
||||||
if (_flw_chunkCoordToSectionIndex(sectionPos, lightSectionIndex)) {
|
|
||||||
// TODO: useful debug mode for this.
|
|
||||||
// flw_vertexOverlay = ivec2(0, 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint sectionOffset = lightSectionIndex * _FLW_LIGHT_SECTION_SIZE_INTS;
|
|
||||||
|
|
||||||
lightCoord = _flw_lightAt(sectionOffset, blockInSectionPos);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uniform uint _flw_baseDraw;
|
uniform uint _flw_baseDraw;
|
||||||
|
|
||||||
flat out uvec3 _flw_packedMaterial;
|
flat out uvec3 _flw_packedMaterial;
|
||||||
|
|
|
@ -2,6 +2,12 @@
|
||||||
|
|
||||||
uniform uvec4 _flw_packedMaterial;
|
uniform uvec4 _flw_packedMaterial;
|
||||||
|
|
||||||
|
#ifdef _FLW_EMBEDDED
|
||||||
|
bool _flw_embeddedLight(vec3 worldPos, out vec2 lightCoord) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -4,12 +4,6 @@
|
||||||
uniform uvec4 _flw_packedMaterial;
|
uniform uvec4 _flw_packedMaterial;
|
||||||
uniform int _flw_baseInstance = 0;
|
uniform int _flw_baseInstance = 0;
|
||||||
|
|
||||||
#ifdef _FLW_EMBEDDED
|
|
||||||
bool _flw_embeddedLight(vec3 worldPos, out vec2 lightCoord) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
_flw_uberMaterialVertexIndex = _flw_packedMaterial.x;
|
_flw_uberMaterialVertexIndex = _flw_packedMaterial.x;
|
||||||
_flw_unpackMaterialProperties(_flw_packedMaterial.w, flw_material);
|
_flw_unpackMaterialProperties(_flw_packedMaterial.w, flw_material);
|
||||||
|
|
Loading…
Reference in a new issue