@:directlyUsed@:src({
@param var faceMatrix:Mat3;
@param var envMap:SamplerCube;
@const var isSpecular:Bool;
@const var isSRGB:Bool;
@param var roughness:Float;
@param var cubeSize:Float;
@param var cubeScaleFactor:Float;
@param var hdrMax:Float;
function cosineWeightedSampling(p:Vec2, n:Vec3):Vec3 {
var sq = sqrt(1 - p.x);
var alpha = 2 * PI * p.y;
var ltan = vec3(sq * cos(alpha), sq * sin(alpha), sqrt(p.x));
var up = abs(n.z) < 0.999 ? vec3(0, 0, 1) : vec3(1, 0, 0);
var tanX = normalize(cross(up, n));
var tanY = normalize(cross(n, tanX));
return (tanX * ltan.x + tanY * ltan.y + n * ltan.z).normalize();
};
function getNormal():Vec3 {
var d = input.uv * 2. - 1.;
if (isSpecular) {
d += cubeScaleFactor * (d * d * d);
};
return (vec3(d, 1.) * faceMatrix).normalize();
};
function gammaCorrect(color:Vec3):Vec3 {
return isSRGB ? color : color.pow(vec3(2.2));
};
function fragment() {
var color = vec3(0.);
var n = getNormal();
var totalWeight = 1e-10;
var numSamples = 1 << samplesBits;
for (i in 0 ... numSamples) {
var p = hammersley(i, numSamples);
var l:Vec3;
if (isSpecular) {
var h = importanceSampleGGX(roughness, p, n);
var v = n;
l = reflect(-v, h).normalize();
} else {
l = cosineWeightedSampling(p, n);
};
var amount = n.dot(l).saturate();
if (amount > 0) {
var envColor = gammaCorrect(min(envMap.get(l).rgb, hdrMax));
color += envColor * amount;
totalWeight += amount;
};
};
output.color = vec4(color / totalWeight, 1.);
};
})@:build(hxsl.Macros.buildShader())@:autoBuild(hxsl.Macros.buildShader())