Enums, example based on LumiLights, README

This commit is contained in:
JFronny 2020-11-26 20:11:38 +01:00
parent fd3e722391
commit 3043a8cde2
21 changed files with 751 additions and 63 deletions

8
.gitignore vendored
View File

@ -112,7 +112,11 @@ gradle-app.setting
**/build/
# Common working directory
run/
!/run
/run/*
!/run/resourcepacks
/run/resourcepacks/*
!/run/resourcepacks/lumi
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
!gradle-wrapper.jar

37
README.md Normal file
View File

@ -0,0 +1,37 @@
# Respackopts
Respackopts provides resource packs with config menus\
By default it integrates with frex (canvas shaders) and libcd (use this as reference)\
An example for the frex/canvas integration can be found [here](https://gitlab.com/JFronny/respackopts/-/tree/master/run/resourcepacks/lumi)
# Using Respackopts
## Users
You will just need to install Respackopts. A menu button will appear besides all supported resourcepacks.
## Resource pack authors
You will need to define a respackopts conf as seen [here](https://gitlab.com/JFronny/respackopts/-/blob/master/run/resourcepacks/lumi/assets/respackopts/conf.json)
This config may include:
- boolean values, expressed as Json bools
- number values, expressed as Json numbers
- string values (not accessible from default integrations), expressed as Json strings
- enums, expressed as Json arrays containing simple strings
The version property defines the format version. It will be incremented if changes to the layout of the config are made\
I will likely attempt to support older versions if I decide to make an incompatible change.\
To use the information from the config you will need to use and integration module/plugin.\
For the ones included by default:
### Canvas
Respackopts defines a config supplier, you can include it with `#include respackopts:config_supplier`\
Values can be accessed with `packId_entryId` for basic elements.\
Enum values can be accessed with `packId_entryId_enumKey`.\
Examples of using these are available [here](https://gitlab.com/JFronny/respackopts/-/tree/master/run/resourcepacks/lumi)
### LibCD
The LibCD integration defines a condition named `respackopts:cfg` that takes a string describing the location of a bool as `packId:entryId`
There have been issues with LibCD in development, so it might be smart not to use it.
## Mod developers
All data is available in static HashMaps in `io.gitlab.jfronny.respackopts.Respackopts`.\
To save information, call `Respackopts.save()`, `Respackopts.load()` to load.
`boolVals`, `numVals`, `strVals` and `enumKeys` use the resource pack ID as their first key,
then the property name. After that you get the value. Enums are expressed as numbers with enum key names in enumKeys.\
If you need code to be ran after changes are made to the state, add an action to `saveActions`.\
This is currently used for the Canvas/FREX integration, which uses it to generate shader code.

View File

@ -0,0 +1,377 @@
/*
* Lumi Lights - A shader pack for Canvas
* Copyright (c) 2020 spiralhalo and Contributors
*
* See `README.md` for license notice.
*/
#include canvas:shaders/internal/header.glsl
#include canvas:shaders/internal/varying.glsl
#include canvas:shaders/internal/diffuse.glsl
#include canvas:shaders/internal/flags.glsl
#include canvas:shaders/internal/fog.glsl
#include frex:shaders/api/world.glsl
#include frex:shaders/api/player.glsl
#include frex:shaders/api/material.glsl
#include frex:shaders/api/fragment.glsl
#include frex:shaders/api/sampler.glsl
#include frex:shaders/lib/math.glsl
#include frex:shaders/lib/color.glsl
#include canvas:shaders/internal/program.glsl
#include lumi:shaders/api/varying.glsl
#include canvas:apitarget
#include respackopts:config_supplier
/******************************************************
canvas:shaders/internal/material_main.frag
******************************************************/
#define M_PI 3.1415926535897932384626433832795
const float hdr_sunStr = 3;
const float hdr_moonStr = 0.4;
const float hdr_blockStr = 1.5;
const float hdr_handHeldStr = 0.9;
const float hdr_skylessStr = 0.2;
const float hdr_baseMinStr = 0.0;
const float hdr_baseMaxStr = 0.25;
const float hdr_emissiveStr = 1;
const float hdr_relAmbient = 0.09;
const float hdr_relSunHorizon = 0.5;
const float hdr_zWobbleDefault = 0.1;
const float hdr_finalMult = 1;
const float hdr_gamma = 2.2;
float hdr_gammaAdjust(float x){
return pow(x, hdr_gamma);
}
vec3 hdr_gammaAdjust(vec3 x){
return pow(x, vec3(hdr_gamma));
}
vec3 hdr_reinhardJodieTonemap(in vec3 v) {
float l = frx_luminance(v);
vec3 tv = v / (1.0f + v);
return mix(v / (1.0f + l), tv, tv);
}
vec3 hdr_vibrantTonemap(in vec3 v){
return v / (frx_luminance(v) + vec3(1.0));
}
void _cv_startFragment(inout frx_FragmentData data) {
int cv_programId = _cv_fragmentProgramId();
#include canvas:startfragment
}
float l2_clampScale(float e0, float e1, float v){
return clamp((v-e0)/(e1-e0), 0.0, 1.0);
}
float l2_max3(vec3 vec){
return max(vec.x, max(vec.y, vec.z));
}
// vec3 l2_what(vec3 rgb){
// return vec3(0.4123910 * rgb.r + 0.3575840 * rgb.g + 0.1804810 * rgb.b,
// 0.2126390 * rgb.r + 0.7151690 * rgb.g + 0.0721923 * rgb.b,
// 0.0193308 * rgb.r + 0.1191950 * rgb.g + 0.9505320 * rgb.b);
// }
vec3 l2_blockLight(float blockLight){
float bl = l2_clampScale(0.03125, 1.0, blockLight);
bl *= bl * hdr_blockStr;
vec3 block = hdr_gammaAdjust(vec3(bl, bl*0.875, bl*0.75));
#if HANDHELD_LIGHT_RADIUS != 0
vec4 held = frx_heldLight();
if (held.w > 0.0) {
float hl = l2_clampScale(held.w * HANDHELD_LIGHT_RADIUS, 0.0, gl_FogFragCoord);
hl *= hl * hdr_handHeldStr;
return block + hdr_gammaAdjust(held.rgb * hl);
}
#endif
return block;
}
vec3 l2_emissiveLight(float emissivity){
return vec3(hdr_gammaAdjust(emissivity) * hdr_emissiveStr);
}
float l2_skyLight(float skyLight, float intensity)
{
float sl = l2_clampScale(0.03125, 1.0, skyLight);
return hdr_gammaAdjust(sl) * intensity;
}
vec3 l2_ambientColor(float time){
vec3 ambientColor = hdr_gammaAdjust(vec3(0.6, 0.9, 1.0)) * hdr_sunStr * hdr_relAmbient;
vec3 sunriseAmbient = hdr_gammaAdjust(vec3(1.0, 0.8, 0.4)) * hdr_sunStr * hdr_relAmbient * hdr_relSunHorizon;
vec3 sunsetAmbient = hdr_gammaAdjust(vec3(1.0, 0.6, 0.2)) * hdr_sunStr * hdr_relAmbient * hdr_relSunHorizon;
vec3 nightAmbient = hdr_gammaAdjust(vec3(1.0, 1.0, 2.0)) * hdr_moonStr * hdr_relAmbient;
if(time > 0.94){
ambientColor = mix(nightAmbient, sunriseAmbient, l2_clampScale(0.94, 0.98, time));
} else if(time > 0.52){
ambientColor = mix(sunsetAmbient, nightAmbient, l2_clampScale(0.52, 0.56, time));
} else if(time > 0.48){
ambientColor = mix(ambientColor, sunsetAmbient, l2_clampScale(0.48, 0.5, time));
} else if(time < 0.02){
ambientColor = mix(ambientColor, sunriseAmbient, l2_clampScale(0.02, 0, time));
}
return ambientColor;
}
vec3 l2_skyAmbient(float skyLight, float time, float intensity){
float sa = l2_skyLight(skyLight, intensity) * 2.5;
return sa * l2_ambientColor(time);
}
float l2_userBrightness(){
float base = texture2D(frxs_lightmap, vec2(0.03125, 0.03125)).r;
// if(frx_isWorldTheNether()){
// return smoothstep(0.15/*0.207 no true darkness in nether*/, 0.577, base);
// } else if (frx_isWorldTheEnd(){
// return smoothstep(0.18/*0.271 no true darkness in the end*/, 0.685, base);
// } else {
// return smoothstep(0.053, 0.135, base);
// }
// Simplify nether/the end check
if(frx_worldHasSkylight()){
return smoothstep(0.053, 0.135, base);
} else {
return smoothstep(0.15, 0.63, base);
}
}
vec3 l2_skylessLightColor(){
return hdr_gammaAdjust(vec3(1.0));
}
vec3 l2_dimensionColor(){
if (frx_isWorldTheNether()) {
float min_col = min(min(gl_Fog.color.rgb.x, gl_Fog.color.rgb.y), gl_Fog.color.rgb.z);
float max_col = max(max(gl_Fog.color.rgb.x, gl_Fog.color.rgb.y), gl_Fog.color.rgb.z);
float sat = 0.0;
if (max_col != 0.0) {
sat = (max_col-min_col)/max_col;
}
return hdr_gammaAdjust(clamp((gl_Fog.color.rgb*(1/max_col))+pow(sat,2)/2, 0.0, 1.0));
}
else {
return hdr_gammaAdjust(vec3(0.8, 0.7, 1.0));
}
}
vec3 l2_skylessLight(vec3 normal){
if(frx_worldHasSkylight()){
return vec3(0);
} else {
float yalign = dot(normal,vec3(0, 0.977358, 0.211593)); // a bit towards z for more interesting effect
yalign = frx_isSkyDarkened()?abs(yalign):max(0,yalign);
return yalign * hdr_skylessStr * l2_skylessLightColor() * l2_userBrightness();
}
}
vec3 l2_baseAmbient(){
if(frx_worldHasSkylight()){
return vec3(0.1) * mix(hdr_baseMinStr, hdr_baseMaxStr, l2_userBrightness());
} else {
return l2_dimensionColor() * mix(hdr_baseMinStr, hdr_baseMaxStr, l2_userBrightness());
}
}
vec3 l2_sunColor(float time){
vec3 sunColor = hdr_gammaAdjust(vec3(1.0, 1.0, lumi_sunColorFactor)) * hdr_sunStr;
vec3 sunriseColor = hdr_gammaAdjust(vec3(1.0, 0.8, 0.4)) * hdr_sunStr * hdr_relSunHorizon;
vec3 sunsetColor = hdr_gammaAdjust(vec3(1.0, 0.6, 0.4)) * hdr_sunStr * hdr_relSunHorizon;
if(time > 0.94){
sunColor = sunriseColor;
} else if(time > 0.56){
sunColor = vec3(0); // pitch black at night
} else if(time > 0.54){
sunColor = mix(sunsetColor, vec3(0), l2_clampScale(0.54, 0.56, time));
} else if(time > 0.5){
sunColor = sunsetColor;
} else if(time > 0.48){
sunColor = mix(sunColor, sunsetColor, l2_clampScale(0.48, 0.5, time));
} else if(time < 0.02){
sunColor = mix(sunColor, sunriseColor, l2_clampScale(0.02, 0, time));
}
return sunColor;
}
vec3 l2_vanillaSunDir(in float time, float zWobble){
// wrap time to account for sunrise
time -= (time >= 0.75) ? 1.0 : 0.0;
// supposed offset of sunset/sunrise from 0/12000 daytime. might get better result with datamining?
float sunHorizonDur = 0.04;
// angle of sun in radians
float angleRad = l2_clampScale(-sunHorizonDur, 0.5+sunHorizonDur, time) * M_PI;
return normalize(vec3(cos(angleRad), sin(angleRad), zWobble));
}
vec3 l2_sunLight(float skyLight, in float time, float intensity, float rainGradient, vec3 diffuseNormal){
// wrap time to account for sunrise
float customTime = (time >= 0.75) ? (time - 1.0) : time;
float customIntensity = l2_clampScale(-0.08, 0.00, customTime);
if(customTime >= 0.25){
customIntensity = l2_clampScale(0.58, 0.5, customTime);
}
customIntensity *= mix(1.0, 0.0, rainGradient);
float sl = l2_skyLight(skyLight, max(customIntensity, intensity));
// direct sun light doesn't reach into dark spot as much as sky ambient
sl = frx_smootherstep(0.5,1.0,sl);
// zWobble is added to make more interesting looking diffuse light
// TODO: might be fun to use frx_worldDay() with sine wave for the zWobble to simulate annual sun position change
sl *= max(0.0, dot(l2_vanillaSunDir(time, hdr_zWobbleDefault), diffuseNormal));
return sl * l2_sunColor(time);
}
vec3 l2_moonLight(float skyLight, float time, float intensity, vec3 diffuseNormal){
float ml = l2_skyLight(skyLight, intensity) * frx_moonSize() * hdr_moonStr;
float aRad = l2_clampScale(0.56, 0.94, time) * M_PI;
ml *= max(0.0, dot(vec3(cos(aRad), sin(aRad), 0), diffuseNormal));
if(time < 0.58){
ml *= l2_clampScale(0.54, 0.58, time);
} else if(time > 0.92){
ml *= l2_clampScale(0.96, 0.92, time);
}
return vec3(ml);
}
float l2_specular(float time, vec3 aNormal, vec3 aPos, vec3 cameraPos, float power)
{
// calculate sun position (0 zWobble to make it look accurate with vanilla sun visuals)
vec3 sunDir = l2_vanillaSunDir(time, 0);
// obtain the direction of the camera
vec3 viewDir = normalize(cameraPos - aPos);
// calculate the specular light
return pow(max(0.0, dot(reflect(-sunDir, aNormal), viewDir)),power);
}
float l2_ao(frx_FragmentData fragData) {
#if AO_SHADING_MODE != AO_MODE_NONE
float ao = fragData.ao ? _cvv_ao : 1.0;
return hdr_gammaAdjust(min(1.0, ao + fragData.emissivity));
#else
return 1.0;
#endif
}
void main() {
frx_FragmentData fragData = frx_FragmentData (
texture2D(frxs_spriteAltas, _cvv_texcoord, _cv_getFlag(_CV_FLAG_UNMIPPED) * -4.0),
_cvv_color,
frx_matEmissive() ? 1.0 : 0.0,
!frx_matDisableDiffuse(),
!frx_matDisableAo(),
_cvv_normal,
_cvv_lightcoord
);
_cv_startFragment(fragData);
vec4 a = fragData.spriteColor * fragData.vertexColor;
float bloom = fragData.emissivity; // separate bloom from emissivity
if(frx_isGui()){
#if DIFFUSE_SHADING_MODE != DIFFUSE_MODE_NONE
if(fragData.diffuse){
float diffuse = mix(_cvv_diffuse, 1, fragData.emissivity);
vec3 shading = mix(vec3(0.5, 0.4, 0.8) * diffuse * diffuse, vec3(1.0), diffuse);
a.rgb *= shading;
}
#endif
} else {
a.rgb = hdr_gammaAdjust(a.rgb);
// If diffuse is disabled (e.g. grass) then the normal points up by default
float ao = l2_ao(fragData);
vec3 diffuseNormal = fragData.diffuse?fragData.vertexNormal * frx_normalModelMatrix():vec3(0,1,0);
vec3 block = l2_blockLight(fragData.light.x);
vec3 sun = l2_sunLight(fragData.light.y, frx_worldTime(), frx_ambientIntensity(), frx_rainGradient(), diffuseNormal);
vec3 moon = l2_moonLight(fragData.light.y, frx_worldTime(), frx_ambientIntensity(), diffuseNormal);
vec3 skyAmbient = l2_skyAmbient(fragData.light.y, frx_worldTime(), frx_ambientIntensity());
vec3 emissive = l2_emissiveLight(fragData.emissivity);
vec3 nether = l2_skylessLight(diffuseNormal);
vec3 light = block + moon + l2_baseAmbient() + skyAmbient + sun + nether;
light *= ao; // AO is supposed to be applied to ambient only, but things look better with AO on everything except for emissive light
light += emissive;
vec3 specular = vec3(0.0);
if (wwv_specPower > 0.01) {
vec3 specularNormal = fragData.vertexNormal * frx_normalModelMatrix();
float skyAccess = smoothstep(0.89, 1.0, fragData.light.y);
vec3 fragPos = frx_var0.xyz;
vec3 cameraPos = frx_var1.xyz;
vec3 sunDir = l2_vanillaSunDir(frx_worldTime(), 0);
vec3 sun = l2_sunLight(fragData.light.y, frx_worldTime(), frx_ambientIntensity(), frx_rainGradient(), sunDir);
float specularAmount = l2_specular(frx_worldTime(), specularNormal, fragPos, cameraPos, wwv_specPower);
specular = sun * specularAmount * skyAccess;
}
a.rgb *= light;
a.rgb += specular;
float specularLuminance = frx_luminance(specular);
a.a += specularLuminance;
bloom += specularLuminance;
a.rgb *= hdr_finalMult;
#if lumi_tonemap == lumi_tonemap_vibrant
a.rgb = pow(hdr_vibrantTonemap(a.rgb), vec3(1.0 / hdr_gamma));
#elif lumi_tonemap == reinhardJodie
a.rgb = pow(hdr_reinhardJodieTonemap(a.rgb), vec3(1.0 / hdr_gamma));
#else
a.rgb = pow(frx_toneMap(a.rgb), vec3(1.0 / hdr_gamma));
#endif
}
// PERF: varyings better here?
if (_cv_getFlag(_CV_FLAG_CUTOUT) == 1.0) {
float t = _cv_getFlag(_CV_FLAG_TRANSLUCENT_CUTOUT) == 1.0 ? _CV_TRANSLUCENT_CUTOUT_THRESHOLD : 0.5;
if (a.a < t) {
discard;
}
}
// PERF: varyings better here?
if (_cv_getFlag(_CV_FLAG_FLASH_OVERLAY) == 1.0) {
a = a * 0.25 + 0.75;
} else if (_cv_getFlag(_CV_FLAG_HURT_OVERLAY) == 1.0) {
a = vec4(0.25 + a.r * 0.75, a.g * 0.75, a.b * 0.75, a.a);
}
// TODO: need a separate fog pass?
gl_FragData[TARGET_BASECOLOR] = _cv_fog(a);
gl_FragDepth = gl_FragCoord.z;
#if TARGET_EMISSIVE > 0
gl_FragData[TARGET_EMISSIVE] = vec4(bloom * a.a, 1.0, 0.0, 1.0);
#endif
}

View File

@ -0,0 +1,89 @@
#include canvas:shaders/internal/header.glsl
#include frex:shaders/api/context.glsl
#include canvas:shaders/internal/varying.glsl
#include canvas:shaders/internal/vertex.glsl
#include canvas:shaders/internal/flags.glsl
#include frex:shaders/api/vertex.glsl
#include frex:shaders/api/sampler.glsl
#include canvas:shaders/internal/diffuse.glsl
#include canvas:shaders/internal/program.glsl
#include lumi:shaders/api/varying.glsl
#include canvas:apitarget
/******************************************************
canvas:shaders/internal/material_main.vert
******************************************************/
void _cv_startVertex(inout frx_VertexData data, in int cv_programId) {
#include canvas:startvertex
}
void _cv_endVertex(inout frx_VertexData data, in int cv_programId) {
#include canvas:endvertex
}
void main() {
frx_VertexData data = frx_VertexData(
gl_Vertex,
in_uv,
in_color,
(in_normal_flags.xyz - 127.0) / 127.0,
in_lightmap.rg * 0.00390625 + 0.03125
);
// Adding +0.5 prevents striping or other strangeness in flag-dependent rendering
// due to FP error on some cards/drivers. Also made varying attribute invariant (rolls eyes at OpenGL)
_cvv_flags = uint(in_normal_flags.w + 0.5);
wwv_specPower = 0.0;
_cv_setupProgram();
int cv_programId = _cv_vertexProgramId();
_cv_startVertex(data, cv_programId);
if (_cvu_atlas[_CV_SPRITE_INFO_TEXTURE_SIZE] != 0.0) {
float spriteIndex = in_material.x;
// for sprite atlas textures, convert from normalized (0-1) to interpolated coordinates
vec4 spriteBounds = texture2DLod(frxs_spriteInfo, vec2(0, spriteIndex / _cvu_atlas[_CV_SPRITE_INFO_TEXTURE_SIZE]), 0);
float atlasHeight = _cvu_atlas[_CV_ATLAS_HEIGHT];
float atlasWidth = _cvu_atlas[_CV_ATLAS_WIDTH];
// snap sprite bounds to integer coordinates to correct for floating point error
spriteBounds *= vec4(atlasWidth, atlasHeight, atlasWidth, atlasHeight);
spriteBounds += vec4(0.5, 0.5, 0.5, 0.5);
spriteBounds -= fract(spriteBounds);
spriteBounds /= vec4(atlasWidth, atlasHeight, atlasWidth, atlasHeight);
data.spriteUV = spriteBounds.xy + data.spriteUV * spriteBounds.zw;
}
data.spriteUV = _cv_textureCoord(data.spriteUV, 0);
vec4 viewCoord = gl_ModelViewMatrix * data.vertex;
gl_ClipVertex = viewCoord;
gl_FogFragCoord = length(viewCoord.xyz);
//data.normal *= gl_NormalMatrix;
data.vertex = gl_ModelViewProjectionMatrix * data.vertex;
gl_Position = data.vertex;
_cv_endVertex(data, cv_programId);
_cvv_texcoord = data.spriteUV;
_cvv_color = data.color;
_cvv_normal = data.normal;
#if DIFFUSE_SHADING_MODE != DIFFUSE_MODE_NONE
_cvv_diffuse = _cv_diffuse(_cvv_normal);
#endif
#if AO_SHADING_MODE != AO_MODE_NONE
_cvv_ao = in_lightmap.b / 255.0;
#endif
_cvv_lightcoord = data.light;
}

View File

@ -0,0 +1,30 @@
/*
* Derived from Canvas source code (https://github.com/grondag/canvas/)
*
* Changes are made to add bloom to sky fragments.
*/
#include canvas:shaders/internal/process/header.glsl
#include frex:shaders/lib/color.glsl
#include frex:shaders/lib/sample.glsl
#include frex:shaders/lib/math.glsl
/******************************************************
canvas:shaders/internal/process/emissive_color.frag
******************************************************/
uniform sampler2D _cvu_base;
uniform sampler2D _cvu_emissive;
uniform ivec2 _cvu_size;
varying vec2 _cvv_texcoord;
void main() {
vec4 e = texture2D(_cvu_emissive, _cvv_texcoord);
bool sky = e.g == 0.0;
float bloom = sky ? 0.25 : e.r;
vec4 c = frx_fromGamma(texture2D(_cvu_base, _cvv_texcoord));
gl_FragData[0] = vec4(c.rgb * bloom, e.r);
}

View File

@ -0,0 +1,7 @@
{
"blendMode": "translucent",
"disableAo": true,
"disableDiffuse": true,
"vertexSource": "lumi:shaders/material/water.vert",
"fragmentSource": "lumi:shaders/material/water.frag"
}

View File

@ -0,0 +1,2 @@
// If wwv_specPower is used, frx_var0 must be reserved for fragPos and frx_var1 must be reserved for cameraPos
varying float wwv_specPower;

View File

@ -0,0 +1,7 @@
#include frex:shaders/lib/noise/noise3d.glsl
float l2_noise(vec3 aPos, float renderTime, float scale, float amplitude)
{
float invScale = 1/scale;
return (snoise(vec3(aPos.x*invScale, aPos.z*invScale, renderTime)) * 0.5+0.5) * amplitude;
}

View File

@ -0,0 +1,38 @@
#include lumi:shaders/api/varying.glsl
#include lumi:shaders/lib/noise.glsl
#include frex:shaders/api/fragment.glsl
#include frex:shaders/api/world.glsl
#include respackopts:config_supplier
void frx_startFragment(inout frx_FragmentData fragData) {
fragData.spriteColor.rgb *= fragData.spriteColor.rgb * lumi_waterColorFactor;
if(fragData.vertexNormal.y > 0.01) {
// hack
fragData.light.y += 0.077 * smoothstep(1.0, 0.99, fragData.vertexNormal.y);
fragData.light.y = min(0.96875, fragData.light.y);
vec3 worldPos = frx_modelOriginWorldPos() + frx_var0.xyz;
// water wavyness parameter
float timeScale = 2; // speed
float noiseScale = 2; // wavelength
float noiseAmp = 0.03125 * noiseScale;// * timeScale; // amplitude
// inferred parameter
float renderTime = frx_renderSeconds() * 0.5 * timeScale;
float microSample = 0.01 * noiseScale;
// base noise
float noise = l2_noise(worldPos, renderTime, noiseScale, noiseAmp);
// normal recalculation
vec3 noiseOrigin = vec3(0, noise, 0);
vec3 noiseTangent = vec3(microSample, l2_noise(worldPos + vec3(microSample,0,0), renderTime, noiseScale, noiseAmp), 0) - noiseOrigin;
vec3 noiseBitangent = vec3(0, l2_noise(worldPos + vec3(0,0,microSample), renderTime, noiseScale, noiseAmp), microSample) - noiseOrigin;
// noisy normal
vec3 noisyNormal = normalize(cross(noiseBitangent, noiseTangent));
fragData.vertexNormal = noisyNormal;
}
}

View File

@ -0,0 +1,8 @@
#include frex:shaders/api/vertex.glsl
#include lumi:shaders/api/varying.glsl
void frx_startVertex(inout frx_VertexData data) {
frx_var0.xyz = data.vertex.xyz;
frx_var1.xyz = (gl_ModelViewMatrixInverse * vec4(0.0, 0.0, 0.0, 1.0)).xyz;
wwv_specPower = 100.0;
}

View File

@ -0,0 +1,3 @@
{
"defaultMaterial": "lumi:tasty_liquid"
}

View File

@ -0,0 +1,3 @@
{
"defaultMaterial": "lumi:tasty_liquid"
}

View File

@ -0,0 +1,13 @@
{
"id": "lumi",
"version": 1,
"conf": {
"tonemap": [
"reinhardJodie",
"vibrant",
"fxr"
],
"sunColorFactor": 0.8,
"waterColorFactor": 1
}
}

View File

@ -0,0 +1,6 @@
{
"pack": {
"pack_format": 6,
"description": "§3Aesthetic shader pack\n§8by awoo [v1.0-wip]"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -6,6 +6,8 @@ import com.google.gson.JsonPrimitive;
import me.shedaniel.clothconfig2.api.ConfigBuilder;
import me.shedaniel.clothconfig2.api.ConfigCategory;
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
import me.shedaniel.clothconfig2.gui.entries.DropdownBoxEntry;
import me.shedaniel.clothconfig2.impl.builders.DropdownMenuBuilder;
import net.minecraft.client.gui.screen.FatalErrorScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.*;
@ -13,6 +15,7 @@ import net.minecraft.util.Language;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeSet;
public class GuiFactory {
public void buildCategory(JsonObject source, String screenId, ConfigCategory config, ConfigEntryBuilder entryBuilder) {
@ -22,6 +25,8 @@ public class GuiFactory {
Respackopts.numVals.put(screenId, new HashMap<>());
if (!Respackopts.strVals.containsKey(screenId))
Respackopts.strVals.put(screenId, new HashMap<>());
if (!Respackopts.enumKeys.containsKey(screenId))
Respackopts.enumKeys.put(screenId, new HashMap<>());
String b = "respackopts.field." + screenId;
for (Map.Entry<String, JsonElement> entry : source.entrySet()) {
String n = entry.getKey();
@ -41,23 +46,19 @@ public class GuiFactory {
Respackopts.boolVals.get(screenId).put(n, defaultValue);
config.addEntry(entryBuilder.startBooleanToggle(getText(n, b), currentValue)
.setDefaultValue(defaultValue)
.setSaveConsumer(v -> {
Respackopts.boolVals.get(screenId).put(n, v);
})
.setSaveConsumer(v -> Respackopts.boolVals.get(screenId).put(n, v))
.build());
}
else if (p.isNumber()) {
double defaultValue = p.getAsDouble();
double currentValue = defaultValue;
Double currentValue = defaultValue;
if (Respackopts.numVals.get(screenId).containsKey(n))
currentValue = Respackopts.numVals.get(screenId).get(n);
else
Respackopts.numVals.get(screenId).put(n, defaultValue);
config.addEntry(entryBuilder.startDoubleField(getText(n, b), currentValue)
.setDefaultValue(defaultValue)
.setSaveConsumer(v -> {
Respackopts.numVals.get(screenId).put(n, v);
})
.setSaveConsumer(v -> Respackopts.numVals.get(screenId).put(n, v))
.build());
}
else if (p.isString()) {
@ -69,12 +70,34 @@ public class GuiFactory {
Respackopts.strVals.get(screenId).put(n, defaultValue);
config.addEntry(entryBuilder.startStrField(getText(n, b), currentValue)
.setDefaultValue(defaultValue)
.setSaveConsumer(v -> {
Respackopts.strVals.get(screenId).put(n, v);
})
.setSaveConsumer(v -> Respackopts.strVals.get(screenId).put(n, v))
.build());
}
}
else if (e.isJsonArray()) {
TreeSet<String> ev = Respackopts.enumKeys.get(screenId).get(n);
Double c = Respackopts.numVals.get(screenId).get(n);
String sel = ev.first();
int i = 0;
for (String s1 : ev) {
if (c.intValue() == i) {
sel = s1;
}
i++;
}
config.addEntry(entryBuilder.startDropdownMenu(getText(n, b), (DropdownBoxEntry.SelectionTopCellElement) DropdownMenuBuilder.TopCellElementBuilder.of(sel, (s) -> s, (s) -> getText(s, n + "." + b)), new DropdownBoxEntry.DefaultSelectionCellCreator())
.setSuggestionMode(false)
.setDefaultValue(ev.first())
.setSelections(() -> ev.iterator())
.setSaveConsumer(v -> {
int j = 0;
for (String s1 : ev) {
if (s1.equals(v))
Respackopts.numVals.get(screenId).put(n, (double) j);
j++;
}
}).build());
}
else {
System.err.println("[respackopts] Unsupported non-primitive datatype");
}
@ -88,11 +111,7 @@ public class GuiFactory {
.setParentScreen(parent)
.setTitle(getText(resourcepackid, "respackopts.title"));
ConfigEntryBuilder entryBuilder = builder.entryBuilder();
builder.setSavingRunnable(() -> {
System.out.println("Save");
Respackopts.updateShaders();
Respackopts.save();
});
builder.setSavingRunnable(Respackopts::save);
ConfigCategory config = builder.getOrCreateCategory(getText(resourcepackid, "respackopts.category"));
buildCategory(source, resourcepackid, config, entryBuilder);
return builder.build();

View File

@ -18,10 +18,7 @@ public class MMI implements ModMenuApi {
.setParentScreen(parent)
.setTitle(new TranslatableText("respackopts.mainconfig"));
ConfigEntryBuilder entryBuilder = builder.entryBuilder();
builder.setSavingRunnable(() -> {
Respackopts.updateShaders();
Respackopts.save();
});
builder.setSavingRunnable(Respackopts::save);
Respackopts.resPackMetas.forEach((s, v) -> {
ConfigCategory config = builder.getOrCreateCategory(new TranslatableText("respackopts.category." + v.id));
Respackopts.factory.buildCategory(v.conf, v.id, config, entryBuilder);

View File

@ -8,11 +8,13 @@ import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.loader.api.FabricLoader;
import javax.swing.*;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.HashSet;
import java.util.TreeSet;
import java.util.function.Consumer;
@Environment(EnvType.CLIENT)
@ -20,19 +22,20 @@ public class Respackopts implements ClientModInitializer {
public static HashMap<String, HashMap<String, Boolean>> boolVals;
public static HashMap<String, HashMap<String, Double>> numVals;
public static HashMap<String, HashMap<String, String>> strVals;
public static HashMap<String, HashMap<String, TreeSet<String>>> enumKeys;
public static Gson g = new Gson();
public static GuiFactory factory = new GuiFactory();
public static final Integer metaVersion = 1;
public static HashMap<String, Respackmeta> resPackMetas = new HashMap<>();
public static final String ID = "respackopts";
static final Path p = FabricLoader.getInstance().getConfigDir().resolve("respackopts");
public static final HashSet<Consumer<String>> shaderConsumers = new HashSet<>();
public static final HashSet<Runnable> saveActions = new HashSet<>();
@Override
public void onInitializeClient() {
load();
Respackopts.updateShaders();
Respackopts.save();
if (FabricLoader.getInstance().isDevelopmentEnvironment())
shaderConsumers.add(System.out::println);
saveActions.add(() -> System.out.println("Save"));
}
public static void save() {
@ -61,6 +64,9 @@ public class Respackopts implements ClientModInitializer {
e.printStackTrace();
}
}
for (Runnable action : saveActions) {
action.run();
}
}
public static void load() {
@ -90,37 +96,14 @@ public class Respackopts implements ClientModInitializer {
deNull();
}
public static void deNull() {
private static void deNull() {
if (boolVals == null)
boolVals = new HashMap<>();
if (numVals == null)
numVals = new HashMap<>();
if (strVals == null)
strVals = new HashMap<>();
}
public static void updateShaders() {
StringBuilder sb = new StringBuilder();
numVals.forEach((s, v) -> v.forEach((s1, v1) -> {
sb.append("\n");
sb.append("#define ");
sb.append(s);
sb.append("_");
sb.append(s1);
sb.append(" ");
sb.append(v1);
}));
boolVals.forEach((s, v) -> v.forEach((s1, v1) -> {
if (v1) {
sb.append("\n");
sb.append("#define ");
sb.append(s);
sb.append("_");
sb.append(s1);
}
}));
for (Consumer<String> consumer : shaderConsumers) {
consumer.accept(sb.toString());
}
if (enumKeys == null)
enumKeys = new HashMap<>();
}
}

View File

@ -6,14 +6,52 @@ import io.gitlab.jfronny.respackopts.Respackopts;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.util.Identifier;
import java.util.concurrent.atomic.AtomicInteger;
public class FrexCompat implements FrexInitializer {
String currentShaderCode = "";
@Override
public void onInitalizeFrex() {
System.out.println("[respackopts] enabling canvas support");
ShaderConfig.registerShaderConfigSupplier(new Identifier(Respackopts.ID, "config_supplier"), () -> currentShaderCode);
Respackopts.shaderConsumers.add((s) -> {
currentShaderCode = s;
ShaderConfig.registerShaderConfigSupplier(new Identifier(Respackopts.ID, "config_supplier"), () -> {
StringBuilder sb = new StringBuilder();
Respackopts.numVals.forEach((s, v) -> v.forEach((s1, v1) -> {
sb.append("\n");
sb.append("#define ");
sb.append(s);
sb.append("_");
sb.append(s1);
sb.append(" ");
String tmp = v1.toString();
if (tmp.endsWith(".0"))
tmp = tmp.substring(0, tmp.length() - 2);
sb.append(tmp);
}));
Respackopts.boolVals.forEach((s, v) -> v.forEach((s1, v1) -> {
if (v1) {
sb.append("\n");
sb.append("#define ");
sb.append(s);
sb.append("_");
sb.append(s1);
}
}));
Respackopts.enumKeys.forEach((s, v) -> v.forEach((s1, v1) -> {
AtomicInteger i = new AtomicInteger(0);
v1.forEach((s2) -> {
sb.append("\n");
sb.append("#define ");
sb.append(s);
sb.append("_");
sb.append(s1);
sb.append("_");
sb.append(s2);
sb.append(" ");
sb.append(i.getAndIncrement());
});
}));
return sb.toString();
});
System.out.println("[respackopts] enabled frex/canvas support");
Respackopts.saveActions.add(() -> {
try {
ShaderConfig.invalidateShaderConfig();
}

View File

@ -1,9 +1,6 @@
package io.gitlab.jfronny.respackopts.mixin;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.*;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.data.Respackmeta;
import net.minecraft.resource.ResourcePackManager;
@ -20,7 +17,9 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.TreeSet;
@Mixin(ResourcePackManager.class)
public class ResourcePackManagerMixin {
@ -38,9 +37,11 @@ public class ResourcePackManagerMixin {
Respackopts.numVals.put(conf.id, new HashMap<>());
if (!Respackopts.strVals.containsKey(conf.id))
Respackopts.strVals.put(conf.id, new HashMap<>());
if (!Respackopts.enumKeys.containsKey(conf.id))
Respackopts.enumKeys.put(conf.id, new HashMap<>());
for (Map.Entry<String, JsonElement> entry : conf.conf.entrySet()) {
String n = entry.getKey();
if (n.contains(":") || n.contains(".")) {
if (n.contains(":") || n.contains(".") || n.contains("_")) {
System.err.println(n + " contains invalid characters");
continue;
}
@ -60,6 +61,32 @@ public class ResourcePackManagerMixin {
Respackopts.strVals.get(conf.id).put(n, p.getAsString());
}
}
else if (e.isJsonArray()) {
JsonArray a = e.getAsJsonArray();
for (JsonElement element : a) {
if (!element.isJsonPrimitive()) {
System.err.println("[respackopts] Unsupported non-primitive datatype");
continue;
}
if (!Respackopts.enumKeys.get(conf.id).containsKey(n)) {
Respackopts.enumKeys.get(conf.id).put(n, new TreeSet<>());
}
JsonPrimitive p = element.getAsJsonPrimitive();
if (!p.isString()) {
System.err.println("[respackopts] Unsupported non-string enum key");
continue;
}
String b = p.getAsString();
if (b.contains(":") || b.contains(".") || b.contains("_")) {
System.err.println(b + " contains invalid characters");
continue;
}
Respackopts.enumKeys.get(conf.id).get(n).add(b);
}
if (!Respackopts.numVals.get(conf.id).containsKey(n)) {
Respackopts.numVals.get(conf.id).put(n, 0d);
}
}
else {
System.err.println("[respackopts] Unsupported non-primitive datatype");
}
@ -75,9 +102,8 @@ public class ResourcePackManagerMixin {
}
}
});
Respackopts.load();
Respackopts.updateShaders();
Respackopts.save();
Respackopts.load();
}
private boolean hasMetadata(ResourcePackProfile v, String fname) {

View File

@ -2,5 +2,6 @@
"respackopts.loadFailed": "Failed to load resourcepacks",
"respackopts.loadError": "There is an issue with the resourcepack configs. Please take a look at the game log",
"respackopts.configure": "Configure",
"respackopts.mainconfig": "ResPack Opts"
"respackopts.mainconfig": "ResPack Opts",
"respackopts.invalid": "Invalider Wert"
}