99 lines
2.2 KiB
Plaintext
99 lines
2.2 KiB
Plaintext
|
|
#[set(everything)]
|
|
const constants: {
|
|
N: float3x3;
|
|
WVP: float4x4;
|
|
tex_unpack: float;
|
|
};
|
|
|
|
struct vert_in {
|
|
pos: float4;
|
|
nor: float2;
|
|
tex: float2;
|
|
}
|
|
|
|
struct vert_out {
|
|
pos: float4;
|
|
tex: float2;
|
|
wnormal: float3;
|
|
}
|
|
|
|
fun mesh_posnortex_vert(input: vert_in): vert_out {
|
|
var output: vert_out;
|
|
output.pos = constants.WVP * float4(input.pos.xyz, 1.0);
|
|
output.tex = input.tex * constants.tex_unpack;
|
|
output.wnormal = normalize(constants.N * float3(input.nor.xy, input.pos.w));
|
|
return output;
|
|
}
|
|
|
|
fun octahedron_wrap(v: float2): float2 {
|
|
var a: float2;
|
|
if (v.x >= 0.0) {
|
|
a.x = 1.0;
|
|
}
|
|
else {
|
|
a.x = -1.0;
|
|
}
|
|
|
|
if (v.y >= 0.0) {
|
|
a.y = 1.0;
|
|
}
|
|
else {
|
|
a.y = -1.0;
|
|
}
|
|
|
|
var r: float2;
|
|
r.x = abs(v.y);
|
|
r.y = abs(v.x);
|
|
r.x = 1.0 - r.x;
|
|
r.y = 1.0 - r.y;
|
|
return r * a;
|
|
|
|
// return (1.0 - abs(v.yx)) * (float2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
|
|
}
|
|
|
|
fun pack_f32_i16(f: float, i: uint): float {
|
|
// GBuffer helper - Sebastien Lagarde
|
|
// https://seblagarde.wordpress.com/2018/09/02/gbuffer-helper-packing-integer-and-float-together/
|
|
// const num_bit_target: int = 16;
|
|
// const num_bit_i: int = 4;
|
|
// const prec: float = float(1 << num_bit_target);
|
|
// const maxi: float = float(1 << num_bit_i);
|
|
// const prec_minus_one: float = prec - 1.0;
|
|
// const t1: float = ((prec / maxi) - 1.0) / prec_minus_one;
|
|
// const t2: float = (prec / maxi) / prec_minus_one;
|
|
// return t1 * f + t2 * float(i);
|
|
return 0.062504762 * f + 0.062519999 * float(i);
|
|
}
|
|
|
|
fun mesh_posnortex_frag(input: vert_out): float4[3] {
|
|
var n: float3 = normalize(input.wnormal);
|
|
var basecol: float3 = float3(0.2, 0.2, 0.2) + input.tex.x * 0.0000001; // keep tex_coord
|
|
var roughness: float = 0.4;
|
|
var metallic: float = 0.0;
|
|
var occlusion: float = 1.0;
|
|
|
|
// n /= abs(n.x) + abs(n.y) + abs(n.z);
|
|
n = (n / abs(n.x) + abs(n.y) + abs(n.z));
|
|
if (n.z >= 0.0) {
|
|
n.xy = n.xy;
|
|
}
|
|
else {
|
|
n.xy = octahedron_wrap(n.xy);
|
|
}
|
|
|
|
// var matid: uint = 0;
|
|
var matid: uint = uint(0.0);
|
|
var color: float4[3];
|
|
color[0] = float4(n.xy, roughness, pack_f32_i16(metallic, matid));
|
|
color[1] = float4(basecol, occlusion);
|
|
color[2] = float4(0.0, 0.0, 0.0, 0.0);
|
|
return color;
|
|
}
|
|
|
|
#[pipe]
|
|
struct pipe {
|
|
vertex = mesh_posnortex_vert;
|
|
fragment = mesh_posnortex_frag;
|
|
}
|