FogRenderer.java

net.minecraft.client.renderer.fog.FogRenderer

信息

  • 全限定名:net.minecraft.client.renderer.fog.FogRenderer
  • 类型:public class
  • 包:net.minecraft.client.renderer.fog
  • 源码路径:src/main/java/net/minecraft/client/renderer/fog/FogRenderer.java
  • 起始行号:L37
  • 实现:AutoCloseable
  • 职责:

    TODO

字段/常量

  • FOG_UBO_SIZE

    • 类型: int
    • 修饰符: public static final
    • 源码定位: L38
    • 说明:

      TODO

  • FOG_ENVIRONMENTS

    • 类型: List<FogEnvironment>
    • 修饰符: private static final
    • 源码定位: L39
    • 说明:

      TODO

  • fogEnabled

    • 类型: boolean
    • 修饰符: private static
    • 源码定位: L47
    • 说明:

      TODO

  • emptyBuffer

    • 类型: GpuBuffer
    • 修饰符: private final
    • 源码定位: L48
    • 说明:

      TODO

  • regularBuffer

    • 类型: MappableRingBuffer
    • 修饰符: private final
    • 源码定位: L49
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.renderer.fog.FogRenderer.FogMode
    • 类型: enum
    • 修饰符: public static
    • 源码定位: L227
    • 说明:

      TODO

构造器

public FogRenderer() @ L51

  • 构造器名:FogRenderer
  • 源码定位:L51
  • 修饰符:public

参数:

说明:

TODO

方法

下面的方法块按源码顺序生成。

public void close() @ L66

  • 方法名:close
  • 源码定位:L66
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void endFrame() @ L72

  • 方法名:endFrame
  • 源码定位:L72
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public GpuBufferSlice getBuffer(FogRenderer.FogMode mode) @ L76

  • 方法名:getBuffer
  • 源码定位:L76
  • 返回类型:GpuBufferSlice
  • 修饰符:public

参数:

  • mode: FogRenderer.FogMode

说明:

TODO

private void computeFogColor(Camera camera, float partialTicks, ClientLevel level, int renderDistance, float darkenWorldAmount, Vector4f dest) @ L87

  • 方法名:computeFogColor
  • 源码定位:L87
  • 返回类型:void
  • 修饰符:private

参数:

  • camera: Camera
  • partialTicks: float
  • level: ClientLevel
  • renderDistance: int
  • darkenWorldAmount: float
  • dest: Vector4f

说明:

TODO

public static boolean toggleFog() @ L158

  • 方法名:toggleFog
  • 源码定位:L158
  • 返回类型:boolean
  • 修饰符:public static

参数:

说明:

TODO

public FogData setupFog(Camera camera, int renderDistanceInChunks, DeltaTracker deltaTracker, float darkenWorldAmount, ClientLevel level) @ L162

  • 方法名:setupFog
  • 源码定位:L162
  • 返回类型:FogData
  • 修饰符:public

参数:

  • camera: Camera
  • renderDistanceInChunks: int
  • deltaTracker: DeltaTracker
  • darkenWorldAmount: float
  • level: ClientLevel

说明:

TODO

public void updateBuffer(FogData fog) @ L183

  • 方法名:updateBuffer
  • 源码定位:L183
  • 返回类型:void
  • 修饰符:public

参数:

  • fog: FogData

说明:

TODO

private FogType getFogType(Camera camera) @ L199

  • 方法名:getFogType
  • 源码定位:L199
  • 返回类型:FogType
  • 修饰符:private

参数:

  • camera: Camera

说明:

TODO

private void updateBuffer(ByteBuffer byteBuffer, int offset, Vector4f fogColor, float environmentalStart, float environmentalEnd, float renderDistanceStart, float renderDistanceEnd, float skyEnd, float endClouds) @ L204

  • 方法名:updateBuffer
  • 源码定位:L204
  • 返回类型:void
  • 修饰符:private

参数:

  • byteBuffer: ByteBuffer
  • offset: int
  • fogColor: Vector4f
  • environmentalStart: float
  • environmentalEnd: float
  • renderDistanceStart: float
  • renderDistanceEnd: float
  • skyEnd: float
  • endClouds: float

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class FogRenderer implements AutoCloseable {
    public static final int FOG_UBO_SIZE = new Std140SizeCalculator().putVec4().putFloat().putFloat().putFloat().putFloat().putFloat().putFloat().get();
    private static final List<FogEnvironment> FOG_ENVIRONMENTS = Lists.newArrayList(
        new LavaFogEnvironment(),
        new PowderedSnowFogEnvironment(),
        new BlindnessFogEnvironment(),
        new DarknessFogEnvironment(),
        new WaterFogEnvironment(),
        new AtmosphericFogEnvironment()
    );
    private static boolean fogEnabled = true;
    private final GpuBuffer emptyBuffer;
    private final MappableRingBuffer regularBuffer;
 
    public FogRenderer() {
        GpuDevice device = RenderSystem.getDevice();
        this.regularBuffer = new MappableRingBuffer(() -> "Fog UBO", 130, FOG_UBO_SIZE);
 
        try (MemoryStack stack = MemoryStack.stackPush()) {
            ByteBuffer buffer = stack.malloc(FOG_UBO_SIZE);
            this.updateBuffer(
                buffer, 0, new Vector4f(0.0F), Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE
            );
            this.emptyBuffer = device.createBuffer(() -> "Empty fog", 128, buffer.flip());
        }
 
        RenderSystem.setShaderFog(this.getBuffer(FogRenderer.FogMode.NONE));
    }
 
    @Override
    public void close() {
        this.emptyBuffer.close();
        this.regularBuffer.close();
    }
 
    public void endFrame() {
        this.regularBuffer.rotate();
    }
 
    public GpuBufferSlice getBuffer(FogRenderer.FogMode mode) {
        if (!fogEnabled) {
            return this.emptyBuffer.slice(0L, FOG_UBO_SIZE);
        } else {
            return switch (mode) {
                case NONE -> this.emptyBuffer.slice(0L, FOG_UBO_SIZE);
                case WORLD -> this.regularBuffer.currentBuffer().slice(0L, FOG_UBO_SIZE);
            };
        }
    }
 
    private void computeFogColor(Camera camera, float partialTicks, ClientLevel level, int renderDistance, float darkenWorldAmount, Vector4f dest) {
        FogType fogType = this.getFogType(camera);
        Entity entity = camera.entity();
        FogEnvironment colorSourceEnvironment = null;
        FogEnvironment darknessModifyingEnvironment = null;
 
        for (FogEnvironment fogEnvironment : FOG_ENVIRONMENTS) {
            if (fogEnvironment.isApplicable(fogType, entity)) {
                if (colorSourceEnvironment == null && fogEnvironment.providesColor()) {
                    colorSourceEnvironment = fogEnvironment;
                }
 
                if (darknessModifyingEnvironment == null && fogEnvironment.modifiesDarkness()) {
                    darknessModifyingEnvironment = fogEnvironment;
                }
            }
        }
 
        if (colorSourceEnvironment == null) {
            throw new IllegalStateException("No color source environment found");
        } else {
            int color = colorSourceEnvironment.getBaseColor(level, camera, renderDistance, partialTicks);
            float voidDarknessOnsetRange = level.getLevelData().voidDarknessOnsetRange();
            float darkness = Mth.clamp((voidDarknessOnsetRange + level.getMinY() - (float)camera.position().y) / voidDarknessOnsetRange, 0.0F, 1.0F);
            if (darknessModifyingEnvironment != null) {
                LivingEntity livingEntity = (LivingEntity)entity;
                darkness = darknessModifyingEnvironment.getModifiedDarkness(livingEntity, darkness, partialTicks);
            }
 
            float fogRed = ARGB.redFloat(color);
            float fogGreen = ARGB.greenFloat(color);
            float fogBlue = ARGB.blueFloat(color);
            if (darkness > 0.0F && fogType != FogType.LAVA && fogType != FogType.POWDER_SNOW) {
                float brightness = Mth.square(1.0F - darkness);
                fogRed *= brightness;
                fogGreen *= brightness;
                fogBlue *= brightness;
            }
 
            if (darkenWorldAmount > 0.0F) {
                fogRed = Mth.lerp(darkenWorldAmount, fogRed, fogRed * 0.7F);
                fogGreen = Mth.lerp(darkenWorldAmount, fogGreen, fogGreen * 0.6F);
                fogBlue = Mth.lerp(darkenWorldAmount, fogBlue, fogBlue * 0.6F);
            }
 
            float brightenFactor;
            if (fogType == FogType.WATER) {
                if (entity instanceof LocalPlayer) {
                    brightenFactor = ((LocalPlayer)entity).getWaterVision();
                } else {
                    brightenFactor = 1.0F;
                }
            } else if (entity instanceof LivingEntity livingEntity
                && livingEntity.hasEffect(MobEffects.NIGHT_VISION)
                && !livingEntity.hasEffect(MobEffects.DARKNESS)) {
                brightenFactor = GameRenderer.getNightVisionScale(livingEntity, partialTicks);
            } else {
                brightenFactor = 0.0F;
            }
 
            if (fogRed != 0.0F && fogGreen != 0.0F && fogBlue != 0.0F) {
                float targetScale = 1.0F / Math.max(fogRed, Math.max(fogGreen, fogBlue));
                fogRed = Mth.lerp(brightenFactor, fogRed, fogRed * targetScale);
                fogGreen = Mth.lerp(brightenFactor, fogGreen, fogGreen * targetScale);
                fogBlue = Mth.lerp(brightenFactor, fogBlue, fogBlue * targetScale);
            }
 
            dest.set(fogRed, fogGreen, fogBlue, 1.0F);
        }
    }
 
    public static boolean toggleFog() {
        return fogEnabled = !fogEnabled;
    }
 
    public FogData setupFog(Camera camera, int renderDistanceInChunks, DeltaTracker deltaTracker, float darkenWorldAmount, ClientLevel level) {
        float partialTickTime = deltaTracker.getGameTimeDeltaPartialTick(false);
        float renderDistanceInBlocks = renderDistanceInChunks * 16;
        FogType fogType = this.getFogType(camera);
        Entity entity = camera.entity();
        FogData fog = new FogData();
        this.computeFogColor(camera, partialTickTime, level, renderDistanceInChunks, darkenWorldAmount, fog.color);
 
        for (FogEnvironment fogEnvironment : FOG_ENVIRONMENTS) {
            if (fogEnvironment.isApplicable(fogType, entity)) {
                fogEnvironment.setupFog(fog, camera, level, renderDistanceInBlocks, deltaTracker);
                break;
            }
        }
 
        float renderDistanceFogSpan = Mth.clamp(renderDistanceInBlocks / 10.0F, 4.0F, 64.0F);
        fog.renderDistanceStart = renderDistanceInBlocks - renderDistanceFogSpan;
        fog.renderDistanceEnd = renderDistanceInBlocks;
        return fog;
    }
 
    public void updateBuffer(FogData fog) {
        try (GpuBuffer.MappedView view = RenderSystem.getDevice().createCommandEncoder().mapBuffer(this.regularBuffer.currentBuffer(), false, true)) {
            this.updateBuffer(
                view.data(),
                0,
                fog.color,
                fog.environmentalStart,
                fog.environmentalEnd,
                fog.renderDistanceStart,
                fog.renderDistanceEnd,
                fog.skyEnd,
                fog.cloudEnd
            );
        }
    }
 
    private FogType getFogType(Camera camera) {
        FogType blockFogType = camera.getFluidInCamera();
        return blockFogType == FogType.NONE ? FogType.ATMOSPHERIC : blockFogType;
    }
 
    private void updateBuffer(
        ByteBuffer byteBuffer,
        int offset,
        Vector4f fogColor,
        float environmentalStart,
        float environmentalEnd,
        float renderDistanceStart,
        float renderDistanceEnd,
        float skyEnd,
        float endClouds
    ) {
        byteBuffer.position(offset);
        Std140Builder.intoBuffer(byteBuffer)
            .putVec4(fogColor)
            .putFloat(environmentalStart)
            .putFloat(environmentalEnd)
            .putFloat(renderDistanceStart)
            .putFloat(renderDistanceEnd)
            .putFloat(skyEnd)
            .putFloat(endClouds);
    }
 
    @OnlyIn(Dist.CLIENT)
    public static enum FogMode {
        NONE,
        WORLD;
    }
}

引用的其他类

  • GpuBuffer

    • 引用位置: 字段
  • GpuBufferSlice

    • 引用位置: 返回值
  • Std140Builder

    • 引用位置: 方法调用
    • 关联成员: Std140Builder.intoBuffer()
  • Std140SizeCalculator

    • 引用位置: 构造调用
    • 关联成员: Std140SizeCalculator()
  • RenderSystem

    • 引用位置: 方法调用
    • 关联成员: RenderSystem.getDevice(), RenderSystem.setShaderFog()
  • Camera

    • 引用位置: 参数
  • DeltaTracker

    • 引用位置: 参数
  • ClientLevel

    • 引用位置: 参数
  • GameRenderer

    • 引用位置: 方法调用
    • 关联成员: GameRenderer.getNightVisionScale()
  • MappableRingBuffer

    • 引用位置: 字段/构造调用
    • 关联成员: MappableRingBuffer()
  • FogData

    • 引用位置: 参数/构造调用/返回值
    • 关联成员: FogData()
  • AtmosphericFogEnvironment

    • 引用位置: 构造调用
    • 关联成员: AtmosphericFogEnvironment()
  • BlindnessFogEnvironment

    • 引用位置: 构造调用
    • 关联成员: BlindnessFogEnvironment()
  • DarknessFogEnvironment

    • 引用位置: 构造调用
    • 关联成员: DarknessFogEnvironment()
  • FogEnvironment

    • 引用位置: 字段
  • LavaFogEnvironment

    • 引用位置: 构造调用
    • 关联成员: LavaFogEnvironment()
  • PowderedSnowFogEnvironment

    • 引用位置: 构造调用
    • 关联成员: PowderedSnowFogEnvironment()
  • WaterFogEnvironment

    • 引用位置: 构造调用
    • 关联成员: WaterFogEnvironment()
  • ARGB

    • 引用位置: 方法调用
    • 关联成员: ARGB.blueFloat(), ARGB.greenFloat(), ARGB.redFloat()
  • Mth

    • 引用位置: 方法调用
    • 关联成员: Mth.clamp(), Mth.lerp(), Mth.square()
  • FogType

    • 引用位置: 返回值