HOME | DD

#download #guide #mmd #mme #seeu #shader #hlsl #mikumikudance #mmeデータ配布
Published: 2022-03-04 04:42:54 +0000 UTC; Views: 17545; Favourites: 12; Downloads: 11
Redirect to original
Description
An animation program like MMD is all about changing what appears on the screen. There are two main ways an object loaded into MMD can do this: by using its own data and textures to draw something that replaces what's already on the screen, or by taking what other objects have already drawn and modifying and displaying it in some way.When an effect is doing the first thing, it's called a shader, because the most important way an object's appearance changes is in response to light, which generates shadows and shading. All shaders in MMD are effect files, but not all effects are shaders.
The shader we're looking at isn't even really a shader because it doesn't use light. It just displays basic properties of a model.
Note: there is a Modeler's Shader (bowlroll.net/file/15915 ) that displays a bunch of different versions of a model showing various properties, but I haven't used it. This guide is more about understanding a shader, so you can make it show what you want.
An effect file is processed in the order it's written. Anything with a name must be defined before it can be used. This can be a little confusing, because you see a bunch of things and don't know how they fit together, or even where the shader starts to do things. Generally, a shader sets various variables. Then it defines a vertex shader which runs for every vertex you can see at the intersection of lines in wireframe mode. Then it defines a pixel shader which runs for every pixel that shows up on the screen based on the position of vertices.
But a shader is only run if it belongs to a technique. MMD splits shaders into self-shadow and non-self-shadow techniques. There is also the shadow map technique, called Z-plot, that runs before anything else; the ground shadow technique, that runs before pmd objects; and the edge technique, that runs after an object's main (self-shadow or non) technique. If those aren't defined, MMD uses its built-in versions.
In the effect we're looking at, the non-self-shadow technique has been commented out with the /*[...]*/ characters, so MMD uses its default shader when self-shadow is off, like when you press C to select a bone.
Let's start from the top. The text colors are from the default text editor in Ubuntu, gedit aka Text Editor, which has detected that this is a C-language text file. I can also change it to 'CG Shader Language', which highlights float4x4 but un-highlights the purple text.
Comments are blue, and don't affect processing. Japanese text files should have (and be opened as) Shift-JIS or CP932 encoding, so bone and model names work correctly, in case you open an effect and it has garbled text, but this one doesn't. (If a file path has characters that aren't in the Japanese character set like accents, it won't work at all with MME, while effect files with Japanese names require Japanese locale to be set.)
Variable types:
An effect can define a structure that gives specific names to elements that use the basic variable types, but this one doesn't. So we have
- float (floating point), can be very small or large, including negative. Other values generally get converted to this.
- bool (boolean logic), can be true or false. When converting to a bool, anything other than 0 becomes true; when converting from a bool, true is 1, and false is 0.
- int (integer), whole-number values.
bool and int are generally used when you want to make it clear you don't want fractions. If a number doesn't have a decimal point or an 'f' at the end, it's treated as an integer, which rounds down with division, so (variable + 5/3) is just (variable + 1).
float4 is four different float variables, that can be referred to with x,y,z,w or r,g,b,a (red, green, blue, alpha). float4x4 is a grid, most commonly used for the matrices that transform positions or directions either into a common worldframe, or into a more useful representation (such as so that if a certain position component is below 0, it's behind the camera).
Section 1: matrices. The bit after the colon is a semantic, not a comment. MMD or MME fills in the value of the variable when a technique runs based on the semantic. The WorldMatrix is actually different (flattened) within ground shadow technique, but this shader doesn't deal with that.
Section 2: a control variable, using ":CONTROLOBJECT" semantic. If a string item is not provided, the value supplied depends on the type (bool, float, float3, float4x4) of the variable, with different values for accessories (.x files), but this shader doesn't use this variable right now. When changing the name, the quotation marks are necessary.
Then material properties, using semantics. With other programs, "Ambient" is probably a value that the developer scales up and down and is unrelated to directional lights, but in MMD it gets confused with Emissive and so there are really only three colors, not four.
SpecularPower determines how concentrated the specular reflections are for an object with non-zero MaterialSpecular, but it's also used by AutoLuminous to specify a glowy material.
Section 3: some pre-compiler token things. In some shaders, these are important for turning on or off sections of code when the shader is first loaded, in order to reduce the operations done for every pixel or vertex. With #define , a value is inserted in place of the token name everywhere it appears later in the file.
Section 4: special values that are set automatically, based on their name, despite having no semantics. These are described in the MME Reference. A 'static' variable has some special description, I'm not really sure, but in MMD any variable that depends on another one has to be 'static'. Since the compiler optimizes things, I don't think defining a 'static' variable has any particular benefit other than making an effect file shorter and easier to understand.
The parentheses are because I copied it from within the pixel shader, where it needed them. Having a separate variable can sometimes help because it can describe what some math does, even if the name is abbreviated. "!" means Not for logic; it converts a 0 into 1 and any non-zero value should be treated as 1 and get converted to 0. I try to be careful about using it because I found some buggy behavior with it in the past.
"&&" means And for logic: the expression is true only if "Not spadd" is true and use_spheremap is also true. That is, spheres are in use but the value from the sphere isn't added to the existing color (increasing it), but is instead multiplied (reducing it, since the brightest sphere color is 1). When the shader runs for a material, before the first vertex it will check these values and then provide the result to the hardware units that run for each vertex or pixel. (Occasionally, some matrix operations don't appear to be optimized correctly this way.)
Section 5: MATERIALTEXTURE is another semantic. MME actually uses certain sampler registers in MMD, and if you register the shadow map sampler wrong this can be wrong as well, but it works here. First we define the texture, which is whatever the pmd or x file says. Mip levels are reduced sizes of a texture, effectively blurred together, that are used for distant objects so small motions or screen distances don't cause huge changes in the sampled texture value. They are why textures often have sizes that are a power of 2, since with any other size the middle of a texture eventually stops getting blurred with smaller mip levels.
The sampler is what a shader actually reads from. Some effects, more commonly the second type that includes post-effects, will specify a texture as a writing target in a technique's script, but we don't.
"texture =
"#if PROCESS_ALL_IN_LINEAR_LIGHT" is another pre-compiler token, copied from a different effect. Since we haven't made it True, it evaluates to False. "#ifdef " can also be used, but a value of 0 or 1 can allow for more compact conditional processing representations. If it were true here, sRGBTexture would mean we convert from an sRGB colorspace, where any given range of light values, as represented by numbers, is sort of squished towards a certain value, to one where a number is linear with the amount of light. This makes typical color values smaller. The artistic design in MMD isn't tuned to use linear math, but it makes things like specular reflections on a colored surface, or the blending from a transparent object with things behind it, more realistic.
Parentheses and curly brackets must always match. Indents are frequently used to make it clear where a process or collection of properties starts and ends. Some people make frequent mistakes here. The compiler should give the line number of an error, and a good text editor (like gedit) will tell you the line number and column of the cursor position.
Finally, after defining everything that the shaders use, we come to the shaders. (The original Stealth.fx has nothing before pixel shader, because it doesn't use anything.)
Section 6: the vertex shader. The "VS" stands for Vertex Shader by convention, but the only way to be sure is because, later on, it's listed in the pass of the technique as "VertexShader = compile vs_2_0 VS_Stealth". If you can't double-click to highlight a word, then press Ctrl-F to search, and then Ctrl-G to search forward and another key like Ctrl-Alt-G to search backwards, use a different text editor!
This vertex shader starts with 'float4 VS_Stealth(...'. The float4 is the return value, which we must provide with 'return' in the function body. At the end of the matching parenthesis, we have ') : POSITION'. With the colon, this is another semantic. It means the float4 represents the final position for the vertex the shader is running for.
Inside the parentheses are the arguments. A shader differs from other functions in that things have semantics. Normally when calling a function you provide a parameter for each argument (or maybe an argument for each parameter), but in the technique we just describe 'VS_Stealth()', with no arguments. This is because semantics automatically provide a value, based on whatever the model creator set and (for pmd models) bone movements and so on.
A vertex shader is required to provide a position for its vertex; every other input and output is optional. The keyword 'out' before a variable type means a variable is initialized in the shader or function and that value can be used elsewhere. The 'return' keyword is for the main value; not sure if other values can still be modified after the 'return'. If you want to provide multiple values, the alternative is with a structure that holds all the values. Since the structure can be named anything, something that looks confusing might be a structure, and you could try searching upwards for that word.
Vertex shader parameters:
float4 Pos : POSITION
~ XYZ in 3D space, and the last number is a 1 due to how transformation matrices work. If you use 0 as the last number, matrices won't change the position of an arbitrary vector with respect to the origin (0,0,0), only rotation.
~ for accessories, this provided position is always the same no matter where the object is (the position is in Object space) and we change it to a common reference frame using the world matrix.
~ for pmd, position changes based on bone movements including ones like Center, All Parents, and outside parent registration, and world matrix does nothing.
~ edge and ground shadow techniques modify position before it reaches vertex shader.
float2 Tex : TEXCOORD0
~ main texture coordinate for a vertex. Instead of specifying this as 'inout' and passing it directly, we combine it to save space as practice.
float3 Normal : NORMAL
~ supposed to generally point outwards from a face. For pmd, has already been rotated from original value.
out float4 TexSph : TEXCOORD0
~ we're combining two float2 output values into a float4, because (maybe depending on shader model) you can only interpolate around eight values, and this frees up a slot. We use TEXCOORD0, but it could also be COLOR0 with the same result here.
out float3 outNormal : TEXCOORD1
~ Vertex shader can have NORMAL semantic input but not output so we needed a different name.
Along with the main, float4 POSITION that comes from 'return', these out values get passed to the pixel shader, regardless of whether or not it uses them. They're calculated for each vertex, then the pixel receives an interpolated value in-between the vertices on each side of it.
So the value of outNormal for the pixels next to a vertex are all very close to that vertex's value, instead of following the accurate physical representation where they might all point away like on the three sides of the corner of a cube. This smooth distribution means that lighting calculations based on these normals don't show a sharp boundary.
At least, that's true if every time a vertex is used, it has the same normal. You can make it use different normals to get a sharp-looking edge.
'mul' is a special form of multiplication using matrices. Unlike arithmetic with single numbers, order matters. With '(float3x3)', we cast the float4x4 matrix as a different value. Casting can either simplify an array of variables or duplicate a variable to create an array. What we do here, multiplying a float3 by float3x3, is the same as multiplying a float4 with a 0 at the end by the original, float4x4 matrix. As mentioned above, this only changes the normal if it's an accessory (x file).
The second mul(), with TexSph.zw, is for sphere map. Once again, with 3x3, we are rotating a vector around the origin. Normals are a vector pointing away from a vertex or pixel, and we use that starting point as (0,0,0) because the normal's direction is relative to it both before and after the normal is rotated.
The orientation after applying ViewMatrix is what we see when the final result is drawn to the screen. If the camera is tilted to the left, what was previously upwards is now to the right. In the center of the screen is View space coordinates XY = 0. To the right is positive X and upwards is positive Y. Spheremap is from mapping these directions directly onto the spheremap file. Positive Y with ViewMatrix is towards the top of the spheremap, while positive X is its right side. Normals are supposed to have a length of 1, and the set of all rays with length 1 is a sphere.
'.xy' is called a swivel or something. X and Y are the first two values in the float3 that results from mul(float3,float3x3); we discard the third, Z value. Essentially, we are squishing the set of outcomes that form a sphere into a circle, with the endpoint anywhere within that circle. If the normal was pointing directly towards the camera, the endpoint ends up at the center of the spheremap.
This math converts the screen coordinates, from [-1,1] bottom to top, into texture coordinates, [0,1] from top to bottom: '* float2(0.5,-0.5) + 0.5'. The first 0.5 applies to the X value, the -0.5 to the Y value, and then both get the +0.5. With this [0,1] range, X is known as U and Y is known as V.
WorldViewProjMatrix combines three matrix operations, which must be done in order and are normally done for every vertex. Otherwise, a vertex won't move properly on the screen as the camera moves and rotates.
Section 7: the pixel shader. The code for shaders is self-contained, and the pixel shader doesn't have to be next to its vertex shader. Once again, we have an output value or (rarely) structure for the pixel shader, and input values from the vertex shader. There are a few other possible semantics that we won't look at here.
The input values are based on the semantics. The names don't have to match, as we see with outNormal becoming Normal, and many shaders have an output structure called Out (with no semantic) that becomes an input called IN. For variables without a semantic, variable type and order is used and has to match.
The COLOR semantic (capitalization doesn't matter) is required for pixel shader, just as Position is for vertex, and I suppose that's a clue as to what they are.
The first thing we do is use tex2D. As another built-in function, this has a specific form and requirements, which can be found online. There are other versions of this function, like tex2Dlod for level-of-detail; this one automatically selects a miplevel (if available) by computing four pixels at a time and finding the difference in sample location.
There is no benefit to reusing the names of variables. The compiler has no qualms about putting data in a register no matter what you call it.
With SphColor, the TexSph.zw that we calculated in vertex shader and interpolated for this pixel is the 3rd and 4th components, equal to TexSph.ba (blue, alpha). So if you specify Color = float4(0.1,0.2,0.3,1), Color.a = Color.w = 1.
Although the sphere coordinate should always be within a circle, the tex coordinate could potentially be far outside the [0,1] range. Since we specified Wrap, the texture would repeat.
The next part is commented out, just like the non-self-shadow technique below it. If any of these lines are moved outside of the comment block, the first 'return' is used.
This is a conditional test: 'Value ? result if true : result if false'. We have '1' as the value here, which is always true, but you can switch it to 0 to use the second form, where the Normal's range of [-1,1] has been compressed to [0,1], which is all displayed in the output color range instead of the bottom half being black.
float4(...) means the values inside are combined into a float4 array. Pay attention to the type of each part. Normal is float3, from the shader arguments, while the final 1 is an integer that we automatically convert to a float. The last number in this color is the alpha, with 0 being completely transparent and 1 being opaque.
With float4(TexSph.xy, use_texture, 1), we use texture XY as the red and green, and the flag for whether or not the material uses a texture as blue. If the texture is specified but the file wasn't found (including screen.bmp with nothing to show), this parameter remains at 0 (false), so no blue. From this, we can see that even if a material has no texture, it can still have texture coordinates, which is useful for effects that need these coordinates, like normal maps.
The return value with the COLOR semantic is then drawn to the screen; possibly an offcreen render target that is then accessed by some other effect.
Section 8: techniques. In the self-shadow technique that we have on, the 'AlphaTestEnable = false' render state makes it so that even if a pixel's alpha is 0, it still gets drawn to the screen. It updates the depth buffer when it does this, which prevents any pixels at a more distant depth from being drawn after it. This is why with the 'use_texture ? TexColor : 0' output, SeeU's body, which is drawn first, prevents her hair from being drawn behind it afterwards.
Along with self-shadow vs non-self-shadow, MMD selects a technique to use for the main drawing step using several criteria. If spheremaps, toon (used by all pmd and no x files), or texture is specified for a technique, MMD will use the technique that matches a material. This leads to 2*2*2*2 = 16 techniques in the default shader and many other shaders, although a few combinations (accessories with both texture and sphere) might not be possible. Since we don't specify whether our technique uses any of these, MMD uses it for all materials with self-shadow enabled. Each technique increases compile time.
Apparently vs and ps _1_0 are an option (it didn't break this super-simple shader), but not sure how they differ from 2_0. If a shader is complex, it may require 3_0, which older or more basic hardware might not support. My computer with a dedicated GPU is from 2009 and supports at least 3_0.
Unusual properties of SeeU
Starting from left and going clockwise. China dress Seeu's body doesn't use any textures!
China dress SeeU's body skin's relative brightness is a lot higher for Emissive, which normally doesn't change with light, than with Ambient. It actually doesn't match her face, which is a little bit sloppy. But the other two models also don't use the 1.0 Ambient, 0.5 Emissive that a lot of models have now.
SeeU uses specular, which is so rare (maybe because it's harder to tune and looks a little weird without linear light processing).
Part of China dress SeeU's dress, and White Tiger SeeU's shoes and head accessories, don't use a texture but still provide texture coordinates.
Original and White Tiger SeeU use sphere multiply to darken their skirts at grazing angles.
Original and White Tiger SeeU have significant sphere add on hair, but it's missing from China dress SeeU.
Toon colors that aren't gray and also don't match the hue of the main color that they modify.
That's it. I hope this guide was of help.
SeeU was illegally downloaded despite not having purchased the Windows 100% magazine where she was included. Don't download from here:
Original SeeU: tstorage.info/46efyvuj3g1l
White Tiger SeeU: tstorage.info/6xf8xrnhianr
China dress SeeU: tstorage.info/3ctijqgnzmeb
Stage: ジュエルハートステージ by 一護牛乳
seiga.nicovideo.jp/seiga/im101…
Sofa (Sofa_(WM_g).pmx) and giant pillow (クッション(ブルーc).pmx), from ソファと椅子v1.2:
seiga.nicovideo.jp/seiga/im320…
Made the pillow giant by entering large values for expression slider, like 10 (have to type it in).
Glass shader for crystal: released with many other effects by creator of MME in a video that's too hard to find, but included.
Panel with bevel: Effect/AdultShader_v014/specialized/Panel/Panel_1.6_ratio_bevel.x
Floor mirror: Effect/AdultShader_v014/specialized/Looking_glass.fx, must change PREFER_LINEAR_OUTPUT_TO_FLOAT_TEXTURE to 0 if using with post-effects.
THIS TEST SHADER: Effect/AdultShader_v014/testing/display info/Show simple properties.fx
The 'painting' was from turning on screen capture, then turning it off and changing camera angle. It isn't working with fake camera yet even though the most basic version probably only requires changing about two lines of mirror parent effect.
Almost used: A Large TV by Melissa
seiga.nicovideo.jp/seiga/im768…
Poses: いろいろ撮影ポーズ by KEITEL
seiga.nicovideo.jp/seiga/im916…
MME Reference in English: pastebin.com/ar63p8jk
How I got MME working on GNU/Linux with Wine (maybe outdated): pastebin.com/c7GpQ0tm
Time spent on this: 12 hours
Expectation of figuring out why some materials don't seem to care about math when it comes to self-shadows: low, but I'm delaying anyway