GPU: add mechanism for splitting up big gpu_shader_material.glsl file

Compiling this big file for every Eevee material is bad for performance, and
now that we are adding more nodes it gets worse. This patch adds a simple
mechanism to split up that file, and use only the parts used by shader nodes.

When a function is used by GPU_link, we detect which GLSL file it came from
and use it in GLSL code generation automatically. Dependencies between GLSL
files are manually specified, and function names must be unique across all
GLSL files.

Most of the actual splitting up will be done in later commits.

Differential Revision: https://developer.blender.org/D5569
This commit is contained in:
Brecht Van Lommel 2019-08-23 14:36:22 +02:00
parent 6b189d2bcf
commit 7f840426fd
9 changed files with 410 additions and 319 deletions

View File

@ -116,6 +116,7 @@ set(SRC
intern/gpu_batch_private.h
intern/gpu_codegen.h
intern/gpu_context_private.h
intern/gpu_material_library.h
intern/gpu_matrix_private.h
intern/gpu_primitive_private.h
intern/gpu_private.h
@ -232,6 +233,9 @@ data_to_c_simple(shaders/gpu_shader_keyframe_diamond_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_geometry.glsl SRC)
data_to_c_simple(shaders/gpu_shader_material.glsl SRC)
data_to_c_simple(shaders/gpu_shader_material_hash.glsl SRC)
data_to_c_simple(shaders/gpu_shader_material_magic.glsl SRC)
data_to_c_simple(shaders/gpu_shader_material_white_noise.glsl SRC)
data_to_c_simple(shaders/gpu_shader_gpencil_stroke_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_gpencil_stroke_frag.glsl SRC)

View File

@ -51,15 +51,11 @@
#include "BLI_sys_types.h" /* for intptr_t support */
#include "gpu_codegen.h"
#include "gpu_material_library.h"
#include <string.h>
#include <stdarg.h>
extern char datatoc_gpu_shader_material_glsl[];
extern char datatoc_gpu_shader_geometry_glsl[];
static char *glsl_material_library = NULL;
/* -------------------- GPUPass Cache ------------------ */
/**
* Internal shader cache: This prevent the shader recompilation / stall when
@ -147,6 +143,7 @@ typedef struct GPUFunction {
eGPUType paramtype[MAX_PARAMETER];
GPUFunctionQual paramqual[MAX_PARAMETER];
int totparam;
GPUMaterialLibrary *library;
} GPUFunction;
/* Indices match the eGPUType enum */
@ -230,15 +227,17 @@ static char *gpu_str_skip_token(char *str, char *token, int max)
return str;
}
static void gpu_parse_functions_string(GHash *hash, char *code)
static void gpu_parse_material_library(GHash *hash, GPUMaterialLibrary *library)
{
GPUFunction *function;
eGPUType type;
GPUFunctionQual qual;
int i;
char *code = library->code;
while ((code = strstr(code, "void "))) {
function = MEM_callocN(sizeof(GPUFunction), "GPUFunction");
function->library = library;
code = gpu_str_skip_token(code, NULL, 0);
code = gpu_str_skip_token(code, function->name, MAX_FUNCTION_NAME);
@ -367,11 +366,6 @@ static char *gpu_generate_function_prototyps(GHash *hash)
static GPUFunction *gpu_lookup_function(const char *name)
{
if (!FUNCTION_HASH) {
FUNCTION_HASH = BLI_ghash_str_new("GPU_lookup_function gh");
gpu_parse_functions_string(FUNCTION_HASH, glsl_material_library);
}
return BLI_ghash_lookup(FUNCTION_HASH, (const void *)name);
}
@ -395,11 +389,6 @@ void gpu_codegen_exit(void)
GPU_shader_free_builtin_shaders();
if (glsl_material_library) {
MEM_freeN(glsl_material_library);
glsl_material_library = NULL;
}
#if 0
if (FUNCTION_PROTOTYPES) {
MEM_freeN(FUNCTION_PROTOTYPES);
@ -1381,20 +1370,15 @@ static char *code_generate_geometry(ListBase *nodes, const char *geom_code, cons
void GPU_code_generate_glsl_lib(void)
{
DynStr *ds;
/* only initialize the library once */
if (glsl_material_library) {
/* Only parse GLSL shader files once. */
if (FUNCTION_HASH) {
return;
}
ds = BLI_dynstr_new();
BLI_dynstr_append(ds, datatoc_gpu_shader_material_glsl);
glsl_material_library = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
FUNCTION_HASH = BLI_ghash_str_new("GPU_lookup_function gh");
for (int i = 0; gpu_material_libraries[i].code; i++) {
gpu_parse_material_library(FUNCTION_HASH, &gpu_material_libraries[i]);
}
}
/* GPU pass binding/unbinding */
@ -1796,6 +1780,19 @@ GPUNodeLink *GPU_builtin(eGPUBuiltin builtin)
return link;
}
static void gpu_material_use_library(GPUMaterial *material, GPUMaterialLibrary *library)
{
GSet *used_libraries = gpu_material_used_libraries(material);
if (BLI_gset_add(used_libraries, library->code)) {
if (library->dependencies) {
for (int i = 0; library->dependencies[i]; i++) {
BLI_gset_add(used_libraries, library->dependencies[i]);
}
}
}
}
bool GPU_link(GPUMaterial *mat, const char *name, ...)
{
GPUNode *node;
@ -1810,6 +1807,8 @@ bool GPU_link(GPUMaterial *mat, const char *name, ...)
return false;
}
gpu_material_use_library(mat, function->library);
node = GPU_node_begin(name);
va_start(params, name);
@ -1849,6 +1848,8 @@ bool GPU_stack_link(GPUMaterial *material,
return false;
}
gpu_material_use_library(material, function->library);
node = GPU_node_begin(name);
totin = 0;
totout = 0;
@ -1962,6 +1963,30 @@ static bool gpu_pass_is_valid(GPUPass *pass)
return (pass->compiled == false || pass->shader != NULL);
}
static char *code_generate_material_library(GPUMaterial *material, const char *frag_lib)
{
DynStr *ds = BLI_dynstr_new();
if (frag_lib) {
BLI_dynstr_append(ds, frag_lib);
}
GSet *used_libraries = gpu_material_used_libraries(material);
/* Add library code in order, for dependencies. */
for (int i = 0; gpu_material_libraries[i].code; i++) {
GPUMaterialLibrary *library = &gpu_material_libraries[i];
if (BLI_gset_haskey(used_libraries, library->code)) {
BLI_dynstr_append(ds, library->code);
}
}
char *result = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
return result;
}
GPUPass *GPU_generate_pass(GPUMaterial *material,
GPUNodeLink *frag_outlink,
struct GPUVertAttrLayers *attrs,
@ -2000,7 +2025,7 @@ GPUPass *GPU_generate_pass(GPUMaterial *material,
/* Either the shader is not compiled or there is a hash collision...
* continue generating the shader strings. */
char *tmp = BLI_strdupcat(frag_lib, glsl_material_library);
char *tmp = code_generate_material_library(material, frag_lib);
geometrycode = code_generate_geometry(nodes, geom_code, defines);
vertexcode = code_generate_vertex(nodes, vert_code, (geometrycode != NULL));

View File

@ -33,6 +33,7 @@ struct GPUNode;
struct GPUOutput;
struct GPUShader;
struct GPUVertAttrLayers;
struct GSet;
struct ListBase;
/* Pass Generation
@ -207,4 +208,6 @@ struct GPUTexture **gpu_material_ramp_texture_row_set(GPUMaterial *mat,
float *pixels,
float *row);
struct GSet *gpu_material_used_libraries(struct GPUMaterial *material);
#endif

View File

@ -37,6 +37,7 @@
#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_string_utils.h"
#include "BLI_ghash.h"
#include "BKE_main.h"
#include "BKE_node.h"
@ -102,6 +103,8 @@ struct GPUMaterial {
GPUTexture *coba_tex; /* 1D Texture array containing all color bands. */
GPUColorBandBuilder *coba_builder;
GSet *used_libraries;
#ifndef NDEBUG
char name[64];
#endif
@ -183,6 +186,8 @@ static void gpu_material_free_single(GPUMaterial *material)
if (material->coba_tex != NULL) {
GPU_texture_free(material->coba_tex);
}
BLI_gset_free(material->used_libraries, NULL);
}
void GPU_material_free(ListBase *gpumaterial)
@ -582,6 +587,11 @@ void gpu_material_add_node(GPUMaterial *material, GPUNode *node)
BLI_addtail(&material->nodes, node);
}
GSet *gpu_material_used_libraries(GPUMaterial *material)
{
return material->used_libraries;
}
/* Return true if the material compilation has not yet begin or begin. */
eGPUMaterialStatus GPU_material_status(GPUMaterial *mat)
{
@ -659,6 +669,9 @@ GPUMaterial *GPU_material_from_nodetree(Scene *scene,
UNUSED_VARS(name);
#endif
mat->used_libraries = BLI_gset_new(
BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "GPUMaterial.used_libraries");
/* localize tree to create links for reroute and mute */
bNodeTree *localtree = ntreeLocalize(ntree);
ntreeGPUMaterialNodes(localtree, mat, &has_surface_output, &has_volume_output);

View File

@ -0,0 +1,49 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2005 Blender Foundation.
* All rights reserved.
*/
/** \file
* \ingroup gpu
*
* List of all gpu_shader_material_*.glsl files used by GLSL materials. These
* will be parsed to make all functions in them available to use for GPU_link().
*
* If a file uses functions from another file, it must be added to the list of
* dependencies, and be placed after that file in the list. */
#ifndef __GPU_MATERIAL_LIBRARY_H__
#define __GPU_MATERIAL_LIBRARY_H__
typedef struct GPUMaterialLibrary {
char *code;
char *dependencies[8];
} GPUMaterialLibrary;
extern char datatoc_gpu_shader_material_glsl[];
extern char datatoc_gpu_shader_material_hash_glsl[];
extern char datatoc_gpu_shader_material_magic_glsl[];
extern char datatoc_gpu_shader_material_white_noise_glsl[];
static GPUMaterialLibrary gpu_material_libraries[] = {
{datatoc_gpu_shader_material_hash_glsl, {NULL}},
{datatoc_gpu_shader_material_glsl, {datatoc_gpu_shader_material_hash_glsl, NULL}},
{datatoc_gpu_shader_material_magic_glsl, {NULL}},
{datatoc_gpu_shader_material_white_noise_glsl, {datatoc_gpu_shader_material_hash_glsl, NULL}},
{NULL, {NULL}}};
#endif

View File

@ -1167,235 +1167,6 @@ float integer_noise(int n)
return 0.5 * (float(nn) / 1073741824.0);
}
/* ***** Jenkins Lookup3 Hash Functions ***** */
/* Source: http://burtleburtle.net/bob/c/lookup3.c */
#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
#define mix(a, b, c) \
{ \
a -= c; \
a ^= rot(c, 4); \
c += b; \
b -= a; \
b ^= rot(a, 6); \
a += c; \
c -= b; \
c ^= rot(b, 8); \
b += a; \
a -= c; \
a ^= rot(c, 16); \
c += b; \
b -= a; \
b ^= rot(a, 19); \
a += c; \
c -= b; \
c ^= rot(b, 4); \
b += a; \
}
#define final(a, b, c) \
{ \
c ^= b; \
c -= rot(b, 14); \
a ^= c; \
a -= rot(c, 11); \
b ^= a; \
b -= rot(a, 25); \
c ^= b; \
c -= rot(b, 16); \
a ^= c; \
a -= rot(c, 4); \
b ^= a; \
b -= rot(a, 14); \
c ^= b; \
c -= rot(b, 24); \
}
uint hash_uint(uint kx)
{
uint a, b, c;
a = b = c = 0xdeadbeefu + (1u << 2u) + 13u;
a += kx;
final(a, b, c);
return c;
}
uint hash_uint2(uint kx, uint ky)
{
uint a, b, c;
a = b = c = 0xdeadbeefu + (2u << 2u) + 13u;
b += ky;
a += kx;
final(a, b, c);
return c;
}
uint hash_uint3(uint kx, uint ky, uint kz)
{
uint a, b, c;
a = b = c = 0xdeadbeefu + (3u << 2u) + 13u;
c += kz;
b += ky;
a += kx;
final(a, b, c);
return c;
}
uint hash_uint4(uint kx, uint ky, uint kz, uint kw)
{
uint a, b, c;
a = b = c = 0xdeadbeefu + (4u << 2u) + 13u;
a += kx;
b += ky;
c += kz;
mix(a, b, c);
a += kw;
final(a, b, c);
return c;
}
#undef rot
#undef final
#undef mix
uint hash_int(int kx)
{
return hash_uint(uint(kx));
}
uint hash_int2(int kx, int ky)
{
return hash_uint2(uint(kx), uint(ky));
}
uint hash_int3(int kx, int ky, int kz)
{
return hash_uint3(uint(kx), uint(ky), uint(kz));
}
uint hash_int4(int kx, int ky, int kz, int kw)
{
return hash_uint4(uint(kx), uint(ky), uint(kz), uint(kw));
}
/* Hashing uint or uint[234] into a float in the range [0, 1]. */
float hash_uint_to_float(uint kx)
{
return float(hash_uint(kx)) / float(0xFFFFFFFFu);
}
float hash_uint2_to_float(uint kx, uint ky)
{
return float(hash_uint2(kx, ky)) / float(0xFFFFFFFFu);
}
float hash_uint3_to_float(uint kx, uint ky, uint kz)
{
return float(hash_uint3(kx, ky, kz)) / float(0xFFFFFFFFu);
}
float hash_uint4_to_float(uint kx, uint ky, uint kz, uint kw)
{
return float(hash_uint4(kx, ky, kz, kw)) / float(0xFFFFFFFFu);
}
/* Hashing float or vec[234] into a float in the range [0, 1]. */
float hash_float_to_float(float k)
{
return hash_uint_to_float(floatBitsToUint(k));
}
float hash_vec2_to_float(vec2 k)
{
return hash_uint2_to_float(floatBitsToUint(k.x), floatBitsToUint(k.y));
}
float hash_vec3_to_float(vec3 k)
{
return hash_uint3_to_float(floatBitsToUint(k.x), floatBitsToUint(k.y), floatBitsToUint(k.z));
}
float hash_vec4_to_float(vec4 k)
{
return hash_uint4_to_float(
floatBitsToUint(k.x), floatBitsToUint(k.y), floatBitsToUint(k.z), floatBitsToUint(k.w));
}
/* Hashing vec[234] into vec[234] of components in the range [0, 1]. */
vec2 hash_vec2_to_vec2(vec2 k)
{
return vec2(hash_vec2_to_float(k), hash_vec3_to_float(vec3(k, 1.0)));
}
vec3 hash_vec3_to_vec3(vec3 k)
{
return vec3(
hash_vec3_to_float(k), hash_vec4_to_float(vec4(k, 1.0)), hash_vec4_to_float(vec4(k, 2.0)));
}
vec4 hash_vec4_to_vec4(vec4 k)
{
return vec4(hash_vec4_to_float(k.xyzw),
hash_vec4_to_float(k.wxyz),
hash_vec4_to_float(k.zwxy),
hash_vec4_to_float(k.yzwx));
}
/* Hashing float or vec[234] into vec3 of components in range [0, 1]. */
vec3 hash_float_to_vec3(float k)
{
return vec3(
hash_float_to_float(k), hash_vec2_to_float(vec2(k, 1.0)), hash_vec2_to_float(vec2(k, 2.0)));
}
vec3 hash_vec2_to_vec3(vec2 k)
{
return vec3(
hash_vec2_to_float(k), hash_vec3_to_float(vec3(k, 1.0)), hash_vec3_to_float(vec3(k, 2.0)));
}
vec3 hash_vec4_to_vec3(vec4 k)
{
return vec3(hash_vec4_to_float(k.xyzw), hash_vec4_to_float(k.zxwy), hash_vec4_to_float(k.wzyx));
}
/* White Noise */
void node_white_noise_1d(vec3 vector, float w, out float value)
{
value = hash_float_to_float(w);
}
void node_white_noise_2d(vec3 vector, float w, out float value)
{
value = hash_vec2_to_float(vector.xy);
}
void node_white_noise_3d(vec3 vector, float w, out float value)
{
value = hash_vec3_to_float(vector);
}
void node_white_noise_4d(vec3 vector, float w, out float value)
{
value = hash_vec4_to_float(vec4(vector, w));
}
/* Cell Noise */
float bits_to_01(uint bits)
@ -3022,68 +2793,6 @@ void node_tex_image_empty(vec3 co, out vec4 color, out float alpha)
alpha = 0.0;
}
void node_tex_magic(
vec3 co, float scale, float distortion, float depth, out vec4 color, out float fac)
{
vec3 p = co * scale;
float x = sin((p.x + p.y + p.z) * 5.0);
float y = cos((-p.x + p.y - p.z) * 5.0);
float z = -cos((-p.x - p.y + p.z) * 5.0);
if (depth > 0) {
x *= distortion;
y *= distortion;
z *= distortion;
y = -cos(x - y + z);
y *= distortion;
if (depth > 1) {
x = cos(x - y - z);
x *= distortion;
if (depth > 2) {
z = sin(-x - y - z);
z *= distortion;
if (depth > 3) {
x = -cos(-x + y - z);
x *= distortion;
if (depth > 4) {
y = -sin(-x + y + z);
y *= distortion;
if (depth > 5) {
y = -cos(-x + y + z);
y *= distortion;
if (depth > 6) {
x = cos(x + y + z);
x *= distortion;
if (depth > 7) {
z = sin(x + y - z);
z *= distortion;
if (depth > 8) {
x = -cos(-x - y + z);
x *= distortion;
if (depth > 9) {
y = -sin(x - y + z);
y *= distortion;
}
}
}
}
}
}
}
}
}
}
if (distortion != 0.0) {
distortion *= 2.0;
x /= distortion;
y /= distortion;
z /= distortion;
}
color = vec4(0.5 - x, 0.5 - y, 0.5 - z, 1.0);
fac = (color.x + color.y + color.z) / 3.0;
}
float noise_fade(float t)
{
return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);

View File

@ -0,0 +1,206 @@
/* ***** Jenkins Lookup3 Hash Functions ***** */
/* Source: http://burtleburtle.net/bob/c/lookup3.c */
#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
#define mix(a, b, c) \
{ \
a -= c; \
a ^= rot(c, 4); \
c += b; \
b -= a; \
b ^= rot(a, 6); \
a += c; \
c -= b; \
c ^= rot(b, 8); \
b += a; \
a -= c; \
a ^= rot(c, 16); \
c += b; \
b -= a; \
b ^= rot(a, 19); \
a += c; \
c -= b; \
c ^= rot(b, 4); \
b += a; \
}
#define final(a, b, c) \
{ \
c ^= b; \
c -= rot(b, 14); \
a ^= c; \
a -= rot(c, 11); \
b ^= a; \
b -= rot(a, 25); \
c ^= b; \
c -= rot(b, 16); \
a ^= c; \
a -= rot(c, 4); \
b ^= a; \
b -= rot(a, 14); \
c ^= b; \
c -= rot(b, 24); \
}
uint hash_uint(uint kx)
{
uint a, b, c;
a = b = c = 0xdeadbeefu + (1u << 2u) + 13u;
a += kx;
final(a, b, c);
return c;
}
uint hash_uint2(uint kx, uint ky)
{
uint a, b, c;
a = b = c = 0xdeadbeefu + (2u << 2u) + 13u;
b += ky;
a += kx;
final(a, b, c);
return c;
}
uint hash_uint3(uint kx, uint ky, uint kz)
{
uint a, b, c;
a = b = c = 0xdeadbeefu + (3u << 2u) + 13u;
c += kz;
b += ky;
a += kx;
final(a, b, c);
return c;
}
uint hash_uint4(uint kx, uint ky, uint kz, uint kw)
{
uint a, b, c;
a = b = c = 0xdeadbeefu + (4u << 2u) + 13u;
a += kx;
b += ky;
c += kz;
mix(a, b, c);
a += kw;
final(a, b, c);
return c;
}
#undef rot
#undef final
#undef mix
uint hash_int(int kx)
{
return hash_uint(uint(kx));
}
uint hash_int2(int kx, int ky)
{
return hash_uint2(uint(kx), uint(ky));
}
uint hash_int3(int kx, int ky, int kz)
{
return hash_uint3(uint(kx), uint(ky), uint(kz));
}
uint hash_int4(int kx, int ky, int kz, int kw)
{
return hash_uint4(uint(kx), uint(ky), uint(kz), uint(kw));
}
/* Hashing uint or uint[234] into a float in the range [0, 1]. */
float hash_uint_to_float(uint kx)
{
return float(hash_uint(kx)) / float(0xFFFFFFFFu);
}
float hash_uint2_to_float(uint kx, uint ky)
{
return float(hash_uint2(kx, ky)) / float(0xFFFFFFFFu);
}
float hash_uint3_to_float(uint kx, uint ky, uint kz)
{
return float(hash_uint3(kx, ky, kz)) / float(0xFFFFFFFFu);
}
float hash_uint4_to_float(uint kx, uint ky, uint kz, uint kw)
{
return float(hash_uint4(kx, ky, kz, kw)) / float(0xFFFFFFFFu);
}
/* Hashing float or vec[234] into a float in the range [0, 1]. */
float hash_float_to_float(float k)
{
return hash_uint_to_float(floatBitsToUint(k));
}
float hash_vec2_to_float(vec2 k)
{
return hash_uint2_to_float(floatBitsToUint(k.x), floatBitsToUint(k.y));
}
float hash_vec3_to_float(vec3 k)
{
return hash_uint3_to_float(floatBitsToUint(k.x), floatBitsToUint(k.y), floatBitsToUint(k.z));
}
float hash_vec4_to_float(vec4 k)
{
return hash_uint4_to_float(
floatBitsToUint(k.x), floatBitsToUint(k.y), floatBitsToUint(k.z), floatBitsToUint(k.w));
}
/* Hashing vec[234] into vec[234] of components in the range [0, 1]. */
vec2 hash_vec2_to_vec2(vec2 k)
{
return vec2(hash_vec2_to_float(k), hash_vec3_to_float(vec3(k, 1.0)));
}
vec3 hash_vec3_to_vec3(vec3 k)
{
return vec3(
hash_vec3_to_float(k), hash_vec4_to_float(vec4(k, 1.0)), hash_vec4_to_float(vec4(k, 2.0)));
}
vec4 hash_vec4_to_vec4(vec4 k)
{
return vec4(hash_vec4_to_float(k.xyzw),
hash_vec4_to_float(k.wxyz),
hash_vec4_to_float(k.zwxy),
hash_vec4_to_float(k.yzwx));
}
/* Hashing float or vec[234] into vec3 of components in range [0, 1]. */
vec3 hash_float_to_vec3(float k)
{
return vec3(
hash_float_to_float(k), hash_vec2_to_float(vec2(k, 1.0)), hash_vec2_to_float(vec2(k, 2.0)));
}
vec3 hash_vec2_to_vec3(vec2 k)
{
return vec3(
hash_vec2_to_float(k), hash_vec3_to_float(vec3(k, 1.0)), hash_vec3_to_float(vec3(k, 2.0)));
}
vec3 hash_vec4_to_vec3(vec4 k)
{
return vec3(hash_vec4_to_float(k.xyzw), hash_vec4_to_float(k.zxwy), hash_vec4_to_float(k.wzyx));
}

View File

@ -0,0 +1,61 @@
void node_tex_magic(
vec3 co, float scale, float distortion, float depth, out vec4 color, out float fac)
{
vec3 p = co * scale;
float x = sin((p.x + p.y + p.z) * 5.0);
float y = cos((-p.x + p.y - p.z) * 5.0);
float z = -cos((-p.x - p.y + p.z) * 5.0);
if (depth > 0) {
x *= distortion;
y *= distortion;
z *= distortion;
y = -cos(x - y + z);
y *= distortion;
if (depth > 1) {
x = cos(x - y - z);
x *= distortion;
if (depth > 2) {
z = sin(-x - y - z);
z *= distortion;
if (depth > 3) {
x = -cos(-x + y - z);
x *= distortion;
if (depth > 4) {
y = -sin(-x + y + z);
y *= distortion;
if (depth > 5) {
y = -cos(-x + y + z);
y *= distortion;
if (depth > 6) {
x = cos(x + y + z);
x *= distortion;
if (depth > 7) {
z = sin(x + y - z);
z *= distortion;
if (depth > 8) {
x = -cos(-x - y + z);
x *= distortion;
if (depth > 9) {
y = -sin(x - y + z);
y *= distortion;
}
}
}
}
}
}
}
}
}
}
if (distortion != 0.0) {
distortion *= 2.0;
x /= distortion;
y /= distortion;
z /= distortion;
}
color = vec4(0.5 - x, 0.5 - y, 0.5 - z, 1.0);
fac = (color.x + color.y + color.z) / 3.0;
}

View File

@ -0,0 +1,21 @@
/* White Noise */
void node_white_noise_1d(vec3 vector, float w, out float value)
{
value = hash_float_to_float(w);
}
void node_white_noise_2d(vec3 vector, float w, out float value)
{
value = hash_vec2_to_float(vector.xy);
}
void node_white_noise_3d(vec3 vector, float w, out float value)
{
value = hash_vec3_to_float(vector);
}
void node_white_noise_4d(vec3 vector, float w, out float value)
{
value = hash_vec4_to_float(vec4(vector, w));
}