Compare commits

...
1 Commits
Author SHA1 Message Date
koka 1c23d0c17e Separate PBR and SSR ranges and remove foliage sheen in beta.149
Build Sanctuary / build (push) Waiting to run
2026-09-18 20:40:47 +02:00
14 changed files with 158 additions and 30 deletions
+8 -2
View File
@@ -1,5 +1,11 @@
# Sanctuary
## beta.149 — Distances PBR / SSR et feuillage (pack local)
Deux distances séparées, 64 blocs par défaut chacune, jusqu’à 256 blocs.
Option renommée « SSR » et suppression du voile spéculaire sur le feuillage.
[Contrat et vérifications](docs/independent-distances-beta149.md).
## beta.148 — PBR 50 % et soleil diffus (pack local)
PBR à 50 %, reflet solaire plus doux avec fusion par texel préservant
@@ -2348,7 +2354,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.148 |
| Sanctuary / pack | beta.149 |
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
@@ -2377,7 +2383,7 @@ décrits dans [Validation](docs/testing.md).
Résultats :
- `mods/sanctuary/build/libs/sanctuary-beta.148.jar` : mod à installer avec
- `mods/sanctuary/build/libs/sanctuary-beta.149.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-149 — Distances PBR et SSR indépendantes
Branche `codex/separate-reflection-distances-beta149`, socle beta.148 `6f87144`.
- Deux réglages : Distance PBR et Distance SSR, chacun à 64 blocs par défaut.
Choix 16, 32, 64, 128, 256 blocs, enregistrés séparément.
- Le PBR conserve son propre fondu et sa propre limite de portée. Le SSR
utilise sa distance pour les surfaces réfléchissantes et sa recherche de
paysage. Le maillage et la sélection des surfaces couvrent le maximum des
deux portées actives, afin que réduire l’une ne coupe pas l’autre.
- Ancien défaut commun 32 migré une fois vers PBR 64 ; nouveau réglage SSR 64.
Les anciennes valeurs PBR différentes de 32 restent conservées. Après la
migration, un choix explicite 32 est conservé comme les autres valeurs.
- Option nommée exactement « SSR » en français et en anglais, sans la mention
« expérimental ». Les autres options expérimentales du jeu sont inchangées.
- Intensités PBR 50 % et SSR 20 %, rendu solaire diffus de beta.148 conservés.
SSR conserve sa dépendance au PBR et les limites du paysage visible/chargé
et du budget de maillage.
- Les feuilles (et fibres de laine, même profil entièrement mat) ne reçoivent
plus de large éclat spéculaire blanc. Leur relief normal reste présent.
La pierre et le bois retrouvent exactement leur poids spéculaire précédent,
comme les surfaces polies, les métaux, l’eau et le verre. La suppression
concerne les profils non métalliques de rugosité 0,98, avec transition 0,90–0,98.
## Vérifications
Contrôles de persistance indépendante, valeurs par défaut et libellés FR/EN.
Scènes graphiques avec PBR variable/SSR 256 puis PBR 256/SSR variable.
- Suite PBR/préférences Vulkan réussie : deux défauts 64 et persistance
indépendante sur 16/32/64/128/256 ; libellés FR/EN et nom SSR vérifiés.
Journal : `build/beta149-pbr-vulkan.log`.
- Suites SSR Vulkan et OpenGL réussies avec les portées dissociées, F5,
intersections, eau/verre/métal, soleil/lune, OFF/zéro et rechargement.
Journaux : `build/beta149-ssr-vulkan.log`, `build/beta149-ssr-opengl.log`.
Ces passes précèdent l’ajustement final du profil entièrement mat.
- Suite PBR Vulkan finale avec feuillage réussie : 170 172 pixels de feuilles
contrôlés, saturation relative 1,00007, relief visible sur 63 236 pixels.
Journal : `build/beta149-foliage-vulkan.log` ; captures correspondantes
dans `build/evidence/beta149-foliage-vulkan/`.
- Bois et briques après recentrage sur le feuillage : aucun pixel modifié
par rapport à la capture précédant l’ajustement, sur les zones de contrôle
de 26 304 et 40 896 pixels respectivement.
- `./gradlew check build` exécuté dans l’instantané isolé : 252 tests serveur,
229 réussis et 23 échecs, mêmes identifiants qu’en beta.148. Aucun nouvel échec.
Journal : `build/beta149-check-build-isolated.log` ; comparaison :
`build/beta149-server-failures.json`. L’ajustement final du feuillage concerne
seulement le shader et son test client. Le contrôle global reste en échec.
- Suite PBR OpenGL finale réussie également : 170 199 pixels de feuilles,
saturation relative 1,00001, relief visible sur 63 263 pixels.
Journal : `build/beta149-foliage-opengl.log` ; captures correspondantes
dans `build/evidence/beta149-foliage-opengl/`.
- Assemblage final réussi : `./gradlew build assemblePack -x :sanctuary:check`,
sans répéter les contrôles purs/serveur exécutés dans l’instantané.
Journal : `build/beta149-build-pack.log`. Cette exclusion ne transforme
pas le contrôle complet en réussite.
## Artefact
[Sanctuary-beta.149.mrpack](../build/Sanctuary-beta.149.mrpack), copié aussi dans
`sanctuary-beta/build/` avec les autres versions. Archive vérifiée, un seul JAR
Sanctuary beta.149 identique au JAR construit, shaders identiques aux sources,
libellés SSR et deux portées FR/EN vérifiés. Minecraft 26.3 / Loader 0.19.5.
Taille : 10 520 465 octets. SHA-256 :
`ef5519d9a0e2006b865b62371a6f8712db02ab138aa9698339d6fdb02fb4befa`.
Reçu : `build/beta149-artifacts.json`. Aucune installation Prism ni publication.
+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.148
pack_version=beta.148
mod_version=beta.149
pack_version=beta.149
resource_pack_version=beta.121
maven_group=fr.koka.sanctuary
jei_version=30.32.0-sanctuary.3
@@ -50,10 +50,33 @@ public final class Pbr134ClientChecks implements FabricClientGameTest {
c.runOnClient(m->m.getWindow().setWindowed(oldWidth,oldHeight));c.waitFor(m->m.gameRenderer.mainRenderTarget().width==on.width(),200);frames(c);
c.runOnClient(m->{VanillaLight.setPixelShadows(true);VanillaLight.setSsgi(true);VanillaLight.setBloom(true);VanillaLight.setOreEmission(true);VanillaLight.setEdgeHighlights(true);});
c.waitFor(m->PixelShadows.applied()&&PixelShadows.ready()&&ScreenSpaceGI.applied()&&Bloom.applied()&&EdgeHighlights.applied()&&ProceduralPbr.applied(),1200);frames(c);capture(c,"pbr-combined");
foliage(c,server);
c.runOnClient(m->VanillaLight.setEnabled(false));c.waitTicks(8);c.runOnClient(m->check(!ProceduralPbr.allocated()&&ProceduralPbr.materialCount()==0,"Global OFF releases PBR"));
c.runOnClient(m->{VanillaLight.setEnabled(true);VanillaLight.setPbr(false);VanillaLight.setSsgi(false);});
System.out.println("PBR134_PASS normals; profiles; texture cache; directional lighting; intensity; OFF/zero; tiny camera; reload; resize; combined; default="+delta+" high="+high+" directional="+directions);
}
private static void foliage(ClientGameTestContext c,TestServerContext server){
c.runOnClient(m->{VanillaLight.setSsr(false);VanillaLight.setPbrIntensity(50);VanillaLight.setPixelShadows(false);VanillaLight.setSsgi(false);VanillaLight.setBloom(false);VanillaLight.setOreEmission(false);VanillaLight.setEdgeHighlights(false);});
server.runOnServer(s->{command(s,"time set 1000");for(int x=-5;x<=24;x++)for(int z=-5;z<=24;z++)
s.overworld().setBlockAndUpdate(new BlockPos(x,64,z),Blocks.OAK_LEAVES.defaultBlockState().setValue(net.minecraft.world.level.block.LeavesBlock.PERSISTENT,true));});
camera(c,server,10.5,69,5.5,65);look(c,server,0,40);settle(c);
enable(c,false);var off=capture(c,"pbr149-leaves-off");enable(c,true);var on=capture(c,"pbr149-leaves-on");
double nativeChroma=0,pbrChroma=0;int samples=0,relief=0;
for(int y=off.height()/3;y<off.height()*9/10;y++)for(int x=off.width()/10;x<off.width()*9/10;x++){
int i=y*off.width()+x,a=off.pixels()[i],b=on.pixels()[i],r=a>>16&255,g=a>>8&255,blue=a&255;
if(g<30||g<r*1.1||g<blue*1.1)continue;
nativeChroma+=chroma(a);pbrChroma+=chroma(b);samples++;
if(Math.abs((b>>16&255)-r)+Math.abs((b>>8&255)-g)+Math.abs((b&255)-blue)>6)relief++;
}
double retained=pbrChroma/nativeChroma;
System.out.println("PBR149_LEAVES samples="+samples+" chromaRetained="+retained+" relief="+relief);
check(samples>1000&&retained>.985,"Leaves preserve green colour without specular veil: "+retained);
check(relief>100,"Leaf normal relief remains visible");
}
private static double chroma(int pixel){
int r=pixel>>16&255,g=pixel>>8&255,b=pixel&255,max=Math.max(r,Math.max(g,b)),min=Math.min(r,Math.min(g,b));
return (max-min)/(double)Math.max(1,max);
}
private static void closeRange(ClientGameTestContext c,TestServerContext server){
int failures=0;
c.runOnClient(m->VanillaLight.setPbrIntensity(80));
@@ -91,9 +114,11 @@ public final class Pbr134ClientChecks implements FabricClientGameTest {
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.pbrDistance()==64&&VanillaLight.ssrDistance()==64,"Independent distances default to 64");
check(!VanillaLight.naturalWater(false)&&VanillaLight.naturalWater(true),"World-specific water defaults");
for(int n:new int[]{16,32,64,128,256}){VanillaLight.setPbrDistance(n);forgetPreferences();check(VanillaLight.pbrDistance()==n,"Shared distance persistence");}
for(int n:new int[]{16,32,64,128,256}){VanillaLight.setPbrDistance(n);forgetPreferences();check(VanillaLight.pbrDistance()==n&&VanillaLight.ssrDistance()==64,"PBR distance changes independently");}
for(int n:new int[]{16,32,64,128,256}){VanillaLight.setSsrDistance(n);forgetPreferences();check(VanillaLight.ssrDistance()==n&&VanillaLight.pbrDistance()==256,"SSR distance changes independently");}
VanillaLight.setSsrDistance(64);
for(int n:new int[]{0,1,2,4,8}){VanillaLight.setWaterBlendRadius(n);forgetPreferences();check(VanillaLight.waterBlendRadius()==n,"Water blend persistence");}
VanillaLight.setPbrDistance(32);VanillaLight.setWaterBlendRadius(4);
check(!VanillaLight.ssr()&&VanillaLight.ssrIntensity()==20,"Missing SSR defaults OFF at 20 percent");
@@ -102,10 +127,11 @@ public final class Pbr134ClientChecks implements FabricClientGameTest {
var manager=net.minecraft.client.Minecraft.getInstance().getLanguageManager();var oldLanguage=manager.getSelected();
for(String locale:new String[]{"fr_fr","en_us"}){
manager.setSelected(locale);manager.onResourceManagerReload(net.minecraft.client.Minecraft.getInstance().getResourceManager());
for(String key:new String[]{"pbr_distance","pbr_distance_help","pbr_distance_value","water_blend","water_blend_help","water_blend_value","ssr","ssr_help","ssr_intensity","ssr_intensity_help","ssr_intensity_value"}){
for(String key:new String[]{"ssr_distance","ssr_distance_help","ssr_distance_value","pbr_distance","pbr_distance_help","pbr_distance_value","water_blend","water_blend_help","water_blend_value","ssr","ssr_help","ssr_intensity","ssr_intensity_help","ssr_intensity_value"}){
String full="sanctuary.shaders."+key;check(!net.minecraft.network.chat.Component.translatable(full,50).getString().equals(full),"SSR FR/EN "+full);
}
}
check(net.minecraft.network.chat.Component.translatable("sanctuary.shaders.ssr").getString().equals("SSR"),"SSR label without experimental qualifier");
manager.setSelected(oldLanguage);manager.onResourceManagerReload(net.minecraft.client.Minecraft.getInstance().getResourceManager());
Files.writeString(p,"{\"naturalWater\":false,\"pbrIntensity\":37}");forgetPreferences();
check(!VanillaLight.naturalWater(false)&&!VanillaLight.naturalWater(true)&&VanillaLight.pbrIntensity()==37,"Legacy water OFF and personal PBR intensity are preserved");
@@ -46,10 +46,17 @@ final class PixelReflectionsClientChecks {
c.runOnClient(m->m.options.setCameraType(net.minecraft.client.CameraType.FIRST_PERSON));c.waitTicks(20);
server.runOnServer(s->command(s,"gamemode spectator @a"));c.waitTicks(10);
for(int distance:new int[]{16,64,128,256,32}){
c.runOnClient(m->VanillaLight.setPbrDistance(distance));settle(c);frames(c);capture(c,"ssr146-distance-"+distance);
c.runOnClient(m->check(ProceduralPbr.applied()&&PixelReflections.applied(),"Both material passes share distance "+distance));
c.runOnClient(m->{VanillaLight.setPbrDistance(distance);VanillaLight.setSsrDistance(256);});settle(c);frames(c);capture(c,"ssr146-distance-"+distance);
c.runOnClient(m->check(ProceduralPbr.applied()&&PixelReflections.applied(),"Independent material distances render at PBR "+distance+" / SSR 256"));
}
for(int distance:new int[]{16,64,256}){
c.runOnClient(m->{VanillaLight.setPbrDistance(256);VanillaLight.setSsrDistance(distance);});settle(c);frames(c);
capture(c,"ssr149-independent-"+distance);
c.runOnClient(m->check(ProceduralPbr.applied()&&PixelReflections.applied(),"PBR 256 remains active with independent SSR "+distance));
}
c.runOnClient(m->VanillaLight.setPbrDistance(32));
c.runOnClient(m->VanillaLight.setSsrDistance(32));
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");
@@ -48,7 +48,7 @@ final class PbrTerrain implements AutoCloseable {
long frame=mc.level.getGameTime();var active=new ArrayList<Section>();
for(var render:mc.levelRenderer.visibleSections()){
long key=render.getSectionNode();var pos=render.getRenderOrigin();
if(pos.offset(8,8,8).distToCenterSqr(camera)>Math.pow(VanillaLight.pbrDistance()+16,2))continue;
if(pos.offset(8,8,8).distToCenterSqr(camera)>Math.pow(VanillaLight.materialDistance()+16,2))continue;
var chunk=mc.level.getChunkSource().getChunk(pos.getX()>>4,pos.getZ()>>4,ChunkStatus.FULL,false);
if(chunk==null)continue;
var storage=chunk.getSection(mc.level.getSectionIndex(pos.getY()));
@@ -90,8 +90,8 @@ public final class PixelReflections {
if(uniform==null)uniform=new MappableRingBuffer(()->"Sanctuary reflection parameters",GpuBuffer.USAGE_UNIFORM|GpuBuffer.USAGE_MAP_WRITE,160);
uniform.rotate();try(var map=uniform.currentBuffer().map(false,true)){
Std140Builder.intoBuffer(map.data()).putMat4f(vp).putMat4f(new Matrix4f(vp).invert())
.putVec4(RenderSystem.getDevice().getDeviceInfo().isZZeroToOne()?1:0,VanillaLight.ssrIntensity()/100f,VanillaLight.pbrIntensity()/100f,VanillaLight.pbrDistance())
.putVec4(Math.max(128,VanillaLight.pbrDistance()),32,0,0);
.putVec4(RenderSystem.getDevice().getDeviceInfo().isZZeroToOne()?1:0,VanillaLight.ssrIntensity()/100f,VanillaLight.pbrIntensity()/100f,VanillaLight.ssrDistance())
.putVec4(Math.max(128,VanillaLight.ssrDistance()),32,VanillaLight.materialDistance(),0);
}
int max=java.util.stream.Stream.concat(solid.stream(),transparent.stream()).mapToInt(PbrTerrain.Entry::indices).max().orElse(0);
RenderSystem.getSequentialBuffer(PrimitiveTopology.QUADS).requestIndexCount(max);
@@ -29,12 +29,15 @@ public final class ShaderOptionsScreen extends OptionsSubScreen {
list.addBig(OptionInstance.createBoolean("sanctuary.shaders.pbr",OptionInstance.cachedConstantTooltip(
Component.translatable("sanctuary.shaders.pbr_help")),VanillaLight.pbr(),VanillaLight::setPbr));
slider("pbr_intensity",VanillaLight.pbrIntensity(),VanillaLight::setPbrIntensity);
list.addBig(OptionInstance.createBoolean("sanctuary.shaders.ssr",OptionInstance.cachedConstantTooltip(
Component.translatable("sanctuary.shaders.ssr_help")),VanillaLight.ssr(),VanillaLight::setSsr));
slider("ssr_intensity",VanillaLight.ssrIntensity(),VanillaLight::setSsrIntensity);
list.addBig(new OptionInstance<Integer>("sanctuary.shaders.pbr_distance",OptionInstance.cachedConstantTooltip(
Component.translatable("sanctuary.shaders.pbr_distance_help")),(caption,value)->Component.translatable("sanctuary.shaders.pbr_distance_value",value),
new OptionInstance.Enum<>(List.of(16,32,64,128,256),Codec.INT),VanillaLight.pbrDistance(),VanillaLight::setPbrDistance));
list.addBig(OptionInstance.createBoolean("sanctuary.shaders.ssr",OptionInstance.cachedConstantTooltip(
Component.translatable("sanctuary.shaders.ssr_help")),VanillaLight.ssr(),VanillaLight::setSsr));
slider("ssr_intensity",VanillaLight.ssrIntensity(),VanillaLight::setSsrIntensity);
list.addBig(new OptionInstance<Integer>("sanctuary.shaders.ssr_distance",OptionInstance.cachedConstantTooltip(
Component.translatable("sanctuary.shaders.ssr_distance_help")),(caption,value)->Component.translatable("sanctuary.shaders.ssr_distance_value",value),
new OptionInstance.Enum<>(List.of(16,32,64,128,256),Codec.INT),VanillaLight.ssrDistance(),VanillaLight::setSsrDistance));
list.addBig(OptionInstance.createBoolean("sanctuary.shaders.colored_lights",OptionInstance.cachedConstantTooltip(
Component.translatable("sanctuary.shaders.colored_lights_help")),VanillaLight.coloredLights(),VanillaLight::setColoredLights));
list.addBig(OptionInstance.createBoolean("sanctuary.shaders.warm_torches",OptionInstance.cachedConstantTooltip(
@@ -31,7 +31,9 @@ public final class VanillaLight {
boolean pbr=true;
int pbrIntensity=50;
int pbrBalanceVersion;
int pbrDistance=32;
int pbrDistance=64;
int ssrDistance=64;
int reflectionDistanceVersion;
boolean ssr=false;
int ssrIntensity=20;
boolean ssgi=true;
@@ -64,7 +66,10 @@ public final class VanillaLight {
preferences.sunshaftIntensity=Math.clamp(preferences.sunshaftIntensity,0,100);
preferences.lensFlareIntensity=Math.clamp(preferences.lensFlareIntensity,0,100);
preferences.ssrIntensity=Math.clamp(preferences.ssrIntensity,0,100);
if(preferences.reflectionDistanceVersion<1&&preferences.pbrDistance==32)preferences.pbrDistance=64;
preferences.reflectionDistanceVersion=1;
preferences.pbrDistance=normalizePbrDistance(preferences.pbrDistance);
preferences.ssrDistance=normalizePbrDistance(preferences.ssrDistance);
// Migrate the previous 80% baseline once; later explicit 80% choices persist.
if(preferences.pbrBalanceVersion<1&&preferences.pbrIntensity==80)preferences.pbrIntensity=50;
preferences.pbrBalanceVersion=1;
@@ -114,6 +119,9 @@ public final class VanillaLight {
public static int ssrIntensity(){enabled();return preferences.ssrIntensity;}
public static void setSsr(boolean value){enabled();preferences.ssr=value;save();}
public static void setSsrIntensity(int value){enabled();preferences.ssrIntensity=Math.clamp(value,0,100);save();}
public static int ssrDistance(){enabled();return preferences.ssrDistance;}
public static void setSsrDistance(int value){enabled();preferences.ssrDistance=normalizePbrDistance(value);save();}
static int materialDistance(){return Math.max(pbrDistance(),ssr()&&ssrIntensity()>0?ssrDistance():0);}
public static int pbrDistance(){enabled();return preferences.pbrDistance;}
public static void setPbrDistance(int value){enabled();preferences.pbrDistance=normalizePbrDistance(value);save();}
static int normalizePbrDistance(int value){return value<24?16:value<48?32:value<96?64:value<192?128:256;}
@@ -1,7 +1,7 @@
{
"sanctuary.shaders.ssr_intensity_value": "Reflection strength: %s%%",
"sanctuary.shaders.ssr_intensity_help": "Strength of visible landscape reflections on solids and water. Default: 20%.",
"sanctuary.shaders.ssr": "Landscape reflections — experimental",
"sanctuary.shaders.ssr": "SSR",
"sanctuary.shaders.ssr_help": "Colours material texels with the visible landscape. Requires PBR; off-screen objects cannot be reflected.",
"sanctuary.shaders.ssr_intensity": "Reflection strength",
"sanctuary.graphics.default_vulkan": "Vulkan (default)",
@@ -2330,10 +2330,13 @@
"sanctuary.shaders.water_intensity": "Water intensity",
"sanctuary.shaders.water_intensity_help": "At 0%, keeps native rendering. At 100%, applies all three profiles.",
"sanctuary.shaders.water_intensity_value": "Water intensity: %s%%",
"sanctuary.shaders.pbr_distance": "PBR and SSR distance",
"sanctuary.shaders.pbr_distance_value": "PBR and SSR distance: %s blocks",
"sanctuary.shaders.pbr_distance_help": "Shared range for relief and reflecting surfaces. 16, 32, 64, 128 or 256 blocks. Longer distances cost more; mesh memory is bounded.",
"sanctuary.shaders.pbr_distance": "PBR distance",
"sanctuary.shaders.pbr_distance_value": "PBR distance: %s blocks",
"sanctuary.shaders.pbr_distance_help": "Independent PBR range: 16, 32, 64, 128 or 256 blocks. Default: 64 blocks. Limited to visible terrain and mesh budget.",
"sanctuary.shaders.water_blend": "Water blending",
"sanctuary.shaders.water_blend_value": "Water blending: %s × %s blocks",
"sanctuary.shaders.water_blend_help": "Transition width between bed-dependent water colours: 1, 3, 5, 9 or 17 blocks. Default: 9 × 9."
"sanctuary.shaders.water_blend_help": "Transition width between bed-dependent water colours: 1, 3, 5, 9 or 17 blocks. Default: 9 × 9.",
"sanctuary.shaders.ssr_distance": "SSR distance",
"sanctuary.shaders.ssr_distance_value": "SSR distance: %s blocks",
"sanctuary.shaders.ssr_distance_help": "Independent SSR range: 16, 32, 64, 128 or 256 blocks. Default: 64 blocks. Limited to visible terrain and mesh budget."
}
@@ -1,7 +1,7 @@
{
"sanctuary.shaders.ssr_intensity_value": "Intensité des reflets : %s %%",
"sanctuary.shaders.ssr_intensity_help": "Intensité des reflets du paysage visible, sur les solides et l’eau. Défaut : 20 %.",
"sanctuary.shaders.ssr": "Reflets du paysage — expérimental",
"sanctuary.shaders.ssr": "SSR",
"sanctuary.shaders.ssr_help": "Colore les pixels de matière avec le paysage visible. PBR requis ; les objets hors écran ne sont pas réfléchis.",
"sanctuary.shaders.ssr_intensity": "Intensité des reflets",
"sanctuary.graphics.default_vulkan": "Vulkan (par défaut)",
@@ -2330,10 +2330,13 @@
"sanctuary.shaders.water_intensity": "Intensité de l’eau",
"sanctuary.shaders.water_intensity_help": "À 0 %, conserve le rendu natif. À 100 %, applique les trois profils.",
"sanctuary.shaders.water_intensity_value": "Intensité de l’eau: %s%%",
"sanctuary.shaders.pbr_distance": "Distance PBR et SSR",
"sanctuary.shaders.pbr_distance_value": "Distance PBR et SSR : %s blocs",
"sanctuary.shaders.pbr_distance_help": "Portée commune du relief et des surfaces réfléchissantes. 16, 32, 64, 128 ou 256 blocs. Les distances élevées coûtent davantage ; budget de maillage limité.",
"sanctuary.shaders.pbr_distance": "Distance PBR",
"sanctuary.shaders.pbr_distance_value": "Distance PBR: %s blocs",
"sanctuary.shaders.pbr_distance_help": "Portée indépendante du PBR : 16, 32, 64, 128 ou 256 blocs. Défaut : 64 blocs. Limitée au terrain visible et au budget de maillage.",
"sanctuary.shaders.water_blend": "Mélange des eaux",
"sanctuary.shaders.water_blend_value": "Mélange des eaux : %s × %s blocs",
"sanctuary.shaders.water_blend_help": "Étendue de la transition des teintes selon le fond : 1, 3, 5, 9 ou 17 blocs. Défaut : 9 × 9."
"sanctuary.shaders.water_blend_help": "Étendue de la transition des teintes selon le fond : 1, 3, 5, 9 ou 17 blocs. Défaut : 9 × 9.",
"sanctuary.shaders.ssr_distance": "Distance SSR",
"sanctuary.shaders.ssr_distance_value": "Distance SSR: %s blocs",
"sanctuary.shaders.ssr_distance_help": "Portée indépendante du SSR : 16, 32, 64, 128 ou 256 blocs. Défaut : 64 blocs. Limitée au terrain visible et au budget de maillage."
}
@@ -148,8 +148,12 @@ 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 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));
// Fully matte foliage/fibres receive normal relief, not a broad white specular veil.
// Stone/wood (roughness <= .88), polished surfaces, metals and water are unchanged.
float fullyMatte=smoothstep(.9,.98,material.b)*(1.0-material.a);
float shineWeight=family<.5?1.0-fullyMatte:1.0;
vec3 skyShine=min(specular*amount*solarRadiance*intensity*5.0*shineWeight,vec3(8.0));
vec3 lampShine=min(localShine(n,v,arrival.xyz,material,albedo)*localAmount*intensity*5.0*shineWeight,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.
@@ -9,7 +9,7 @@ layout(location=2) in vec2 maskUv;
layout(location=3) in vec4 tint;
void main(){
vec2 dx=dFdx(blockUv),dy=dFdy(blockUv);
if(length(relativePosition)>=ReflectionParams.w)discard;
if(length(relativePosition)>=ReflectionLimits.z)discard;
// Minecraft's world projection uses reverse depth: zero is the far plane.
float opaque=texelFetch(OpaqueDepth,ivec2(gl_FragCoord.xy),0).r;
// Native and material transforms differ slightly in evaluation order. A fixed
+1 -1
View File
@@ -1,6 +1,6 @@
name = "Sanctuary"
author = "KOKA99CAB"
version = "beta.148"
version = "beta.149"
pack-format = "packwiz:1.1.0"
[index]