Prechádzať zdrojové kódy

Add a 3D tonemapping and color correction demo (#857)

This showcases various tonemapping operators and their interaction
with several color correction textures (1D and 3D).

A script generating neutral 3D LUT textures is also included.

Co-authored-by: Allen Pestaluky <[email protected]>
Hugo Locurcio 1 mesiac pred
rodič
commit
dc3670e25a
81 zmenil súbory, kde vykonal 2259 pridanie a 0 odobranie
  1. 261 0
      3d/tonemap_color_correction/3d_primitives.tscn
  2. 14 0
      3d/tonemap_color_correction/README.md
  3. BIN
      3d/tonemap_color_correction/example_luts/1d/detect_white_clipping.png
  4. 34 0
      3d/tonemap_color_correction/example_luts/1d/detect_white_clipping.png.import
  5. BIN
      3d/tonemap_color_correction/example_luts/1d/frozen.png
  6. 34 0
      3d/tonemap_color_correction/example_luts/1d/frozen.png.import
  7. BIN
      3d/tonemap_color_correction/example_luts/1d/heat.png
  8. 34 0
      3d/tonemap_color_correction/example_luts/1d/heat.png.import
  9. BIN
      3d/tonemap_color_correction/example_luts/1d/incandescent.png
  10. 34 0
      3d/tonemap_color_correction/example_luts/1d/incandescent.png.import
  11. BIN
      3d/tonemap_color_correction/example_luts/1d/posterized.png
  12. 34 0
      3d/tonemap_color_correction/example_luts/1d/posterized.png.import
  13. BIN
      3d/tonemap_color_correction/example_luts/1d/posterized_outline.png
  14. 34 0
      3d/tonemap_color_correction/example_luts/1d/posterized_outline.png.import
  15. BIN
      3d/tonemap_color_correction/example_luts/1d/rainbow.png
  16. 34 0
      3d/tonemap_color_correction/example_luts/1d/rainbow.png.import
  17. BIN
      3d/tonemap_color_correction/example_luts/1d/toxic.png
  18. 34 0
      3d/tonemap_color_correction/example_luts/1d/toxic.png.import
  19. BIN
      3d/tonemap_color_correction/example_luts/3d/brighten_shadows.png
  20. 26 0
      3d/tonemap_color_correction/example_luts/3d/brighten_shadows.png.import
  21. BIN
      3d/tonemap_color_correction/example_luts/3d/burned_blue.png
  22. 26 0
      3d/tonemap_color_correction/example_luts/3d/burned_blue.png.import
  23. BIN
      3d/tonemap_color_correction/example_luts/3d/cold_color.png
  24. 26 0
      3d/tonemap_color_correction/example_luts/3d/cold_color.png.import
  25. BIN
      3d/tonemap_color_correction/example_luts/3d/detect_white_clipping.png
  26. 26 0
      3d/tonemap_color_correction/example_luts/3d/detect_white_clipping.png.import
  27. BIN
      3d/tonemap_color_correction/example_luts/3d/dithered.png
  28. 26 0
      3d/tonemap_color_correction/example_luts/3d/dithered.png.import
  29. BIN
      3d/tonemap_color_correction/example_luts/3d/hue_shift.png
  30. 26 0
      3d/tonemap_color_correction/example_luts/3d/hue_shift.png.import
  31. BIN
      3d/tonemap_color_correction/example_luts/3d/posterized.png
  32. 26 0
      3d/tonemap_color_correction/example_luts/3d/posterized.png.import
  33. BIN
      3d/tonemap_color_correction/example_luts/3d/sepia.png
  34. 26 0
      3d/tonemap_color_correction/example_luts/3d/sepia.png.import
  35. BIN
      3d/tonemap_color_correction/example_luts/3d/stressed.png
  36. 26 0
      3d/tonemap_color_correction/example_luts/3d/stressed.png.import
  37. BIN
      3d/tonemap_color_correction/example_luts/3d/warm_color.png
  38. 26 0
      3d/tonemap_color_correction/example_luts/3d/warm_color.png.import
  39. BIN
      3d/tonemap_color_correction/example_luts/3d/yellowen.png
  40. 26 0
      3d/tonemap_color_correction/example_luts/3d/yellowen.png.import
  41. 421 0
      3d/tonemap_color_correction/gradients.tscn
  42. 21 0
      3d/tonemap_color_correction/gradients/gradient_bars.gd
  43. 1 0
      3d/tonemap_color_correction/gradients/gradient_bars.gd.uid
  44. 45 0
      3d/tonemap_color_correction/gradients/gradient_bars.tscn
  45. 45 0
      3d/tonemap_color_correction/gradients/gradient_steps.gdshader
  46. 1 0
      3d/tonemap_color_correction/gradients/gradient_steps.gdshader.uid
  47. 46 0
      3d/tonemap_color_correction/gradients/gradients_controls.gd
  48. 1 0
      3d/tonemap_color_correction/gradients/gradients_controls.gd.uid
  49. 84 0
      3d/tonemap_color_correction/gradients/hues.gdshader
  50. 1 0
      3d/tonemap_color_correction/gradients/hues.gdshader.uid
  51. 91 0
      3d/tonemap_color_correction/hues.tscn
  52. 1 0
      3d/tonemap_color_correction/icon.svg
  53. 37 0
      3d/tonemap_color_correction/icon.svg.import
  54. BIN
      3d/tonemap_color_correction/neutral_luts/1d/lut_neutral_1d.png
  55. 34 0
      3d/tonemap_color_correction/neutral_luts/1d/lut_neutral_1d.png.import
  56. 47 0
      3d/tonemap_color_correction/neutral_luts/3d/create_neutral_3d_luts.gd
  57. 1 0
      3d/tonemap_color_correction/neutral_luts/3d/create_neutral_3d_luts.gd.uid
  58. BIN
      3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_17x17x17_horizontal.png
  59. 26 0
      3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_17x17x17_horizontal.png.import
  60. BIN
      3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_17x17x17_vertical.png
  61. 26 0
      3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_17x17x17_vertical.png.import
  62. BIN
      3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_33x33x33_horizontal.png
  63. 26 0
      3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_33x33x33_horizontal.png.import
  64. BIN
      3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_33x33x33_vertical.png
  65. 26 0
      3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_33x33x33_vertical.png.import
  66. BIN
      3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_51x51x51_horizontal.png
  67. 26 0
      3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_51x51x51_horizontal.png.import
  68. BIN
      3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_51x51x51_vertical.png
  69. 26 0
      3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_51x51x51_vertical.png.import
  70. BIN
      3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_65x65x65_horizontal.png
  71. 26 0
      3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_65x65x65_horizontal.png.import
  72. BIN
      3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_65x65x65_vertical.png
  73. 26 0
      3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_65x65x65_vertical.png.import
  74. 101 0
      3d/tonemap_color_correction/options.gd
  75. 1 0
      3d/tonemap_color_correction/options.gd.uid
  76. 32 0
      3d/tonemap_color_correction/project.godot
  77. 0 0
      3d/tonemap_color_correction/screenshots/.gdignore
  78. BIN
      3d/tonemap_color_correction/screenshots/tonemap_color_correction.webp
  79. 203 0
      3d/tonemap_color_correction/test.tscn
  80. 3 0
      3d/tonemap_color_correction/test_scene.gd
  81. 1 0
      3d/tonemap_color_correction/test_scene.gd.uid

+ 261 - 0
3d/tonemap_color_correction/3d_primitives.tscn

@@ -0,0 +1,261 @@
+[gd_scene load_steps=26 format=3 uid="uid://bfbqknlrqre0c"]
+
+[ext_resource type="Script" uid="uid://cljtufy2vjbmv" path="res://test_scene.gd" id="1_vpdan"]
+
+[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_y6uuk"]
+sky_top_color = Color(0, 0, 0, 1)
+sky_horizon_color = Color(0.1984, 0.242987, 0.32, 1)
+ground_bottom_color = Color(0.156863, 0.160784, 0.2, 1)
+ground_horizon_color = Color(0.156863, 0.160784, 0.2, 1)
+sun_angle_max = 6.0
+sun_curve = 3.51379
+
+[sub_resource type="Sky" id="Sky_lexvt"]
+sky_material = SubResource("ProceduralSkyMaterial_y6uuk")
+
+[sub_resource type="Environment" id="Environment_lqw28"]
+background_mode = 2
+sky = SubResource("Sky_lexvt")
+tonemap_mode = 2
+tonemap_white = 6.0
+glow_enabled = true
+glow_intensity = 0.09
+glow_blend_mode = 1
+fog_enabled = true
+fog_density = 0.025
+fog_aerial_perspective = 1.0
+adjustment_enabled = true
+
+[sub_resource type="BoxMesh" id="BoxMesh_ff240"]
+size = Vector3(512, 1, 512)
+
+[sub_resource type="Gradient" id="Gradient_sho7j"]
+offsets = PackedFloat32Array(0.260163, 0.398374, 0.536585, 0.699187, 0.829268, 1)
+colors = PackedColorArray(0.336608, 0.336608, 0.336608, 1, 0.589096, 0.589095, 0.589096, 1, 0.521141, 0.52114, 0.521141, 1, 0.762404, 0.762404, 0.762403, 1, 0.48179, 0.48179, 0.481789, 1, 1, 1, 1, 1)
+
+[sub_resource type="FastNoiseLite" id="FastNoiseLite_dm8vr"]
+
+[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_hbgko"]
+width = 1024
+height = 1024
+seamless = true
+color_ramp = SubResource("Gradient_sho7j")
+noise = SubResource("FastNoiseLite_dm8vr")
+
+[sub_resource type="FastNoiseLite" id="FastNoiseLite_mq5hl"]
+
+[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_tdt10"]
+width = 1024
+height = 1024
+seamless = true
+as_normal_map = true
+bump_strength = 10.0
+noise = SubResource("FastNoiseLite_mq5hl")
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_4ldfp"]
+albedo_texture = SubResource("NoiseTexture2D_hbgko")
+normal_enabled = true
+normal_texture = SubResource("NoiseTexture2D_tdt10")
+uv1_scale = Vector3(512, 256, 1)
+texture_filter = 5
+
+[sub_resource type="BoxMesh" id="BoxMesh_6wvpc"]
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_l4mxj"]
+albedo_color = Color(0, 0, 0, 1)
+emission_enabled = true
+emission = Color(2, 1.5, 1, 1)
+
+[sub_resource type="SphereMesh" id="SphereMesh_qnmea"]
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_kssqo"]
+metallic = 1.0
+roughness = 0.0
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_4geml"]
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_3eq2w"]
+metallic = 1.0
+roughness = 0.5
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_uqci1"]
+albedo_color = Color(0.501961, 0.501961, 0.501961, 1)
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_8sl4i"]
+albedo_color = Color(0.501961, 0.501961, 0.501961, 1)
+metallic = 1.0
+roughness = 0.5
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_pauuc"]
+albedo_color = Color(1, 0.25098, 0.25098, 1)
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_8w4e2"]
+albedo_color = Color(1, 0.25098, 0.25098, 1)
+metallic = 1.0
+roughness = 0.5
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_cb5og"]
+albedo_color = Color(0.25098, 1, 0.25098, 1)
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ah8ww"]
+albedo_color = Color(0.25098, 1, 0.25098, 1)
+metallic = 1.0
+roughness = 0.5
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ako3b"]
+albedo_color = Color(0.25098, 0.25098, 1, 1)
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_suuj5"]
+albedo_color = Color(0.25098, 0.25098, 1, 1)
+metallic = 1.0
+roughness = 0.5
+
+[node name="3DPrimitives" type="Node3D" node_paths=PackedStringArray("world_environment")]
+script = ExtResource("1_vpdan")
+world_environment = NodePath("WorldEnvironment")
+
+[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
+transform = Transform3D(0.866126, 0.13782, -0.480448, 0.0352591, 0.941991, 0.333781, 0.49858, -0.306037, 0.811024, -2.58974, 2.10013, -4.66397)
+light_color = Color(0.776471, 0.917647, 1, 1)
+light_energy = 0.4
+shadow_enabled = true
+shadow_bias = 0.04
+shadow_blur = 2.0
+directional_shadow_mode = 0
+directional_shadow_fade_start = 1.0
+directional_shadow_max_distance = 12.0
+
+[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
+environment = SubResource("Environment_lqw28")
+
+[node name="Ground" type="MeshInstance3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.5, -0.4, 1)
+mesh = SubResource("BoxMesh_ff240")
+surface_material_override/0 = SubResource("StandardMaterial3D_4ldfp")
+
+[node name="Testers" type="Node3D" parent="."]
+
+[node name="GlowingBox" type="MeshInstance3D" parent="Testers"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4, 0.5, 0)
+mesh = SubResource("BoxMesh_6wvpc")
+skeleton = NodePath("../..")
+surface_material_override/0 = SubResource("StandardMaterial3D_l4mxj")
+
+[node name="OmniLight3D" type="OmniLight3D" parent="Testers/GlowingBox"]
+light_energy = 2.0
+shadow_blur = 2.0
+
+[node name="GlowingSphere" type="MeshInstance3D" parent="Testers"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4, 1.5, 0)
+mesh = SubResource("SphereMesh_qnmea")
+skeleton = NodePath("../..")
+surface_material_override/0 = SubResource("StandardMaterial3D_l4mxj")
+
+[node name="OmniLight3D" type="OmniLight3D" parent="Testers/GlowingSphere"]
+light_energy = 2.0
+shadow_blur = 2.0
+
+[node name="MirrorSphere" type="MeshInstance3D" parent="Testers"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4, 2.5, -1)
+mesh = SubResource("SphereMesh_qnmea")
+skeleton = NodePath("../..")
+surface_material_override/0 = SubResource("StandardMaterial3D_kssqo")
+
+[node name="WhiteBox" type="MeshInstance3D" parent="Testers"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 0.5, 0)
+mesh = SubResource("BoxMesh_6wvpc")
+skeleton = NodePath("../..")
+surface_material_override/0 = SubResource("StandardMaterial3D_4geml")
+
+[node name="WhiteSphere" type="MeshInstance3D" parent="Testers"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 1.5, 0)
+mesh = SubResource("SphereMesh_qnmea")
+skeleton = NodePath("../..")
+surface_material_override/0 = SubResource("StandardMaterial3D_4geml")
+
+[node name="WhiteMetallicSphere" type="MeshInstance3D" parent="Testers"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 2.5, -1)
+mesh = SubResource("SphereMesh_qnmea")
+skeleton = NodePath("../..")
+surface_material_override/0 = SubResource("StandardMaterial3D_3eq2w")
+
+[node name="GrayBox" type="MeshInstance3D" parent="Testers"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 0.5, 0)
+mesh = SubResource("BoxMesh_6wvpc")
+skeleton = NodePath("../..")
+surface_material_override/0 = SubResource("StandardMaterial3D_uqci1")
+
+[node name="GraySphere" type="MeshInstance3D" parent="Testers"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 1.5, 0)
+mesh = SubResource("SphereMesh_qnmea")
+skeleton = NodePath("../..")
+surface_material_override/0 = SubResource("StandardMaterial3D_uqci1")
+
+[node name="GrayMetallicSphere" type="MeshInstance3D" parent="Testers"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 2.5, -1)
+mesh = SubResource("SphereMesh_qnmea")
+skeleton = NodePath("../..")
+surface_material_override/0 = SubResource("StandardMaterial3D_8sl4i")
+
+[node name="RedBox" type="MeshInstance3D" parent="Testers"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 0.5, 0)
+mesh = SubResource("BoxMesh_6wvpc")
+skeleton = NodePath("../..")
+surface_material_override/0 = SubResource("StandardMaterial3D_pauuc")
+
+[node name="RedSphere" type="MeshInstance3D" parent="Testers"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 1.5, 0)
+mesh = SubResource("SphereMesh_qnmea")
+skeleton = NodePath("../..")
+surface_material_override/0 = SubResource("StandardMaterial3D_pauuc")
+
+[node name="RedMetallicSphere" type="MeshInstance3D" parent="Testers"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 2.5, -1)
+mesh = SubResource("SphereMesh_qnmea")
+skeleton = NodePath("../..")
+surface_material_override/0 = SubResource("StandardMaterial3D_8w4e2")
+
+[node name="GreenBox" type="MeshInstance3D" parent="Testers"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
+mesh = SubResource("BoxMesh_6wvpc")
+skeleton = NodePath("../..")
+surface_material_override/0 = SubResource("StandardMaterial3D_cb5og")
+
+[node name="GreenSphere" type="MeshInstance3D" parent="Testers"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0)
+mesh = SubResource("SphereMesh_qnmea")
+skeleton = NodePath("../..")
+surface_material_override/0 = SubResource("StandardMaterial3D_cb5og")
+
+[node name="GreenMetallicSphere" type="MeshInstance3D" parent="Testers"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, -1)
+mesh = SubResource("SphereMesh_qnmea")
+skeleton = NodePath("../..")
+surface_material_override/0 = SubResource("StandardMaterial3D_ah8ww")
+
+[node name="BlueBox" type="MeshInstance3D" parent="Testers"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0.5, 0)
+mesh = SubResource("BoxMesh_6wvpc")
+skeleton = NodePath("../..")
+surface_material_override/0 = SubResource("StandardMaterial3D_ako3b")
+
+[node name="BlueSphere" type="MeshInstance3D" parent="Testers"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1.5, 0)
+mesh = SubResource("SphereMesh_qnmea")
+skeleton = NodePath("../..")
+surface_material_override/0 = SubResource("StandardMaterial3D_ako3b")
+
+[node name="BlueMetallicSphere" type="MeshInstance3D" parent="Testers"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 2.5, -1)
+mesh = SubResource("SphereMesh_qnmea")
+skeleton = NodePath("../..")
+surface_material_override/0 = SubResource("StandardMaterial3D_suuj5")
+
+[node name="Camera3D" type="Camera3D" parent="."]
+transform = Transform3D(0.942327, -0.0710023, 0.327076, 6.57846e-09, 0.977239, 0.212141, -0.334694, -0.199906, 0.920879, 0.669204, 2.35, 4.04922)
+fov = 50.0
+
+[node name="ReflectionProbe" type="ReflectionProbe" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.5, 2, 0)
+size = Vector3(512, 512, 512)
+enable_shadows = true

+ 14 - 0
3d/tonemap_color_correction/README.md

@@ -0,0 +1,14 @@
+# Tonemapping and Color Correction
+
+This showcases various tonemapping operators and their interaction with several
+color correction textures (1D and 3D).
+
+A script generating neutral 3D LUT textures is also included.
+
+Language: GDScript
+
+Renderer: Forward+
+
+## Screenshots
+
+![Screenshot](screenshots/tonemap_color_correction.webp)

BIN
3d/tonemap_color_correction/example_luts/1d/detect_white_clipping.png


+ 34 - 0
3d/tonemap_color_correction/example_luts/1d/detect_white_clipping.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://8iyvvj75q6bd"
+path="res://.godot/imported/detect_white_clipping.png-ff83ca2587cf6e3783223e00c5b42bce.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://example_luts/1d/detect_white_clipping.png"
+dest_files=["res://.godot/imported/detect_white_clipping.png-ff83ca2587cf6e3783223e00c5b42bce.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1

BIN
3d/tonemap_color_correction/example_luts/1d/frozen.png


+ 34 - 0
3d/tonemap_color_correction/example_luts/1d/frozen.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://3fu2y401e2wn"
+path="res://.godot/imported/frozen.png-457f8ff344433e9f459b5caaede7bfab.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://example_luts/1d/frozen.png"
+dest_files=["res://.godot/imported/frozen.png-457f8ff344433e9f459b5caaede7bfab.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1

BIN
3d/tonemap_color_correction/example_luts/1d/heat.png


+ 34 - 0
3d/tonemap_color_correction/example_luts/1d/heat.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://t3ag4e6j1i7n"
+path="res://.godot/imported/heat.png-27bfc7c4ee7ae772dcd2e3b8c4e82264.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://example_luts/1d/heat.png"
+dest_files=["res://.godot/imported/heat.png-27bfc7c4ee7ae772dcd2e3b8c4e82264.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1

BIN
3d/tonemap_color_correction/example_luts/1d/incandescent.png


+ 34 - 0
3d/tonemap_color_correction/example_luts/1d/incandescent.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b76jtu3lfrof8"
+path="res://.godot/imported/incandescent.png-b204183d282b9168fd54f936bbf329ce.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://example_luts/1d/incandescent.png"
+dest_files=["res://.godot/imported/incandescent.png-b204183d282b9168fd54f936bbf329ce.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1

BIN
3d/tonemap_color_correction/example_luts/1d/posterized.png


+ 34 - 0
3d/tonemap_color_correction/example_luts/1d/posterized.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://emt27ho4felt"
+path="res://.godot/imported/posterized.png-a34de9ef248db176b274e5299bfdfe43.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://example_luts/1d/posterized.png"
+dest_files=["res://.godot/imported/posterized.png-a34de9ef248db176b274e5299bfdfe43.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1

BIN
3d/tonemap_color_correction/example_luts/1d/posterized_outline.png


+ 34 - 0
3d/tonemap_color_correction/example_luts/1d/posterized_outline.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cy3n57u6o0x5t"
+path="res://.godot/imported/posterized_outline.png-a5caa8e602fc1e5b6e6b8ce44670a14d.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://example_luts/1d/posterized_outline.png"
+dest_files=["res://.godot/imported/posterized_outline.png-a5caa8e602fc1e5b6e6b8ce44670a14d.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1

BIN
3d/tonemap_color_correction/example_luts/1d/rainbow.png


+ 34 - 0
3d/tonemap_color_correction/example_luts/1d/rainbow.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://0y7x46bwdm8q"
+path="res://.godot/imported/rainbow.png-3f78eb0d72b9b81b1fbcb63640e8b7c7.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://example_luts/1d/rainbow.png"
+dest_files=["res://.godot/imported/rainbow.png-3f78eb0d72b9b81b1fbcb63640e8b7c7.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1

BIN
3d/tonemap_color_correction/example_luts/1d/toxic.png


+ 34 - 0
3d/tonemap_color_correction/example_luts/1d/toxic.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cacjitmb1bk88"
+path="res://.godot/imported/toxic.png-b2acad2fbcf1706454391fb0b2887380.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://example_luts/1d/toxic.png"
+dest_files=["res://.godot/imported/toxic.png-b2acad2fbcf1706454391fb0b2887380.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1

BIN
3d/tonemap_color_correction/example_luts/3d/brighten_shadows.png


+ 26 - 0
3d/tonemap_color_correction/example_luts/3d/brighten_shadows.png.import

@@ -0,0 +1,26 @@
+[remap]
+
+importer="3d_texture"
+type="CompressedTexture3D"
+uid="uid://1e0vurlkfhcc"
+path="res://.godot/imported/brighten_shadows.png-61280821ebde1ed825cfb67e480939d6.ctex3d"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://example_luts/3d/brighten_shadows.png"
+dest_files=["res://.godot/imported/brighten_shadows.png-61280821ebde1ed825cfb67e480939d6.ctex3d"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+slices/horizontal=33
+slices/vertical=1

BIN
3d/tonemap_color_correction/example_luts/3d/burned_blue.png


+ 26 - 0
3d/tonemap_color_correction/example_luts/3d/burned_blue.png.import

@@ -0,0 +1,26 @@
+[remap]
+
+importer="3d_texture"
+type="CompressedTexture3D"
+uid="uid://clhpel6jn4gus"
+path="res://.godot/imported/burned_blue.png-3fa578a6aed0a39c8ea444d1fdfa2bd0.ctex3d"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://example_luts/3d/burned_blue.png"
+dest_files=["res://.godot/imported/burned_blue.png-3fa578a6aed0a39c8ea444d1fdfa2bd0.ctex3d"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+slices/horizontal=33
+slices/vertical=1

BIN
3d/tonemap_color_correction/example_luts/3d/cold_color.png


+ 26 - 0
3d/tonemap_color_correction/example_luts/3d/cold_color.png.import

@@ -0,0 +1,26 @@
+[remap]
+
+importer="3d_texture"
+type="CompressedTexture3D"
+uid="uid://b4jlxhcbyp0e8"
+path="res://.godot/imported/cold_color.png-210fff9bc7f9e391d44adb29f141a6a0.ctex3d"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://example_luts/3d/cold_color.png"
+dest_files=["res://.godot/imported/cold_color.png-210fff9bc7f9e391d44adb29f141a6a0.ctex3d"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+slices/horizontal=33
+slices/vertical=1

BIN
3d/tonemap_color_correction/example_luts/3d/detect_white_clipping.png


+ 26 - 0
3d/tonemap_color_correction/example_luts/3d/detect_white_clipping.png.import

@@ -0,0 +1,26 @@
+[remap]
+
+importer="3d_texture"
+type="CompressedTexture3D"
+uid="uid://buqiwm6kbrupc"
+path="res://.godot/imported/detect_white_clipping.png-5e597e393d8905a1d4a3c347c8c9f065.ctex3d"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://example_luts/3d/detect_white_clipping.png"
+dest_files=["res://.godot/imported/detect_white_clipping.png-5e597e393d8905a1d4a3c347c8c9f065.ctex3d"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+slices/horizontal=33
+slices/vertical=1

BIN
3d/tonemap_color_correction/example_luts/3d/dithered.png


+ 26 - 0
3d/tonemap_color_correction/example_luts/3d/dithered.png.import

@@ -0,0 +1,26 @@
+[remap]
+
+importer="3d_texture"
+type="CompressedTexture3D"
+uid="uid://b422dlqu7vaap"
+path="res://.godot/imported/dithered.png-20af5512e106e0d0d22dc6f2401670ba.ctex3d"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://example_luts/3d/dithered.png"
+dest_files=["res://.godot/imported/dithered.png-20af5512e106e0d0d22dc6f2401670ba.ctex3d"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+slices/horizontal=33
+slices/vertical=1

BIN
3d/tonemap_color_correction/example_luts/3d/hue_shift.png


+ 26 - 0
3d/tonemap_color_correction/example_luts/3d/hue_shift.png.import

@@ -0,0 +1,26 @@
+[remap]
+
+importer="3d_texture"
+type="CompressedTexture3D"
+uid="uid://d34wgtqnau46i"
+path="res://.godot/imported/hue_shift.png-bdb03b2ebc9f7e73fb02d799a0ad2345.ctex3d"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://example_luts/3d/hue_shift.png"
+dest_files=["res://.godot/imported/hue_shift.png-bdb03b2ebc9f7e73fb02d799a0ad2345.ctex3d"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+slices/horizontal=33
+slices/vertical=1

BIN
3d/tonemap_color_correction/example_luts/3d/posterized.png


+ 26 - 0
3d/tonemap_color_correction/example_luts/3d/posterized.png.import

@@ -0,0 +1,26 @@
+[remap]
+
+importer="3d_texture"
+type="CompressedTexture3D"
+uid="uid://do3vr08hxucu1"
+path="res://.godot/imported/posterized.png-44ac6ee9d7b1cdeeb7d89b28e8d80785.ctex3d"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://example_luts/3d/posterized.png"
+dest_files=["res://.godot/imported/posterized.png-44ac6ee9d7b1cdeeb7d89b28e8d80785.ctex3d"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+slices/horizontal=33
+slices/vertical=1

BIN
3d/tonemap_color_correction/example_luts/3d/sepia.png


+ 26 - 0
3d/tonemap_color_correction/example_luts/3d/sepia.png.import

@@ -0,0 +1,26 @@
+[remap]
+
+importer="3d_texture"
+type="CompressedTexture3D"
+uid="uid://8nw1mdfywg0d"
+path="res://.godot/imported/sepia.png-3fc1524e0a3f1aac46a6ca885424898a.ctex3d"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://example_luts/3d/sepia.png"
+dest_files=["res://.godot/imported/sepia.png-3fc1524e0a3f1aac46a6ca885424898a.ctex3d"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+slices/horizontal=33
+slices/vertical=1

BIN
3d/tonemap_color_correction/example_luts/3d/stressed.png


+ 26 - 0
3d/tonemap_color_correction/example_luts/3d/stressed.png.import

@@ -0,0 +1,26 @@
+[remap]
+
+importer="3d_texture"
+type="CompressedTexture3D"
+uid="uid://do2pdpu2dw1m3"
+path="res://.godot/imported/stressed.png-fb7bc49bf082d84552336c3272977359.ctex3d"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://example_luts/3d/stressed.png"
+dest_files=["res://.godot/imported/stressed.png-fb7bc49bf082d84552336c3272977359.ctex3d"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+slices/horizontal=33
+slices/vertical=1

BIN
3d/tonemap_color_correction/example_luts/3d/warm_color.png


+ 26 - 0
3d/tonemap_color_correction/example_luts/3d/warm_color.png.import

@@ -0,0 +1,26 @@
+[remap]
+
+importer="3d_texture"
+type="CompressedTexture3D"
+uid="uid://dsoc6y7s4jh1o"
+path="res://.godot/imported/warm_color.png-d14ef9e5e700aed592bef8aba446a65c.ctex3d"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://example_luts/3d/warm_color.png"
+dest_files=["res://.godot/imported/warm_color.png-d14ef9e5e700aed592bef8aba446a65c.ctex3d"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+slices/horizontal=33
+slices/vertical=1

BIN
3d/tonemap_color_correction/example_luts/3d/yellowen.png


+ 26 - 0
3d/tonemap_color_correction/example_luts/3d/yellowen.png.import

@@ -0,0 +1,26 @@
+[remap]
+
+importer="3d_texture"
+type="CompressedTexture3D"
+uid="uid://billfphypqcrj"
+path="res://.godot/imported/yellowen.png-3cb1221bb144a870704136f5b5a4b8fc.ctex3d"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://example_luts/3d/yellowen.png"
+dest_files=["res://.godot/imported/yellowen.png-3cb1221bb144a870704136f5b5a4b8fc.ctex3d"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+slices/horizontal=33
+slices/vertical=1

+ 421 - 0
3d/tonemap_color_correction/gradients.tscn

@@ -0,0 +1,421 @@
+[gd_scene load_steps=32 format=3 uid="uid://drmdg7kgtgadn"]
+
+[ext_resource type="Script" uid="uid://cljtufy2vjbmv" path="res://test_scene.gd" id="1_t2d15"]
+[ext_resource type="PackedScene" uid="uid://bavd54phmfgyh" path="res://gradients/gradient_bars.tscn" id="2_p2qnr"]
+[ext_resource type="Shader" uid="uid://cg2ft7motxwuc" path="res://gradients/gradient_steps.gdshader" id="3_28j7b"]
+[ext_resource type="Script" uid="uid://bd2eaaib4wnpa" path="res://gradients/gradients_controls.gd" id="4_fust6"]
+
+[sub_resource type="Environment" id="Environment_lqw28"]
+background_mode = 1
+background_energy_multiplier = 0.0
+ambient_light_source = 1
+reflected_light_source = 1
+tonemap_white = 6.0
+glow_intensity = 0.09
+glow_blend_mode = 1
+fog_density = 0.025
+adjustment_enabled = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_bstc8"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(1, 0, 0, 1)
+shader_parameter/steps = 10
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_eljuh"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(1, 0, 0, 1)
+shader_parameter/steps = 1
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_81w4g"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(1, 0.0392157, 0.0392157, 1)
+shader_parameter/steps = 10
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_ots2d"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(1, 0.0392157, 0.0392157, 1)
+shader_parameter/steps = 1
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_41i5d"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(1, 0.501961, 0.0392157, 1)
+shader_parameter/steps = 10
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_j0kf1"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(1, 0.501961, 0.0392157, 1)
+shader_parameter/steps = 1
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_smq08"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(1, 0.0392157, 0.501961, 1)
+shader_parameter/steps = 10
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_w135p"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(1, 0.0392157, 0.501961, 1)
+shader_parameter/steps = 1
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_2wh7i"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(0, 1, 0, 1)
+shader_parameter/steps = 10
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_xj3wk"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(0, 1, 0, 1)
+shader_parameter/steps = 1
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_ttmyv"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(0.0392157, 1, 0.0392157, 1)
+shader_parameter/steps = 10
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_g72v6"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(0.0392157, 1, 0.0392157, 1)
+shader_parameter/steps = 1
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_wjnjt"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(0.501961, 1, 0.0392157, 1)
+shader_parameter/steps = 10
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_wm7wm"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(0.501961, 1, 0.0392157, 1)
+shader_parameter/steps = 1
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_7d5gp"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(0.0392157, 1, 0.501961, 1)
+shader_parameter/steps = 10
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_115u5"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(0.0392157, 1, 0.501961, 1)
+shader_parameter/steps = 1
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_g82jm"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(0, 0, 1, 1)
+shader_parameter/steps = 10
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_ceq2s"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(0, 0, 1, 1)
+shader_parameter/steps = 1
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_tg3s4"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(0.0392157, 0.0392157, 1, 1)
+shader_parameter/steps = 10
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_xss0p"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(0.0392157, 0.0392157, 1, 1)
+shader_parameter/steps = 1
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_w3opq"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(0.501961, 0.0392157, 1, 1)
+shader_parameter/steps = 10
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_qwbip"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(0.501961, 0.0392157, 1, 1)
+shader_parameter/steps = 1
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_x3aop"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(0.0392157, 0.501961, 1, 1)
+shader_parameter/steps = 10
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_j2m03"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(0.0392157, 0.501961, 1, 1)
+shader_parameter/steps = 1
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_2llro"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(0.501961, 0.501961, 0.501961, 1)
+shader_parameter/steps = 10
+shader_parameter/exponential_view = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_es2ea"]
+render_priority = 0
+shader = ExtResource("3_28j7b")
+shader_parameter/my_color = Color(0.501961, 0.501961, 0.501961, 1)
+shader_parameter/steps = 1
+shader_parameter/exponential_view = true
+
+[node name="Gradients" type="Node3D" node_paths=PackedStringArray("world_environment")]
+script = ExtResource("1_t2d15")
+world_environment = NodePath("WorldEnvironment")
+
+[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
+environment = SubResource("Environment_lqw28")
+
+[node name="Camera3D" type="Camera3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.5)
+projection = 1
+
+[node name="Label3D" type="Label3D" parent="."]
+transform = Transform3D(0.15, 0, 0, 0, 0.15, 0, 0, 0, 0.15, -0.795469, 0.279246, 0)
+text = "0.0"
+horizontal_alignment = 0
+vertical_alignment = 2
+
+[node name="Label3D2" type="Label3D" parent="."]
+transform = Transform3D(0.15, 0, 0, 0, 0.15, 0, 0, 0, 0.15, 0.0286667, 0.279246, 0)
+text = "1.0"
+horizontal_alignment = 2
+vertical_alignment = 2
+
+[node name="Label3D3" type="Label3D" parent="."]
+transform = Transform3D(0.15, 0, 0, 0, 0.15, 0, 0, 0, 0.15, 0.0461101, 0.279246, 0)
+text = "0.0"
+horizontal_alignment = 0
+vertical_alignment = 2
+
+[node name="Label3D4" type="Label3D" parent="."]
+transform = Transform3D(0.15, 0, 0, 0, 0.15, 0, 0, 0, 0.15, 0.867011, 0.279246, 0)
+text = "6.0"
+horizontal_alignment = 2
+vertical_alignment = 2
+
+[node name="Gradients_White" parent="." instance=ExtResource("2_p2qnr")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.25, 0)
+
+[node name="Gradients_Red" parent="." instance=ExtResource("2_p2qnr")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.2, 0)
+
+[node name="0-to-HDR" parent="Gradients_Red" index="0"]
+material_override = SubResource("ShaderMaterial_bstc8")
+
+[node name="0-to-1" parent="Gradients_Red" index="1"]
+material_override = SubResource("ShaderMaterial_eljuh")
+
+[node name="Gradients_Red2" parent="." instance=ExtResource("2_p2qnr")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.15, 0)
+
+[node name="0-to-HDR" parent="Gradients_Red2" index="0"]
+material_override = SubResource("ShaderMaterial_81w4g")
+
+[node name="0-to-1" parent="Gradients_Red2" index="1"]
+material_override = SubResource("ShaderMaterial_ots2d")
+
+[node name="Gradients_Red3" parent="." instance=ExtResource("2_p2qnr")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0)
+
+[node name="0-to-HDR" parent="Gradients_Red3" index="0"]
+material_override = SubResource("ShaderMaterial_41i5d")
+
+[node name="0-to-1" parent="Gradients_Red3" index="1"]
+material_override = SubResource("ShaderMaterial_j0kf1")
+
+[node name="Gradients_Red4" parent="." instance=ExtResource("2_p2qnr")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.05, 0)
+
+[node name="0-to-HDR" parent="Gradients_Red4" index="0"]
+material_override = SubResource("ShaderMaterial_smq08")
+
+[node name="0-to-1" parent="Gradients_Red4" index="1"]
+material_override = SubResource("ShaderMaterial_w135p")
+
+[node name="Gradients_Green" parent="." instance=ExtResource("2_p2qnr")]
+
+[node name="0-to-HDR" parent="Gradients_Green" index="0"]
+material_override = SubResource("ShaderMaterial_2wh7i")
+
+[node name="0-to-1" parent="Gradients_Green" index="1"]
+material_override = SubResource("ShaderMaterial_xj3wk")
+
+[node name="Gradients_Green2" parent="." instance=ExtResource("2_p2qnr")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.05, 0)
+
+[node name="0-to-HDR" parent="Gradients_Green2" index="0"]
+material_override = SubResource("ShaderMaterial_ttmyv")
+
+[node name="0-to-1" parent="Gradients_Green2" index="1"]
+material_override = SubResource("ShaderMaterial_g72v6")
+
+[node name="Gradients_Green3" parent="." instance=ExtResource("2_p2qnr")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.1, 0)
+
+[node name="0-to-HDR" parent="Gradients_Green3" index="0"]
+material_override = SubResource("ShaderMaterial_wjnjt")
+
+[node name="0-to-1" parent="Gradients_Green3" index="1"]
+material_override = SubResource("ShaderMaterial_wm7wm")
+
+[node name="Gradients_Green4" parent="." instance=ExtResource("2_p2qnr")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.15, 0)
+
+[node name="0-to-HDR" parent="Gradients_Green4" index="0"]
+material_override = SubResource("ShaderMaterial_7d5gp")
+
+[node name="0-to-1" parent="Gradients_Green4" index="1"]
+material_override = SubResource("ShaderMaterial_115u5")
+
+[node name="Gradients_Blue" parent="." instance=ExtResource("2_p2qnr")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.2, 0)
+
+[node name="0-to-HDR" parent="Gradients_Blue" index="0"]
+material_override = SubResource("ShaderMaterial_g82jm")
+
+[node name="0-to-1" parent="Gradients_Blue" index="1"]
+material_override = SubResource("ShaderMaterial_ceq2s")
+
+[node name="Gradients_Blue2" parent="." instance=ExtResource("2_p2qnr")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.25, 0)
+
+[node name="0-to-HDR" parent="Gradients_Blue2" index="0"]
+material_override = SubResource("ShaderMaterial_tg3s4")
+
+[node name="0-to-1" parent="Gradients_Blue2" index="1"]
+material_override = SubResource("ShaderMaterial_xss0p")
+
+[node name="Gradients_Blue3" parent="." instance=ExtResource("2_p2qnr")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.3, 0)
+
+[node name="0-to-HDR" parent="Gradients_Blue3" index="0"]
+material_override = SubResource("ShaderMaterial_w3opq")
+
+[node name="0-to-1" parent="Gradients_Blue3" index="1"]
+material_override = SubResource("ShaderMaterial_qwbip")
+
+[node name="Gradients_Blue4" parent="." instance=ExtResource("2_p2qnr")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.35, 0)
+
+[node name="0-to-HDR" parent="Gradients_Blue4" index="0"]
+material_override = SubResource("ShaderMaterial_x3aop")
+
+[node name="0-to-1" parent="Gradients_Blue4" index="1"]
+material_override = SubResource("ShaderMaterial_j2m03")
+
+[node name="Gradients_Custom" parent="." instance=ExtResource("2_p2qnr")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.4, 0)
+
+[node name="0-to-HDR" parent="Gradients_Custom" index="0"]
+material_override = SubResource("ShaderMaterial_2llro")
+
+[node name="0-to-1" parent="Gradients_Custom" index="1"]
+material_override = SubResource("ShaderMaterial_es2ea")
+
+[node name="Label3D" parent="Gradients_Custom" index="2"]
+text = "#808080"
+
+[node name="Controls" type="Node" parent="." node_paths=PackedStringArray("max_value_label", "custom_bar")]
+script = ExtResource("4_fust6")
+bars = Array[NodePath]([NodePath("../Gradients_White"), NodePath("../Gradients_Red"), NodePath("../Gradients_Red2"), NodePath("../Gradients_Red3"), NodePath("../Gradients_Red4"), NodePath("../Gradients_Green"), NodePath("../Gradients_Green2"), NodePath("../Gradients_Green3"), NodePath("../Gradients_Green4"), NodePath("../Gradients_Blue"), NodePath("../Gradients_Blue2"), NodePath("../Gradients_Blue3"), NodePath("../Gradients_Blue4"), NodePath("../Gradients_Custom")])
+max_value_label = NodePath("../Label3D4")
+colors = Array[Color]([Color(1, 1, 1, 1), Color(1, 0, 0, 1), Color(1, 0.0392157, 0.0392157, 1), Color(1, 0.501961, 0.0392157, 1), Color(1, 0.0392157, 0.501961, 1), Color(0, 1, 0, 1), Color(0.0392157, 1, 0.0392157, 1), Color(0.501961, 1, 0.0392157, 1), Color(0.0392157, 1, 0.501961, 1), Color(0, 0, 1, 1), Color(0.0392157, 0.0392157, 1, 1), Color(0.501961, 0.0392157, 1, 1), Color(0.0392157, 0.501961, 1, 1)])
+custom_bar = NodePath("../Gradients_Custom")
+
+[node name="StepsControls" type="HBoxContainer" parent="Controls"]
+offset_left = 937.0
+offset_top = 85.0
+offset_right = 1137.0
+offset_bottom = 125.0
+
+[node name="Label" type="Label" parent="Controls/StepsControls"]
+layout_mode = 2
+text = "Max Value"
+
+[node name="Steps" type="HSlider" parent="Controls/StepsControls"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 4
+min_value = 1.0
+max_value = 20.0
+value = 6.0
+
+[node name="HBoxContainer" type="HBoxContainer" parent="Controls"]
+offset_left = 14.0
+offset_top = 604.0
+offset_right = 420.0
+offset_bottom = 644.0
+theme_override_constants/separation = 10
+
+[node name="Exponential" type="CheckButton" parent="Controls/HBoxContainer"]
+layout_mode = 2
+tooltip_text = "Uses a power 2 exponential function. This allows for easier viewing of the darker range of values."
+text = "Exponential Scale"
+
+[node name="Label" type="Label" parent="Controls/HBoxContainer"]
+layout_mode = 2
+text = "Custom Color"
+
+[node name="ColorPickerButton" type="ColorPickerButton" parent="Controls/HBoxContainer"]
+custom_minimum_size = Vector2(100, 0)
+layout_mode = 2
+color = Color(0.501961, 0.501961, 0.501961, 1)
+
+[connection signal="value_changed" from="Controls/StepsControls/Steps" to="Controls" method="_on_steps_value_changed"]
+[connection signal="toggled" from="Controls/HBoxContainer/Exponential" to="Controls" method="_on_exponential_toggled"]
+[connection signal="color_changed" from="Controls/HBoxContainer/ColorPickerButton" to="Controls" method="_on_color_picker_button_color_changed"]
+
+[editable path="Gradients_White"]
+[editable path="Gradients_Red"]
+[editable path="Gradients_Red2"]
+[editable path="Gradients_Red3"]
+[editable path="Gradients_Red4"]
+[editable path="Gradients_Green"]
+[editable path="Gradients_Green2"]
+[editable path="Gradients_Green3"]
+[editable path="Gradients_Green4"]
+[editable path="Gradients_Blue"]
+[editable path="Gradients_Blue2"]
+[editable path="Gradients_Blue3"]
+[editable path="Gradients_Blue4"]
+[editable path="Gradients_Custom"]

+ 21 - 0
3d/tonemap_color_correction/gradients/gradient_bars.gd

@@ -0,0 +1,21 @@
+class_name GradientBars extends Node3D
+
+@export var sdr_bar: GeometryInstance3D
+@export var hdr_bar: GeometryInstance3D
+@export var label: Label3D
+
+func set_num_steps(steps: int) -> void:
+	var shader_mat: ShaderMaterial = hdr_bar.material_override as ShaderMaterial
+	if shader_mat:
+		shader_mat.set_shader_parameter("steps", min(1, steps))
+
+func set_color(color: Color) -> void:
+	var shader_mat: ShaderMaterial = sdr_bar.material_override as ShaderMaterial
+	if shader_mat:
+		shader_mat.set_shader_parameter("my_color", color)
+
+	shader_mat = hdr_bar.material_override as ShaderMaterial
+	if shader_mat:
+		shader_mat.set_shader_parameter("my_color", color)
+
+	label.text = "#" + color.to_html(false)

+ 1 - 0
3d/tonemap_color_correction/gradients/gradient_bars.gd.uid

@@ -0,0 +1 @@
+uid://biih7x6urqpmj

+ 45 - 0
3d/tonemap_color_correction/gradients/gradient_bars.tscn

@@ -0,0 +1,45 @@
+[gd_scene load_steps=6 format=3 uid="uid://bavd54phmfgyh"]
+
+[ext_resource type="Script" uid="uid://biih7x6urqpmj" path="res://gradients/gradient_bars.gd" id="1_idd8e"]
+[ext_resource type="Shader" uid="uid://cg2ft7motxwuc" path="res://gradients/gradient_steps.gdshader" id="2_njjq2"]
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_oxi6c"]
+render_priority = 0
+shader = ExtResource("2_njjq2")
+shader_parameter/my_color = Color(1, 1, 1, 1)
+shader_parameter/steps = 10
+shader_parameter/exponential_view = true
+
+[sub_resource type="QuadMesh" id="QuadMesh_p6ckv"]
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_tnbw4"]
+render_priority = 0
+shader = ExtResource("2_njjq2")
+shader_parameter/my_color = Color(1, 1, 1, 1)
+shader_parameter/steps = 1
+shader_parameter/exponential_view = true
+
+[node name="Gradients" type="Node3D" node_paths=PackedStringArray("sdr_bar", "hdr_bar", "label")]
+script = ExtResource("1_idd8e")
+sdr_bar = NodePath("0-to-1")
+hdr_bar = NodePath("0-to-HDR")
+label = NodePath("Label3D")
+
+[node name="0-to-HDR" type="MeshInstance3D" parent="."]
+transform = Transform3D(0.83, 0, 0, 0, 0.043, 0, 0, 0, 1, 0.458494, 0, 0)
+material_override = SubResource("ShaderMaterial_oxi6c")
+mesh = SubResource("QuadMesh_p6ckv")
+skeleton = NodePath("../..")
+
+[node name="0-to-1" type="MeshInstance3D" parent="."]
+transform = Transform3D(0.83, 0, 0, 0, 0.043, 0, 0, 0, 1, -0.383273, 0, 0)
+material_override = SubResource("ShaderMaterial_tnbw4")
+mesh = SubResource("QuadMesh_p6ckv")
+skeleton = NodePath("../..")
+
+[node name="Label3D" type="Label3D" parent="."]
+transform = Transform3D(0.124, 0, 0, 0, 0.124, 0, 0, 0, 0.124, -0.804691, 0.0298065, 0)
+text = "#000000"
+outline_size = 0
+horizontal_alignment = 2
+vertical_alignment = 0

+ 45 - 0
3d/tonemap_color_correction/gradients/gradient_steps.gdshader

@@ -0,0 +1,45 @@
+shader_type spatial;
+render_mode unshaded;
+
+uniform vec3 my_color : source_color = vec3(1.0, 1.0, 1.0);
+uniform int steps : hint_range(1, 20);
+uniform bool exponential_view = true;
+
+void fragment() {
+	// Draw base color
+	ALBEDO = my_color;
+
+	if (UV.y > 0.25)
+	{
+		// Draw gradient
+		float scale = UV.x * float(steps);
+
+		if (exponential_view)
+		{
+			scale = (scale * scale) / float(steps);
+		}
+
+		ALBEDO *= scale;
+	}
+	else
+	{
+		// Draw step separation bars
+		for (int i = 1; i < steps; i++)
+		{
+			float threshold = 0.002; // Bar size
+			float target = float(i);
+
+			if (exponential_view)
+			{
+				target = sqrt(float(i) * float(steps));
+			}
+
+			target = target / float(steps);
+
+			if (UV.x < target + threshold && UV.x > target - threshold)
+			{
+				ALBEDO = vec3(0); // Bars are colored black
+			}
+		}
+	}
+}

+ 1 - 0
3d/tonemap_color_correction/gradients/gradient_steps.gdshader.uid

@@ -0,0 +1 @@
+uid://cg2ft7motxwuc

+ 46 - 0
3d/tonemap_color_correction/gradients/gradients_controls.gd

@@ -0,0 +1,46 @@
+extends Node
+
+@export var bars: Array[NodePath]
+@export var max_value_label: Label3D
+@export var colors: Array[Color]
+@export var custom_bar: GradientBars
+@export var hues: MeshInstance3D
+
+func _ready():
+	for i in range(colors.size()):
+		var bar_path: NodePath = bars[i]
+		var bar: GradientBars = get_node(bar_path) as GradientBars
+		var col: Color = colors[i]
+		bar.set_color(col)
+
+	_on_steps_value_changed(6)
+	_on_color_picker_button_color_changed(Color(0.5, 0.5, 0.5, 1))
+	_on_exponential_toggled(false)
+
+func _on_steps_value_changed(value):
+	max_value_label.text = "%.1f" % value
+	for bar_path in bars:
+		var bar = get_node(bar_path)
+		var shader_mat = bar.hdr_bar.material_override as ShaderMaterial
+		shader_mat.set_shader_parameter("steps", value)
+	if hues:
+		var shader_mat = hues.material_override as ShaderMaterial
+		shader_mat.set_shader_parameter("steps", value)
+
+
+func _on_color_picker_button_color_changed(color):
+	if custom_bar:
+		custom_bar.set_color(color)
+
+
+func _on_exponential_toggled(button_pressed):
+	for bar_path in bars:
+		var bar = get_node(bar_path)
+		var shader_mat = bar.hdr_bar.material_override as ShaderMaterial
+		shader_mat.set_shader_parameter("exponential_view", button_pressed)
+
+		shader_mat = bar.sdr_bar.material_override as ShaderMaterial
+		shader_mat.set_shader_parameter("exponential_view", button_pressed)
+	if hues:
+		var shader_mat = hues.material_override as ShaderMaterial
+		shader_mat.set_shader_parameter("exponential_view", button_pressed)

+ 1 - 0
3d/tonemap_color_correction/gradients/gradients_controls.gd.uid

@@ -0,0 +1 @@
+uid://bd2eaaib4wnpa

+ 84 - 0
3d/tonemap_color_correction/gradients/hues.gdshader

@@ -0,0 +1,84 @@
+shader_type spatial;
+render_mode unshaded;
+
+uniform int steps : hint_range(1, 20);
+uniform bool exponential_view = true;
+
+void fragment() {
+	float top_bar = 0.01;
+	if (UV.y >= top_bar)
+	{
+		float padding = 0.002;
+		float y = (UV.y - top_bar - padding) / (1.0 - top_bar - padding * 2.0);
+		y = clamp(y, 0.0, 1.0);
+		float segments = 1.0 / 6.0;
+		vec3 col = vec3(0);
+		if (y < segments)
+		{
+			col.r = 1.0;
+			col.g = y / segments;
+			col.b = 0.0;
+		}
+		else if (y < segments * 2.0)
+		{
+			col.r = (y - segments * 2.0) / -segments;
+			col.g = 1.0;
+			col.b = 0.0;
+		}
+		else if (y < segments * 3.0)
+		{
+			col.r = 0.0;
+			col.g = 1.0;
+			col.b = (y - segments * 2.0) / segments;
+		}
+		else if (y < segments * 4.0)
+		{
+			col.r = 0.0;
+			col.g = (y - segments * 4.0) / -segments;
+			col.b = 1.0;
+		}
+		else if (y < segments * 5.0)
+		{
+			col.r = (y - segments * 4.0) / segments;
+			col.g = 0.0;
+			col.b = 1.0;
+		}
+		else
+		{
+			col.r = 1.0;
+			col.g = 0.0;
+			col.b = (y - segments * 6.0) / -segments;
+		}
+
+		float scale = UV.x * float(steps);
+
+		if (exponential_view)
+		{
+			scale = (scale * scale) / float(steps);
+		}
+
+		ALBEDO = col * scale;
+	}
+	else
+	{
+		ALBEDO = vec3(1.0);
+		// Draw step separation bars
+		for (int i = 1; i < steps; i++)
+		{
+			float threshold = 0.002; // Bar size
+			float target = float(i);
+
+			if (exponential_view)
+			{
+				target = sqrt(float(i) * float(steps));
+			}
+
+			target = target / float(steps);
+
+			if (UV.x < target + threshold && UV.x > target - threshold)
+			{
+				ALBEDO = vec3(0); // Bars are colored black
+			}
+		}
+	}
+}

+ 1 - 0
3d/tonemap_color_correction/gradients/hues.gdshader.uid

@@ -0,0 +1 @@
+uid://bj23rrwhjw2qf

+ 91 - 0
3d/tonemap_color_correction/hues.tscn

@@ -0,0 +1,91 @@
+[gd_scene load_steps=7 format=3 uid="uid://c52ta7ygsn7wv"]
+
+[ext_resource type="Script" uid="uid://cljtufy2vjbmv" path="res://test_scene.gd" id="1_oue8n"]
+[ext_resource type="Shader" uid="uid://bj23rrwhjw2qf" path="res://gradients/hues.gdshader" id="2_dw6v8"]
+[ext_resource type="Script" uid="uid://bd2eaaib4wnpa" path="res://gradients/gradients_controls.gd" id="4_jldl5"]
+
+[sub_resource type="Environment" id="Environment_lqw28"]
+background_mode = 1
+background_energy_multiplier = 0.0
+ambient_light_source = 1
+reflected_light_source = 1
+tonemap_white = 6.0
+glow_intensity = 0.09
+glow_blend_mode = 1
+fog_density = 0.025
+adjustment_enabled = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_2qf08"]
+render_priority = 0
+shader = ExtResource("2_dw6v8")
+shader_parameter/steps = 1
+shader_parameter/exponential_view = false
+
+[sub_resource type="QuadMesh" id="QuadMesh_06xbs"]
+
+[node name="Gradients" type="Node3D" node_paths=PackedStringArray("world_environment")]
+script = ExtResource("1_oue8n")
+world_environment = NodePath("WorldEnvironment")
+
+[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
+environment = SubResource("Environment_lqw28")
+
+[node name="Camera3D" type="Camera3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.5)
+projection = 1
+
+[node name="Label3D" type="Label3D" parent="."]
+transform = Transform3D(0.15, 0, 0, 0, 0.15, 0, 0, 0, 0.15, -0.873761, 0.279246, 0)
+text = "0.0"
+horizontal_alignment = 0
+vertical_alignment = 2
+
+[node name="Label3D4" type="Label3D" parent="."]
+transform = Transform3D(0.15, 0, 0, 0, 0.15, 0, 0, 0, 0.15, 0.867011, 0.279246, 0)
+text = "6.0"
+horizontal_alignment = 2
+vertical_alignment = 2
+
+[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
+transform = Transform3D(1.7376, 0, 0, 0, 0.707668, 0, 0, 0, 1, 0, -0.0814103, 0)
+material_override = SubResource("ShaderMaterial_2qf08")
+mesh = SubResource("QuadMesh_06xbs")
+
+[node name="Controls" type="Node" parent="." node_paths=PackedStringArray("max_value_label", "custom_bar", "hues")]
+script = ExtResource("4_jldl5")
+max_value_label = NodePath("../Label3D4")
+custom_bar = NodePath("")
+hues = NodePath("../MeshInstance3D")
+
+[node name="StepsControls" type="HBoxContainer" parent="Controls"]
+offset_left = 937.0
+offset_top = 85.0
+offset_right = 1137.0
+offset_bottom = 125.0
+
+[node name="Label" type="Label" parent="Controls/StepsControls"]
+layout_mode = 2
+text = "Max Value"
+
+[node name="Steps" type="HSlider" parent="Controls/StepsControls"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 4
+min_value = 1.0
+max_value = 20.0
+value = 6.0
+
+[node name="HBoxContainer" type="HBoxContainer" parent="Controls"]
+offset_left = 14.0
+offset_top = 604.0
+offset_right = 420.0
+offset_bottom = 644.0
+theme_override_constants/separation = 10
+
+[node name="Exponential" type="CheckButton" parent="Controls/HBoxContainer"]
+layout_mode = 2
+tooltip_text = "Uses a power 2 exponential function. This allows for easier viewing of the darker range of values."
+text = "Exponential Scale"
+
+[connection signal="value_changed" from="Controls/StepsControls/Steps" to="Controls" method="_on_steps_value_changed"]
+[connection signal="toggled" from="Controls/HBoxContainer/Exponential" to="Controls" method="_on_exponential_toggled"]

+ 1 - 0
3d/tonemap_color_correction/icon.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><path fill="gray" d="M 24,8 A 16,16 0 0 0 8,24 v 80 a 16,16 0 0 0 16,16 h 80 a 16,16 0 0 0 16,-16 V 24 A 16,16 0 0 0 104,8 Z m 0,16 h 80 v 80 H 24 Z m 36,20 h 8 v 8 H 60 Z M 28,28 v 72 h 24 v -8 h 8 v -8 h -8 v -8 h 8 v -8 h -8 v -8 h 8 v -8 h -8 v -8 h 8 v -8 h -8 v -8 z m 32,0 h 8 v 8 h -8 z m 0,48 h 8 v 8 h -8 z m 0,-16 h 8 v 8 h -8 z m 0,32 h 8 v 8 h -8 z m 8,-56 h 8 v 8 h -8 z m 0,16 h 8 v 8 h -8 z m 0,16 h 8 v 8 h -8 z m 0,16 h 8 v 8 h -8 z"/></svg>

+ 37 - 0
3d/tonemap_color_correction/icon.svg.import

@@ -0,0 +1,37 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://drhyssghe5h2u"
+path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://icon.svg"
+dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false

BIN
3d/tonemap_color_correction/neutral_luts/1d/lut_neutral_1d.png


+ 34 - 0
3d/tonemap_color_correction/neutral_luts/1d/lut_neutral_1d.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dwo7k84e3jyhn"
+path="res://.godot/imported/lut_neutral_1d.png-74ab0b1ca495284805ebaec6de158513.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://neutral_luts/1d/lut_neutral_1d.png"
+dest_files=["res://.godot/imported/lut_neutral_1d.png-74ab0b1ca495284805ebaec6de158513.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1

+ 47 - 0
3d/tonemap_color_correction/neutral_luts/3d/create_neutral_3d_luts.gd

@@ -0,0 +1,47 @@
+# This script can be run from the script editor (File > Run or press Ctrl + Shift + X).
+@tool
+extends EditorScript
+
+## Creates a neutral 3D look-up texture (LUT), i.e. where the input color matches the output color exactly.
+## Using a high-resolution neutral LUT texture in Environment's color correction property will not
+## *visibly* appear rendering, even though the LUT is still sampled.
+## Lower resolution neutral LUTs such as 17×17×17 and 33×33×33 will still somewhat impact rendering
+## due to the limitations of bilinear filtering.
+func create_neutral_lut(name: String, size: int, vertical: bool):
+	var image = Image.create_empty(
+			size if vertical else (size * size),
+			(size * size) if vertical else size,
+			false,
+			Image.FORMAT_RGB8
+	)
+
+	for z in size:
+		var x_offset := int(z * size) if not vertical else 0
+		var y_offset := int(z * size) if vertical else 0
+		for x in size:
+			for y in size:
+				# Bias rounding by +0.2 to be more neutral, especially at lower resolutions
+				# (this bias is empirically determined).
+				image.set_pixel(x_offset + x, y_offset + y, Color8(
+						roundi(((x + 0.2) / float(size - 1)) * 255),
+						roundi(((y + 0.2) / float(size - 1)) * 255),
+						roundi(((z + 0.2) / float(size - 1)) * 255)
+				))
+
+	image.save_png("user://" + name + ".png")
+
+
+func _run() -> void:
+	create_neutral_lut("lut_neutral_17x17x17_horizontal", 17, false)
+	create_neutral_lut("lut_neutral_33x33x33_horizontal", 33, false)
+	create_neutral_lut("lut_neutral_51x51x51_horizontal", 51, false)
+	create_neutral_lut("lut_neutral_65x65x65_horizontal", 65, false)
+	create_neutral_lut("lut_neutral_17x17x17_vertical", 17, true)
+	create_neutral_lut("lut_neutral_33x33x33_vertical", 33, true)
+	create_neutral_lut("lut_neutral_51x51x51_vertical", 51, true)
+	create_neutral_lut("lut_neutral_65x65x65_vertical", 65, true)
+
+	# Open destination folder containing the generated LUT images.
+	# After importing the textures in a project, remember to change their import mode to Texture3D
+	# in the Import dock as well as the number of horizontal/vertical slices.
+	OS.shell_open(ProjectSettings.globalize_path("user://"))

+ 1 - 0
3d/tonemap_color_correction/neutral_luts/3d/create_neutral_3d_luts.gd.uid

@@ -0,0 +1 @@
+uid://bc7untshmfr58

BIN
3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_17x17x17_horizontal.png


+ 26 - 0
3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_17x17x17_horizontal.png.import

@@ -0,0 +1,26 @@
+[remap]
+
+importer="3d_texture"
+type="CompressedTexture3D"
+uid="uid://svhxhskvc1ej"
+path="res://.godot/imported/lut_neutral_17x17x17_horizontal.png-c5f3682baea97b44083410e28a2e99b4.ctex3d"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://neutral_luts/3d/lut_neutral_17x17x17_horizontal.png"
+dest_files=["res://.godot/imported/lut_neutral_17x17x17_horizontal.png-c5f3682baea97b44083410e28a2e99b4.ctex3d"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+slices/horizontal=17
+slices/vertical=1

BIN
3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_17x17x17_vertical.png


+ 26 - 0
3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_17x17x17_vertical.png.import

@@ -0,0 +1,26 @@
+[remap]
+
+importer="3d_texture"
+type="CompressedTexture3D"
+uid="uid://bguc5hh7slmlo"
+path="res://.godot/imported/lut_neutral_17x17x17_vertical.png-6b846382386086e1e01f633db62d2c54.ctex3d"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://neutral_luts/3d/lut_neutral_17x17x17_vertical.png"
+dest_files=["res://.godot/imported/lut_neutral_17x17x17_vertical.png-6b846382386086e1e01f633db62d2c54.ctex3d"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+slices/horizontal=1
+slices/vertical=17

BIN
3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_33x33x33_horizontal.png


+ 26 - 0
3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_33x33x33_horizontal.png.import

@@ -0,0 +1,26 @@
+[remap]
+
+importer="3d_texture"
+type="CompressedTexture3D"
+uid="uid://c3p5b2v6oja3y"
+path="res://.godot/imported/lut_neutral_33x33x33_horizontal.png-bae1d3bae7f0d2b478262929608ad846.ctex3d"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://neutral_luts/3d/lut_neutral_33x33x33_horizontal.png"
+dest_files=["res://.godot/imported/lut_neutral_33x33x33_horizontal.png-bae1d3bae7f0d2b478262929608ad846.ctex3d"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+slices/horizontal=33
+slices/vertical=1

BIN
3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_33x33x33_vertical.png


+ 26 - 0
3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_33x33x33_vertical.png.import

@@ -0,0 +1,26 @@
+[remap]
+
+importer="3d_texture"
+type="CompressedTexture3D"
+uid="uid://dvlp8mlgbkj3f"
+path="res://.godot/imported/lut_neutral_33x33x33_vertical.png-69da577e0228b682d262506dd9d34706.ctex3d"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://neutral_luts/3d/lut_neutral_33x33x33_vertical.png"
+dest_files=["res://.godot/imported/lut_neutral_33x33x33_vertical.png-69da577e0228b682d262506dd9d34706.ctex3d"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+slices/horizontal=1
+slices/vertical=33

BIN
3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_51x51x51_horizontal.png


+ 26 - 0
3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_51x51x51_horizontal.png.import

@@ -0,0 +1,26 @@
+[remap]
+
+importer="3d_texture"
+type="CompressedTexture3D"
+uid="uid://cjusris28a85l"
+path="res://.godot/imported/lut_neutral_51x51x51_horizontal.png-8c0264beb369c74c96ec75702926b34d.ctex3d"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://neutral_luts/3d/lut_neutral_51x51x51_horizontal.png"
+dest_files=["res://.godot/imported/lut_neutral_51x51x51_horizontal.png-8c0264beb369c74c96ec75702926b34d.ctex3d"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+slices/horizontal=51
+slices/vertical=1

BIN
3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_51x51x51_vertical.png


+ 26 - 0
3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_51x51x51_vertical.png.import

@@ -0,0 +1,26 @@
+[remap]
+
+importer="3d_texture"
+type="CompressedTexture3D"
+uid="uid://ba1x5yakt4nf5"
+path="res://.godot/imported/lut_neutral_51x51x51_vertical.png-f3efa5a6b157d169d8f4cfd875ab3288.ctex3d"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://neutral_luts/3d/lut_neutral_51x51x51_vertical.png"
+dest_files=["res://.godot/imported/lut_neutral_51x51x51_vertical.png-f3efa5a6b157d169d8f4cfd875ab3288.ctex3d"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+slices/horizontal=1
+slices/vertical=51

BIN
3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_65x65x65_horizontal.png


+ 26 - 0
3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_65x65x65_horizontal.png.import

@@ -0,0 +1,26 @@
+[remap]
+
+importer="3d_texture"
+type="CompressedTexture3D"
+uid="uid://b6v8r3lbgudp"
+path="res://.godot/imported/lut_neutral_65x65x65_horizontal.png-7323f7fab3f1e9e7ca4b9a33b86c3ea4.ctex3d"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://neutral_luts/3d/lut_neutral_65x65x65_horizontal.png"
+dest_files=["res://.godot/imported/lut_neutral_65x65x65_horizontal.png-7323f7fab3f1e9e7ca4b9a33b86c3ea4.ctex3d"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+slices/horizontal=65
+slices/vertical=1

BIN
3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_65x65x65_vertical.png


+ 26 - 0
3d/tonemap_color_correction/neutral_luts/3d/lut_neutral_65x65x65_vertical.png.import

@@ -0,0 +1,26 @@
+[remap]
+
+importer="3d_texture"
+type="CompressedTexture3D"
+uid="uid://be1s8u1ncylqn"
+path="res://.godot/imported/lut_neutral_65x65x65_vertical.png-db5d2b7b9384014bf41fc04438963ab5.ctex3d"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://neutral_luts/3d/lut_neutral_65x65x65_vertical.png"
+dest_files=["res://.godot/imported/lut_neutral_65x65x65_vertical.png-db5d2b7b9384014bf41fc04438963ab5.ctex3d"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+slices/horizontal=1
+slices/vertical=65

+ 101 - 0
3d/tonemap_color_correction/options.gd

@@ -0,0 +1,101 @@
+extends VBoxContainer
+
+@export var scenes: Array[PackedScene]
+
+var current_scene: TestScene = null
+var world_environment: WorldEnvironment = null
+
+func _ready():
+	_on_scene_option_button_item_selected(0)
+
+func _on_scene_option_button_item_selected(index):
+	if current_scene != null:
+		current_scene.queue_free()
+		current_scene = null
+
+	var old_environment: Environment = null
+	if world_environment != null:
+		old_environment = world_environment.environment
+
+	var new_scene: PackedScene = scenes[index]
+	current_scene = new_scene.instantiate() as TestScene
+	if current_scene:
+		add_child(current_scene)
+
+		world_environment = current_scene.world_environment
+		if old_environment != null:
+			world_environment.environment.tonemap_mode = old_environment.tonemap_mode
+			world_environment.environment.tonemap_exposure = old_environment.tonemap_exposure
+			world_environment.environment.tonemap_white = old_environment.tonemap_white
+			world_environment.environment.adjustment_color_correction = old_environment.adjustment_color_correction
+			world_environment.environment.adjustment_saturation = old_environment.adjustment_saturation
+
+
+func _on_tonemap_mode_item_selected(index: int) -> void:
+	world_environment.environment.tonemap_mode = index as Environment.ToneMapper
+	# Hide whitepoint if not relevant (Linear and AgX tonemapping do not use a whitepoint).
+	%Whitepoint.visible = world_environment.environment.tonemap_mode != Environment.TONE_MAPPER_LINEAR and world_environment.environment.tonemap_mode != Environment.TONE_MAPPER_AGX
+
+
+func _on_exposure_value_changed(value: float) -> void:
+	world_environment.environment.tonemap_exposure = value
+	$TonemapMode/Exposure/Value.text = str(value).pad_decimals(1)
+
+
+func _on_whitepoint_value_changed(value: float) -> void:
+	world_environment.environment.tonemap_white = value
+	$TonemapMode/Whitepoint/Value.text = str(value).pad_decimals(1)
+
+
+func _on_color_correction_item_selected(index: int) -> void:
+	# Use alphabetical order in the `example_luts` folder.
+	match index:
+		0:  # None
+			world_environment.environment.adjustment_color_correction = null
+		1:
+			world_environment.environment.adjustment_color_correction = preload("res://example_luts/1d/detect_white_clipping.png")
+		2:
+			world_environment.environment.adjustment_color_correction = preload("res://example_luts/1d/frozen.png")
+		3:
+			world_environment.environment.adjustment_color_correction = preload("res://example_luts/1d/heat.png")
+		4:
+			world_environment.environment.adjustment_color_correction = preload("res://example_luts/1d/incandescent.png")
+		5:
+			world_environment.environment.adjustment_color_correction = preload("res://example_luts/1d/posterized.png")
+		6:
+			world_environment.environment.adjustment_color_correction = preload("res://example_luts/1d/posterized_outline.png")
+		7:
+			world_environment.environment.adjustment_color_correction = preload("res://example_luts/1d/rainbow.png")
+		8:
+			world_environment.environment.adjustment_color_correction = preload("res://example_luts/1d/toxic.png")
+		9:
+			world_environment.environment.adjustment_color_correction = preload("res://example_luts/3d/brighten_shadows.png")
+		10:
+			world_environment.environment.adjustment_color_correction = preload("res://example_luts/3d/burned_blue.png")
+		11:
+			world_environment.environment.adjustment_color_correction = preload("res://example_luts/3d/cold_color.png")
+		12:
+			world_environment.environment.adjustment_color_correction = preload("res://example_luts/3d/detect_white_clipping.png")
+		13:
+			world_environment.environment.adjustment_color_correction = preload("res://example_luts/3d/dithered.png")
+		14:
+			world_environment.environment.adjustment_color_correction = preload("res://example_luts/3d/hue_shift.png")
+		15:
+			world_environment.environment.adjustment_color_correction = preload("res://example_luts/3d/posterized.png")
+		16:
+			world_environment.environment.adjustment_color_correction = preload("res://example_luts/3d/sepia.png")
+		17:
+			world_environment.environment.adjustment_color_correction = preload("res://example_luts/3d/stressed.png")
+		18:
+			world_environment.environment.adjustment_color_correction = preload("res://example_luts/3d/warm_color.png")
+		19:
+			world_environment.environment.adjustment_color_correction = preload("res://example_luts/3d/yellowen.png")
+
+
+func _on_saturation_value_changed(value: float) -> void:
+	world_environment.environment.adjustment_saturation = value
+	$ColorCorrection/Saturation/Value.text = str(value).pad_decimals(1)
+
+
+func _on_debanding_toggled(button_pressed: bool) -> void:
+	get_viewport().use_debanding = button_pressed

+ 1 - 0
3d/tonemap_color_correction/options.gd.uid

@@ -0,0 +1 @@
+uid://dv01ma5mjl4l5

+ 32 - 0
3d/tonemap_color_correction/project.godot

@@ -0,0 +1,32 @@
+; Engine configuration file.
+; It's best edited using the editor UI and not directly,
+; since the parameters that go here are not all obvious.
+;
+; Format:
+;   [section] ; section goes between []
+;   param=value ; assign values to parameters
+
+config_version=5
+
+[application]
+
+config/name="Tonemapping and Color Correction"
+config/description="This showcases various tonemapping operators and their interaction
+with several color correction textures (1D and 3D).
+
+A script generating neutral 3D LUT textures is also included."
+run/main_scene="res://test.tscn"
+config/features=PackedStringArray("4.4")
+config/icon="uid://drhyssghe5h2u"
+
+[display]
+
+window/stretch/mode="canvas_items"
+window/stretch/aspect="expand"
+
+[rendering]
+
+lights_and_shadows/directional_shadow/soft_shadow_filter_quality=3
+textures/default_filters/anisotropic_filtering_level=4
+anti_aliasing/quality/msaa_3d=2
+anti_aliasing/quality/use_debanding=true

+ 0 - 0
3d/tonemap_color_correction/screenshots/.gdignore


BIN
3d/tonemap_color_correction/screenshots/tonemap_color_correction.webp


+ 203 - 0
3d/tonemap_color_correction/test.tscn

@@ -0,0 +1,203 @@
+[gd_scene load_steps=5 format=3 uid="uid://bulw0pypka0bv"]
+
+[ext_resource type="Script" uid="uid://dv01ma5mjl4l5" path="res://options.gd" id="1_20y27"]
+[ext_resource type="PackedScene" uid="uid://bfbqknlrqre0c" path="res://3d_primitives.tscn" id="2_leeh8"]
+[ext_resource type="PackedScene" uid="uid://drmdg7kgtgadn" path="res://gradients.tscn" id="3_py7p5"]
+[ext_resource type="PackedScene" uid="uid://c52ta7ygsn7wv" path="res://hues.tscn" id="4_pbomq"]
+
+[node name="Node3D" type="Node3D"]
+
+[node name="Options" type="VBoxContainer" parent="."]
+offset_left = 16.0
+offset_top = 16.0
+offset_right = 576.0
+offset_bottom = 82.0
+script = ExtResource("1_20y27")
+scenes = Array[PackedScene]([ExtResource("2_leeh8"), ExtResource("3_py7p5"), ExtResource("4_pbomq")])
+
+[node name="TonemapMode" type="HBoxContainer" parent="Options"]
+layout_mode = 2
+theme_override_constants/separation = 15
+
+[node name="SceneLabel" type="Label" parent="Options/TonemapMode"]
+layout_mode = 2
+text = "Scene"
+
+[node name="SceneOptionButton" type="OptionButton" parent="Options/TonemapMode"]
+layout_mode = 2
+selected = 0
+item_count = 3
+popup/item_0/text = "3D Primitives"
+popup/item_0/id = 0
+popup/item_1/text = "Gradients"
+popup/item_1/id = 1
+popup/item_2/text = "Hues"
+popup/item_2/id = 2
+
+[node name="Label" type="Label" parent="Options/TonemapMode"]
+layout_mode = 2
+text = "Tonemap Mode"
+
+[node name="OptionButton" type="OptionButton" parent="Options/TonemapMode"]
+layout_mode = 2
+selected = 2
+item_count = 5
+popup/item_0/text = "Linear"
+popup/item_0/id = 0
+popup/item_1/text = "Reinhard"
+popup/item_1/id = 1
+popup/item_2/text = "Filmic"
+popup/item_2/id = 2
+popup/item_3/text = "ACES"
+popup/item_3/id = 3
+popup/item_4/text = "AgX"
+popup/item_4/id = 4
+
+[node name="Exposure" type="HBoxContainer" parent="Options/TonemapMode"]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(250, 0)
+layout_mode = 2
+theme_override_constants/separation = 10
+
+[node name="Label" type="Label" parent="Options/TonemapMode/Exposure"]
+layout_mode = 2
+size_flags_horizontal = 3
+text = "Exposure"
+horizontal_alignment = 2
+
+[node name="HSlider" type="HSlider" parent="Options/TonemapMode/Exposure"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 4
+min_value = 0.1
+max_value = 5.0
+step = 0.1
+value = 1.0
+
+[node name="Value" type="Label" parent="Options/TonemapMode/Exposure"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_stretch_ratio = 0.4
+text = "1.0"
+
+[node name="Whitepoint" type="HBoxContainer" parent="Options/TonemapMode"]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(250, 0)
+layout_mode = 2
+theme_override_constants/separation = 10
+
+[node name="Label" type="Label" parent="Options/TonemapMode/Whitepoint"]
+layout_mode = 2
+size_flags_horizontal = 3
+text = "Whitepoint"
+horizontal_alignment = 2
+
+[node name="HSlider" type="HSlider" parent="Options/TonemapMode/Whitepoint"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 4
+min_value = 0.1
+max_value = 16.0
+step = 0.1
+value = 1.0
+
+[node name="Value" type="Label" parent="Options/TonemapMode/Whitepoint"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_stretch_ratio = 0.4
+text = "6.0"
+
+[node name="ColorCorrection" type="HBoxContainer" parent="Options"]
+layout_mode = 2
+theme_override_constants/separation = 15
+
+[node name="Label" type="Label" parent="Options/ColorCorrection"]
+layout_mode = 2
+text = "Color Correction"
+
+[node name="OptionButton" type="OptionButton" parent="Options/ColorCorrection"]
+layout_mode = 2
+selected = 0
+item_count = 20
+popup/item_0/text = "None"
+popup/item_0/id = 0
+popup/item_1/text = "Detect White Clipping (1D)"
+popup/item_1/id = 1
+popup/item_2/text = "Frozen (1D)"
+popup/item_2/id = 2
+popup/item_3/text = "Heat (1D)"
+popup/item_3/id = 3
+popup/item_4/text = "Incandescent (1D)"
+popup/item_4/id = 4
+popup/item_5/text = "Posterized (1D)"
+popup/item_5/id = 5
+popup/item_6/text = "Posterized Outline (1D)"
+popup/item_6/id = 6
+popup/item_7/text = "Rainbow (1D)"
+popup/item_7/id = 7
+popup/item_8/text = "Toxic (1D)"
+popup/item_8/id = 8
+popup/item_9/text = "Brighten Shadows (3D)"
+popup/item_9/id = 9
+popup/item_10/text = "Burned Blue (3D)"
+popup/item_10/id = 10
+popup/item_11/text = "Cold Color (3D)"
+popup/item_11/id = 11
+popup/item_12/text = "Detect White Clipping (3D)"
+popup/item_12/id = 12
+popup/item_13/text = "Dithered (3D)"
+popup/item_13/id = 13
+popup/item_14/text = "Hue Shift (3D)"
+popup/item_14/id = 14
+popup/item_15/text = "Posterized (3D)"
+popup/item_15/id = 15
+popup/item_16/text = "Sepia (3D)"
+popup/item_16/id = 16
+popup/item_17/text = "Stressed (3D)"
+popup/item_17/id = 17
+popup/item_18/text = "Warm Color (3D)"
+popup/item_18/id = 18
+popup/item_19/text = "Yellowed (3D)"
+popup/item_19/id = 19
+
+[node name="Saturation" type="HBoxContainer" parent="Options/ColorCorrection"]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(250, 0)
+layout_mode = 2
+theme_override_constants/separation = 10
+
+[node name="Label" type="Label" parent="Options/ColorCorrection/Saturation"]
+layout_mode = 2
+size_flags_horizontal = 3
+text = "Saturation"
+horizontal_alignment = 2
+
+[node name="HSlider" type="HSlider" parent="Options/ColorCorrection/Saturation"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 4
+min_value = -2.0
+max_value = 2.0
+step = 0.1
+value = 1.0
+tick_count = 3
+
+[node name="Value" type="Label" parent="Options/ColorCorrection/Saturation"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_stretch_ratio = 0.4
+text = "1.0"
+
+[node name="Debanding" type="CheckButton" parent="Options"]
+layout_mode = 2
+size_flags_horizontal = 0
+button_pressed = true
+text = "Debanding"
+
+[connection signal="item_selected" from="Options/TonemapMode/SceneOptionButton" to="Options" method="_on_scene_option_button_item_selected"]
+[connection signal="item_selected" from="Options/TonemapMode/OptionButton" to="Options" method="_on_tonemap_mode_item_selected"]
+[connection signal="value_changed" from="Options/TonemapMode/Exposure/HSlider" to="Options" method="_on_exposure_value_changed"]
+[connection signal="value_changed" from="Options/TonemapMode/Whitepoint/HSlider" to="Options" method="_on_whitepoint_value_changed"]
+[connection signal="item_selected" from="Options/ColorCorrection/OptionButton" to="Options" method="_on_color_correction_item_selected"]
+[connection signal="value_changed" from="Options/ColorCorrection/Saturation/HSlider" to="Options" method="_on_saturation_value_changed"]
+[connection signal="toggled" from="Options/Debanding" to="Options" method="_on_debanding_toggled"]

+ 3 - 0
3d/tonemap_color_correction/test_scene.gd

@@ -0,0 +1,3 @@
+class_name TestScene extends Node3D
+
+@export var world_environment: WorldEnvironment

+ 1 - 0
3d/tonemap_color_correction/test_scene.gd.uid

@@ -0,0 +1 @@
+uid://cljtufy2vjbmv