diff --git a/build.gradle.kts b/build.gradle.kts index b50959e9..878f08a0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ plugins { } group = "gg.generations" -version = "2.4.2-SNAPSHOT" +version = "2.4.3-SNAPSHOT" java.toolchain.languageVersion.set(JavaLanguageVersion.of(17)) diff --git a/src/library/java/gg/generations/rarecandy/pokeutils/MaterialReference.java b/src/library/java/gg/generations/rarecandy/pokeutils/MaterialReference.java index 9d51cb93..b9c05ac5 100644 --- a/src/library/java/gg/generations/rarecandy/pokeutils/MaterialReference.java +++ b/src/library/java/gg/generations/rarecandy/pokeutils/MaterialReference.java @@ -29,6 +29,9 @@ public MaterialReference deserialize(JsonElement json, Type typeOfT, JsonDeseria var cull = jsonObject.has("cull") ? CullType.from(jsonObject.getAsJsonPrimitive("cull").getAsString()) : CullType.Forward; return new CullMaterialReference(texture, cull); } + case "unlit" -> { + return new UnlitMaterialReference(texture); + } default -> throw new JsonParseException("Material type %s invalid".formatted(type)); } diff --git a/src/library/java/gg/generations/rarecandy/pokeutils/UnlitMaterialReference.java b/src/library/java/gg/generations/rarecandy/pokeutils/UnlitMaterialReference.java new file mode 100644 index 00000000..70f3bda5 --- /dev/null +++ b/src/library/java/gg/generations/rarecandy/pokeutils/UnlitMaterialReference.java @@ -0,0 +1,12 @@ +package gg.generations.rarecandy.pokeutils; + +public class UnlitMaterialReference extends DiffuseMaterialReference { + @Override + public String shader() { + return "unlit"; + } + + public UnlitMaterialReference(String texture) { + super(texture); + } +} diff --git a/src/library/java/gg/generations/rarecandy/renderer/animation/Animation.java b/src/library/java/gg/generations/rarecandy/renderer/animation/Animation.java index 570de219..f0170f16 100644 --- a/src/library/java/gg/generations/rarecandy/renderer/animation/Animation.java +++ b/src/library/java/gg/generations/rarecandy/renderer/animation/Animation.java @@ -167,7 +167,6 @@ private AnimationNode[] fillAnimationNodesGfb(gg.generations.rarecandy.pokeutils trueIndex++; nodeIdMap.put(Objects.requireNonNull(boneAnim.name()).replace(".trmdl", ""), trueIndex); - System.out.println(trueIndex); var node = animationNodes[trueIndex] = new AnimationNode(); diff --git a/src/library/java/gg/generations/rarecandy/renderer/loading/ModelLoader.java b/src/library/java/gg/generations/rarecandy/renderer/loading/ModelLoader.java index a923ed1b..965e978e 100644 --- a/src/library/java/gg/generations/rarecandy/renderer/loading/ModelLoader.java +++ b/src/library/java/gg/generations/rarecandy/renderer/loading/ModelLoader.java @@ -72,6 +72,9 @@ public static void create2(MultiRenderObject objects, var name = entry.getKey(); var buffer = ByteBuffer.wrap(entry.getValue()); var gfbAnim = gg.generations.rarecandy.pokeutils.tranm.Animation.getRootAsAnimation(buffer); + + if(gfbAnim.anim() == null) continue; + animations.put(name, new Animation(name, gfbAnim, new Skeleton(skeleton))); } @@ -528,8 +531,12 @@ private Map readGfbAnimations(PixelAsset asset) { .collect(Collectors.toMap(this::cleanAnimName, Map.Entry::getValue)); } - private String cleanAnimName(Map.Entry entry) { + public String cleanAnimName(Map.Entry entry) { var str = entry.getKey(); + return cleanAnimName(str); + } + + public String cleanAnimName(String str) { var substringEnd = str.lastIndexOf(".") == -1 ? str.length() : str.lastIndexOf("."); var substringStart = str.lastIndexOf("/") == -1 ? 0 : str.lastIndexOf("/"); return str.substring(substringStart, substringEnd); diff --git a/src/library/resources/shaders/animated/animated.fs.glsl b/src/library/resources/shaders/animated/animated_pbr.fs.glsl similarity index 100% rename from src/library/resources/shaders/animated/animated.fs.glsl rename to src/library/resources/shaders/animated/animated_pbr.fs.glsl diff --git a/src/library/resources/shaders/animated/solid.fs.glsl b/src/library/resources/shaders/animated/solid.fs.glsl new file mode 100644 index 00000000..a00e88c5 --- /dev/null +++ b/src/library/resources/shaders/animated/solid.fs.glsl @@ -0,0 +1,18 @@ +#version 450 core +#define ambientLight 0.6f + +in vec2 texCoord0; + +out vec4 outColor; + +uniform sampler2D diffuse; + +uniform float lightLevel; + +void main() { + vec4 color = texture2D(diffuse, texCoord0); + + if (color.a < 0.01) discard; + + outColor = vec4(lightLevel, lightLevel, lightLevel, 1.0f) * color; +} diff --git a/src/library/resources/shaders/animated/transparent.fs.glsl b/src/library/resources/shaders/animated/transparent.fs.glsl index c59a84d8..3f020b56 100644 --- a/src/library/resources/shaders/animated/transparent.fs.glsl +++ b/src/library/resources/shaders/animated/transparent.fs.glsl @@ -2,46 +2,16 @@ #define ambientLight 0.6f in vec2 texCoord0; -in vec3 normal; -in vec3 toLightVector; -in vec3 toCameraVector; out vec4 outColor; uniform sampler2D diffuse; -uniform int intColor; -uniform float shineDamper; -uniform float reflectivity; -uniform float diffuseColorMix; -uniform float alpha; - -vec3 intToColor() { - return vec3((intColor >> 16 & 255) / 255.0, (intColor >> 8 & 255) / 255.0, (intColor & 255) / 255.0); -} +uniform float lightLevel; void main() { vec4 color = texture2D(diffuse, texCoord0); - vec3 lightColor = intToColor(); - vec3 pixelmonColor = mix(lightColor, vec3(1.0, 1.0, 1.0), diffuseColorMix); - vec3 unitNormal = normalize(normal); - vec3 unitLightVector = normalize(toLightVector); - vec3 lightDir = -unitLightVector; - vec3 unitToCameraVector = normalize(toCameraVector); - - // Diffuse Lighting - float rawDiffuse = dot(unitNormal, unitLightVector); - float diffuse = max(rawDiffuse, ambientLight); - vec3 coloredDiffuse = diffuse * pixelmonColor; - - // Specular Lighting - vec3 reflectedLightDir = reflect(lightDir, unitNormal); - float rawSpecularFactor = dot(reflectedLightDir, unitToCameraVector); - float specularFactor = max(rawSpecularFactor, 0.0f); - float dampedFactor = pow(specularFactor, shineDamper); - vec3 finalSpecular = dampedFactor * reflectivity * lightColor; - - outColor = vec4(coloredDiffuse, 1.0f) * color + vec4(finalSpecular, 1.0f); + outColor = vec4(lightLevel, lightLevel, lightLevel, 1.0f) * color; outColor.a = color.a; } diff --git a/src/library/resources/shaders/animated/transparent_pbr.fs.glsl b/src/library/resources/shaders/animated/transparent_pbr.fs.glsl new file mode 100644 index 00000000..c59a84d8 --- /dev/null +++ b/src/library/resources/shaders/animated/transparent_pbr.fs.glsl @@ -0,0 +1,47 @@ +#version 450 core +#define ambientLight 0.6f + +in vec2 texCoord0; +in vec3 normal; +in vec3 toLightVector; +in vec3 toCameraVector; + +out vec4 outColor; + +uniform sampler2D diffuse; + +uniform int intColor; +uniform float shineDamper; +uniform float reflectivity; +uniform float diffuseColorMix; +uniform float alpha; + +vec3 intToColor() { + return vec3((intColor >> 16 & 255) / 255.0, (intColor >> 8 & 255) / 255.0, (intColor & 255) / 255.0); +} + +void main() { + vec4 color = texture2D(diffuse, texCoord0); + + vec3 lightColor = intToColor(); + vec3 pixelmonColor = mix(lightColor, vec3(1.0, 1.0, 1.0), diffuseColorMix); + vec3 unitNormal = normalize(normal); + vec3 unitLightVector = normalize(toLightVector); + vec3 lightDir = -unitLightVector; + vec3 unitToCameraVector = normalize(toCameraVector); + + // Diffuse Lighting + float rawDiffuse = dot(unitNormal, unitLightVector); + float diffuse = max(rawDiffuse, ambientLight); + vec3 coloredDiffuse = diffuse * pixelmonColor; + + // Specular Lighting + vec3 reflectedLightDir = reflect(lightDir, unitNormal); + float rawSpecularFactor = dot(reflectedLightDir, unitToCameraVector); + float specularFactor = max(rawSpecularFactor, 0.0f); + float dampedFactor = pow(specularFactor, shineDamper); + vec3 finalSpecular = dampedFactor * reflectivity * lightColor; + + outColor = vec4(coloredDiffuse, 1.0f) * color + vec4(finalSpecular, 1.0f); + outColor.a = color.a; +} diff --git a/src/library/resources/shaders/animated/unlit.fs.glsl b/src/library/resources/shaders/animated/unlit.fs.glsl new file mode 100644 index 00000000..74c8f9b4 --- /dev/null +++ b/src/library/resources/shaders/animated/unlit.fs.glsl @@ -0,0 +1,13 @@ +#version 450 core +#define ambientLight 0.6f + +in vec2 texCoord0; + +out vec4 outColor; + +uniform sampler2D diffuse; + +void main() { + vec4 color = texture2D(diffuse, texCoord0); + outColor = color; +} diff --git a/src/main/java/gg/generations/rarecandy/tools/gui/GuiPipelines.java b/src/main/java/gg/generations/rarecandy/tools/gui/GuiPipelines.java index 72da0cc2..03394728 100644 --- a/src/main/java/gg/generations/rarecandy/tools/gui/GuiPipelines.java +++ b/src/main/java/gg/generations/rarecandy/tools/gui/GuiPipelines.java @@ -14,12 +14,7 @@ public class GuiPipelines { .supplyUniform("viewMatrix", ctx -> ctx.uniform().uploadMat4f(ctx.instance().viewMatrix())) .supplyUniform("modelMatrix", ctx -> ctx.uniform().uploadMat4f(ctx.instance().transformationMatrix())) .supplyUniform("projectionMatrix", (ctx) -> ctx.uniform().uploadMat4f(projectionMatrix)) - .supplyUniform("lightPosition", ctx -> ctx.uniform().uploadVec3f(new Vector3f(0, 2, 0))) - .supplyUniform("reflectivity", ctx -> ctx.uniform().uploadFloat(0.3f)) - .supplyUniform("shineDamper", ctx -> ctx.uniform().uploadFloat(0.3f)) - .supplyUniform("intColor", ctx -> ctx.uniform().uploadInt(0xFFFFFF)) - .supplyUniform("diffuseColorMix", ctx -> ctx.uniform().uploadFloat(0.7f)) - .supplyUniform("boneTransforms", ctx -> ctx.uniform().uploadMat4fs(ctx.instance() instanceof AnimatedObjectInstance instance ? instance.getTransforms() : AnimationController.NO_ANIMATION)) + .supplyUniform("boneTransforms", ctx -> ctx.uniform().uploadMat4fs(ctx.instance() instanceof AnimatedObjectInstance instance ? instance.getTransforms() != null ? instance.getTransforms() : AnimationController.NO_ANIMATION : AnimationController.NO_ANIMATION)) .supplyUniform("diffuse", ctx -> { ctx.object().getVariant(ctx.instance().variant()).getDiffuseTexture().bind(0); ctx.uniform().uploadInt(0); @@ -32,20 +27,35 @@ public class GuiPipelines { material.blendType().disable(); }); + private static final Pipeline.Builder PBR = new Pipeline.Builder(BASE) + .supplyUniform("lightPosition", ctx -> ctx.uniform().uploadVec3f(new Vector3f(0, 2, 0))) + .supplyUniform("reflectivity", ctx -> ctx.uniform().uploadFloat(0.3f)) + .supplyUniform("shineDamper", ctx -> ctx.uniform().uploadFloat(0.3f)) + .supplyUniform("intColor", ctx -> ctx.uniform().uploadInt(0xFFFFFF)) + .supplyUniform("diffuseColorMix", ctx -> ctx.uniform().uploadFloat(0.7f)); + public static final Pipeline STATIC = new Pipeline.Builder(BASE) .shader(builtin("static/static.vs.glsl"), builtin("static/static.fs.glsl")) .build(); - public static final Pipeline ANIMATED = new Pipeline.Builder(BASE) - .shader(builtin("animated/animated.vs.glsl"), builtin("animated/animated.fs.glsl")) + public static final Pipeline.Builder LIGHT = new Pipeline.Builder(BASE) + .supplyUniform("lightLevel", ctx -> ctx.uniform().uploadFloat(RareCandyCanvas.getLightLevel())); + + public static final Pipeline SOLID = new Pipeline.Builder(LIGHT) + .shader(builtin("animated/animated.vs.glsl"), builtin("animated/solid.fs.glsl")) .build(); - public static final Pipeline TRANSPARENT = new Pipeline.Builder(BASE) + public static final Pipeline TRANSPARENT = new Pipeline.Builder(LIGHT) .shader(builtin("animated/animated.vs.glsl"), builtin("animated/transparent.fs.glsl")) .build(); + public static final Pipeline UNLIT = new Pipeline.Builder(BASE) + .shader(builtin("animated/animated.vs.glsl"), builtin("animated/unlit.fs.glsl")) + .build(); + + public static final Pipeline POKEMON_EYES = new Pipeline.Builder(BASE) - .shader(builtin("animated/animated.vs.glsl"), builtin("animated/animated.fs.glsl")) + .shader(builtin("animated/animated.vs.glsl"), builtin("animated/animated_pbr.fs.glsl")) .supplyUniform("boneTransforms", ctx -> ctx.uniform().uploadMat4fs(ctx.instance() instanceof AnimatedObjectInstance instance ? instance.getTransforms() : AnimationController.NO_ANIMATION)) .build(); diff --git a/src/main/java/gg/generations/rarecandy/tools/gui/PixelAssetTree.java b/src/main/java/gg/generations/rarecandy/tools/gui/PixelAssetTree.java index 3c8b9c78..e1b3c99a 100644 --- a/src/main/java/gg/generations/rarecandy/tools/gui/PixelAssetTree.java +++ b/src/main/java/gg/generations/rarecandy/tools/gui/PixelAssetTree.java @@ -66,7 +66,7 @@ public void mouseReleased(MouseEvent e) { } else if (path.getParentPath() != null) if (path.getParentPath().getLastPathComponent().toString().equals("animations")) { - PixelAssetTree.this.gui.handler.getCanvas().setAnimation(path.getLastPathComponent().toString().replace(".tranm", "")); + PixelAssetTree.this.gui.handler.getCanvas().setAnimation(path.getLastPathComponent().toString().replace(".tranm", "").replace(".gfbanm", "")); } else if (path.getParentPath().getLastPathComponent().toString().equals("variants")) { PixelAssetTree.this.gui.handler.getCanvas().setVariant(path.getLastPathComponent().toString()); } diff --git a/src/main/java/gg/generations/rarecandy/tools/gui/PokeUtilsGui.java b/src/main/java/gg/generations/rarecandy/tools/gui/PokeUtilsGui.java index b0ad70a8..11b74e3f 100644 --- a/src/main/java/gg/generations/rarecandy/tools/gui/PokeUtilsGui.java +++ b/src/main/java/gg/generations/rarecandy/tools/gui/PokeUtilsGui.java @@ -2,12 +2,10 @@ import com.github.weisj.darklaf.LafManager; import gg.generations.rarecandy.renderer.model.material.PipelineRegistry; -import gg.generations.rarecandy.renderer.pipeline.Pipeline; import org.lwjgl.opengl.awt.AWTGLCanvas; import javax.swing.*; import java.awt.*; -import java.util.function.Function; public class PokeUtilsGui extends JPanel { @@ -49,7 +47,11 @@ public PokeUtilsGui() { } }); - PipelineRegistry.setFunction(s-> s.equals("transparent") ? GuiPipelines.TRANSPARENT : GuiPipelines.ANIMATED); + PipelineRegistry.setFunction(s-> switch(s) { + case "transparent"-> GuiPipelines.TRANSPARENT; + case "unlit" -> GuiPipelines.UNLIT; + default -> GuiPipelines.SOLID; + }); var renderLoop = new Runnable() { @Override diff --git a/src/main/java/gg/generations/rarecandy/tools/gui/RareCandyCanvas.java b/src/main/java/gg/generations/rarecandy/tools/gui/RareCandyCanvas.java index 481324d5..5e9319f1 100644 --- a/src/main/java/gg/generations/rarecandy/tools/gui/RareCandyCanvas.java +++ b/src/main/java/gg/generations/rarecandy/tools/gui/RareCandyCanvas.java @@ -30,6 +30,9 @@ public class RareCandyCanvas extends AWTGLCanvas { public static Matrix4f projectionMatrix; + + private static float lightLevel = 0.6f; + public final Matrix4f viewMatrix = new Matrix4f(); public final List instances = new ArrayList<>(); private final int scaleModifier = 0; @@ -40,7 +43,16 @@ public class RareCandyCanvas extends AWTGLCanvas { private MultiRenderObject loadedModel; private AnimatedObjectInstance loadedModelInstance; + private static float previousLightLevel; + public static void setLightLevel(float lightLevel) { + previousLightLevel = RareCandyCanvas.lightLevel; + RareCandyCanvas.lightLevel = lightLevel; + } + + static float getLightLevel() { + return lightLevel; + } public RareCandyCanvas() { super(defaultData()); @@ -88,7 +100,7 @@ public void initGL() { GuiPipelines.onInitialize(); this.renderer = new RareCandy(); - GL11C.glClearColor(60 / 255f, 63 / 255f, 65 / 255f, 1); + GL11C.glClearColor(lightLevel, lightLevel, lightLevel, 1); GL11C.glEnable(GL11C.GL_DEPTH_TEST); try (var is = Pipeline.class.getResourceAsStream("/models/grid.glb")) { @@ -108,6 +120,9 @@ public void paintGL() { if (loadedModelInstance != null) { loadedModelInstance.transformationMatrix().identity().scale(loadedModel.scale); } + + if(lightLevel != previousLightLevel) + renderer.render(false, (System.currentTimeMillis() - startTime) / 16000); swapBuffers(); @@ -154,7 +169,7 @@ private Pipeline getPokemonPipeline(String materialName) { if (materialName.equals("transparent")) { return GuiPipelines.TRANSPARENT; } else { - return GuiPipelines.ANIMATED; + return GuiPipelines.SOLID; } } diff --git a/src/main/java/gg/generations/rarecandy/tools/pixelmonTester/Pipelines.java b/src/main/java/gg/generations/rarecandy/tools/pixelmonTester/Pipelines.java index 98de819b..3be67a03 100644 --- a/src/main/java/gg/generations/rarecandy/tools/pixelmonTester/Pipelines.java +++ b/src/main/java/gg/generations/rarecandy/tools/pixelmonTester/Pipelines.java @@ -27,7 +27,7 @@ public Pipelines(Matrix4f projectionMatrix) { }); this.animated = new Pipeline.Builder(base) - .shader(builtin("animated/animated.vs.glsl"), builtin("animated/animated.fs.glsl")) + .shader(builtin("animated/animated.vs.glsl"), builtin("animated/animated_pbr.fs.glsl")) .supplyUniform("boneTransforms", ctx -> ctx.uniform().uploadMat4fs(((AnimatedObjectInstance) ctx.instance()).getTransforms())) .build(); }