init commit

This commit is contained in:
Azumgi 2018-01-22 12:10:53 +03:00
commit cbbebc0bd2
210 changed files with 49265 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
bin/
TEMP/
Docs/

147
FEATURES_LIST.MD Normal file
View file

@ -0,0 +1,147 @@
Goals
=====
The old Vermintide Mod Framework is a good tool, but it has a lot of legacy code, some of its components' code is hardly readable, and after the new workshop update it's more like a bunch of functions than a framework. So I decided to rewrite the whole thing from the scratch. My goals were:
1. Write VMF using self-documenting code. So it would be easy to read and maintain.
2. Move all the managing code from the mods to VMF if possible. So the modders will spend less time on writing managing code.
3. Make public VMF functions names short and clear. This and #2 will make mods' code shorter and clearer.
4. Make it easy for the mods to communicate with each other.
5. Make it work with bundled mods (new mod format).
In short, make VMF the real framework, which will provide a very user-friendly API and will do all the managing for the modders.
New Approach
============
From now on, I'll refer to old VMF as "Old-VMF" and to new VMF as "VMF".
Also, when comparing functions, (*) means same functionality and (+) means new functionality.
Mods Handling
-------------
The modders who's working with Old-VMF are used to the string `local mod, mod_name, oi = Mods.new_mod("ModName")`. That was an unnecessary step. The created "mod" was just a table which could be accessed from anywhere with `Mods.get_mod("ModName")` function, and all the interactions with VMF were made via public functions. So a lot of modders just skipped this step since they didn't need it.
But, from now on, the mod instance is not a table anymore, it's the object of the class `VMFMod` and it is the core element of any mod. It is the bridge between the mod and VMF. From this moment, there are only 2 public functions in VMF:
* `new_mod(mod_name)` - creates the new instance of `VMFMod` class object and returns it
* `get_mod(mod_name)` - returns already created mod instance or `nil` if it doesn't exist
All the other VMF functionality can be accessed only through the created `VMFMod` objects.
To understand what I'm talking about, just look at this little example:
```lua
local mod = new_mod("totally_useless_mod")
mod:hook("MatchmakingManager.update", function(func, ...)
func(...)
mod:echo("Some annoying message you'll see a lot of times no matter what")
end)
```
This approach allows to simplify a lot of things for the modder and makes it much easier for VMF to handle things on its own.
Basic functions and events
--------------------------
Now let's get to some basic functions.
Before:
`EchoConsole(message [string])`
After:
`mod:echo(message [string], show_mod_name [bool])`
(*) Shows the message in the chat.
(+) If `show_mod_name` is `true` the message will be prefixed with `[mod_name] `.
(+) The message will also appear in the log as `[ECHO][mod_name] message`
Before:
`Safe_pcall(...)`
After:
`mod:pcall(...)`
(*) Lets safely execute function, shows the error message in the chat
(+) Shows which mod failed to execute the code.
(+) Log it.
Also, there is the new thing in VMF: events. It's working like this:
1. The modder defines `mod.some_event_name = some_function`
2. Certain conditions for some_event are met
3. If the mod has `mod.some_event_name` defined, VMF calls it and passes specific event arguments
Here are some basic events:
`mod.unload()` - is called when the mod is about to be reloaded
`mod.update(dt)` - is called every tick
Now, the example from above, but using `update` event this time:
```lua
local mod = new_mod("totally_useless_mod")
mod.update = function(dt)
mod:echo("Some annoying message you'll see a lot of times no matter what")
end
```
Hooking system
--------------
Imagine that you're debugging your code and experimenting with different hooks, but some time later you notice, that some hook you deleted from the code 20 mins ago is still working. You do the /reload, but it doesn't help, so you have to restart the game to stop it. Sounds familiar? Well, that's not the case anymore. Now VMF removes all the hooks when it's about to be reloaded.
Before:
`Mods.hook.set(mod_name, "Object.Function", new_function)`
After:
`mod:hook("Object.Function", new_function)`
(*) Hooks the function
(+) It won't crash anymore if there's misprint in `"Object.Function"` or it doesn't exist. The error message with the mod name will be shown in the chat instead. Actually, there are many small changes like that, which will make debugging easier. There is no point to describe them all so I just skip them from now on.
Before:
`Mods.hook.enable(false, mod_name, "Object.Function")`
After:
`mod:hook_disable("Object.Function")`
(*) Disables hook (but not removes)
Before:
`Mods.hook.enable(true, mod_name, "Object.Function")`
After:
`mod:hook_enable("Object.Function")`
(*) Enables disabled hook
Before:
`Mods.hook.remove("Object.Function", mod_name)`
After:
`mod:hook_remove("Object.Function")`
(*) Removes hook
Also, new functions:
`mod:disable_all_hooks()`
`mod:enable_all_hooks()`
`mod:remove_all_hooks()`
(*) Disables/enables/removes all hooks for certain mod
Settings manager
-------------------------
This is the new thing. In the Old-VMF mods interacted with user settings via 'Application' directly. Now VMF is using settings manager. What's the difference?
* Settings manager operates settings within the mod namespace, so now you can define settings with the same name for different mods. Forget about `cb_bot_improvements_keep_tomes`. `keep_tomes` will do it.
* In Old-VMF, in order to actually save changed settings, some mods had to save settings to file right after changing it. That wasn't good for HDD. Now, setting manager takes care of it. It will automatically save changed settings to file when changing map / reloading VMF / closing options menu.
FUNCTIONS:
`mod:get(setting_name)` - returns setting value or `nil`
`mod:set(setting_name, setting_value, call_setting_changed_event)` - changes setting value. If `call_setting_changed_event` is `true`, the `setting_changed` event will be called for the mod.
EVENT:
`mod.setting_changed(setting_name)` - is called whenever something changes mods setting with `call_setting_changed_event` set to `true`.
With this event you won't need to repeatedly check if some option is changed. By default, after mod initilizing, the only thing that will call `mod:set` is the the VMF options menu. And it will always call `setting_changed` event.
Localization
Gui (WIP)
Options menu (WIP)
Keybindings (Will do)
Network (Will do)
Actions
Chat
Game modes
Debug modules

4
README.MD Normal file
View file

@ -0,0 +1,4 @@
1) Clone project somewhere
2) Make a hardlink of SDK bin folder inside cloned project
`mklink /J "C:\Vermintide\VMF_SDK\bin" "C:\Program Files (x86)\Steam\steamapps\common\Warhammer End Times Vermintide Mod Tools\bin"`
3) Run .bat-file every time you need to compile project

3
compile_mod.bat Normal file
View file

@ -0,0 +1,3 @@
"./bin/stingray_win64_dev_x64.exe" --compile-for win32 --source-dir vmf_source --data-dir TEMP/compile --bundle-dir TEMP/bundle
copy TEMP\bundle\*. "C:\Programs (x86)\Steam\steamapps\common\Warhammer End Times Vermintide\bundle\mods"
pause

View file

@ -0,0 +1,13 @@
group = "Math"
display_name = "Absolute"
inputs = {
"f36f88b8-8111-4fc3-b56c-32a80e7db111" = { name = "a" display_name = "A" type = "auto" }
}
output = {
type = { typeof: "a" }
}
code = """
RESULT(abs(a));
"""

View file

@ -0,0 +1,14 @@
group = "Math"
display_name = "Add"
inputs = {
"f72597c4-7487-419a-affb-df690e6582e1" = { name = "a" display_name = "A" type = "auto" }
"0806db0d-2c4a-43ca-99cc-f5a2f036a8e8" = { name = "b" display_name = "B" type = "auto" }
}
output = {
type = { largestof: ["a", "b"] }
}
code = """
RESULT(a + b);
"""

View file

@ -0,0 +1,21 @@
group = "Particle Billboard"
display_name = "Particle ID"
imports = {
particle_id = {
type = "float"
semantic = "TEXCOORD5"
domain = "vertex"
}
}
output = {
type = { typeof: "particle_id" }
}
code = """
RESULT(particle_id);
"""

View file

@ -0,0 +1,20 @@
group = "Particle Billboard"
display_name = "UV Frame"
imports = {
uv_frame = {
type = "float"
domain = "vertex"
output_channel = "uv_frame"
}
}
defines = ["NEEDS_UV_ANIMATION"]
output = {
type = { typeof: "uv_frame" }
}
code = """
RESULT(uv_frame);
"""

View file

@ -0,0 +1,20 @@
group = "Particle Billboard"
display_name = "UV Scale"
imports = {
uv_scale = {
type = "float2"
domain = "vertex"
output_channel = "uv_scale"
}
}
defines = ["NEEDS_UV_SCALE"]
output = {
type = { typeof: "uv_scale" }
}
code = """
RESULT(uv_scale);
"""

View file

@ -0,0 +1,41 @@
group = "Particle Billboard"
display_name = "Vertex Color"
imports = {
color = {
type = "float4"
semantic = "COLOR"
domain = "vertex"
}
}
output = {
type = { typeof: "color" }
}
options = {
"c5b9991a-f14d-4f37-ad66-8a41103d5967" = "VC_COMPRESSED"
"71f11ae4-8f03-4a75-b3a0-4899eff35d29" = "FAST_GAMMA_DECODE"
"dbf19835-b8f4-4a3c-829b-c5fafdb60989" = "FAST_GAMMA_DECODE_ALPHA"
}
ui = [
{ type = "checkbox" display_name = "Fast Gamma Decode" option = "71f11ae4-8f03-4a75-b3a0-4899eff35d29" }
{ type = "checkbox" display_name = "Fast Gamma Decode Alpha" option = "dbf19835-b8f4-4a3c-829b-c5fafdb60989" }
{ type = "checkbox" display_name = "Compressed" option = "c5b9991a-f14d-4f37-ad66-8a41103d5967" }
]
code = """
#if defined(FAST_GAMMA_DECODE)
color = fast_gamma_to_linear_rgb(color);
#endif
#if defined(FAST_GAMMA_DECODE_ALPHA)
color.a *= color.a;
#endif
#if defined(VC_COMPRESSED)
color = decode_vertex_color(color);
#endif
RESULT(color);
"""

View file

@ -0,0 +1,59 @@
group = "Particle Billboard"
display_name = "Soft Particles"
depends_on = [
"core/stingray_renderer/output_nodes/standard_base"
"core/stingray_renderer/output_nodes/unlit_base",
"core/stingray_renderer/output_nodes/particle_base",
"core/stingray_renderer/output_nodes/particle_gbuffer_base",
"core/stingray_renderer/output_nodes/particle_distortion_base"]
inputs = {
"a9330f88-8b4b-4979-a25e-e7fbe031eabd" = {
name = "opacity"
display_name = "Opacity"
type = "scalar"
domain = "pixel"
is_required = true
}
"1ee9af1f-65f2-4739-ad28-5ea6a0e68fc3" = {
name = "depth_fade_distance"
display_name = "Depth Fade Distance"
type = "scalar"
domain = "pixel"
is_required = true
}
}
imports = {
pixel_depth = {
type = "float"
domain = "pixel"
output_channel = "pixel_depth"
}
screen_pos = {
type = "float2"
domain = "pixel"
output_channel = "screen_pos"
}
}
defines = ["NEEDS_PIXEL_DEPTH", "NEEDS_LINEAR_DEPTH", "NEEDS_SCREEN_POS"]
domain = "pixel"
output = {
type = { typeof: "opacity" }
}
language = "hlsl"
code = """
#if defined(HAS_LINEAR_DEPTH)
float gbuffer_depth = gbuffer_decode_depth(TEX2D(linear_depth, screen_pos.xy));
float result = opacity * saturate(abs(gbuffer_depth - pixel_depth) / depth_fade_distance);
#else
float result = opacity;
#endif
RESULT(result);
"""

View file

@ -0,0 +1,21 @@
group = "Particle Billboard"
display_name = "Particle UV"
imports = {
// TODO: fix
//"on_platform(GL)": {
// corner_info = { type = "float2" semantic = "COLOR1" domain = "vertex" }
//}
//"!on_platform(GL)": {
corner_info = { type = "float2" semantic = "POSITION1" domain = "vertex" }
//}
}
domain = "vertex"
output = {
type = "float2"
}
code = """
RESULT(corner_info * float2(1,-1) * 0.5 + 0.5);
"""

View file

@ -0,0 +1,40 @@
group = "Particle Billboard"
display_name = "UV Animation"
inputs = {
"8a8a12c1-e3b5-4666-a9dd-b6b083f75e7a" = { name = "uv" display_name = "UV" type = "float2" is_required = true }
"242d1648-a626-445b-9534-bccec094112f" = { name = "frame_size" display_name = "Frame Size" type = "float2" is_required = true }
"c5823c75-4ae5-4c71-b070-315fa4d03e8e" = { name = "graph_uv_frame" display_name = "UV Frame (Debug Only)" type = { scalar: ["HAS_UV_FRAME"] } is_required = false }
}
imports = {
vertex_uv_frame = {
type = "float"
domain = "vertex"
output_channel = "uv_frame"
}
}
defines = ["NEEDS_UV_ANIMATION"]
output = {
type = { typeof: "uv" }
}
code = """
float uv_frame;
#if defined(HAS_UV_FRAME)
uv_frame = graph_uv_frame;
#else
uv_frame = vertex_uv_frame;
#endif
uv *= frame_size;
float n_frames = 1.0 / frame_size.x;
int frame_x = fmod(uv_frame, n_frames);
int frame_y = uv_frame / n_frames;
float2 offset = float2(frame_x * frame_size.x, frame_y * frame_size.y);
uv += offset;
RESULT(uv);
"""

View file

@ -0,0 +1,227 @@
group = "Fatshark"
display_name = "Black-Body Radiation (In progress)"
inputs = {
"8deba514-fbf0-4f71-808a-5654f82238b0" = { name = "T" display_name = "T" type = "scalar" is_required = true }
"149ae0c3-db91-4009-9aed-45281b8e3d4c" = { name = "blend" display_name = "Blend" type = { scalar: ["HAS_BLEND_FACTOR"] } is_required = false }
}
output = {
type = "float3"
}
code = """
float3 table[89] = {
float3(3.769647E-03, 4.146161E-04, 1.847260E-02),
float3(9.382967E-03, 1.059646E-03, 4.609784E-02),
float3(2.214302E-02, 2.452194E-03, 1.096090E-01),
float3(4.742986E-02, 4.971717E-03, 2.369246E-01),
float3(8.953803E-02, 9.079860E-03, 4.508369E-01),
float3(1.446214E-01, 1.429377E-02, 7.378822E-01),
float3(2.035729E-01, 2.027369E-02, 1.051821E+00),
float3(2.488523E-01, 2.612106E-02, 1.305008E+00),
float3(2.918246E-01, 3.319038E-02, 1.552826E+00),
float3(3.227087E-01, 4.157940E-02, 1.748280E+00),
float3(3.482554E-01, 5.033657E-02, 1.917479E+00),
float3(3.418483E-01, 5.743393E-02, 1.918437E+00),
float3(3.224637E-01, 6.472352E-02, 1.848545E+00),
float3(2.826646E-01, 7.238339E-02, 1.664439E+00),
float3(2.485254E-01, 8.514816E-02, 1.522157E+00),
float3(2.219781E-01, 1.060145E-01, 1.428440E+00),
float3(1.806905E-01, 1.298957E-01, 1.250610E+00),
float3(1.291920E-01, 1.535066E-01, 9.991789E-01),
float3(8.182895E-02, 1.788048E-01, 7.552379E-01),
float3(4.600865E-02, 2.064828E-01, 5.617313E-01),
float3(2.083981E-02, 2.379160E-01, 4.099313E-01),
float3(7.097731E-03, 2.850680E-01, 3.105939E-01),
float3(2.461588E-03, 3.483536E-01, 2.376753E-01),
float3(3.649178E-03, 4.277595E-01, 1.720018E-01),
float3(1.556989E-02, 5.204972E-01, 1.176796E-01),
float3(4.315171E-02, 6.206256E-01, 8.283548E-02),
float3(7.962917E-02, 7.180890E-01, 5.650407E-02),
float3(1.268468E-01, 7.946448E-01, 3.751912E-02),
float3(1.818026E-01, 8.575799E-01, 2.438164E-02),
float3(2.405015E-01, 9.071347E-01, 1.566174E-02),
float3(3.098117E-01, 9.544675E-01, 9.846470E-03),
float3(3.804244E-01, 9.814106E-01, 6.131421E-03),
float3(4.494206E-01, 9.890228E-01, 3.790291E-03),
float3(5.280233E-01, 9.994608E-01, 2.327186E-03),
float3(6.133784E-01, 9.967737E-01, 1.432128E-03),
float3(7.016774E-01, 9.902549E-01, 8.822531E-04),
float3(7.967750E-01, 9.732611E-01, 5.452416E-04),
float3(8.853376E-01, 9.424569E-01, 3.386739E-04),
float3(9.638388E-01, 8.963613E-01, 2.117772E-04),
float3(1.051011E+00, 8.587203E-01, 1.335031E-04),
float3(1.109767E+00, 8.115868E-01, 8.494468E-05),
float3(1.143620E+00, 7.544785E-01, 5.460706E-05),
float3(1.151033E+00, 6.918553E-01, 3.549661E-05),
float3(1.134757E+00, 6.270066E-01, 2.334738E-05),
float3(1.083928E+00, 5.583746E-01, 1.554631E-05),
float3(1.007344E+00, 4.895950E-01, 1.048387E-05),
float3(9.142877E-01, 4.229897E-01, 0.000000E+00),
float3(8.135565E-01, 3.609245E-01, 0.000000E+00),
float3(6.924717E-01, 2.980865E-01, 0.000000E+00),
float3(5.755410E-01, 2.416902E-01, 0.000000E+00),
float3(4.731224E-01, 1.943124E-01, 0.000000E+00),
float3(3.844986E-01, 1.547397E-01, 0.000000E+00),
float3(2.997374E-01, 1.193120E-01, 0.000000E+00),
float3(2.277792E-01, 8.979594E-02, 0.000000E+00),
float3(1.707914E-01, 6.671045E-02, 0.000000E+00),
float3(1.263808E-01, 4.899699E-02, 0.000000E+00),
float3(9.224597E-02, 3.559982E-02, 0.000000E+00),
float3(6.639960E-02, 2.554223E-02, 0.000000E+00),
float3(4.710606E-02, 1.807939E-02, 0.000000E+00),
float3(3.292138E-02, 1.261573E-02, 0.000000E+00),
float3(2.262306E-02, 8.661284E-03, 0.000000E+00),
float3(1.575417E-02, 6.027677E-03, 0.000000E+00),
float3(1.096778E-02, 4.195941E-03, 0.000000E+00),
float3(7.608750E-03, 2.910864E-03, 0.000000E+00),
float3(5.214608E-03, 1.995557E-03, 0.000000E+00),
float3(3.569452E-03, 1.367022E-03, 0.000000E+00),
float3(2.464821E-03, 9.447269E-04, 0.000000E+00),
float3(1.703876E-03, 6.537050E-04, 0.000000E+00),
float3(1.186238E-03, 4.555970E-04, 0.000000E+00),
float3(8.269535E-04, 3.179738E-04, 0.000000E+00),
float3(5.758303E-04, 2.217445E-04, 0.000000E+00),
float3(4.058303E-04, 1.565566E-04, 0.000000E+00),
float3(2.856577E-04, 1.103928E-04, 0.000000E+00),
float3(2.021853E-04, 7.827442E-05, 0.000000E+00),
float3(1.438270E-04, 5.578862E-05, 0.000000E+00),
float3(1.024685E-04, 3.981884E-05, 0.000000E+00),
float3(7.347551E-05, 2.860175E-05, 0.000000E+00),
float3(5.259870E-05, 2.051259E-05, 0.000000E+00),
float3(3.806114E-05, 1.487243E-05, 0.000000E+00),
float3(2.758222E-05, 1.080001E-05, 0.000000E+00),
float3(2.004122E-05, 7.863920E-06, 0.000000E+00),
float3(1.458792E-05, 5.736935E-06, 0.000000E+00),
float3(1.068141E-05, 4.211597E-06, 0.000000E+00),
float3(7.857521E-06, 3.106561E-06, 0.000000E+00),
float3(5.768284E-06, 2.286786E-06, 0.000000E+00),
float3(4.259166E-06, 1.693147E-06, 0.000000E+00),
float3(3.167765E-06, 1.262556E-06, 0.000000E+00),
float3(2.358723E-06, 9.422514E-07, 0.000000E+00),
float3(1.762465E-06, 7.053860E-07, 0.000000E+00)
};
float3 table2[89] = {
float3(0.003769647000000E6, 0.000414616100000E6, 0.018472600000000E6),
float3(0.009382967000000E6, 0.001059646000000E6, 0.046097840000000E6),
float3(0.022143020000000E6, 0.002452194000000E6, 0.109609000000000E6),
float3(0.047429860000000E6, 0.004971717000000E6, 0.236924600000000E6),
float3(0.089538030000000E6, 0.009079860000000E6, 0.450836900000000E6),
float3(0.144621400000000E6, 0.014293770000000E6, 0.737882200000000E6),
float3(0.203572900000000E6, 0.020273690000000E6, 1.051821000000000E6),
float3(0.248852300000000E6, 0.026121060000000E6, 1.305008000000000E6),
float3(0.291824600000000E6, 0.033190380000000E6, 1.552826000000000E6),
float3(0.322708700000000E6, 0.041579400000000E6, 1.748280000000000E6),
float3(0.348255400000000E6, 0.050336570000000E6, 1.917479000000000E6),
float3(0.341848300000000E6, 0.057433930000000E6, 1.918437000000000E6),
float3(0.322463700000000E6, 0.064723520000000E6, 1.848545000000000E6),
float3(0.282664600000000E6, 0.072383390000000E6, 1.664439000000000E6),
float3(0.248525400000000E6, 0.085148160000000E6, 1.522157000000000E6),
float3(0.221978100000000E6, 0.106014500000000E6, 1.428440000000000E6),
float3(0.180690500000000E6, 0.129895700000000E6, 1.250610000000000E6),
float3(0.129192000000000E6, 0.153506600000000E6, 0.999178900000000E6),
float3(0.081828950000000E6, 0.178804800000000E6, 0.755237900000000E6),
float3(0.046008650000000E6, 0.206482800000000E6, 0.561731300000000E6),
float3(0.020839810000000E6, 0.237916000000000E6, 0.409931300000000E6),
float3(0.007097731000000E6, 0.285068000000000E6, 0.310593900000000E6),
float3(0.002461588000000E6, 0.348353600000000E6, 0.237675300000000E6),
float3(0.003649178000000E6, 0.427759500000000E6, 0.172001800000000E6),
float3(0.015569890000000E6, 0.520497200000000E6, 0.117679600000000E6),
float3(0.043151710000000E6, 0.620625600000000E6, 0.082835480000000E6),
float3(0.079629170000000E6, 0.718089000000000E6, 0.056504070000000E6),
float3(0.126846800000000E6, 0.794644800000000E6, 0.037519120000000E6),
float3(0.181802600000000E6, 0.857579900000000E6, 0.024381640000000E6),
float3(0.240501500000000E6, 0.907134700000000E6, 0.015661740000000E6),
float3(0.309811700000000E6, 0.954467500000000E6, 0.009846470000000E6),
float3(0.380424400000000E6, 0.981410600000000E6, 0.006131421000000E6),
float3(0.449420600000000E6, 0.989022800000000E6, 0.003790291000000E6),
float3(0.528023300000000E6, 0.999460800000000E6, 0.002327186000000E6),
float3(0.613378400000000E6, 0.996773700000000E6, 0.001432128000000E6),
float3(0.701677400000000E6, 0.990254900000000E6, 0.000882253100000E6),
float3(0.796775000000000E6, 0.973261100000000E6, 0.000545241600000E6),
float3(0.885337600000000E6, 0.942456900000000E6, 0.000338673900000E6),
float3(0.963838800000000E6, 0.896361300000000E6, 0.000211777200000E6),
float3(1.051011000000000E6, 0.858720300000000E6, 0.000133503100000E6),
float3(1.109767000000000E6, 0.811586800000000E6, 0.000084944680000E6),
float3(1.143620000000000E6, 0.754478500000000E6, 0.000054607060000E6),
float3(1.151033000000000E6, 0.691855300000000E6, 0.000035496610000E6),
float3(1.134757000000000E6, 0.627006600000000E6, 0.000023347380000E6),
float3(1.083928000000000E6, 0.558374600000000E6, 0.000015546310000E6),
float3(1.007344000000000E6, 0.489595000000000E6, 0.000010483870000E6),
float3(0.914287700000000E6, 0.422989700000000E6, 0E6),
float3(0.813556500000000E6, 0.360924500000000E6, 0E6),
float3(0.692471700000000E6, 0.298086500000000E6, 0E6),
float3(0.575541000000000E6, 0.241690200000000E6, 0E6),
float3(0.473122400000000E6, 0.194312400000000E6, 0E6),
float3(0.384498600000000E6, 0.154739700000000E6, 0E6),
float3(0.299737400000000E6, 0.119312000000000E6, 0E6),
float3(0.227779200000000E6, 0.089795940000000E6, 0E6),
float3(0.170791400000000E6, 0.066710450000000E6, 0E6),
float3(0.126380800000000E6, 0.048996990000000E6, 0E6),
float3(0.092245970000000E6, 0.035599820000000E6, 0E6),
float3(0.066399600000000E6, 0.025542230000000E6, 0E6),
float3(0.047106060000000E6, 0.018079390000000E6, 0E6),
float3(0.032921380000000E6, 0.012615730000000E6, 0E6),
float3(0.022623060000000E6, 0.008661284000000E6, 0E6),
float3(0.015754170000000E6, 0.006027677000000E6, 0E6),
float3(0.010967780000000E6, 0.004195941000000E6, 0E6),
float3(0.007608750000000E6, 0.002910864000000E6, 0E6),
float3(0.005214608000000E6, 0.001995557000000E6, 0E6),
float3(0.003569452000000E6, 0.001367022000000E6, 0E6),
float3(0.002464821000000E6, 0.000944726900000E6, 0E6),
float3(0.001703876000000E6, 0.000653705000000E6, 0E6),
float3(0.001186238000000E6, 0.000455597000000E6, 0E6),
float3(0.000826953500000E6, 0.000317973800000E6, 0E6),
float3(0.000575830300000E6, 0.000221744500000E6, 0E6),
float3(0.000405830300000E6, 0.000156556600000E6, 0E6),
float3(0.000285657700000E6, 0.000110392800000E6, 0E6),
float3(0.000202185300000E6, 0.000078274420000E6, 0E6),
float3(0.000143827000000E6, 0.000055788620000E6, 0E6),
float3(0.000102468500000E6, 0.000039818840000E6, 0E6),
float3(0.000073475510000E6, 0.000028601750000E6, 0E6),
float3(0.000052598700000E6, 0.000020512590000E6, 0E6),
float3(0.000038061140000E6, 0.000014872430000E6, 0E6),
float3(0.000027582220000E6, 0.000010800010000E6, 0E6),
float3(0.000020041220000E6, 0.000007863920000E6, 0E6),
float3(0.000014587920000E6, 0.000005736935000E6, 0E6),
float3(0.000010681410000E6, 0.000004211597000E6, 0E6),
float3(0.000007857521000E6, 0.000003106561000E6, 0E6),
float3(0.000005768284000E6, 0.000002286786000E6, 0E6),
float3(0.000004259166000E6, 0.000001693147000E6, 0E6),
float3(0.000003167765000E6, 0.000001262556000E6, 0E6),
float3(0.000002358723000E6, 0.000000942251400E6, 0E6),
float3(0.000001762465000E6, 0.000000705386000E6, 0E6)
};
// TODO: convert to RGB
float3x3 xyz2srgb = {
3.2404542, -1.5371385, -0.4985314,
-0.9692660, 1.8760108, 0.0415560,
0.0556434, -0.2040259, 1.0572252
};
float3x3 xyz2rgb = {
0.41847, -0.15866, -0.082835,
-0.091169, 0.25243, 0.015708,
0.00092090, -0.0025498, 0.17860
};
float3 XYZ = float3(0, 0, 0);
[unroll]
for (uint i = 0u; i < 89u; ++i) {
float w = (390.0 + 5.0*float(i-1));
XYZ += (3.7402 * table2[i])/(pow(w, 5.0) * 1E-14 * (exp(14384800.0/(w*T)) - 1.0));
//XYZ += 3.7402/(pow(w, 5.0) * 1E-20 * (exp(1.43848/(w*0.0000001*T)) - 1.0)) * table[i];
}
XYZ *= 5.0; // integrate with step size
float3 result = mul(xyz2srgb, XYZ);
#if defined(HAS_BLEND_FACTOR)
//result = lerp(result, normalize(result), blend);
//TODO: convert to xyZ space and lerp http://magnuswrenninge.com/content/pubs/ProductionVolumeRenderingSystems2011.pdf
#endif
RESULT(result);
"""

View file

@ -0,0 +1,49 @@
group = "Utility"
display_name = "Blend Normals"
inputs = {
"67493629-fffe-4fe8-bf7c-0c6467b09013" = { name = "base" display_name = "Base" type = "vector3" }
"22ed0f5a-9b5c-4e06-80d6-46eec7c75e34" = { name = "detail" display_name = "Detail" type = "vector3" }
}
output = {
type = { typeof: "base" }
}
options = {
"8ad8224b-0141-4598-8240-c9d6fbbd2508" = "WHITEOUT"
"f2ff7295-8050-4f0c-ba42-3d1aa83de416" = "IGNOREZ"
"bac6bd71-9ed1-4948-886f-00fb6cf48489" = "REORIENTED"
}
ui = [
{
type = "drop_down"
display_name = "Method"
options = {
"Whiteout" = "8ad8224b-0141-4598-8240-c9d6fbbd2508"
"Ignore Detail Z" = "f2ff7295-8050-4f0c-ba42-3d1aa83de416"
"Reoriented" = "bac6bd71-9ed1-4948-886f-00fb6cf48489"
}
default = "8ad8224b-0141-4598-8240-c9d6fbbd2508"
}
]
code = """
// we assume the user has set the sample_texture node to normal_map and
// the decode step (*2 -1) has already happened on our inputs
float3 blended_normals;
float2 xy = base.xy + detail.xy;
#if defined(IGNOREZ)
blended_normals = normalize(new_float3(xy.x, xy.y, base.z));
#elif defined(REORIENTED)
// Since our decode_normal step (*2 -1) already unpacks the normals, we compensate the
// original math below to give the same results
float3 t = new_float3(base.x, base.y, base.z + 1.0);
float3 u = detail.xyz * new_float3(-1.0, -1.0, 1.0);
blended_normals = normalize(t*dot(t, u) - u*t.z);
#else // whiteout
blended_normals = normalize(new_float3(xy.x, xy.y, base.z*detail.z));
#endif
RESULT(blended_normals);
"""

View file

@ -0,0 +1,18 @@
group = "Input"
display_name = "Camera Position"
imports = {
camera_pos = {
type = "float3"
domain = "global"
source = "engine"
}
}
output = {
type = { typeof: "camera_pos" }
}
code = """
RESULT(camera_pos);
"""

View file

@ -0,0 +1,13 @@
group = "Math"
display_name = "Ceil"
inputs = {
"15a35abd-ee72-4498-8233-3542fde59a81" = { name = "a" display_name = "A" type = "auto" }
}
output = {
type = { typeof: "a" }
}
code = """
RESULT(ceil(a));
"""

View file

@ -0,0 +1,15 @@
group = "Math"
display_name = "Clamp"
inputs = {
"be3ca146-3448-40d8-bd4b-da66ef6ff935" = { name = "x" display_name = "Value" type = "auto" }
"6f471281-8e67-4fd5-978f-5e378ef0668d" = { name = "max" display_name = "Max" type = "auto" }
"e64169ad-12a5-41ba-a708-4cc5526e1ea0" = { name = "min" display_name = "Min" type = "auto" }
}
output = {
type = { typeof: "x" }
}
code = """
RESULT(clamp(x,min,max));
"""

View file

@ -0,0 +1,19 @@
group = "Color Map"
display_name = "Jet"
inputs = {
"ff0fa2dd-930d-44f4-ab07-bbf75dd71f2e" = { name = "v" display_name = "A" type = "scalar" }
}
output = {
type = "float3"
}
code = """
v *= 4.0f;
float3 result = float3(
saturate(min(v - 1.5f, -v + 4.5f)),
saturate(min(v - 0.5f, -v + 3.5f)),
saturate(min(v + 0.5f, -v + 2.5f)));
RESULT(result);
"""

View file

@ -0,0 +1,13 @@
group = "Constant"
display_name = "Constant Scalar"
inputs = {
"c4d6bc08-c489-430f-a836-ed490e59c3f9" = { name = "a" display_name = "A" type = "scalar"}
}
output = {
type = { typeof: "a" }
}
code = """
RESULT(a);
"""

View file

@ -0,0 +1,13 @@
group = "Constant"
display_name = "Constant Vector2"
inputs = {
"6ff26be7-68a1-4b89-b9dd-551d216086c2" = { name = "a" display_name = "XY" type = "float2"}
}
output = {
type = { typeof: "a" }
}
code = """
RESULT(a);
"""

View file

@ -0,0 +1,13 @@
group = "Constant"
display_name = "Constant Vector3"
inputs = {
"6ff26be7-68a1-4b89-b9dd-551d216086c2" = { name = "a" display_name = "RGB" type = "float3"}
}
output = {
type = { typeof: "a" }
}
code = """
RESULT(a);
"""

View file

@ -0,0 +1,13 @@
group = "Constant"
display_name = "Constant Vector4"
inputs = {
"6ff26be7-68a1-4b89-b9dd-551d216086c2" = { name = "a" display_name = "RGBA" type = "float4"}
}
output = {
type = { typeof: "a" }
}
code = """
RESULT(a);
"""

View file

@ -0,0 +1,14 @@
group = "Construct"
display_name = "Construct Vector2"
inputs = {
"8231a2cb-b751-4ecd-94eb-3e6d048ba173" = { name = "x" display_name = "X" type = "scalar"}
"46536067-b418-47a5-bc6b-234972e963e9" = { name = "y" display_name = "Y" type = "scalar"}
}
output = {
type = "float2"
}
code = """
RESULT(float2(x,y));
"""

View file

@ -0,0 +1,15 @@
group = "Construct"
display_name = "Construct Vector3"
inputs = {
"c010729f-6137-412c-99a5-f263fdeaa53c" = { name = "r" display_name = "R" type = "scalar"}
"d6179868-364c-4f38-bdc0-ea639b305015" = { name = "g" display_name = "G" type = "scalar"}
"6cce8b1d-5c70-44ea-bea3-b1ceafeb750e" = { name = "b" display_name = "B" type = "scalar"}
}
output = {
type = "float3"
}
code = """
RESULT(float3(r,g,b));
"""

View file

@ -0,0 +1,16 @@
group = "Construct"
display_name = "Construct Vector4"
inputs = {
"e51d4226-628e-4714-809e-af60a5a09c87" = { name = "r" display_name = "R" type = "scalar"}
"00e9b0e5-91d3-4102-8909-de18ecefb1b5" = { name = "g" display_name = "G" type = "scalar"}
"49508d27-9f26-4716-aba6-3b2684ba4b08" = { name = "b" display_name = "B" type = "scalar"}
"d2e05875-2413-4431-af0f-0de8658cff7d" = { name = "a" display_name = "A" type = "scalar"}
}
output = {
type = "float4"
}
code = """
RESULT(float4(r,g,b,a));
"""

View file

@ -0,0 +1,13 @@
group = "Math"
display_name = "Cosine"
inputs = {
"d0ff3f8a-3bc5-4a02-8edf-562e3985985e" = { name = "a" display_name = "Angle" type = "auto" }
}
output = {
type = { typeof: "a" }
}
code = """
RESULT(cos(a));
"""

View file

@ -0,0 +1,14 @@
group = "Math"
display_name = "Cross Product"
inputs = {
"316b7c7c-7541-4973-ba8d-322cd8525716" = { name = "a" display_name = "A" type = "vector3" }
"295b5797-0402-479f-93cc-77708fcd453f" = { name = "b" display_name = "B" type = "vector3" }
}
output = {
type = { typeof: "a" }
}
code = """
RESULT(cross(a,b));
"""

View file

@ -0,0 +1,18 @@
group = "Input"
display_name = "Time"
imports = {
time = {
type = "float"
domain = "global"
source = "engine"
}
}
output = {
type = { typeof: "time" }
}
code = """
RESULT(time);
"""

View file

@ -0,0 +1,19 @@
group = "Math"
display_name = "Ddx"
inputs = {
"F301E39A-AA1D-4F5E-BA28-3BEFBEB7AF1D" = { name = "a" display_name = "A" type = "auto" }
}
domain = "pixel"
output = {
type = { typeof: "a" }
}
code = """
#if defined(STAGE_PIXEL)
RESULT(ddx(a));
#else
RESULT(new_float3(0, 0, 0));
#endif
"""

View file

@ -0,0 +1,19 @@
group = "Math"
display_name = "Ddy"
inputs = {
"FF05235F-0371-4500-8CD3-2B849D67EA92" = { name = "a" display_name = "A" type = "auto" }
}
domain = "pixel"
output = {
type = { typeof: "a" }
}
code = """
#if defined(STAGE_PIXEL)
RESULT(ddy(a));
#else
RESULT(a); // Need a way to splat a vector of 'a_type' to return 0
#endif
"""

View file

@ -0,0 +1,23 @@
group = "Decal"
display_name = "Decal Box Edge Distance"
depends_on = ["core/stingray_renderer/output_nodes/decal_base"]
defines = ["NEEDS_OBJECT_POSITION"]
imports = {
object_position = {
type = "float3"
domain = "pixel"
output_channel = "object_position"
}
}
output = {
type = "float"
}
code = """
float3 dist = min(object_position - bounding_volume._m00_m01_m02, bounding_volume._m10_m11_m12 - object_position) * bounding_volume._m20_m21_m22;
RESULT(min(dist.x, min(dist.y, dist.z)));
"""

View file

@ -0,0 +1,66 @@
group = "Decal"
display_name = "Decal Parallax / Bump Offset"
depends_on = ["core/stingray_renderer/output_nodes/decal_base"]
// scale and bias map the height value into a range that better represents the physical properties (size) of the surface
inputs = {
"95FB056C-9DDF-434C-8D8E-A03F30F5C42D" = { name = "uv" display_name = "UV" type = "vector2"}
"B897C7FC-96E3-45D9-9AF1-A1C797386C61" = { name = "height" display_name = "Height" type = "scalar"}
"6046b049-ae9d-49f6-9f75-58a34a3bac15" = { name = "scale" display_name = "Parallax Scale" is_required = false type = { scalar: ["HAS_SCALE"] }}
"ed989589-8b44-4ec4-b5a7-8fb5cd739854" = { name = "bias" display_name = "Parallax Bias" is_required = false type = { scalar: ["HAS_BIAS"] }}
}
defines = ["NEEDS_TANGENT_SPACE", "NEEDS_EYE_VECTOR"]
imports = {
eye_vector = {
type = "float3"
domain = "pixel"
output_channel = "eye_vector"
}
tsm0 = {
type = "float3"
domain = "pixel"
output_channel = "tsm0"
}
tsm1 = {
type = "float3"
domain = "pixel"
output_channel = "tsm1"
}
tsm2 = {
type = "float3"
domain = "pixel"
output_channel = "tsm2"
}
}
output = {
type = { typeof: "uv" }
}
code = """
float3 dir = normalize(eye_vector);
// Get camera vector in tangent space
float3 dir_ts = new_float3(
dot(dir, float3(tsm0.x, tsm1.x, tsm2.x)),
dot(dir, float3(tsm0.y, tsm1.y, tsm2.y)),
dot(dir, float3(tsm0.z, tsm1.z, tsm2.z)));
float2 norm_dir_ts = normalize(dir_ts).xy;
#if defined(HAS_SCALE)
float scale_value = scale;
#else
float scale_value = 0.04;
#endif
#if defined(HAS_BIAS)
float bias_value = bias;
#else
float bias_value = 0.02;
#endif
RESULT(uv + float2(norm_dir_ts.x, -norm_dir_ts.y) * (height*scale_value - bias_value));
"""

View file

@ -0,0 +1,39 @@
group = "Decal"
display_name = "Decal Tangent To World"
depends_on = ["core/stingray_renderer/output_nodes/decal_base"]
inputs = {
"f72597c4-7487-419a-affb-df690e6582e1" = { name = "v" display_name = "Vector" type = "float3" }
}
defines = ["NEEDS_TANGENT_SPACE"]
imports = {
tsm0 = {
type = "float3"
domain = "pixel"
output_channel = "tsm0"
}
tsm1 = {
type = "float3"
domain = "pixel"
output_channel = "tsm1"
}
tsm2 = {
type = "float3"
domain = "pixel"
output_channel = "tsm2"
}
}
output = {
type = { typeof: "v" }
}
code = """
float3 res = float3(
dot(v, tsm0),
dot(v, tsm1),
dot(v, tsm2));
RESULT(normalize(res));
"""

View file

@ -0,0 +1,19 @@
group = "Decal"
display_name = "Decal UV"
depends_on = ["core/stingray_renderer/output_nodes/decal_base"]
imports = {
decal_uv = {
type = "float2"
domain = "pixel"
output_channel = "decal_uv"
}
}
output = {
type = { typeof: "decal_uv" }
}
code = """
RESULT(decal_uv);
"""

View file

@ -0,0 +1,22 @@
group = "Decal"
display_name = "Decal World Position"
depends_on = ["core/stingray_renderer/output_nodes/decal_base"]
defines = ["NEEDS_WORLD_SPACE_POSITION"]
imports = {
world_position = {
type = "float3"
domain = "pixel"
output_channel = "world_position"
}
}
output = {
type = "float3"
}
code = """
RESULT(world_position);
"""

View file

@ -0,0 +1,28 @@
group = "Utility"
display_name = "Desaturation"
// Luminance controls what channel is brighter then another. E.g. Green is brighter then red and blue when desaturated
inputs = {
"1E4F2254-F27B-418F-AB46-9229A599980F" = { name = "color" display_name = "Color" type = "vector3" }
"FFCB2ED4-2061-432C-8AB5-E1A9EDED9038" = { name = "amount" display_name = "Amount" is_required = false type = { scalar: ["HAS_AMOUNT"] } }
"fb2bf997-f6f1-42a0-bd29-b6a12f9f3417" = { name = "luminance" display_name = "Luminance" is_required = false type = { vector3: ["HAS_LUM"] }}
}
output = {
type = { typeof: "color" }
}
code = """
#if defined(HAS_LUM)
float3 lum = luminance;
#else
float3 lum = float3(0.3, 0.6, 0.1);
#endif
float l = dot(lum, color);
float3 desaturated = new_float3(l, l, l);
#if defined(HAS_AMOUNT)
RESULT(lerp(color, desaturated, amount));
#else
RESULT(desaturated);
#endif
"""

View file

@ -0,0 +1,14 @@
group = "Math"
display_name = "Distance"
inputs = {
"4baab897-370b-4def-9790-ece5b1abf91f" = { name = "a" display_name = "A" type = { vector2:[] vector3:[] vector4:[] } }
"6fc97f2b-a585-4430-9f2d-93069a891bfc" = { name = "b" display_name = "B" type = { vector2:[] vector3:[] vector4:[] } }
}
output = {
type = "float"
}
code = """
RESULT(distance(a, b));
"""

View file

@ -0,0 +1,72 @@
group = "Fatshark"
display_name = "Distance Fade"
depends_on = [
"core/stingray_renderer/output_nodes/standard_base"
"core/stingray_renderer/output_nodes/unlit_base",
"core/stingray_renderer/output_nodes/particle_base",
"core/stingray_renderer/output_nodes/particle_gbuffer_base",
"core/stingray_renderer/output_nodes/particle_distortion_base"]
inputs = {
"01a82a06-57f6-4dc2-8a63-f3c7119064aa" = {
name = "depth_fade_distance"
display_name = "Depth Fade Distance"
type = "scalar"
domain = "pixel"
is_required = true
}
}
imports = {
pixel_depth = {
type = "float"
domain = "pixel"
output_channel = "pixel_depth"
}
screen_pos = {
type = "float2"
domain = "pixel"
output_channel = "screen_pos"
}
}
defines = ["NEEDS_PIXEL_DEPTH", "NEEDS_LINEAR_DEPTH", "NEEDS_SCREEN_POS"]
domain = "pixel"
output = {
type = "float"
}
options = {
"b110967d-d67a-485f-af33-90ad4bed2eec" = "SMOOTH_STEP"
}
ui = [
{
type = "drop_down"
display_name = "Fade Curve"
options = {
"Linear" = "00000000-0000-0000-0000-000000000000"
"Smooth" = "b110967d-d67a-485f-af33-90ad4bed2eec"
}
default = "00000000-0000-0000-0000-000000000000"
}
]
language = "hlsl"
code = """
#if defined(HAS_LINEAR_DEPTH)
float gbuffer_depth = gbuffer_decode_depth(TEX2D(linear_depth, screen_pos.xy));
#ifdef SMOOTH_STEP
float result = smoothstep(gbuffer_depth, gbuffer_depth - depth_fade_distance, pixel_depth);
#else
float result = saturate((gbuffer_depth - pixel_depth) / depth_fade_distance);
#endif
#else
float result = 1.0;
#endif
RESULT(result);
"""

View file

@ -0,0 +1,14 @@
group = "Math"
display_name = "Divide"
inputs = {
"78dddd43-ff51-4173-bb0c-99d8c27b6bb2" = { name = "a" display_name = "A" type = "auto" }
"03986150-1b08-4045-80c9-d08d58842627" = { name = "b" display_name = "B" type = "auto" }
}
output = {
type = { largestof: ["a", "b"] }
}
code = """
RESULT(a / b);
"""

View file

@ -0,0 +1,14 @@
group = "Math"
display_name = "Dot Product"
inputs = {
"1227923c-0ef1-4823-b673-301cc9a5fc69" = { name = "a" display_name = "A" type = "auto" }
"0e627d0f-2503-4925-9811-d44aca00e49c" = { name = "b" display_name = "B" type = "auto" }
}
output = {
type = "float"
}
code = """
RESULT(dot(a,b));
"""

View file

@ -0,0 +1,13 @@
group = "Math"
display_name = "Exp"
inputs = {
"837f2c43-756b-4f27-8911-b623e50b982a" = { name = "a" display_name = "A" type = "auto" }
}
output = {
type = { typeof: "a" }
}
code = """
RESULT(exp(a));
"""

View file

@ -0,0 +1,18 @@
group = "Fatshark"
display_name = "Eye Intensity"
imports = {
eye_intensity = {
type = "float"
domain = "global"
source = "shading_environment"
}
}
output = {
type = { typeof: "eye_intensity" }
}
code = """
RESULT(eye_intensity);
"""

View file

@ -0,0 +1,25 @@
group = "Input"
display_name = "Eye Vector"
depends_on = [
"core/stingray_renderer/output_nodes/standard_base",
"core/stingray_renderer/output_nodes/unlit_base"
"core/stingray_renderer/output_nodes/terrain_base"
]
imports = {
dir = {
type = "float3"
domain = "vertex"
output_channel = "eye_vector"
}
}
defines = ["NEEDS_EYE_VECTOR"]
output = {
type = { typeof: "dir" }
}
code = """
RESULT(dir);
"""

View file

@ -0,0 +1,44 @@
group = "Utility"
display_name = "Flipbook"
inputs = {
"3BA4F382-41EB-4796-B32F-7A8B51BD8DFB" = { name = "fps" display_name = "FPS" is_required = false type = {scalar: ["HAS_FPS"]} }
"75F62304-E764-4DD7-9BDF-A486E92C92F2" = { name = "time" display_name = "Time" type = "scalar" }
"EE08FB38-9E0A-4009-BB48-A40EB8B85092" = { name = "uv" display_name = "UV" type = "vector2" }
"6b59bfdf-20fc-4817-88ea-4c2f0d08d4af" = { name = "sprite_rows" display_name = "Sprite Rows" is_required = false type = { scalar: ["HAS_ROWS"] }}
"3aba8613-fe85-4516-a049-0edd78e35d48" = { name = "sprite_cols" display_name = "Sprite Columns" is_required = false type = { scalar: ["HAS_COLS"] }}
}
output = {
type = { typeof: "uv" }
}
code = """
#if defined(HAS_FPS)
float frame_per_sec = fps;
#else
float frame_per_sec = 5.0;
#endif
#if defined(HAS_ROWS)
float sprite_per_row = sprite_rows;
#else
float sprite_per_row = 2.0;
#endif
#if defined(HAS_COLS)
float sprite_per_col = sprite_cols;
#else
float sprite_per_col = 2.0;
#endif
float current_frame = floor( fmod((frame_per_sec * time), (sprite_per_row * sprite_per_col)) );
float sprite_u = fmod(current_frame, sprite_per_row) / sprite_per_row;
float sprite_v = floor(current_frame / sprite_per_row) / sprite_per_col;
// add local UV offset
sprite_u += uv.x / sprite_per_row;
sprite_v += uv.y / sprite_per_col;
RESULT(float2(sprite_u, sprite_v));
"""

View file

@ -0,0 +1,185 @@
group = "Sampling"
display_name = "Flipbook Sample Texture"
inputs = {
"c85ccdaf-b0e2-4526-a617-2b14f402f43c" = { name = "uv" display_name = "UV" type = "vector2" }
"4571da41-20ef-47cc-9811-7ed4d59cd85a" = { name = "mip_level" is_required = false display_name = "Mip Level" type = { scalar: ["HAS_MIPLEVEL"] } }
"1fd6339d-ba9f-4ac8-b463-4a49f5f3a90e" = { name = "fps" display_name = "FPS" is_required = false type = {scalar: ["HAS_FPS"]} }
"42b961f8-1b7f-4f41-98ce-11b98adc05e4" = { name = "time" display_name = "Time" type = "scalar" }
"7c9904c4-2039-451b-a38a-5f77ec69f878" = { name = "sprite_rows" display_name = "Sprite Rows" is_required = false type = { scalar: ["HAS_ROWS"] }}
"eee52ea3-790c-40e0-ab60-c53308bc4043" = { name = "sprite_cols" display_name = "Sprite Columns" is_required = false type = { scalar: ["HAS_COLS"] }}
}
domain = "pixel"
output = {
type = "float4"
}
options = {
"acb6ef9d-5ba0-42e4-85f3-2924b4b4be25" = "ADDRESS_CLAMP"
"5dd59b3d-1762-4a14-9930-7500230ef3db" = "ADDRESS_WRAP"
"f669a3a6-0376-4187-840e-80000e2939d5" = "FILTER_LINEAR"
"43dea0e2-a77d-410d-88bb-945dac9139d8" = "FILTER_POINT"
"1e067464-12d8-4826-9b72-cfd5765003e3" = "FILTER_ANISOTROPIC"
"fb3f709b-a54a-4e93-ac9f-e9fc76fb8bcd" = "SRGB"
"43710e4f-f52a-4038-8ec8-d6cb0546103b" = "RGBM_DECODE"
"e94e53e6-49b6-4194-a747-8f064a5932e0" = "LINEAR"
"0268506C-B417-49DC-BBBE-3D5949595940" = "FLIP_GREEN"
}
ui = [
{
type = "drop_down"
display_name = "Encoding"
options = {
"Linear Color" = "e94e53e6-49b6-4194-a747-8f064a5932e0"
"sRGB Color" = "fb3f709b-a54a-4e93-ac9f-e9fc76fb8bcd"
"RGBM Color" = "43710e4f-f52a-4038-8ec8-d6cb0546103b"
}
default = "fb3f709b-a54a-4e93-ac9f-e9fc76fb8bcd"
}
{
type = "drop_down"
display_name = "Address mode"
options = {
"Clamp" = "acb6ef9d-5ba0-42e4-85f3-2924b4b4be25"
"Wrap" = "5dd59b3d-1762-4a14-9930-7500230ef3db"
}
default = "5dd59b3d-1762-4a14-9930-7500230ef3db"
}
{
type = "drop_down"
display_name = "Filter mode"
options = {
"Anisotropic" = "1e067464-12d8-4826-9b72-cfd5765003e3"
"Linear" = "f669a3a6-0376-4187-840e-80000e2939d5"
"Point" = "43dea0e2-a77d-410d-88bb-945dac9139d8"
}
default = "1e067464-12d8-4826-9b72-cfd5765003e3"
}
{ type = "checkbox" display_name = "Invert Green Channel" option = "0268506C-B417-49DC-BBBE-3D5949595940" }
]
code_blocks = {
default = {
include: ["misc"]
language = "hlsl"
samplers = {
texture_map = {
display_name = "Texture"
type = "2d"
sampler_state = "core/shader_nodes/graph_common#default_node_sampler"
source = "material"
}
}
code = """
#if defined(HAS_FPS)
float frame_per_sec = fps;
#else
float frame_per_sec = 5.0;
#endif
#if defined(HAS_ROWS)
float sprite_per_row = sprite_rows;
#else
float sprite_per_row = 2.0;
#endif
#if defined(HAS_COLS)
float sprite_per_col = sprite_cols;
#else
float sprite_per_col = 2.0;
#endif
float frame_value = frame_per_sec * time;
float frame = fmod(frame_value, sprite_per_row * sprite_per_col);
float lerp_value = frac(frame);
float current_frame = floor(frame);
float next_frame = floor(fmod(frame_value + 1.0, sprite_per_row * sprite_per_col));
float2 sprites_dim = float2(sprite_per_row, sprite_per_col);
float2 current_uv = calculate_uv(uv, sprites_dim, current_frame);
float2 next_uv = calculate_uv(uv, sprites_dim, next_frame);
// sample textures
float4 result_current_frame;
#if defined(HAS_MIPLEVEL)
result_current_frame = sample_texture_mip(texture_map, current_uv, mip_level);
#else
result_current_frame = sample_texture(texture_map, current_uv);
#endif
float4 result_next_frame;
#if defined(HAS_MIPLEVEL)
result_next_frame = sample_texture_mip(texture_map, next_uv, mip_level);
#else
result_next_frame = sample_texture(texture_map, next_uv);
#endif
float4 result = lerp(result_current_frame, result_next_frame, lerp_value);
RESULT(result);
"""
}
misc = {
language = "hlsl"
code="""
inline float2 calculate_uv(float2 uv, float2 sprites_dim, float frame)
{
float sprite_u = fmod(frame, sprites_dim.x) / sprites_dim.x;
float sprite_v = floor(frame / sprites_dim.x) / sprites_dim.y;
sprite_u += uv.x / sprites_dim.x;
sprite_v += uv.y / sprites_dim.y;
float2 texcoord = float2(sprite_u, sprite_v);
return texcoord;
}
inline float4 sample_texture(Sampler2D texture_map, float2 texcoord)
{
float4 result;
result = TEX2D(texture_map, texcoord);
#if defined(FLIP_GREEN)
result.y = 1.0-result.y;
#endif
#if defined(RENDERER_GL) && defined(SRGB)
result = fast_gamma_to_linear_rgb(result);
#endif
#if defined(RGBM_DECODE)
result = float4(rgbm_decode(result), result.a);
#endif
return result;
}
inline float4 sample_texture_mip(Sampler2D texture_map, float2 texcoord, float mip_level)
{
float4 result;
result = TEX2DLOD(texture_map, texcoord, mip_level);
#if defined(FLIP_GREEN)
result.y = 1.0-result.y;
#endif
#if defined(RENDERER_GL) && defined(SRGB)
result = fast_gamma_to_linear_rgb(result);
#endif
#if defined(RGBM_DECODE)
result = float4(rgbm_decode(result), result.a);
#endif
return result;
}
"""
}
}

View file

@ -0,0 +1,13 @@
group = "Math"
display_name = "Floor"
inputs = {
"9535d4e4-6a99-4590-952d-c2c11d0872b6" = { name = "a" display_name = "A" type = "auto" }
}
output = {
type = { typeof: "a" }
}
code = """
RESULT(floor(a));
"""

View file

@ -0,0 +1,14 @@
group = "Math"
display_name = "Fmod"
inputs = {
"f4e67b79-cc94-444f-99ca-c01316eb4cab" = { name = "a" display_name = "A" type = "auto" }
"abb0de2c-a337-4cb5-a2c1-5ffb3770a960" = { name = "b" display_name = "B" type = "auto" }
}
output = {
type = { largestof: ["a", "b"] }
}
code = """
RESULT(fmod(a,b));
"""

View file

@ -0,0 +1,13 @@
group = "Math"
display_name = "Fractional (Decimal)"
inputs = {
"06acde87-5eb5-4800-881d-ed7c05de6ac6" = { name = "a" display_name = "A" type = "auto" }
}
output = {
type = { typeof: "a" }
}
code = """
RESULT(frac(a));
"""

View file

@ -0,0 +1,85 @@
group = "Utility"
display_name = "Fresnel"
inputs = {
"904B4365-2955-4899-B615-62A05F0D5726" = { name = "custom_min" display_name = "Minimum" is_required = false type = {scalar: ["HAS_FRESNELMIN"]} }
"B89878F6-57BC-4491-9825-E28D1A96A519" = { name = "custom_max" display_name = "Maximum / Exponent" is_required = false type = {scalar: ["HAS_FRESNELMAX"]} }
"98C44AA8-6F34-4C99-8AD9-CA8A787F12BB" = { name = "custom_normal" display_name = "Normal" is_required = false type = {vector3: ["HAS_CUSTOMNORMAL"]} }
}
depends_on = ["core/stingray_renderer/output_nodes/standard_base", "core/stingray_renderer/output_nodes/unlit_base",
"core/stingray_renderer/output_nodes/billboard_base", "core/stingray_renderer/output_nodes/billboard_unlit_base"]
output = {
type = "float"
}
defines = ["NEEDS_WORLD_SPACE_NORMAL", "NEEDS_EYE_VECTOR"]
imports = {
normal = {
type = "float3"
domain = "vertex"
output_channel = "world_space_normal"
}
eye_vector = {
type = "float3"
domain = "vertex"
output_channel = "eye_vector"
}
}
options = {
"8E67341F-137F-4555-9E8C-FAE0E41D3D0D" = "USE_MINMAX"
"9653C6EC-D10A-4EBC-B76F-E2E8EABB9194" = "USE_EXPONENT"
}
ui = [
{
type = "drop_down"
display_name = "Method"
options = {
"Use Min/Max" = "8E67341F-137F-4555-9E8C-FAE0E41D3D0D"
"Use Exponent" = "9653C6EC-D10A-4EBC-B76F-E2E8EABB9194"
}
default = "8E67341F-137F-4555-9E8C-FAE0E41D3D0D"
}
]
code = """
float result = 0.0;
#if defined(HAS_FRESNELMAX)
float maximum = custom_max;
#else
float maximum = 1.0;
#endif
#if defined(HAS_CUSTOMNORMAL)
float3 n = custom_normal;
#else
float3 n = normalize(normal);
#endif
// The eye_vector channel is per-vertex, if we interpolate it and use it per-pixel it has to be renormalized.
float3 dir = normalize(eye_vector);
// method 1, artist friendly Fresnel controls:
#if defined(USE_MINMAX)
#if defined(HAS_FRESNELMIN)
float minimum = custom_min;
#else
float minimum = 0.8;
#endif
float v_dot_n = saturate(1.0 - dot(dir, n));
float range = max(maximum, minimum) - minimum;
result = saturate((v_dot_n - minimum) / range);
// method 2, classic exponent control:
#else
result = pow(max(1.0 - abs(dot(n, dir)), 0.0001), maximum);
#endif
RESULT(result);
"""

View file

@ -0,0 +1,42 @@
sampler_states = {
default_node_sampler = {
states = {
"defined(TAA_ENABLED)" = {
mip_lod_bias = "-2.0"
}
"defined(ADDRESS_CLAMP)" = {
"on_renderer(GL)" = {
address_u = "address_clamp_to_edge"
address_v = "address_clamp_to_edge"
address_w = "address_clamp_to_edge"
}
"on_renderer(D3D11, D3D12, GNM)" = {
address_u = "address_clamp"
address_v = "address_clamp"
address_w = "address_clamp"
}
}
"defined(ADDRESS_WRAP)" = {
address_u = "address_wrap"
address_v = "address_wrap"
address_w = "address_wrap"
}
"defined(FILTER_LINEAR)" = {
filter = "min_mag_mip_linear"
}
"defined(FILTER_POINT)" = {
filter = "min_mag_mip_point"
}
"defined(FILTER_ANISOTROPIC)" = {
filter = "anisotropic"
max_anisotropy = "8"
}
"defined(SRGB)" = {
srgb = "true"
}
"!defined(SRGB)" = {
srgb = "false"
}
}
}
}

View file

@ -0,0 +1,38 @@
group = "Utility"
display_name = "HSV to RGB"
inputs = {
"BCBF488E-5D40-43DF-A021-0762C58443EB" = { name = "hsv" display_name = "HSV" type = "vector3" }
}
output = {
type = { typeof: "hsv" }
}
code_blocks = {
hsv_to_rgb_block = {
code = """
// Convert pure hue to RGB
inline float3 hue_to_rgb( float h ) {
float r = abs(h * 6.0 - 3.0) - 1.0;
float g = 2.0 - abs(h * 6.0 - 2.0);
float b = 2.0 - abs(h * 6.0 - 4.0);
return saturate(float3(r,g,b));
}
// HSV to RGB conversion based on work by Sam Hocevar and Emil Persson
// explanation: http://chilliant.blogspot.ca/2014/04/rgbhsv-in-hlsl-5.html
inline float3 hsv_to_rgb( float3 hsv ) {
float3 rgb = hue_to_rgb(hsv.x);
return ((rgb - 1.0) * hsv.y + 1.0) * hsv.z;
}
"""
}
default = {
include: ["hsv_to_rgb_block"]
code = """
RESULT(hsv_to_rgb(hsv));
"""
}
}

View file

@ -0,0 +1,69 @@
// todo: output_a and output_b should be locked such that both are the same data type
// For now we will assume the user does this manually
group = "Math"
display_name = "If"
inputs = {
"CED7BBF3-0B48-4335-B933-095A41CA0294" = { name = "input_a" display_name = "A" type = "auto" }
"39BC7619-2768-480B-ACFD-63FA66EF6905" = { name = "input_b" display_name = "B" type = "auto" }
"4CBB4480-79E8-4CE7-AC0F-8B09BAF12390" = { name = "output_a" display_name = "True" type = "auto" }
"F2F74E58-402D-472B-87DD-331E00DB416C" = { name = "output_b" display_name = "False" type = "auto" }
}
output = {
type = { typeof: "output_a" }
}
options = {
"9A84282B-F1A2-46D4-9FC4-5A76FC9B30DD" = "OP_EQUAL"
"6F615C8C-0C2E-4571-87BF-2131125BB9BD" = "OP_NOTEQUAL"
"9D6AE0AA-46AA-41C6-BD40-2F4030EA9668" = "OP_SMALLER"
"B153EA25-006C-4918-B18D-F934D95B1DDF" = "OP_LARGER"
"C14A2EBF-0E4F-40FC-A77B-552CFE5A8AA8" = "OP_SMALLEREQUAL"
"C5160115-6432-4FB7-9F16-44C0C45B4423" = "OP_LARGEREQUAL"
"B593D445-6CB9-4606-BDEC-87985B85CEE0" = "OP_AND"
"DAD8F6A0-EEE4-4CC1-9D34-B5BDD67FEF44" = "OP_OR"
}
ui = [
{
type = "drop_down"
display_name = "Operator"
options = {
"Equal (==)" = "9A84282B-F1A2-46D4-9FC4-5A76FC9B30DD"
"Not Equal (!=)" = "6F615C8C-0C2E-4571-87BF-2131125BB9BD"
"Less (<)" = "9D6AE0AA-46AA-41C6-BD40-2F4030EA9668"
"Greater (>)" = "B153EA25-006C-4918-B18D-F934D95B1DDF"
"Less Equal (<=)" = "C14A2EBF-0E4F-40FC-A77B-552CFE5A8AA8"
"Greater Equal (>=)" = "C5160115-6432-4FB7-9F16-44C0C45B4423"
"And (&&)" = "B593D445-6CB9-4606-BDEC-87985B85CEE0"
"Or (||)" = "DAD8F6A0-EEE4-4CC1-9D34-B5BDD67FEF44"
}
default = "9A84282B-F1A2-46D4-9FC4-5A76FC9B30DD"
}
]
code = """
output_a_type result;
#if defined(OP_EQUAL)
result = (input_a == input_b) ? output_a : output_b;
#elif defined(OP_NOTEQUAL)
result = (input_a != input_b) ? output_a : output_b;
#elif defined(OP_SMALLER)
result = (input_a < input_b) ? output_a : output_b;
#elif defined(OP_LARGER)
result = (input_a > input_b) ? output_a : output_b;
#elif defined(OP_SMALLEREQUAL)
result = (input_a <= input_b) ? output_a : output_b;
#elif defined(OP_LARGEREQUAL)
result = (input_a >- input_b) ? output_a : output_b;
#elif defined(OP_AND)
result = (input_a && input_b) ? output_a : output_b;
#elif defined(OP_OR)
result = (input_a || input_b) ? output_a : output_b;
#else
result = output_a;
#endif
RESULT( result );
"""

View file

@ -0,0 +1,13 @@
group = "Math"
display_name = "Invert / One Minus"
inputs = {
"DB6BAC1D-3931-42BD-BD08-829BFBCBAD47" = { name = "a" display_name = "A" type = "auto"}
}
output = {
type = { typeof: "a" }
}
code = """
RESULT(1.0 - a);
"""

View file

@ -0,0 +1,13 @@
group = "Math"
display_name = "Length"
inputs = {
"6fc97f2b-a585-4430-9f2d-93069a891bfc" = { name = "v" display_name = "Vector" type = { vector2:[] vector3:[] vector4:[] } }
}
output = {
type = "float"
}
code = """
RESULT(length(v));
"""

View file

@ -0,0 +1,15 @@
group = "Math"
display_name = "Linear Interpolate"
inputs = {
"995996dc-408e-4e6f-a310-0db5b3276075" = { name = "a" display_name = "A" type = "auto" }
"5551ea38-126d-4d89-ab57-14b36b92a93c" = { name = "b" display_name = "B" type = "auto" }
"cdc83a63-3365-4c10-9353-79ff5f2fd1f0" = { name = "w" display_name = "Weight" type = "auto" }
}
output = {
type = { largestof: ["a", "b"] }
}
code = """
RESULT(lerp(a, b, w));
"""

View file

@ -0,0 +1,19 @@
group = "Light"
display_name = "Light Color"
depends_on = ["core/stingray_renderer/output_nodes/light_base"]
imports = {
light_color = {
type = "float3"
domain = "global"
source = "engine"
}
}
output = {
type = { typeof: "light_color" }
}
code = """
RESULT(light_color);
"""

View file

@ -0,0 +1,19 @@
group = "Light"
display_name = "Light Vector"
depends_on = ["core/stingray_renderer/output_nodes/light_base"]
imports = {
light_vector = {
type = "float3"
domain = "pixel"
output_channel = "light_vector"
}
}
output = {
type = "float3"
}
code = """
RESULT(light_vector);
"""

View file

@ -0,0 +1,24 @@
group = "Input"
display_name = "Material Variable"
exports = {
material_variable = {
type = "float3"
value = [0.0 0.0 0.0]
ui = {
is_editable = true
min = [0.0 0.0 0.0]
max = [1.0 1.0 1.0]
step = [0.001 0.001 0.001]
}
}
}
output = {
type = { typeof: "material_variable" }
}
code = """
RESULT(material_variable);
"""

View file

@ -0,0 +1,14 @@
group = "Math"
display_name = "Maximum"
inputs = {
"f72597c4-7487-419a-affb-ef690e6582e1" = { name = "a" display_name = "A" type = "auto" }
"0806db0d-2c4a-43ca-99cc-e5a2f036a8e8" = { name = "b" display_name = "B" type = "auto" }
}
output = {
type = { largestof: ["a", "b"] }
}
code = """
RESULT( max(a,b) );
"""

View file

@ -0,0 +1,14 @@
group = "Math"
display_name = "Minimum"
inputs = {
"f72597c4-7487-419a-affb-af690e6582e1" = { name = "a" display_name = "A" type = "auto" }
"0806db0d-2c4a-43ca-99cc-a5a2f036a8e8" = { name = "b" display_name = "Min" type = "auto" }
}
output = {
type = { largestof: ["a", "b"] }
}
code = """
RESULT( min(a,b) );
"""

View file

@ -0,0 +1,14 @@
group = "Math"
display_name = "Multiply"
inputs = {
"c5823c75-4ae5-4c71-b070-315fa4d03e8e" = { name = "a" display_name = "A" type = "auto" }
"242d1648-a626-445b-9534-bccec094112f" = { name = "b" display_name = "B" type = "auto" }
}
output = {
type = { largestof: ["a", "b"] }
}
code = """
RESULT(a * b);
"""

View file

@ -0,0 +1,151 @@
group = "Noise (Expensive)"
display_name = "Noise 2D"
inputs = {
"43350130-56d2-4f38-8946-2db61bc0dc27" = { name = "uv" display_name = "UV" is_required = true type = "vector2" domain = "pixel" }
"73505236-5232-4270-a364-5c30356d44d5" = { name = "a" display_name = "A" is_required = false type = { scalar: ["HAS_A_INPUT"] } domain = "pixel" }
"2ea53a8d-bd55-4b4b-81f4-7bf2166c4d9c" = { name = "b" display_name = "B" is_required = false type = { scalar: ["HAS_B_INPUT"] } domain = "pixel" }
"5a2a194b-1ba3-4b56-834d-349aea030a90" = { name = "c" display_name = "C" is_required = false type = { scalar: ["HAS_C_INPUT"] } domain = "pixel" }
}
domain = "pixel"
output = {
type = "float"
}
options = {
"fa47640c-251a-45ea-9b64-b66548831364" = "VALUE_2D"
"bf7f9537-897f-4765-937c-a8f6ed136c57" = "VALUE_PERLIN_2D"
"4d8f1b18-68b6-4583-89ce-55bbae9e26fb" = "VALUE_HERMITE_2D"
"ea90178c-95ca-4f4a-9e65-40d4ff1c7de2" = "PERLIN_2D"
"1df75adb-e671-4b6a-a312-b9cefbdf662b" = "HERMITE_2D"
"a32eedbc-2170-4ef1-ae28-cd99278fd7b7" = "CUBIST_2D"
"d34696e9-a9d1-4c99-93ed-c3e0d84eb03a" = "CELLULAR_2D"
"968553bd-efc4-43ef-b271-887992a50bcb" = "POLKA_DOT_2D"
"dc1b5dfb-3629-415c-9dbc-ee0f88a75c4b" = "STARS_2D"
"a7e6eafc-1322-48e6-94a0-9c57b12ee1e1" = "SIMPLEX_PERLIN_2D"
"cb95451e-3c58-458d-a1db-1a900822a3df" = "SIMPLEX_CELLULAR_2D"
"1e2afae4-0c42-4dd2-9ba6-34fab2887aed" = "SIMPLEX_POLKA_DOT_2D"
}
ui = [
{
type = "drop_down"
display_name = "Noise Type"
options = {
"Value [0, 1]" = "fa47640c-251a-45ea-9b64-b66548831364"
"Value-Perlin [-1, 1], a" = "bf7f9537-897f-4765-937c-a8f6ed136c57"
"Value-Hermite [-1, 1], a, b" = "4d8f1b18-68b6-4583-89ce-55bbae9e26fb"
"Perlin [-1, 1]" = "ea90178c-95ca-4f4a-9e65-40d4ff1c7de2"
"Hermite [-1, 1]" = "1df75adb-e671-4b6a-a312-b9cefbdf662b"
"Cubist [0, 1], a, b" = "a32eedbc-2170-4ef1-ae28-cd99278fd7b7"
"Cellular [0, 1]" = "d34696e9-a9d1-4c99-93ed-c3e0d84eb03a"
"Polka Dot [0, 1], a, b" = "968553bd-efc4-43ef-b271-887992a50bcb"
"Stars [0, 1], a, b, c" = "dc1b5dfb-3629-415c-9dbc-ee0f88a75c4b"
"Simplex Perlin [-1, 1]" = "a7e6eafc-1322-48e6-94a0-9c57b12ee1e1"
"Simplex Cellular [0, ~1]" = "cb95451e-3c58-458d-a1db-1a900822a3df"
"Simplex Polka Dot [0, 1], a, b" = "1e2afae4-0c42-4dd2-9ba6-34fab2887aed"
}
default = "fa47640c-251a-45ea-9b64-b66548831364"
}
]
code_blocks = {
default = {
include:["core/stingray_renderer/shader_libraries/noise#noise_functions"]
code = {
hlsl = """
#if defined(VALUE_2D)
float result = Value2D(uv);
#elif defined(VALUE_PERLIN_2D)
#ifndef HAS_A_INPUT
float blend = 0.5;
#else
float blend = a;
#endif
float result = ValuePerlin2D(uv, blend);
#elif defined(VALUE_HERMITE_2D)
#ifndef HAS_A_INPUT
float MAXVALUE = 1.0;
#else
float MAXVALUE = a;
#endif
#ifndef HAS_B_INPUT
float MAXGRADIENT = 1.0;
#else
float MAXGRADIENT = b;
#endif
float result = ValueHermite2D(uv, 2.0*MAXVALUE, 2.0*MAXGRADIENT, 1.0 / ( MAXVALUE + MAXGRADIENT * 0.3125 * 2.0 ));
#elif defined(PERLIN_2D)
float result = Perlin2D(uv);
#elif defined(HERMITE_2D)
float result = Hermite2D(uv);
#elif defined(CUBIST_2D)
#ifndef HAS_A_INPUT
float high = 1.0;
#else
float high = a;
#endif
#ifndef HAS_B_INPUT
float low = -2.0;
#else
float low = b;
#endif
float result = Cubist2D(uv, float2(low, 1.0/(high-low)));
#elif defined(CELLULAR_2D)
float result = Cellular2D(uv);
#elif defined(POLKA_DOT_2D)
#ifndef HAS_A_INPUT
float high_radius = 1.0;
#else
float high_radius = a;
#endif
#ifndef HAS_B_INPUT
float low_radius = 0.1;
#else
float low_radius = b;
#endif
float result = PolkaDot2D(uv, low_radius, high_radius);
#elif defined(STARS_2D)
#ifndef HAS_A_INPUT
float probability = 0.5;
#else
float probability = a;
#endif
#ifndef HAS_B_INPUT
float max_dimness = 1.0;
#else
float max_dimness = b;
#endif
#ifndef HAS_C_INPUT
float two_over_radius = 4.0;
#else
float two_over_radius = b;
#endif
float result = Stars2D(uv, probability, max_dimness, two_over_radius);
#elif defined(SIMPLEX_PERLIN_2D)
float result = SimplexPerlin2D(uv);
#elif defined(SIMPLEX_CELLULAR_2D)
float result = SimplexCellular2D(uv);
#elif defined(SIMPLEX_POLKA_DOT_2D)
#ifndef HAS_A_INPUT
float radius = 1.0;
#else
float radius = a;
#endif
#ifndef HAS_B_INPUT
float variation = 0.1;
#else
float variation = b;
#endif
float result = SimplexPolkaDot2D(uv, radius, variation);
#else
float result = 0.0;
#endif
RESULT(result);
"""
}
}
}

View file

@ -0,0 +1,130 @@
group = "Noise (Expensive)"
display_name = "Noise 3D"
inputs = {
"3679b6ae-ea55-4c84-a531-7d3f350f505f" = { name = "uvw" display_name = "UVW" is_required = true type = "vector3" domain = "pixel" }
"93aded2c-9f72-44e4-9b0a-9e6b892b99e3" = { name = "a" display_name = "A" is_required = false type = { scalar: ["HAS_A_INPUT"] } domain = "pixel" }
"ba717440-5742-42f5-b81a-145b3ab1ddec" = { name = "b" display_name = "B" is_required = false type = { scalar: ["HAS_B_INPUT"] } domain = "pixel" }
}
domain = "pixel"
output = {
type = "float"
}
options = {
"b154b1bb-8b43-44c1-ba03-8c552176375e" = "VALUE_3D"
"8d01fa80-ecec-4140-b09a-635b6e96e646" = "VALUE_PERLIN_3D"
"ee3af997-15bf-46b0-b121-901260a53611" = "VALUE_HERMITE_3D"
"4739a4bb-9b3d-481d-bf32-0988f06fc6b8" = "PERLIN_3D"
"43513af3-331c-4cd3-a8af-57898d2629e1" = "HERMITE_3D"
"efd29873-4430-45c8-a4fb-5631704e3fa2" = "CUBIST_3D"
"59d1c03c-f309-4432-aee2-590f909e7459" = "CELLULAR_3D"
"526f7923-e8a6-4499-b9f7-4ae586a67bf4" = "POLKA_DOT_3D"
"5c697940-af02-4d4e-bbe3-8be2506641e8" = "SIMPLEX_PERLIN_3D"
"c617d225-bffb-466b-9022-56993ee40265" = "SIMPLEX_CELLULAR_3D"
"56dd9739-c575-4f04-bc4b-a525ff413985" = "SIMPLEX_POLKA_DOT_3D"
}
ui = [
{
type = "drop_down"
display_name = "Noise Type"
options = {
"Value [0, 1]" = "b154b1bb-8b43-44c1-ba03-8c552176375e"
"Value-Perlin [-1, 1], a" = "8d01fa80-ecec-4140-b09a-635b6e96e646"
"Value-Hermite [-1, 1], a, b" = "ee3af997-15bf-46b0-b121-901260a53611"
"Perlin [-1, 1]" = "4739a4bb-9b3d-481d-bf32-0988f06fc6b8"
"Hermite [-1, 1]" = "43513af3-331c-4cd3-a8af-57898d2629e1"
"Cubist [0, 1], a, b" = "efd29873-4430-45c8-a4fb-5631704e3fa2"
"Cellular [0, 1]" = "59d1c03c-f309-4432-aee2-590f909e7459"
"Polka Dot [0, 1], a, b" = "526f7923-e8a6-4499-b9f7-4ae586a67bf4"
"Simplex Perlin [-1, 1]" = "5c697940-af02-4d4e-bbe3-8be2506641e8"
"Simplex Cellular [0, ~1]" = "c617d225-bffb-466b-9022-56993ee40265"
"Simplex Polka Dot [0, 1], a, b" = "56dd9739-c575-4f04-bc4b-a525ff413985"
}
default = "b154b1bb-8b43-44c1-ba03-8c552176375e"
}
]
code_blocks = {
default = {
include:["core/stingray_renderer/shader_libraries/noise#noise_functions"]
code = {
hlsl = """
#if defined(VALUE_3D)
float result = Value3D(uvw);
#elif defined(VALUE_PERLIN_3D)
#ifndef HAS_A_INPUT
float blend = 0.5;
#else
float blend = a;
#endif
float result = ValuePerlin3D(uvw, blend);
#elif defined(VALUE_HERMITE_3D)
#ifndef HAS_A_INPUT
float MAXVALUE = 1.0;
#else
float MAXVALUE = a;
#endif
#ifndef HAS_B_INPUT
float MAXGRADIENT = 1.0;
#else
float MAXGRADIENT = b;
#endif
float result = ValueHermite3D(uvw, 2.0*MAXVALUE, 2.0*MAXGRADIENT, 1.0 / ( MAXVALUE + MAXGRADIENT * 0.3125 * 2.0 ));
#elif defined(PERLIN_3D)
float result = Perlin3D(uvw);
#elif defined(HERMITE_3D)
float result = Hermite3D(uvw);
#elif defined(CUBIST_3D)
#ifndef HAS_A_INPUT
float high = 1.0;
#else
float high = a;
#endif
#ifndef HAS_B_INPUT
float low = -2.0;
#else
float low = b;
#endif
float result = Cubist3D(uvw, float2(low, 1.0/(high-low)));
#elif defined(CELLULAR_3D)
float result = Cellular3D(uvw);
#elif defined(POLKA_DOT_3D)
#ifndef HAS_A_INPUT
float high_radius = 1.0;
#else
float high_radius = a;
#endif
#ifndef HAS_B_INPUT
float low_radius = 0.1;
#else
float low_radius = b;
#endif
float result = PolkaDot3D(uvw, low_radius, high_radius);
#elif defined(SIMPLEX_PERLIN_3D)
float result = SimplexPerlin3D(uvw);
#elif defined(SIMPLEX_CELLULAR_3D)
float result = SimplexCellular3D(uvw);
#elif defined(SIMPLEX_POLKA_DOT_3D)
#ifndef HAS_A_INPUT
float radius = 1.0;
#else
float radius = a;
#endif
#ifndef HAS_B_INPUT
float variation = 0.1;
#else
float variation = b;
#endif
float result = SimplexPolkaDot3D(uvw, radius, variation);
#else
float result = 0.0;
#endif
RESULT(result);
"""
}
}
}

View file

@ -0,0 +1,51 @@
group = "Noise (Expensive)"
display_name = "Noise 4D"
inputs = {
"e339bcc7-ba49-41b4-ac71-d581785422f4" = { name = "uvwx" display_name = "UVWX" is_required = true type = "vector4" domain = "pixel" }
}
domain = "pixel"
output = {
type = "float"
}
options = {
"8c8ae6d6-a4af-493e-ad52-16c51418000d" = "VALUE_4D"
"41aa617b-94b2-4741-91b8-2d51bf66032d" = "PERLIN_4D"
"12684be0-1484-4f68-bbe0-176fad7c0307" = "SIMPLEX_PERLIN_4D"
}
ui = [
{
type = "drop_down"
display_name = "Noise Type"
options = {
"Value [0, 1]" = "8c8ae6d6-a4af-493e-ad52-16c51418000d"
"Perlin [-1, 1]" = "41aa617b-94b2-4741-91b8-2d51bf66032d"
"Simplex Perlin [-1, 1]" = "12684be0-1484-4f68-bbe0-176fad7c0307"
}
default = "8c8ae6d6-a4af-493e-ad52-16c51418000d"
}
]
code_blocks = {
default = {
include:["core/stingray_renderer/shader_libraries/noise#noise_functions"]
code = {
hlsl = """
#if defined(VALUE_4D)
float result = Value4D(uvwx);
#elif defined(PERLIN_4D)
float result = Perlin4D(uvwx);
#elif defined(SIMPLEX_PERLIN_4D)
float result = simplex_noise4D(uvwx);
#else
float result = 0.0;
#endif
RESULT(result);
"""
}
}
}

View file

@ -0,0 +1,15 @@
group = "Math"
display_name = "Normalize"
domain = "pixel"
inputs = {
"7bc3f92e-1302-40b5-9aea-723e5a7b6b94" = { name = "a" display_name = "Vector" type = { vector2:[] vector3:[] vector4:[] } }
}
output = {
type = { typeof: "a" }
}
code = """
RESULT(normalize(a));
"""

View file

@ -0,0 +1,15 @@
group = "Math"
display_name = "Normalize VS"
domain = "vertex"
inputs = {
"7bc3f92e-1302-40b5-9aea-723e5a7b6b94" = { name = "a" display_name = "Vector" type = { vector2:[] vector3:[] vector4:[] } }
}
output = {
type = { typeof: "a" }
}
code = """
RESULT(normalize(a));
"""

View file

@ -0,0 +1,48 @@
group = "Transform"
display_name = "Object To World"
depends_on = ["core/stingray_renderer/output_nodes/standard_base", "core/stingray_renderer/output_nodes/light_base", "core/stingray_renderer/output_nodes/unlit_base", "core/stingray_renderer/output_nodes/terrain_base"]
inputs = {
"f72597c4-7487-419a-affb-df690e6582e1" = { name = "v" display_name = "Vector" type = "float3" }
}
options = {
"43344bde-3298-4b5f-8993-0be2a71a83b3" = "ROTATE_ONLY"
}
ui = [
{
type = "drop_down"
display_name = "Mode"
options = {
"Full Transform" = "00000000-0000-0000-0000-000000000000"
"Rotation only" = "43344bde-3298-4b5f-8993-0be2a71a83b3"
}
}
]
defines = ["NEEDS_WORLD_POSE"]
imports = {
world = {
type = "float4x4"
domain = "global"
source = "engine"
}
}
output = {
type = { typeof: "v" }
}
code = """
#if defined(BILLBOARD)
RESULT(world._m30_m31_m32 + v);
#else
#if defined(ROTATE_ONLY)
RESULT(mul(v, to_mat3(world)));
#else
RESULT(mul(float4(v, 1), world).xyz);
#endif
#endif
"""

View file

@ -0,0 +1,35 @@
group = "Utility"
display_name = "Option Switch"
inputs = {
"34654E2D-A837-462D-8A9E-27E9700AF34B" = { name = "a" display_name = "Enabled" type = "auto" }
"E1797178-8357-4545-A104-DDDFC5452428" = { name = "b" display_name = "Disabled" type = "auto" }
}
output = {
type = { typeof: "a" }
}
options = {
"B7F82F51-D658-453E-9E48-FC00F79D57D3" = "OPTION_DISABLED"
"96FC39FC-908B-454E-8DC5-FED9B0848619" = "OPTION_ENABLED"
}
ui = [
{
type = "drop_down"
display_name = "Option"
options = {
"Disabled" = "B7F82F51-D658-453E-9E48-FC00F79D57D3"
"Enabled" = "96FC39FC-908B-454E-8DC5-FED9B0848619"
}
default = "B7F82F51-D658-453E-9E48-FC00F79D57D3"
}
]
code = """
#if defined(OPTION_ENABLED)
RESULT(a);
#else
RESULT(b);
#endif
"""

View file

@ -0,0 +1,31 @@
group = "Orientation"
display_name = "Forward Axis"
depends_on = ["core/stingray_renderer/output_nodes/standard_base", "core/stingray_renderer/output_nodes/light_base"]
defines = ["NEEDS_WORLD_POSE"]
imports = {
world = {
type = "float4x4"
domain = "global"
source = "engine"
}
}
output = {
type = "float3"
}
code_blocks = {
default = {
code = {
glsl = """
RESULT(normalize(vec3(world[0].y, world[1].y, world[2].y)));
"""
hlsl = """
RESULT(normalize(world._m10_m11_m12));
"""
}
}
}

View file

@ -0,0 +1,31 @@
group = "Orientation"
display_name = "Position"
depends_on = ["core/stingray_renderer/output_nodes/standard_base", "core/stingray_renderer/output_nodes/light_base"]
defines = ["NEEDS_WORLD_POSE"]
imports = {
world = {
type = "float4x4"
domain = "global"
source = "engine"
}
}
output = {
type = "float3"
}
code_blocks = {
default = {
code = {
glsl = """
RESULT(vec3(world[0].w, world[1].w, world[2].w));
"""
hlsl = """
RESULT(world._m30_m31_m32);
"""
}
}
}

View file

@ -0,0 +1,31 @@
group = "Orientation"
display_name = "Right Axis"
depends_on = ["core/stingray_renderer/output_nodes/standard_base", "core/stingray_renderer/output_nodes/light_base"]
defines = ["NEEDS_WORLD_POSE"]
imports = {
world = {
type = "float4x4"
domain = "global"
source = "engine"
}
}
output = {
type = "float3"
}
code_blocks = {
default = {
code = {
glsl = """
RESULT(normalize(vec3(world[0].x, world[1].x, world[2].x)));
"""
hlsl = """
RESULT(normalize(world._m00_m01_m02));
"""
}
}
}

View file

@ -0,0 +1,31 @@
group = "Orientation"
display_name = "Up Axis"
depends_on = ["core/stingray_renderer/output_nodes/standard_base", "core/stingray_renderer/output_nodes/light_base"]
defines = ["NEEDS_WORLD_POSE"]
imports = {
world = {
type = "float4x4"
domain = "global"
source = "engine"
}
}
output = {
type = "float3"
}
code_blocks = {
default = {
code = {
glsl = """
RESULT(normalize(vec3(world[0].z, world[1].z, world[2].z)));
"""
hlsl = """
RESULT(normalize(world._m20_m21_m22));
"""
}
}
}

View file

@ -0,0 +1,29 @@
group = "Utility"
display_name = "Panner"
inputs = {
"40A76949-E7DB-47FB-9AEC-3FA98DD3FA2E" = { name = "uv" display_name = "UV" type = "vector2" }
"0CE9AD0A-0B3F-43B1-9139-12176F3AAD8E" = { name = "time" display_name = "Time" type = "scalar" }
"9a282471-a2d2-4591-a57e-c70179bb1962" = { name = "speed_u" display_name = "Speed U" is_required = false type = { scalar: ["HAS_SPEED_U"] }}
"e3419eb2-3635-4586-b58c-89ffd88d20d5" = { name = "speed_v" display_name = "Speed V" is_required = false type = { scalar: ["HAS_SPEED_V"] }}
}
output = {
type = { typeof: "uv" }
}
code = """
#if defined(HAS_SPEED_U)
float speed_x = speed_u;
#else
float speed_x = 0.33;
#endif
#if defined(HAS_SPEED_V)
float speed_y = speed_v;
#else
float speed_y = 0.33;
#endif
RESULT( float2(time*speed_x, time*speed_y) + uv );
"""

View file

@ -0,0 +1,65 @@
group = "Utility"
display_name = "Parallax / Bump Offset"
// scale and bias map the height value into a range that better represents the physical properties (size) of the surface
inputs = {
"95FB056C-9DDF-434C-8D8E-A03F30F5C42D" = { name = "uv" display_name = "UV" type = "vector2"}
"B897C7FC-96E3-45D9-9AF1-A1C797386C61" = { name = "height" display_name = "Height" type = "scalar"}
"6046b049-ae9d-49f6-9f75-58a34a3bac15" = { name = "scale" display_name = "Parallax Scale" is_required = false type = { scalar: ["HAS_SCALE"] }}
"ed989589-8b44-4ec4-b5a7-8fb5cd739854" = { name = "bias" display_name = "Parallax Bias" is_required = false type = { scalar: ["HAS_BIAS"] }}
}
defines = ["NEEDS_TANGENT_SPACE", "NEEDS_EYE_VECTOR"]
imports = {
eye_vector = {
type = "float3"
domain = "vertex"
output_channel = "eye_vector"
}
tsm0 = {
type = "float3"
domain = "vertex"
output_channel = "tsm0"
}
tsm1 = {
type = "float3"
domain = "vertex"
output_channel = "tsm1"
}
tsm2 = {
type = "float3"
domain = "vertex"
output_channel = "tsm2"
}
}
output = {
type = { typeof: "uv" }
}
code = """
float3 dir = normalize(eye_vector);
// Get camera vector in tangent space
float3 dir_ts = new_float3(
dot(dir, float3(tsm0.x, tsm1.x, tsm2.x)),
dot(dir, float3(tsm0.y, tsm1.y, tsm2.y)),
dot(dir, float3(tsm0.z, tsm1.z, tsm2.z)));
float2 norm_dir_ts = normalize(dir_ts).xy;
#if defined(HAS_SCALE)
float scale_value = scale;
#else
float scale_value = 0.04;
#endif
#if defined(HAS_BIAS)
float bias_value = bias;
#else
float bias_value = 0.02;
#endif
RESULT(uv + float2(norm_dir_ts.x, -norm_dir_ts.y) * (height*scale_value - bias_value));
"""

View file

@ -0,0 +1,29 @@
group = "Fatshark"
display_name = "Camera Depth"
depends_on = [
"core/stingray_renderer/output_nodes/standard_base"
"core/stingray_renderer/output_nodes/unlit_base",
"core/stingray_renderer/output_nodes/particle_base",
"core/stingray_renderer/output_nodes/particle_gbuffer_base",
"core/stingray_renderer/output_nodes/particle_distortion_base"]
imports = {
pixel_depth = {
type = "float"
domain = "pixel"
output_channel = "pixel_depth"
}
}
defines = ["NEEDS_PIXEL_DEPTH"]
domain = "pixel"
output = {
type = "float"
}
language = "hlsl"
code = """
RESULT(pixel_depth - camera_near_far.x);
"""

View file

@ -0,0 +1,14 @@
group = "Math"
display_name = "Power"
inputs = {
"447b3fe2-c820-4511-a923-b38b0f6c9fe6" = { name = "a" display_name = "Value" type = "auto" }
"e16267f4-8b4e-4079-b13d-f380cfd386ec" = { name = "b" display_name = "Power" type = "auto" }
}
output = {
type = { largestof: ["a", "b"] }
}
code = """
RESULT(pow(a,b));
"""

View file

@ -0,0 +1,71 @@
group = "Sampling"
display_name = "Projected Texcoord"
inputs = {
"a75dd59e-43f1-4dc8-bdb9-e0ec41e304c2" = { name = "hit_position" display_name = "Hit Position" type = "float4" }
"3a1f306e-4d12-45e8-9262-0b709ae4662f" = { name = "hit_normal" display_name = "Hit Normal" type = "float4" }
"814da82a-eccb-40b6-b9c2-074ae141ead4" = { name = "hit_tangent" display_name = "Hit Tangent" type = "float4" }
"70164922-9e7e-4c74-bbaf-92de6838bb86" = { name = "max_dist" display_name = "Diameter" type = "float" }
}
defines = ["NEEDS_UNSKINNED_WORLD_POS", "NEEDS_WORLD_POSE"]
domain = "pixel"
output = {
type = "float3"
}
imports = {
wpos = {
type = "float3"
domain = "vertex"
output_channel = "unskinned_world_pos"
}
normal = {
type = "float3"
domain = "vertex"
output_channel = "unskinned_normal"
}
world = {
type = "float4x4"
domain = "global"
source = "engine"
}
}
code = """
float3 output = float3(0,0,0);
[branch]
if( hit_position.w > 0.5 ) {
float3 pos = mul(hit_position, world).xyz;
float dist = distance(wpos, pos);
[branch]
if( dist < max_dist ) {
float3 world_normal = mul(normal, (float3x3)world);
float3 hit_normal_world = mul(normalize(hit_normal), world);
float side = sqrt( max_dist * max_dist + max_dist * max_dist );
float dot_value = dot(hit_normal_world, world_normal );
[branch]
if( dot_value > 0.0 ) {
float3 hit_tangent_world = mul(normalize(hit_tangent), world);
float3 hit_binormal_world = cross(hit_tangent_world, hit_normal_world);
float3 t_hit_pos = rotate_point3(pos, (float3)hit_tangent_world, (float3)hit_binormal_world, (float3)hit_normal_world);
float3 t_pos = rotate_point3(wpos, (float3)hit_tangent_world, (float3)hit_binormal_world, (float3)hit_normal_world);
float offset = side * 0.4;
float diff_x = (t_hit_pos.x - t_pos.x);
float diff_y = (t_hit_pos.y - t_pos.y);
float x = (offset + diff_x)/(offset * 2);
float y = (offset + diff_y)/(offset * 2);
float valid = clamp(dot_value * 3,0,1);
if( abs(diff_x) > offset || abs(diff_y) > offset )
valid = 0;
output = float3(x,y,valid);
}
}
}
RESULT(output);
"""

View file

@ -0,0 +1,14 @@
group = "Math"
display_name = "Reflect"
inputs = {
"b79bdce4-ed04-4d7c-9f79-cb6174a5e1cc" = { name = "ray" display_name = "Vector" type = { vector2:[] vector3:[] vector4:[] } }
"3d065d63-3541-4223-91bf-4db3ecf7d4a6" = { name = "normal" display_name = "Normal" type = { vector2:[] vector3:[] vector4:[] } }
}
output = {
type = { typeof: "ray" }
}
code = """
RESULT(reflect(ray, normal));
"""

View file

@ -0,0 +1,42 @@
group = "Math"
display_name = "Refract"
inputs = {
"061d4f41-aed3-4f91-843f-bcb4ed0084ed" = { name = "ray" display_name = "In Vector" type = { vector2:[] vector3:[] vector4:[] } }
"93312e6b-6a60-4ac1-991e-d999857424a9" = { name = "normal" display_name = "Normal" type = { vector2:[] vector3:[] vector4:[] } }
"1eabad46-a82f-4f11-9e92-414d90b5fff3" = { name = "index" display_name = "Index" type = "scalar" }
}
output = {
type = { typeof: "ray" }
}
code_blocks = {
gnm_refract_block = {
code = """
#if defined(RENDERER_GNM)
inline float2 gnm_refract(float2 r, float2 n, float i) { return refract(float3(r,0), float3(n,0), i).xy; }
inline float2 gnm_refract(float2 r, float3 n, float i) { return refract(float3(r,0), n, i).xy; }
inline float2 gnm_refract(float2 r, float4 n, float i) { return refract(float3(r,0), n.xyz, i).xy; }
inline float3 gnm_refract(float3 r, float2 n, float i) { return refract(r, float3(n,0), i); }
inline float3 gnm_refract(float3 r, float3 n, float i) { return refract(r, n, i); }
inline float3 gnm_refract(float3 r, float4 n, float i) { return refract(r, n.xyz, i); }
inline float4 gnm_refract(float4 r, float2 n, float i) { return float4(refract(r.xyz, float3(n,0), i), 0); }
inline float4 gnm_refract(float4 r, float3 n, float i) { return float4(refract(r.xyz, n, i), 0); }
inline float4 gnm_refract(float4 r, float4 n, float i) { return float4(refract(r.xyz, n.xyz, 0), 0); }
#endif
"""
}
default = {
include: ["gnm_refract_block"]
code = """
#if defined(RENDERER_GNM)
RESULT(gnm_refract(ray, normal, index));
#else
RESULT(refract(ray, normal, index));
#endif
"""
}
}

View file

@ -0,0 +1,57 @@
group = "Utility"
display_name = "RGB to HSV"
inputs = {
"96D9D117-6A3A-469A-A9B2-3EEDE48F9848" = { name = "rgb" display_name = "RGB" type = "vector3" }
"DAFF208B-6720-4EA8-99C2-423C636A230C" = { name = "hue" is_required = false display_name = "Hue" type = { scalar: ["HAS_HUE"] } }
"7E1968C6-238F-4FB0-A142-9A52B189223C" = { name = "sat" is_required = false display_name = "Saturation" type = { scalar: ["HAS_SAT"] } }
"57AD6551-795C-4A19-BD00-A814628F2976" = { name = "bright" is_required = false display_name = "Brightness / Value" type = { scalar: ["HAS_BRIGHT"] } }
}
output = {
type = { typeof: "rgb" }
}
code_blocks = {
rgb_to_hsv_block = {
code = """
// epsilon is used to remove the need to check for division-by-zero
const float epsilon_hsv = 1e-10;
// RGB to Hue Chroma Value
inline float3 rgb_to_hcv( float3 rgb ) {
float4 p = (rgb.g < rgb.b) ? float4(rgb.bg, -1.0, 2.0/3.0) : float4(rgb.gb, 0.0, -1.0/3.0);
float4 q = (rgb.r < p.x) ? float4(p.xyw, rgb.r) : float4(rgb.r, p.yzx);
float c = q.x - min(q.w, q.y);
float h = abs((q.w - q.y) / (6.0 * c + epsilon_hsv) + q.z);
return float3(h, c, q.x);
}
// RGB to HSV conversion based on work by Sam Hocevar and Emil Persson
// explanation: http://chilliant.blogspot.ca/2014/04/rgbhsv-in-hlsl-5.html
inline float3 rgb_to_hsv( float3 rgb ) {
float3 hcv = rgb_to_hcv(rgb);
float s = hcv.y / (hcv.z + epsilon_hsv);
return float3(hcv.x, s, hcv.z);
}
"""
}
default = {
include: ["rgb_to_hsv_block"]
code = """
float3 hsv = rgb_to_hsv(rgb);
#if defined(HAS_HUE)
float n = 0.0;
hsv.x = modf(hsv.x + hue, n);
#endif
#if defined(HAS_SAT)
hsv.y *= sat;
#endif
#if defined(HAS_BRIGHT)
hsv.z *= bright;
#endif
RESULT(hsv);
"""
}
}

View file

@ -0,0 +1,29 @@
group = "Particle Ribbon"
display_name = "Ribbon UV"
imports = {
strip_info = { type = "float" semantic = "POSITION1" domain = "vertex" }
ribbon_distance = { type = "float" semantic = "TEXCOORD6" domain = "vertex" }
}
options = {
"10abb86e-61d5-4927-9d22-6e87ce3b85ba" = "FLIP_TEXCOORDS"
}
ui = [
{ type = "checkbox" display_name = "flip texcoords" option = "10abb86e-61d5-4927-9d22-6e87ce3b85ba" }
]
domain = "vertex"
output = {
type = "float2"
}
code = """
#if defined(FLIP_TEXCOORDS)
RESULT(float2(strip_info * 0.5 + 0.5, ribbon_distance));
#else
RESULT(float2(ribbon_distance, strip_info * 0.5 + 0.5));
#endif
"""

View file

@ -0,0 +1,20 @@
group = "Particle Ribbon"
display_name = "UV Frame"
imports = {
uv_frame = {
type = "float"
domain = "vertex"
output_channel = "uv_frame"
}
}
defines = ["NEEDS_UV_ANIMATION"]
output = {
type = { typeof: "uv_frame" }
}
code = """
RESULT(uv_frame);
"""

View file

@ -0,0 +1,20 @@
group = "Particle Ribbon"
display_name = "UV Scale"
imports = {
uv_scale = {
type = "float2"
domain = "vertex"
output_channel = "uv_scale"
}
}
defines = ["NEEDS_UV_SCALE"]
output = {
type = { typeof: "uv_scale" }
}
code = """
RESULT(uv_scale);
"""

View file

@ -0,0 +1,25 @@
group = "Particle Ribbon"
display_name = "Vertex Color"
imports = {
color = {
type = "float4"
semantic = "COLOR"
domain = "vertex"
}
}
output = {
type = { typeof: "color" }
}
options = {
}
ui = [
]
code = """
color = fast_gamma_to_linear_rgba(decode_vertex_color(color));
RESULT(color);
"""

View file

@ -0,0 +1,41 @@
group = "Utility"
display_name = "Rotator"
inputs = {
"96650519-54EC-47A2-B34E-3B1989F56BB3" = { name = "uv" display_name = "UV" type = "vector2" }
"178ABCED-40BA-40B1-BAA4-FB5F9732353B" = { name = "time" display_name = "Time" type = "scalar" }
"ffac2478-636b-4b9b-95b9-cd504781e2c2" = { name = "pivot" display_name = "Pivot" is_required = false type = { vector2: ["HAS_PIVOT"] }}
"399aba19-4e60-4287-b1d3-ee2acb8fd406" = { name = "speed" display_name = "Speed" is_required = false type = { scalar: ["HAS_SPEED"] }}
}
output = {
type = { typeof: "uv" }
}
code = """
#ifdef HAS_SPEED
float speed_value = speed;
#else
float speed_value = 0.1;
#endif
#ifdef HAS_PIVOT
float2 pivot_value = pivot;
#else
float2 pivot_value = float2(0.5, 0.5);
#endif
time_type t = time * speed_value;
time_type cos_t = cos(t);
time_type sin_t = sin(t);
// rotate vector around a pivot
#if defined(RENDERER_GL)
// gl constructs matrices in columns.
float2x2 rot_matrix = float2x2(cos_t, sin_t, -sin_t, cos_t);
#else
// hlsl constructs matrices in rows.
float2x2 rot_matrix = float2x2(cos_t, -sin_t, sin_t, cos_t);
#endif
RESULT( pivot_value + mul(uv - pivot_value, rot_matrix) );
"""

View file

@ -0,0 +1,91 @@
group = "Sampling"
display_name = "Sample Cube Texture"
inputs = {
"1ee9af1f-65f2-4739-ad28-5ea6a0e68fc3" = { name = "texcoord" display_name = "UVW" type = "vector3" domain = "pixel" }
"aa23e053-3c53-40f7-a06f-23d5d5a65924" = { name = "mip_level" is_required = false display_name = "Mip Level" type = { scalar: ["HAS_MIPLEVEL"] } }
}
domain = "pixel"
output = {
type = "float4"
}
options = {
"acb6ef9d-5ba0-42e4-85f3-2924b4b4be25" = "ADDRESS_CLAMP"
"5dd59b3d-1762-4a14-9930-7500230ef3db" = "ADDRESS_WRAP"
"f669a3a6-0376-4187-840e-80000e2939d5" = "FILTER_LINEAR"
"43dea0e2-a77d-410d-88bb-945dac9139d8" = "FILTER_POINT"
"1e067464-12d8-4826-9b72-cfd5765003e3" = "FILTER_ANISOTROPIC"
"fb3f709b-a54a-4e93-ac9f-e9fc76fb8bcd" = "SRGB"
"90e20826-8689-42fa-8e24-f484ec64c5c3" = "NORMAL_MAP_DECODE"
"43710e4f-f52a-4038-8ec8-d6cb0546103b" = "RGBM_DECODE"
"e94e53e6-49b6-4194-a747-8f064a5932e0" = "LINEAR"
}
ui = [
{
type = "drop_down"
display_name = "Encoding"
options = {
"Linear Color" = "e94e53e6-49b6-4194-a747-8f064a5932e0"
"sRGB Color" = "fb3f709b-a54a-4e93-ac9f-e9fc76fb8bcd"
"Normal Map" = "90e20826-8689-42fa-8e24-f484ec64c5c3"
"RGBM Color" = "43710e4f-f52a-4038-8ec8-d6cb0546103b"
}
default = "fb3f709b-a54a-4e93-ac9f-e9fc76fb8bcd"
}
{
type = "drop_down"
display_name = "Address mode"
options = {
"Clamp" = "acb6ef9d-5ba0-42e4-85f3-2924b4b4be25"
"Wrap" = "5dd59b3d-1762-4a14-9930-7500230ef3db"
}
default = "5dd59b3d-1762-4a14-9930-7500230ef3db"
}
{
type = "drop_down"
display_name = "Filter mode"
options = {
"Anisotropic" = "1e067464-12d8-4826-9b72-cfd5765003e3"
"Linear" = "f669a3a6-0376-4187-840e-80000e2939d5"
"Point" = "43dea0e2-a77d-410d-88bb-945dac9139d8"
}
default = "f669a3a6-0376-4187-840e-80000e2939d5"
}
]
code_blocks = {
default = {
language = "hlsl"
samplers = {
texture_map = {
display_name = "Texture"
type = "cube"
sampler_state = "core/shader_nodes/graph_common#default_node_sampler"
source = "material"
}
}
code = """
float4 result;
#if defined(HAS_MIPLEVEL)
result = TEXCUBELOD(texture_map, texcoord, mip_level);
#else
result = TEXCUBE(texture_map, texcoord);
#endif
#if defined(RENDERER_GL) && defined(SRGB)
result = fast_gamma_to_linear_rgba(result);
#endif
#if defined(NORMAL_MAP_DECODE)
result = float4(decode_normal_map(result), 0);
#elif defined(RGBM_DECODE)
result = float4(rgbm_decode(result), 0);
#endif
RESULT(result);
"""
}
}

View file

@ -0,0 +1,197 @@
group = "Sampling"
display_name = "Sample Texture"
inputs = {
"1ee9af1f-65f2-4739-ad28-5ea6a0e68fc3" = { name = "texcoord" display_name = "UV" type = "vector2" domain = "pixel" }
"aa23e053-3c53-40f7-a06f-23d5d5a65924" = { name = "mip_level" is_required = false display_name = "Mip Level" type = { scalar: ["HAS_MIPLEVEL"] } }
}
domain = "pixel"
output = {
type = "float4"
}
options = {
"acb6ef9d-5ba0-42e4-85f3-2924b4b4be25" = "ADDRESS_CLAMP"
"5dd59b3d-1762-4a14-9930-7500230ef3db" = "ADDRESS_WRAP"
"f669a3a6-0376-4187-840e-80000e2939d5" = "FILTER_LINEAR"
"43dea0e2-a77d-410d-88bb-945dac9139d8" = "FILTER_POINT"
"1e067464-12d8-4826-9b72-cfd5765003e3" = "FILTER_ANISOTROPIC"
"fb3f709b-a54a-4e93-ac9f-e9fc76fb8bcd" = "SRGB"
"90e20826-8689-42fa-8e24-f484ec64c5c3" = "NORMAL_MAP_DECODE"
"43710e4f-f52a-4038-8ec8-d6cb0546103b" = "RGBM_DECODE"
"e94e53e6-49b6-4194-a747-8f064a5932e0" = "LINEAR"
"0268506C-B417-49DC-BBBE-3D5949595940" = "FLIP_GREEN"
"aea8c8f4-81e6-4784-bc83-bee2f73eea58" = "NORMAL_ROUGHNESS_DECODE"
}
ui = [
{
type = "drop_down"
display_name = "Encoding"
options = {
"Linear Color" = "e94e53e6-49b6-4194-a747-8f064a5932e0"
"sRGB Color" = "fb3f709b-a54a-4e93-ac9f-e9fc76fb8bcd"
"Normal Map" = "90e20826-8689-42fa-8e24-f484ec64c5c3"
"Normal Roughness Map" = "aea8c8f4-81e6-4784-bc83-bee2f73eea58"
"RGBM Color" = "43710e4f-f52a-4038-8ec8-d6cb0546103b"
}
default = "fb3f709b-a54a-4e93-ac9f-e9fc76fb8bcd"
}
{
type = "drop_down"
display_name = "Address mode"
options = {
"Clamp" = "acb6ef9d-5ba0-42e4-85f3-2924b4b4be25"
"Wrap" = "5dd59b3d-1762-4a14-9930-7500230ef3db"
}
default = "5dd59b3d-1762-4a14-9930-7500230ef3db"
}
{
type = "drop_down"
display_name = "Filter mode"
options = {
"Anisotropic" = "1e067464-12d8-4826-9b72-cfd5765003e3"
"Linear" = "f669a3a6-0376-4187-840e-80000e2939d5"
"Point" = "43dea0e2-a77d-410d-88bb-945dac9139d8"
}
default = "1e067464-12d8-4826-9b72-cfd5765003e3"
}
{ type = "checkbox" display_name = "Invert Green Channel" option = "0268506C-B417-49DC-BBBE-3D5949595940" }
]
code_blocks = {
default = {
include: ["texture_debug"]
language = "hlsl"
samplers = {
texture_map = {
display_name = "Texture"
type = "2d"
sampler_state = "core/shader_nodes/graph_common#default_node_sampler"
source = "material"
}
}
code = """
float4 result;
#if defined(HAS_MIPLEVEL)
result = TEX2DLOD(texture_map, texcoord, mip_level);
#else
result = TEX2D(texture_map, texcoord);
#endif
#if defined(FLIP_GREEN)
result.y = 1.0-result.y;
#endif
#if defined(RENDERER_GL) && defined(SRGB)
result = fast_gamma_to_linear_rgb(result);
#endif
#if defined(NORMAL_MAP_DECODE)
result = float4(decode_normal_map(result), result.a);
#elif defined(RGBM_DECODE)
result = float4(rgbm_decode(result), result.a);
#elif defined(NORMAL_ROUGHNESS_DECODE)
float3 N = 2.0*result.rgb - 1.0;
float roughness = result.a;
#if 0
// Specular AA
// TODO: Pre-bake this code
// http://blog.selfshadow.com/publications/s2013-shading-course/rad/s2013_pbs_rad_notes.pdf
float r = length(N);
if (r < 1.0) {
float rr = r * r ;
float kappa = (3.0 * r - r * rr) / (1.0 - rr) ;
float variance = 1.0 / (2.0 * kappa) ;
roughness = sqrt (roughness * roughness + variance);
}
#endif
result = float4(normalize(N), roughness);
#endif
#if defined(MIPMAP_LEVEL_VISUALIZATION)
// inspired by http://aras-p.info/blog/2011/05/03/a-way-to-visualize-mip-levels/
#if defined(HAS_MIPLEVEL)
float4 mip_color = miplevel_debug_color(mip_level);
result = lerp(result, mip_color, mip_color.a);
#else
float mip_level_ = calculate_miplevel(texture_map, texcoord);
float4 mip_color = miplevel_debug_color(mip_level_);
result = lerp(result, mip_color, mip_color.a);
#endif
#elif defined(TEXTURE_DENSITY_VISUALIZATION)
float texture_density = calculate_texture_density(texture_map, texcoord);
float4 blend_color = texture_density_debug(texture_density, 10.0);
result = lerp(result, blend_color, blend_color.a);
#elif defined(COLORED_TEXTURE_DENSITY_VISUALIZATION)
float texture_density = calculate_texture_density(texture_map, texcoord);
float4 blend_color = texture_density_debug(texture_density, 10.0);
result = lerp(float4(0.0, 1.0, 0.0, 0.0), blend_color, blend_color.a);
#endif
RESULT(result);
"""
}
texture_debug = {
language = "hlsl"
code="""
// Seems to be fairly accurate to HLSL
inline float calculate_miplevel(Sampler2D texture_map, float2 uv)
{
// The OpenGL Graphics System: A Specification 4.2
// - chapter 3.9.11, equation 3.21
float2 texture_dim;
texture_map.tex.GetDimensions(texture_dim.x, texture_dim.y);
float2 texcoord = uv * texture_dim;
float2 dx_vtc = ddx(texcoord);
float2 dy_vtc = ddy(texcoord);
float delta_max_sqr = max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc));
return 0.5 * log2(delta_max_sqr); // == log2(sqrt(delta_max_sqr));
}
inline float calculate_texture_density(Sampler2D texture_map, float2 uv)
{
float2 texture_dim;
texture_map.tex.GetDimensions(texture_dim.x, texture_dim.y);
float2 texcoord = uv * texture_dim;
return max(length(ddx(texcoord)), length(ddy(texcoord)));
}
inline float calculate_mipmap_texture_density(Sampler2D texture_map, float2 uv)
{
uint mip_level_ = calculate_miplevel(texture_map, uv);
return calculate_texture_density(texture_map, uv/float(1<<mip_level_));
}
inline float4 miplevel_debug_color(float mip_level)
{
float4 color_table[6] = {
float4(0.0,0.0,1.0,0.8),
float4(0.0,0.5,1.0,0.4),
float4(1.0,1.0,1.0,0.0),
float4(1.0,0.7,0.0,0.2),
float4(1.0,0.3,0.0,0.6),
float4(1.0,0.0,0.0,0.8)
};
uint lower_mip = min(floor(mip_level), 5u);
uint higher_mip = min(ceil(mip_level), 5u);
return lerp(color_table[lower_mip], color_table[higher_mip], frac(mip_level));
}
inline float4 texture_density_debug(float texture_density, float max_value)
{
if(texture_density < 1.0) {
float alpha = saturate(1.0 - texture_density);
return float4(0.0, 0.0, 1.0, alpha);
} else {
float alpha = saturate((texture_density - 1.0)/(max_value - 1.0));
return float4(1.0, 0.0, 0.0, alpha);
}
}
"""
}
}

View file

@ -0,0 +1,152 @@
group = "Sampling"
display_name = "Sample Texture or Pass Through"
inputs = {
"f520fb94-80ca-4703-b0cc-2edadb1cf8bf" = { name = "input" display_name = "Input" type = "vector3" domain = "pixel" }
"1ee9af1f-65f2-4739-ad28-5ea6a0e68fc3" = { name = "texcoord" display_name = "UV" type = "vector3" domain = "pixel" }
"58b09e14-84e1-4c59-a9a7-23caeb184fa6" = { name = "tint_color" display_name = "Tint Color" is_required = false type = { vector3: ["HAS_TINT"] } domain = "pixel" }
}
domain = "pixel"
output = {
type = "float4"
}
options = {
"acb6ef9d-5ba0-42e4-85f3-2924b4b4be25" = "ADDRESS_CLAMP"
"5dd59b3d-1762-4a14-9930-7500230ef3db" = "ADDRESS_WRAP"
"f669a3a6-0376-4187-840e-80000e2939d5" = "FILTER_LINEAR"
"43dea0e2-a77d-410d-88bb-945dac9139d8" = "FILTER_POINT"
"1e067464-12d8-4826-9b72-cfd5765003e3" = "FILTER_ANISOTROPIC"
"fb3f709b-a54a-4e93-ac9f-e9fc76fb8bcd" = "SRGB"
"90e20826-8689-42fa-8e24-f484ec64c5c3" = "NORMAL_MAP_DECODE"
"43710e4f-f52a-4038-8ec8-d6cb0546103b" = "RGBM_DECODE"
"e94e53e6-49b6-4194-a747-8f064a5932e0" = "LINEAR"
"0268506C-B417-49DC-BBBE-3D5949595940" = "FLIP_GREEN"
"aea8c8f4-81e6-4784-bc83-bee2f73eea58" = "NORMAL_ROUGHNESS_DECODE"
}
ui = [
{
type = "drop_down"
display_name = "Encoding"
options = {
"Linear Color" = "e94e53e6-49b6-4194-a747-8f064a5932e0"
"sRGB Color" = "fb3f709b-a54a-4e93-ac9f-e9fc76fb8bcd"
"Normal Map" = "90e20826-8689-42fa-8e24-f484ec64c5c3"
"Normal Roughness Map" = "aea8c8f4-81e6-4784-bc83-bee2f73eea58"
"RGBM Color" = "43710e4f-f52a-4038-8ec8-d6cb0546103b"
}
default = "fb3f709b-a54a-4e93-ac9f-e9fc76fb8bcd"
}
{
type = "drop_down"
display_name = "Address mode"
options = {
"Clamp" = "acb6ef9d-5ba0-42e4-85f3-2924b4b4be25"
"Wrap" = "5dd59b3d-1762-4a14-9930-7500230ef3db"
}
default = "5dd59b3d-1762-4a14-9930-7500230ef3db"
}
{
type = "drop_down"
display_name = "Filter mode"
options = {
"Anisotropic" = "1e067464-12d8-4826-9b72-cfd5765003e3"
"Linear" = "f669a3a6-0376-4187-840e-80000e2939d5"
"Point" = "43dea0e2-a77d-410d-88bb-945dac9139d8"
}
default = "1e067464-12d8-4826-9b72-cfd5765003e3"
}
{ type = "checkbox" display_name = "Invert Green Channel" option = "0268506C-B417-49DC-BBBE-3D5949595940" }
]
code_blocks = {
default = {
include: ["texture_mip_calculate"]
language = "hlsl"
samplers = {
texture_map = {
display_name = "Texture"
type = "2d"
sampler_state = "core/shader_nodes/graph_common#default_node_sampler"
source = "material"
}
}
code = """
float4 result;
float mip_level = calculate_miplevel_test( texture_map, texcoord );
[branch]
if( texcoord.z > 0 ) {
result = TEX2DLOD(texture_map, texcoord, mip_level);
#if defined(HAS_TINT)
result.rgb *= tint_color;
#endif
#if !defined(NORMAL_MAP_DECODE) && !defined(NORMAL_ROUGHNESS_DECODE)
result = lerp(float4(input,1), result, result.a * texcoord.z);
#endif
#if defined(FLIP_GREEN)
result.y = 1.0-result.y;
#endif
#if defined(RENDERER_GL) && defined(SRGB)
result = fast_gamma_to_linear_rgba(result);
#endif
#if defined(NORMAL_MAP_DECODE)
float alpha = result.a;
result = float4(decode_normal_map(result), 0.0);
float2 xy = result.xy + input.xy;
result = lerp(float4(input,1), float4(normalize(new_float3(xy.x, xy.y, input.z*result.z)), 1), alpha * texcoord.z);
result.a = alpha;
#elif defined(RGBM_DECODE)
result = float4(rgbm_decode(result), 0.0);
#elif defined(NORMAL_ROUGHNESS_DECODE)
float3 N = 2.0*result.rgb - 1.0;
float roughness = result.a;
#if 0
// Specular AA
// TODO: Pre-bake this code
// http://blog.selfshadow.com/publications/s2013-shading-course/rad/s2013_pbs_rad_notes.pdf
float r = length(N);
if (r < 1.0) {
float rr = r * r ;
float kappa = (3.0 * r - r * rr) / (1.0 - rr) ;
float variance = 1.0 / (2.0 * kappa) ;
roughness = sqrt (roughness * roughness + variance);
}
#endif
N = lerp(input, N, result.a);
result = float4(normalize(N), roughness);
#endif
} else {
result = float4(input,0);
}
RESULT(result);
"""
}
texture_mip_calculate = {
language = "hlsl"
code="""
// Seems to be fairly accurate to HLSL
inline float calculate_miplevel_test(Sampler2D texture_map, float2 uv)
{
// The OpenGL Graphics System: A Specification 4.2
// - chapter 3.9.11, equation 3.21
float2 texture_dim;
texture_map.tex.GetDimensions(texture_dim.x, texture_dim.y);
float2 texcoord = uv * texture_dim;
float2 dx_vtc = ddx(texcoord);
float2 dy_vtc = ddy(texcoord);
float delta_max_sqr = max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc));
return 0.5 * log2(delta_max_sqr); // == log2(sqrt(delta_max_sqr));
}
"""
}
}

View file

@ -0,0 +1,115 @@
group = "Sampling"
display_name = "Sample Texture VS"
inputs = {
"1ee9af1f-65f2-4739-ad28-5ea6a0e68fc3" = { name = "texcoord" display_name = "UV" type = "vector2" domain = "pixel" }
"aa23e053-3c53-40f7-a06f-23d5d5a65924" = { name = "mip_level" is_required = true display_name = "Mip Level" type = { scalar: ["HAS_MIPLEVEL"] } }
}
domain = "vertex"
output = {
type = "float4"
}
options = {
"acb6ef9d-5ba0-42e4-85f3-2924b4b4be25" = "ADDRESS_CLAMP"
"5dd59b3d-1762-4a14-9930-7500230ef3db" = "ADDRESS_WRAP"
"f669a3a6-0376-4187-840e-80000e2939d5" = "FILTER_LINEAR"
"43dea0e2-a77d-410d-88bb-945dac9139d8" = "FILTER_POINT"
"1e067464-12d8-4826-9b72-cfd5765003e3" = "FILTER_ANISOTROPIC"
"fb3f709b-a54a-4e93-ac9f-e9fc76fb8bcd" = "SRGB"
"90e20826-8689-42fa-8e24-f484ec64c5c3" = "NORMAL_MAP_DECODE"
"43710e4f-f52a-4038-8ec8-d6cb0546103b" = "RGBM_DECODE"
"e94e53e6-49b6-4194-a747-8f064a5932e0" = "LINEAR"
"0268506C-B417-49DC-BBBE-3D5949595940" = "FLIP_GREEN"
"aea8c8f4-81e6-4784-bc83-bee2f73eea58" = "NORMAL_ROUGHNESS_DECODE"
}
ui = [
{
type = "drop_down"
display_name = "Encoding"
options = {
"Linear Color" = "e94e53e6-49b6-4194-a747-8f064a5932e0"
"sRGB Color" = "fb3f709b-a54a-4e93-ac9f-e9fc76fb8bcd"
"Normal Map" = "90e20826-8689-42fa-8e24-f484ec64c5c3"
"Normal Roughness Map" = "aea8c8f4-81e6-4784-bc83-bee2f73eea58"
"RGBM Color" = "43710e4f-f52a-4038-8ec8-d6cb0546103b"
}
default = "fb3f709b-a54a-4e93-ac9f-e9fc76fb8bcd"
}
{
type = "drop_down"
display_name = "Address mode"
options = {
"Clamp" = "acb6ef9d-5ba0-42e4-85f3-2924b4b4be25"
"Wrap" = "5dd59b3d-1762-4a14-9930-7500230ef3db"
}
default = "5dd59b3d-1762-4a14-9930-7500230ef3db"
}
{
type = "drop_down"
display_name = "Filter mode"
options = {
"Anisotropic" = "1e067464-12d8-4826-9b72-cfd5765003e3"
"Linear" = "f669a3a6-0376-4187-840e-80000e2939d5"
"Point" = "43dea0e2-a77d-410d-88bb-945dac9139d8"
}
default = "1e067464-12d8-4826-9b72-cfd5765003e3"
}
{ type = "checkbox" display_name = "Invert Green Channel" option = "0268506C-B417-49DC-BBBE-3D5949595940" }
]
code_blocks = {
default = {
language = "hlsl"
samplers = {
texture_map = {
display_name = "Texture"
type = "2d"
sampler_state = "core/shader_nodes/graph_common#default_node_sampler"
source = "material"
}
}
code = """
float4 result;
#if defined(HAS_MIPLEVEL)
result = TEX2DLOD(texture_map, texcoord, mip_level);
#else
result = TEX2D(texture_map, texcoord);
#endif
#if defined(FLIP_GREEN)
result.y = 1.0-result.y;
#endif
#if defined(RENDERER_GL) && defined(SRGB)
result = fast_gamma_to_linear_rgb(result);
#endif
#if defined(NORMAL_MAP_DECODE)
result = float4(decode_normal_map(result), result.a);
#elif defined(RGBM_DECODE)
result = float4(rgbm_decode(result), result.a);
#elif defined(NORMAL_ROUGHNESS_DECODE)
float3 N = 2.0*result.rgb - 1.0;
float roughness = result.a;
#if 0
// Specular AA
// TODO: Pre-bake this code
// http://blog.selfshadow.com/publications/s2013-shading-course/rad/s2013_pbs_rad_notes.pdf
float r = length(N);
if (r < 1.0) {
float rr = r * r ;
float kappa = (3.0 * r - r * rr) / (1.0 - rr) ;
float variance = 1.0 / (2.0 * kappa) ;
roughness = sqrt (roughness * roughness + variance);
}
#endif
result = float4(normalize(N), roughness);
#endif
RESULT(result);
"""
}
}

View file

@ -0,0 +1,13 @@
group = "Math"
display_name = "Sine"
inputs = {
"0505200e-439a-476b-b6a6-d643cf80e20b" = { name = "a" display_name = "Angle" type = "auto" }
}
output = {
type = { typeof: "a" }
}
code = """
RESULT(sin(a));
"""

View file

@ -0,0 +1,81 @@
group = "Skydome"
display_name = "Cloud Map"
depends_on = ["core/stingray_renderer/output_nodes/skydome_base"]
inputs = {
"72b20d47-88d1-48a4-99f5-819433b2d601" = { name = "texcoord" display_name = "UV" type = "vector2" domain = "pixel" }
}
domain = "pixel"
output = {
type = "float4"
}
options = {
"49e69d88-c7ce-4223-b3ce-149c0bf72a0a" = "ADDRESS_CLAMP"
"80c5c862-1d7e-4fc8-acfb-6fed1cd608f2" = "ADDRESS_WRAP"
"d293ab9d-8dda-4a7d-9114-0ff75dfe2378" = "FILTER_LINEAR"
"b780e0f4-527f-43c1-a39c-860e17417114" = "FILTER_POINT"
"04dac948-1138-4283-861f-20c70a20548f" = "FILTER_ANISOTROPIC"
"63b1e469-c7c0-4a32-b5da-5cf14d304ca0" = "SRGB"
"c3acf080-6620-435c-aeca-1f6ba47ee1b5" = "LINEAR"
"3f78e559-e91b-4b93-a68b-0140a240193c" = "RGBM_DECODE"
}
ui = [
{
type = "drop_down"
display_name = "Encoding"
options = {
"Linear Color" = "c3acf080-6620-435c-aeca-1f6ba47ee1b5"
"sRGB Color" = "63b1e469-c7c0-4a32-b5da-5cf14d304ca0"
"RGBM Color" = "3f78e559-e91b-4b93-a68b-0140a240193c"
}
default = "63b1e469-c7c0-4a32-b5da-5cf14d304ca0"
}
{
type = "drop_down"
display_name = "Address mode"
options = {
"Clamp" = "49e69d88-c7ce-4223-b3ce-149c0bf72a0a"
"Wrap" = "80c5c862-1d7e-4fc8-acfb-6fed1cd608f2"
}
default = "80c5c862-1d7e-4fc8-acfb-6fed1cd608f2"
}
{
type = "drop_down"
display_name = "Filter mode"
options = {
"Anisotropic" = "04dac948-1138-4283-861f-20c70a20548f"
"Linear" = "c3acf080-6620-435c-aeca-1f6ba47ee1b5"
"Point" = "b780e0f4-527f-43c1-a39c-860e17417114"
}
default = "04dac948-1138-4283-861f-20c70a20548f"
}
]
code_blocks = {
default = {
language = "hlsl"
samplers = {
skydome_cloud_map = {
sampler_state = "core/shader_nodes/graph_common#default_node_sampler"
source = "resource_set"
slot_name = "skydome_cloud_map"
type = "2d"
}
}
code = """
float4 result = TEX2D(skydome_cloud_map, texcoord);
#if defined(RENDERER_GL) && defined(SRGB)
result = fast_gamma_to_linear_rgba(result);
#elif defined(RGBM_DECODE)
result = float4(rgbm_decode(result), 0);
#endif
RESULT(result);
"""
}
}

View file

@ -0,0 +1,19 @@
group = "Skydome"
display_name = "Cloud Speed/Scale"
depends_on = ["core/stingray_renderer/output_nodes/skydome_base"]
imports = {
skydome_cloud_speed_scale = {
type = "float2"
domain = "global"
source = "shading_environment"
}
}
output = {
type = { typeof: "skydome_cloud_speed_scale" }
}
code = """
RESULT(skydome_cloud_speed_scale);
"""

View file

@ -0,0 +1,98 @@
group = "Skydome"
display_name = "Skydome Color"
depends_on = ["core/stingray_renderer/output_nodes/skydome_base"]
inputs = {
"33d9da7d-4833-40a3-84d9-c88daa3b2c1e" = { name = "texcoord" display_name = "UV" type = "vector2" domain = "pixel" }
}
imports = {
skydome_u_offset = {
type = "float"
domain = "global"
source = "shading_environment"
}
skydome_intensity = {
type = "float"
domain = "global"
source = "shading_environment"
}
}
domain = "pixel"
output = {
type = "float4"
}
options = {
"e333e9d1-0cb9-4caa-a40e-d212b375c777" = "ADDRESS_CLAMP"
"6599f9bf-2828-4b29-a20f-2f78e991862b" = "ADDRESS_WRAP"
"b5ec6d15-ed64-4c8a-b850-5c269a296f4a" = "FILTER_LINEAR"
"4f6b3270-b92a-433a-88e4-b2a3d015bd8a" = "FILTER_POINT"
"f7162c47-1353-4a4c-adfc-5b52dedc6053" = "FILTER_ANISOTROPIC"
"2392b33c-e963-4553-bebd-066f2a27bc30" = "SRGB"
"cf74777c-db6d-4ccc-b20a-801302770d6d" = "LINEAR"
"1f9c9f28-91ea-4bc9-ad22-f099146fead1" = "RGBM_DECODE"
}
ui = [
{
type = "drop_down"
display_name = "Encoding"
options = {
"Linear Color" = "cf74777c-db6d-4ccc-b20a-801302770d6d"
"sRGB Color" = "2392b33c-e963-4553-bebd-066f2a27bc30"
"RGBM Color" = "1f9c9f28-91ea-4bc9-ad22-f099146fead1"
}
default = "cf74777c-db6d-4ccc-b20a-801302770d6d"
}
{
type = "drop_down"
display_name = "Address mode"
options = {
"Clamp" = "e333e9d1-0cb9-4caa-a40e-d212b375c777"
"Wrap" = "6599f9bf-2828-4b29-a20f-2f78e991862b"
}
default = "6599f9bf-2828-4b29-a20f-2f78e991862b"
}
{
type = "drop_down"
display_name = "Filter mode"
options = {
"Anisotropic" = "f7162c47-1353-4a4c-adfc-5b52dedc6053"
"Linear" = "b5ec6d15-ed64-4c8a-b850-5c269a296f4a"
"Point" = "4f6b3270-b92a-433a-88e4-b2a3d015bd8a"
}
default = "b5ec6d15-ed64-4c8a-b850-5c269a296f4a"
}
]
code_blocks = {
default = {
language = "hlsl"
samplers = {
skydome_map = {
sampler_state = "core/shader_nodes/graph_common#default_node_sampler"
source = "resource_set"
slot_name = "skydome_map"
type = "2d"
}
}
code = """
float4 skydome_color = TEX2D(skydome_map, texcoord + float2(skydome_u_offset, 0));
#if defined(RENDERER_GL) && defined(SRGB)
skydome_color = fast_gamma_to_linear_rgba(skydome_color);
#elif defined(RGBM_DECODE)
skydome_color = float4(rgbm_decode(skydome_color), 0);
#endif
skydome_color.rgb *= skydome_intensity;
RESULT(skydome_color);
"""
}
}

View file

@ -0,0 +1,114 @@
group = "Skydome"
display_name = "Fog Color/Sun Blend"
depends_on = ["core/stingray_renderer/output_nodes/skydome_base"]
imports = {
eye_vector = {
type = "float3"
domain = "vertex"
output_channel = "eye_vector"
}
fog_color = {
type = "float3"
domain = "global"
source = "shading_environment"
}
sun_direction = {
type = "float3"
domain = "global"
source = "shading_environment"
}
sun_color = {
type = "float3"
domain = "global"
source = "engine"
}
fog_sun_blend = {
type = "float3"
domain = "global"
source = "shading_environment"
}
/*
// TODO
custom_fog_blend_direction = {
type = "float3"
domain = "global"
source = "shading_environment"
}
custom_fog_blend_color = {
type = "float3"
domain = "global"
source = "shading_environment"
}
custom_fog_blend = {
type = "float3"
domain = "global"
source = "shading_environment"
}
secondary_sun_direction = {
type = "float3"
domain = "global"
source = "shading_environment"
}
secondary_sun_color = {
type = "float3"
domain = "global"
source = "shading_environment"
}
secondary_sun_blend = {
type = "float3"
domain = "global"
source = "shading_environment"
}*/
}
defines = ["NEEDS_EYE_VECTOR", "HAS_SUN_COLOR"]
domain = "pixel"
output = {
type = "float4"
}
options = {
"44123bdc-7a38-4a69-b738-ad93e819f28c" = "SECONDARY_SUN_BLEND"
"f169202d-4a88-4347-8f26-af46d249a5f6" = "CUSTOM_FOG_BLEND"
}
ui = [
{ type = "checkbox" display_name = "Secondary sun blend" option = "44123bdc-7a38-4a69-b738-ad93e819f28c" }
{ type = "checkbox" display_name = "Custom fog blend" option = "f169202d-4a88-4347-8f26-af46d249a5f6" }
]
language = "hlsl"
code = """
float3 view_dir = normalize(eye_vector);
half sa = 0.0;
float3 c = fog_color;
/*#if defined(SECONDARY_SUN_BLEND)
sa = secondary_sun_blend.x * pow(saturate(dot(view_dir, secondary_sun_direction)), secondary_sun_blend.y);
c = lerp(c, secondary_sun_blend.z * secondary_sun_color, sa);
#endif
#if defined(CUSTOM_FOG_BLEND)
sa = custom_fog_blend.x * pow(saturate(dot(view_dir, custom_fog_blend_direction)), custom_fog_blend.y);
c = lerp(c, custom_fog_blend.z * custom_fog_blend_color, sa);
#endif*/
sa = fog_sun_blend.x * pow(saturate(dot(view_dir, sun_direction)), fog_sun_blend.y);
c = lerp(c, fog_sun_blend.z * sun_color, sa);
RESULT(float4(c, sa));
"""

View file

@ -0,0 +1,19 @@
group = "Skydome"
display_name = "Skydome Fog Height/Falloff"
depends_on = ["core/stingray_renderer/output_nodes/skydome_base"]
imports = {
skydome_fog_height_falloff = {
type = "float2"
domain = "global"
source = "shading_environment"
}
}
output = {
type = { typeof: "skydome_fog_height_falloff" }
}
code = """
RESULT(skydome_fog_height_falloff);
"""

View file

@ -0,0 +1,19 @@
group = "Skydome"
display_name = "Skydome Intensity"
depends_on = ["core/stingray_renderer/output_nodes/skydome_base"]
imports = {
skydome_intensity = {
type = "float"
domain = "global"
source = "shading_environment"
}
}
output = {
type = { typeof: "skydome_intensity" }
}
code = """
RESULT(skydome_intensity);
"""

View file

@ -0,0 +1,19 @@
group = "Skydome"
display_name = "Skydome Tint Color"
depends_on = ["core/stingray_renderer/output_nodes/skydome_base"]
imports = {
skydome_tint_color = {
type = "float3"
domain = "global"
source = "shading_environment"
}
}
output = {
type = { typeof: "skydome_tint_color" }
}
code = """
RESULT(skydome_tint_color);
"""

Some files were not shown because too many files have changed in this diff Show more