166 lines
7.4 KiB
Haxe
166 lines
7.4 KiB
Haxe
package arm.node;
|
|
|
|
import arm.ui.UISidebar;
|
|
import arm.shader.NodeShader;
|
|
import arm.shader.NodeShaderContext;
|
|
import arm.shader.NodeShaderData;
|
|
import arm.shader.ShaderFunctions;
|
|
import arm.shader.MaterialParser;
|
|
import arm.Enums;
|
|
|
|
class MakeBake {
|
|
|
|
public static function run(con: NodeShaderContext, vert: NodeShader, frag: NodeShader) {
|
|
if (Context.bakeType == BakeAO) { // Voxel
|
|
#if rp_voxelao
|
|
// Apply normal channel
|
|
frag.wposition = true;
|
|
frag.n = true;
|
|
frag.vVec = true;
|
|
frag.add_function(ShaderFunctions.str_cotangentFrame);
|
|
#if kha_direct3d11
|
|
frag.write('mat3 TBN = cotangentFrame(n, vVec, texCoord);');
|
|
#else
|
|
frag.write('mat3 TBN = cotangentFrame(n, -vVec, texCoord);');
|
|
#end
|
|
frag.write('n = nortan * 2.0 - 1.0;');
|
|
frag.write('n.y = -n.y;');
|
|
frag.write('n = normalize(mul(n, TBN));');
|
|
|
|
frag.write(MakeMaterial.voxelgiHalfExtents());
|
|
frag.write('vec3 voxpos = wposition / voxelgiHalfExtents;');
|
|
frag.add_uniform('sampler3D voxels');
|
|
frag.add_function(ShaderFunctions.str_traceAO);
|
|
frag.n = true;
|
|
var strength = Context.bakeAoStrength;
|
|
var radius = Context.bakeAoRadius;
|
|
var offset = Context.bakeAoOffset;
|
|
frag.write('float ao = traceAO(voxpos, n, $radius, $offset) * $strength;');
|
|
if (Context.bakeAxis != BakeXYZ) {
|
|
var axis = axisString(Context.bakeAxis);
|
|
frag.write('ao *= dot(n, $axis);');
|
|
}
|
|
frag.write('ao = 1.0 - ao;');
|
|
frag.write('fragColor[0] = vec4(ao, ao, ao, 1.0);');
|
|
#end
|
|
}
|
|
else if (Context.bakeType == BakeCurvature) {
|
|
var pass = MaterialParser.bake_passthrough;
|
|
var strength = pass ? MaterialParser.bake_passthrough_strength : Context.bakeCurvStrength + "";
|
|
var radius = pass ? MaterialParser.bake_passthrough_radius : Context.bakeCurvRadius + "";
|
|
var offset = pass ? MaterialParser.bake_passthrough_offset : Context.bakeCurvOffset + "";
|
|
frag.n = true;
|
|
frag.write('vec3 dx = dFdx(n);');
|
|
frag.write('vec3 dy = dFdy(n);');
|
|
frag.write('float curvature = max(dot(dx, dx), dot(dy, dy));');
|
|
frag.write('curvature = clamp(pow(curvature, (1.0 / ' + radius + ') * 0.25) * ' + strength + ' * 2.0 + ' + offset + ' / 10.0, 0.0, 1.0);');
|
|
if (Context.bakeAxis != BakeXYZ) {
|
|
var axis = axisString(Context.bakeAxis);
|
|
frag.write('curvature *= dot(n, $axis);');
|
|
}
|
|
frag.write('fragColor[0] = vec4(curvature, curvature, curvature, 1.0);');
|
|
}
|
|
else if (Context.bakeType == BakeNormal) { // Tangent
|
|
frag.n = true;
|
|
frag.add_uniform('sampler2D texpaint_undo', '_texpaint_undo'); // Baked high-poly normals
|
|
frag.write('vec3 n0 = textureLod(texpaint_undo, texCoord, 0.0).rgb * vec3(2.0, 2.0, 2.0) - vec3(1.0, 1.0, 1.0);');
|
|
frag.add_function(ShaderFunctions.str_cotangentFrame);
|
|
frag.write('mat3 invTBN = transpose(cotangentFrame(n, n, texCoord));');
|
|
frag.write('vec3 res = normalize(mul(n0, invTBN)) * vec3(0.5, 0.5, 0.5) + vec3(0.5, 0.5, 0.5);');
|
|
frag.write('fragColor[0] = vec4(res, 1.0);');
|
|
}
|
|
else if (Context.bakeType == BakeNormalObject) {
|
|
frag.n = true;
|
|
frag.write('fragColor[0] = vec4(n * vec3(0.5, 0.5, 0.5) + vec3(0.5, 0.5, 0.5), 1.0);');
|
|
if (Context.bakeUpAxis == BakeUpY) {
|
|
frag.write('fragColor[0].rgb = vec3(fragColor[0].r, fragColor[0].b, 1.0 - fragColor[0].g);');
|
|
}
|
|
}
|
|
else if (Context.bakeType == BakeHeight) {
|
|
frag.wposition = true;
|
|
frag.add_uniform('sampler2D texpaint_undo', '_texpaint_undo'); // Baked high-poly positions
|
|
frag.write('vec3 wpos0 = textureLod(texpaint_undo, texCoord, 0.0).rgb * vec3(2.0, 2.0, 2.0) - vec3(1.0, 1.0, 1.0);');
|
|
frag.write('float res = distance(wpos0, wposition) * 10.0;');
|
|
frag.write('fragColor[0] = vec4(res, res, res, 1.0);');
|
|
}
|
|
else if (Context.bakeType == BakeDerivative) {
|
|
frag.add_uniform('sampler2D texpaint_undo', '_texpaint_undo'); // Baked height
|
|
frag.write('vec2 texDx = dFdx(texCoord);');
|
|
frag.write('vec2 texDy = dFdy(texCoord);');
|
|
frag.write('float h0 = textureLod(texpaint_undo, texCoord, 0.0).r * 100;');
|
|
frag.write('float h1 = textureLod(texpaint_undo, texCoord + texDx, 0.0).r * 100;');
|
|
frag.write('float h2 = textureLod(texpaint_undo, texCoord + texDy, 0.0).r * 100;');
|
|
frag.write('fragColor[0] = vec4((h1 - h0) * 0.5 + 0.5, (h2 - h0) * 0.5 + 0.5, 0.0, 1.0);');
|
|
}
|
|
else if (Context.bakeType == BakePosition) {
|
|
frag.wposition = true;
|
|
frag.write('fragColor[0] = vec4(wposition * vec3(0.5, 0.5, 0.5) + vec3(0.5, 0.5, 0.5), 1.0);');
|
|
if (Context.bakeUpAxis == BakeUpY) {
|
|
frag.write('fragColor[0].rgb = vec3(fragColor[0].r, fragColor[0].b, 1.0 - fragColor[0].g);');
|
|
}
|
|
}
|
|
else if (Context.bakeType == BakeTexCoord) {
|
|
frag.write('fragColor[0] = vec4(texCoord.xy, 0.0, 1.0);');
|
|
}
|
|
else if (Context.bakeType == BakeMaterialID) {
|
|
frag.add_uniform('sampler2D texpaint_nor_undo', '_texpaint_nor_undo');
|
|
frag.write('float sample_matid = textureLod(texpaint_nor_undo, texCoord, 0.0).a + 1.0 / 255.0;');
|
|
frag.write('float matid_r = fract(sin(dot(vec2(sample_matid, sample_matid * 20.0), vec2(12.9898, 78.233))) * 43758.5453);');
|
|
frag.write('float matid_g = fract(sin(dot(vec2(sample_matid * 20.0, sample_matid), vec2(12.9898, 78.233))) * 43758.5453);');
|
|
frag.write('float matid_b = fract(sin(dot(vec2(sample_matid, sample_matid * 40.0), vec2(12.9898, 78.233))) * 43758.5453);');
|
|
frag.write('fragColor[0] = vec4(matid_r, matid_g, matid_b, 1.0);');
|
|
}
|
|
else if (Context.bakeType == BakeObjectID) {
|
|
frag.add_uniform('float objectId', '_objectId');
|
|
frag.write('float obid = objectId + 1.0 / 255.0;');
|
|
frag.write('float id_r = fract(sin(dot(vec2(obid, obid * 20.0), vec2(12.9898, 78.233))) * 43758.5453);');
|
|
frag.write('float id_g = fract(sin(dot(vec2(obid * 20.0, obid), vec2(12.9898, 78.233))) * 43758.5453);');
|
|
frag.write('float id_b = fract(sin(dot(vec2(obid, obid * 40.0), vec2(12.9898, 78.233))) * 43758.5453);');
|
|
frag.write('fragColor[0] = vec4(id_r, id_g, id_b, 1.0);');
|
|
}
|
|
else if (Context.bakeType == BakeVertexColor) {
|
|
if (con.allow_vcols) {
|
|
con.add_elem("col", "short4norm");
|
|
frag.write('fragColor[0] = vec4(vcolor.r, vcolor.g, vcolor.b, 1.0);');
|
|
}
|
|
else {
|
|
frag.write('fragColor[0] = vec4(1.0, 1.0, 1.0, 1.0);');
|
|
}
|
|
}
|
|
}
|
|
|
|
public static function positionAndNormal(vert: NodeShader, frag: NodeShader) {
|
|
vert.add_out('vec3 position');
|
|
vert.add_out('vec3 normal');
|
|
vert.add_uniform('mat4 W', '_worldMatrix');
|
|
vert.write('position = vec4(mul(vec4(pos.xyz, 1.0), W)).xyz;');
|
|
vert.write('normal = vec3(nor.xy, pos.w);');
|
|
vert.write('vec2 tpos = vec2(tex.x * 2.0 - 1.0, (1.0 - tex.y) * 2.0 - 1.0);');
|
|
vert.write('gl_Position = vec4(tpos, 0.0, 1.0);');
|
|
frag.add_out('vec4 fragColor[2]');
|
|
frag.write('fragColor[0] = vec4(position, 1.0);');
|
|
frag.write('fragColor[1] = vec4(normal, 1.0);');
|
|
}
|
|
|
|
public static function setColorWrites(con_paint: NodeShaderContext) {
|
|
// Bake into base color, disable other slots
|
|
con_paint.data.color_writes_red[1] = false;
|
|
con_paint.data.color_writes_green[1] = false;
|
|
con_paint.data.color_writes_blue[1] = false;
|
|
con_paint.data.color_writes_alpha[1] = false;
|
|
con_paint.data.color_writes_red[2] = false;
|
|
con_paint.data.color_writes_green[2] = false;
|
|
con_paint.data.color_writes_blue[2] = false;
|
|
con_paint.data.color_writes_alpha[2] = false;
|
|
}
|
|
|
|
static function axisString(i:Int):String {
|
|
return i == BakeX ? "vec3(1,0,0)" :
|
|
i == BakeY ? "vec3(0,1,0)" :
|
|
i == BakeZ ? "vec3(0,0,1)" :
|
|
i == BakeMX ? "vec3(-1,0,0)" :
|
|
i == BakeMY ? "vec3(0,-1,0)" :
|
|
"vec3(0,0,-1)";
|
|
}
|
|
}
|