PostChain.java

net.minecraft.client.renderer.PostChain

信息

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

    TODO

字段/常量

  • MAIN_TARGET_ID

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

      TODO

  • passes

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

      TODO

  • internalTargets

    • 类型: Map<Identifier,PostChainConfig.InternalTarget>
    • 修饰符: private final
    • 源码定位: L35
    • 说明:

      TODO

  • externalTargets

    • 类型: Set<Identifier>
    • 修饰符: private final
    • 源码定位: L36
    • 说明:

      TODO

  • persistentTargets

    • 类型: Map<Identifier,RenderTarget>
    • 修饰符: private final
    • 源码定位: L37
    • 说明:

      TODO

  • projection

    • 类型: Projection
    • 修饰符: private final
    • 源码定位: L38
    • 说明:

      TODO

  • projectionMatrixBuffer

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

      TODO

内部类/嵌套类型

  • net.minecraft.client.renderer.PostChain.TargetBundle
    • 类型: interface
    • 修饰符: public
    • 源码定位: L190
    • 说明:

      TODO

构造器

private PostChain(List<PostPass> passes, Map<Identifier,PostChainConfig.InternalTarget> internalTargets, Set<Identifier> externalTargets, Projection projection, ProjectionMatrixBuffer projectionMatrixBuffer) @ L41

  • 构造器名:PostChain
  • 源码定位:L41
  • 修饰符:private

参数:

  • passes: List
  • internalTargets: Map<Identifier,PostChainConfig.InternalTarget>
  • externalTargets: Set
  • projection: Projection
  • projectionMatrixBuffer: ProjectionMatrixBuffer

说明:

TODO

方法

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

public static PostChain load(PostChainConfig config, TextureManager textureManager, Set<Identifier> allowedExternalTargets, Identifier id, Projection projection, ProjectionMatrixBuffer projectionMatrixBuffer) @ L55

  • 方法名:load
  • 源码定位:L55
  • 返回类型:PostChain
  • 修饰符:public static

参数:

  • config: PostChainConfig
  • textureManager: TextureManager
  • allowedExternalTargets: Set
  • id: Identifier
  • projection: Projection
  • projectionMatrixBuffer: ProjectionMatrixBuffer

说明:

TODO

private static PostPass createPass(TextureManager textureManager, PostChainConfig.Pass config, Identifier id) @ L81

  • 方法名:createPass
  • 源码定位:L81
  • 返回类型:PostPass
  • 修饰符:private static

参数:

  • textureManager: TextureManager
  • config: PostChainConfig.Pass
  • id: Identifier

说明:

TODO

public void addToFrame(FrameGraphBuilder frame, int screenWidth, int screenHeight, PostChain.TargetBundle providedTargets) @ L124

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

参数:

  • frame: FrameGraphBuilder
  • screenWidth: int
  • screenHeight: int
  • providedTargets: PostChain.TargetBundle

说明:

TODO

public void process(RenderTarget mainTarget, GraphicsResourceAllocator resourceAllocator) @ L156

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

参数:

  • mainTarget: RenderTarget
  • resourceAllocator: GraphicsResourceAllocator

说明:

TODO

private RenderTarget getOrCreatePersistentTarget(Identifier id, RenderTargetDescriptor descriptor) @ L164

  • 方法名:getOrCreatePersistentTarget
  • 源码定位:L164
  • 返回类型:RenderTarget
  • 修饰符:private

参数:

  • id: Identifier
  • descriptor: RenderTargetDescriptor

说明:

TODO

public void close() @ L179

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

参数:

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class PostChain implements AutoCloseable {
    public static final Identifier MAIN_TARGET_ID = Identifier.withDefaultNamespace("main");
    private final List<PostPass> passes;
    private final Map<Identifier, PostChainConfig.InternalTarget> internalTargets;
    private final Set<Identifier> externalTargets;
    private final Map<Identifier, RenderTarget> persistentTargets = new HashMap<>();
    private final Projection projection;
    private final ProjectionMatrixBuffer projectionMatrixBuffer;
 
    private PostChain(
        List<PostPass> passes,
        Map<Identifier, PostChainConfig.InternalTarget> internalTargets,
        Set<Identifier> externalTargets,
        Projection projection,
        ProjectionMatrixBuffer projectionMatrixBuffer
    ) {
        this.passes = passes;
        this.internalTargets = internalTargets;
        this.externalTargets = externalTargets;
        this.projection = projection;
        this.projectionMatrixBuffer = projectionMatrixBuffer;
    }
 
    public static PostChain load(
        PostChainConfig config,
        TextureManager textureManager,
        Set<Identifier> allowedExternalTargets,
        Identifier id,
        Projection projection,
        ProjectionMatrixBuffer projectionMatrixBuffer
    ) throws ShaderManager.CompilationException {
        Stream<Identifier> referencedTargets = config.passes().stream().flatMap(PostChainConfig.Pass::referencedTargets);
        Set<Identifier> referencedExternalTargets = referencedTargets.filter(targetId -> !config.internalTargets().containsKey(targetId))
            .collect(Collectors.toSet());
        Set<Identifier> invalidExternalTargets = Sets.difference(referencedExternalTargets, allowedExternalTargets);
        if (!invalidExternalTargets.isEmpty()) {
            throw new ShaderManager.CompilationException("Referenced external targets are not available in this context: " + invalidExternalTargets);
        } else {
            Builder<PostPass> passes = ImmutableList.builder();
 
            for (int i = 0; i < config.passes().size(); i++) {
                PostChainConfig.Pass pass = config.passes().get(i);
                passes.add(createPass(textureManager, pass, id.withSuffix("/" + i)));
            }
 
            return new PostChain(passes.build(), config.internalTargets(), referencedExternalTargets, projection, projectionMatrixBuffer);
        }
    }
 
    private static PostPass createPass(TextureManager textureManager, PostChainConfig.Pass config, Identifier id) throws ShaderManager.CompilationException {
        RenderPipeline.Builder pipelineBuilder = RenderPipeline.builder(RenderPipelines.POST_PROCESSING_SNIPPET)
            .withFragmentShader(config.fragmentShaderId())
            .withVertexShader(config.vertexShaderId())
            .withLocation(id);
 
        for (PostChainConfig.Input input : config.inputs()) {
            pipelineBuilder.withSampler(input.samplerName() + "Sampler");
        }
 
        pipelineBuilder.withUniform("SamplerInfo", UniformType.UNIFORM_BUFFER);
 
        for (String uniformGroupName : config.uniforms().keySet()) {
            pipelineBuilder.withUniform(uniformGroupName, UniformType.UNIFORM_BUFFER);
        }
 
        RenderPipeline pipeline = pipelineBuilder.build();
        List<PostPass.Input> inputs = new ArrayList<>();
 
        label110:
        for (PostChainConfig.Input input : config.inputs()) {
            Objects.requireNonNull(input);
            PostChainConfig.Input var8 = input;
            byte var9 = 0;
 
            {
                switch (var8) {
                    case PostChainConfig.TextureInput(String var36, Identifier var37, int var38, int var39, boolean var40):
                                    AbstractTexture var41 = textureManager.getTexture(var37.withPath(path -> "textures/effect/" + path + ".png"));
                                    inputs.add(new PostPass.TextureInput(var36, var41, var38, var39, var40));
                                    continue label110;
                    case PostChainConfig.TargetInput(String var21, Identifier var42, boolean var43, boolean var44):
                                inputs.add(new PostPass.TargetInput(var21, var42, var43, var44));
                                continue label110;
                    default:
                        throw new MatchException(null, null);
                }
            }
        }
 
        return new PostPass(pipeline, config.outputTarget(), config.uniforms(), inputs);
    }
 
    public void addToFrame(FrameGraphBuilder frame, int screenWidth, int screenHeight, PostChain.TargetBundle providedTargets) {
        this.projection.setSize(screenWidth, screenHeight);
        GpuBufferSlice projectionBuffer = this.projectionMatrixBuffer.getBuffer(this.projection);
        Map<Identifier, ResourceHandle<RenderTarget>> targets = new HashMap<>(this.internalTargets.size() + this.externalTargets.size());
 
        for (Identifier id : this.externalTargets) {
            targets.put(id, providedTargets.getOrThrow(id));
        }
 
        for (Entry<Identifier, PostChainConfig.InternalTarget> entry : this.internalTargets.entrySet()) {
            Identifier id = entry.getKey();
            PostChainConfig.InternalTarget target = entry.getValue();
            RenderTargetDescriptor descriptor = new RenderTargetDescriptor(
                target.width().orElse(screenWidth), target.height().orElse(screenHeight), true, target.clearColor()
            );
            if (target.persistent()) {
                RenderTarget persistentTarget = this.getOrCreatePersistentTarget(id, descriptor);
                targets.put(id, frame.importExternal(id.toString(), persistentTarget));
            } else {
                targets.put(id, frame.createInternal(id.toString(), descriptor));
            }
        }
 
        for (PostPass pass : this.passes) {
            pass.addToFrame(frame, targets, projectionBuffer);
        }
 
        for (Identifier id : this.externalTargets) {
            providedTargets.replace(id, targets.get(id));
        }
    }
 
    @Deprecated
    public void process(RenderTarget mainTarget, GraphicsResourceAllocator resourceAllocator) {
        FrameGraphBuilder frame = new FrameGraphBuilder();
        PostChain.TargetBundle targets = PostChain.TargetBundle.of(MAIN_TARGET_ID, frame.importExternal("main", mainTarget));
        this.addToFrame(frame, mainTarget.width, mainTarget.height, targets);
        frame.execute(resourceAllocator);
    }
 
    private RenderTarget getOrCreatePersistentTarget(Identifier id, RenderTargetDescriptor descriptor) {
        RenderTarget target = this.persistentTargets.get(id);
        if (target == null || target.width != descriptor.width() || target.height != descriptor.height()) {
            if (target != null) {
                target.destroyBuffers();
            }
 
            target = descriptor.allocate();
            descriptor.prepare(target);
            this.persistentTargets.put(id, target);
        }
 
        return target;
    }
 
    @Override
    public void close() {
        this.persistentTargets.values().forEach(RenderTarget::destroyBuffers);
        this.persistentTargets.clear();
 
        for (PostPass pass : this.passes) {
            pass.close();
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    public interface TargetBundle {
        static PostChain.TargetBundle of(Identifier targetId, ResourceHandle<RenderTarget> target) {
            return new PostChain.TargetBundle() {
                private ResourceHandle<RenderTarget> handle = target;
 
                @Override
                public void replace(Identifier id, ResourceHandle<RenderTarget> handle) {
                    if (id.equals(targetId)) {
                        this.handle = handle;
                    } else {
                        throw new IllegalArgumentException("No target with id " + id);
                    }
                }
 
                @Override
                public @Nullable ResourceHandle<RenderTarget> get(Identifier id) {
                    return id.equals(targetId) ? this.handle : null;
                }
            };
        }
 
        void replace(Identifier id, ResourceHandle<RenderTarget> handle);
 
        @Nullable ResourceHandle<RenderTarget> get(Identifier id);
 
        default ResourceHandle<RenderTarget> getOrThrow(Identifier id) {
            ResourceHandle<RenderTarget> handle = this.get(id);
            if (handle == null) {
                throw new IllegalArgumentException("Missing target with id " + id);
            } else {
                return handle;
            }
        }
    }
}

引用的其他类

  • FrameGraphBuilder

    • 引用位置: 参数/构造调用
    • 关联成员: FrameGraphBuilder()
  • RenderPipeline

    • 引用位置: 方法调用
    • 关联成员: RenderPipeline.builder()
  • RenderTarget

    • 引用位置: 参数/字段/返回值
  • GraphicsResourceAllocator

    • 引用位置: 参数
  • RenderTargetDescriptor

    • 引用位置: 参数/构造调用
    • 关联成员: RenderTargetDescriptor()
  • PostChainConfig

    • 引用位置: 参数/字段/方法调用
    • 关联成员: PostChainConfig.TargetInput(), PostChainConfig.TextureInput()
  • PostPass

    • 引用位置: 参数/字段/方法调用/构造调用/返回值
    • 关联成员: PostPass(), PostPass.TargetInput(), PostPass.TextureInput(), TargetInput(), TextureInput()
  • Projection

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

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

    • 引用位置: 方法调用/构造调用
    • 关联成员: CompilationException(), ShaderManager.CompilationException()
  • TextureManager

    • 引用位置: 参数
  • Identifier

    • 引用位置: 参数/字段/方法调用
    • 关联成员: Identifier.withDefaultNamespace()