Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package foundry.veil.api.client.render.light.data;

import com.mojang.blaze3d.vertex.VertexConsumer;
import foundry.veil.api.client.color.Colorc;
import foundry.veil.api.client.editor.EditorAttributeProvider;
import foundry.veil.api.client.registry.LightTypeRegistry;
import foundry.veil.api.client.render.CullFrustum;
import foundry.veil.api.client.render.MatrixStack;
import foundry.veil.api.client.render.light.DDALightData;
import foundry.veil.api.client.render.light.InstancedLightData;
import foundry.veil.api.client.render.light.LightGuideProvider;
import imgui.ImGui;
import net.minecraft.client.Camera;
import net.minecraft.util.Mth;
Expand All @@ -20,7 +23,7 @@
*
* @since 4.4.0
*/
public class SpotLightData extends LightData implements InstancedLightData, DDALightData, EditorAttributeProvider {
public class SpotLightData extends LightData implements InstancedLightData, DDALightData, EditorAttributeProvider, LightGuideProvider {

private static final float MAX_ANGLE_SIZE = (float) (65535.0 / 2.0 / Math.PI);

Expand All @@ -33,6 +36,7 @@ public class SpotLightData extends LightData implements InstancedLightData, DDAL
protected float angle;
protected float distance;
protected boolean occlusionEnabled;
protected float inscattering;

public SpotLightData() {
this.matrix = new Matrix4d();
Expand All @@ -44,6 +48,7 @@ public SpotLightData() {
this.angle = (float) Math.toRadians(45);
this.distance = 1.0F;
this.occlusionEnabled = false;
this.inscattering = 0.0F;
}

@Override
Expand Down Expand Up @@ -111,6 +116,14 @@ public boolean isOcclusionEnabled() {
return this.occlusionEnabled;
}

/**
* @return The strength of the light's in-scattering effect.
* @since 4.4.0
*/
public float getInscatteringStrength() {
return this.inscattering;
}

/**
* Sets the size of the light's surface
*
Expand Down Expand Up @@ -150,6 +163,15 @@ public SpotLightData setOcclusionEnabled(boolean occlusionEnabled) {
return this;
}

/**
* @since 4.4.0
* */
public SpotLightData setInscatteringStrength(float inscattering) {
this.inscattering = inscattering;
this.markDirty();
return this;
}

@Override
public SpotLightData setColor(Vector3fc color) {
super.setColor(color);
Expand Down Expand Up @@ -195,6 +217,7 @@ public void store(ByteBuffer buffer) {
buffer.position(buffer.position() + 2); // Padding
buffer.putFloat(this.distance);
buffer.putFloat(this.occlusionEnabled ? 1.0F : 0.0F);
buffer.putFloat(this.inscattering);
}

@Override
Expand Down Expand Up @@ -235,6 +258,8 @@ public void renderImGuiAttributes() {
float[] editAngle = new float[]{this.angle};
float[] editDistance = new float[]{this.distance};

float[] editInscattering = new float[]{this.inscattering};

if (ImGui.sliderAngle("size", editSize, 0.1F, 180.0F, "%.1f")) {
this.setSize(editSize[0]);
}
Expand Down Expand Up @@ -294,5 +319,40 @@ public void renderImGuiAttributes() {
this.occlusionEnabled = !this.occlusionEnabled;
this.markDirty();
}

if (ImGui.dragScalar("In-scattering", editInscattering, 0.01F, 0.0F)) {
this.setInscatteringStrength(editInscattering[0]);
}
}

@Override
public void renderLightGuide(MatrixStack stack, VertexConsumer consumer) {
stack.matrixPush();

stack.translate(this.position.x, this.position.y, this.position.z);
Vector3f rot = this.orientation.getEulerAnglesXYZ(new Vector3f()).mul(-1);
stack.rotate(new Quaternionf().rotateX(rot.x).rotateLocalY(rot.y).rotateLocalZ(rot.z));

Matrix4f pose = stack.position();

float radius = this.distance * (float) Math.tan(this.size);

for (int i = -8; i < 25; i++) {
float x = (float) Math.sin(i / (float) 32 * Mth.TWO_PI) * radius;
float y = (float) Math.cos(i / (float) 32 * Mth.TWO_PI) * radius;
consumer.addVertex(pose, x, y, this.distance).setColor(this.color.red(), this.color.green(), this.color.blue(), this.color.alpha());
}

int spokes = 8;
for (int i = 0; i < spokes; i++) {
float theta = i / (float) spokes * Mth.TWO_PI;
float x = (float) Math.sin(theta) * radius;
float y = (float) Math.cos(theta) * radius;

consumer.addVertex(pose, 0, 0, 0).setColor(this.color.red(), this.color.green(), this.color.blue(), this.color.alpha());
consumer.addVertex(pose, x, y, this.distance).setColor(this.color.red(), this.color.green(), this.color.blue(), this.color.alpha());
}

stack.matrixPop();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"format": "POSITION_TEX",
"mode": "QUADS",
"bufferSize": "TRANSIENT",
"sort": false,
"affectsCrumbling": false,
"outline": false,
"layers": [
{
"type": "veil:shader",
"name": "veil:light/inscattering/spot"
},
{
"type": "minecraft:write_mask",
"depth": false
},
{
"type": "minecraft:depth_test",
"mode": "notequal"
},
{
"type": "minecraft:transparency",
"mode": "additive"
}
]
}
3 changes: 3 additions & 0 deletions wiki/Lights.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Area lights emit light from a quad, which can be rotated to face any direction.
### [Directional Lights](https://github.com/FoundryMC/Veil/blob/1.21/common/src/main/java/foundry/veil/api/client/render/light/data/DirectionalLightData.java)
Directional lights, unlike point and area lights, do not have a position, merely having a `direction` property. Directional lights simulate the sun, shadowing faces away from the light.

### [Spot Lights](https://github.com/FoundryMC/Veil/blob/1.21/common/src/main/java/foundry/veil/api/client/render/light/data/SpotLightData.java)
Spot lights emit light from a point, which can be rotated to face any direction. Spot lights have the same values as Area lights except it has one `size` value instead of separate width and height values.

## Light Renderers
Each light type additionally its own [`LightTypeRenderer`](https://github.com/FoundryMC/Veil/blob/1.21/common/src/main/java/foundry/veil/api/client/render/light/renderer/LightTypeRenderer.java). Each `LightTypeRenderer` is responsible for rendering all lights of its assigned types. Lights that have a position (like point and area lights) can extend the [`InstancedLightRenderer`](https://github.com/FoundryMC/Veil/blob/1.21/common/src/main/java/foundry/veil/api/client/render/light/renderer/InstancedLightRenderer.java) to have some methods built in.

Expand Down