Add Lacunarity and Normalize Inputs to the Noise Texture Node #110839

Merged
Omar Emara merged 11 commits from Hoshinova/blender:add-noise-inputs into main 2023-08-15 17:38:54 +02:00
Member

This PR adds the Lacunarity and Normalize inputs from the Voronoi Texture node to the Noise Texture node.

The Lacunarity input controls by which factor each successive Perlin noise octave is scaled. Currently it is hard coded to a value of 2.0. This input makes it changeable to the user.

The Noise node normalizes it's output by default. The Normalize input makes it possible for the user to turn it off.
To keep the behavior consistent with past versions it is on by default.

This PR adds the Lacunarity and Normalize inputs from the [Voronoi Texture node](https://projects.blender.org/blender/blender/pulls/106827) to the Noise Texture node. The Lacunarity input controls by which factor each successive Perlin noise octave is scaled. Currently it is hard coded to a value of `2.0`. This input makes it changeable to the user. The Noise node normalizes it's output by default. The Normalize input makes it possible for the user to turn it off. To keep the behavior consistent with past versions it is on by default.
Hoshinova added 2 commits 2023-08-05 19:58:16 +02:00
Hoshinova requested review from Jacques Lucke 2023-08-05 20:01:49 +02:00
Hoshinova requested review from Omar Emara 2023-08-05 20:01:49 +02:00
Author
Member

I've only added the inputs for now but knowing how long the review process takes, I created the PR so design questions can already be discussed.

I've only added the inputs for now but knowing how long the review process takes, I created the PR so design questions can already be discussed.
Author
Member

Code wise the fractal_voronoi_x_fx function from 46a17df415/intern/cycles/kernel/svm/voronoi.h (L883) has exactly the same fractalization logic as the one used for the Noise Texture node with the additional inputs already added, so I plan to replace the corresponding Noise Texture functions with a modified version of that.

Code wise the `fractal_voronoi_x_fx` function from https://projects.blender.org/blender/blender/src/commit/46a17df41546d90f74485378bfddec620d0a0f93/intern/cycles/kernel/svm/voronoi.h#L883 has exactly the same fractalization logic as the one used for the Noise Texture node with the additional inputs already added, so I plan to replace the corresponding Noise Texture functions with a modified version of that.
Member

What is a practical example for turning off normalization? That doesn't seem very useful to me.
Also adding Lacunarity kind of turns the noise texture into a Musgrave texture doesn't it?

What is a practical example for turning off normalization? That doesn't seem very useful to me. Also adding Lacunarity kind of turns the noise texture into a Musgrave texture doesn't it?
Author
Member

What is a practical example for turning off normalization?

Pretty mich all cases where the height of the Fractal Perlin noise actually matters, like with procedural terrain generation.

Also adding Lacunarity kind of turns the noise texture into a Musgrave texture doesn't it?

Surprisingly no. The Dimension input of the Musgrave Texture does a very weird thing, where it acts like the Roughness inputs but is the value is taken as Roughness = Lacunarity^(-Dimension) d870f9e841/intern/cycles/kernel/svm/musgrave.h (L202), which is completely unintuitive to even the most technical users, which is probably why I see many artists shy away from it.
So while the Musgrave Texture has a Lacunarity input it effectively has no usable Roughness input.

But you're bringing up an interesting point. I've always wondered why Blender has 2 Perlin noise nodes, neither of which being called Perlin noise, but both of which having features the other one doesn't.

Ideally my plan is to merge the Musgrave Texture node and the Noise Texture node into a single Perlin noise node, but implementation wise that still has many open questions regarding backwards compatibility.

Which is why for now I decided to at least make the Noise Texture have it's full set of features.

> What is a practical example for turning off normalization? Pretty mich all cases where the height of the Fractal Perlin noise actually matters, like with procedural terrain generation. > Also adding Lacunarity kind of turns the noise texture into a Musgrave texture doesn't it? Surprisingly no. The Dimension input of the Musgrave Texture does a very weird thing, where it acts like the Roughness inputs but is the value is taken as Roughness = Lacunarity^(-Dimension) https://projects.blender.org/blender/blender/src/commit/d870f9e841a5ea8c289414808e9b8390bb4825b2/intern/cycles/kernel/svm/musgrave.h#L202, which is completely unintuitive to even the most technical users, which is probably why I see many artists shy away from it. So while the Musgrave Texture has a Lacunarity input it effectively has no usable Roughness input. But you're bringing up an interesting point. I've always wondered why Blender has 2 Perlin noise nodes, neither of which being called Perlin noise, but both of which having features the other one doesn't. Ideally my plan is to merge the Musgrave Texture node and the Noise Texture node into a single Perlin noise node, but implementation wise that still has many open questions regarding backwards compatibility. Which is why for now I decided to at least make the Noise Texture have it's full set of features.
Author
Member

Also code wise I noticed, that there is actually no need to replace any functions. Simple replacing 2.0 with lacunarity already does the trick. And for the normalization an if statement around the corresponding code should also be enough.

So I don't see any downsides to this, neither user experience nor code wise.

Also code wise I noticed, that there is actually no need to replace any functions. Simple replacing 2.0 with lacunarity already does the trick. And for the normalization an if statement around the corresponding code should also be enough. So I don't see any downsides to this, neither user experience nor code wise.
Member

Since work to bring features from Musgrave texture to the noise texture was approved before in D7065, I see no reason to block the addition of Lacunarity.

I still don't see how normalization could be useful, Perlin noise intrinsically has no reasonable maximum, so leaving it to its own maximum brings us what value? Can you demonstrate a visual practical example?

Since work to bring features from Musgrave texture to the noise texture was approved before in D7065, I see no reason to block the addition of Lacunarity. I still don't see how normalization could be useful, Perlin noise intrinsically has no reasonable maximum, so leaving it to its own maximum brings us what value? Can you demonstrate a visual practical example?
First-time contributor

A while ago I posted this picture in the Pull Request for Fractal Voronoi noise:
250.png

Both the water and the fire were created using a combination of Voronoi Texture node and Noise Texture node.
The fire and the water were created using two separate node trees and as you can see they are aligned such that the fire sits perfectly on top of the water.
The fact that the Noise Texture node normalizes the Fractal Perlin noise makes that alignment much more difficult, because it introduces an offset to the midlevel of the noise which scales along as you scale the noise output.
To combat this issue I had to manually un-normalize the output for every node, which gets tedious if the node setup is complex like in this case.

Alternatively I could've used the Musgrave Texture node which unlike the Noise Texture node doesn't normalize it's output, but found the Dimension input to be hard to work with, just as Hoshinova described.

Apart from that the Noise Texture node normalization tends to overcompensate for higher Roughness values making the entire output just 0.5ish.

A while ago I posted this picture in the Pull Request for Fractal Voronoi noise: ![250.png](/attachments/e377bafc-9c88-4587-ae7e-bc06679cdd8b) Both the water and the fire were created using a combination of Voronoi Texture node and Noise Texture node. The fire and the water were created using two separate node trees and as you can see they are aligned such that the fire sits perfectly on top of the water. The fact that the Noise Texture node normalizes the Fractal Perlin noise makes that alignment much more difficult, because it introduces an offset to the midlevel of the noise which scales along as you scale the noise output. To combat this issue I had to manually un-normalize the output for every node, which gets tedious if the node setup is complex like in this case. Alternatively I could've used the Musgrave Texture node which unlike the Noise Texture node doesn't normalize it's output, but found the Dimension input to be hard to work with, just as Hoshinova described. Apart from that the Noise Texture node normalization tends to overcompensate for higher Roughness values making the entire output just 0.5ish.
8.8 MiB
Author
Member

@OmarEmaraDev So there you have it.
Thanks again @Raiko for your explanation!

@OmarEmaraDev So there you have it. Thanks again @Raiko for your explanation!
Hoshinova changed title from Add Lacunarity and Normalize Inputs to the Noise Texture Node to WIP: Add Lacunarity and Normalize Inputs to the Noise Texture Node 2023-08-06 16:04:49 +02:00
Hoshinova requested review from Brecht Van Lommel 2023-08-06 16:04:57 +02:00

@blender-bot package

@blender-bot package
Member

Package build started. Download here when ready.

Package build started. [Download here](https://builder.blender.org/download/patch/PR110839) when ready.
Brecht Van Lommel requested changes 2023-08-08 18:06:38 +02:00
Brecht Van Lommel left a comment
Owner

The functionality and Cycles implementation look fine to me.

I guess the Eevee implementation is still missing since it does not use the parameters.

The functionality and Cycles implementation look fine to me. I guess the Eevee implementation is still missing since it does not use the parameters.
Hoshinova added 1 commit 2023-08-09 15:27:24 +02:00
buildbot/vexp-code-patch-coordinator Build done. Details
e1b82960d3
-- Implement new inputs to shader and geometry nodes.
Author
Member

As you may have noticed I changed the way normalization is done.
In the old code the octaves are first normalized individually then added together then normalized again.
In the new code both steps are combined into one normalization step after the fractalization process.
This makes the new code slightly faster as it saves a few additions and multiplications but more importantly it separates the normalization step from the fractalization process, making it possible to easily turn on or off.

To dispel any possible doubts about whether or not the new code always computes the same output as the old code and for future reference here is a quick proof:

The way the old code computes the output can be explicitly written as:

output =\frac{ \sum_{i=0}^{detail} ((0.5*snoise(p*lacunarity^i)+0.5)*roughness^i) }{maxamp}

where maxamp = \sum_{i=0}^{detail}(roughness^i)

The way the new code computes the output can be explicitly written as:

output =0.5*\frac{ \sum_{i=0}^{detail} (snoise(p*lacunarity^i)*roughness^i) }{maxamp}+0.5

The old and new code always compute the same output iff the expression on the right side of both equations are equivalent.
Thus:

\frac{ \sum_{i=0}^{detail} ((0.5*snoise(p*lacunarity^i)+0.5)*roughness^i) }{maxamp}
=\frac{ \sum_{i=0}^{detail} (0.5*snoise(p*lacunarity^i)*roughness^i+0.5*roughness^i) }{maxamp}
=\frac{ \sum_{i=0}^{detail} (0.5*snoise(p*lacunarity^i)*roughness^i) }{maxamp} + \frac{ \sum_{i=0}^{detail} (0.5*roughness^i) }{maxamp}
=0.5*\frac{ \sum_{i=0}^{detail} (snoise(p*lacunarity^i)*roughness^i) }{maxamp} + 0.5*\frac{ \sum_{i=0}^{detail} (roughness^i) }{maxamp}
=0.5*\frac{ \sum_{i=0}^{detail} (snoise(p*lacunarity^i)*roughness^i) }{maxamp} + 0.5*\frac{ \sum_{i=0}^{detail} (roughness^i) }{ \sum_{i=0}^{detail}(roughness^i)}
=0.5*\frac{ \sum_{i=0}^{detail} (snoise(p*lacunarity^i)*roughness^i) }{maxamp}+0.5

This concludes the proof.

As you may have noticed I changed the way normalization is done. In the old code the octaves are first normalized individually then added together then normalized again. In the new code both steps are combined into one normalization step after the fractalization process. This makes the new code slightly faster as it saves a few additions and multiplications but more importantly it separates the normalization step from the fractalization process, making it possible to easily turn on or off. To dispel any possible doubts about whether or not the new code always computes the same output as the old code and for future reference here is a quick proof: The way the old code computes the output can be explicitly written as: $$output =\frac{ \sum_{i=0}^{detail} ((0.5*snoise(p*lacunarity^i)+0.5)*roughness^i) }{maxamp}$$ where $maxamp = \sum_{i=0}^{detail}(roughness^i)$ The way the new code computes the output can be explicitly written as: $$output =0.5*\frac{ \sum_{i=0}^{detail} (snoise(p*lacunarity^i)*roughness^i) }{maxamp}+0.5$$ The old and new code always compute the same output iff the expression on the right side of both equations are equivalent. Thus: $$\frac{ \sum_{i=0}^{detail} ((0.5*snoise(p*lacunarity^i)+0.5)*roughness^i) }{maxamp}$$ $$=\frac{ \sum_{i=0}^{detail} (0.5*snoise(p*lacunarity^i)*roughness^i+0.5*roughness^i) }{maxamp}$$ $$=\frac{ \sum_{i=0}^{detail} (0.5*snoise(p*lacunarity^i)*roughness^i) }{maxamp} + \frac{ \sum_{i=0}^{detail} (0.5*roughness^i) }{maxamp}$$ $$=0.5*\frac{ \sum_{i=0}^{detail} (snoise(p*lacunarity^i)*roughness^i) }{maxamp} + 0.5*\frac{ \sum_{i=0}^{detail} (roughness^i) }{maxamp}$$ $$=0.5*\frac{ \sum_{i=0}^{detail} (snoise(p*lacunarity^i)*roughness^i) }{maxamp} + 0.5*\frac{ \sum_{i=0}^{detail} (roughness^i) }{ \sum_{i=0}^{detail}(roughness^i)}$$ $$=0.5*\frac{ \sum_{i=0}^{detail} (snoise(p*lacunarity^i)*roughness^i) }{maxamp}+0.5$$ This concludes the proof.

@blender-bot package

@blender-bot package
Member

Package build started. Download here when ready.

Package build started. [Download here](https://builder.blender.org/download/patch/PR110839) when ready.
Hoshinova added 1 commit 2023-08-09 18:14:16 +02:00
buildbot/vexp-code-patch-coordinator Build done. Details
893b425dcc
Merge branch 'main' into add-noise-inputs
Member

@blender-bot package

@blender-bot package
Member

Package build started. Download here when ready.

Package build started. [Download here](https://builder.blender.org/download/patch/PR110839) when ready.
Author
Member

Here's a test file to show that the new behavior is same for all shader node implementations:
Noise_Test_File.blend

The output of the new Noise Texture node should be identical with the old one when Normalize is turned on and Lacunarity is set to 2.0.

Here's a test file to show that the new behavior is same for all shader node implementations: [Noise_Test_File.blend](/attachments/ad90643e-26f4-4f6e-84c6-cc001b85112a) The output of the new Noise Texture node should be identical with the old one when `Normalize` is turned on and `Lacunarity` is set to 2.0.
Jacques Lucke requested changes 2023-08-09 21:44:07 +02:00
Jacques Lucke left a comment
Member

The code looks fine to me too, but it's breaking a bunch of tests currently. That should be fixed.
I haven't looked at it in detail yet, but the reason might just be missing versioning code for the normalize property.

The code looks fine to me too, but it's breaking a bunch of tests currently. That should be fixed. I haven't looked at it in detail yet, but the reason might just be missing versioning code for the normalize property.
@ -1216,3 +1216,3 @@
NodeTexBase base;
int dimensions;
char _pad[4];
int normalize;
Member

Use uint8_t for normalize and keep a padding of 3 bytes.

Use `uint8_t` for `normalize` and keep a padding of 3 bytes.
Hoshinova marked this conversation as resolved
Hoshinova added 1 commit 2023-08-10 14:34:29 +02:00
buildbot/vexp-code-patch-coordinator Build done. Details
312ba903f8
-- Do versioning
Member

@blender-bot package

@blender-bot package
Member

Package build started. Download here when ready.

Package build started. [Download here](https://builder.blender.org/download/patch/PR110839) when ready.
Hoshinova added 1 commit 2023-08-10 15:28:19 +02:00
Hoshinova added 1 commit 2023-08-11 11:09:19 +02:00
buildbot/vexp-code-patch-coordinator Build done. Details
e848057d17
BLENDER_SOURCE_CODE_COMMIT commit message number: 18
Jacques Lucke approved these changes 2023-08-15 11:49:29 +02:00
Jacques Lucke left a comment
Member

LGTM.

LGTM.
Member

Ah, you still have to increase BLENDER_FILE_SUBVERSION in this patch.

@blender-bot build

Ah, you still have to increase `BLENDER_FILE_SUBVERSION` in this patch. @blender-bot build
Hoshinova added 3 commits 2023-08-15 14:31:24 +02:00
Hoshinova changed title from WIP: Add Lacunarity and Normalize Inputs to the Noise Texture Node to Add Lacunarity and Normalize Inputs to the Noise Texture Node 2023-08-15 14:33:39 +02:00
Brecht Van Lommel approved these changes 2023-08-15 14:36:17 +02:00
Member

@blender-bot build

@blender-bot build
Member

If you don't want us to merge a specific patch, add the WIP: prefix to the commit title. Besides that, I don't know what you expect us to do when we want to merge it?

If you don't want us to merge a specific patch, add the `WIP:` prefix to the commit title. Besides that, I don't know what you expect us to do when we want to merge it?
Omar Emara requested changes 2023-08-15 17:06:23 +02:00
@ -5157,0 +5157,4 @@
prop = RNA_def_property(srna, "normalize", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "normalize", 0);
RNA_def_property_ui_text(prop, "Normalize", "Normalize output Distance to 0.0 to 1.0 range");
Member

Misplaced mentioned of Distance.

Misplaced mentioned of Distance.
Hoshinova marked this conversation as resolved
@ -31,0 +32,4 @@
.min(0.0f)
.max(1000.0f)
.default_value(2.0f)
.description("The scale of a Voronoi layer relative to that of the previous layer");
Member

Misplaced mention of Voronoi. Also maybe use Octave instead of Layer.

Misplaced mention of Voronoi. Also maybe use Octave instead of Layer.
Hoshinova marked this conversation as resolved
Hoshinova added 1 commit 2023-08-15 17:26:44 +02:00
Omar Emara approved these changes 2023-08-15 17:28:22 +02:00
Omar Emara merged commit 0702c24a36 into main 2023-08-15 17:38:54 +02:00
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
8 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#110839
No description provided.