Skip to content

Commit

Permalink
Rewrite ripples and glow ripples
Browse files Browse the repository at this point in the history
  • Loading branch information
doctor4t committed Jan 1, 2025
1 parent 5f8a97e commit dd34ad0
Show file tree
Hide file tree
Showing 11 changed files with 185 additions and 105 deletions.
5 changes: 5 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
------------------------------------------------------
Effective 2.4.2 (Alpha) - 1.21.1
------------------------------------------------------
- Rewrote ripples and glow ripples

------------------------------------------------------
Effective 2.4.1 (Alpha) - 1.21.1
------------------------------------------------------
Expand Down
5 changes: 0 additions & 5 deletions src/client/java/org/ladysnake/effective/core/Effective.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,6 @@ public void onInitializeClient() {
EffectiveParticles.initialize();

// Particles
// WATERFALL_CLOUD = Registry.register(Registries.PARTICLE_TYPE, Effective.id("waterfall_cloud"), WATERFALL_CLOUD);
// ParticleFactoryRegistry.getInstance().register(WATERFALL_CLOUD, WaterfallCloudParticle.Factory::new);
// MIST = Registry.register(Registries.PARTICLE_TYPE, Effective.id("mist"), MIST);
// ParticleFactoryRegistry.getInstance().register(MIST, MistParticleType.Factory::new);

CHORUS_PETAL = Registry.register(Registries.PARTICLE_TYPE, Effective.id("chorus_petal"), FabricParticleTypes.simple(true));
ParticleFactoryRegistry.getInstance().register(CHORUS_PETAL, ChorusPetalParticle.Factory::new);
EYES = Registry.register(Registries.PARTICLE_TYPE, Effective.id("eyes"), FabricParticleTypes.simple(true));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public interface EffectiveParticles {
SimpleParticleType GLOW_RIPPLE = create("glow_ripple", FabricParticleTypes.simple(true));
SimpleParticleType BUBBLE = create("bubble", FabricParticleTypes.simple(true));
SimpleParticleType END_BUBBLE = create("end_bubble", FabricParticleTypes.simple(true));
SimpleParticleType WATERFALL_CLOUD = create("waterfall_cloud", FabricParticleTypes.simple(true));
SimpleParticleType MIST = create("mist", FabricParticleTypes.simple(true));

static void initialize() {
PARTICLES.keySet().forEach(particle -> Registry.register(Registries.PARTICLE_TYPE, PARTICLES.get(particle), particle));
Expand All @@ -47,5 +49,7 @@ private static void registerFactories() {
ParticleFactoryRegistry.getInstance().register(GLOW_RIPPLE, GlowRippleParticle.Factory::new);
ParticleFactoryRegistry.getInstance().register(BUBBLE, BubbleParticle.Factory::new);
ParticleFactoryRegistry.getInstance().register(END_BUBBLE, EndBubbleParticle.Factory::new);
ParticleFactoryRegistry.getInstance().register(WATERFALL_CLOUD, CascadeParticle.Factory::new);
ParticleFactoryRegistry.getInstance().register(MIST, MistParticle.Factory::new);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,29 @@
import net.minecraft.client.world.ClientWorld;
import net.minecraft.particle.SimpleParticleType;
import net.minecraft.util.math.BlockPos;
import org.ladysnake.effective.core.Effective;

public class WaterfallCloudParticle extends SpriteBillboardParticle {
public class CascadeParticle extends SpriteBillboardParticle {
private final SpriteProvider spriteProvider;

public WaterfallCloudParticle(ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ, SpriteProvider spriteProvider) {
public CascadeParticle(ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ, SpriteProvider spriteProvider) {
super(world, x, y, z, velocityX, velocityY, velocityZ);

this.velocityX = velocityX;
this.velocityY = velocityY;
this.velocityZ = velocityZ;

this.spriteProvider = spriteProvider;
this.maxAge = 500;
this.scale = .05f;
this.maxAge = 10;
this.scale = .5f;

this.setSpriteForAge(spriteProvider);

// WorldParticleBuilder.create(Effective.WATERFALL_CLOUD)
// .enableForcedSpawn()
// .enableNoClip()
// .setMotion((world.getRandom().nextFloat() * waterfall.strength()) / 10f * Math.signum(offsetX), (world.getRandom().nextFloat() * waterfall.strength()) / 10f, (world.getRandom().nextFloat() * waterfall.strength()) / 10f * Math.signum(offsetZ))
// .spawn(world, blockPos.getX() + .5 + offsetX, blockPos.getY() + world.getRandom().nextFloat(), blockPos.getZ() + .5 + offsetZ);
}

public ParticleTextureSheet getType() {
Expand Down Expand Up @@ -68,7 +75,7 @@ public Factory(SpriteProvider spriteProvider) {

@Override
public Particle createParticle(SimpleParticleType parameters, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) {
return new WaterfallCloudParticle(world, x, y, z, velocityX, velocityY, velocityZ, this.spriteProvider);
return new CascadeParticle(world, x, y, z, velocityX, velocityY, velocityZ, this.spriteProvider);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,57 +18,22 @@
import org.joml.Vector3f;

public class GlowRippleParticle extends RippleParticle {
public float redAndGreen = random.nextFloat() / 5f;
public float blue = 1.0f;
public BlockPos pos;

private GlowRippleParticle(ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ, SpriteProvider spriteProvider) {
super(world, x, y, z, velocityX, velocityY, velocityZ, spriteProvider);

pos = BlockPos.ofFloored(x, y, z);
float randFloat = random.nextFloat() / 5f;
float redAndGreenRender = Math.min(1, randFloat + world.getLightLevel(LightType.BLOCK, pos) / 15f);
this.red = redAndGreenRender;
this.green = redAndGreenRender;
this.blue = 1.0f;
}

@Override
public void buildGeometry(VertexConsumer vertexConsumer, Camera camera, float tickDelta) {
this.setSpriteForAge(spriteProvider);

Vec3d vec3d = camera.getPos();
float f = (float) (MathHelper.lerp(tickDelta, this.prevPosX, this.x) - vec3d.getX());
float g = (float) (MathHelper.lerp(tickDelta, this.prevPosY, this.y) - vec3d.getY());
float h = (float) (MathHelper.lerp(tickDelta, this.prevPosZ, this.z) - vec3d.getZ());
Quaternionf quaternion2;
if (this.angle == 0.0F) {
quaternion2 = camera.getRotation();
} else {
quaternion2 = new Quaternionf(camera.getRotation());
float i = MathHelper.lerp(tickDelta, this.prevAngle, this.angle);
quaternion2.rotateZ(i);
}

Vector3f Vec3f = new Vector3f(-1.0F, -1.0F, 0.0F);
Vec3f.rotate(quaternion2);
Vector3f[] Vec3fs = new Vector3f[]{new Vector3f(-1.0F, -1.0F, 0.0F), new Vector3f(-1.0F, 1.0F, 0.0F), new Vector3f(1.0F, 1.0F, 0.0F), new Vector3f(1.0F, -1.0F, 0.0F)};
float j = this.getSize(tickDelta);

for (int k = 0; k < 4; ++k) {
Vector3f Vec3f2 = Vec3fs[k];
Vec3f2.rotate(new Quaternionf().rotateXYZ((float) Math.toRadians(90f), 0f, 0f));
Vec3f2.mul(j);
Vec3f2.add(f, g, h);
}

float minU = this.getMinU();
float maxU = this.getMaxU();
float minV = this.getMinV();
float maxV = this.getMaxV();

int l = LightmapTextureManager.MAX_LIGHT_COORDINATE;
float redAndGreenRender = Math.min(1, redAndGreen + world.getLightLevel(LightType.BLOCK, pos) / 15f);

vertexConsumer.vertex(Vec3fs[0].x(), Vec3fs[0].y(), Vec3fs[0].z()).texture(maxU, maxV).color(redAndGreenRender, redAndGreenRender, blue, alpha).light(l);
vertexConsumer.vertex(Vec3fs[1].x(), Vec3fs[1].y(), Vec3fs[1].z()).texture(maxU, minV).color(redAndGreenRender, redAndGreenRender, blue, alpha).light(l);
vertexConsumer.vertex(Vec3fs[2].x(), Vec3fs[2].y(), Vec3fs[2].z()).texture(minU, minV).color(redAndGreenRender, redAndGreenRender, blue, alpha).light(l);
vertexConsumer.vertex(Vec3fs[3].x(), Vec3fs[3].y(), Vec3fs[3].z()).texture(minU, maxV).color(redAndGreenRender, redAndGreenRender, blue, alpha).light(l);
protected int getBrightness(float tint) {
return LightmapTextureManager.MAX_LIGHT_COORDINATE;
}

@Environment(EnvType.CLIENT)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,38 @@

import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.particle.ParticleFactory;
import net.minecraft.client.particle.ParticleTextureSheet;
import net.minecraft.client.particle.SpriteBillboardParticle;
import net.minecraft.client.particle.*;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.particle.SimpleParticleType;
import org.ladysnake.effective.core.Effective;

public class MistParticle extends SpriteBillboardParticle {
protected MistParticle(ClientWorld clientWorld, double d, double e, double f) {
super(clientWorld, d, e, f);
public MistParticle(ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ, SpriteProvider spriteProvider) {
super(world, x, y, z, velocityX, velocityY, velocityZ);

this.velocityX = velocityX;
this.velocityY = velocityY;
this.velocityZ = velocityZ;

this.setSpriteForAge(spriteProvider);


// WorldParticleBuilder.create(Effective.MIST)
// .enableForcedSpawn()
// .setSpinData(SpinParticleData.create((world.random.nextFloat() - world.random.nextFloat()) / 20f).build())
// .setScaleData(GenericParticleData.create(10f + world.random.nextFloat() * 5f).build())
// .setTransparencyData(
// GenericParticleData.create(0.001f, 0.1f, 0f)
// .setEasing(Easing.EXPO_OUT, Easing.SINE_OUT)
// .build()
// )
// .setLifetime(300)
// .enableNoClip()
// .setNaturalLighting()
// .setRenderType(LodestoneWorldParticleRenderType.TRANSPARENT.withDepthFade())
// .setColorData(ColorParticleData.create(waterfall.mistColor(), waterfall.mistColor()).build())
// .setMotion(world.getRandom().nextFloat() / 15f * Math.signum(offsetX), world.getRandom().nextGaussian() / 25f, world.getRandom().nextFloat() / 15f * Math.signum(offsetZ))
// .spawn(world, blockPos.getX() + .5f, blockPos.getY() + .5f, blockPos.getZ() + .5f);
}

@Override
Expand All @@ -21,9 +43,15 @@ public ParticleTextureSheet getType() {

@Environment(EnvType.CLIENT)
public static class Factory implements ParticleFactory<SimpleParticleType> {
private final SpriteProvider spriteProvider;

public Factory(SpriteProvider spriteProvider) {
this.spriteProvider = spriteProvider;
}

@Override
public Particle createParticle(SimpleParticleType parameters, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) {
return new MistParticle(world, x, y, z);
return new MistParticle(world, x, y, z, velocityX, velocityY, velocityZ, this.spriteProvider);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//package org.ladysnake.effective.core.render.particle;
//
//import com.mojang.blaze3d.systems.RenderSystem;
//import net.minecraft.client.MinecraftClient;
//import net.minecraft.client.particle.ParticleTextureSheet;
//import net.minecraft.client.render.BufferBuilder;
//import net.minecraft.client.render.Tessellator;
//import net.minecraft.client.texture.SpriteAtlasTexture;
//import net.minecraft.client.texture.TextureManager;
//import org.jetbrains.annotations.NotNull;
//import org.jetbrains.annotations.Nullable;
//
//public class SoftParticleRenderType implements ParticleTextureSheet {
// @NotNull
// public static final SoftParticleRenderType SOFT_PARTICLE = new SoftParticleRenderType();
//
// @Override
// public @Nullable BufferBuilder begin(Tessellator tessellator, TextureManager textureManager) {
// final MinecraftClient minecraft = MinecraftClient.getInstance();
//
// RenderSystem.setShader(() -> softParticle);
//
// // Disallow soft particles from writing to the depth buffer
// RenderSystem.depthMask(false);
//
// // Set `Sampler0` to the particle atlas
// // noinspection deprecation
// RenderSystem.setShaderTexture(0, SpriteAtlasTexture.PARTICLE_ATLAS_TEXTURE);
//
// RenderSystem.enableBlend();
// RenderSystem.defaultBlendFunc();
//
// // Set the sampler for the depth texture
// softParticle.setSampler("DiffuseDepthSampler", minecraft.getMainRenderTarget().getDepthTextureId());
//
// return tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.PARTICLE);
// }
//}
Original file line number Diff line number Diff line change
Expand Up @@ -148,53 +148,26 @@ private static Waterfall getWaterfallAt(BlockView world, BlockPos pos, FluidStat
}

public static void addWaterfallCloud(World world, Waterfall waterfall) {
// boolean isGlowingWater = EffectiveUtils.isGlowingWater(world, waterfall.blockPos());
// Color glowingWaterColor = EffectiveUtils.getGlowingWaterColor(world, waterfall.blockPos());
// Color white = new Color(0xFFFFFF);
// BlockPos blockPos = waterfall.blockPos();
//
// for (int i = 0; i < EffectiveConfig.cascadeCloudDensity; i++) {
// if (waterfall != null) {
// double offsetX = world.getRandom().nextGaussian() / 5f;
// double offsetZ = world.getRandom().nextGaussian() / 5f;
//
// WorldParticleBuilder.create(Effective.WATERFALL_CLOUD)
// .enableForcedSpawn()
// .enableNoClip()
// .setLightLevel(isGlowingWater ? LightmapTextureManager.MAX_LIGHT_COORDINATE : -1)
// .setScaleData(GenericParticleData.create((0.4f + waterfall.strength() * world.random.nextFloat())).build())
// .setColorData(ColorParticleData.create(isGlowingWater ? glowingWaterColor : white, isGlowingWater ? glowingWaterColor : white).build())
// .setLifetime(10)
// .setRenderType(LodestoneWorldParticleRenderType.TRANSPARENT.withDepthFade())
// .setMotion((world.getRandom().nextFloat() * waterfall.strength()) / 10f * Math.signum(offsetX), (world.getRandom().nextFloat() * waterfall.strength()) / 10f, (world.getRandom().nextFloat() * waterfall.strength()) / 10f * Math.signum(offsetZ))
// .spawn(world, blockPos.getX() + .5 + offsetX, blockPos.getY() + world.getRandom().nextFloat(), blockPos.getZ() + .5 + offsetZ);
// }
// }
//
// if (EffectiveConfig.cascadeMistDensity > 0f && waterfall.strength() >= 1.6f) {
// if ((world.random.nextFloat() * 100f) <= EffectiveConfig.cascadeMistDensity) {
// double offsetX = world.getRandom().nextGaussian() / 5f;
// double offsetZ = world.getRandom().nextGaussian() / 5f;
//
// WorldParticleBuilder.create(Effective.MIST)
// .enableForcedSpawn()
// .setSpinData(SpinParticleData.create((world.random.nextFloat() - world.random.nextFloat()) / 20f).build())
// .setScaleData(GenericParticleData.create(10f + world.random.nextFloat() * 5f).build())
// .setTransparencyData(
// GenericParticleData.create(0.001f, 0.1f, 0f)
// .setEasing(Easing.EXPO_OUT, Easing.SINE_OUT)
// .build()
// )
// .setLifetime(300)
// .enableNoClip()
// .setNaturalLighting()
// .setRenderType(LodestoneWorldParticleRenderType.TRANSPARENT.withDepthFade())
// .setColorData(ColorParticleData.create(waterfall.mistColor(), waterfall.mistColor()).build())
// .setMotion(world.getRandom().nextFloat() / 15f * Math.signum(offsetX), world.getRandom().nextGaussian() / 25f, world.getRandom().nextFloat() / 15f * Math.signum(offsetZ))
// .spawn(world, blockPos.getX() + .5f, blockPos.getY() + .5f, blockPos.getZ() + .5f);
// }
// }
boolean isGlowingWater = EffectiveUtils.isGlowingWater(world, waterfall.blockPos());
Color glowingWaterColor = EffectiveUtils.getGlowingWaterColor(world, waterfall.blockPos());
Color white = new Color(0xFFFFFF);
BlockPos blockPos = waterfall.blockPos();

for (int i = 0; i < EffectiveConfig.cascadeCloudDensity; i++) {
if (waterfall != null) {
double offsetX = world.getRandom().nextGaussian() / 5f;
double offsetZ = world.getRandom().nextGaussian() / 5f;

}
}

if (EffectiveConfig.cascadeMistDensity > 0f && waterfall.strength() >= 1.6f) {
if ((world.random.nextFloat() * 100f) <= EffectiveConfig.cascadeMistDensity) {
double offsetX = world.getRandom().nextGaussian() / 5f;
double offsetZ = world.getRandom().nextGaussian() / 5f;

}
}
}

public static void scheduleParticleTick(Waterfall waterfall, int ticks) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#version 150

#moj_import <fog.glsl>

uniform sampler2D Sampler0;
uniform sampler2D Sampler2;
uniform sampler2D DiffuseDepthSampler;

uniform mat4 ProjMat;
uniform vec4 ColorModulator;
uniform float FogStart;
uniform float FogEnd;
uniform vec4 FogColor;
uniform vec2 ScreenSize;

in float vertexDistance;
in vec2 texCoord0;
in vec4 vertexColor;

out vec4 fragColor;

const vec3 normal = vec3(0.0, 0.0, 1.0);

float linearizeDepth(float depthSample) {
// Same calculation mojang does, to linearize depths using the projection matrix values
return -ProjMat[3].z / (depthSample * -2.0 + 1.0 - ProjMat[2].z);
}

void main() {
vec4 color = texture(Sampler0, texCoord0) * vertexColor * ColorModulator;
if (color.a < 0.001) {
discard;
}

// Depth only occupies the red channel, we don't care about the other two
float depthSample = texture(DiffuseDepthSampler, gl_FragCoord.xy / ScreenSize).r;

float depth = linearizeDepth(depthSample);
float particleDepth = linearizeDepth(gl_FragCoord.z);

// Linearly blends from 1x to 0x opacity at 1+ meter depth difference to 0 depth difference
float opacity = color.a * min(depth - particleDepth, 1.0);

fragColor = linear_fog(vec4(color.rgb, opacity), vertexDistance, FogStart, FogEnd, FogColor);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"vertex": "particle",
"fragment": "effective:soft_particle",
"samplers": [
{ "name": "Sampler0" },
{ "name": "Sampler2" },
{ "name": "DiffuseDepthSampler" }
],
"uniforms": [
{ "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
{ "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
{ "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] },
{ "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] },
{ "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] },
{ "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "FogShape", "type": "int", "count": 1, "values": [ 0 ] },
{ "name": "ScreenSize", "type": "float", "count": 2, "values": [ 1.0, 1.0 ] }
]
}
1 change: 1 addition & 0 deletions src/client/resources/effective.accesswidener
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ accessible field net/minecraft/block/entity/EnderChestBlockEntity lidAnimator Ln
accessible field net/minecraft/block/entity/EnderChestBlockEntity stateManager Lnet/minecraft/block/entity/ViewerCountManager;
accessible field net/minecraft/client/sound/SoundManager soundSystem Lnet/minecraft/client/sound/SoundSystem;
accessible field net/minecraft/client/sound/SoundSystem tickingSounds Ljava/util/List;
accessible field net/minecraft/client/render/GameRenderer programs Ljava/util/Map;

0 comments on commit dd34ad0

Please sign in to comment.