Compare commits

...
1 Commits
Author SHA1 Message Date
koka 6f871446bb Balance PBR at 50 percent and soften solar water highlights in beta.148
Build Sanctuary / build (push) Waiting to run
2026-09-18 20:12:08 +02:00
11 changed files with 114 additions and 17 deletions
+8 -2
View File
@@ -1,5 +1,11 @@
# Sanctuary
## beta.148 — PBR 50 % et soleil diffus (pack local)
PBR à 50 %, reflet solaire plus doux avec fusion par texel préservant
la texture de l’eau. SSR à 20 %, portée commune jusqu’à 256 blocs.
[Contrat et vérifications](docs/pbr-soft-sun-beta148.md).
## beta.147 — PBR proche, lune et portée 256 (pack local)
Correction du scintillement à très courte distance, reflet lunaire adouci
@@ -2342,7 +2348,7 @@ Depuis beta.090, la cible est **Minecraft 26.3 finale**, publiée le 15 septembr
| Fabric API | 0.160.5+26.3 |
| Fabric Loom | 1.17.20 |
| Gradle Wrapper | 9.5.1, distribution vérifiée par SHA-256 |
| Sanctuary / pack | beta.147 |
| Sanctuary / pack | beta.148 |
Java 25 et Python 3.11 ou plus récent sont nécessaires. Le script pack utilise
uniquement la bibliothèque standard et repère aussi une installation Python
@@ -2371,7 +2377,7 @@ décrits dans [Validation](docs/testing.md).
Résultats :
- `mods/sanctuary/build/libs/sanctuary-beta.147.jar` : mod à installer avec
- `mods/sanctuary/build/libs/sanctuary-beta.148.jar` : mod à installer avec
Fabric API sur la version Minecraft indiquée.
- `build/packwiz/` : pack de développement complet, avec le mod construit et
l'index vérifié. Voir [Installation packwiz](packwiz/README.md).
+68
View File
@@ -0,0 +1,68 @@
# RENDER-148 — PBR 50 % et reflet solaire diffus
Branche `codex/pbr-soft-sun-beta148`, socle beta.147 `96a36d9`.
Minecraft 26.3, Java 25, dépendances et sauvegardes inchangés.
## Résultat
- PBR à 50 % par défaut, SSR toujours à 20 % et portée commune jusqu’à 256.
- Les configurations anciennes contenant exactement PBR 80 % passent à 50 %.
Un marqueur de migration conserve ensuite tout choix explicite, y compris
un nouveau choix 80 %. Les autres anciennes intensités restent conservées.
- Le reflet solaire de l’eau avait un renforcement ×20 et une compression
exponentielle qui effaçait les détails dans une large zone blanche.
Le renforcement passe à ×6 et le lobe est plus diffus (rugosité minimale
de 0,42 au lieu de 0,34 pour le lobe céleste de l’eau).
- Pour le soleil sur l’eau, fusion par texel entre éclaircissement vers le
blanc et lumière douce fondée sur la couleur native. La pondération emploie
une compression rationnelle, sans atteindre brutalement un plateau blanc.
La texture et ses animations restent natives ; aucun bruit ajouté.
- La lune conserve son intensité atténuée, sans renforcement solaire.
Les lampes et matières solides conservent leur fusion spéculaire précédente.
Le bloom reste réglable et suit la lumière réellement ajoutée.
## Vérifications
Scènes plates jetables, Apple M1, Vulkan et OpenGL. Le test solaire contrôle
une lumière largement visible et limite les pixels quasi blancs à moins de
0,5 % de l’image, au lieu d’imposer une grande tache blanche.
Premier contrôle Vulkan à PBR 50 % / SSR 20 % : 149 908 pixels éclaircis,
zéro pixel quasi blanc sur 854 × 480. Captures vues du dessus et à soleil bas
inspectées : la texture reste visible dans la traînée lumineuse.
Preuves : `build/evidence/beta148-preview/`.
Rendu de la traînée solaire approuvé par le créateur après inspection de la capture.
- Suites SSR complètes Vulkan et OpenGL réussies : F5, intersections, portées,
eau/verre/métal, OFF/zéro, lune, bloom, rechargement et redimensionnement.
Journaux : `build/beta148-ssr-vulkan.log`, `build/beta148-ssr-opengl.log`.
Sous OpenGL, 146 680 pixels éclaircis et zéro pixel quasi blanc dans la scène
solaire. La lune reste visible sans saturation (35 865 pixels modifiés).
Preuves : `build/evidence/beta148-ssr-vulkan/` et
`build/evidence/beta148-ssr-opengl/`.
- Suites PBR/préférences Vulkan et OpenGL réussies : défaut 50 %, migration
de l’ancien 80 %, conservation d’un nouveau choix explicite 80 %, valeurs
personnalisées, FR/EN, proximité, OFF/zéro, intensités et rechargement.
Journaux : `build/beta148-pbr-vulkan.log`, `build/beta148-pbr-opengl.log`.
- `./gradlew check build` dans l’instantané isolé : 252 tests serveur,
229 réussis, 23 échecs. Exactement les mêmes identifiants que beta.147,
aucun nouvel échec. Journal : `build/beta148-check-build-isolated.log` ;
comparaison : `build/beta148-server-failures.json`. Le contrôle global
demeure donc en échec.
- Assemblage final réussi : `./gradlew build assemblePack -x :sanctuary:check`,
sans répéter les contrôles purs et serveur déjà exécutés dans l’instantané.
Journal : `build/beta148-build-pack.log`. L’exclusion ne constitue pas
une réussite du contrôle complet.
## Artefact
[Sanctuary-beta.148.mrpack](../build/Sanctuary-beta.148.mrpack), également copié
à côté des autres versions dans `sanctuary-beta/build/`. Archive ZIP vérifiée,
un seul JAR Sanctuary beta.148 identique au JAR construit, shaders finaux
identiques aux sources, textes FR/EN 50 % et dépendances exactes vérifiés.
Taille : 10 520 050 octets. SHA-256 :
`597cc2a96eabc3cf0ebf8ac59b4f94cf7cabf0c773e1dce13c10736ca6fcba38`.
Reçu : `build/beta148-artifacts.json`.
Aucune publication ni installation Prism effectuée.
+2 -2
View File
@@ -9,8 +9,8 @@ loom_version=1.17.20
fabric_api_version=0.160.5+26.3
# Release counter: beta.001, .002, .003, ... (see docs/versioning.md).
mod_version=beta.147
pack_version=beta.147
mod_version=beta.148
pack_version=beta.148
resource_pack_version=beta.121
maven_group=fr.koka.sanctuary
jei_version=30.32.0-sanctuary.3
@@ -86,7 +86,10 @@ public final class Pbr134ClientChecks implements FabricClientGameTest {
}
private static void preferences(){try{
var p=FabricLoader.getInstance().getConfigDir().resolve("sanctuary-shaders.json");Files.writeString(p,"{\"ssgi\":true,\"ssgiIntensity\":35,\"bloom\":false}");forgetPreferences();
check(VanillaLight.pbr()&&VanillaLight.pbrIntensity()==80&&VanillaLight.ssgi()&&!VanillaLight.bloom(),"Missing PBR setting defaults ON while preserving explicit old choices");
check(VanillaLight.pbr()&&VanillaLight.pbrIntensity()==50&&VanillaLight.ssgi()&&!VanillaLight.bloom(),"Missing PBR setting defaults ON while preserving explicit old choices");
Files.writeString(p,"{\"pbrIntensity\":80}");forgetPreferences();
check(VanillaLight.pbrIntensity()==50,"Previous 80 percent baseline migrates to 50 once");
VanillaLight.setPbrIntensity(80);forgetPreferences();check(VanillaLight.pbrIntensity()==80,"New explicit 80 percent choice persists after migration");
for(int n:new int[]{-1,0,50,100,101}){VanillaLight.setPbr(true);VanillaLight.setPbrIntensity(n);forgetPreferences();check(VanillaLight.pbr()&&VanillaLight.pbrIntensity()==Math.clamp(n,0,100),"PBR preference persistence/clamp");}
check(VanillaLight.pbrDistance()==32,"Shared distance default");
check(!VanillaLight.naturalWater(false)&&VanillaLight.naturalWater(true),"World-specific water defaults");
@@ -50,11 +50,19 @@ final class PixelReflectionsClientChecks {
c.runOnClient(m->check(ProceduralPbr.applied()&&PixelReflections.applied(),"Both material passes share distance "+distance));
}
c.runOnClient(m->{VanillaLight.setPbrIntensity(80);VanillaLight.setSsrIntensity(20);});
c.runOnClient(m->{VanillaLight.setPbrIntensity(50);VanillaLight.setSsrIntensity(20);});
camera(c,server,.5,68,10,70);settle(c);frames(c);
c.runOnClient(m->VanillaLight.setPbr(false));c.waitTicks(8);var solarOff=capture(c,"ssr148-solar-water-off");
c.runOnClient(m->VanillaLight.setPbr(true));frames(c);
var solar=capture(c,"ssr146-solar-water");
int white=0;for(int pixel:solar.pixels())if((pixel>>16&255)>235&&(pixel>>8&255)>235&&(pixel&255)>235)white++;
check(white>300,"Solar reflection has a broad near-white footprint at PBR 80 / SSR 20 percent: "+white);
int brightened=0;for(int i=0;i<solar.pixels().length;i++){
int a=solarOff.pixels()[i],b=solar.pixels()[i];
if((b>>16&255)+(b>>8&255)+(b&255)>(a>>16&255)+(a>>8&255)+(a&255)+24)brightened++;
}
check(brightened>5000,"Soft solar reflection remains broadly visible: "+brightened);
check(white<solar.pixels().length*.005,"Soft solar reflection preserves texture instead of a white plateau: "+white);
System.out.println("PBR148_SOLAR brightened="+brightened+" white="+white);
System.out.println("SSR146_SOLAR_WHITE pixels="+white+" width="+solar.width()+" height="+solar.height());
c.runOnClient(m->VanillaLight.setBloom(true));frames(c);capture(c,"ssr146-solar-water-bloom");
c.runOnClient(m->check(MaterialBloom.contribution()!=null,"Material light reaches bloom"));
@@ -64,7 +72,7 @@ final class PixelReflectionsClientChecks {
c.runOnClient(m->VanillaLight.setSsr(false));c.waitTicks(8);
var moon=capture(c,"ssr147-moon-water");
int moonWhite=0;for(int pixel:moon.pixels())if((pixel>>16&255)>235&&(pixel>>8&255)>235&&(pixel&255)>235)moonWhite++;
check(moonWhite<white*.05,"Moon reflection stays much softer than the sun: "+moonWhite+" / "+white);
check(moonWhite<Math.max(10,white*.05),"Moon reflection stays much softer than the sun: "+moonWhite+" / "+white);
c.runOnClient(m->VanillaLight.setPbr(false));c.waitTicks(8);var moonOff=capture(c,"ssr147-moon-water-off");
check(changed(moonOff,moon)>100,"Soft moon reflection remains visible");
System.out.println("PBR147_MOON white="+moonWhite+" sunWhite="+white+" changed="+changed(moonOff,moon));
@@ -454,7 +454,7 @@ public final class PixelShadows122ClientChecks implements FabricClientGameTest {
var path=FabricLoader.getInstance().getConfigDir().resolve("sanctuary-shaders.json");
Files.deleteIfExists(path);forgetPreferences();
check(VanillaLight.bloom()&&VanillaLight.bloomIntensity()==20&&VanillaLight.pbr()&&VanillaLight.ssgi(),"Fresh defaults: bloom20, PBR and SSGI ON");
check(VanillaLight.pbrIntensity()==80&&VanillaLight.ssrIntensity()==20&&VanillaLight.ssgiIntensity()==35,"PBR 80 and SSR 20 defaults, SSGI strength retained");
check(VanillaLight.pbrIntensity()==50&&VanillaLight.ssrIntensity()==20&&VanillaLight.ssgiIntensity()==35,"PBR 50 and SSR 20 defaults, SSGI strength retained");
Files.writeString(path,"{\"pbr\":false,\"ssgi\":false,\"bloomIntensity\":73}");forgetPreferences();
check(!VanillaLight.pbr()&&!VanillaLight.ssgi()&&VanillaLight.bloomIntensity()==73,"Explicit personal toggles and intensity survive changed defaults");
Files.writeString(path,"{\"bloom\":false}");forgetPreferences();
@@ -29,7 +29,8 @@ public final class VanillaLight {
boolean lensFlare=true;
int lensFlareIntensity=30;
boolean pbr=true;
int pbrIntensity=80;
int pbrIntensity=50;
int pbrBalanceVersion;
int pbrDistance=32;
boolean ssr=false;
int ssrIntensity=20;
@@ -64,6 +65,9 @@ public final class VanillaLight {
preferences.lensFlareIntensity=Math.clamp(preferences.lensFlareIntensity,0,100);
preferences.ssrIntensity=Math.clamp(preferences.ssrIntensity,0,100);
preferences.pbrDistance=normalizePbrDistance(preferences.pbrDistance);
// Migrate the previous 80% baseline once; later explicit 80% choices persist.
if(preferences.pbrBalanceVersion<1&&preferences.pbrIntensity==80)preferences.pbrIntensity=50;
preferences.pbrBalanceVersion=1;
preferences.pbrIntensity=Math.clamp(preferences.pbrIntensity,0,100);
preferences.coloredLightIntensity=Math.clamp(preferences.coloredLightIntensity,0,100);
preferences.coloredLightDistance=normalizeColoredLightDistance(preferences.coloredLightDistance);
@@ -2303,7 +2303,7 @@
"sanctuary.shaders.pbr": "PBR · material relief",
"sanctuary.shaders.pbr_help": "Experimental: procedural block normals and roughness, sun, moon and local light highlights. Enable Colored lights for local direction. Range 32 blocks. ON at 80% by default.",
"sanctuary.shaders.pbr_intensity": "PBR intensity",
"sanctuary.shaders.pbr_intensity_help": "Material relief and highlights, including water. Default: 80%.",
"sanctuary.shaders.pbr_intensity_help": "Material relief and highlights, including water. Default: 50%.",
"sanctuary.shaders.pbr_intensity_value": "PBR intensity: %s %%",
"sanctuary.shaders.lens_flare": "Lens flare · soft rectangles",
"sanctuary.shaders.lens_flare_help": "Soft rectangular sun and moon reflections. Obstacles hide the sources. Independent of the bloom halo.",
@@ -2303,7 +2303,7 @@
"sanctuary.shaders.pbr": "PBR · relief des matériaux",
"sanctuary.shaders.pbr_help": "Expérimental : normales procédurales et rugosité des blocs, reflets du soleil, de la lune et des lumières locales. Activer Lumières colorées pour la direction locale. Portée 32 blocs. Activé par défaut à 80 %.",
"sanctuary.shaders.pbr_intensity": "Intensité PBR",
"sanctuary.shaders.pbr_intensity_help": "Relief et éclats des matières, eau comprise. Défaut : 80 %.",
"sanctuary.shaders.pbr_intensity_help": "Relief et éclats des matières, eau comprise. Défaut : 50 %.",
"sanctuary.shaders.pbr_intensity_value": "Intensité PBR : %s %%",
"sanctuary.shaders.lens_flare": "Lens flare · rectangles doux",
"sanctuary.shaders.lens_flare_help": "Reflets rectangulaires du soleil et de la lune, aux bords dégradés. Les obstacles masquent les sources. Indépendant du halo de bloom.",
@@ -128,10 +128,10 @@ void main(){
// A broad solar lobe gives water an extended glitter path at grazing angles.
// Local lamps retain the material's original narrow lobe.
vec4 solarMaterial=material;
solarMaterial.b=max(material.b,family>1.5?.34:.24);
solarMaterial.b=max(material.b,family>1.5?.42:.24);
vec3 specular=localShine(n,v,l,solarMaterial,albedo);
// PbrEnvironment.z identifies sunlight: moonlight keeps its modest base radiance.
float solarRadiance=mix(1.0,family>1.5?20.0:4.0,PbrEnvironment.z);
float solarRadiance=mix(1.0,family>1.5?6.0:4.0,PbrEnvironment.z);
float fog=max(clamp((max(length(relativePosition.xz),abs(relativePosition.y))-PbrFog.x)/max(PbrFog.y-PbrFog.x,.001),0.0,1.0),
clamp((length(relativePosition)-PbrFog.z)/max(PbrFog.w-PbrFog.z,.001),0.0,1.0));
float amount=PbrSun.w*pow(tint.a,8.0)*visibility(relativePosition,baseNormal)*(1.0-fog*PbrEnvironment.x)
@@ -148,8 +148,16 @@ void main(){
lit=clamp(lit*(1.0+localRelief*localAmount),0.0,1.0);
}
// Preserve bright solar highlights instead of capping them at a medium grey.
vec3 shine=min((specular*amount*solarRadiance+localShine(n,v,arrival.xyz,material,albedo)*localAmount)*intensity*5.0,vec3(8.0));
lit+=(1.0-lit)*(1.0-exp(-shine));
vec3 skyShine=min(specular*amount*solarRadiance*intensity*5.0,vec3(8.0));
vec3 lampShine=min(localShine(n,v,arrival.xyz,material,albedo)*localAmount*intensity*5.0,vec3(8.0));
if(family>1.5&&PbrEnvironment.z>.5){
// Soft-light/screen blend per native texel: broad daylight lifts the water
// without replacing its colour and detail with a saturated white cone.
vec3 weight=skyShine/(1.0+skyShine);
vec3 highlight=mix(vec3(1.0),sqrt(lit),.55);
lit=mix(lit,highlight,weight);
}else lit+=(1.0-lit)*(1.0-exp(-skyShine));
lit+=(1.0-lit)*(1.0-exp(-lampShine));
if(any(isnan(lit))||any(isinf(lit)))discard;
fragColor=vec4(sqrt(clamp(lit,0.0,1.0)),1.0);
}
+1 -1
View File
@@ -1,6 +1,6 @@
name = "Sanctuary"
author = "KOKA99CAB"
version = "beta.147"
version = "beta.148"
pack-format = "packwiz:1.1.0"
[index]