- Use struct to separate light and ao fields
- Move light config TODO to impl
- Fix formatting in InstancerProvider docs
This commit is contained in:
Jozufozu 2024-08-01 12:14:14 -07:00
parent 3692dbdf3c
commit 3dc4cf0841
7 changed files with 32 additions and 18 deletions

View file

@ -17,13 +17,13 @@ public interface InstancerProvider {
* <h2>Render Order</h2>
* <p>In general, you can assume all instances in the same instancer will be rendered in a single draw call.
* Backends are free to optimize the ordering of draw calls to a certain extent, but utilities are provided to let
* you control the order of draw calls
* you exert control over the ordering.</p>
* <h4>Mesh Order</h4>
* <br>For one, Meshes within a Model are guaranteed to render in the order they appear in their containing list.
* <p>For one, Meshes within a Model are guaranteed to render in the order they appear in their containing list.
* This lets you e.g. preserve (or break!) vanilla's chunk RenderType order guarantees or control which Meshes of
* your Model render over others.
* your Model render over others.</p>
* <h4>Bias Order</h4>
* <br>The other method is via the {@code bias} parameter to this method. An instancer with a lower bias will have
* <p>The other method is via the {@code bias} parameter to this method. An instancer with a lower bias will have
* its instances draw BEFORE an instancer with a higher bias. This allows you to control the render order between
* your instances to e.g. create an "overlay" instance to selectively color or apply decals to another instance.</p>
*

View file

@ -120,6 +120,7 @@ public final class FlwPrograms {
.build(loader);
}
// TODO: Do not uber this component. Shader compile times are very high now
@Nullable
private static UberShaderComponent createLightComponent(SourceLoader loader) {
return UberShaderComponent.builder(Flywheel.rl("light"))

View file

@ -1,8 +1,11 @@
// TODO: Add config for light smoothness. Should work at a compile flag level
struct FlwLightAo {
vec2 light;
float ao;
};
/// Get the light at the given world position relative to flw_renderOrigin from the given normal.
/// This may be interpolated for smooth lighting.
bool flw_light(vec3 worldPos, vec3 normal, out vec3 light);
bool flw_light(vec3 worldPos, vec3 normal, out FlwLightAo light);
/// Fetches the light value at the given block position.
/// Returns false if the light for the given block is not available.

View file

@ -154,7 +154,7 @@ uint _flw_fetchSolid3x3x3(uint sectionOffset, ivec3 blockInSectionPos) {
#define _flw_index3x3x3(x, y, z) ((x) + (z) * 3u + (y) * 9u)
#define _flw_index3x3x3v(p) _flw_index3x3x3((p.x), (p.y), (p.z))
#define _flw_validCountToAO(validCount) (1. - (4. - (validCount)) * 0.2)
#define _flw_validCountToAo(validCount) (1. - (4. - (validCount)) * 0.2)
/// Calculate the light for a direction by averaging the light at the corners of the block.
///
@ -229,12 +229,13 @@ vec3 _flw_lightForDirection(uint[27] lights, vec3 interpolant, uvec3 c00, uvec3
// Normalize the light coords
light.xy *= 1. / 15.;
// Calculate the AO multiplier from the number of valid blocks
light.z = _flw_validCountToAO(light.z);
light.z = _flw_validCountToAo(light.z);
return light;
}
bool flw_light(vec3 worldPos, vec3 normal, out vec3 light) {
// TODO: Add config for light smoothness. Should work at a compile flag level
bool flw_light(vec3 worldPos, vec3 normal, out FlwLightAo light) {
// 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.
@ -255,7 +256,8 @@ bool flw_light(vec3 worldPos, vec3 normal, out vec3 light) {
if (solid == _FLW_COMPLETELY_SOLID) {
// No point in doing any work if the entire 3x3x3 volume around us is filled.
// Kinda rare but this may happen if our fragment is in the middle of a lot of tinted glass
light = vec3(0., 0., _flw_validCountToAO(0.));
light.light = vec2(0.);
light.ao = _flw_validCountToAo(0.);
return true;
}
@ -294,7 +296,10 @@ bool flw_light(vec3 worldPos, vec3 normal, out vec3 light) {
}
vec3 n2 = normal * normal;
light = lightX * n2.x + lightY * n2.y + lightZ * n2.z;
vec3 lightAo = lightX * n2.x + lightY * n2.y + lightZ * n2.z;
light.light = lightAo.xy;
light.ao = lightAo.z;
return true;
}

View file

@ -1,8 +1,8 @@
void flw_shaderLight() {
vec3 light;
FlwLightAo light;
if (flw_light(flw_vertexPos.xyz, flw_vertexNormal, light)) {
flw_fragLight = max(flw_fragLight, light.xy);
flw_fragLight = max(flw_fragLight, light.light);
flw_fragColor.rgb *= light.z;
flw_fragColor.rgb *= light.ao;
}
}

View file

@ -1,10 +1,10 @@
void flw_shaderLight() {
#ifdef FLW_EMBEDDED
vec3 light;
FlwLightAo light;
if (flw_light(flw_vertexPos.xyz, flw_vertexNormal, light)) {
flw_fragLight = max(flw_fragLight, light.xy);
flw_fragLight = max(flw_fragLight, light.light);
flw_fragColor *= light.z;
flw_fragColor.rgb *= light.ao;
}
#endif
}

View file

@ -1,6 +1,11 @@
struct FlwLightAo {
vec2 light;
float ao;
};
/// Get the light at the given world position.
/// This may be interpolated for smooth lighting.
bool flw_light(vec3 worldPos, vec3 normal, out vec3 light);
bool flw_light(vec3 worldPos, vec3 normal, out FlwLightAo light);
/// Fetches the light value at the given block position.
/// Returns false if the light for the given block is not available.