Larian Banner: Baldur's Gate Patch 9
Previous Thread
Next Thread
Print Thread
Joined: Apr 2013
N
Norbyte Offline OP
addict
OP Offline
addict
N
Joined: Apr 2013
Part 0: Material UI Short Overview

You can open the material editor by clicking on the blue sphere icon in the editor toolbar; it should look like this:
[Linked Image]

1. This pane displays a list of placeable nodes/operations; each node has a different function that we'll explain later. You can place any of them in the graph by dragging them to the "Node Graph" panel.
2. The numbers in the top left corner are performance counters for Vertex Shader instructions, Pixel Shader instructions, Vertex Shader texture samplers, Pixel Shader texture samplers and Shader constants. Green = good, Yellow = a bit performance intensive, Orange = even more performance intensive, Red = performance hog!
3. This is the node graph area where you'll work with the nodes in the material.
Clicking on a node highlights it and displays the properties of the node in the Node Properties pane; allows you to drag it anywhere in the scene.
Right clicking drags the whole scene instead of a node.
To connect two ports (the gray dots in the nodes), simply click on a port and start dragging the mouse to another port.

[Linked Image]
Each node can have multiple inputs (ports on the right side of the node), and outputs (ports on the left side).
One input port can only have on output connected to it, but one output can feed multiple inputs.

4. Here you can view and edit the properties of the node you've selected.
5. This is the preview pane that'll show you a preview (duh) of what the material you've created looks like.

Joined: Apr 2013
N
Norbyte Offline OP
addict
OP Offline
addict
N
Joined: Apr 2013
Part 1: Playing with colors and properties

[Linked Image]

The "Material" node is the main output node of a material.
You can describe the visual look of the scene (from colors to transparency/opacity and position) by passing various parameters to its output ports.

When none of the outputs are connected, our material is pitch black as it reflects no light at all:
[Linked Image]

1) Let's start by giving our material a diffuse color.
The diffuse color defines how much of the light received by the object is reflected *in all directions*.
  • Place a "Vector 3 (3)" node by dragging it to the node graph from the Nodes pane.
    We need a 3-component vector because graphics engines internally handle colors as vectors with 3 components: Red, Green and Blue.
    A (0, 0, 0) diffuse color is completely dark - reflects 0% of the light, whereas a (1, 1, 1) color reflects all light.
    Similarly, a (1, 0, 0) color reflects all light received in the Red channel, and doesn't reflect any light in the Green and Blue channels.
    There are transitions too, such as (0, 0.3, 0), that reflects 30% of the Blue light.
  • Assign a color to the Vector by selecting it, then selecting the ColorValue in the Properties pane, clicking "..." and selecting a color value.
  • Connect the output of the Vector to the Diffuse input of the Material.

The resulting node graph and preview material should look something like this:
[Linked Image]
[Linked Image]

Our sphere now has a color that is the same on all sides, independently of view angle and rotation.


2) Let's proceed by giving it a Specular color too.
(We'll skip the Emissive output for now as its effects are not that spectacular without textures, but we'll do cool stuff with it later :))
Specular color represents how much of the incoming light reflects in a directional manner. The specular response is brightest when your eye lines up with the direction of the reflected incoming light, so specular is view dependent.
  • Place another "Vector 3" node and assign it a color, similarly to the previous example.
    Make sure that the Specular color is different than the Diffuse color otherwise you won't see any specular highlight.
  • Connect the output of the Vector to the Specular input of the Material.

Result:
[Linked Image]
[Linked Image]

The sphere color now depends on the view angle, and will look brighter in the spots where it reflects directional light towards the viewer.

3) The Specular Power controls how shiny or glossy the surface is. A very high specular power represents a mirror-like surface while a lower power represents a rougher surface.
Unlike the Diffuse and Specular outputs, the Specular Power output needs a single value, not a vector, so let's place a "Float (1)" node, connect it to the Specular Power output and experiment with its values.
[Linked Image]

Preview of the material with Specular Power values of 1, 10 and 50:
[Linked Image]
[Linked Image]
[Linked Image]

Reflection: I haven't managed to get this output to work yet frown

Joined: Apr 2013
N
Norbyte Offline OP
addict
OP Offline
addict
N
Joined: Apr 2013
4) Opacity determines how much light passes through the surface.
A material with an Opacity of 0 is completely transparent, while an Opacity of 1 is completely opaque. (There are values in between, just like with colors.)

To be able to use the Opacity output, you *MUST* configure the Transparency properties of the Material node properly (click on the Material node and scroll to the Transparency section in the Node Properties pane)
The options are as follows:
  • AlphaTestClipValue: if the Opacity value is below this, the material is completely "transparent" when BlendMode is set to AlphaTest. If BlendMode is not AlphaTest, this value has no effect.
  • BlendMode: Defines how alpha blending is done.
    • None: The Opacity output is not used, the material is completely opaque. This is the default value.
    • AlphaTest: The Opacity output is used for clipping using AlphaTestClipValue. The fragment is either completely opaque (Opacity >= AlphaTestClipValue) or completely transparent (Opacity < AlphaTestClipValue).
    • AlphaBlend: The color of the object is blended with the color "behind" it according to the Opacity value.
      Color = (MyOpacity * MyColor) + ((1 - MyOpacity) * BehindOpacity * BehindColor)
    • Additive: The color of the object is added to the color of the object(s) behind it.
      Color = MyColor + BehindColor


Node graph:
[Linked Image]

Results with Alpha Blending (left) and Additive Blending (right):
[Linked Image]
[Linked Image]


5) Refraction determines how much the surface changes the direction of light waves (think of water).
This takes a single float value as input, just like Opacity: the ratio of the sines of the angle of incidence and angle of refraction.
A list of refractive indices: http://en.wikipedia.org/wiki/List_of_refractive_indices

Example of refraction in action:
[Linked Image]

... to be continued.

Joined: Jul 2014
S
journeyman
Offline
journeyman
S
Joined: Jul 2014
I think i speak for everyone when i say, you are doing Gods work Sir... Thank you!

Joined: Jun 2014
D
dot Offline
journeyman
Offline
journeyman
D
Joined: Jun 2014
well done! Guess it took 5 minutes wink

Joined: Apr 2013
N
Norbyte Offline OP
addict
OP Offline
addict
N
Joined: Apr 2013
Part 2: Texturing and misc stuff

We haven't assigned textures to the material in the previous part to have a better understanding of how different output nodes work, however we can do that now.
As an example, let's (re)create a basic material for a rock, Rock_Common_Big_B.

Instead of simple colors, we'll now use textures and attach their outputs to the material inputs.
  • Add a texture node (called Texures -> Texture2D in the Nodes pane) to the graph.
    The sampler has multiple outputs: RGB is a 3-component color vector, just like the one we've used when specifying colors; the R,G,B and A values are floating point values for Red, Green, Blue and Alpha.
  • The new texture node is initally highlighted in red, with a "Texture2D : No valid texture resource set" error message, as we haven't assigned a texture to it yet.
    To fix this,
    • Select the Rock_Common_Big_B_DM texture in the Resource Browser (make sure that it stays selected!)
    • Select the Texture2D node in the Material Editor
    • Slect the TextureGUID property in the Properties pane of the node
    • Click "..." and click the green "right arrow" button to assign the selected texture resource to the Texture2D node.
    • Connect the RGB output of the texture node to the Diffuse input of the Material node.


Note: You can select the rock as the preview model in the Preview pane of the material editor by selecting the Rock_Common_Big_B model (has a teapot icon) in the Resource Manager window and clicking the Custom button in the Material Preview pane while the resource is selected, but I've only realized this after I've finished the tutorial, so all screenshots will be of spheres instead of a rock smile

If everything is OK, a textured rock should appear (... or a sphere for me :):
[Linked Image]
[Linked Image]

You can determine the type of a texture by looking at its postfix: (eg. _DM for Rock_Common_Big_B_DM):
  • DM: Diffuse Map
  • SM: Specular Map
  • NM: Normal Map
  • GM: Glow Map
  • MSK: Tint Mask

Let's do something a bit more complex than connecting one node to one material output.
A simple thing that we can do with the diffuse rock texture is previewing color channels separately.
To do this, simply connect the R, G, B or A output to the Diffuse material input.

An example of connecting the Red channel to Diffuse:
[Linked Image]
[Linked Image]

... however the preview color - somewhat unexpectedly - is gray, instead of red; why is that?
The reason is that the engine doesn't differentiate between colors when connecting nodes; what it sees is that we gave a single float value (the Red color) to an input that expects a Vector3 value; in this case, the engine "extends" the float value into a Vector3 by copying the same float value to each component of the vector - e.g. 0.3 becomes (0.3,0.3,0.3).

To get a true red color, we need to pass a vector to the Diffuse input with one of the channels (Red) set to the Red color of the texture, and the other channels set to zero (so they don't reflect light).
To do this, we need two additional nodes:
  • The "Combine" node has one output and 4 inputs, although connecting all of them is not necessary.
    The node works by receiving two or more input floats or vectors, and combining them into a single vector.
    Eg. connecting the R, G and B color to the first 3 inputs will combine them into a Vector3 (R,G,B) output.
    Connecting them in a different order, eg. G, B, R, A will result in a (G,B,R,A) Vector4.
    The node can also append vectors; a Vector3 and a float input will result in a Vector4 output.
    The inputs are always appended to each other from the first (top) input to the last (bottom) one in order.
  • After placing a Combine node, let's connect the Red (R) output of the Texture to the first input of the Combine node.
  • We also need to tell the node that the G and B channels are zero (0), otherwise it won't output a Vector3, this is where the "Float (1)" node from the previous tutorial comes in.
    Place a new Float node and connect its output to the second and third (Green and Blue) input of the Combine node (don't connect the fourth one!).
    The float value is 0 by default, no need to change that.
  • Finally, connect the output of the Combine node to the material Diffuse input.
    (This will disconnect the texture and the material from each other.)

The new - this time really red - material:
[Linked Image]
[Linked Image]



We can also increase/reduce the intensity of one or more of the color components (... and do many other wonderful things):
The basic idea is to use a simple combination of the Multiply (or Divide) and the Combine nodes by multiplying one of the color components before passing it on to the Combine node:
  • Add a new Multiply node to the graph.
    Its operation is very simple, it multiplies the input (X, Y) values, so the output becomes X * Y.
    When multiplying colors, a value less than 1 will reduce and larger than one will increase color intensity.
  • Connect a color component of your choice from the Texture node to the Multiply node (doesn't matter if its connected to the X or Y input, the result is the same.)
  • Connect a Float value to the other input of the Multiply node.
  • Connect the output of the Multiply node to the corresponding Combine input (eg. if you're multiplying the Red component then connect it to the firt input, second input for Green, etc.)
  • Connect the other two Texture color outputs to the empty Combine inputs.

Example of multiplying the green component with 0.5 and 1.5:
[Linked Image]
[Linked Image]
[Linked Image]
NOTE: The Diffuse property specifies the % of light reflected in all directions (0.0 = 0%, 1.0 = 100%).
Multiplying the color with a value larger than one, may yield colors that are larger than 1, which means that the surface emits *more* light than it receives.
While the renderer can handle this, this behavior does not occur in real life materials due to the law of conservation of energy, and should be utilized with care!

... Part 3 will have Diffuse/Specular/Normal maps and a blinking Emissive texture!

Joined: Apr 2013
Location: Germany
veteran
Offline
veteran
Joined: Apr 2013
Location: Germany
I just sneaked in to applaud you, dear sir, for your tutorial! smile


WOOS
Joined: Apr 2013
Location: GENT
member
Offline
member
Joined: Apr 2013
Location: GENT
any way to make textures from JPG files?


Join the Weresheep of Original Sin Facebook page! https://www.facebook.com/WeresheepOfOriginalSin
Joined: Apr 2013
N
Norbyte Offline OP
addict
OP Offline
addict
N
Joined: Apr 2013
Originally Posted by Dexyd
any way to make textures from JPG files?


Yup, open up with any image editor that supports DDS export (I use Paint.NET), save your JPEG as DDS and move it to the location you want to use, eg. Data\Public\%myMod%\Assets\Textures\...\something.dds.

Then open the Resource Browser, create a package for your stuff in your mod if you haven't done so, click the Add Resource icon at the top, select Texture, browse to .dds file and give your new texture resource a name.

If you're importing images without an alpha channel, or with an 1-bit alpha channel, save the DDS with DXT1 compression.
If you're using more than 1 bit for the alpha, export as DXT5.
If the DXT compression artifacts are very noticeable (may happen for certain kinds of textures), import as R8B8G8 (no alpha) or A8R8G8B8 (alpha).

Joined: Apr 2013
Location: GENT
member
Offline
member
Joined: Apr 2013
Location: GENT
pfff, sounds hard, I'll wait with that for a while then. :p Thanks for the answer though.


Join the Weresheep of Original Sin Facebook page! https://www.facebook.com/WeresheepOfOriginalSin
Joined: Apr 2013
N
Norbyte Offline OP
addict
OP Offline
addict
N
Joined: Apr 2013
Originally Posted by Dexyd
pfff, sounds hard, I'll wait with that for a while then. :p Thanks for the answer though.


Lazy! :p

Joined: Apr 2013
Location: GENT
member
Offline
member
Joined: Apr 2013
Location: GENT
Man I cant even make a enemy encounter, let alone do complex stuff :p


Join the Weresheep of Original Sin Facebook page! https://www.facebook.com/WeresheepOfOriginalSin
Joined: Apr 2013
N
Norbyte Offline OP
addict
OP Offline
addict
N
Joined: Apr 2013
Part 3: Making it glow!

For this tutorial we'll start with a new, completely blank material.
In he beginning we'll figure out how to make a simple blink effect, combine that with an emissive texture, spice up the result with other textures, and finally refine the effect to make it look a bit more natural.

The materials we've created before were constant materials, they looked exactly the same independently of what time you looked at them.
The blink effect differs from those, as it changes the appearance of the mesh based on the game time.

For this purpose, the editor provides a "Time" node, which has exactly one float output, the current time.
The time value is a monotonically increasing value (for every frame that the game renders it's guaranteed to be larger than it was in the previous frame).

When you connect the Time node to the material color outputs (ie. Diffuse or Emissive) the material will become completely white.
This is because the Time value is so large that all color components will become saturated (> 1.0).
To make the passage of time visible, we'll have to reduce this value somehow.
Since we're trying to implement a blink effect (which can be described as a periodicically dimming and brightening light), we need a node that implements some kind of periodic function.
The functions implemented by the engine (Sine, Cosine, Frac (Sawtooth), Rectangle (Square), TriangleWave nodes) can be summarized in this image:
[Linked Image]

We can see that except for sine and its buddy cosine, all waveforms look "artificial", so we'll use Sine for this tutorial.
(Feel free to experiment with the others though!)

Thus a simple blink effect can be achieved by chaining a Sine and Time node together, and feeding its output to the Diffuse input like this:
[Linked Image]

After this, the material will periodically brighten and dim, however it'll stay completely black for a long period of time.
This is because the range of output values of the Sine wave is [-1, 1] by default, and every color below 0 is black.
To change this, select the Sine node and change its Minimum property to 0 instead of -1.

[Linked Image]

So far we've created a Sine wave illuminates the whole object. To make it only illuminate certain parts we'll need to add a texture that masks out certain parts and defines color values for others; in D:OS these are called glow maps (with _GM at the end of their names) - I'm going to use the HUM_Waypointshrine_Symbol_Earth_A_GM texture in this tutorial.
The desired effect can be achieved by multiplying the output of the Sine wave with the Texture color like this:
[Linked Image]

The result:
[Linked Image]

Now that the blinking part is done we can also connect the usual textures for the material:
Texture node (HUM_Waypointshrine_Symbol_Earth_A_DM) connects to the Diffuse input
Texture node (HUM_Waypointshrine_Symbol_Earth_A_SM) connects to the Specular input
Texture node (HUM_Waypointshrine_Symbol_Earth_A_NM) connects to the Normal input
We're already using HUM_Waypointshrine_Symbol_Earth_A_GM in the blinking part of the material, so let's connect the output of the blinking Multiply node to the Emissive input.

Note: Just like in the previous tutorial, you can select the HUM_Waypointshrine_Symbol_Earth_A mesh as a Custom mesh for the preview pane for extra immersion!

The end result should look like this:
[Linked Image]
[Linked Image]

While the blink effect looks nice, the timing is completely predictable, so let's make it a bit more random.
The current expression we're multiplying the glow texture with is a simple sin(time) function.

To give it the illusion of randomness we'll combine multiple sine/cosine expressions.
There are lots of sine/cosine/multiply/add/clamp/etc. node combinations that'll yield good results, for this tutorial I've just added some sine waves with different periods and tweaked the numbers until it seemed OK.
(Making stuff "look right" is not exactly straightforward, you'll often have to experiment with different values and expressions to get the result you want.)
Google can be very helpful for this, as it'll do a 2D/3D plot for any function you input.
The one we're using is this: sin(time*0.07) * sin(time*0.25) + sin(time*0.5)

Larger multipliers for the Sine function will increase the flickering speed, smaller multipliers will reduce it.
Changing the Min/Max value for the Sine function will affect the intensity of the emitted light; with the default (-1 to 1) range it'll stay completely bright or dark most of the time, while with eg. (-0.1 to 0.4) it'll use intermediate intensity values more frequently.

The resulting material and preview:
[Linked Image]
[Linked Image]

Joined: Jul 2014
journeyman
Offline
journeyman
Joined: Jul 2014
Hey Norbyte, great stuff and very informative. Would you know if there is a node that resembles the material environment? I need a material that is very glossy and would like the sky to be reflected in that.

Joined: Apr 2013
N
Norbyte Offline OP
addict
OP Offline
addict
N
Joined: Apr 2013
The environment cannot be sampled that way as it would be too costly performance-wise (you would have to render the scene multiple times, each time with a different camera location).

The most common workaround for env sampling is called "environment maps" or "reflection maps". For this you usually have to place "taps" to locations where you want to sample the environment and capture it to a cube texture, then use that texture from the material ... however I'm not sure if this is supported in D:OS. At least I haven't found any sign of environment map generation support.

Joined: Jul 2014
journeyman
Offline
journeyman
Joined: Jul 2014
Thanks for the info m8. Yeh I'm still trying to figure out to create a nice looking metal material, maybe some mirror like reflection would be the same thing right, larian has some materials that have true mirror like surfaces:

[Linked Image]

edit 2:
well playing around with the editor and it seemd the fx fortify material from larian produces results I was looking for, these are w/o uv maps so without the larian text. For the Old school scifi look wink
[Linked Image]

Last edited by FromHolland; 19/08/14 02:31 PM.
Joined: Sep 2014
Z
apprentice
Offline
apprentice
Z
Joined: Sep 2014
I am having trouble importing a material into my mod. When I use the editor it saves my graph as a .lsmg but the resource manager tries to find .lsb files. How did you manage to import the material?

Joined: Apr 2013
N
Norbyte Offline OP
addict
OP Offline
addict
N
Joined: Apr 2013
You need to generate materials from the .lsmg to actually use them.
For more details see: http://www.larian.com/forums/ubbthreads.php?ubb=showflat&Number=564303#Post565774

Joined: Oct 2016
Location: Mexíco
D
stranger
Offline
stranger
D
Joined: Oct 2016
Location: Mexíco
Hi, I did a katana 3D model but every time I pass it to the divinity engine 2 all the colors and materials are lost I only get the model with the default material, so how can I use the original materials of the katana in the engine??? Sorry for the newb question and thanks in advance.

Last edited by Driarenem; 29/04/19 09:23 PM.

Wake up to the truth, is the only way to save humanity.
Joined: May 2010
Location: Oxford
Duchess of Gorgombert
Online Sleepy
Duchess of Gorgombert
Joined: May 2010
Location: Oxford
I could never get the materials file to work. In the end I had to choose the closest I could find from those already in game, create a new PBR record (but not referencing a new file) and apply my custom textures, maps and what-not to the new record. Otherwise it was guaranteed I'd either get the default texture or a CTD on load.


J'aime le fromage.

Link Copied to Clipboard
Powered by UBB.threads™ PHP Forum Software 7.7.5