diff --git a/docs/From-Nodes-To-Code/From-Nodes-To-Code.md b/docs/From-Nodes-To-Code/From-Nodes-To-Code.md
index 90d94268..6b64dcdb 100644
--- a/docs/From-Nodes-To-Code/From-Nodes-To-Code.md
+++ b/docs/From-Nodes-To-Code/From-Nodes-To-Code.md
@@ -1,11 +1,12 @@
# From Nodes To Code
+_Last Updated **2025-02-28**_ for Malt release [2b81a03](https://github.com/bnpr/Malt/commit/2b81a03980c41824166b75f39ee5842de2306bcf)
This tutorial will teach you how to make your own *Malt* shaders.
*Malt* shaders are written in *GLSL* (OpenGL Shading Language), the shader programming language used by *OpenGL* and *Vulkan*.
This tutorial assumes you are already familiar with *EEVEE* nodes.
-You may be surprised by how much of your knowledge about node based programming can easily be applied to code and how much more powerfull and convenient can be for advanced tasks.
+You may be surprised by how much of your knowledge about node based programming can easily be applied to code and how much more powerfull and convenient it can be for advanced tasks.
## Before we start
@@ -35,7 +36,7 @@ Now we can make changes in our shader file and as soon as we save it (*Ctrl+S*)
Let's start by looking at some basic *Malt* examples and what would be their *EEVEE* counterparts, so you can see how they compare to each other.
Read the code, but don't worry if you don't really understand it, we will take a more detailed look at it later.
-To get a better feel of it, let's test this examples as we go.
+To get a better feel of it, let's test these examples as we go.
You could just copy-paste them, but you will get a better grasp by typing them yourself.
It will also serve to get familiar with the extra goodies VSCode provides, like code auto-completion.
@@ -48,12 +49,14 @@ Try to play with the examples, modify them, break them on purpose and take a loo
```glsl
-#include "NPR_Pipeline.glsl"
+#include "NPR_MeshShader.glsl"
-void COMMON_PIXEL_SHADER(Surface S, inout PixelOutput PO)
+#ifdef PIXEL_SHADER
+void MAIN_PASS_PIXEL_SHADER()
{
}
+#endif // PIXEL_SHADER
```
@@ -74,14 +77,22 @@ void COMMON_PIXEL_SHADER(Surface S, inout PixelOutput PO)
```glsl
-#include "NPR_Pipeline.glsl"
+#include "NPR_MeshShader.glsl"
-uniform vec3 color = vec3(0,1,0);
+uniform vec4 color = vec4(0,1,0,1);
-void COMMON_PIXEL_SHADER(Surface S, inout PixelOutput PO)
+#ifdef MAIN_PASS
+layout (location = 0) out vec4 OUT_COLOR;
+#endif // MAIN_PASS
+
+#ifdef PIXEL_SHADER
+void MAIN_PASS_PIXEL_SHADER()
{
- PO.color.rgb = color;
+ #ifdef MAIN_PASS
+ OUT_COLOR = color;
+ #endif // MAIN_PASS
}
+#endif // PIXEL_SHADER
```
@@ -95,8 +106,8 @@ void COMMON_PIXEL_SHADER(Surface S, inout PixelOutput PO)
*See how a new color property has appeared in your Material panel?*
-*Could you change the default green value ```vec3(0,1,0)``` in the code to red?*
-*What happens if you set ```vec3(0.5)``` as the default value?*
+*Could you change the default green value ```vec4(0,1,0,1)``` in the code to red?*
+*What happens if you set ```vec4(0.5)``` as the default value?*
> If you have edited a property in the UI, you can always *Right Click > Reset to Defaul Value*
@@ -105,19 +116,41 @@ void COMMON_PIXEL_SHADER(Surface S, inout PixelOutput PO)
```glsl
-#include "NPR_Pipeline.glsl"
+#include "NPR_MeshShader.glsl"
+#include "Node Utils 2/node_utils_2.glsl"
+#include "Node Utils/node_utils.glsl"
+
+#ifdef MAIN_PASS
+layout (location = 0) out vec4 OUT_COLOR;
+#endif // MAIN_PASS
+// set from within blender
+OPTIONALLY_BINDLESS uniform sampler2D color_texture;
uniform int uv_channel = 0;
-uniform sampler2D color_texture;
+uniform bool smooth_interpolation = true;
-void COMMON_PIXEL_SHADER(Surface S, inout PixelOutput PO)
+#ifdef PIXEL_SHADER
+void MAIN_PASS_PIXEL_SHADER()
{
- vec2 texture_coordinates = S.uv[uv_channel];
-
- vec4 sampled_color = texture(color_texture, texture_coordinates);
-
- PO.color = sampled_color;
+ vec2 texture_coordinates;
+ UV_Map(uv_channel, texture_coordinates);
+
+ vec4 sampled_color;
+ vec2 out_resolution;
+ Image(
+ color_texture,
+ texture_coordinates,
+ smooth_interpolation,
+ sampled_color,
+ out_resolution
+ );
+
+ #ifdef MAIN_PASS
+ OUT_COLOR = sampled_color;
+ #endif // MAIN_PASS
+
}
+#endif // PIXEL_SHADER
```
@@ -138,14 +171,41 @@ void COMMON_PIXEL_SHADER(Surface S, inout PixelOutput PO)
```glsl
-#include "NPR_Pipeline.glsl"
+#include "NPR_MeshShader.glsl"
+#include "Node Utils 2/node_utils_2.glsl"
+#include "Node Utils/node_utils.glsl"
+
+#ifdef MAIN_PASS
+layout (location = 0) out vec4 OUT_COLOR;
+#endif // MAIN_PASS
-uniform vec3 color = vec3(0,1,0);
+OPTIONALLY_BINDLESS uniform sampler1D diffuse_gradient;
+uniform vec3 base_color;
+uniform vec3 color;
-void COMMON_PIXEL_SHADER(Surface S, inout PixelOutput PO)
+#ifdef PIXEL_SHADER
+void MAIN_PASS_PIXEL_SHADER()
{
- PO.color.rgb = color * get_diffuse();
+ vec3 base_color_result = Vec3_color_property(base_color);
+ vec3 color_result = Vec3_color_property(color);
+ vec3 diffuse_result = NPR_diffuse_shading(
+ base_color_result,
+ color_result,
+ diffuse_gradient,
+ /*diffuse_offset=*/0,
+ /*diffuse_full_range=*/false,
+ /*diffuse_max_contribution=*/false,
+ /*diffuse_shadows=*/0,
+ MATERIAL_LIGHT_GROUPS,
+ POSITION,
+ NORMAL
+ );
+
+ #ifdef MAIN_PASS
+ OUT_COLOR = vec4_from_vec3(diffuse_result);
+ #endif // MAIN_PASS
}
+#endif // PIXEL_SHADER
```
@@ -173,25 +233,62 @@ Let's combine the previous examples!
```glsl
-#include "NPR_Pipeline.glsl"
-
-uniform vec3 ambient_color = vec3(0.5,0.5,0.5);
-
+#include "NPR_MeshShader.glsl"
+#include "Node Utils 2/node_utils_2.glsl"
+#include "Node Utils/node_utils.glsl"
+
+#ifdef MAIN_PASS
+layout (location = 0) out vec4 OUT_COLOR;
+#endif // MAIN_PASS
+
+OPTIONALLY_BINDLESS uniform sampler1D diffuse_gradient;
+OPTIONALLY_BINDLESS uniform sampler2D color_texture;
+uniform vec3 base_color;
+uniform vec3 color;
uniform int uv_channel;
-uniform sampler2D color_texture;
+uniform bool smooth_interpolation;
-void COMMON_PIXEL_SHADER(Surface S, inout PixelOutput PO)
+#ifdef PIXEL_SHADER
+void MAIN_PASS_PIXEL_SHADER()
{
- vec3 light_color = get_diffuse() + ambient_color;
-
- vec2 texture_coordinates = S.uv[uv_channel];
-
- vec4 surface_color = texture(color_texture, texture_coordinates);
-
- vec3 result = surface_color.rgb * light_color;
-
- PO.color.rgb = result;
+ vec3 base_color_result = Vec3_color_property(base_color);
+ vec3 color_result = Vec3_color_property(color);
+ vec3 diffuse_result = NPR_diffuse_shading(
+ base_color_result,
+ color_result,
+ diffuse_gradient,
+ /*diffuse_offset=*/0,
+ /*diffuse_full_range=*/false,
+ /*diffuse_max_contribution=*/false,
+ /*diffuse_shadows=*/0,
+ MATERIAL_LIGHT_GROUPS,
+ POSITION,
+ NORMAL
+ );
+
+ vec2 texture_coordinates;
+ UV_Map(uv_channel, texture_coordinates);
+
+ vec4 sampled_color;
+ vec2 out_resolution;
+ Image(
+ color_texture,
+ texture_coordinates,
+ smooth_interpolation,
+ sampled_color,
+ out_resolution
+ );
+
+ vec4 computed_color = Vec4_multiply(
+ vec4_from_vec3(diffuse_result),
+ sampled_color
+ );
+
+ #ifdef MAIN_PASS
+ OUT_COLOR = computed_color;
+ #endif // MAIN_PASS
}
+#endif // PIXEL_SHADER
```
@@ -368,3 +465,4 @@ void third_example()
>I'm working on new chapters, meanwhile, [The Book of Shaders](https://thebookofshaders.com/) is a great resource\!
+**Fun Fact:** Malt ([2b81a03](https://github.com/bnpr/Malt/commit/2b81a03980c41824166b75f39ee5842de2306bcf)) auto-generates GLSL files from your node graphs and saves them to `/your-blender-project/.malt-autogenerated/[your-material].mesh.glsl`
diff --git a/docs/From-Nodes-To-Code/all-together.png b/docs/From-Nodes-To-Code/all-together.png
index 9655c5f5..7fdfd1c5 100644
Binary files a/docs/From-Nodes-To-Code/all-together.png and b/docs/From-Nodes-To-Code/all-together.png differ
diff --git a/docs/From-Nodes-To-Code/flat-color.png b/docs/From-Nodes-To-Code/flat-color.png
index a741a6d5..b7dc7059 100644
Binary files a/docs/From-Nodes-To-Code/flat-color.png and b/docs/From-Nodes-To-Code/flat-color.png differ
diff --git a/docs/From-Nodes-To-Code/lighting.png b/docs/From-Nodes-To-Code/lighting.png
index 03f38135..839e6d7a 100644
Binary files a/docs/From-Nodes-To-Code/lighting.png and b/docs/From-Nodes-To-Code/lighting.png differ
diff --git a/docs/From-Nodes-To-Code/starting-point.png b/docs/From-Nodes-To-Code/starting-point.png
index c92a3b8e..b31cad5f 100644
Binary files a/docs/From-Nodes-To-Code/starting-point.png and b/docs/From-Nodes-To-Code/starting-point.png differ
diff --git a/docs/From-Nodes-To-Code/textures.png b/docs/From-Nodes-To-Code/textures.png
index d9431298..2b0892f9 100644
Binary files a/docs/From-Nodes-To-Code/textures.png and b/docs/From-Nodes-To-Code/textures.png differ