Initial commit: Minecraft 光追着色器包(从零实现的 path tracing)
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user