Giter Site home page Giter Site logo

canvas's Introduction

Canvas

Canvas is a shader-based Renderer for the Fabric modding toolchain. It supports all features of the proposed Fabric Rendering API plus extensions defined in FREX.

Limitations

Canvas is in EARLY ALPHA. Expect it to break. Currently terrain rendering works with shaders but item rendering does not. (It will.). Rendering for blocks in movement (falling blocks, blocks being moved by pistons, etc.) is WIP and will crash.

The FREX extensions, shader library, vertex formats, attribute bindings, and lighting options are subject to change - causing your code to break. Sorry. When there is a stable release (sometime after 1.14 is released) I will avoid breaking changes in shipping versions. Until then, experimentation is the norm.

Why

When people first hear about Canvas they often ask if it is a performance mod or a replacement for Optifine / shader packs. The answer is "no, but..."

Optifine and shader packs primarily target vanilla Minecraft. They work with modded, often well, but they aren't designed as tools for mod authors.

Canvas' entire purpose is to give mod authors more control and options for rendering modded blocks. It could be used for building a shader pack by replacing vanilla models with material-aware models that have custom shaders. But that isn't its main reason for being.

Performance-wise, Canvas does try to be reasonably fast and has/will have optimizations - but the intent of these changes is to make better rendering practical, not to be a general-purpose performance mod. It isn't meant to run on low-end hardware and may or may not make your game run faster overall.

Currently, there are two main optimizations. 1) Canvas buffers and renders SOLID and CUTOUT layers in a single pass with cutout and mip mapping variation handled in the fragment shader. 2) Canvas buffers and renders multiple chunks using the same matrix transform to reduce the number of GL state changes.

Additional optimizations will wait until 1.14 is released and stable.

Using Canvas

Before using Canvas, you should first understand RenderMaterials, Meshes, RenderContexts and other features defined by the Fabric Rendering API. For that information, consult the rendering article on the Fabric Wiki. Note: Fabric wiki is still WIP as of this writing but should be more complete "soon."

You can also see RenderBender for some (not very good) examples of usage. Avoid duplicating those examples directly - they aren't especially performant or suitable for use at scale. As soon as someone releases a model loader / library for Fabric Rendering API / FREX, that will almost certainly be a better approach.

Overlay Sprites

Canvas supports a max sprite depth of three - meaning you can add one or two overlay sprites to each quad. For example, to add one overlay texture, choose a material with a sprite depth of two:

RenderMaterial mat = RendererAccess.INSTANCE.getRenderer().finder().spriteDepth(2)
//select other material properties...
.find();

Specify UV coordinates, blend mode and colors for your overlay sprites like so:

  .blendMode(1, TRANSLUCENT)
  .disableColorIndex(1, true)
  .spriteBake(1, sprite, MutableQuadView.BAKE_LOCK_UV | MutableQuadView.BAKE_NORMALIZED)
  .spriteColor(1, -1, -1, -1, -1)

Note that is doesn't make sense to use BlockRenderLayer.SOLID as the blend mode for overlay textures - it would cover up the texture beneath it. Use TRANSLUCENT or one of the CUTOUT modes instead.

It's likely Canvas will also support "decal" quads in the future, but overlay sprites will be more performant when model and texture geometry make them feasible. (Overlays can be rendered together in a single primitive and avoid the need to project the decal onto existing geometry.)

Attaching Shaders to Materials

Shaders and their uniforms are bundled into a "pipeline" which can then be associated with a material, like so:

  ExtendedRenderer er = (ExtendedRenderer) RendererAccess.INSTANCE.getRenderer();
  Pipeline p = er.pipelineBuilder()
      .vertexSource(new Identifier("renderbender", "shader/test.vert"))
      .fragmentSource(new Identifier("renderbender", "shader/test.frag"))
      .build();
  RenderMaterial mat = er.materialFinder().pipeline(p).find();

Note the renderer must be cast to ExtendedRenderer to access these features. If you need custom uniforms, you can add them via PipelineBuilder.

The identifiers passed to vertexSource and fragmentSource should point to GLSL files in your resource pack. The relative path and file extension must be included, and shader/ is the suggested location.

Your vertex and fragment shaders must have a main procedure. To ensure compatibility, shaders are limited to #version 120 features, plus GL_EXT_gpu_shader4.

Vertex Shaders

Your vertex shader will automatically include all the definitions and library routines in common_lib.glsl and vertex_lib.glsl, which both live in assets/canvas/shader.

Your vertex shader must set gl_Position, gl_ClipVertex, and gl_FogFragCoord along with any varying variables needed in your fragment shader. Canvas also needs to do its own prep for standard texturing and lighting here, assuming you need them.

The easiest way to do this is to call the setupVertex() library function that Canvas provides, and then add your own logic as needed, like so:

void main() {
    // do your custom stuff here!
    setupVertex();
    // or do it here!
}

Fragment Shaders

Your fragment shader will automatically include all the definitions and library routines in common_lib.glsl and fragment_lib.glsl, which both live in assets/canvas/shader.

Canvas handles all lighting - diffuse and ambient occlusion - in the fragment shader. This means your colors will always be unmodified at the start of the fragment routine.

Your fragment shader should set gl_FragColor or, in rare cases, call discard. To get the lit and shaded color that would normally be output, call diffuseColor() and to apply the current distance fog use fog().

Future versions of the fragment library will give more granular options for getting lit or unlit colors and for modifying colors before or after lighting.

Adding Canvas to your project

Add the maven repo where my repos live to your build.gradle

repositories {
    maven {
    	name = "dblsaiko"
    	url = "https://maven.dblsaiko.net/"
    }
    maven {
      name = "Cotton"
      url = "http://server.bbkr.space:8081/artifactory/libs-release/"
    }
}

And add Canvas to your dependencies

dependencies {
	modCompile "grondag:canvas-mc116:1.0.+"
}

Note that versions are subject to change - look at the repo to find latest.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.