Files

221 lines
6.5 KiB
GLSL

#include "/Lib/Settings.glsl"
#include "/Lib/Utilities.glsl"
// MinecraftPT — GbufferData structures
#ifndef GBUFFER_DATA_GLSL
#define GBUFFER_DATA_GLSL
struct Material{
float roughness;
float metalness;
float emissiveness;
float scattering;
float reflectionStrength;
};
struct GbufferData{
vec3 albedo;
float albedoAlpha;
vec3 worldNormal;
vec3 vertexNormal;
vec2 lightmap;
float materialID;
float parallaxShadow;
Material material;
};
// Standard material defaults
#define material_air Material(1.0, 0.0, 0.0, 0.0, 0.0);
#define material_water Material(0.0, 0.018, 0.0, 0.0, 1.0);
#define material_glass Material(0.0, 0.04, 0.0, 0.0, 1.0);
// Material IDs (written to GBuffer)
#define MATID_DEFAULT 0.0
#define MATID_WATER 1.0
#define MATID_STAINEDGLASS 2.0
#define MATID_LEAVES 3.0
#define MATID_GRASS 4.0 // cross plant
#define MATID_HAND 5.0
#define MATID_ENTITIES 6.0
#define MATID_ENTITIES_PLAYER 7.0
#define MATID_ENTITIES_SNOW 8.0
#define MATID_LIGHTNING 9.0
#define MATID_SKY 10.0
#define MATID_TORCH 11.0
#define MATID_FIRE 12.0
#define MATID_ENDROD 13.0
#define MATID_AMETHYST 14.0
#define MATID_SOULTORCH 15.0
#define MATID_REDSTONE_TORCH 16.0
#define MATID_PARTICLE 17.0
#define MATID_END_PORTAL 18.0
#define MATID_SELECTION 19.0
#define MATID_COPPER_LANTERN 20.0
#define MATID_BEACON_BEAM 21.0
// Material from specular texture (LAB PBR)
Material MaterialFromTex(vec4 specTex){
Material material;
material.roughness = 1.0 - specTex.r;
material.roughness = material.roughness * material.roughness;
material.metalness = specTex.g;
material.reflectionStrength = saturate(material.roughness < 0.1 ? 1.0 : pow(specTex.r, 0.2));
material.reflectionStrength = saturate(material.reflectionStrength + material.metalness);
material.metalness = max(material.metalness, 0.04);
material.emissiveness = specTex.a;
material.scattering = 0.0;
return material;
}
// Predefined metal F0 values (from LAB PBR spec)
vec3 PredefinedMetalF0(float index){
vec3 f0 = vec3(0.0);
if (abs(index - 230.0 / 255.0) < 2e-4){
f0 = vec3(0.56, 0.58, 0.58); // Iron
}else if (abs(index - 231.0 / 255.0) < 2e-4){
f0 = vec3(1.00, 0.69, 0.28); // Gold
}else if (abs(index - 232.0 / 255.0) < 2e-4){
f0 = vec3(0.81, 0.82, 0.83); // Aluminum
}else if (abs(index - 233.0 / 255.0) < 2e-4){
f0 = vec3(0.50, 0.49, 0.49); // Chromium
}else if (abs(index - 234.0 / 255.0) < 2e-4){
f0 = vec3(0.95, 0.52, 0.35); // Copper
}else if (abs(index - 235.0 / 255.0) < 2e-4){
f0 = vec3(0.81, 0.83, 0.87); // Lead
}else if (abs(index - 236.0 / 255.0) < 2e-4){
f0 = vec3(0.66, 0.63, 0.58); // Platinum
}else if (abs(index - 237.0 / 255.0) < 2e-4){
f0 = vec3(0.95, 0.91, 0.81); // Silver
}
return f0;
}
// Read solid GBuffer data
GbufferData GetGbufferDataSoild(ivec2 texelCoord){
GbufferData data;
vec4 gbuffer2 = texelFetch(colortex2, texelCoord, 0);
vec4 gbuffer3 = texelFetch(colortex3, texelCoord, 0);
data.albedo = GammaToLinear(texelFetch(colortex0, texelCoord, 0).rgb);
data.albedoAlpha = 1.0;
data.worldNormal = DecodeNormal(texelFetch(colortex1, texelCoord, 0).xy);
data.vertexNormal = DecodeNormal(texelFetch(colortex1, texelCoord, 0).zw);
data.lightmap = gbuffer3.xy;
data.materialID = gbuffer2.a;
data.parallaxShadow = gbuffer3.b;
vec4 specTex = vec4(gbuffer2.r, gbuffer2.g, gbuffer2.b, 0.0);
data.material = MaterialFromTex(specTex);
return data;
}
// Read translucent GBuffer data
GbufferData GetGbufferDataTranslucent(ivec2 texelCoord, out bool isSmooth){
GbufferData data;
vec4 gbuffer5 = texelFetch(colortex5, texelCoord, 0);
vec4 gbuffer6 = texelFetch(colortex6, texelCoord, 0);
data.worldNormal = DecodeNormal(gbuffer6.xy);
data.vertexNormal = DecodeNormal(gbuffer6.zw);
data.lightmap = texelFetch(colortex7, texelCoord, 0).xy;
data.materialID = gbuffer6.a;
data.parallaxShadow = 1.0;
isSmooth = false;
if (data.materialID == MATID_WATER){
data.albedo = GammaToLinear(gbuffer5.rgb);
data.albedoAlpha = gbuffer5.a;
data.material = material_water;
isSmooth = true;
}else if (data.materialID == MATID_STAINEDGLASS){
data.albedo = GammaToLinear(gbuffer5.rgb);
data.albedoAlpha = gbuffer5.a;
data.material = material_glass;
isSmooth = true;
}else if (data.materialID == MATID_PARTICLE){
data.albedo = GammaToLinear(gbuffer5.rgb);
data.albedoAlpha = gbuffer5.a;
data.material = material_air;
}else{
data.albedo = GammaToLinear(texelFetch(colortex0, texelCoord, 0).rgb);
data.albedoAlpha = 1.0;
vec4 specTex = vec4(gbuffer2.r, gbuffer2.g, gbuffer2.b, 0.0);
data.material = MaterialFromTex(specTex);
}
return data;
}
// Material mask utilities
struct MaterialMask{
float sky;
float grass;
float leaves;
float hand;
float entityPlayer;
float water;
float stainedGlass;
float lightning;
float entitiesSnow;
float endrod;
float fire;
float torch;
float lightSource;
float redstoneTorch;
float soulTorch;
float amethyst;
float particle;
float endPortal;
float selection;
};
MaterialMask CalculateMasks(float materialIDs){
MaterialMask mask;
mask.sky = float(materialIDs == MATID_SKY);
mask.grass = float(materialIDs == MATID_GRASS || materialIDs == MATID_BEACON_BEAM);
mask.leaves = float(materialIDs == MATID_LEAVES);
mask.hand = float(materialIDs == MATID_HAND);
mask.water = float(materialIDs == MATID_WATER);
mask.stainedGlass = float(materialIDs == MATID_STAINEDGLASS);
mask.entityPlayer = float(materialIDs == MATID_ENTITIES_PLAYER);
mask.entitiesSnow = float(materialIDs == MATID_ENTITIES_SNOW || materialIDs == MATID_BEACON_BEAM);
mask.lightning = float(materialIDs == MATID_LIGHTNING);
mask.endrod = float(materialIDs == MATID_ENDROD);
mask.fire = float(materialIDs == MATID_FIRE);
mask.torch = float(materialIDs == MATID_TORCH);
mask.redstoneTorch = float(materialIDs == MATID_REDSTONE_TORCH);
mask.amethyst = float(materialIDs == MATID_AMETHYST);
mask.soulTorch = float(materialIDs == MATID_SOULTORCH || materialIDs == MATID_COPPER_LANTERN);
mask.particle = float(materialIDs == MATID_PARTICLE);
mask.endPortal = float(materialIDs == MATID_END_PORTAL);
mask.selection = float(materialIDs == MATID_SELECTION);
return mask;
}
void ApplyMaterial(inout Material material, in MaterialMask materialMask, inout bool isSmooth){
if (materialMask.water > 0.5){
material = material_water;
isSmooth = true;
}else if (materialMask.stainedGlass > 0.5){
material = material_glass;
isSmooth = true;
}
}
#endif