| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- package arm.node;
- import iron.object.MeshObject;
- import iron.data.SceneFormat;
- import arm.ui.UITrait;
- import arm.ui.UINodes;
- import arm.node.MaterialShader;
- import arm.Tool;
- class MakeMeshPreview {
- public static var opacityDiscardDecal = 0.05;
- public static var opacityDiscardScene = 0.5;
- public static function run(data: MaterialShaderData, matcon: TMaterialContext): MaterialShaderContext {
- var isScene = UITrait.inst.worktab.position == SpaceScene;
- var context_id = "mesh";
- var con_mesh: MaterialShaderContext = data.add_context({
- name: context_id,
- depth_write: true,
- compare_mode: "less",
- cull_mode: (UITrait.inst.cullBackfaces || !isScene) ? "clockwise" : "none",
- vertex_elements: [{name: "pos", data: "short4norm"}, {name: "nor", data: "short2norm"}, {name: "tex", data: "short2norm"}] });
- var vert = con_mesh.make_vert();
- var frag = con_mesh.make_frag();
- frag.ins = vert.outs;
- var pos = "pos";
- #if arm_skin
- var isMesh = Std.is(Context.object, MeshObject);
- var skin = isMesh && cast(Context.object, MeshObject).data.geom.bones != null;
- if (skin) {
- pos = "spos";
- con_mesh.add_elem("bone", 'short4norm');
- con_mesh.add_elem("weight", 'short4norm');
- vert.add_function(MaterialFunctions.str_getSkinningDualQuat);
- vert.add_uniform('vec4 skinBones[128 * 2]', '_skinBones');
- vert.add_uniform('float posUnpack', '_posUnpack');
- vert.write_attrib('vec4 skinA;');
- vert.write_attrib('vec4 skinB;');
- vert.write_attrib('getSkinningDualQuat(ivec4(bone * 32767), weight, skinA, skinB);');
- vert.write_attrib('vec3 spos = pos.xyz;');
- vert.write_attrib('spos.xyz *= posUnpack;');
- vert.write_attrib('spos.xyz += 2.0 * cross(skinA.xyz, cross(skinA.xyz, spos.xyz) + skinA.w * spos.xyz);');
- vert.write_attrib('spos.xyz += 2.0 * (skinA.w * skinB.xyz - skinB.w * skinA.xyz + cross(skinA.xyz, skinB.xyz));');
- vert.write_attrib('spos.xyz /= posUnpack;');
- }
- #end
- vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix');
- vert.write_attrib('gl_Position = mul(vec4($pos.xyz, 1.0), WVP);');
- vert.add_out('vec2 texCoord');
- vert.write_attrib('texCoord = tex;');
- if (MaterialBuilder.heightUsed) {
- frag.bposition = true;
- }
- Material.parse_height = MaterialBuilder.heightUsed;
- var sout = Material.parse(UINodes.inst.getCanvasMaterial(), con_mesh, vert, frag, null, null, null, matcon);
- Material.parse_height = false;
- var base = sout.out_basecol;
- var rough = sout.out_roughness;
- var met = sout.out_metallic;
- var occ = sout.out_occlusion;
- var opac = sout.out_opacity;
- var nortan = Material.out_normaltan;
- frag.write('vec3 basecol = pow($base, vec3(2.2, 2.2, 2.2));');
- frag.write('float roughness = $rough;');
- frag.write('float metallic = $met;');
- frag.write('float occlusion = $occ;');
- frag.write('float opacity = $opac;');
- frag.write('vec3 nortan = $nortan;');
- var decal = UITrait.inst.decalPreview;
- if (decal) {
- if (Context.tool == ToolDecal) {
- frag.add_uniform('sampler2D texdecalmask', '_texdecalmask');
- frag.write('opacity *= textureLod(texdecalmask, texCoord, 0.0).r;');
- }
- else if (Context.tool == ToolText) {
- frag.add_uniform('sampler2D textexttool', '_textexttool');
- frag.write('opacity *= textureLod(textexttool, texCoord, 0.0).r;');
- }
- }
- if (decal || isScene) {
- var opac = isScene ? opacityDiscardScene : opacityDiscardDecal;
- frag.write('if (opacity < $opac) discard;');
- }
- frag.add_out('vec4 fragColor[3]');
- frag.n = true;
- frag.add_function(MaterialFunctions.str_packFloatInt16);
- frag.add_function(MaterialFunctions.str_packFloat2);
- frag.add_function(MaterialFunctions.str_cotangentFrame);
- frag.add_function(MaterialFunctions.str_octahedronWrap);
- // Apply normal channel
- if (decal) {
- // TODO
- }
- else {
- frag.vVec = true;
- #if (kha_direct3d11 || kha_direct3d12)
- 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('n /= (abs(n.x) + abs(n.y) + abs(n.z));');
- frag.write('n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);');
- // uint matid = 0;
- frag.write('fragColor[0] = vec4(n.x, n.y, roughness, packFloatInt16(metallic, uint(0)));'); // metallic/matid
- frag.write('fragColor[1] = vec4(basecol.r, basecol.g, basecol.b, packFloat2(occlusion, 1.0));'); // occ/spec
- frag.write('fragColor[2] = vec4(0.0, 0.0, 0.0, 0.0);'); // veloc
- Material.finalize(con_mesh);
- #if arm_skin
- if (skin) {
- vert.write('wnormal = normalize(mul(vec3(nor.xy, pos.w) + 2.0 * cross(skinA.xyz, cross(skinA.xyz, vec3(nor.xy, pos.w)) + skinA.w * vec3(nor.xy, pos.w)), N));');
- }
- #end
- con_mesh.data.shader_from_source = true;
- con_mesh.data.vertex_shader = vert.get();
- con_mesh.data.fragment_shader = frag.get();
- return con_mesh;
- }
- }
|