├── .checkstyle ├── .gitignore ├── HEADER ├── LICENSE ├── README.md ├── build.gradle ├── checkstyle.xml ├── dependencies.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src └── main ├── java └── grondag │ └── frex │ ├── Frex.java │ ├── FrexInitializer.java │ ├── api │ ├── Renderer.java │ ├── RendererFeature.java │ ├── config │ │ ├── FlawlessFrames.java │ │ └── ShaderConfig.java │ ├── event │ │ ├── HeldItemLightListener.java │ │ ├── RenderRegionBakeListener.java │ │ └── WorldRenderEvent.java │ ├── fluid │ │ ├── AbstractFluidModel.java │ │ └── FluidQuadSupplier.java │ ├── light │ │ ├── ItemLight.java │ │ └── ItemLightProvider.java │ ├── material │ │ ├── BlockEntityMaterialMap.java │ │ ├── EntityMaterialMap.java │ │ ├── FrexVertexConsumerProvider.java │ │ ├── MaterialCondition.java │ │ ├── MaterialFinder.java │ │ ├── MaterialLoader.java │ │ ├── MaterialMap.java │ │ ├── RenderMaterial.java │ │ ├── Uniform.java │ │ └── UniformRefreshFrequency.java │ ├── mesh │ │ ├── FrexVertexConsumer.java │ │ ├── MutableQuadView.java │ │ ├── QuadEmitter.java │ │ └── QuadView.java │ └── model │ │ └── LazyForwardingBakedModel.java │ ├── impl │ ├── RendererFeatureImpl.java │ ├── config │ │ ├── FlawlessFramesImpl.java │ │ └── ShaderConfigImpl.java │ ├── event │ │ ├── BlockStateRendererImpl.java │ │ ├── ChunkRenderConditionContext.java │ │ ├── ItemLightListenerImpl.java │ │ └── RenderRegionBakeListenerImpl.java │ ├── fluid │ │ └── FluidQuadSupplierImpl.java │ ├── light │ │ ├── ItemLightDeserializer.java │ │ ├── ItemLightLoader.java │ │ └── SimpleItemLight.java │ └── material │ │ ├── BlockEntityMaterialMapDeserializer.java │ │ ├── BlockEntityMultiMaterialMap.java │ │ ├── BlockEntitySingleMaterialMap.java │ │ ├── DefaultedMultiMaterialMap.java │ │ ├── EntityMaterialMapDeserializer.java │ │ ├── EntityMultiMaterialMap.java │ │ ├── EntitySingleMaterialMap.java │ │ ├── ItemMaterialMapDeserializer.java │ │ ├── MaterialDeserializer.java │ │ ├── MaterialLoaderImpl.java │ │ ├── MaterialMapDeserializer.java │ │ ├── MaterialMapLoader.java │ │ ├── MaterialTransform.java │ │ ├── MaterialTransformDeserializer.java │ │ ├── MaterialTransformLoader.java │ │ ├── MultiMaterialMap.java │ │ ├── ParticleMaterialMapDeserializer.java │ │ ├── SingleMaterialMap.java │ │ └── predicate │ │ ├── ArrayPredicate.java │ │ ├── EntityBiPredicate.java │ │ ├── EntityMaterialBoth.java │ │ ├── EntityMaterialOnly.java │ │ ├── EntityOnly.java │ │ ├── MaterialPredicate.java │ │ ├── MaterialPredicateDeserializer.java │ │ ├── MaterialTester.java │ │ ├── StateBiPredicate.java │ │ ├── StateMaterialBoth.java │ │ ├── StateMaterialOnly.java │ │ └── StateOnly.java │ └── mixin │ ├── MixinChunkBuilder.java │ ├── MixinChunkRendererRegion.java │ └── MixinWorldRendererOldEvents.java └── resources ├── assets └── frex │ ├── frex_icon.png │ └── shaders │ ├── api │ ├── FREX Shader API.md │ ├── fog.h │ ├── fragment.h │ ├── header.h │ ├── material.h │ ├── player.h │ ├── sampler.h │ ├── vertex.h │ ├── view.h │ └── world.h │ └── lib │ ├── bitwise.glsl │ ├── color.glsl │ ├── face.glsl │ ├── math.glsl │ ├── noise │ ├── LICENSE │ ├── README │ ├── cellular2d.glsl │ ├── cellular2x2.glsl │ ├── cellular2x2x2.glsl │ ├── cellular3d.glsl │ ├── classicnoise2d.glsl │ ├── classicnoise3d.glsl │ ├── classicnoise4d.glsl │ ├── noise2d.glsl │ ├── noise3d.glsl │ ├── noise3dgrad.glsl │ ├── noise4d.glsl │ ├── noisecommon.glsl │ └── psrdnoise2d.glsl │ └── sample.glsl ├── fabric.mod.json └── frex.client.json /.checkstyle: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Windows 2 | Thumbs.db 3 | 4 | ## exclude large animated textures 5 | *_anim.png 6 | *_anim_low.png 7 | 8 | # eclipse 9 | bin 10 | *.launch 11 | .settings 12 | .metadata 13 | .classpath 14 | .project 15 | eclipse 16 | 17 | build 18 | run 19 | 20 | 21 | ##idea 22 | *.iml 23 | *.ipr 24 | *.iws 25 | 26 | ## Jars 27 | 28 | ### OSX (adds a lot of garbage)### 29 | .DS_Store 30 | .AppleDouble 31 | .LSOverride 32 | 33 | # Thumbnails 34 | ._* 35 | 36 | #stuff 37 | #config 38 | logs 39 | .html 40 | discarded textures 41 | *.nps 42 | /.apt_generated/ 43 | notes.txt 44 | *.csv 45 | .mixin.out/audit/mixin_implementation_report.txt 46 | -------------------------------------------------------------------------------- /HEADER: -------------------------------------------------------------------------------- 1 | Copyright 2019, 2020 grondag 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 | use this file except in compliance with the License. You may obtain a copy 5 | of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | License for the specific language governing permissions and limitations under 13 | the License. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # THE FREX PROJECT IS NOW PART OF VRAM-GUILD 2 | **THIS REPO IS NO LONGER MAINTAINED.** 3 | 4 | **Please go to https://github.com/vram-guild/frex** 5 | 6 | # FREX - Rendering Extensions for Minecraft Mods 7 | 8 | FREX currently support the Fabric API and Mod Loader. 9 | 10 | Packaged as a separate mod so that rendering implementations and mods that consume these extensions can 11 | depend on it without directly depending on specific implementation. 12 | 13 | More information on using FREX is available on the [Renderosity Wiki](https://github.com/grondag/renderosity/wiki). 14 | 15 | # Using FREX 16 | 17 | Add the maven repo where my libraries live to your build.gradle 18 | 19 | ```gradle 20 | repositories { 21 | maven { 22 | name = "dblsaiko" 23 | url = "https://maven.dblsaiko.net/" 24 | } 25 | } 26 | ``` 27 | 28 | And add FREX to your dependencies 29 | 30 | ```gradle 31 | dependencies { 32 | modCompile "grondag:frex:0.7.+" 33 | include "grondag:frex:0.7.+" 34 | } 35 | ``` 36 | 37 | The ```include``` is not necessary if you are depending on another mod that also includes FREX. Currently, [Canvas](https://github.com/grondag/canvas) and [JMX](https://github.com/grondag/json-model-extensions) both include FREX. 38 | 39 | Note that version is subject to change - look at the repo to find latest. 40 | -------------------------------------------------------------------------------- /dependencies.gradle: -------------------------------------------------------------------------------- 1 | repositories { 2 | mavenLocal() 3 | jcenter(); 4 | maven { 5 | name = "Fabric" 6 | url "https://maven.fabricmc.net/" 7 | } 8 | maven { 9 | name = "dblsaiko" 10 | url = "https://maven.dblsaiko.net/" 11 | } 12 | } 13 | 14 | dependencies { 15 | minecraft "com.mojang:minecraft:${project.minecraft_version}" 16 | mappings "net.fabricmc:yarn:${project.yarn_mappings}" 17 | modApi "net.fabricmc:fabric-loader:${project.loader_version}" 18 | modApi "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" 19 | } 20 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx2G 2 | org.gradle.daemon=false 3 | 4 | group=grondag 5 | mod_name=frex 6 | frex_version=5.6 7 | 8 | mc_tag=mc117 9 | minecraft_version=1.17.1 10 | yarn_mappings=1.17.1+build.23 11 | loader_version=0.11.6 12 | fabric_version=0.40.1+1.17 13 | loom_version=0.9-SNAPSHOT 14 | 15 | license_header=APACHE 16 | 17 | github_repository_owner=grondag 18 | github_repository=frex 19 | curseforge_id=318827 20 | release_type=release 21 | release_version=1.17.1 22 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grondag/frex/a2ffd37980e91befe1246a0bc271b2e70dc84ec5/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | jcenter() 4 | mavenCentral() 5 | maven { 6 | name = 'Fabric' 7 | url = 'https://maven.fabricmc.net/' 8 | } 9 | gradlePluginPortal() 10 | } 11 | } -------------------------------------------------------------------------------- /src/main/java/grondag/frex/Frex.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex; 18 | 19 | import org.apache.logging.log4j.LogManager; 20 | import org.apache.logging.log4j.Logger; 21 | 22 | import net.minecraft.resource.ResourceType; 23 | 24 | import net.fabricmc.api.ClientModInitializer; 25 | import net.fabricmc.fabric.api.client.rendering.v1.InvalidateRenderStateCallback; 26 | import net.fabricmc.fabric.api.resource.ResourceManagerHelper; 27 | import net.fabricmc.loader.api.FabricLoader; 28 | import net.fabricmc.loader.api.ModContainer; 29 | 30 | import grondag.frex.impl.config.FlawlessFramesImpl; 31 | import grondag.frex.impl.fluid.FluidQuadSupplierImpl; 32 | import grondag.frex.impl.light.ItemLightLoader; 33 | import grondag.frex.impl.material.MaterialMapLoader; 34 | 35 | public class Frex implements ClientModInitializer { 36 | public static Logger LOG = LogManager.getLogger("FREX"); 37 | 38 | private static final boolean isAvailable; 39 | 40 | static { 41 | boolean result = false; 42 | 43 | for (final ModContainer mod : FabricLoader.getInstance().getAllMods()) { 44 | if (mod.getMetadata().containsCustomValue("frex:contains_frex_renderer")) { 45 | result = true; 46 | break; 47 | } 48 | } 49 | 50 | isAvailable = result; 51 | } 52 | 53 | // TODO: replace with something that indicates renderer feature set. 54 | @Deprecated 55 | public static boolean isAvailable() { 56 | return isAvailable; 57 | } 58 | 59 | @Override 60 | public void onInitializeClient() { 61 | ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(MaterialMapLoader.INSTANCE); 62 | ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(ItemLightLoader.INSTANCE); 63 | 64 | FabricLoader.getInstance().getEntrypoints("frex", FrexInitializer.class).forEach( 65 | api -> api.onInitalizeFrex()); 66 | 67 | FlawlessFramesImpl.onClientInitialization(); 68 | 69 | InvalidateRenderStateCallback.EVENT.register(FluidQuadSupplierImpl::reload); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/FrexInitializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex; 18 | 19 | /** 20 | * Use to make FREX an optional dependency. To do so, implement this interface 21 | * in a stand-alone class and declare a "frex" end point in the mod's 22 | * fabric.mod.json that points to the implementation. For example: 23 | * 24 | *

25 |  * "entrypoints": {
26 |  *    "frex": [ "yourorg.yourmod.yourpackage.XmFrexInitializer" ]
27 |  * }
28 | * 29 | *

Every mod that implements this interface and declares and end point will receive 30 | * exactly one call to {@link #onInitalizeFrex()}. 31 | * 32 | *

To maintain an optional dependency, all calls to FREX methods must be isolated to 33 | * the FrexInitializer instance or to classes that are only loaded if {@link #onInitalizeFrex()} 34 | * is called. 35 | * 36 | *

Note that it is NOT necessary to implement this interface and register a 37 | * "frex" end point for mods that nest the FREX library or have a hard dependency on FREX. 38 | * Such mods can safely handle FREX registration in their client initialize instance. 39 | */ 40 | public interface FrexInitializer { 41 | /** 42 | * Signals mods that maintain an optional dependency on FREX that FREX is 43 | * loaded. Such mods should handle initialization activities that reference 44 | * FREX classes during this call. 45 | * 46 | *

Will be called during client mod initialization, possibly before the requesting 47 | * mod initialization is complete. It will be called exactly once per game start. 48 | */ 49 | void onInitalizeFrex(); 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/Renderer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api; 18 | 19 | import java.util.function.BooleanSupplier; 20 | 21 | import org.jetbrains.annotations.ApiStatus.Experimental; 22 | import org.jetbrains.annotations.ApiStatus.ScheduledForRemoval; 23 | 24 | import net.minecraft.util.Identifier; 25 | 26 | import net.fabricmc.fabric.api.renderer.v1.RendererAccess; 27 | import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; 28 | 29 | import grondag.frex.Frex; 30 | import grondag.frex.api.material.MaterialCondition; 31 | import grondag.frex.api.material.MaterialFinder; 32 | 33 | /** 34 | * Interface for rendering plug-ins that provide enhanced capabilities 35 | * for model lighting, buffering and rendering. Such plug-ins implement the 36 | * enhanced model rendering interfaces specified by the Fabric API. 37 | */ 38 | public interface Renderer extends net.fabricmc.fabric.api.renderer.v1.Renderer { 39 | /** Will throw exception if not implemented. Check {@link Frex#isAvailable()} before calling. */ 40 | static Renderer get() { 41 | if (Frex.isAvailable()) { 42 | return (Renderer) RendererAccess.INSTANCE.getRenderer(); 43 | } else { 44 | throw new IllegalStateException("A mod tried to obtain a FREX renderer but no FREX implementation is active."); 45 | } 46 | } 47 | 48 | /** 49 | * Obtain a new {@link MaterialFinder} instance used to retrieve 50 | * standard {@link RenderMaterial} instances. 51 | * 52 | *

Renderer does not retain a reference to returned instances and they should be re-used for 53 | * multiple materials when possible to avoid memory allocation overhead. 54 | */ 55 | @Override 56 | MaterialFinder materialFinder(); 57 | 58 | @ScheduledForRemoval 59 | @Deprecated 60 | int maxSpriteDepth(); 61 | 62 | @Experimental 63 | MaterialCondition createCondition(BooleanSupplier supplier, boolean affectBlocks, boolean affectItems); 64 | 65 | @Experimental 66 | MaterialCondition conditionById(Identifier id); 67 | 68 | @Experimental 69 | boolean registerCondition(Identifier id, MaterialCondition pipeline); 70 | 71 | /** 72 | * Identical to {@link #registerMaterial(Identifier, RenderMaterial)} except registrations 73 | * are replaced if they already exist. Meant to be used for materials that are loaded 74 | * from resources and need to be updated during resource reload. 75 | * 76 | *

Note that mods retaining references to materials obtained from the registry will not 77 | * use the new material definition unless they re-query. Material maps will handle this 78 | * automatically but mods must be designed to do so. 79 | * 80 | *

If this feature is not supported by the renderer, behaves like {@link #registerMaterial(Identifier, RenderMaterial)}. 81 | * 82 | *

Returns false if a material with the given identifier was already present. 83 | */ 84 | default boolean registerOrUpdateMaterial(Identifier id, RenderMaterial material) { 85 | return registerMaterial(id, material); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/RendererFeature.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api; 18 | 19 | import grondag.frex.impl.RendererFeatureImpl; 20 | 21 | public interface RendererFeature { 22 | static boolean isAvailable(int featureId) { 23 | return RendererFeatureImpl.isAvailable(featureId); 24 | } 25 | 26 | /** 27 | * Renderers should call this exactly once during init to declare available features. 28 | * 29 | * @param features Array of feature flags declared here or third-party flags declared elsewhere. 30 | */ 31 | static void registerFeatures(int... features) { 32 | RendererFeatureImpl.registerFeatures(features); 33 | } 34 | 35 | // IDs 0 - 4095 are reserved for FREX. 36 | int FREX_BASE = 0; 37 | 38 | /** Present when registerOrUpdateMaterial is supported. */ 39 | int UPDATE_MATERIAL_REGISTRATION = FREX_BASE; 40 | 41 | /** Third-party extension features begin numbering here. */ 42 | int EXTENSION_BASE = 4096; 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/config/FlawlessFrames.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.config; 18 | 19 | import grondag.frex.impl.config.FlawlessFramesImpl; 20 | 21 | /** 22 | * Defines an entry point mods like ReplayMod ("consumers") can use to signal a renderer 23 | * or other mods that affect rendering ("providers") that quality should be favored over 24 | * speed because output is being recorded. An active signal means a provider that 25 | * is altering some visual elements to achieve interactive frame rates should try 26 | * to disable those measures if it will give a noticeable boost to quality. 27 | * 28 | *

At a minimum, a renderer should ensure that terrain iteration blocks the main 29 | * render thread until the entire visible set of chunk sections are determined and all 30 | * visible chunk sections have been built and can be rendered in the frame. 31 | * 32 | *

While this API is defined as part of FREX, it uses standard Java interfaces so that 33 | * it can be implemented and consumed without reference to any FREX library or any other 34 | * mod dependency. This is done to facilitate adoption by suppliers that do not implement 35 | * or depend on FREX and to spare mods that do not use other FREX features from including it. 36 | * 37 | *

This interface and it's implementation are provided as a convenience for providers 38 | * that depend on FREX directly. Providers that do not depend on FREX can copy the relevant 39 | * code from FREX or create their own implementation as desired. 40 | * 41 | *

Mods that want to request control of this feature should implement the {@code frex_flawless_frames} 42 | * entry point, as illustrated below. The entry point class must implement 43 | * {@code Consumer>>}. 44 | * 45 | *

46 |  * "entrypoints": {
47 |  *    "frex_flawless_frames": [ "yourorg.yourmod.yourpackage.MyConsumer" ]
48 |  * }
49 | * 50 | *

Any provider that invokes this end point should ensure every consumer that declares it 51 | * is called exactly once during initialization. (For providers using FREX, the library 52 | * automatically satisfies this guarantee.) 53 | * 54 | *

When an end point is invoked, the consumer will receive a {@code Function>} 55 | * instance. The string name passed in to this function is meant to facilitate logging and debugging 56 | * of activation within the renderer when multiple mods may be using the end point. The resulting 57 | * "activation function" instance can then be used at any time to activate or deactivate this feature. 58 | * 59 | *

Consumers of this endpoint MUST be prepared to be called by multiple providers and 60 | * MUST retrieve, retain and call all received activation functions uniformly. This is necessary 61 | * because the dependency on FREX is entirely optional and thus providers implementations may not be 62 | * shared. This scenario will happen, for example, when a FREX renderer is present and another provider 63 | * that affects rendering (but does not use the FREX library) is loaded and has provided the endpoint. 64 | * 65 | *

The contract for usage of activation functions by consumers is as follows: 66 | *

78 | * 79 | *

The feature will be active when one or more consumers have requested it and inactive 80 | * when no consumers have activated it. FREX dependents can use {@link #isActive()} to query 81 | * the currently effective state. 82 | */ 83 | public interface FlawlessFrames { 84 | /** 85 | * Queries the effective status of this feature. 86 | * @return True if any consumer has requested activation, false otherwise. 87 | */ 88 | static boolean isActive() { 89 | return FlawlessFramesImpl.isActive(); 90 | } 91 | 92 | /** 93 | * Enables or disables logging of feature activation as a diagnostic aid. 94 | */ 95 | static void enableTrace(boolean enable) { 96 | FlawlessFramesImpl.enableTrace(enable); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/config/ShaderConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.config; 18 | 19 | import java.util.function.Supplier; 20 | 21 | import net.minecraft.client.MinecraftClient; 22 | import net.minecraft.util.Identifier; 23 | 24 | import grondag.frex.impl.config.ShaderConfigImpl; 25 | 26 | /** 27 | * Use this to inject constant declarations that are managed by the mod into shaders . 28 | * 29 | *

The declarations are referenced by including a provided token in the shader(s) that need them. 30 | * They are provided by the mod as a string and consumed when needed by the renderer. 31 | * 32 | *

For example if you have a config option named {@code BOOP} with three choices: {@code BOOP_NEVER}, 33 | * {@code BOOP_SOMETIMES} and {@code BOOP_ALWAYS} then you'd generate something like this: 34 | * 35 | *

36 |  * #define BOOP_NEVER 0
37 |  * #define BOOP_SOMETIMES 1
38 |  * #define BOOP_ALWAYS 2
39 |  *
40 |  * // currently selected config
41 |  * #define BOOP BOOP_ALWAYS
42 |  * 
43 | * 44 | *

Shader authors can reference this like so: 45 | * 46 | *

47 |  * #include mymod:boop_config
48 |  *
49 |  * #if BOOP == BOOP_ALWAYS
50 |  * // code that always boops goes here
51 |  * #endif
52 |  * 
53 | * 54 | *

This is only suitable for configuration that can be represented as boolean or numeric values 55 | * via preprocessor declarations and that remain static until changed by the player. 56 | * 57 | *

The renderer implementation is responsible for detecting multiple/nested {code #include} 58 | * statements for the same token and for ignoring all duplicate occurrences. 59 | */ 60 | public interface ShaderConfig { 61 | /** 62 | * Registers a supplier of configuration declarations that will replace the given 63 | * token whenever it is encountered in shader source. 64 | * 65 | *

Will warn if the same token is registered twice and the last registration will be used. 66 | */ 67 | static void registerShaderConfigSupplier(Identifier token, Supplier supplier) { 68 | ShaderConfigImpl.registerShaderConfigSupplier(token, supplier); 69 | } 70 | 71 | /** 72 | * Used by the renderer implementation - retrieves supplier of configuration declarations 73 | * to replace the given token when it is encountered in shader source. 74 | * 75 | *

If the token is not registered, will return a default supplier that outputs 76 | * a GLSL-friendly comment explaining it was not found. 77 | */ 78 | static Supplier getShaderConfigSupplier(Identifier token) { 79 | return ShaderConfigImpl.getShaderConfigSupplier(token); 80 | } 81 | 82 | /** 83 | * Mods should invoke this after changing configuration that affects supplier output 84 | * to force the renderer to recompile shaders. 85 | */ 86 | @SuppressWarnings("resource") 87 | static void invalidateShaderConfig() { 88 | MinecraftClient.getInstance().worldRenderer.reload(); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/event/HeldItemLightListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.event; 18 | 19 | import net.minecraft.entity.LivingEntity; 20 | import net.minecraft.item.ItemStack; 21 | 22 | import net.fabricmc.api.EnvType; 23 | import net.fabricmc.api.Environment; 24 | import net.fabricmc.fabric.api.event.Event; 25 | import net.fabricmc.fabric.api.event.EventFactory; 26 | 27 | import grondag.frex.api.light.ItemLight; 28 | 29 | @Environment(EnvType.CLIENT) 30 | @FunctionalInterface 31 | public interface HeldItemLightListener { 32 | /** 33 | * Use this event to add or modify held item lighting due to effects, worn items 34 | * or other conditions that aren't completely dependent on held items. The renderer will 35 | * call this event once per frame after the held light is retrieved for the current player 36 | * or camera entity. 37 | * 38 | *

Held lights for non-camera entities are currently not supported. 39 | * 40 | * @param holdingEntity The entity that is holding (or not holding) a light provider. 41 | * Currently this is always the camera entity. 42 | * 43 | * @param heldStack The item stack that was used to determine the default result. 44 | * May be empty. If no light was found, will be from the secondary hand. 45 | * 46 | * @param defaultResult The light result determined by the renderer. Will be the same in all 47 | * listener invocations. Use this to know if another listener has 48 | * already changed the current result. 49 | * 50 | * @param currentResult The light result that should be returned if the listener does not 51 | * modify it. May already have been changed by a prior listener. 52 | * Compare with default result to detect this. 53 | * 54 | * @return The light that should be used. Return {@link ItemLight#NONE} to disable 55 | * held light. Can be modified by subsequent listener invocations. 56 | */ 57 | ItemLight onGetHeldItemLight(LivingEntity holdingEntity, ItemStack heldStack, ItemLight defaultResult, ItemLight currentResult); 58 | 59 | Event EVENT = EventFactory.createArrayBacked(HeldItemLightListener.class, listeners -> (holdingEntity, heldStack, defaultResult, currentResult) -> { 60 | for (final HeldItemLightListener handler : listeners) { 61 | currentResult = handler.onGetHeldItemLight(holdingEntity, heldStack, defaultResult, currentResult); 62 | } 63 | 64 | return currentResult; 65 | }); 66 | 67 | /** For use by renderer implementations. */ 68 | static ItemLight apply(LivingEntity holdingEntity, ItemStack heldStack, ItemLight defaultResult) { 69 | return EVENT.invoker().onGetHeldItemLight(holdingEntity, heldStack, defaultResult, defaultResult); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/event/RenderRegionBakeListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.event; 18 | 19 | import java.util.List; 20 | import java.util.function.Predicate; 21 | 22 | import org.jetbrains.annotations.Nullable; 23 | 24 | import net.minecraft.block.BlockState; 25 | import net.minecraft.util.math.BlockPos; 26 | import net.minecraft.world.BlockRenderView; 27 | 28 | import net.fabricmc.api.EnvType; 29 | import net.fabricmc.api.Environment; 30 | 31 | import grondag.frex.impl.event.RenderRegionBakeListenerImpl; 32 | 33 | @Environment(EnvType.CLIENT) 34 | @FunctionalInterface 35 | public interface RenderRegionBakeListener { 36 | void bake(RenderRegionContext context, BlockStateRenderer blockStateRenderer); 37 | 38 | static void register(Predicate predicate, RenderRegionBakeListener listener) { 39 | RenderRegionBakeListenerImpl.register(predicate, listener); 40 | } 41 | 42 | /** 43 | * For use by renderer implementations. Implementations are responsible for providing a thread-safe list 44 | * instance and if populated, invoking all listeners in the list at the appropriate time. Renderer must 45 | * also clear the list instance if needed before calling. 46 | */ 47 | static void prepareInvocations(RenderRegionContext context, List listeners) { 48 | RenderRegionBakeListenerImpl.prepareInvocations(context, listeners); 49 | } 50 | 51 | @Environment(EnvType.CLIENT) 52 | public interface RenderRegionContext { 53 | /** 54 | * Not available until chunk baking. Predicate tests must 55 | * be done based on block position only. 56 | */ 57 | @Nullable BlockRenderView blockView(); 58 | 59 | /** 60 | * Min position (inclusive) of the area being built. 61 | * The region backing {@link #blockView()} will typically have some padding 62 | * extending beyond this. 63 | */ 64 | BlockPos origin(); 65 | 66 | /** 67 | * Size of the area being built, on x-axis,, including the origin. 68 | * The region backing {@link #blockView()} will typically have some padding 69 | * extending beyond this. 70 | * 71 | *

In vanilla, regions are consistently 16x16x16. A renderer mod 72 | * could change region size so this should not be assumed. 73 | */ 74 | default int xSize() { 75 | return 16; 76 | } 77 | 78 | /** 79 | * Size of the area being built, on y-axis,, including the origin. 80 | * The region backing {@link #blockView()} will typically have some padding 81 | * extending beyond this. 82 | * 83 | *

In vanilla, regions are consistently 16x16x16. A renderer mod 84 | * could change region size so this should not be assumed. 85 | */ 86 | default int ySize() { 87 | return 16; 88 | } 89 | 90 | /** 91 | * Size of the area being built, on z-axis, including the origin. 92 | * The region backing {@link #blockView()} will typically have some padding 93 | * extending beyond this. 94 | * 95 | *

In vanilla, regions are consistently 16x16x16. A renderer mod 96 | * could change region size so this should not be assumed. 97 | */ 98 | default int zSize() { 99 | return 16; 100 | } 101 | } 102 | 103 | @Environment(EnvType.CLIENT) 104 | @FunctionalInterface 105 | public interface BlockStateRenderer { 106 | void bake(BlockPos pos, BlockState state); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/event/WorldRenderEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.event; 18 | 19 | import net.minecraft.client.MinecraftClient; 20 | import net.minecraft.client.render.Camera; 21 | import net.minecraft.client.render.GameRenderer; 22 | import net.minecraft.client.render.LightmapTextureManager; 23 | import net.minecraft.client.util.math.MatrixStack; 24 | import net.minecraft.util.math.Matrix4f; 25 | import net.minecraft.util.profiler.Profiler; 26 | 27 | import net.fabricmc.api.EnvType; 28 | import net.fabricmc.api.Environment; 29 | import net.fabricmc.fabric.api.event.Event; 30 | import net.fabricmc.fabric.api.event.EventFactory; 31 | 32 | /** 33 | * 34 | * @deprecated Migrate to to fabric render events module when available. Or to frex-events as interim. Will be removed for 1.17. 35 | */ 36 | @Deprecated 37 | @Environment(EnvType.CLIENT) 38 | public final class WorldRenderEvent { 39 | /** 40 | * Called at the start of world rendering. 41 | */ 42 | @Deprecated 43 | public static final Event BEFORE_WORLD_RENDER = EventFactory.createArrayBacked(BeforeWorldRender.class, callbacks -> (matrices, tickDelta, limitTime, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, matrix4f) -> { 44 | if (EventFactory.isProfilingEnabled()) { 45 | final Profiler profiler = MinecraftClient.getInstance().getProfiler(); 46 | profiler.push("frexBeforeWorldRender"); 47 | 48 | for (final BeforeWorldRender event : callbacks) { 49 | profiler.push(EventFactory.getHandlerName(event)); 50 | event.beforeWorldRender(matrices, tickDelta, limitTime, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, matrix4f); 51 | profiler.pop(); 52 | } 53 | 54 | profiler.pop(); 55 | } else { 56 | for (final BeforeWorldRender event : callbacks) { 57 | event.beforeWorldRender(matrices, tickDelta, limitTime, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, matrix4f); 58 | } 59 | } 60 | }); 61 | 62 | /** 63 | * Called after world rendering. 64 | */ 65 | @Deprecated 66 | public static final Event AFTER_WORLD_RENDER = EventFactory.createArrayBacked(AfterWorldRender.class, callbacks -> (matrices, tickDelta, limitTime, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, matrix4f) -> { 67 | if (EventFactory.isProfilingEnabled()) { 68 | final Profiler profiler = MinecraftClient.getInstance().getProfiler(); 69 | profiler.push("frexAfterWorldRender"); 70 | 71 | for (final AfterWorldRender event : callbacks) { 72 | profiler.push(EventFactory.getHandlerName(event)); 73 | event.afterWorldRender(matrices, tickDelta, limitTime, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, matrix4f); 74 | profiler.pop(); 75 | } 76 | 77 | profiler.pop(); 78 | } else { 79 | for (final AfterWorldRender event : callbacks) { 80 | event.afterWorldRender(matrices, tickDelta, limitTime, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, matrix4f); 81 | } 82 | } 83 | }); 84 | 85 | public interface BeforeWorldRender { 86 | void beforeWorldRender(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f); 87 | } 88 | 89 | public interface AfterWorldRender { 90 | void afterWorldRender(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/fluid/FluidQuadSupplier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.fluid; 18 | 19 | import java.util.Random; 20 | import java.util.function.BiFunction; 21 | import java.util.function.Function; 22 | import java.util.function.Supplier; 23 | 24 | import net.minecraft.fluid.Fluid; 25 | import net.minecraft.item.ItemStack; 26 | import net.minecraft.util.Identifier; 27 | 28 | import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel; 29 | import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; 30 | 31 | import grondag.frex.impl.fluid.FluidQuadSupplierImpl; 32 | 33 | /** 34 | * Identical in operation to {@link FabricBakedModel#emitBlockQuads} but for fluids. 35 | * 36 | *

A FREX-compliant renderer will call this - in addition to the block quad emitter - for 37 | * block state with a non-empty fluid state. Block state is passed instead of fluid state 38 | * to keep the method signature compact and provide access to the block state if needed. 39 | */ 40 | @FunctionalInterface 41 | public interface FluidQuadSupplier extends FabricBakedModel { 42 | @Override 43 | default boolean isVanillaAdapter() { 44 | return false; 45 | } 46 | 47 | @Override 48 | default void emitItemQuads(ItemStack stack, Supplier randomSupplier, RenderContext context) { 49 | // NOOP 50 | } 51 | 52 | static FluidQuadSupplier get(Fluid forFluid) { 53 | return FluidQuadSupplierImpl.get(forFluid); 54 | } 55 | 56 | /** 57 | * Add a FluidQuadSupplier factory for the given fluid. 58 | * 59 | *

Accepts a factory so that instances can be recreated when render state 60 | * is invalidated. This allows implementations to cache sprites or other elements of 61 | * render state without checking for or handling reloads. 62 | */ 63 | static void registerFactory(Function factory, Identifier forFluid) { 64 | FluidQuadSupplierImpl.registerFactory(factory, forFluid); 65 | } 66 | 67 | /** 68 | * To be called 1X by renderer implementation. Provides the logic 69 | * that will implement fluid : supplier factory. 70 | * 71 | *

Handler gets the fluid and the associated factory if available. 72 | */ 73 | static void setReloadHandler(BiFunction, FluidQuadSupplier> handler) { 74 | FluidQuadSupplierImpl.setReloadHandler(handler); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/light/ItemLight.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.light; 18 | 19 | import net.minecraft.item.ItemStack; 20 | 21 | import grondag.frex.impl.light.ItemLightLoader; 22 | import grondag.frex.impl.light.SimpleItemLight; 23 | 24 | @FunctionalInterface 25 | public interface ItemLight { 26 | /** 27 | * How far the light can reach. A value of 1.0 means the light 28 | * can reach the maximum configured distance, 12 blocks by default. 29 | * Zero disables the light source. 30 | * @return 31 | */ 32 | float intensity(); 33 | 34 | /** 35 | * Red light component. 36 | * @return 0 to 1 37 | */ 38 | default float red() { 39 | return 1f; 40 | } 41 | 42 | /** 43 | * Green light component. 44 | * @return 0 to 1 45 | */ 46 | default float green() { 47 | return 1f; 48 | } 49 | 50 | /** 51 | * Blue light component. 52 | * @return 0 to 1 53 | */ 54 | default float blue() { 55 | return 1f; 56 | } 57 | 58 | /** 59 | * Control if the light should work when submerged. 60 | * @return true if works in a fluid 61 | */ 62 | default boolean worksInFluid() { 63 | return true; 64 | } 65 | 66 | /** 67 | * Setting to a value < 360 will result in a spot light effect. 68 | * This is the angle of full brightness within the light cone. 69 | * Attenuation is assumed to be the same as for non-spot lights. 70 | */ 71 | default int innerConeAngleDegrees() { 72 | return 360; 73 | } 74 | 75 | /** 76 | * The angle of reduced brightness around the inner light cone. 77 | * Set to a value < 360 but greater than {@link #innerConeAngleDegrees()} 78 | * to create a fall-off effect around a spot light. 79 | * Attenuation is assumed to be the same as for non-spot lights. 80 | */ 81 | default int outerConeAngleDegrees() { 82 | return 360; 83 | } 84 | 85 | ItemLight NONE = () -> 0; 86 | 87 | static ItemLight get(ItemStack stack) { 88 | if (stack == null || stack.isEmpty()) { 89 | return NONE; 90 | } else if (stack.getItem() instanceof ItemLightProvider) { 91 | return ((ItemLightProvider) stack.getItem()).getItemLight(stack); 92 | } else { 93 | return ItemLightLoader.get(stack); 94 | } 95 | } 96 | 97 | static ItemLight of(float intensity, float red, float green, float blue, boolean worksInFluid) { 98 | return new SimpleItemLight(intensity, red, green, blue, worksInFluid, 360, 360); 99 | } 100 | 101 | static ItemLight of(float intensity, float red, float green, float blue, boolean worksInFluid, int innerConeAngleDegrees, int outerConeAngleDegrees) { 102 | innerConeAngleDegrees = Math.min(360, Math.max(1, innerConeAngleDegrees)); 103 | outerConeAngleDegrees = Math.min(360, Math.max(innerConeAngleDegrees, outerConeAngleDegrees)); 104 | return new SimpleItemLight(intensity, red, green, blue, worksInFluid, innerConeAngleDegrees, outerConeAngleDegrees); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/light/ItemLightProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.light; 18 | 19 | import net.minecraft.item.ItemStack; 20 | 21 | /** 22 | * Implement on items to return light sources programmatically. 23 | */ 24 | @FunctionalInterface 25 | public interface ItemLightProvider { 26 | ItemLight getItemLight(ItemStack stack); 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/material/BlockEntityMaterialMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.material; 18 | 19 | import net.minecraft.block.BlockState; 20 | import net.minecraft.block.entity.BlockEntityType; 21 | 22 | import grondag.frex.impl.material.MaterialMapLoader; 23 | 24 | /** 25 | * Transforms materials for block entities. 26 | * Requires FREX material extensions. 27 | */ 28 | @FunctionalInterface 29 | public interface BlockEntityMaterialMap { 30 | RenderMaterial getMapped(RenderMaterial material, BlockState blockState, MaterialFinder finder); 31 | 32 | static BlockEntityMaterialMap get(BlockEntityType blockEntityType) { 33 | return MaterialMapLoader.INSTANCE.get(blockEntityType); 34 | } 35 | 36 | BlockEntityMaterialMap IDENTITY = (m, s, f) -> m; 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/material/EntityMaterialMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.material; 18 | 19 | import net.minecraft.entity.Entity; 20 | import net.minecraft.entity.EntityType; 21 | 22 | import grondag.frex.impl.material.MaterialMapLoader; 23 | 24 | /** 25 | * Transforms materials for entities. 26 | * Requires FREX material extensions. 27 | */ 28 | @FunctionalInterface 29 | public interface EntityMaterialMap { 30 | RenderMaterial getMapped(RenderMaterial material, Entity entity, MaterialFinder finder); 31 | 32 | static EntityMaterialMap get(EntityType entityType) { 33 | return MaterialMapLoader.INSTANCE.get(entityType); 34 | } 35 | 36 | EntityMaterialMap IDENTITY = (m, e, f) -> m; 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/material/FrexVertexConsumerProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.material; 18 | 19 | import net.minecraft.client.render.VertexConsumer; 20 | import net.minecraft.client.render.VertexConsumerProvider; 21 | 22 | /** 23 | * Extension of {@code VertexConsumerProvider} that provides consumers 24 | * via {@code RenderMaterial} in addition to render layer. Use this to 25 | * emit polygons in Entity and BlockEntity renderers that rely on a custom 26 | * {@code RenderMaterial}. 27 | * 28 | *

If the renderer implementation supports this feature, then {@code VertexConsumerProvider} 29 | * parameters passed during world rendering can probably be safely cast to this interface. 30 | * However, some mods could make calls to block or entity renderer such that 31 | * this interface isn't available there. 32 | */ 33 | public interface FrexVertexConsumerProvider extends VertexConsumerProvider { 34 | /** 35 | * Obtain the appropriate vertex consumer for the given material. 36 | * @param material The material of one or more polygons to be rendered. 37 | * @return VertexConsumer instance to accept polygons for the given material. May not be a vanilla implementation. 38 | */ 39 | VertexConsumer getConsumer(RenderMaterial material); 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/material/MaterialCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.material; 18 | 19 | import org.jetbrains.annotations.ApiStatus.Experimental; 20 | 21 | @Experimental 22 | public interface MaterialCondition { 23 | /** 24 | * Called at most once per frame. 25 | */ 26 | boolean compute(); 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/material/MaterialLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.material; 18 | 19 | import org.jetbrains.annotations.ApiStatus.Experimental; 20 | 21 | import net.minecraft.util.Identifier; 22 | 23 | import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; 24 | 25 | import grondag.frex.impl.material.MaterialLoaderImpl; 26 | 27 | /** 28 | * For use by model loading libraries - handles deserialization of material JSON 29 | * files, creating and registering them in the renderer. Note that resource reload 30 | * events do not cause materials to be reloaded, but shader source will be refreshed 31 | * if the renderer supports that feature. 32 | * 33 | *

Loaded materials will be Fabric API materials if no FREX compliant renderer is present 34 | * and the materials will (obviously) not have shaders in that case. 35 | * 36 | *

Renderer Authors: This interface is implemented by FREX - you do not need to implement it. 37 | */ 38 | @Experimental 39 | public interface MaterialLoader { 40 | /** 41 | * Material files should be in {@code assets//materials} and have a {@code .json} suffix. 42 | * 43 | * @param id domain and path of material json. See notes above. 44 | * @return Loaded material if successful, null if file not found or specified features are unsupported. 45 | */ 46 | static RenderMaterial getOrLoadMaterial(Identifier id) { 47 | return MaterialLoaderImpl.loadMaterial(id); 48 | } 49 | 50 | /** 51 | * @deprecated Use the better-named {@link #getOrLoadMaterial(Identifier)} 52 | */ 53 | @Deprecated 54 | static RenderMaterial loadMaterial(Identifier id) { 55 | return MaterialLoaderImpl.loadMaterial(id); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/material/MaterialMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.material; 18 | 19 | import org.jetbrains.annotations.Nullable; 20 | 21 | import net.minecraft.block.BlockState; 22 | import net.minecraft.client.texture.Sprite; 23 | import net.minecraft.fluid.FluidState; 24 | import net.minecraft.item.ItemStack; 25 | import net.minecraft.particle.ParticleType; 26 | 27 | import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; 28 | 29 | import grondag.frex.impl.material.MaterialMapLoader; 30 | 31 | public interface MaterialMap { 32 | /** 33 | * Used by renderer to avoid overhead of sprite reverse lookup when not needed. 34 | * @return true if map is sprite-sensitive, false if always returns same material 35 | */ 36 | boolean needsSprite(); 37 | 38 | /** 39 | * Returns null if sprite is unmapped or if this is the default material map. 40 | */ 41 | @Nullable RenderMaterial getMapped(@Nullable Sprite sprite); 42 | 43 | static MaterialMap get(BlockState state) { 44 | return MaterialMapLoader.INSTANCE.get(state); 45 | } 46 | 47 | static MaterialMap get(FluidState fluidState) { 48 | return MaterialMapLoader.INSTANCE.get(fluidState); 49 | } 50 | 51 | static MaterialMap getForParticle(ParticleType particleType) { 52 | return MaterialMapLoader.INSTANCE.get(particleType); 53 | } 54 | 55 | static MaterialMap defaultMaterialMap() { 56 | return MaterialMapLoader.DEFAULT_MAP; 57 | } 58 | 59 | static MaterialMap get(ItemStack itemStack) { 60 | return MaterialMapLoader.INSTANCE.get(itemStack); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/material/RenderMaterial.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.material; 18 | 19 | import org.jetbrains.annotations.ApiStatus.ScheduledForRemoval; 20 | import org.jetbrains.annotations.Nullable; 21 | 22 | import net.minecraft.util.Identifier; 23 | 24 | import net.fabricmc.fabric.api.renderer.v1.material.BlendMode; 25 | 26 | public interface RenderMaterial extends net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial { 27 | @Nullable BlendMode blendMode(); 28 | 29 | boolean blur(); 30 | 31 | MaterialCondition condition(); 32 | 33 | boolean cull(); 34 | 35 | int cutout(); 36 | 37 | int decal(); 38 | 39 | int depthTest(); 40 | 41 | @Deprecated 42 | @ScheduledForRemoval 43 | default boolean disableAo(int spriteIndex) { 44 | return disableAo(); 45 | } 46 | 47 | boolean disableAo(); 48 | 49 | @Deprecated 50 | @ScheduledForRemoval 51 | default boolean disableColorIndex(int spriteIndex) { 52 | return disableColorIndex(); 53 | } 54 | 55 | boolean disableColorIndex(); 56 | 57 | @Deprecated 58 | @ScheduledForRemoval 59 | default boolean disableDiffuse(int spriteIndex) { 60 | return disableDiffuse(); 61 | } 62 | 63 | boolean disableDiffuse(); 64 | 65 | boolean discardsTexture(); 66 | 67 | @Deprecated 68 | @ScheduledForRemoval 69 | default boolean emissive(int spriteIndex) { 70 | return emissive(); 71 | } 72 | 73 | boolean emissive(); 74 | 75 | /** 76 | * @deprecated No longer used or valid. Always returns true. 77 | * Will be removed in a subsequent release. 78 | */ 79 | @Deprecated 80 | @ScheduledForRemoval 81 | default boolean enableLightmap() { 82 | return true; 83 | } 84 | 85 | boolean flashOverlay(); 86 | 87 | boolean fog(); 88 | 89 | /** 90 | * @deprecated No longer used or valid. Always returns false. 91 | * Will be removed in a subsequent release. 92 | */ 93 | @Deprecated 94 | @ScheduledForRemoval 95 | default boolean gui() { 96 | return false; 97 | } 98 | 99 | Identifier fragmentShaderId(); 100 | 101 | String fragmentShader(); 102 | 103 | boolean hurtOverlay(); 104 | 105 | boolean lines(); 106 | 107 | boolean sorted(); 108 | 109 | @Override 110 | @Deprecated 111 | @ScheduledForRemoval 112 | default int spriteDepth() { 113 | return 1; 114 | } 115 | 116 | int target(); 117 | 118 | Identifier textureId(); 119 | 120 | String texture(); 121 | 122 | int transparency(); 123 | 124 | boolean unmipped(); 125 | 126 | Identifier vertexShaderId(); 127 | 128 | String vertexShader(); 129 | 130 | int writeMask(); 131 | 132 | /** 133 | * If this material is derived from and/or represents a vanilla {@code RenderLayer} 134 | * and that layer has an associated name (given by Mojang) the name of that layer. 135 | * Value is undefined in other cases. 136 | * 137 | * @return name of associated vanilla {@code RenderLayer} if any, undefined otherwise 138 | */ 139 | String renderLayerName(); 140 | 141 | /** 142 | * True when material should cast shadows. Pipelines that lack 143 | * shadowmaps or some other mechanism for realistic shadows will 144 | * ignore this. Defaults to true. 145 | * 146 | *

Set false for materials that render as solid for practical 147 | * reasons but should not cast shadows. Beacon beams are a vanilla example. 148 | * 149 | * @return true if material should cast shadows 150 | */ 151 | boolean castShadows(); 152 | } 153 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/material/Uniform.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.material; 18 | 19 | import java.nio.FloatBuffer; 20 | import java.nio.IntBuffer; 21 | 22 | import org.jetbrains.annotations.ApiStatus.Experimental; 23 | 24 | import net.minecraft.util.math.Matrix3f; 25 | import net.minecraft.util.math.Matrix4f; 26 | 27 | /** 28 | * Interfaces for uniform initialization. Called by renderer when uniform should 29 | * be potentially updated from game state. 30 | * 31 | *

See {@link ShaderManager} and {@link UniformRefreshFrequency} 32 | */ 33 | @Experimental 34 | public interface Uniform { 35 | @FunctionalInterface 36 | public interface Uniform1f extends Uniform { 37 | void set(float v0); 38 | } 39 | 40 | @FunctionalInterface 41 | public interface Uniform2f extends Uniform { 42 | void set(float v0, float v1); 43 | } 44 | 45 | @FunctionalInterface 46 | public interface Uniform3f extends Uniform { 47 | void set(float v0, float v1, float v2); 48 | } 49 | 50 | @FunctionalInterface 51 | public interface Uniform4f extends Uniform { 52 | void set(float v0, float v1, float v2, float v3); 53 | } 54 | 55 | public interface UniformArrayf extends Uniform { 56 | void set(float[] v); 57 | 58 | void setExternal(FloatBuffer buff); 59 | } 60 | 61 | public interface UniformArray4f extends Uniform { 62 | void set(float[] v); 63 | 64 | void setExternal(FloatBuffer buff); 65 | } 66 | 67 | @FunctionalInterface 68 | public interface Uniform1i extends Uniform { 69 | void set(int v0); 70 | } 71 | 72 | @FunctionalInterface 73 | public interface Uniform2i extends Uniform { 74 | void set(int v0, int v1); 75 | } 76 | 77 | @FunctionalInterface 78 | public interface Uniform3i extends Uniform { 79 | void set(int v0, int v1, int v2); 80 | } 81 | 82 | @FunctionalInterface 83 | public interface Uniform4i extends Uniform { 84 | void set(int v0, int v1, int v2, int v3); 85 | } 86 | 87 | @FunctionalInterface 88 | public interface UniformArrayi extends Uniform { 89 | void set(int[] v); 90 | } 91 | 92 | @FunctionalInterface 93 | public interface Uniform1ui extends Uniform { 94 | void set(int v0); 95 | } 96 | 97 | @FunctionalInterface 98 | public interface Uniform2ui extends Uniform { 99 | void set(int v0, int v1); 100 | } 101 | 102 | @FunctionalInterface 103 | public interface Uniform3ui extends Uniform { 104 | void set(int v0, int v1, int v2); 105 | } 106 | 107 | @FunctionalInterface 108 | public interface Uniform4ui extends Uniform { 109 | void set(int v0, int v1, int v2, int v3); 110 | } 111 | 112 | public interface UniformArrayui extends Uniform { 113 | void set(int[] v); 114 | 115 | void setExternal(IntBuffer data); 116 | } 117 | 118 | @FunctionalInterface 119 | public interface UniformMatrix4f extends Uniform { 120 | void set(Matrix4f matrix); 121 | } 122 | 123 | @FunctionalInterface 124 | public interface UniformMatrix3f extends Uniform { 125 | void set(Matrix3f matrix); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/material/UniformRefreshFrequency.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.material; 18 | 19 | import org.jetbrains.annotations.ApiStatus.Experimental; 20 | 21 | /** 22 | * Governs how often shader uniform initializers are called. 23 | * 24 | *

In all cases, initializers will only be called if a shader using the uniform 25 | * is activated and values are only uploaded if they have changed. 26 | */ 27 | @Experimental 28 | public enum UniformRefreshFrequency { 29 | /** 30 | * Uniform initializer only called 1X a time of program load or reload. 31 | */ 32 | ON_LOAD, 33 | 34 | /** 35 | * Uniform initializer called 1X per game tick. (20X per second) 36 | */ 37 | PER_TICK, 38 | 39 | /** 40 | * Uniform initializer called 1X per render frame. (Variable frequency.) 41 | */ 42 | PER_FRAME 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/mesh/FrexVertexConsumer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | /* 18 | * Copyright 2019, 2020 grondag 19 | * 20 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 21 | * use this file except in compliance with the License. You may obtain a copy 22 | * of the License at 23 | * 24 | * http://www.apache.org/licenses/LICENSE-2.0 25 | * 26 | * Unless required by applicable law or agreed to in writing, software 27 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 28 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 29 | * License for the specific language governing permissions and limitations under 30 | * the License. 31 | */ 32 | 33 | package grondag.frex.api.mesh; 34 | 35 | import org.jetbrains.annotations.ApiStatus.Experimental; 36 | 37 | import net.minecraft.client.render.VertexConsumer; 38 | import net.minecraft.util.math.Matrix3f; 39 | import net.minecraft.util.math.Matrix4f; 40 | 41 | import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; 42 | 43 | @Experimental 44 | public interface FrexVertexConsumer extends VertexConsumer { 45 | /** 46 | * Sets state to be included with normals and material if they are included. Call once 47 | * whenever material changes, including default state or revert 48 | * to default state of the render state. 49 | */ 50 | FrexVertexConsumer material(RenderMaterial material); 51 | 52 | FrexVertexConsumer defaultMaterial(RenderMaterial material); 53 | 54 | FrexVertexConsumer vertex(float x, float y, float z); 55 | 56 | /** 57 | * @param color rgba - alpha is high byte, red and blue pre-swapped if needed 58 | */ 59 | FrexVertexConsumer color(int color); 60 | 61 | @Override 62 | default FrexVertexConsumer vertex(double x, double y, double z) { 63 | vertex((float) x, (float) y, (float) z); 64 | return this; 65 | } 66 | 67 | @Override 68 | FrexVertexConsumer vertex(Matrix4f matrix, float x, float y, float z); 69 | 70 | @Override 71 | FrexVertexConsumer normal(Matrix3f matrix, float x, float y, float z); 72 | 73 | @Override 74 | FrexVertexConsumer color(int red, int green, int blue, int alpha); 75 | 76 | @Override 77 | FrexVertexConsumer texture(float u, float v); 78 | 79 | @Override 80 | FrexVertexConsumer overlay(int u, int v); 81 | 82 | @Override 83 | FrexVertexConsumer light(int u, int v); 84 | 85 | @Override 86 | FrexVertexConsumer normal(float x, float y, float z); 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/mesh/MutableQuadView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.mesh; 18 | 19 | import org.jetbrains.annotations.ApiStatus.ScheduledForRemoval; 20 | import org.jetbrains.annotations.Nullable; 21 | 22 | import net.minecraft.client.render.model.BakedQuad; 23 | import net.minecraft.client.texture.Sprite; 24 | import net.minecraft.util.math.Direction; 25 | import net.minecraft.util.math.Vec3f; 26 | 27 | import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; 28 | 29 | public interface MutableQuadView extends net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView { 30 | @Override 31 | MutableQuadView material(RenderMaterial material); 32 | 33 | @Override 34 | @Nullable 35 | MutableQuadView cullFace(@Nullable Direction face); 36 | 37 | @Override 38 | @Nullable 39 | MutableQuadView nominalFace(Direction face); 40 | 41 | @Override 42 | MutableQuadView colorIndex(int colorIndex); 43 | 44 | @Override 45 | @Deprecated 46 | MutableQuadView fromVanilla(int[] quadData, int startIndex, boolean isItem); 47 | 48 | @Override 49 | MutableQuadView fromVanilla(BakedQuad quad, RenderMaterial material, Direction cullFace); 50 | 51 | @Override 52 | MutableQuadView tag(int tag); 53 | 54 | @Override 55 | MutableQuadView pos(int vertexIndex, float x, float y, float z); 56 | 57 | @Override 58 | default MutableQuadView pos(int vertexIndex, Vec3f vec) { 59 | return pos(vertexIndex, vec.getX(), vec.getY(), vec.getZ()); 60 | } 61 | 62 | @Override 63 | MutableQuadView normal(int vertexIndex, float x, float y, float z); 64 | 65 | @Override 66 | default MutableQuadView normal(int vertexIndex, Vec3f vec) { 67 | return normal(vertexIndex, vec.getX(), vec.getY(), vec.getZ()); 68 | } 69 | 70 | default MutableQuadView tangent(int vertexIndex, Vec3f vec) { 71 | tangent(vertexIndex, vec.getX(), vec.getY(), vec.getZ()); 72 | return this; 73 | } 74 | 75 | MutableQuadView tangent(int vertexIndex, float x, float y, float z); 76 | 77 | @Override 78 | MutableQuadView lightmap(int vertexIndex, int lightmap); 79 | 80 | @Override 81 | default MutableQuadView lightmap(int b0, int b1, int b2, int b3) { 82 | lightmap(0, b0); 83 | lightmap(1, b1); 84 | lightmap(2, b2); 85 | lightmap(3, b3); 86 | return this; 87 | } 88 | 89 | @Override 90 | @Deprecated 91 | @ScheduledForRemoval 92 | default MutableQuadView spriteColor(int vertexIndex, int spriteIndex, int color) { 93 | return vertexColor(vertexIndex, color); 94 | } 95 | 96 | /** 97 | * Set color for given vertex. 98 | */ 99 | MutableQuadView vertexColor(int vertexIndex, int color); 100 | 101 | @Override 102 | @Deprecated 103 | @ScheduledForRemoval 104 | default MutableQuadView spriteColor(int spriteIndex, int c0, int c1, int c2, int c3) { 105 | return quadColor(c0, c1, c2, c3); 106 | } 107 | 108 | /** 109 | * Convenience: set color for all vertices at once. 110 | */ 111 | default MutableQuadView quadColor(int c0, int c1, int c2, int c3) { 112 | vertexColor(0, c0); 113 | vertexColor(1, c1); 114 | vertexColor(2, c2); 115 | vertexColor(3, c3); 116 | return this; 117 | } 118 | 119 | @Override 120 | @Deprecated 121 | @ScheduledForRemoval 122 | default MutableQuadView sprite(int vertexIndex, int spriteIndex, float u, float v) { 123 | return sprite(vertexIndex, u, v); 124 | } 125 | 126 | /** 127 | * Set sprite atlas coordinates. 128 | */ 129 | MutableQuadView sprite(int vertexIndex, float u, float v); 130 | 131 | @Override 132 | @Deprecated 133 | @ScheduledForRemoval 134 | default MutableQuadView spriteBake(int spriteIndex, Sprite sprite, int bakeFlags) { 135 | return spriteBake(sprite, bakeFlags); 136 | } 137 | 138 | /** 139 | * Assigns sprite atlas u,v coordinates to this quad for the given sprite. 140 | * Can handle UV locking, rotation, interpolation, etc. Control this behavior 141 | * by passing additive combinations of the BAKE_ flags defined in this interface. 142 | * Behavior for {@code spriteIndex > 0} is currently undefined. 143 | */ 144 | MutableQuadView spriteBake(Sprite sprite, int bakeFlags); 145 | } 146 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/mesh/QuadEmitter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.mesh; 18 | 19 | import org.jetbrains.annotations.ApiStatus.ScheduledForRemoval; 20 | 21 | import net.minecraft.client.texture.Sprite; 22 | import net.minecraft.util.math.Direction; 23 | import net.minecraft.util.math.Vec3f; 24 | 25 | import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; 26 | 27 | public interface QuadEmitter extends net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter, MutableQuadView { 28 | @Override 29 | QuadEmitter material(RenderMaterial material); 30 | 31 | @Override 32 | QuadEmitter cullFace(Direction face); 33 | 34 | @Override 35 | QuadEmitter nominalFace(Direction face); 36 | 37 | @Override 38 | QuadEmitter colorIndex(int colorIndex); 39 | 40 | @Override 41 | QuadEmitter fromVanilla(int[] quadData, int startIndex, boolean isItem); 42 | 43 | @Override 44 | QuadEmitter tag(int tag); 45 | 46 | @Override 47 | QuadEmitter pos(int vertexIndex, float x, float y, float z); 48 | 49 | @Override 50 | default QuadEmitter pos(int vertexIndex, Vec3f vec) { 51 | MutableQuadView.super.pos(vertexIndex, vec); 52 | return this; 53 | } 54 | 55 | @Override 56 | QuadEmitter normal(int vertexIndex, float x, float y, float z); 57 | 58 | @Override 59 | default QuadEmitter normal(int vertexIndex, Vec3f vec) { 60 | MutableQuadView.super.normal(vertexIndex, vec); 61 | return this; 62 | } 63 | 64 | @Override 65 | default QuadEmitter tangent(int vertexIndex, Vec3f vec) { 66 | MutableQuadView.super.tangent(vertexIndex, vec); 67 | return this; 68 | } 69 | 70 | @Override 71 | QuadEmitter tangent(int vertexIndex, float x, float y, float z); 72 | 73 | @Override 74 | QuadEmitter lightmap(int vertexIndex, int lightmap); 75 | 76 | @Override 77 | default QuadEmitter lightmap(int b0, int b1, int b2, int b3) { 78 | MutableQuadView.super.lightmap(b0, b1, b2, b3); 79 | return this; 80 | } 81 | 82 | @Override 83 | @Deprecated 84 | @ScheduledForRemoval 85 | default QuadEmitter spriteColor(int vertexIndex, int spriteIndex, int color) { 86 | vertexColor(vertexIndex, color); 87 | return this; 88 | } 89 | 90 | @Override 91 | @Deprecated 92 | @ScheduledForRemoval 93 | default QuadEmitter spriteColor(int spriteIndex, int c0, int c1, int c2, int c3) { 94 | quadColor(c0, c1, c2, c3); 95 | return this; 96 | } 97 | 98 | @Override 99 | @Deprecated 100 | @ScheduledForRemoval 101 | default QuadEmitter sprite(int vertexIndex, int spriteIndex, float u, float v) { 102 | sprite(vertexIndex, u, v); 103 | return this; 104 | } 105 | 106 | @Override 107 | @Deprecated 108 | @ScheduledForRemoval 109 | default QuadEmitter spriteUnitSquare(int spriteIndex) { 110 | sprite(0, 0, 0); 111 | sprite(1, 0, 1); 112 | sprite(2, 1, 1); 113 | sprite(3, 1, 0); 114 | return this; 115 | } 116 | 117 | @Override 118 | @Deprecated 119 | @ScheduledForRemoval 120 | default QuadEmitter spriteBake(int spriteIndex, Sprite sprite, int bakeFlags) { 121 | spriteBake(sprite, bakeFlags); 122 | return this; 123 | } 124 | 125 | @Override 126 | default QuadEmitter square(Direction nominalFace, float left, float bottom, float right, float top, float depth) { 127 | net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter.super.square(nominalFace, left, bottom, right, top, depth); 128 | return this; 129 | } 130 | 131 | @Override 132 | QuadEmitter emit(); 133 | } 134 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/api/model/LazyForwardingBakedModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.api.model; 18 | 19 | import java.util.List; 20 | import java.util.Random; 21 | import java.util.function.Supplier; 22 | 23 | import net.minecraft.block.BlockState; 24 | import net.minecraft.client.render.model.BakedModel; 25 | import net.minecraft.client.render.model.BakedQuad; 26 | import net.minecraft.client.render.model.json.ModelOverrideList; 27 | import net.minecraft.client.render.model.json.ModelTransformation; 28 | import net.minecraft.client.texture.Sprite; 29 | import net.minecraft.item.ItemStack; 30 | import net.minecraft.util.math.BlockPos; 31 | import net.minecraft.util.math.Direction; 32 | import net.minecraft.world.BlockRenderView; 33 | 34 | import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel; 35 | import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; 36 | 37 | /** 38 | * Improved base class for specialized model implementations that need to wrap other baked models. 39 | * Avoids boilerplate code for pass-through methods.}. 40 | */ 41 | public abstract class LazyForwardingBakedModel implements BakedModel, FabricBakedModel { 42 | protected BakedModel lazyWrapped; 43 | 44 | /** MUST BE THREAD-SAFE AND INVARIANT. */ 45 | protected abstract BakedModel createWrapped(); 46 | 47 | protected BakedModel wrapped() { 48 | BakedModel wrapped = lazyWrapped; 49 | 50 | if (wrapped == null) { 51 | wrapped = createWrapped(); 52 | lazyWrapped = wrapped; 53 | } 54 | 55 | return wrapped; 56 | } 57 | 58 | @Override 59 | public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) { 60 | ((FabricBakedModel) wrapped()).emitBlockQuads(blockView, state, pos, randomSupplier, context); 61 | } 62 | 63 | @Override 64 | public boolean isVanillaAdapter() { 65 | return ((FabricBakedModel) wrapped()).isVanillaAdapter(); 66 | } 67 | 68 | @Override 69 | public void emitItemQuads(ItemStack stack, Supplier randomSupplier, RenderContext context) { 70 | ((FabricBakedModel) wrapped()).emitItemQuads(stack, randomSupplier, context); 71 | } 72 | 73 | @Override 74 | public List getQuads(BlockState blockState, Direction face, Random rand) { 75 | return wrapped().getQuads(blockState, face, rand); 76 | } 77 | 78 | @Override 79 | public boolean useAmbientOcclusion() { 80 | return wrapped().useAmbientOcclusion(); 81 | } 82 | 83 | @Override 84 | public boolean hasDepth() { 85 | return wrapped().hasDepth(); 86 | } 87 | 88 | @Override 89 | public boolean isSideLit() { 90 | return wrapped().isSideLit(); 91 | } 92 | 93 | @Override 94 | public boolean isBuiltin() { 95 | return wrapped().isBuiltin(); 96 | } 97 | 98 | @Override 99 | public Sprite getParticleSprite() { 100 | return wrapped().getParticleSprite(); 101 | } 102 | 103 | @Override 104 | public ModelTransformation getTransformation() { 105 | return wrapped().getTransformation(); 106 | } 107 | 108 | @Override 109 | public ModelOverrideList getOverrides() { 110 | return wrapped().getOverrides(); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/RendererFeatureImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl; 18 | 19 | import org.jetbrains.annotations.ApiStatus.Internal; 20 | 21 | @Internal 22 | public class RendererFeatureImpl { 23 | private static final long[] FLAGS = new long[128]; 24 | 25 | public static boolean isAvailable(int featureId) { 26 | return (FLAGS[featureId >> 6] & (1L << (featureId & 63))) != 0; 27 | } 28 | 29 | public static void registerFeatures(int... features) { 30 | for (final int featureId : features) { 31 | FLAGS[featureId >> 6] |= (1L << (featureId & 63)); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/config/FlawlessFramesImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.config; 18 | 19 | import java.util.Collections; 20 | import java.util.IdentityHashMap; 21 | import java.util.Set; 22 | import java.util.function.Consumer; 23 | import java.util.function.Function; 24 | 25 | import net.fabricmc.loader.api.FabricLoader; 26 | 27 | import grondag.frex.Frex; 28 | 29 | public class FlawlessFramesImpl { 30 | private static class Controller implements Consumer { 31 | final String owner; 32 | boolean isActive = false; 33 | 34 | private Controller(String owner) { 35 | this.owner = owner; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return owner; 41 | } 42 | 43 | @Override 44 | public void accept(Boolean isActive) { 45 | if (this.isActive != isActive) { 46 | synchronized (ACTIVE) { 47 | if (this.isActive) { 48 | ACTIVE.remove(this); 49 | if (enableTrace) Frex.LOG.info("Deactivating Flawless Frames at request of " + owner); 50 | } else { 51 | ACTIVE.add(this); 52 | if (enableTrace) Frex.LOG.info("Activating Flawless Frames at request of " + owner); 53 | } 54 | 55 | this.isActive = isActive; 56 | 57 | if (enableTrace) { 58 | Frex.LOG.info("Flawless Frames current status is " + isActive()); 59 | if (isActive()) Frex.LOG.info("Current active controllers are: " + ACTIVE.toString()); 60 | } 61 | } 62 | } 63 | } 64 | } 65 | 66 | @SuppressWarnings("unchecked") 67 | public static void onClientInitialization() { 68 | final Function> provider = Controller::new; 69 | FabricLoader.getInstance().getEntrypoints("frex_flawless_frames", Consumer.class).forEach(api -> api.accept(provider)); 70 | } 71 | 72 | private static final Set ACTIVE = Collections.newSetFromMap(new IdentityHashMap()); 73 | private static boolean enableTrace = false; 74 | 75 | public static boolean isActive() { 76 | return !ACTIVE.isEmpty(); 77 | } 78 | 79 | public static void enableTrace(boolean enable) { 80 | enableTrace = enable; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/config/ShaderConfigImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.config; 18 | 19 | import java.util.function.Supplier; 20 | 21 | import com.google.common.base.Preconditions; 22 | import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; 23 | import org.jetbrains.annotations.ApiStatus.Internal; 24 | 25 | import net.minecraft.util.Identifier; 26 | 27 | import grondag.frex.Frex; 28 | 29 | @Internal 30 | public class ShaderConfigImpl { 31 | private static final Object2ObjectOpenHashMap> MAP = new Object2ObjectOpenHashMap<>(); 32 | 33 | public static Supplier getShaderConfigSupplier(Identifier token) { 34 | Preconditions.checkNotNull(token, "Encountered null shader config token. This is a bug in a mod."); 35 | 36 | return MAP.getOrDefault(token, () -> "// WARNING - INCLUDE TOKEN NOT FOUND: " + token.toString()); 37 | } 38 | 39 | public static void registerShaderConfigSupplier(Identifier token, Supplier supplier) { 40 | Preconditions.checkNotNull(token, "Encountered null shader config token. This is a bug in a mod."); 41 | Preconditions.checkNotNull(supplier, "Encountered null shader config supplier. This is a bug in a mod."); 42 | 43 | if (MAP.put(token, supplier) != null) { 44 | Frex.LOG.warn("ShaderConfigSupplier for token " + token.toString() + " was registered more than once. The last registration will be used."); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/event/BlockStateRendererImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.event; 18 | 19 | import net.minecraft.block.BlockState; 20 | import net.minecraft.client.render.block.BlockRenderManager; 21 | import net.minecraft.client.render.chunk.ChunkRendererRegion; 22 | import net.minecraft.client.render.model.BakedModel; 23 | import net.minecraft.client.util.math.MatrixStack; 24 | import net.minecraft.util.math.BlockPos; 25 | 26 | import net.fabricmc.fabric.impl.client.indigo.renderer.accessor.AccessChunkRendererRegion; 27 | 28 | import grondag.frex.api.event.RenderRegionBakeListener.BlockStateRenderer; 29 | 30 | public class BlockStateRendererImpl implements BlockStateRenderer { 31 | private BlockRenderManager blockRenderManager; 32 | private MatrixStack matrixStack; 33 | private ChunkRendererRegion chunkRendererRegion; 34 | 35 | public void prepare(BlockRenderManager blockRenderManager, MatrixStack matrixStack, ChunkRendererRegion chunkRendererRegion) { 36 | this.blockRenderManager = blockRenderManager; 37 | this.matrixStack = matrixStack; 38 | this.chunkRendererRegion = chunkRendererRegion; 39 | } 40 | 41 | @Override 42 | public void bake(BlockPos pos, BlockState state) { 43 | final BakedModel model = blockRenderManager.getModel(state); 44 | 45 | matrixStack.push(); 46 | matrixStack.translate(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15); 47 | ((AccessChunkRendererRegion) chunkRendererRegion).fabric_getRenderer().tesselateBlock(state, pos, model, matrixStack); 48 | matrixStack.pop(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/event/ChunkRenderConditionContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.event; 18 | 19 | import it.unimi.dsi.fastutil.objects.ObjectArrayList; 20 | import org.jetbrains.annotations.Nullable; 21 | 22 | import net.minecraft.util.math.BlockPos; 23 | import net.minecraft.world.BlockRenderView; 24 | 25 | import grondag.frex.api.event.RenderRegionBakeListener; 26 | import grondag.frex.api.event.RenderRegionBakeListener.RenderRegionContext; 27 | 28 | public class ChunkRenderConditionContext implements RenderRegionContext { 29 | public final ObjectArrayList listeners = new ObjectArrayList<>(); 30 | private final BlockPos.Mutable origin = new BlockPos.Mutable(); 31 | 32 | public ChunkRenderConditionContext prepare(int x, int y, int z) { 33 | listeners.clear(); 34 | origin.set(x, y, z); 35 | return this; 36 | } 37 | 38 | public @Nullable RenderRegionBakeListener[] getListeners() { 39 | if (listeners.isEmpty()) { 40 | return null; 41 | } else { 42 | return listeners.toArray(new RenderRegionBakeListener[listeners.size()]); 43 | } 44 | } 45 | 46 | @Override 47 | public BlockRenderView blockView() { 48 | return null; 49 | } 50 | 51 | @Override 52 | public BlockPos origin() { 53 | return origin; 54 | } 55 | 56 | public interface RenderRegionListenerProvider { 57 | @Nullable RenderRegionBakeListener[] frex_getRenderRegionListeners(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/event/ItemLightListenerImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.event; 18 | 19 | import java.util.List; 20 | import java.util.function.Predicate; 21 | 22 | import net.fabricmc.api.EnvType; 23 | import net.fabricmc.api.Environment; 24 | import net.fabricmc.fabric.api.event.Event; 25 | import net.fabricmc.fabric.api.event.EventFactory; 26 | 27 | import grondag.frex.api.event.RenderRegionBakeListener; 28 | import grondag.frex.api.event.RenderRegionBakeListener.RenderRegionContext; 29 | 30 | @Environment(EnvType.CLIENT) 31 | public class ItemLightListenerImpl { 32 | @Environment(EnvType.CLIENT) 33 | @FunctionalInterface 34 | private interface BakeHandler { 35 | void handle(RenderRegionContext context, List list); 36 | } 37 | 38 | private static class BakeHandlerImpl implements BakeHandler { 39 | private final Predicate predicate; 40 | private final RenderRegionBakeListener listener; 41 | 42 | private BakeHandlerImpl(Predicate predicate, RenderRegionBakeListener listener) { 43 | this.predicate = predicate; 44 | this.listener = listener; 45 | } 46 | 47 | @Override 48 | public void handle(RenderRegionContext context, List list) { 49 | if (predicate.test(context)) { 50 | list.add(listener); 51 | } 52 | } 53 | } 54 | 55 | private static final Event EVENT = EventFactory.createArrayBacked(BakeHandler.class, listeners -> (context, list) -> { 56 | for (final BakeHandler handler : listeners) { 57 | handler.handle(context, list); 58 | } 59 | }); 60 | 61 | public static void register(Predicate predicate, RenderRegionBakeListener handler) { 62 | EVENT.register(new BakeHandlerImpl(predicate, handler)); 63 | } 64 | 65 | public static void prepareInvocations(RenderRegionContext context, List list) { 66 | EVENT.invoker().handle(context, list); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/event/RenderRegionBakeListenerImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.event; 18 | 19 | import java.util.List; 20 | import java.util.function.Predicate; 21 | 22 | import net.fabricmc.api.EnvType; 23 | import net.fabricmc.api.Environment; 24 | import net.fabricmc.fabric.api.event.Event; 25 | import net.fabricmc.fabric.api.event.EventFactory; 26 | 27 | import grondag.frex.api.event.RenderRegionBakeListener; 28 | import grondag.frex.api.event.RenderRegionBakeListener.RenderRegionContext; 29 | 30 | @Environment(EnvType.CLIENT) 31 | public class RenderRegionBakeListenerImpl { 32 | @Environment(EnvType.CLIENT) 33 | @FunctionalInterface 34 | private interface BakeHandler { 35 | void handle(RenderRegionContext context, List list); 36 | } 37 | 38 | private static class BakeHandlerImpl implements BakeHandler { 39 | private final Predicate predicate; 40 | private final RenderRegionBakeListener listener; 41 | 42 | private BakeHandlerImpl(Predicate predicate, RenderRegionBakeListener listener) { 43 | this.predicate = predicate; 44 | this.listener = listener; 45 | } 46 | 47 | @Override 48 | public void handle(RenderRegionContext context, List list) { 49 | if (predicate.test(context)) { 50 | list.add(listener); 51 | } 52 | } 53 | } 54 | 55 | private static final Event EVENT = EventFactory.createArrayBacked(BakeHandler.class, listeners -> (context, list) -> { 56 | for (final BakeHandler handler : listeners) { 57 | handler.handle(context, list); 58 | } 59 | }); 60 | 61 | public static void register(Predicate predicate, RenderRegionBakeListener handler) { 62 | EVENT.register(new BakeHandlerImpl(predicate, handler)); 63 | } 64 | 65 | public static void prepareInvocations(RenderRegionContext context, List list) { 66 | EVENT.invoker().handle(context, list); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/fluid/FluidQuadSupplierImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.fluid; 18 | 19 | import java.util.IdentityHashMap; 20 | import java.util.function.BiFunction; 21 | import java.util.function.Function; 22 | 23 | import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; 24 | import org.jetbrains.annotations.ApiStatus.Internal; 25 | 26 | import net.minecraft.fluid.Fluid; 27 | import net.minecraft.util.Identifier; 28 | import net.minecraft.util.registry.Registry; 29 | 30 | import grondag.frex.Frex; 31 | import grondag.frex.api.fluid.FluidQuadSupplier; 32 | 33 | @Internal 34 | public class FluidQuadSupplierImpl { 35 | private static final Object2ObjectOpenHashMap> FACTORIES = new Object2ObjectOpenHashMap<>(); 36 | private static final IdentityHashMap SUPPLIERS = new IdentityHashMap<>(); 37 | private static BiFunction, FluidQuadSupplier> handler; 38 | 39 | public static void reload() { 40 | SUPPLIERS.clear(); 41 | 42 | if (handler != null) { 43 | Registry.FLUID.forEach(fluid -> { 44 | final Function factory = FACTORIES.get(Registry.FLUID.getId(fluid)); 45 | SUPPLIERS.put(fluid, handler.apply(fluid, factory)); 46 | }); 47 | } 48 | } 49 | 50 | public static FluidQuadSupplier get(Fluid forFluid) { 51 | return SUPPLIERS.get(forFluid); 52 | } 53 | 54 | public static void registerFactory(Function factory, Identifier forFluidId) { 55 | if (FACTORIES.put(forFluidId, factory) != null) { 56 | Frex.LOG.warn("A FluidQuadSupplier was registered more than once for fluid " + forFluidId.toString() + ". This is probably a mod conflict and the fluid may not render correctly."); 57 | } 58 | } 59 | 60 | public static void setReloadHandler(BiFunction, FluidQuadSupplier> handlerIn) { 61 | assert handler == null; 62 | handler = handlerIn; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/light/ItemLightDeserializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.light; 18 | 19 | import java.io.InputStreamReader; 20 | 21 | import com.google.gson.JsonObject; 22 | import org.jetbrains.annotations.ApiStatus.Internal; 23 | 24 | import net.minecraft.util.JsonHelper; 25 | 26 | import grondag.frex.api.light.ItemLight; 27 | 28 | @Internal 29 | public class ItemLightDeserializer { 30 | private ItemLightDeserializer() { } 31 | 32 | public static ItemLight deserialize(InputStreamReader reader) { 33 | final JsonObject obj = JsonHelper.deserialize(reader); 34 | 35 | final float intensity = JsonHelper.getFloat(obj, "intensity", 0f); 36 | 37 | if (intensity == 0) { 38 | return ItemLight.NONE; 39 | } 40 | 41 | final float red = JsonHelper.getFloat(obj, "red", 1f); 42 | final float green = JsonHelper.getFloat(obj, "green", 1f); 43 | final float blue = JsonHelper.getFloat(obj, "blue", 1f); 44 | final boolean worksInFluid = JsonHelper.getBoolean(obj, "worksInFluid", true); 45 | final int innerConeAngleDegrees = JsonHelper.getInt(obj, "innerConeAngleDegrees", 360); 46 | final int outerConeAngleDegrees = JsonHelper.getInt(obj, "outerConeAngleDegrees", innerConeAngleDegrees); 47 | 48 | return ItemLight.of(intensity, red, green, blue, worksInFluid, innerConeAngleDegrees, outerConeAngleDegrees); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/light/ItemLightLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.light; 18 | 19 | import java.io.FileNotFoundException; 20 | import java.io.InputStreamReader; 21 | import java.nio.charset.StandardCharsets; 22 | import java.util.Collection; 23 | import java.util.IdentityHashMap; 24 | import java.util.Iterator; 25 | import java.util.List; 26 | 27 | import com.google.common.collect.ImmutableList; 28 | 29 | import net.minecraft.item.Item; 30 | import net.minecraft.item.ItemStack; 31 | import net.minecraft.resource.Resource; 32 | import net.minecraft.resource.ResourceManager; 33 | import net.minecraft.util.Identifier; 34 | import net.minecraft.util.registry.Registry; 35 | 36 | import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; 37 | 38 | import grondag.frex.Frex; 39 | import grondag.frex.api.light.ItemLight; 40 | 41 | public class ItemLightLoader implements SimpleSynchronousResourceReloadListener { 42 | private ItemLightLoader() { } 43 | 44 | @Override 45 | public void reload(ResourceManager manager) { 46 | MAP.clear(); 47 | final Iterator items = Registry.ITEM.iterator(); 48 | 49 | while (items.hasNext()) { 50 | loadItem(manager, items.next()); 51 | } 52 | } 53 | 54 | private void loadItem(ResourceManager manager, Item item) { 55 | final Identifier itemId = Registry.ITEM.getId(item); 56 | final Identifier id = new Identifier(itemId.getNamespace(), "lights/item/" + itemId.getPath() + ".json"); 57 | 58 | try (Resource res = manager.getResource(id)) { 59 | final ItemLight light = ItemLightDeserializer.deserialize(new InputStreamReader(res.getInputStream(), StandardCharsets.UTF_8)); 60 | 61 | if (light != ItemLight.NONE) { 62 | MAP.put(item, light); 63 | } 64 | } catch (final FileNotFoundException e) { 65 | // eat these, lights are not required 66 | } catch (final Exception e) { 67 | Frex.LOG.info("Unable to load item light data for " + id.toString() + " due to exception " + e.toString()); 68 | } 69 | } 70 | 71 | @Override 72 | public Identifier getFabricId() { 73 | return id; 74 | } 75 | 76 | @Override 77 | public Collection getFabricDependencies() { 78 | return DEPS; 79 | } 80 | 81 | private static List DEPS = ImmutableList.of(); 82 | private static final Identifier id = new Identifier("frex:item_light"); 83 | public static final ItemLightLoader INSTANCE = new ItemLightLoader(); 84 | private static final IdentityHashMap MAP = new IdentityHashMap<>(); 85 | 86 | public static ItemLight get(ItemStack stack) { 87 | return MAP.getOrDefault(stack.getItem(), ItemLight.NONE); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/light/SimpleItemLight.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.light; 18 | 19 | import grondag.frex.api.light.ItemLight; 20 | 21 | public class SimpleItemLight implements ItemLight { 22 | private final float intensity; 23 | private final float red; 24 | private final float green; 25 | private final float blue; 26 | private final boolean worksInFluid; 27 | private final int innerConeAngleDegrees; 28 | private final int outerConeAngleDegrees; 29 | 30 | public SimpleItemLight( 31 | float intensity, 32 | float red, 33 | float green, 34 | float blue, 35 | boolean worksInFluid, 36 | int innerConeAngleDegrees, 37 | int outerConeAngleDegrees 38 | ) { 39 | this.intensity = intensity; 40 | this.red = red; 41 | this.green = green; 42 | this.blue = blue; 43 | this.worksInFluid = worksInFluid; 44 | this.innerConeAngleDegrees = innerConeAngleDegrees; 45 | this.outerConeAngleDegrees = outerConeAngleDegrees; 46 | } 47 | 48 | @Override 49 | public float intensity() { 50 | return intensity; 51 | } 52 | 53 | @Override 54 | public float red() { 55 | return red; 56 | } 57 | 58 | @Override 59 | public float green() { 60 | return green; 61 | } 62 | 63 | @Override 64 | public float blue() { 65 | return blue; 66 | } 67 | 68 | @Override 69 | public boolean worksInFluid() { 70 | return worksInFluid; 71 | } 72 | 73 | @Override 74 | public int innerConeAngleDegrees() { 75 | return innerConeAngleDegrees; 76 | } 77 | 78 | @Override 79 | public int outerConeAngleDegrees() { 80 | return outerConeAngleDegrees; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/BlockEntityMultiMaterialMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material; 18 | 19 | import java.util.function.BiPredicate; 20 | 21 | import org.jetbrains.annotations.ApiStatus.Internal; 22 | 23 | import net.minecraft.block.BlockState; 24 | 25 | import grondag.frex.api.material.BlockEntityMaterialMap; 26 | import grondag.frex.api.material.MaterialFinder; 27 | import grondag.frex.api.material.RenderMaterial; 28 | 29 | @Internal 30 | class BlockEntityMultiMaterialMap implements BlockEntityMaterialMap { 31 | private final BiPredicate[] predicates; 32 | private final MaterialTransform[] transforms; 33 | 34 | BlockEntityMultiMaterialMap(BiPredicate[] predicates, MaterialTransform[] transforms) { 35 | assert predicates != null; 36 | assert transforms != null; 37 | 38 | this.predicates = predicates; 39 | this.transforms = transforms; 40 | } 41 | 42 | @Override 43 | public RenderMaterial getMapped(RenderMaterial material, BlockState blockState, MaterialFinder finder) { 44 | final int limit = predicates.length; 45 | 46 | for (int i = 0; i < limit; ++i) { 47 | if (predicates[i].test(blockState, material)) { 48 | return transforms[i].transform(material, finder); 49 | } 50 | } 51 | 52 | return material; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/BlockEntitySingleMaterialMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material; 18 | 19 | import java.util.function.BiPredicate; 20 | 21 | import org.jetbrains.annotations.ApiStatus.Internal; 22 | 23 | import net.minecraft.block.BlockState; 24 | 25 | import grondag.frex.api.material.BlockEntityMaterialMap; 26 | import grondag.frex.api.material.MaterialFinder; 27 | import grondag.frex.api.material.RenderMaterial; 28 | 29 | @Internal 30 | class BlockEntitySingleMaterialMap implements BlockEntityMaterialMap { 31 | private final MaterialTransform transform; 32 | private final BiPredicate predicate; 33 | 34 | BlockEntitySingleMaterialMap(BiPredicate predicate, MaterialTransform transform) { 35 | this.predicate = predicate; 36 | this.transform = transform; 37 | } 38 | 39 | @Override 40 | public RenderMaterial getMapped(RenderMaterial material, BlockState blockState, MaterialFinder finder) { 41 | return predicate.test(blockState, material) ? transform.transform(material, finder) : material; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/DefaultedMultiMaterialMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material; 18 | 19 | import java.util.IdentityHashMap; 20 | 21 | import org.jetbrains.annotations.ApiStatus.Internal; 22 | 23 | import net.minecraft.client.texture.Sprite; 24 | 25 | import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; 26 | 27 | import grondag.frex.api.material.MaterialMap; 28 | 29 | @Internal 30 | class DefaultedMultiMaterialMap implements MaterialMap { 31 | protected final IdentityHashMap spriteMap; 32 | protected final RenderMaterial defaultMaterial; 33 | 34 | DefaultedMultiMaterialMap(RenderMaterial defaultMaterial, IdentityHashMap spriteMap) { 35 | this.defaultMaterial = defaultMaterial; 36 | this.spriteMap = spriteMap; 37 | } 38 | 39 | @Override 40 | public boolean needsSprite() { 41 | return true; 42 | } 43 | 44 | @Override 45 | public RenderMaterial getMapped(Sprite sprite) { 46 | return spriteMap.getOrDefault(sprite, defaultMaterial); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/EntityMultiMaterialMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material; 18 | 19 | import java.util.function.BiPredicate; 20 | 21 | import org.jetbrains.annotations.ApiStatus.Internal; 22 | 23 | import net.minecraft.entity.Entity; 24 | 25 | import grondag.frex.api.material.EntityMaterialMap; 26 | import grondag.frex.api.material.MaterialFinder; 27 | import grondag.frex.api.material.RenderMaterial; 28 | 29 | @Internal 30 | class EntityMultiMaterialMap implements EntityMaterialMap { 31 | private final BiPredicate[] predicates; 32 | private final MaterialTransform[] transforms; 33 | 34 | EntityMultiMaterialMap(BiPredicate[] predicates, MaterialTransform[] transforms) { 35 | assert predicates != null; 36 | assert transforms != null; 37 | 38 | this.predicates = predicates; 39 | this.transforms = transforms; 40 | } 41 | 42 | @Override 43 | public RenderMaterial getMapped(RenderMaterial material, Entity entity, MaterialFinder finder) { 44 | final int limit = predicates.length; 45 | 46 | for (int i = 0; i < limit; ++i) { 47 | if (predicates[i].test(entity, material)) { 48 | return transforms[i].transform(material, finder); 49 | } 50 | } 51 | 52 | return material; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/EntitySingleMaterialMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material; 18 | 19 | import java.util.function.BiPredicate; 20 | 21 | import org.jetbrains.annotations.ApiStatus.Internal; 22 | 23 | import net.minecraft.entity.Entity; 24 | 25 | import grondag.frex.api.material.EntityMaterialMap; 26 | import grondag.frex.api.material.MaterialFinder; 27 | import grondag.frex.api.material.RenderMaterial; 28 | 29 | @Internal 30 | class EntitySingleMaterialMap implements EntityMaterialMap { 31 | private final MaterialTransform transform; 32 | private final BiPredicate predicate; 33 | 34 | EntitySingleMaterialMap(BiPredicate predicate, MaterialTransform transform) { 35 | this.predicate = predicate; 36 | this.transform = transform; 37 | } 38 | 39 | @Override 40 | public RenderMaterial getMapped(RenderMaterial material, Entity entity, MaterialFinder finder) { 41 | return predicate.test(entity, material) ? transform.transform(material, finder) : material; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/ItemMaterialMapDeserializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material; 18 | 19 | import java.io.InputStreamReader; 20 | import java.util.IdentityHashMap; 21 | 22 | import com.google.gson.JsonObject; 23 | import org.jetbrains.annotations.ApiStatus.Internal; 24 | import org.jetbrains.annotations.Nullable; 25 | 26 | import net.minecraft.item.Item; 27 | import net.minecraft.util.Identifier; 28 | import net.minecraft.util.JsonHelper; 29 | 30 | import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; 31 | 32 | import grondag.frex.Frex; 33 | import grondag.frex.api.material.MaterialMap; 34 | 35 | @Internal 36 | public class ItemMaterialMapDeserializer { 37 | public static void deserialize(Item item, Identifier idForLog, InputStreamReader reader, IdentityHashMap itemMap) { 38 | try { 39 | final JsonObject json = JsonHelper.deserialize(reader); 40 | final String idString = idForLog.toString(); 41 | 42 | final MaterialMap globalDefaultMap = MaterialMapLoader.DEFAULT_MAP; 43 | @Nullable RenderMaterial defaultMaterial = null; 44 | MaterialMap result = globalDefaultMap; 45 | 46 | if (json.has("defaultMaterial")) { 47 | defaultMaterial = MaterialLoaderImpl.loadMaterial(json.get("defaultMaterial").getAsString(), defaultMaterial); 48 | result = new SingleMaterialMap(defaultMaterial); 49 | } 50 | 51 | if (json.has("defaultMap")) { 52 | result = MaterialMapDeserializer.loadMaterialMap(idString + "#default", json.getAsJsonObject("defaultMap"), result, defaultMaterial); 53 | } 54 | 55 | if (result != globalDefaultMap) { 56 | itemMap.put(item, result); 57 | } 58 | } catch (final Exception e) { 59 | Frex.LOG.warn("Unable to load block material map for " + idForLog.toString() + " due to unhandled exception:", e); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/MaterialLoaderImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material; 18 | 19 | import java.io.InputStream; 20 | import java.io.InputStreamReader; 21 | import java.nio.charset.StandardCharsets; 22 | 23 | import com.google.gson.JsonObject; 24 | import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; 25 | import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; 26 | import org.jetbrains.annotations.ApiStatus.Internal; 27 | 28 | import net.minecraft.client.MinecraftClient; 29 | import net.minecraft.client.texture.Sprite; 30 | import net.minecraft.client.texture.SpriteAtlasTexture; 31 | import net.minecraft.resource.Resource; 32 | import net.minecraft.resource.ResourceManager; 33 | import net.minecraft.util.Identifier; 34 | import net.minecraft.util.JsonHelper; 35 | 36 | import net.fabricmc.fabric.api.renderer.v1.Renderer; 37 | import net.fabricmc.fabric.api.renderer.v1.RendererAccess; 38 | import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; 39 | 40 | import grondag.frex.Frex; 41 | import grondag.frex.api.RendererFeature; 42 | 43 | @Internal 44 | public final class MaterialLoaderImpl { 45 | private MaterialLoaderImpl() { } 46 | 47 | private static final ObjectOpenHashSet CAUGHT = new ObjectOpenHashSet<>(); 48 | private static final Object2ObjectOpenHashMap LOAD_CACHE = new Object2ObjectOpenHashMap<>(); 49 | 50 | /** Clear load cache and errors. Call at start of loading each pass. */ 51 | public static void reset() { 52 | CAUGHT.clear(); 53 | LOAD_CACHE.clear(); 54 | } 55 | 56 | static RenderMaterial loadMaterial(String materialString, RenderMaterial defaultValue) { 57 | final Identifier id = new Identifier(materialString); 58 | 59 | RenderMaterial result = loadMaterialCached(id); 60 | 61 | if (result == null) { 62 | result = RendererAccess.INSTANCE.getRenderer().materialById(id); 63 | } 64 | 65 | return result == null ? defaultValue : result; 66 | } 67 | 68 | public static RenderMaterial loadMaterial(Identifier id) { 69 | final RenderMaterial result = loadMaterialCached(id); 70 | // Check for materials registered via code 71 | return result == null ? RendererAccess.INSTANCE.getRenderer().materialById(id) : result; 72 | } 73 | 74 | private static synchronized RenderMaterial loadMaterialCached(Identifier idIn) { 75 | final Renderer r = RendererAccess.INSTANCE.getRenderer(); 76 | 77 | RenderMaterial result = LOAD_CACHE.get(idIn); 78 | 79 | if (result == null) { 80 | result = loadMaterialInner(idIn); 81 | LOAD_CACHE.put(idIn, result); 82 | 83 | if (RendererFeature.isAvailable(RendererFeature.UPDATE_MATERIAL_REGISTRATION)) { 84 | ((grondag.frex.api.Renderer) r).registerOrUpdateMaterial(idIn, result); 85 | } else { 86 | r.registerMaterial(idIn, result); 87 | } 88 | } 89 | 90 | return result; 91 | } 92 | 93 | private static RenderMaterial loadMaterialInner(Identifier idIn) { 94 | // Don't try to load the standard material 95 | if (RenderMaterial.MATERIAL_STANDARD.equals(idIn)) { 96 | return null; 97 | } 98 | 99 | final Identifier id = new Identifier(idIn.getNamespace(), "materials/" + idIn.getPath() + ".json"); 100 | 101 | RenderMaterial result = null; 102 | final ResourceManager rm = MinecraftClient.getInstance().getResourceManager(); 103 | 104 | try (Resource res = rm.getResource(id)) { 105 | result = MaterialDeserializer.deserialize(readJsonObject(res)); 106 | } catch (final Exception e) { 107 | // TODO: make error suppression configurable 108 | if (CAUGHT.add(idIn)) { 109 | Frex.LOG.info("Unable to load render material " + idIn.toString() + " due to exception " + e.toString()); 110 | } 111 | } 112 | 113 | return result; 114 | } 115 | 116 | static Sprite loadSprite(String idForLog, String spriteId, SpriteAtlasTexture atlas, Sprite missingSprite) { 117 | final Sprite sprite = atlas.getSprite(new Identifier(spriteId)); 118 | 119 | if (sprite == null || sprite == missingSprite) { 120 | Frex.LOG.warn("Unable to find sprite " + spriteId + " for material map " + idForLog + ". Using default material."); 121 | return null; 122 | } 123 | 124 | return sprite; 125 | } 126 | 127 | public static JsonObject readJsonObject(Resource res) { 128 | InputStream stream = null; 129 | InputStreamReader reader = null; 130 | JsonObject result = null; 131 | 132 | try { 133 | stream = res.getInputStream(); 134 | reader = new InputStreamReader(stream, StandardCharsets.UTF_8); 135 | result = JsonHelper.deserialize(reader); 136 | } catch (final Exception e) { 137 | throw new RuntimeException("Unexpected error during material deserialization", e); 138 | } finally { 139 | try { 140 | if (reader != null) { 141 | reader.close(); 142 | } 143 | 144 | if (stream != null) { 145 | stream.close(); 146 | } 147 | } catch (final Exception e) { 148 | Frex.LOG.warn("Unexpected error during material deserialization", e); 149 | } 150 | } 151 | 152 | return result; 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/MaterialTransform.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material; 18 | 19 | import grondag.frex.api.material.MaterialFinder; 20 | import grondag.frex.api.material.RenderMaterial; 21 | 22 | @FunctionalInterface 23 | public interface MaterialTransform { 24 | default RenderMaterial transform(RenderMaterial material, MaterialFinder finder) { 25 | finder.copyFrom(material); 26 | apply(finder); 27 | return finder.find(); 28 | } 29 | 30 | void apply(MaterialFinder finder); 31 | 32 | MaterialTransform IDENTITY = (f) -> { }; 33 | 34 | static MaterialTransform constant(RenderMaterial material) { 35 | return new MaterialTransform() { 36 | @Override 37 | public RenderMaterial transform(RenderMaterial ignored, MaterialFinder finder) { 38 | return material; 39 | } 40 | 41 | @Override 42 | public void apply(MaterialFinder finder) { 43 | // NOOP 44 | } 45 | }; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/MaterialTransformLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material; 18 | 19 | import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; 20 | import org.jetbrains.annotations.ApiStatus.Internal; 21 | 22 | import net.minecraft.client.MinecraftClient; 23 | import net.minecraft.resource.Resource; 24 | import net.minecraft.resource.ResourceManager; 25 | import net.minecraft.util.Identifier; 26 | 27 | import grondag.frex.Frex; 28 | 29 | @Internal 30 | public final class MaterialTransformLoader { 31 | private MaterialTransformLoader() { } 32 | 33 | private static final ObjectOpenHashSet CAUGHT = new ObjectOpenHashSet<>(); 34 | 35 | static MaterialTransform loadTransform(String idForLog, String materialString, MaterialTransform defaultValue) { 36 | try { 37 | final MaterialTransform result = loadTransformInner(new Identifier(materialString)); 38 | return result == null ? defaultValue : result; 39 | } catch (final Exception e) { 40 | Frex.LOG.warn("Unable to load material transform " + materialString + " for material map " + idForLog + " because of exception. Using default transform.", e); 41 | return defaultValue; 42 | } 43 | } 44 | 45 | private static MaterialTransform loadTransformInner(Identifier idIn) { 46 | final Identifier id = new Identifier(idIn.getNamespace(), "materials/" + idIn.getPath() + ".json"); 47 | 48 | MaterialTransform result = null; 49 | final ResourceManager rm = MinecraftClient.getInstance().getResourceManager(); 50 | 51 | try (Resource res = rm.getResource(id)) { 52 | result = MaterialTransformDeserializer.deserialize(MaterialLoaderImpl.readJsonObject(res)); 53 | } catch (final Exception e) { 54 | // TODO: make error suppression configurable 55 | if (CAUGHT.add(idIn)) { 56 | Frex.LOG.info("Unable to load material transform " + idIn.toString() + " due to exception " + e.toString()); 57 | } 58 | } 59 | 60 | return result; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/MultiMaterialMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material; 18 | 19 | import java.util.IdentityHashMap; 20 | 21 | import org.jetbrains.annotations.ApiStatus.Internal; 22 | 23 | import net.minecraft.client.texture.Sprite; 24 | 25 | import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; 26 | 27 | import grondag.frex.api.material.MaterialMap; 28 | 29 | @Internal 30 | class MultiMaterialMap implements MaterialMap { 31 | private final IdentityHashMap spriteMap; 32 | 33 | MultiMaterialMap(IdentityHashMap spriteMap) { 34 | this.spriteMap = spriteMap; 35 | } 36 | 37 | @Override 38 | public boolean needsSprite() { 39 | return true; 40 | } 41 | 42 | @Override 43 | public RenderMaterial getMapped(Sprite sprite) { 44 | return spriteMap.get(sprite); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/ParticleMaterialMapDeserializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material; 18 | 19 | import java.io.InputStreamReader; 20 | import java.util.IdentityHashMap; 21 | 22 | import com.google.gson.JsonObject; 23 | import org.jetbrains.annotations.ApiStatus.Internal; 24 | 25 | import net.minecraft.particle.ParticleType; 26 | import net.minecraft.util.Identifier; 27 | import net.minecraft.util.JsonHelper; 28 | 29 | import grondag.frex.Frex; 30 | import grondag.frex.api.material.MaterialMap; 31 | 32 | @Internal 33 | public class ParticleMaterialMapDeserializer { 34 | public static void deserialize(ParticleType particleType, Identifier idForLog, InputStreamReader reader, IdentityHashMap, MaterialMap> map) { 35 | try { 36 | final JsonObject json = JsonHelper.deserialize(reader); 37 | 38 | if (json.has("material")) { 39 | final MaterialMap result = new SingleMaterialMap(MaterialLoaderImpl.loadMaterial(json.get("material").getAsString(), null)); 40 | map.put(particleType, result); 41 | } 42 | } catch (final Exception e) { 43 | Frex.LOG.warn("Unable to load particle material map for " + idForLog.toString() + " due to unhandled exception:", e); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/SingleMaterialMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material; 18 | 19 | import org.jetbrains.annotations.ApiStatus.Internal; 20 | import org.jetbrains.annotations.Nullable; 21 | 22 | import net.minecraft.client.texture.Sprite; 23 | 24 | import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; 25 | 26 | import grondag.frex.api.material.MaterialMap; 27 | 28 | @Internal 29 | class SingleMaterialMap implements MaterialMap { 30 | private final RenderMaterial material; 31 | 32 | SingleMaterialMap(RenderMaterial material) { 33 | this.material = material; 34 | } 35 | 36 | @Override 37 | public boolean needsSprite() { 38 | return false; 39 | } 40 | 41 | @Override 42 | public @Nullable RenderMaterial getMapped(Sprite sprite) { 43 | return material; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/predicate/EntityBiPredicate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material.predicate; 18 | 19 | import java.util.function.BiPredicate; 20 | 21 | import net.minecraft.entity.Entity; 22 | 23 | import grondag.frex.api.material.RenderMaterial; 24 | 25 | public abstract class EntityBiPredicate implements BiPredicate { 26 | public static EntityBiPredicate ENTITY_ALWAYS_TRUE = new EntityBiPredicate() { 27 | @Override 28 | public boolean test(Entity entity, RenderMaterial renderMaterial) { 29 | return true; 30 | } 31 | 32 | @Override 33 | public boolean equals(Object obj) { 34 | return obj == ENTITY_ALWAYS_TRUE; 35 | } 36 | }; 37 | 38 | @Override 39 | public abstract boolean equals(Object obj); 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/predicate/EntityMaterialBoth.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material.predicate; 18 | 19 | import net.minecraft.entity.Entity; 20 | 21 | import grondag.frex.api.material.RenderMaterial; 22 | 23 | public class EntityMaterialBoth extends EntityBiPredicate { 24 | private final EntityOnly entityOnly; 25 | private final MaterialPredicate materialPredicate; 26 | 27 | public EntityMaterialBoth(EntityOnly entityOnly, MaterialPredicate materialPredicate) { 28 | this.entityOnly = entityOnly; 29 | this.materialPredicate = materialPredicate; 30 | } 31 | 32 | @Override 33 | public boolean test(Entity entity, RenderMaterial renderMaterial) { 34 | return entityOnly.test(entity) && materialPredicate.test(renderMaterial); 35 | } 36 | 37 | @Override 38 | public boolean equals(Object obj) { 39 | if (obj instanceof EntityMaterialBoth) { 40 | return entityOnly.equals(((EntityMaterialBoth) obj).entityOnly) 41 | && materialPredicate.equals(((EntityMaterialBoth) obj).materialPredicate); 42 | } else { 43 | return false; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/predicate/EntityMaterialOnly.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material.predicate; 18 | 19 | import net.minecraft.entity.Entity; 20 | 21 | import grondag.frex.api.material.RenderMaterial; 22 | 23 | public class EntityMaterialOnly extends EntityBiPredicate { 24 | private final MaterialPredicate materialPredicate; 25 | 26 | public EntityMaterialOnly(MaterialPredicate materialPredicate) { 27 | this.materialPredicate = materialPredicate; 28 | } 29 | 30 | @Override 31 | public boolean test(Entity ignored, RenderMaterial renderMaterial) { 32 | return materialPredicate.test(renderMaterial); 33 | } 34 | 35 | @Override 36 | public boolean equals(Object obj) { 37 | if (obj instanceof EntityMaterialOnly) { 38 | return materialPredicate.equals(((EntityMaterialOnly) obj).materialPredicate); 39 | } else { 40 | return false; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/predicate/EntityOnly.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material.predicate; 18 | 19 | import com.google.gson.JsonElement; 20 | import com.google.gson.JsonObject; 21 | import org.jetbrains.annotations.Nullable; 22 | 23 | import net.minecraft.entity.Entity; 24 | import net.minecraft.entity.passive.CatEntity; 25 | import net.minecraft.predicate.NbtPredicate; 26 | import net.minecraft.predicate.PlayerPredicate; 27 | import net.minecraft.predicate.entity.EntityEffectPredicate; 28 | import net.minecraft.predicate.entity.EntityEquipmentPredicate; 29 | import net.minecraft.predicate.entity.EntityFlagsPredicate; 30 | import net.minecraft.predicate.entity.FishingHookPredicate; 31 | import net.minecraft.scoreboard.AbstractTeam; 32 | import net.minecraft.util.Identifier; 33 | import net.minecraft.util.JsonHelper; 34 | 35 | import grondag.frex.api.material.RenderMaterial; 36 | 37 | /** 38 | * Stripped-down adaptation of vanilla class used for entity loot predicates. 39 | */ 40 | public class EntityOnly extends EntityBiPredicate { 41 | public static final EntityOnly ANY; 42 | 43 | private final EntityEffectPredicate effects; 44 | private final NbtPredicate nbt; 45 | private final EntityFlagsPredicate flags; 46 | private final EntityEquipmentPredicate equipment; 47 | private final PlayerPredicate player; 48 | private final FishingHookPredicate fishingHook; 49 | @Nullable private final String team; 50 | @Nullable private final Identifier catType; 51 | 52 | private EntityOnly(EntityEffectPredicate effects, NbtPredicate nbt, EntityFlagsPredicate flags, EntityEquipmentPredicate equipment, PlayerPredicate player, FishingHookPredicate fishingHook, @Nullable String team, @Nullable Identifier catType) { 53 | this.effects = effects; 54 | this.nbt = nbt; 55 | this.flags = flags; 56 | this.equipment = equipment; 57 | this.player = player; 58 | this.fishingHook = fishingHook; 59 | this.team = team; 60 | this.catType = catType; 61 | } 62 | 63 | public boolean test(Entity entity) { 64 | return test(entity, null); 65 | } 66 | 67 | @Override 68 | public boolean test(Entity entity, RenderMaterial ignored) { 69 | if (this == ANY) { 70 | return true; 71 | } else if (entity == null) { 72 | return false; 73 | } else { 74 | if (!effects.test(entity)) { 75 | return false; 76 | } else if (!nbt.test(entity)) { 77 | return false; 78 | } else if (!flags.test(entity)) { 79 | return false; 80 | } else if (!equipment.test(entity)) { 81 | return false; 82 | } else if (!player.test(entity)) { 83 | return false; 84 | } else if (!fishingHook.test(entity)) { 85 | return false; 86 | } else { 87 | if (team != null) { 88 | final AbstractTeam abstractTeam = entity.getScoreboardTeam(); 89 | 90 | if (abstractTeam == null || !team.equals(abstractTeam.getName())) { 91 | return false; 92 | } 93 | } 94 | 95 | return catType == null || entity instanceof CatEntity && ((CatEntity) entity).getTexture().equals(catType); 96 | } 97 | } 98 | } 99 | 100 | public static EntityOnly fromJson(@Nullable JsonElement json) { 101 | if (json != null && !json.isJsonNull()) { 102 | final JsonObject jsonObject = JsonHelper.asObject(json, "entity"); 103 | final EntityEffectPredicate effects = EntityEffectPredicate.fromJson(jsonObject.get("effects")); 104 | final NbtPredicate nbt = NbtPredicate.fromJson(jsonObject.get("nbt")); 105 | final EntityFlagsPredicate flags = EntityFlagsPredicate.fromJson(jsonObject.get("flags")); 106 | final EntityEquipmentPredicate equipment = EntityEquipmentPredicate.fromJson(jsonObject.get("equipment")); 107 | final PlayerPredicate player = PlayerPredicate.fromJson(jsonObject.get("player")); 108 | final FishingHookPredicate fishHook = FishingHookPredicate.fromJson(jsonObject.get("fishing_hook")); 109 | final String team = JsonHelper.getString(jsonObject, "team", (String) null); 110 | final Identifier catType = jsonObject.has("catType") ? new Identifier(JsonHelper.getString(jsonObject, "catType")) : null; 111 | 112 | return new EntityOnly(effects, nbt, flags, equipment, player, fishHook, team, catType); 113 | } else { 114 | return ANY; 115 | } 116 | } 117 | 118 | static { 119 | ANY = new EntityOnly(EntityEffectPredicate.EMPTY, NbtPredicate.ANY, EntityFlagsPredicate.ANY, EntityEquipmentPredicate.ANY, PlayerPredicate.ANY, FishingHookPredicate.ANY, (String) null, (Identifier) null); 120 | } 121 | 122 | @Override 123 | public boolean equals(Object obj) { 124 | // not worth elaborating 125 | return this == obj; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/predicate/MaterialPredicate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material.predicate; 18 | 19 | import java.util.function.Predicate; 20 | 21 | import grondag.frex.api.material.RenderMaterial; 22 | 23 | public abstract class MaterialPredicate implements Predicate { 24 | public static MaterialPredicate MATERIAL_ALWAYS_TRUE = new MaterialPredicate() { 25 | @Override 26 | public boolean equals(Object obj) { 27 | return obj == MATERIAL_ALWAYS_TRUE; 28 | } 29 | 30 | @Override 31 | public boolean test(RenderMaterial renderMaterial) { 32 | return true; 33 | } 34 | }; 35 | 36 | @Override 37 | public abstract boolean equals(Object obj); 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/predicate/MaterialPredicateDeserializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material.predicate; 18 | 19 | import static grondag.frex.impl.material.predicate.MaterialPredicate.MATERIAL_ALWAYS_TRUE; 20 | 21 | import com.google.gson.JsonObject; 22 | 23 | public class MaterialPredicateDeserializer { 24 | public static MaterialPredicate deserialize(JsonObject json) { 25 | if (json == null || json.isJsonNull()) { 26 | return MATERIAL_ALWAYS_TRUE; 27 | } 28 | 29 | final ArrayPredicate arrayPredicate = new ArrayPredicate(json); 30 | 31 | if (arrayPredicate.size() == 0) { 32 | return MATERIAL_ALWAYS_TRUE; 33 | } else if (arrayPredicate.size() == 1) { 34 | return arrayPredicate.get(0); 35 | } else { 36 | return arrayPredicate; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/predicate/StateBiPredicate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material.predicate; 18 | 19 | import java.util.function.BiPredicate; 20 | 21 | import net.minecraft.block.BlockState; 22 | 23 | import grondag.frex.api.material.RenderMaterial; 24 | 25 | public abstract class StateBiPredicate implements BiPredicate { 26 | public static StateBiPredicate BLOCK_ALWAYS_TRUE = new StateBiPredicate() { 27 | @Override 28 | public boolean test(BlockState blockState, RenderMaterial renderMaterial) { 29 | return true; 30 | } 31 | 32 | @Override 33 | public boolean equals(Object obj) { 34 | return obj == BLOCK_ALWAYS_TRUE; 35 | } 36 | }; 37 | 38 | @Override 39 | public abstract boolean equals(Object obj); 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/predicate/StateMaterialBoth.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material.predicate; 18 | 19 | import net.minecraft.block.BlockState; 20 | import net.minecraft.predicate.StatePredicate; 21 | 22 | import grondag.frex.api.material.RenderMaterial; 23 | 24 | public class StateMaterialBoth extends StateBiPredicate { 25 | private final StatePredicate statePredicate; 26 | private final MaterialPredicate materialPredicate; 27 | 28 | public StateMaterialBoth(StatePredicate statePredicate, MaterialPredicate materialPredicate) { 29 | this.statePredicate = statePredicate; 30 | this.materialPredicate = materialPredicate; 31 | } 32 | 33 | @Override 34 | public boolean test(BlockState blockState, RenderMaterial renderMaterial) { 35 | return statePredicate.test(blockState) && materialPredicate.test(renderMaterial); 36 | } 37 | 38 | @Override 39 | public boolean equals(Object obj) { 40 | if (obj instanceof StateMaterialBoth) { 41 | return statePredicate.equals(((StateMaterialBoth) obj).statePredicate) 42 | && materialPredicate.equals(((StateMaterialBoth) obj).materialPredicate); 43 | } else { 44 | return false; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/predicate/StateMaterialOnly.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material.predicate; 18 | 19 | import net.minecraft.block.BlockState; 20 | 21 | import grondag.frex.api.material.RenderMaterial; 22 | 23 | public class StateMaterialOnly extends StateBiPredicate { 24 | private MaterialPredicate materialPredicate; 25 | 26 | public StateMaterialOnly(MaterialPredicate materialPredicate) { 27 | this.materialPredicate = materialPredicate; 28 | } 29 | 30 | @Override 31 | public boolean test(BlockState ignored, RenderMaterial renderMaterial) { 32 | return materialPredicate.test(renderMaterial); 33 | } 34 | 35 | @Override 36 | public boolean equals(Object obj) { 37 | if (obj instanceof StateMaterialOnly) { 38 | return materialPredicate.equals(((StateMaterialOnly) obj).materialPredicate); 39 | } else { 40 | return false; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/impl/material/predicate/StateOnly.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.impl.material.predicate; 18 | 19 | import net.minecraft.block.BlockState; 20 | import net.minecraft.predicate.StatePredicate; 21 | 22 | import grondag.frex.api.material.RenderMaterial; 23 | 24 | public class StateOnly extends StateBiPredicate { 25 | private final StatePredicate statePredicate; 26 | 27 | public StateOnly(StatePredicate statePredicate) { 28 | this.statePredicate = statePredicate; 29 | } 30 | 31 | @Override 32 | public boolean test(BlockState blockState, RenderMaterial renderMaterial) { 33 | return statePredicate.test(blockState); 34 | } 35 | 36 | @Override 37 | public boolean equals(Object obj) { 38 | if (obj instanceof StateOnly) { 39 | return statePredicate.equals(((StateOnly) obj).statePredicate); 40 | } else { 41 | return false; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/mixin/MixinChunkBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.mixin; 18 | 19 | import java.util.Random; 20 | import java.util.Set; 21 | 22 | import org.spongepowered.asm.mixin.Mixin; 23 | import org.spongepowered.asm.mixin.Shadow; 24 | import org.spongepowered.asm.mixin.Unique; 25 | import org.spongepowered.asm.mixin.injection.At; 26 | import org.spongepowered.asm.mixin.injection.Inject; 27 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 28 | import org.spongepowered.asm.mixin.injection.callback.LocalCapture; 29 | 30 | import net.minecraft.block.entity.BlockEntity; 31 | import net.minecraft.client.render.block.BlockRenderManager; 32 | import net.minecraft.client.render.chunk.BlockBufferBuilderStorage; 33 | import net.minecraft.client.render.chunk.ChunkBuilder; 34 | import net.minecraft.client.render.chunk.ChunkBuilder.BuiltChunk; 35 | import net.minecraft.client.render.chunk.ChunkOcclusionDataBuilder; 36 | import net.minecraft.client.render.chunk.ChunkRendererRegion; 37 | import net.minecraft.client.util.math.MatrixStack; 38 | import net.minecraft.util.math.BlockPos; 39 | import net.minecraft.world.BlockRenderView; 40 | 41 | import net.fabricmc.api.EnvType; 42 | import net.fabricmc.api.Environment; 43 | 44 | import grondag.frex.api.event.RenderRegionBakeListener; 45 | import grondag.frex.api.event.RenderRegionBakeListener.RenderRegionContext; 46 | import grondag.frex.impl.event.BlockStateRendererImpl; 47 | import grondag.frex.impl.event.ChunkRenderConditionContext.RenderRegionListenerProvider; 48 | 49 | @Environment(EnvType.CLIENT) 50 | @Mixin(targets = "net/minecraft/client/render/chunk/ChunkBuilder$BuiltChunk$RebuildTask") 51 | public class MixinChunkBuilder implements RenderRegionContext { 52 | @Shadow protected BuiltChunk field_20839; 53 | 54 | @Unique 55 | private final BlockStateRendererImpl blockStateRenderer = new BlockStateRendererImpl(); 56 | 57 | // could shadow this but is set to null by the time we need it 58 | @Unique 59 | private ChunkRendererRegion contextRegion; 60 | 61 | @Inject(method = "Lnet/minecraft/client/render/chunk/ChunkBuilder$BuiltChunk$RebuildTask;render(FFFLnet/minecraft/client/render/chunk/ChunkBuilder$ChunkData;Lnet/minecraft/client/render/chunk/BlockBufferBuilderStorage;)Ljava/util/Set;", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/BlockPos;iterate(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/BlockPos;)Ljava/lang/Iterable;"), locals = LocalCapture.CAPTURE_FAILHARD) 62 | private void onRender(float cameraX, float cameraY, float cameraZ, ChunkBuilder.ChunkData data, BlockBufferBuilderStorage buffers, CallbackInfoReturnable> cir, int i, BlockPos blockPos, BlockPos blockPos2, ChunkOcclusionDataBuilder chunkOcclusionDataBuilder, Set set, ChunkRendererRegion chunkRendererRegion, MatrixStack matrixStack, Random random, BlockRenderManager blockRenderManager) { 63 | if (chunkRendererRegion != null) { 64 | final RenderRegionBakeListener[] listeners = ((RenderRegionListenerProvider) chunkRendererRegion).frex_getRenderRegionListeners(); 65 | 66 | if (listeners != null) { 67 | contextRegion = chunkRendererRegion; 68 | blockStateRenderer.prepare(blockRenderManager, matrixStack, chunkRendererRegion); 69 | final int limit = listeners.length; 70 | 71 | for (int n = 0; n < limit; ++n) { 72 | listeners[n].bake(this, blockStateRenderer); 73 | } 74 | 75 | contextRegion = null; 76 | } 77 | } 78 | } 79 | 80 | @Override 81 | public BlockRenderView blockView() { 82 | return contextRegion; 83 | } 84 | 85 | @Override 86 | public BlockPos origin() { 87 | return field_20839.getOrigin(); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/mixin/MixinChunkRendererRegion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.mixin; 18 | 19 | import org.jetbrains.annotations.Nullable; 20 | import org.spongepowered.asm.mixin.Mixin; 21 | import org.spongepowered.asm.mixin.Unique; 22 | import org.spongepowered.asm.mixin.injection.At; 23 | import org.spongepowered.asm.mixin.injection.Inject; 24 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 25 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 26 | 27 | import net.minecraft.client.render.chunk.ChunkRendererRegion; 28 | import net.minecraft.util.math.BlockPos; 29 | import net.minecraft.world.World; 30 | import net.minecraft.world.chunk.WorldChunk; 31 | 32 | import net.fabricmc.api.EnvType; 33 | import net.fabricmc.api.Environment; 34 | 35 | import grondag.frex.api.event.RenderRegionBakeListener; 36 | import grondag.frex.impl.event.ChunkRenderConditionContext; 37 | import grondag.frex.impl.event.ChunkRenderConditionContext.RenderRegionListenerProvider; 38 | 39 | @Environment(EnvType.CLIENT) 40 | @Mixin(ChunkRendererRegion.class) 41 | public class MixinChunkRendererRegion implements RenderRegionListenerProvider { 42 | @Unique 43 | private @Nullable RenderRegionBakeListener[] listeners; 44 | 45 | private static final ThreadLocal TRANSFER_POOL = ThreadLocal.withInitial(ChunkRenderConditionContext::new); 46 | 47 | @Inject(method = "isEmptyBetween", at = @At("RETURN"), cancellable = true) 48 | private static void isChunkEmpty(BlockPos startPos, BlockPos endPos, int i, int j, WorldChunk[][] worldChunks, CallbackInfoReturnable cir) { 49 | // even if region not empty we still test here and capture listeners here 50 | final ChunkRenderConditionContext context = TRANSFER_POOL.get().prepare(startPos.getX() + 1, startPos.getY() + 1, startPos.getZ() + 1); 51 | RenderRegionBakeListener.prepareInvocations(context, context.listeners); 52 | 53 | if (cir.getReturnValueZ() && !context.listeners.isEmpty()) { 54 | // if empty but has listeners, force it to build 55 | cir.setReturnValue(false); 56 | } 57 | } 58 | 59 | @Inject(method = "*", at = @At("RETURN")) 60 | private void onInit(World world, int chunkX, int chunkZ, WorldChunk[][] chunks, BlockPos startPos, BlockPos endPos, CallbackInfo ci) { 61 | // capture our predicate search results while still on the same thread - will happen right after the hook above 62 | listeners = TRANSFER_POOL.get().getListeners(); 63 | } 64 | 65 | @Override 66 | public @Nullable RenderRegionBakeListener[] frex_getRenderRegionListeners() { 67 | return listeners; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/grondag/frex/mixin/MixinWorldRendererOldEvents.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2020 grondag 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package grondag.frex.mixin; 18 | 19 | import org.jetbrains.annotations.ApiStatus.Internal; 20 | import org.spongepowered.asm.mixin.Mixin; 21 | import org.spongepowered.asm.mixin.injection.At; 22 | import org.spongepowered.asm.mixin.injection.Inject; 23 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 24 | 25 | import net.minecraft.client.render.Camera; 26 | import net.minecraft.client.render.GameRenderer; 27 | import net.minecraft.client.render.LightmapTextureManager; 28 | import net.minecraft.client.render.WorldRenderer; 29 | import net.minecraft.client.util.math.MatrixStack; 30 | import net.minecraft.util.math.Matrix4f; 31 | 32 | import grondag.frex.Frex; 33 | import grondag.frex.api.event.WorldRenderEvent; 34 | 35 | @Internal 36 | @SuppressWarnings("deprecation") 37 | @Mixin(WorldRenderer.class) 38 | public class MixinWorldRendererOldEvents { 39 | @Inject(at = @At("HEAD"), method = "render") 40 | private void beforeRender(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci) { 41 | if (!Frex.isAvailable()) { 42 | WorldRenderEvent.BEFORE_WORLD_RENDER.invoker().beforeWorldRender(matrices, tickDelta, limitTime, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, matrix4f); 43 | } 44 | } 45 | 46 | @Inject(at = @At("RETURN"), method = "render") 47 | private void afterRender(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci) { 48 | if (!Frex.isAvailable()) { 49 | WorldRenderEvent.AFTER_WORLD_RENDER.invoker().afterWorldRender(matrices, tickDelta, limitTime, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, matrix4f); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/frex_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grondag/frex/a2ffd37980e91befe1246a0bc271b2e70dc84ec5/src/main/resources/assets/frex/frex_icon.png -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/api/fog.h: -------------------------------------------------------------------------------- 1 | 2 | /**************************************************************** 3 | * Specifies the variables available in the FREX shader 4 | * API to describe fog parameters for the current primitive. 5 | * 6 | * See FREX Shader API.md for license and general informaiton. 7 | ***************************************************************/ 8 | 9 | /* 10 | * Equals 1 if fog is enabled for the current render pass. 11 | */ 12 | const int frx_fogEnabled; 13 | 14 | /* 15 | * The starting distance for fog, following the conventions 16 | * of vanilla fog rendering. Some pipelines with realistic 17 | * fog modeling may not use this or may use it differently. 18 | */ 19 | const float frx_fogStart; 20 | 21 | /* 22 | * The end distance for fog, following the conventions 23 | * of vanilla fog rendering. Some pipelines with realistic 24 | * fog modeling may not use this or may use it differently. 25 | */ 26 | const float frx_fogEnd; 27 | 28 | /* 29 | * The color of fog used in vanilla fog rendering for the 30 | * current rendering pass. Some pipelines with realistic 31 | * fog modeling may not use this or may use it differently. 32 | */ 33 | const vec4 frx_fogColor; 34 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/api/header.h: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | /**************************************************************** 4 | * Specifies the definitions used in the FREX shader 5 | * API to indicate the operating mode of renderer. 6 | * 7 | * Typical usage is to control conditional compilation of 8 | * features that may not work or work differently in, 9 | * for example, GUI vs world rendering. 10 | * 11 | * These definitions will be automatically included by the 12 | * renderer implementation at the top of the combined source 13 | * file. It is never necessary to include header.h or header.glsl. 14 | * 15 | * Do not declare versions in any pipeline or material shader 16 | * source files. GLSL version is controlled by the active pipeline 17 | * and will be AT LEAST 330 but can be higher if the active pipeline 18 | * requests it. The renderer will automatically pre-pend the 19 | * configured version at the top of the combined source file and 20 | * will strip any version declarations from input source files. 21 | * 22 | * See FREX Shader API.md for license and general informaiton. 23 | ***************************************************************/ 24 | 25 | // If not present, lightmaps and other vanilla-specific data will not be valid or may not present. 26 | // Access to vanilla lighting data should be guarded by #ifdef on this constant. 27 | // Controlled by the active pipeline. 28 | #define VANILLA_LIGHTING 29 | 30 | // present in world context only when feature is enabled - if not present then foliage shaders should NOOP 31 | #define ANIMATED_FOLIAGE 32 | 33 | // Will define VERTEX_SHADER or FRAGMENT_SHADER - useful for checks in common libraries 34 | #define VERTEX_SHADER 35 | 36 | // Present only when pipeline supports the shadowmap feature and it is enabled 37 | #define SHADOW_MAP_PRESENT 38 | 39 | // Present only when shadow map enabled 40 | #define SHADOW_MAP_SIZE 1024 41 | 42 | // Present when material shaders are being run to generate a shadow map or depth math 43 | #define DEPTH_PASS 44 | 45 | // Present when extended texture maps to support Physically-Based Rendering are available 46 | // Will not be defined during depth/shadow pass. 47 | #define PBR_ENABLED 48 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/api/material.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * Specifies the variables and methods available in the 3 | * FREX shader API to describe the material properties of 4 | * the current primitive.in 5 | * 6 | * See FREX Shader API.md for license and general information. 7 | *************************************************************************/ 8 | 9 | /* 10 | * Equals 1 when material is emissive, zero otherwise. 11 | * For emissive materials, this is on/off, not a range. 12 | */ 13 | const int frx_matEmissive; 14 | 15 | /* 16 | * Equals 1 when material is cutout. When 1, 17 | * fragments will be discarded if alpha < 0.5. 18 | */ 19 | const int frx_matCutout; 20 | 21 | /* 22 | * Equals 1 when material has Level of Detail (mip mapping) disabled. Zero otherwise. 23 | * Currently the RenderMaterial finder only allows this for cutout materials. 24 | */ 25 | const int frx_matUnmipped; 26 | 27 | /* 28 | * Equals 1 when material is marked to disable ambient occlusion shading. Zero otherwise. 29 | */ 30 | const int frx_matDisableAo; 31 | 32 | /* 33 | * Equals 1 when material is marked to disable "diffuse" shading. Zero otherwise. 34 | * This may have a different or no effect in non-vanilla lighting models. 35 | */ 36 | const int frx_matDisableDiffuse; 37 | 38 | /* 39 | * Equals 1 when should render the red "hurt" overlay. Zero otherwise. 40 | * Mostly for use in pipeline shaders - material shaders aren't expected to handle. 41 | */ 42 | const int frx_matHurt; 43 | 44 | /* 45 | * Equals 1 when should render the white "flash" overlay. Zero otherwise. 46 | * Mostly for use in pipeline shaders - material shaders aren't expected to handle. 47 | */ 48 | const int frx_matFlash; 49 | 50 | /* 51 | * Equals 1 if material has enchantment glint, 0 otherwise. 52 | */ 53 | const int frx_matGlint; 54 | 55 | /* 56 | * RESERVED FOR FUTURE FEATURE - not yet implemented. 57 | * 58 | * Coarse indication of where the surface is located. 59 | * Zero means the surface is not exposed to the sky and 60 | * cannot get wet or otherwise be affected from directly above. 61 | * 62 | * Values 1.0, 2.0 and 3.0 indicate icy, temperate or hot biome 63 | * temperatures, respectively. 64 | * 65 | * Values > 0 also mean the surface exposed to the sky. 66 | * Does not mean it is facing up - check normals for that - 67 | * but does it mean it could get wet/icy/etc. 68 | */ 69 | const float frx_matExposure; 70 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/api/player.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * Specifies the variables and methods available in the 3 | * FREX shader API to access infomration about the player. 4 | * 5 | * See FREX Shader API.md for license and general informaiton. 6 | *************************************************************************/ 7 | 8 | /* 9 | * Magnitude of effects that affect vision: night vision, being in fluid, etc. 10 | * Experimental, likely to change. 11 | */ 12 | const float frx_effectModifier; 13 | 14 | /* 15 | * Color and magnitude of light source held by player in either hand. 16 | * RGB are the light color, alpha channel holds the 0-1 magnitude. 17 | * 18 | * Magnitude 1 currently represents a source that can reach 15 blocks. 19 | * This scale is subject to change. 20 | * 21 | * If the player is not holding a light source, all values are zero. 22 | */ 23 | const vec4 frx_heldLight; 24 | 25 | /** 26 | * A value less than 2PI radians should create a spot light effect. 27 | * This is the angle of full brightness within the light cone. 28 | * Attenuation is assumed to be the same as for non-spot lights. 29 | */ 30 | const float frx_heldLightInnerRadius; 31 | 32 | /* 33 | * The angle of reduced brightness around the inner light cone. 34 | * If greater than frx_heldLightInnerConeAngle should create a 35 | * fall-off effect around a spot light. 36 | * Attenuation is assumed to be the same as for non-spot lights. 37 | */ 38 | const float frx_heldLightOuterRadius; 39 | 40 | // Player effect indicators. 41 | // Will equal 1 when player has the given effect. 42 | // Includes all vanilla player effects as of 1.16.4 43 | const int frx_effectSpeed; 44 | const int frx_effectSlowness; 45 | const int frx_effectHast; 46 | const int frx_effectMiningFatigue; 47 | const int frx_effectStrength; 48 | const int frx_effectInstantHealth; 49 | const int frx_effectInstantDamage; 50 | const int frx_effectJumpBoost; 51 | const int frx_effectNausea; 52 | const int frx_effectRegeneration; 53 | const int frx_effectResistance; 54 | const int frx_effectFireResistance; 55 | const int frx_effectWaterBreathing; 56 | const int frx_effectInvisibility; 57 | const int frx_effectBlindness; 58 | const int frx_effectNightVision; 59 | const int frx_effectHunger; 60 | const int frx_effectWeakness; 61 | const int frx_effectPoison; 62 | const int frx_effectWither; 63 | const int frx_effectHealthBoost; 64 | const int frx_effectAbsorption; 65 | const int frx_effectSaturation; 66 | const int frx_effectGlowing; 67 | const int frx_effectLevitation; 68 | const int frx_effectLuck; 69 | const int frx_effectUnluck; 70 | const int frx_effectSlowFalling; 71 | const int frx_effectConduitPower; 72 | const int frx_effectDolphinsGrace; 73 | const int frx_effectBadOmen; 74 | const int frx_effectHeroOfTheVillage; 75 | 76 | // Player situation indicators. 77 | // Will equal 1 when the situation is true. 78 | const int frx_playerEyeInFluid; 79 | const int frx_playerEyeInWater; 80 | const int frx_playerEyeInLava; 81 | const int frx_playerSneaking; 82 | const int frx_playerSwimming; 83 | const int frx_playerSneakingPose; 84 | const int frx_playerSwimmingPose; 85 | const int frx_playerCreative; 86 | const int frx_playerSpectator; 87 | const int frx_playerRiding; 88 | const int frx_playerOnFire; 89 | const int frx_playerSleeping; 90 | const int frx_playerSprinting; 91 | const int frx_playerWet; 92 | 93 | /* 94 | * Value of timer that triggers "spooky" sounds when player is underground. Range 0-1. 95 | */ 96 | const float frx_playerMood; 97 | 98 | /* 99 | * Eye position in world coordinates. 100 | */ 101 | const vec3 frx_eyePos; 102 | 103 | /* 104 | * Normalized, linear light level at player/viewer eye position. 105 | * Zero is no light and 1 is max. No correction for gamma, dimension, etc. 106 | * Component x is block and y is sky. 107 | */ 108 | const vec2 frx_eyeBrightness; 109 | 110 | /* 111 | * Same as frx_eyeBrightness but with exponential smoothing. 112 | * Optionally, can smooth only decreases, leaving increases instant. 113 | * Speed & bidirectionality are controlled in pipeline config. 114 | */ 115 | const vec2 frx_smoothedEyeBrightness; 116 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/api/sampler.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * Specifies the variables and methods available in the 3 | * FREX shader API to access samplers directly. 4 | * 5 | * See FREX Shader API.md for license and general informaiton. 6 | *************************************************************************/ 7 | 8 | uniform sampler2D frxs_baseColor; 9 | 10 | /* 11 | * When a texture atlas is in use, the renderer will automatically 12 | * map from normalized coordinates to texture coordinates before the 13 | * fragment shader runs. But this doesn't help if you want to 14 | * re-sample during fragment shading using normalized coordinates. 15 | * 16 | * This function will remap normalized coordinates to atlas coordinates. 17 | * It has no effect when the bound texture is not an atlas texture. 18 | */ 19 | vec2 frx_mapNormalizedUV(vec2 coord); 20 | 21 | /* 22 | * Takes texture atlas coordinates and remaps them to normalized. 23 | * Has no effect when the bound texture is not an atlas texture. 24 | */ 25 | vec2 frx_normalizeMappedUV(vec2 coord); 26 | 27 | uniform sampler2D frxs_lightmap; 28 | 29 | /* 30 | * Shadow-type sampler for shadow map texture, useful for final map testing 31 | * and exploits hardware accumulation of shadow test results 32 | * 33 | * Same underlying image as frxs_shadowMapTexture. 34 | * 35 | * Available only in fragment shader when SHADOW_MAP_PRESENT is defined. 36 | */ 37 | uniform sampler2DArrayShadow frxs_shadowMap; 38 | 39 | /* 40 | * Regular sampler for shadow map texture, useful for 41 | * probing depth at specific points for PCSS or Contact-Hardening Shadows. 42 | * 43 | * Same underlying image as frxs_shadowMapTexture. 44 | * 45 | * Available only in fragment shader when SHADOW_MAP_PRESENT is defined. 46 | */ 47 | uniform sampler2DArray frxs_shadowMapTexture; 48 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/api/vertex.h: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | * Specifies the variables and methods in the FREX shader 3 | * API sepcific to vertex shaders. 4 | * 5 | * See FREX Shader API.md for license and general informaiton. 6 | ***************************************************************/ 7 | 8 | /* 9 | * Vertex position in camera space. Transformation in frx_materialVertex() 10 | * is the primary means for achieving animation effects. 11 | * Remember that normals must be transformed separately! 12 | */ 13 | out vec4 frx_vertex; 14 | 15 | /* 16 | * The texture coordinates for the vertex. Used for base color and PBR texture maps. 17 | * For atlas textures, the renderer will initialize this with normalized 0-1 coordinates 18 | * before calling frx_materialVertex() and convert them to mapped (non-normalized) 19 | * atlas coordinates before calling frx_pipelineVertex(); 20 | */ 21 | out vec2 frx_texcoord; 22 | 23 | /* 24 | * RGB vertex color, with alpha. 25 | * Usage of alpha is controlled by the material blend mode: 26 | * if cutout is enabled, fragment will be discarded (see: api/material.glsl) 27 | * if SHADER_PASS != SHADER_PASS_SOLID fragment will be blended using the alpha channel 28 | * in other cases (solid pass rendering) alpha is ignored and could be used for other purposes 29 | * 30 | * Vertex color is not transformed by the renderer. 31 | * The renderer must not modify vertex alpha values given from the model 32 | * in the solid render pass, even if the data is not used. This means mod 33 | * authors can use that value for other purposes in a material shader. 34 | */ 35 | out vec4 frx_vertexColor; 36 | 37 | /* 38 | * Vertex normal in camera/world space. Transformation in frx_materialVertex() 39 | * is the primary means for achieving animation effects. 40 | * Transforming normal in addition to vertex is important for correct lighting. 41 | */ 42 | out vec3 frx_vertexNormal; 43 | 44 | /* 45 | * Initialized with vanilla lighting data from CPU. 46 | * Depending on the context or lighting model in effect, 47 | * this may not be a unit vector and/or unused. 48 | * The emissive flag or an emissive texture map (when supported) 49 | * are generally better alternatives for achieving emissive lighting effects. 50 | * 51 | * All values are normalized (0-1). 52 | * 53 | * Components are as follows: 54 | * X: Block light intensity. 55 | * Y: Sky light intensity. 56 | * Z: AO shading. Will be initialized to 1.0 if frx_matDisableAo is true or AO is disabled in the game. 57 | * 58 | * Not available in depth pass. 59 | * Gate usage with #ifndef DEPTH_PASS. 60 | */ 61 | out vec3 frx_vertexLight; 62 | 63 | 64 | /* 65 | * Varying variables for generic use in material shaders. Material 66 | * shader authors are encouraged to exhaust these before creating new 67 | * custom out variables. 68 | * 69 | * This is necessary because custom shaders may be consolidated 70 | * into a single shader with logic controlled via uniforms or vertex data. 71 | * This is done either to reduce draw calls or as a way to achieve 72 | * sorted translucency with mixed custom shaders. 73 | * 74 | * If we do not reuse these variables, then three bad things can happen: 75 | * 1) Naming conflicts (could be avoided with care) 76 | * 2) Exceed hardware/driver limits 77 | * 3) Wasteful interpolation if unused varyings aren't stripped by the compiler. 78 | * 79 | * Authors do not need to worry about conflicting usage of these variables 80 | * by other shaders in the same compilation - only a single pair of custom 81 | * vertex/fragment shaders will be active for a single polygon. 82 | * 83 | * Note that pipeline shader devs should NOT use these. There will only 84 | * ever be a single pipeline active at any time - piplines can define as 85 | * many out variables as needed, within reason. 86 | * 87 | * Not available in depth pass. 88 | */ 89 | out vec4 frx_var0; 90 | out vec4 frx_var1; 91 | out vec4 frx_var2; 92 | out vec4 frx_var3; 93 | 94 | /** 95 | * Interpolated camera distance. Used for fog. 96 | * Set by renderer after material shader runs. Do not modify. 97 | * 98 | * Not available in depth pass. 99 | */ 100 | out float frx_distance; 101 | 102 | /**************************************************************** 103 | * API METHODS 104 | ****************************************************************/ 105 | 106 | /* 107 | * Called by renderer after all variables are initialized and before 108 | * frx_pipelineVertex() is called to update vertex outputs. 109 | * 110 | * The running vertex shader will have multiple, renamed versions of 111 | * this method - one for each unique material vertex shader present 112 | * in the game. The specific method called is controlled by the material 113 | * associated with the current triangle. If the current material does 114 | * not define a custom material shader, no extra processing will happen 115 | * before frx_pipelineVertex() is called. 116 | */ 117 | void frx_materialVertex(); 118 | 119 | /* 120 | * Called by renderer after frx_materialVertex() completes. 121 | * Pipeline authors implement this method to read vertex data, 122 | * apply transformation and update as needed. Pipeline vertex shaders 123 | * may also capture additional vertex outputs as neeed. 124 | * These steps are specific to the design of each pipeline. 125 | * 126 | * The pipeline shader is responsible for ALL updates to vertex outputs, 127 | * including those defined by the FREX API. 128 | */ 129 | void frx_pipelineVertex(); 130 | 131 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/lib/bitwise.glsl: -------------------------------------------------------------------------------- 1 | /****************************************************** 2 | frex:shaders/lib/bitwise.glsl 3 | DEPRECATED - No longer useful now that we have 4 | reliable bitwide operations in GLSL. 5 | ******************************************************/ 6 | 7 | #define frx_bitValue(byteValue, bitIndex) float((byteValue >> bitIndex) & 1u) 8 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/lib/color.glsl: -------------------------------------------------------------------------------- 1 | /****************************************************** 2 | frex:shaders/lib/color.glsl 3 | 4 | Common color processing functions. 5 | 6 | Portions taken from Wisdom Shaders by Cheng (Bob) Cao, Apache 2.0 license 7 | https://github.com/bobcao3/Wisdom-Shaders 8 | 9 | ******************************************************/ 10 | 11 | #define FRX_GAMMA 2.4 12 | #define FRX_INVERSE_GAMMA (1.0 / FRX_GAMMA) 13 | 14 | vec4 frx_fromGamma(vec4 c) { 15 | return pow(c, vec4(FRX_GAMMA)); 16 | } 17 | 18 | vec4 frx_toGamma(vec4 c) { 19 | return pow(c, vec4(FRX_INVERSE_GAMMA)); 20 | } 21 | 22 | vec3 frx_fromGamma(vec3 c) { 23 | return pow(c, vec3(FRX_GAMMA)); 24 | } 25 | 26 | vec3 frx_toGamma(vec3 c) { 27 | return pow(c, vec3(FRX_INVERSE_GAMMA)); 28 | } 29 | 30 | //float frx_luma(vec3 c) { 31 | // return dot(c, vec3(0.2126, 0.7152, 0.0722)); 32 | //} 33 | 34 | const mat3 FRX_ACES_INPUT_MATRIX = mat3( 35 | vec3(0.59719, 0.07600, 0.02840), 36 | vec3(0.35458, 0.90834, 0.13383), 37 | vec3(0.04823, 0.01566, 0.83777) 38 | ); 39 | 40 | // ODT_SAT => XYZ => D60_2_D65 => sRGB 41 | const mat3 FRX_ACES_OUTPUT_MATRIX = mat3( 42 | vec3(1.60475, -0.10208, -0.00327), 43 | vec3(-0.53108, 1.10813, -0.07276), 44 | vec3(-0.07367, -0.00605, 1.07602) 45 | ); 46 | 47 | vec3 FRX_RRT_AND_ODTF_FIT(vec3 v) { 48 | vec3 a = v * (v + 0.0245786f) - 0.000090537f; 49 | vec3 b = v * (0.983729f * v + 0.4329510f) + 0.238081f; 50 | return a / b; 51 | } 52 | 53 | vec3 frx_toneMap(vec3 color) { 54 | color = FRX_ACES_INPUT_MATRIX * color; 55 | color = FRX_RRT_AND_ODTF_FIT(color); 56 | return FRX_ACES_OUTPUT_MATRIX * color; 57 | } 58 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/lib/face.glsl: -------------------------------------------------------------------------------- 1 | /****************************************************** 2 | frex:shaders/lib/face.glsl 3 | 4 | Utilities for deriving facing and face-related attributes. 5 | ******************************************************/ 6 | 7 | #define FACE_DOWN 0 8 | #define FACE_UP 1 9 | #define FACE_NORTH 2 10 | #define FACE_SOUTH 3 11 | #define FACE_WEST 4 12 | #define FACE_EAST 5 13 | 14 | const mat3[6] FRX_UV_MATRIX = mat3[6]( 15 | mat3(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0), 16 | mat3(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0), 17 | mat3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0), 18 | mat3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0), 19 | mat3(0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0), 20 | mat3(0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0) 21 | ); 22 | 23 | /* 24 | * Returns the FACE_ constant most consistent with the 25 | * provided world-space normal. 26 | * 27 | * Will return garbage for normals in screen space. 28 | */ 29 | int frx_face(vec3 normal) { 30 | vec3 a = abs(normal); 31 | float m = max(max(a.x, a.y), a.z); 32 | 33 | return a.x == m ? (normal.x > 0 ? FACE_EAST : FACE_WEST) 34 | : a.y == m ? (normal.y > 0 ? FACE_UP : FACE_DOWN) 35 | : (normal.z > 0 ? FACE_SOUTH : FACE_NORTH); 36 | } 37 | 38 | /* 39 | * Estimates UV coordinates for a world-space position 40 | * and world-space normal, assuming texture coordinates 41 | * are from the 0,0 face corner to the opposite corner. 42 | * 43 | * The result is similar to "locked-uv" coordinate mapping 44 | * in block/item models. 45 | * 46 | * Will return garbage for vertex or normals in screen space. 47 | */ 48 | vec2 frx_faceUv(vec3 pos, vec3 normal) { 49 | mat3 m = FRX_UV_MATRIX[frx_face(normal)]; 50 | vec3 result = m * pos; 51 | return result.xy; 52 | } 53 | 54 | /* 55 | * Estimates UV coordinates for a world-space position 56 | * and world-space normal, assuming texture coordinates 57 | * are from the 0,0 face corner to the opposite corner. 58 | * 59 | * The result is similar to "locked-uv" coordinate mapping 60 | * in block/item models. 61 | * 62 | * Will return garbage for vertex or normals in screen space. 63 | */ 64 | vec2 frx_faceUv(vec3 pos, int face) { 65 | mat3 m = FRX_UV_MATRIX[face]; 66 | vec3 result = m * pos; 67 | return result.xy; 68 | } 69 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/lib/math.glsl: -------------------------------------------------------------------------------- 1 | /****************************************************** 2 | frex:shaders/lib/math.glsl 3 | 4 | Commonly useful declarations and utilities. 5 | Use of these is entirely optional - half the fun 6 | is making your own. 7 | ******************************************************/ 8 | 9 | #define PI 3.1415926535897932384626433832795 10 | #define HALF_PI 1.57079632679489661923 // I prefer a whole pi when I can get it, but I won't say no to half. 11 | #define TAU 6.2831853071795864769252867665590 // two PI 12 | 13 | /* 14 | * Has been around forever. Gives a psuedorandom 15 | * hash value given two variables. Wouldn't be OK 16 | * for cryptography but may get the job done here. 17 | * 18 | * https://thebookofshaders.com/10/ 19 | * https://stackoverflow.com/questions/12964279/whats-the-origin-of-this-glsl-rand-one-liner 20 | */ 21 | float frx_noise2d(vec2 st) { 22 | return fract(sin(dot(st.xy, vec2(12.9898, 78.233)))*43758.5453123); 23 | } 24 | 25 | /** 26 | * Ken Perlin's improved smoothstep 27 | */ 28 | float frx_smootherstep(float edge0, float edge1, float x) { 29 | // Scale, and clamp to 0..1 range 30 | x = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0); 31 | // Evaluate polynomial 32 | return x * x * x * (x * (x * 6 - 15) + 10); 33 | } 34 | 35 | /** 36 | * Ken Perlin's improved smoothstep 37 | */ 38 | vec3 frx_smootherstep(float edge0, float edge1, vec3 value) { 39 | // Scale, and clamp to 0..1 range 40 | vec3 r = clamp((value - edge0) / (edge1 - edge0), 0.0, 1.0); 41 | // Evaluate polynomial 42 | return r * r * r * (r * (r * 6 - 15) + 10); 43 | } 44 | 45 | /* 46 | * Animated 2d noise function, 47 | * designed to accept a time parameter. 48 | * 49 | * Based in part on 2D Noise by Morgan McGuire @morgan3d 50 | * https://www.shadertoy.com/view/4dS3Wd 51 | */ 52 | float frx_noise2dt (in vec2 st, float t) { 53 | vec2 i = floor(st); 54 | vec2 f = fract(st); 55 | 56 | // Compute values for four corners 57 | float a = frx_noise2d(i); 58 | float b = frx_noise2d(i + vec2(1.0, 0.0)); 59 | float c = frx_noise2d(i + vec2(0.0, 1.0)); 60 | float d = frx_noise2d(i + vec2(1.0, 1.0)); 61 | 62 | a = 0.5 + sin((0.5 + a) * t) * 0.5; 63 | b = 0.5 + sin((0.5 + b) * t) * 0.5; 64 | c = 0.5 + sin((0.5 + c) * t) * 0.5; 65 | d = 0.5 + sin((0.5 + d) * t) * 0.5; 66 | 67 | // Mix 4 corners 68 | return mix(a, b, f.x) + 69 | (c - a)* f.y * (1.0 - f.x) + 70 | (d - b) * f.x * f.y; 71 | } 72 | 73 | /* 74 | * Converts RGB to grayscale. 75 | */ 76 | float frx_luminance(vec3 color) { 77 | return dot(color.rgb, vec3(0.299, 0.587, 0.114)); 78 | } 79 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/lib/noise/LICENSE: -------------------------------------------------------------------------------- 1 | NOTE: shaders in this folder are from https://github.com/stegu/webgl-noise 2 | and are bundled for convenience of shader authors. 3 | Original license is reproduced below and applies only to content in this folder. 4 | -- Grondag 5 | 6 | Copyright (C) 2011 by Ashima Arts (Simplex noise) 7 | Copyright (C) 2011-2016 by Stefan Gustavson (Classic noise and others) 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in 17 | all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/lib/noise/README: -------------------------------------------------------------------------------- 1 | NOTE: shaders in this folder are from https://github.com/stegu/webgl-noise 2 | and are bundled for convenience of shader authors. 3 | Original readme is reproduced below. 4 | -- Grondag 5 | 6 | 7 | These files contain noise functions that are compatible with all 8 | current versions of GLSL (1.20 and up), and all you need to use them 9 | is provided in the source file. There is no external data, and no 10 | setup procedure. Just cut and paste and call the function. 11 | 12 | GLSL has a very rudimentary linker, so some helper functions are 13 | included in several of the files with the same name. If you want to 14 | use more than one of these functions in the same shader, you may run 15 | into problems with redefinition of the functions mod289() and permute(). 16 | If that happens, just delete any superfluous definitions. 17 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/lib/noise/cellular2d.glsl: -------------------------------------------------------------------------------- 1 | #include frex:shaders/lib/noise/noisecommon.glsl 2 | 3 | /****************************************************** 4 | frex:shaders/lib/noise/cellular2d.glsl 5 | 6 | External MIT noise library - bundled for convenience. 7 | 8 | No modifications have been made except to remove 9 | the #version header, add this comment block, and 10 | move some shared functions to noisecommon.glsl. 11 | ******************************************************/ 12 | 13 | // Cellular noise ("Worley noise") in 2D in GLSL. 14 | // Copyright (c) Stefan Gustavson 2011-04-19. All rights reserved. 15 | // This code is released under the conditions of the MIT license. 16 | // See LICENSE file for details. 17 | // https://github.com/stegu/webgl-noise 18 | 19 | // Cellular noise, returning F1 and F2 in a vec2. 20 | // Standard 3x3 search window for good F1 and F2 values 21 | vec2 cellular(vec2 P) { 22 | #define K 0.142857142857// 1/7 23 | #define Ko 0.428571428571// 3/7 24 | #define jitter 1.0// Less gives more regular pattern 25 | vec2 Pi = mod289(floor(P)); 26 | vec2 Pf = fract(P); 27 | vec3 oi = vec3(-1.0, 0.0, 1.0); 28 | vec3 of = vec3(-0.5, 0.5, 1.5); 29 | vec3 px = permute(Pi.x + oi); 30 | vec3 p = permute(px.x + Pi.y + oi);// p11, p12, p13 31 | vec3 ox = fract(p*K) - Ko; 32 | vec3 oy = mod7(floor(p*K))*K - Ko; 33 | vec3 dx = Pf.x + 0.5 + jitter*ox; 34 | vec3 dy = Pf.y - of + jitter*oy; 35 | vec3 d1 = dx * dx + dy * dy;// d11, d12 and d13, squared 36 | p = permute(px.y + Pi.y + oi);// p21, p22, p23 37 | ox = fract(p*K) - Ko; 38 | oy = mod7(floor(p*K))*K - Ko; 39 | dx = Pf.x - 0.5 + jitter*ox; 40 | dy = Pf.y - of + jitter*oy; 41 | vec3 d2 = dx * dx + dy * dy;// d21, d22 and d23, squared 42 | p = permute(px.z + Pi.y + oi);// p31, p32, p33 43 | ox = fract(p*K) - Ko; 44 | oy = mod7(floor(p*K))*K - Ko; 45 | dx = Pf.x - 1.5 + jitter*ox; 46 | dy = Pf.y - of + jitter*oy; 47 | vec3 d3 = dx * dx + dy * dy;// d31, d32 and d33, squared 48 | // Sort out the two smallest distances (F1, F2) 49 | vec3 d1a = min(d1, d2); 50 | d2 = max(d1, d2);// Swap to keep candidates for F2 51 | d2 = min(d2, d3);// neither F1 nor F2 are now in d3 52 | d1 = min(d1a, d2);// F1 is now in d1 53 | d2 = max(d1a, d2);// Swap to keep candidates for F2 54 | d1.xy = (d1.x < d1.y) ? d1.xy : d1.yx;// Swap if smaller 55 | d1.xz = (d1.x < d1.z) ? d1.xz : d1.zx;// F1 is in d1.x 56 | d1.yz = min(d1.yz, d2.yz);// F2 is now not in d2.yz 57 | d1.y = min(d1.y, d1.z);// nor in d1.z 58 | d1.y = min(d1.y, d2.x);// F2 is in d1.y, we're done. 59 | return sqrt(d1.xy); 60 | } 61 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/lib/noise/cellular2x2.glsl: -------------------------------------------------------------------------------- 1 | #include frex:shaders/lib/noise/noisecommon.glsl 2 | 3 | /****************************************************** 4 | frex:shaders/lib/noise/cellular2x2.glsl 5 | 6 | External MIT noise library - bundled for convenience. 7 | 8 | No modifications have been made except to remove 9 | the #version header, add this comment block, and 10 | move some shared functions to noisecommon.glsl. 11 | ******************************************************/ 12 | 13 | // Cellular noise ("Worley noise") in 2D in GLSL. 14 | // Copyright (c) Stefan Gustavson 2011-04-19. All rights reserved. 15 | // This code is released under the conditions of the MIT license. 16 | // See LICENSE file for details. 17 | // https://github.com/stegu/webgl-noise 18 | 19 | // Cellular noise, returning F1 and F2 in a vec2. 20 | // Speeded up by using 2x2 search window instead of 3x3, 21 | // at the expense of some strong pattern artifacts. 22 | // F2 is often wrong and has sharp discontinuities. 23 | // If you need a smooth F2, use the slower 3x3 version. 24 | // F1 is sometimes wrong, too, but OK for most purposes. 25 | vec2 cellular2x2(vec2 P) { 26 | #define K 0.142857142857// 1/7 27 | #define K2 0.0714285714285// K/2 28 | #define jitter 0.8// jitter 1.0 makes F1 wrong more often 29 | vec2 Pi = mod289(floor(P)); 30 | vec2 Pf = fract(P); 31 | vec4 Pfx = Pf.x + vec4(-0.5, -1.5, -0.5, -1.5); 32 | vec4 Pfy = Pf.y + vec4(-0.5, -0.5, -1.5, -1.5); 33 | vec4 p = permute(Pi.x + vec4(0.0, 1.0, 0.0, 1.0)); 34 | p = permute(p + Pi.y + vec4(0.0, 0.0, 1.0, 1.0)); 35 | vec4 ox = mod7(p)*K+K2; 36 | vec4 oy = mod7(floor(p*K))*K+K2; 37 | vec4 dx = Pfx + jitter*ox; 38 | vec4 dy = Pfy + jitter*oy; 39 | vec4 d = dx * dx + dy * dy;// d11, d12, d21 and d22, squared 40 | // Sort out the two smallest distances 41 | #if 0 42 | // Cheat and pick only F1 43 | d.xy = min(d.xy, d.zw); 44 | d.x = min(d.x, d.y); 45 | return vec2(sqrt(d.x));// F1 duplicated, F2 not computed 46 | #else 47 | // Do it right and find both F1 and F2 48 | d.xy = (d.x < d.y) ? d.xy : d.yx;// Swap if smaller 49 | d.xz = (d.x < d.z) ? d.xz : d.zx; 50 | d.xw = (d.x < d.w) ? d.xw : d.wx; 51 | d.y = min(d.y, d.z); 52 | d.y = min(d.y, d.w); 53 | return sqrt(d.xy); 54 | #endif 55 | } 56 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/lib/noise/cellular2x2x2.glsl: -------------------------------------------------------------------------------- 1 | #include frex:shaders/lib/noise/noisecommon.glsl 2 | 3 | /****************************************************** 4 | frex:shaders/lib/noise/cellular2x2x2.glsl 5 | 6 | External MIT noise library - bundled for convenience. 7 | 8 | No modifications have been made except to remove 9 | the #version header, add this comment block, and 10 | move some shared functions to noisecommon.glsl. 11 | ******************************************************/ 12 | 13 | // Cellular noise ("Worley noise") in 3D in GLSL. 14 | // Copyright (c) Stefan Gustavson 2011-04-19. All rights reserved. 15 | // This code is released under the conditions of the MIT license. 16 | // See LICENSE file for details. 17 | // https://github.com/stegu/webgl-noise 18 | 19 | // Cellular noise, returning F1 and F2 in a vec2. 20 | // Speeded up by using 2x2x2 search window instead of 3x3x3, 21 | // at the expense of some pattern artifacts. 22 | // F2 is often wrong and has sharp discontinuities. 23 | // If you need a good F2, use the slower 3x3x3 version. 24 | vec2 cellular2x2x2(vec3 P) { 25 | #define K 0.142857142857// 1/7 26 | #define Ko 0.428571428571// 1/2-K/2 27 | #define K2 0.020408163265306// 1/(7*7) 28 | #define Kz 0.166666666667// 1/6 29 | #define Kzo 0.416666666667// 1/2-1/6*2 30 | #define jitter 0.8// smaller jitter gives less errors in F2 31 | vec3 Pi = mod289(floor(P)); 32 | vec3 Pf = fract(P); 33 | vec4 Pfx = Pf.x + vec4(0.0, -1.0, 0.0, -1.0); 34 | vec4 Pfy = Pf.y + vec4(0.0, 0.0, -1.0, -1.0); 35 | vec4 p = permute(Pi.x + vec4(0.0, 1.0, 0.0, 1.0)); 36 | p = permute(p + Pi.y + vec4(0.0, 0.0, 1.0, 1.0)); 37 | vec4 p1 = permute(p + Pi.z);// z+0 38 | vec4 p2 = permute(p + Pi.z + vec4(1.0));// z+1 39 | vec4 ox1 = fract(p1*K) - Ko; 40 | vec4 oy1 = mod7(floor(p1*K))*K - Ko; 41 | vec4 oz1 = floor(p1*K2)*Kz - Kzo;// p1 < 289 guaranteed 42 | vec4 ox2 = fract(p2*K) - Ko; 43 | vec4 oy2 = mod7(floor(p2*K))*K - Ko; 44 | vec4 oz2 = floor(p2*K2)*Kz - Kzo; 45 | vec4 dx1 = Pfx + jitter*ox1; 46 | vec4 dy1 = Pfy + jitter*oy1; 47 | vec4 dz1 = Pf.z + jitter*oz1; 48 | vec4 dx2 = Pfx + jitter*ox2; 49 | vec4 dy2 = Pfy + jitter*oy2; 50 | vec4 dz2 = Pf.z - 1.0 + jitter*oz2; 51 | vec4 d1 = dx1 * dx1 + dy1 * dy1 + dz1 * dz1;// z+0 52 | vec4 d2 = dx2 * dx2 + dy2 * dy2 + dz2 * dz2;// z+1 53 | 54 | // Sort out the two smallest distances (F1, F2) 55 | #if 0 56 | // Cheat and sort out only F1 57 | d1 = min(d1, d2); 58 | d1.xy = min(d1.xy, d1.wz); 59 | d1.x = min(d1.x, d1.y); 60 | return vec2(sqrt(d1.x)); 61 | #else 62 | // Do it right and sort out both F1 and F2 63 | vec4 d = min(d1, d2);// F1 is now in d 64 | d2 = max(d1, d2);// Make sure we keep all candidates for F2 65 | d.xy = (d.x < d.y) ? d.xy : d.yx;// Swap smallest to d.x 66 | d.xz = (d.x < d.z) ? d.xz : d.zx; 67 | d.xw = (d.x < d.w) ? d.xw : d.wx;// F1 is now in d.x 68 | d.yzw = min(d.yzw, d2.yzw);// F2 now not in d2.yzw 69 | d.y = min(d.y, d.z);// nor in d.z 70 | d.y = min(d.y, d.w);// nor in d.w 71 | d.y = min(d.y, d2.x);// F2 is now in d.y 72 | return sqrt(d.xy);// F1 and F2 73 | #endif 74 | } 75 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/lib/noise/classicnoise2d.glsl: -------------------------------------------------------------------------------- 1 | #include frex:shaders/lib/noise/noisecommon.glsl 2 | 3 | /****************************************************** 4 | frex:shaders/lib/noise/classicnoise2d.glsl 5 | 6 | External MIT noise library - bundled for convenience. 7 | 8 | No modifications have been made except to remove 9 | the #version header, add this comment block, and 10 | move some shared functions to noisecommon.glsl. 11 | ******************************************************/ 12 | 13 | // 14 | // GLSL textureless classic 2D noise "cnoise", 15 | // with an RSL-style periodic variant "pnoise". 16 | // Author: Stefan Gustavson (stefan.gustavson@liu.se) 17 | // Version: 2011-08-22 18 | // 19 | // Many thanks to Ian McEwan of Ashima Arts for the 20 | // ideas for permutation and gradient selection. 21 | // 22 | // Copyright (c) 2011 Stefan Gustavson. All rights reserved. 23 | // Distributed under the MIT license. See LICENSE file. 24 | // https://github.com/stegu/webgl-noise 25 | // 26 | 27 | vec2 fade(vec2 t) { 28 | return t*t*t*(t*(t*6.0-15.0)+10.0); 29 | } 30 | 31 | // Classic Perlin noise 32 | float cnoise(vec2 P) 33 | { 34 | vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0); 35 | vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0); 36 | Pi = mod289(Pi);// To avoid truncation effects in permutation 37 | vec4 ix = Pi.xzxz; 38 | vec4 iy = Pi.yyww; 39 | vec4 fx = Pf.xzxz; 40 | vec4 fy = Pf.yyww; 41 | 42 | vec4 i = permute(permute(ix) + iy); 43 | 44 | vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0; 45 | vec4 gy = abs(gx) - 0.5; 46 | vec4 tx = floor(gx + 0.5); 47 | gx = gx - tx; 48 | 49 | vec2 g00 = vec2(gx.x, gy.x); 50 | vec2 g10 = vec2(gx.y, gy.y); 51 | vec2 g01 = vec2(gx.z, gy.z); 52 | vec2 g11 = vec2(gx.w, gy.w); 53 | 54 | vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); 55 | g00 *= norm.x; 56 | g01 *= norm.y; 57 | g10 *= norm.z; 58 | g11 *= norm.w; 59 | 60 | float n00 = dot(g00, vec2(fx.x, fy.x)); 61 | float n10 = dot(g10, vec2(fx.y, fy.y)); 62 | float n01 = dot(g01, vec2(fx.z, fy.z)); 63 | float n11 = dot(g11, vec2(fx.w, fy.w)); 64 | 65 | vec2 fade_xy = fade(Pf.xy); 66 | vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x); 67 | float n_xy = mix(n_x.x, n_x.y, fade_xy.y); 68 | return 2.3 * n_xy; 69 | } 70 | 71 | // Classic Perlin noise, periodic variant 72 | float pnoise(vec2 P, vec2 rep) 73 | { 74 | vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0); 75 | vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0); 76 | Pi = mod(Pi, rep.xyxy);// To create noise with explicit period 77 | Pi = mod289(Pi);// To avoid truncation effects in permutation 78 | vec4 ix = Pi.xzxz; 79 | vec4 iy = Pi.yyww; 80 | vec4 fx = Pf.xzxz; 81 | vec4 fy = Pf.yyww; 82 | 83 | vec4 i = permute(permute(ix) + iy); 84 | 85 | vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0; 86 | vec4 gy = abs(gx) - 0.5; 87 | vec4 tx = floor(gx + 0.5); 88 | gx = gx - tx; 89 | 90 | vec2 g00 = vec2(gx.x, gy.x); 91 | vec2 g10 = vec2(gx.y, gy.y); 92 | vec2 g01 = vec2(gx.z, gy.z); 93 | vec2 g11 = vec2(gx.w, gy.w); 94 | 95 | vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); 96 | g00 *= norm.x; 97 | g01 *= norm.y; 98 | g10 *= norm.z; 99 | g11 *= norm.w; 100 | 101 | float n00 = dot(g00, vec2(fx.x, fy.x)); 102 | float n10 = dot(g10, vec2(fx.y, fy.y)); 103 | float n01 = dot(g01, vec2(fx.z, fy.z)); 104 | float n11 = dot(g11, vec2(fx.w, fy.w)); 105 | 106 | vec2 fade_xy = fade(Pf.xy); 107 | vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x); 108 | float n_xy = mix(n_x.x, n_x.y, fade_xy.y); 109 | return 2.3 * n_xy; 110 | } 111 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/lib/noise/noise2d.glsl: -------------------------------------------------------------------------------- 1 | #include frex:shaders/lib/noise/noisecommon.glsl 2 | 3 | /****************************************************** 4 | frex:shaders/lib/noise/noise2d.glsl 5 | 6 | External MIT noise library - bundled for convenience. 7 | 8 | No modifications have been made except to remove 9 | the #version header, add this comment block, and 10 | move some shared functions to noisecommon.glsl. 11 | ******************************************************/ 12 | 13 | // 14 | // Description : Array and textureless GLSL 2D simplex noise function. 15 | // Author : Ian McEwan, Ashima Arts. 16 | // Maintainer : stegu 17 | // Lastmod : 20110822 (ijm) 18 | // License : Copyright (C) 2011 Ashima Arts. All rights reserved. 19 | // Distributed under the MIT License. See LICENSE file. 20 | // https://github.com/ashima/webgl-noise 21 | // https://github.com/stegu/webgl-noise 22 | // 23 | 24 | float snoise(vec2 v) 25 | { 26 | const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 27 | 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) 28 | -0.577350269189626, // -1.0 + 2.0 * C.x 29 | 0.024390243902439);// 1.0 / 41.0 30 | // First corner 31 | vec2 i = floor(v + dot(v, C.yy)); 32 | vec2 x0 = v - i + dot(i, C.xx); 33 | 34 | // Other corners 35 | vec2 i1; 36 | //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 37 | //i1.y = 1.0 - i1.x; 38 | i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); 39 | // x0 = x0 - 0.0 + 0.0 * C.xx ; 40 | // x1 = x0 - i1 + 1.0 * C.xx ; 41 | // x2 = x0 - 1.0 + 2.0 * C.xx ; 42 | vec4 x12 = x0.xyxy + C.xxzz; 43 | x12.xy -= i1; 44 | 45 | // Permutations 46 | i = mod289(i);// Avoid truncation effects in permutation 47 | vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0)) 48 | + i.x + vec3(0.0, i1.x, 1.0)); 49 | 50 | vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0); 51 | m = m*m; 52 | m = m*m; 53 | 54 | // Gradients: 41 points uniformly over a line, mapped onto a diamond. 55 | // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) 56 | 57 | vec3 x = 2.0 * fract(p * C.www) - 1.0; 58 | vec3 h = abs(x) - 0.5; 59 | vec3 ox = floor(x + 0.5); 60 | vec3 a0 = x - ox; 61 | 62 | // Normalise gradients implicitly by scaling m 63 | // Approximation of: m *= inversesqrt( a0*a0 + h*h ); 64 | m *= 1.79284291400159 - 0.85373472095314 * (a0*a0 + h*h); 65 | 66 | // Compute final noise value at P 67 | vec3 g; 68 | g.x = a0.x * x0.x + h.x * x0.y; 69 | g.yz = a0.yz * x12.xz + h.yz * x12.yw; 70 | return 130.0 * dot(m, g); 71 | } 72 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/lib/noise/noise3d.glsl: -------------------------------------------------------------------------------- 1 | #include frex:shaders/lib/noise/noisecommon.glsl 2 | 3 | /****************************************************** 4 | frex:shaders/lib/noise/noise3d.glsl 5 | 6 | External MIT noise library - bundled for convenience. 7 | 8 | No modifications have been made except to remove 9 | the #version header, add this comment block, and 10 | move some shared functions to noisecommon.glsl. 11 | ******************************************************/ 12 | 13 | // 14 | // Description : Array and textureless GLSL 2D/3D/4D simplex 15 | // noise functions. 16 | // Author : Ian McEwan, Ashima Arts. 17 | // Maintainer : stegu 18 | // Lastmod : 20110822 (ijm) 19 | // License : Copyright (C) 2011 Ashima Arts. All rights reserved. 20 | // Distributed under the MIT License. See LICENSE file. 21 | // https://github.com/ashima/webgl-noise 22 | // https://github.com/stegu/webgl-noise 23 | // 24 | 25 | float snoise(vec3 v) 26 | { 27 | const vec2 C = vec2(1.0/6.0, 1.0/3.0); 28 | const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); 29 | 30 | // First corner 31 | vec3 i = floor(v + dot(v, C.yyy)); 32 | vec3 x0 = v - i + dot(i, C.xxx); 33 | 34 | // Other corners 35 | vec3 g = step(x0.yzx, x0.xyz); 36 | vec3 l = 1.0 - g; 37 | vec3 i1 = min(g.xyz, l.zxy); 38 | vec3 i2 = max(g.xyz, l.zxy); 39 | 40 | // x0 = x0 - 0.0 + 0.0 * C.xxx; 41 | // x1 = x0 - i1 + 1.0 * C.xxx; 42 | // x2 = x0 - i2 + 2.0 * C.xxx; 43 | // x3 = x0 - 1.0 + 3.0 * C.xxx; 44 | vec3 x1 = x0 - i1 + C.xxx; 45 | vec3 x2 = x0 - i2 + C.yyy;// 2.0*C.x = 1/3 = C.y 46 | vec3 x3 = x0 - D.yyy;// -1.0+3.0*C.x = -0.5 = -D.y 47 | 48 | // Permutations 49 | i = mod289(i); 50 | vec4 p = permute(permute(permute( 51 | i.z + vec4(0.0, i1.z, i2.z, 1.0)) 52 | + i.y + vec4(0.0, i1.y, i2.y, 1.0)) 53 | + i.x + vec4(0.0, i1.x, i2.x, 1.0)); 54 | 55 | // Gradients: 7x7 points over a square, mapped onto an octahedron. 56 | // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) 57 | float n_ = 0.142857142857;// 1.0/7.0 58 | vec3 ns = n_ * D.wyz - D.xzx; 59 | 60 | vec4 j = p - 49.0 * floor(p * ns.z * ns.z);// mod(p,7*7) 61 | 62 | vec4 x_ = floor(j * ns.z); 63 | vec4 y_ = floor(j - 7.0 * x_);// mod(j,N) 64 | 65 | vec4 x = x_ *ns.x + ns.yyyy; 66 | vec4 y = y_ *ns.x + ns.yyyy; 67 | vec4 h = 1.0 - abs(x) - abs(y); 68 | 69 | vec4 b0 = vec4(x.xy, y.xy); 70 | vec4 b1 = vec4(x.zw, y.zw); 71 | 72 | //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; 73 | //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; 74 | vec4 s0 = floor(b0)*2.0 + 1.0; 75 | vec4 s1 = floor(b1)*2.0 + 1.0; 76 | vec4 sh = -step(h, vec4(0.0)); 77 | 78 | vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy; 79 | vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww; 80 | 81 | vec3 p0 = vec3(a0.xy, h.x); 82 | vec3 p1 = vec3(a0.zw, h.y); 83 | vec3 p2 = vec3(a1.xy, h.z); 84 | vec3 p3 = vec3(a1.zw, h.w); 85 | 86 | //Normalise gradients 87 | vec4 norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); 88 | p0 *= norm.x; 89 | p1 *= norm.y; 90 | p2 *= norm.z; 91 | p3 *= norm.w; 92 | 93 | // Mix final noise value 94 | vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0); 95 | m = m * m; 96 | return 42.0 * dot(m*m, vec4(dot(p0, x0), dot(p1, x1), 97 | dot(p2, x2), dot(p3, x3))); 98 | } 99 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/lib/noise/noise3dgrad.glsl: -------------------------------------------------------------------------------- 1 | #include frex:shaders/lib/noise/noisecommon.glsl 2 | 3 | /****************************************************** 4 | frex:shaders/lib/noise/noise3dgrad.glsl 5 | 6 | External MIT noise library - bundled for convenience. 7 | 8 | No modifications have been made except to remove 9 | the #version header, add this comment block, and 10 | move some shared functions to noisecommon.glsl. 11 | ******************************************************/ 12 | 13 | // 14 | // Description : Array and textureless GLSL 2D/3D/4D simplex 15 | // noise functions. 16 | // Author : Ian McEwan, Ashima Arts. 17 | // Maintainer : stegu 18 | // Lastmod : 20110822 (ijm) 19 | // License : Copyright (C) 2011 Ashima Arts. All rights reserved. 20 | // Distributed under the MIT License. See LICENSE file. 21 | // https://github.com/ashima/webgl-noise 22 | // https://github.com/stegu/webgl-noise 23 | // 24 | 25 | float snoise(vec3 v, out vec3 gradient) 26 | { 27 | const vec2 C = vec2(1.0/6.0, 1.0/3.0); 28 | const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); 29 | 30 | // First corner 31 | vec3 i = floor(v + dot(v, C.yyy)); 32 | vec3 x0 = v - i + dot(i, C.xxx); 33 | 34 | // Other corners 35 | vec3 g = step(x0.yzx, x0.xyz); 36 | vec3 l = 1.0 - g; 37 | vec3 i1 = min(g.xyz, l.zxy); 38 | vec3 i2 = max(g.xyz, l.zxy); 39 | 40 | // x0 = x0 - 0.0 + 0.0 * C.xxx; 41 | // x1 = x0 - i1 + 1.0 * C.xxx; 42 | // x2 = x0 - i2 + 2.0 * C.xxx; 43 | // x3 = x0 - 1.0 + 3.0 * C.xxx; 44 | vec3 x1 = x0 - i1 + C.xxx; 45 | vec3 x2 = x0 - i2 + C.yyy;// 2.0*C.x = 1/3 = C.y 46 | vec3 x3 = x0 - D.yyy;// -1.0+3.0*C.x = -0.5 = -D.y 47 | 48 | // Permutations 49 | i = mod289(i); 50 | vec4 p = permute(permute(permute( 51 | i.z + vec4(0.0, i1.z, i2.z, 1.0)) 52 | + i.y + vec4(0.0, i1.y, i2.y, 1.0)) 53 | + i.x + vec4(0.0, i1.x, i2.x, 1.0)); 54 | 55 | // Gradients: 7x7 points over a square, mapped onto an octahedron. 56 | // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) 57 | float n_ = 0.142857142857;// 1.0/7.0 58 | vec3 ns = n_ * D.wyz - D.xzx; 59 | 60 | vec4 j = p - 49.0 * floor(p * ns.z * ns.z);// mod(p,7*7) 61 | 62 | vec4 x_ = floor(j * ns.z); 63 | vec4 y_ = floor(j - 7.0 * x_);// mod(j,N) 64 | 65 | vec4 x = x_ *ns.x + ns.yyyy; 66 | vec4 y = y_ *ns.x + ns.yyyy; 67 | vec4 h = 1.0 - abs(x) - abs(y); 68 | 69 | vec4 b0 = vec4(x.xy, y.xy); 70 | vec4 b1 = vec4(x.zw, y.zw); 71 | 72 | //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; 73 | //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; 74 | vec4 s0 = floor(b0)*2.0 + 1.0; 75 | vec4 s1 = floor(b1)*2.0 + 1.0; 76 | vec4 sh = -step(h, vec4(0.0)); 77 | 78 | vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy; 79 | vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww; 80 | 81 | vec3 p0 = vec3(a0.xy, h.x); 82 | vec3 p1 = vec3(a0.zw, h.y); 83 | vec3 p2 = vec3(a1.xy, h.z); 84 | vec3 p3 = vec3(a1.zw, h.w); 85 | 86 | //Normalise gradients 87 | vec4 norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); 88 | p0 *= norm.x; 89 | p1 *= norm.y; 90 | p2 *= norm.z; 91 | p3 *= norm.w; 92 | 93 | // Mix final noise value 94 | vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0); 95 | vec4 m2 = m * m; 96 | vec4 m4 = m2 * m2; 97 | vec4 pdotx = vec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)); 98 | 99 | // Determine noise gradient 100 | vec4 temp = m2 * m * pdotx; 101 | gradient = -8.0 * (temp.x * x0 + temp.y * x1 + temp.z * x2 + temp.w * x3); 102 | gradient += m4.x * p0 + m4.y * p1 + m4.z * p2 + m4.w * p3; 103 | gradient *= 42.0; 104 | 105 | return 42.0 * dot(m4, pdotx); 106 | } 107 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/lib/noise/noise4d.glsl: -------------------------------------------------------------------------------- 1 | #include frex:shaders/lib/noise/noisecommon.glsl 2 | 3 | /****************************************************** 4 | frex:shaders/lib/noise/noise4d.glsl 5 | 6 | External MIT noise library - bundled for convenience. 7 | 8 | No modifications have been made except to remove 9 | the #version header, add this comment block, and 10 | move some shared functions to noisecommon.glsl. 11 | ******************************************************/ 12 | 13 | // 14 | // Description : Array and textureless GLSL 2D/3D/4D simplex 15 | // noise functions. 16 | // Author : Ian McEwan, Ashima Arts. 17 | // Maintainer : stegu 18 | // Lastmod : 20110822 (ijm) 19 | // License : Copyright (C) 2011 Ashima Arts. All rights reserved. 20 | // Distributed under the MIT License. See LICENSE file. 21 | // https://github.com/ashima/webgl-noise 22 | // https://github.com/stegu/webgl-noise 23 | // 24 | 25 | vec4 grad4(float j, vec4 ip) 26 | { 27 | const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0); 28 | vec4 p, s; 29 | 30 | p.xyz = floor(fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0; 31 | p.w = 1.5 - dot(abs(p.xyz), ones.xyz); 32 | s = vec4(lessThan(p, vec4(0.0))); 33 | p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www; 34 | 35 | return p; 36 | } 37 | 38 | // (sqrt(5) - 1)/4 = F4, used once below 39 | #define F4 0.309016994374947451 40 | 41 | float snoise(vec4 v) 42 | { 43 | const vec4 C = vec4(0.138196601125011, // (5 - sqrt(5))/20 G4 44 | 0.276393202250021, // 2 * G4 45 | 0.414589803375032, // 3 * G4 46 | -0.447213595499958);// -1 + 4 * G4 47 | 48 | // First corner 49 | vec4 i = floor(v + dot(v, vec4(F4))); 50 | vec4 x0 = v - i + dot(i, C.xxxx); 51 | 52 | // Other corners 53 | 54 | // Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI) 55 | vec4 i0; 56 | vec3 isX = step(x0.yzw, x0.xxx); 57 | vec3 isYZ = step(x0.zww, x0.yyz); 58 | // i0.x = dot( isX, vec3( 1.0 ) ); 59 | i0.x = isX.x + isX.y + isX.z; 60 | i0.yzw = 1.0 - isX; 61 | // i0.y += dot( isYZ.xy, vec2( 1.0 ) ); 62 | i0.y += isYZ.x + isYZ.y; 63 | i0.zw += 1.0 - isYZ.xy; 64 | i0.z += isYZ.z; 65 | i0.w += 1.0 - isYZ.z; 66 | 67 | // i0 now contains the unique values 0,1,2,3 in each channel 68 | vec4 i3 = clamp(i0, 0.0, 1.0); 69 | vec4 i2 = clamp(i0-1.0, 0.0, 1.0); 70 | vec4 i1 = clamp(i0-2.0, 0.0, 1.0); 71 | 72 | // x0 = x0 - 0.0 + 0.0 * C.xxxx 73 | // x1 = x0 - i1 + 1.0 * C.xxxx 74 | // x2 = x0 - i2 + 2.0 * C.xxxx 75 | // x3 = x0 - i3 + 3.0 * C.xxxx 76 | // x4 = x0 - 1.0 + 4.0 * C.xxxx 77 | vec4 x1 = x0 - i1 + C.xxxx; 78 | vec4 x2 = x0 - i2 + C.yyyy; 79 | vec4 x3 = x0 - i3 + C.zzzz; 80 | vec4 x4 = x0 + C.wwww; 81 | 82 | // Permutations 83 | i = mod289(i); 84 | float j0 = permute(permute(permute(permute(i.w) + i.z) + i.y) + i.x); 85 | vec4 j1 = permute(permute(permute(permute ( 86 | i.w + vec4(i1.w, i2.w, i3.w, 1.0)) 87 | + i.z + vec4(i1.z, i2.z, i3.z, 1.0)) 88 | + i.y + vec4(i1.y, i2.y, i3.y, 1.0)) 89 | + i.x + vec4(i1.x, i2.x, i3.x, 1.0)); 90 | 91 | // Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope 92 | // 7*7*6 = 294, which is close to the ring size 17*17 = 289. 93 | vec4 ip = vec4(1.0/294.0, 1.0/49.0, 1.0/7.0, 0.0); 94 | 95 | vec4 p0 = grad4(j0, ip); 96 | vec4 p1 = grad4(j1.x, ip); 97 | vec4 p2 = grad4(j1.y, ip); 98 | vec4 p3 = grad4(j1.z, ip); 99 | vec4 p4 = grad4(j1.w, ip); 100 | 101 | // Normalise gradients 102 | vec4 norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); 103 | p0 *= norm.x; 104 | p1 *= norm.y; 105 | p2 *= norm.z; 106 | p3 *= norm.w; 107 | p4 *= taylorInvSqrt(dot(p4, p4)); 108 | 109 | // Mix contributions from the five corners 110 | vec3 m0 = max(0.6 - vec3(dot(x0, x0), dot(x1, x1), dot(x2, x2)), 0.0); 111 | vec2 m1 = max(0.6 - vec2(dot(x3, x3), dot(x4, x4)), 0.0); 112 | m0 = m0 * m0; 113 | m1 = m1 * m1; 114 | return 49.0 * (dot(m0*m0, vec3(dot(p0, x0), dot(p1, x1), dot(p2, x2))) 115 | + dot(m1*m1, vec2(dot(p3, x3), dot(p4, x4)))); 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/lib/noise/noisecommon.glsl: -------------------------------------------------------------------------------- 1 | /****************************************************** 2 | frex:shaders/lib/noise/noisecommon.glsl 3 | 4 | External MIT noise library - bundled for convenience. 5 | 6 | Modifications include: 7 | + remove the #version header 8 | + add this comment block 9 | + move some shared functions to this file 10 | + use #define for some small functions 11 | ******************************************************/ 12 | 13 | #define mod289(x) (x - floor(x * (1.0 / 289.0)) * 289.0) // Modulo 289 without a division (only multiplications) 14 | #define mod7(x) (x - floor(x * (1.0 / 7.0)) * 7.0) // Modulo 7 without a division 15 | #define taylorInvSqrt(r) (1.79284291400159 - 0.85373472095314 * r) 16 | 17 | // Permutation polynomial: (34x^2 + x) mod 289, ring size 289 = 17*17 18 | // Can't be defined because used recursively 19 | vec4 permute(vec4 x) { return mod289((34.0 * x + 1.0) * x); } 20 | vec3 permute(vec3 x) { return mod289((34.0 * x + 1.0) * x); } 21 | float permute(float x) { return mod289(((x*34.0)+1.0)*x); } 22 | -------------------------------------------------------------------------------- /src/main/resources/assets/frex/shaders/lib/sample.glsl: -------------------------------------------------------------------------------- 1 | /****************************************************** 2 | frex:shaders/lib/sample.glsl 3 | 4 | Common sampling functions. 5 | ******************************************************/ 6 | 7 | // Temporally stable box filter, as described by Jorge Jiminez, 2014 8 | // http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare 9 | vec4 frx_sample13(sampler2D tex, vec2 uv, vec2 distance, int lod) { 10 | vec4 a = textureLod(tex, uv + distance * vec2(-1.0, -1.0), lod); 11 | vec4 b = textureLod(tex, uv + distance * vec2(0.0, -1.0), lod); 12 | vec4 c = textureLod(tex, uv + distance * vec2(1.0, -1.0), lod); 13 | vec4 d = textureLod(tex, uv + distance * vec2(-0.5, -0.5), lod); 14 | vec4 e = textureLod(tex, uv + distance * vec2(0.5, -0.5), lod); 15 | vec4 f = textureLod(tex, uv + distance * vec2(-1.0, 0.0), lod); 16 | vec4 g = textureLod(tex, uv, lod); 17 | vec4 h = textureLod(tex, uv + distance * vec2(1.0, 0.0), lod); 18 | vec4 i = textureLod(tex, uv + distance * vec2(-0.5, 0.5), lod); 19 | vec4 j = textureLod(tex, uv + distance * vec2(0.5, 0.5), lod); 20 | vec4 k = textureLod(tex, uv + distance * vec2(-1.0, 1.0), lod); 21 | vec4 l = textureLod(tex, uv + distance * vec2(0.0, 1.0), lod); 22 | vec4 m = textureLod(tex, uv + distance * vec2(1.0, 1.0), lod); 23 | 24 | vec2 div = (1.0 / 4.0) * vec2(0.5, 0.125); 25 | 26 | vec4 o = (d + e + i + j) * div.x; 27 | o += (a + b + g + f) * div.y; 28 | o += (b + c + h + g) * div.y; 29 | o += (f + g + l + k) * div.y; 30 | o += (g + h + m + l) * div.y; 31 | 32 | return o; 33 | } 34 | 35 | // non-LOD version of above 36 | vec4 frx_sample13(sampler2D tex, vec2 uv, vec2 distance) { 37 | vec4 a = texture(tex, uv + distance * vec2(-1.0, -1.0)); 38 | vec4 b = texture(tex, uv + distance * vec2(0.0, -1.0)); 39 | vec4 c = texture(tex, uv + distance * vec2(1.0, -1.0)); 40 | vec4 d = texture(tex, uv + distance * vec2(-0.5, -0.5)); 41 | vec4 e = texture(tex, uv + distance * vec2(0.5, -0.5)); 42 | vec4 f = texture(tex, uv + distance * vec2(-1.0, 0.0)); 43 | vec4 g = texture(tex, uv); 44 | vec4 h = texture(tex, uv + distance * vec2(1.0, 0.0)); 45 | vec4 i = texture(tex, uv + distance * vec2(-0.5, 0.5)); 46 | vec4 j = texture(tex, uv + distance * vec2(0.5, 0.5)); 47 | vec4 k = texture(tex, uv + distance * vec2(-1.0, 1.0)); 48 | vec4 l = texture(tex, uv + distance * vec2(0.0, 1.0)); 49 | vec4 m = texture(tex, uv + distance * vec2(1.0, 1.0)); 50 | 51 | vec2 div = (1.0 / 4.0) * vec2(0.5, 0.125); 52 | 53 | vec4 o = (d + e + i + j) * div.x; 54 | o += (a + b + g + f) * div.y; 55 | o += (b + c + h + g) * div.y; 56 | o += (f + g + l + k) * div.y; 57 | o += (g + h + m + l) * div.y; 58 | 59 | return o; 60 | } 61 | 62 | // Used for bloom upsample, as described by Jorge Jiminez, 2014 63 | // http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare 64 | vec4 frx_sampleTent(sampler2D tex, vec2 uv, vec2 distance, int lod) { 65 | vec4 d = distance.xyxy * vec4(1.0, 1.0, -1.0, 0.0); 66 | 67 | vec4 sum = textureLod(tex, uv - d.xy, lod) 68 | + textureLod(tex, uv - d.wy, lod) * 2.0 69 | + textureLod(tex, uv - d.zy, lod) 70 | + textureLod(tex, uv + d.zw, lod) * 2.0 71 | + textureLod(tex, uv, lod) * 4.0 72 | + textureLod(tex, uv + d.xw, lod) * 2.0 73 | + textureLod(tex, uv + d.zy, lod) 74 | + textureLod(tex, uv + d.wy, lod) * 2.0 75 | + textureLod(tex, uv + d.xy, lod); 76 | 77 | return sum * (1.0 / 16.0); 78 | } 79 | 80 | // non-LOD version of above 81 | vec4 frx_sampleTent(sampler2D tex, vec2 uv, vec2 distance) { 82 | vec4 d = distance.xyxy * vec4(1.0, 1.0, -1.0, 0.0); 83 | 84 | vec4 sum = texture(tex, uv - d.xy) 85 | + texture(tex, uv - d.wy) * 2.0 86 | + texture(tex, uv - d.zy) 87 | + texture(tex, uv + d.zw) * 2.0 88 | + texture(tex, uv) * 4.0 89 | + texture(tex, uv + d.xw) * 2.0 90 | + texture(tex, uv + d.zy) 91 | + texture(tex, uv + d.wy) * 2.0 92 | + texture(tex, uv + d.xy); 93 | 94 | return sum * (1.0 / 16.0); 95 | } 96 | -------------------------------------------------------------------------------- /src/main/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "frex", 4 | "version": "${version}", 5 | "name": "FREX", 6 | "description": "Advanced rendering features for Fabric mods", 7 | "authors": [ 8 | "Grondag" 9 | ], 10 | "contact": { 11 | "homepage": "https://minecraft.curseforge.com/projects/frex", 12 | "issues": "https://github.com/grondag/frex/issues", 13 | "sources": "https://github.com/grondag/frex" 14 | }, 15 | 16 | "license": "Apache-2.0", 17 | "icon": "assets/frex/frex_icon.png", 18 | 19 | "environment": "client", 20 | "mixins": [ 21 | "frex.client.json" 22 | ], 23 | "entrypoints": { 24 | "client": [ "grondag.frex.Frex" ] 25 | }, 26 | "depends": { 27 | "fabricloader": ">=0.11.3", 28 | "minecraft": "1.17.x", 29 | "java": ">=16", 30 | "fabric": "*" 31 | }, 32 | "custom": { 33 | "modmenu": { 34 | "badges": [ "library" ] 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/resources/frex.client.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8", 4 | "package": "grondag.frex.mixin", 5 | "compatibilityLevel": "JAVA_16", 6 | "mixins": [ 7 | "MixinChunkBuilder", 8 | "MixinChunkRendererRegion", 9 | "MixinWorldRendererOldEvents" 10 | ], 11 | "injectors": { 12 | "defaultRequire": 1 13 | } 14 | } --------------------------------------------------------------------------------