PostPass.java

net.minecraft.client.renderer.PostPass

信息

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

    TODO

字段/常量

  • UBO_SIZE_PER_SAMPLER

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

      TODO

  • name

    • 类型: String
    • 修饰符: private final
    • 源码定位: L35
    • 说明:

      TODO

  • pipeline

    • 类型: RenderPipeline
    • 修饰符: private final
    • 源码定位: L36
    • 说明:

      TODO

  • outputTargetId

    • 类型: Identifier
    • 修饰符: private final
    • 源码定位: L37
    • 说明:

      TODO

  • customUniforms

    • 类型: Map<String,GpuBuffer>
    • 修饰符: private final
    • 源码定位: L38
    • 说明:

      TODO

  • infoUbo

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

      TODO

  • inputs

    • 类型: List<PostPass.Input>
    • 修饰符: private final
    • 源码定位: L40
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.renderer.PostPass.Input

    • 类型: interface
    • 修饰符: public
    • 源码定位: L156
    • 说明:

      TODO

  • net.minecraft.client.renderer.PostPass.InputTexture

    • 类型: record
    • 修饰符: package-private
    • 源码定位: L170
    • 说明:

      TODO

  • net.minecraft.client.renderer.PostPass.TargetInput

    • 类型: record
    • 修饰符: public
    • 源码定位: L174
    • 说明:

      TODO

  • net.minecraft.client.renderer.PostPass.TextureInput

    • 类型: record
    • 修饰符: public
    • 源码定位: L203
    • 说明:

      TODO

构造器

public PostPass(RenderPipeline pipeline, Identifier outputTargetId, Map<String,List<UniformValue>> uniformGroups, List<PostPass.Input> inputs) @ L42

  • 构造器名:PostPass
  • 源码定位:L42
  • 修饰符:public

参数:

  • pipeline: RenderPipeline
  • outputTargetId: Identifier
  • uniformGroups: Map<String,List>
  • inputs: List<PostPass.Input>

说明:

TODO

方法

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

public void addToFrame(FrameGraphBuilder frame, Map<Identifier,ResourceHandle<RenderTarget>> targets, GpuBufferSlice shaderOrthoMatrix) @ L75

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

参数:

  • frame: FrameGraphBuilder
  • targets: Map<Identifier,ResourceHandle>
  • shaderOrthoMatrix: GpuBufferSlice

说明:

TODO

public void close() @ L146

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

参数:

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class PostPass implements AutoCloseable {
    private static final int UBO_SIZE_PER_SAMPLER = new Std140SizeCalculator().putVec2().get();
    private final String name;
    private final RenderPipeline pipeline;
    private final Identifier outputTargetId;
    private final Map<String, GpuBuffer> customUniforms = new HashMap<>();
    private final MappableRingBuffer infoUbo;
    private final List<PostPass.Input> inputs;
 
    public PostPass(RenderPipeline pipeline, Identifier outputTargetId, Map<String, List<UniformValue>> uniformGroups, List<PostPass.Input> inputs) {
        this.pipeline = pipeline;
        this.name = pipeline.getLocation().toString();
        this.outputTargetId = outputTargetId;
        this.inputs = inputs;
 
        for (Entry<String, List<UniformValue>> uniformGroup : uniformGroups.entrySet()) {
            List<UniformValue> uniforms = uniformGroup.getValue();
            if (!uniforms.isEmpty()) {
                Std140SizeCalculator calculator = new Std140SizeCalculator();
 
                for (UniformValue uniform : uniforms) {
                    uniform.addSize(calculator);
                }
 
                int size = calculator.get();
 
                try (MemoryStack stack = MemoryStack.stackPush()) {
                    Std140Builder builder = Std140Builder.onStack(stack, size);
 
                    for (UniformValue uniform : uniforms) {
                        uniform.writeTo(builder);
                    }
 
                    this.customUniforms
                        .put(uniformGroup.getKey(), RenderSystem.getDevice().createBuffer(() -> this.name + " / " + uniformGroup.getKey(), 128, builder.get()));
                }
            }
        }
 
        this.infoUbo = new MappableRingBuffer(() -> this.name + " SamplerInfo", 130, (inputs.size() + 1) * UBO_SIZE_PER_SAMPLER);
    }
 
    public void addToFrame(FrameGraphBuilder frame, Map<Identifier, ResourceHandle<RenderTarget>> targets, GpuBufferSlice shaderOrthoMatrix) {
        FramePass pass = frame.addPass(this.name);
 
        for (PostPass.Input input : this.inputs) {
            input.addToPass(pass, targets);
        }
 
        ResourceHandle<RenderTarget> outputHandle = targets.computeIfPresent(
            this.outputTargetId, (id, handle) -> pass.readsAndWrites((ResourceHandle<RenderTarget>)handle)
        );
        if (outputHandle == null) {
            throw new IllegalStateException("Missing handle for target " + this.outputTargetId);
        } else {
            pass.executes(
                () -> {
                    RenderTarget outputTarget = outputHandle.get();
                    RenderSystem.backupProjectionMatrix();
                    RenderSystem.setProjectionMatrix(shaderOrthoMatrix, ProjectionType.ORTHOGRAPHIC);
                    CommandEncoder commandEncoder = RenderSystem.getDevice().createCommandEncoder();
                    SamplerCache samplerCache = RenderSystem.getSamplerCache();
                    List<PostPass.InputTexture> inputTextures = this.inputs
                        .stream()
                        .map(
                            i -> new PostPass.InputTexture(
                                i.samplerName(), i.texture(targets), samplerCache.getClampToEdge(i.bilinear() ? FilterMode.LINEAR : FilterMode.NEAREST)
                            )
                        )
                        .toList();
 
                    try (GpuBuffer.MappedView view = commandEncoder.mapBuffer(this.infoUbo.currentBuffer(), false, true)) {
                        Std140Builder builder = Std140Builder.intoBuffer(view.data());
                        builder.putVec2(outputTarget.width, outputTarget.height);
 
                        for (PostPass.InputTexture inputxxx : inputTextures) {
                            builder.putVec2(inputxxx.view.getWidth(0), inputxxx.view.getHeight(0));
                        }
                    }
 
                    try (RenderPass renderPass = commandEncoder.createRenderPass(
                            () -> "Post pass " + this.name,
                            outputTarget.getColorTextureView(),
                            OptionalInt.empty(),
                            outputTarget.useDepth ? outputTarget.getDepthTextureView() : null,
                            OptionalDouble.empty()
                        )) {
                        renderPass.setPipeline(this.pipeline);
                        RenderSystem.bindDefaultUniforms(renderPass);
                        renderPass.setUniform("SamplerInfo", this.infoUbo.currentBuffer());
 
                        for (Entry<String, GpuBuffer> entry : this.customUniforms.entrySet()) {
                            renderPass.setUniform(entry.getKey(), entry.getValue());
                        }
 
                        for (PostPass.InputTexture inputx : inputTextures) {
                            renderPass.bindTexture(inputx.samplerName() + "Sampler", inputx.view(), inputx.sampler());
                        }
 
                        renderPass.draw(0, 3);
                    }
 
                    this.infoUbo.rotate();
                    RenderSystem.restoreProjectionMatrix();
 
                    for (PostPass.Input inputxx : this.inputs) {
                        inputxx.cleanup(targets);
                    }
                }
            );
        }
    }
 
    @Override
    public void close() {
        for (GpuBuffer buffer : this.customUniforms.values()) {
            buffer.close();
        }
 
        this.infoUbo.close();
    }
 
    @OnlyIn(Dist.CLIENT)
    public interface Input {
        void addToPass(FramePass pass, Map<Identifier, ResourceHandle<RenderTarget>> targets);
 
        default void cleanup(Map<Identifier, ResourceHandle<RenderTarget>> targets) {
        }
 
        GpuTextureView texture(final Map<Identifier, ResourceHandle<RenderTarget>> targets);
 
        String samplerName();
 
        boolean bilinear();
    }
 
    @OnlyIn(Dist.CLIENT)
    record InputTexture(String samplerName, GpuTextureView view, GpuSampler sampler) {
    }
 
    @OnlyIn(Dist.CLIENT)
    public record TargetInput(String samplerName, Identifier targetId, boolean depthBuffer, boolean bilinear) implements PostPass.Input {
        private ResourceHandle<RenderTarget> getHandle(Map<Identifier, ResourceHandle<RenderTarget>> targets) {
            ResourceHandle<RenderTarget> handle = targets.get(this.targetId);
            if (handle == null) {
                throw new IllegalStateException("Missing handle for target " + this.targetId);
            } else {
                return handle;
            }
        }
 
        @Override
        public void addToPass(FramePass pass, Map<Identifier, ResourceHandle<RenderTarget>> targets) {
            pass.reads(this.getHandle(targets));
        }
 
        @Override
        public GpuTextureView texture(Map<Identifier, ResourceHandle<RenderTarget>> targets) {
            ResourceHandle<RenderTarget> handle = this.getHandle(targets);
            RenderTarget target = handle.get();
            GpuTextureView textureView = this.depthBuffer ? target.getDepthTextureView() : target.getColorTextureView();
            if (textureView == null) {
                throw new IllegalStateException("Missing " + (this.depthBuffer ? "depth" : "color") + "texture for target " + this.targetId);
            } else {
                return textureView;
            }
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    public record TextureInput(String samplerName, AbstractTexture texture, int width, int height, boolean bilinear) implements PostPass.Input {
        @Override
        public void addToPass(FramePass pass, Map<Identifier, ResourceHandle<RenderTarget>> targets) {
        }
 
        @Override
        public GpuTextureView texture(Map<Identifier, ResourceHandle<RenderTarget>> targets) {
            return this.texture.getTextureView();
        }
    }
}

引用的其他类

  • GpuBuffer

    • 引用位置: 字段
  • GpuBufferSlice

    • 引用位置: 参数
  • Std140Builder

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

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

    • 引用位置: 参数
  • RenderPipeline

    • 引用位置: 参数/字段
  • RenderTarget

    • 引用位置: 参数
  • ResourceHandle

    • 引用位置: 参数
  • RenderSystem

    • 引用位置: 方法调用
    • 关联成员: RenderSystem.backupProjectionMatrix(), RenderSystem.bindDefaultUniforms(), RenderSystem.getDevice(), RenderSystem.getSamplerCache(), RenderSystem.restoreProjectionMatrix(), RenderSystem.setProjectionMatrix()
  • MappableRingBuffer

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

    • 引用位置: 参数
  • Identifier

    • 引用位置: 参数/字段