├── Editor.meta
├── Editor
├── SkyboxBlenderEditor.cs
└── SkyboxBlenderEditor.cs.meta
├── LICENSE
├── LICENSE.meta
├── README.md
├── README.md.meta
├── Scripts.meta
├── Scripts
├── SkyboxBlender.cs
└── SkyboxBlender.cs.meta
├── Shaders.meta
└── Shaders
├── SkyboxBlender.shader
└── SkyboxBlender.shader.meta
/Editor.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 13402b2e357223446bc2d35890e354b4
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Editor/SkyboxBlenderEditor.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 | using UnityEditor;
5 |
6 | [CustomEditor(typeof(SkyboxBlender))]
7 | public class SkyboxBlenderEditor : Editor
8 | {
9 | SerializedProperty skyBox1;
10 | SerializedProperty skyBox2;
11 |
12 | SerializedProperty blendedSkybox;
13 | SerializedProperty exposure;
14 | SerializedProperty rotation;
15 | SerializedProperty tint;
16 | SerializedProperty invertColors;
17 | SerializedProperty blendMode;
18 | SerializedProperty blend;
19 |
20 | SerializedProperty bindOnStart;
21 | SerializedProperty updateLightingOnStart;
22 | SerializedProperty updateLightingEveryFrame;
23 | SerializedProperty updateReflectionsOnStart;
24 | SerializedProperty updateReflectionsEveryFrame;
25 |
26 | SerializedProperty reflectionResolution;
27 |
28 | private void OnEnable()
29 | {
30 | skyBox1 = serializedObject.FindProperty("skyBox1");
31 | skyBox2 = serializedObject.FindProperty("skyBox2");
32 |
33 | blendedSkybox = serializedObject.FindProperty("blendedSkybox");
34 | exposure = serializedObject.FindProperty("exposure");
35 | rotation = serializedObject.FindProperty("rotation");
36 | tint = serializedObject.FindProperty("tint");
37 | invertColors = serializedObject.FindProperty("invertColors");
38 | blendMode = serializedObject.FindProperty("blendMode");
39 | blend = serializedObject.FindProperty("blend");
40 |
41 | bindOnStart = serializedObject.FindProperty("bindOnStart");
42 | updateLightingOnStart = serializedObject.FindProperty("updateLightingOnStart");
43 | updateLightingEveryFrame = serializedObject.FindProperty("updateLightingEveryFrame");
44 | updateReflectionsOnStart = serializedObject.FindProperty("updateReflectionsOnStart");
45 | updateReflectionsEveryFrame = serializedObject.FindProperty("updateReflectionsEveryFrame");
46 |
47 | reflectionResolution = serializedObject.FindProperty("reflectionResolution"); ;
48 | }
49 |
50 | public override void OnInspectorGUI()
51 | {
52 | SkyboxBlender skyboxBlender = (SkyboxBlender)target;
53 |
54 | serializedObject.Update();
55 |
56 | //Input skyboxes
57 | EditorGUILayout.BeginVertical("HelpBox");
58 | EditorGUILayout.LabelField("Input Skyboxes", EditorStyles.boldLabel);
59 | EditorGUI.indentLevel++;
60 |
61 | EditorGUILayout.PropertyField(skyBox1);
62 | EditorGUILayout.PropertyField(skyBox2);
63 |
64 | EditorGUILayout.Space();
65 | EditorGUILayout.PropertyField(bindOnStart);
66 | if (GUILayout.Button("Bind Textures")) { skyboxBlender.BindTextures(); }
67 |
68 | EditorGUILayout.Space();
69 | EditorGUI.indentLevel--;
70 | EditorGUILayout.EndVertical();
71 |
72 | //Blended skyboxes
73 | EditorGUILayout.BeginVertical("HelpBox");
74 | EditorGUILayout.LabelField("Blended Skybox", EditorStyles.boldLabel);
75 | EditorGUI.indentLevel++;
76 |
77 | EditorGUILayout.PropertyField(blendedSkybox);
78 | EditorGUILayout.PropertyField(exposure);
79 | EditorGUILayout.PropertyField(rotation);
80 | EditorGUILayout.PropertyField(tint);
81 | EditorGUILayout.PropertyField(invertColors);
82 | EditorGUILayout.PropertyField(blendMode);
83 | EditorGUILayout.PropertyField(blend);
84 |
85 | EditorGUILayout.Space();
86 | EditorGUI.indentLevel--;
87 | EditorGUILayout.EndVertical();
88 |
89 | //Environment lighting
90 | EditorGUILayout.BeginVertical("HelpBox");
91 | EditorGUILayout.LabelField("Environment Lighting", EditorStyles.boldLabel);
92 | EditorGUI.indentLevel++;
93 |
94 | EditorGUILayout.PropertyField(updateLightingOnStart);
95 | EditorGUILayout.PropertyField(updateLightingEveryFrame);
96 | if (GUILayout.Button("Update Lighting")) { skyboxBlender.UpdateLighting(); }
97 |
98 | EditorGUILayout.Space();
99 | EditorGUI.indentLevel--;
100 | EditorGUILayout.EndVertical();
101 |
102 | //Environment reflections
103 | EditorGUILayout.BeginVertical("HelpBox");
104 | EditorGUILayout.LabelField("Environment Reflections", EditorStyles.boldLabel);
105 | EditorGUI.indentLevel++;
106 |
107 | EditorGUILayout.PropertyField(reflectionResolution);
108 | if (GUILayout.Button("Update Probe")) { skyboxBlender.UpdateReflectionProbe(); }
109 |
110 | EditorGUILayout.Space();
111 | EditorGUILayout.PropertyField(updateReflectionsOnStart);
112 | EditorGUILayout.PropertyField(updateReflectionsEveryFrame);
113 | if (GUILayout.Button("Update Reflections")) { skyboxBlender.UpdateReflections(); }
114 |
115 | EditorGUILayout.Space();
116 | EditorGUI.indentLevel--;
117 | EditorGUILayout.EndVertical();
118 |
119 |
120 | serializedObject.ApplyModifiedProperties();
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/Editor/SkyboxBlenderEditor.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b0e97d41b6ffc264d9fb2a6f284ce145
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Barbelot
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LICENSE.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b63ae4654ec84874388a8b7600bd9681
3 | DefaultImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Unity-Skybox-Blender
2 | A tool to blend skyboxes in Unity with realtime environment lighting and reflections updates.
3 |
4 | ## How to use
5 |
6 | 1. Add the SkyboxBlender.cs script to an object in your scene.
7 | 2. Assign the two input skybox materials to blend to the SkyboxBlender.
8 | 2. Create a new material with the SkyboxBlender/BlendedSkybox shader.
9 | 3. Assign the newly created material to the SkyboxBlender and to your scene skybox.
10 | 5. Blend !
11 |
12 | ## Useful information
13 |
14 | - To update the reflection probe resolution after changing it, use the Update Probe button.
15 | - The script executes in edit mode to visualize the blend result in the editor, you can disable it by removing the [ExecuteInEditMode] tag in the SkyboxBlender script.
16 | - The input skyboxes materials are expected to use the Unity built-in Skybox/6-sided shader.
17 | - The SkyboxBlender script set the Environment Reflections Source to Custom. If you remove the script and your scene is all black, set the Environment Reflections Source back to Skybox in the Lighting tab, as described [here](https://github.com/Barbelot/Unity-Skybox-Blender/issues/1).
18 |
19 | ## Known Issues
20 |
21 | - The reflection update does not always work properly when not updating every frames.
22 |
--------------------------------------------------------------------------------
/README.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0aa993b781da13940aeceeba7ca6acd9
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Scripts.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f472385305e1ddf408dc6e6bb41c406b
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Scripts/SkyboxBlender.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 | using UnityEngine.Rendering;
5 |
6 | [ExecuteInEditMode]
7 | public class SkyboxBlender : MonoBehaviour {
8 |
9 | [SerializeField] public enum BlendMode { Linear, Smoothstep, Maximum, Add, Substract, Multiply }
10 | [SerializeField] public enum ProbeResolution { _16, _32, _64, _128, _256, _512, _1024, _2048 }
11 |
12 | //[Header("Input Skyboxes")]
13 | [SerializeField] public Material skyBox1;
14 | [SerializeField] public Material skyBox2;
15 |
16 | //[Header("Blended Skybox")]
17 | [SerializeField] public Material blendedSkybox;
18 | [SerializeField] [Range(0, 8)] public float exposure = 1;
19 | [SerializeField] [Range(0, 360)] public float rotation = 0;
20 | [SerializeField] public Color tint = Color.white;
21 | [SerializeField] [Range(0, 1)] public float invertColors = 0;
22 | [SerializeField] public BlendMode blendMode = BlendMode.Linear;
23 | [SerializeField] [Range(0, 1)] public float blend = 0;
24 |
25 | [SerializeField] public bool bindOnStart = true;
26 | [SerializeField] public bool updateLightingOnStart = true;
27 | [SerializeField] public bool updateLightingEveryFrame = true;
28 | [SerializeField] public bool updateReflectionsOnStart = true;
29 | [SerializeField] public bool updateReflectionsEveryFrame = true;
30 |
31 | [SerializeField] public ProbeResolution reflectionResolution = ProbeResolution._128;
32 |
33 | private ReflectionProbe probeComponent = null;
34 | private GameObject probeGameObject = null;
35 | private Cubemap blendedCubemap = null;
36 | private int renderId = -1;
37 |
38 | #region MonoBehaviour Functions
39 |
40 | // Use this for initialization
41 | void Start () {
42 |
43 | if (bindOnStart)
44 | BindTextures();
45 |
46 | //Update the material parameters
47 | UpdateBlendedMaterialParameters();
48 |
49 | if (updateLightingOnStart)
50 | UpdateLighting();
51 |
52 | if (updateReflectionsOnStart)
53 | UpdateReflections();
54 | }
55 |
56 | // Update is called once per frame
57 | void Update () {
58 |
59 | //Update material parameters
60 | UpdateBlendedMaterialParameters();
61 |
62 | //Update lighting
63 | if (updateLightingEveryFrame)
64 | UpdateLighting();
65 |
66 | //Update reflections
67 | if (updateReflectionsEveryFrame)
68 | UpdateReflections();
69 | }
70 |
71 | /*
72 | private void OnValidate()
73 | {
74 | if (!updateInEditMode)
75 | return;
76 |
77 | Update();
78 | }
79 | */
80 |
81 | #endregion
82 |
83 | ///
84 | /// Get the probe resolution value
85 | ///
86 | int GetProbeResolution(ProbeResolution probeResolution)
87 | {
88 | switch (probeResolution)
89 | {
90 | case ProbeResolution._16:
91 | return 16;
92 | case ProbeResolution._32:
93 | return 32;
94 | case ProbeResolution._64:
95 | return 64;
96 | case ProbeResolution._128:
97 | return 128;
98 | case ProbeResolution._256:
99 | return 256;
100 | case ProbeResolution._512:
101 | return 512;
102 | case ProbeResolution._1024:
103 | return 1024;
104 | case ProbeResolution._2048:
105 | return 2048;
106 | default:
107 | return 128;
108 | }
109 | }
110 |
111 | ///
112 | /// Create a reflection probe gameobject and setup the cubemap for environment reflections
113 | ///
114 | void CreateReflectionProbe()
115 | {
116 | //Search for the reflection probe object
117 | probeGameObject = GameObject.Find("Skybox Blender Reflection Probe");
118 |
119 | if (!probeGameObject)
120 | {
121 | //Create the gameobject if its not here
122 | probeGameObject = new GameObject("Skybox Blender Reflection Probe");
123 | probeGameObject.transform.parent = gameObject.transform;
124 | // Use a location such that the new Reflection Probe will not interfere with other Reflection Probes in the scene.
125 | probeGameObject.transform.position = new Vector3(0, -1000, 0);
126 | }
127 |
128 | probeComponent = probeGameObject.GetComponent();
129 |
130 | if (probeComponent)
131 | {
132 | DestroyImmediate(probeComponent);
133 | }
134 |
135 | // Create a Reflection Probe that only contains the Skybox. The Update function controls the Reflection Probe refresh.
136 | probeComponent = probeGameObject.AddComponent() as ReflectionProbe;
137 |
138 | }
139 |
140 | ///
141 | /// Update the reflection probe and cubemap
142 | ///
143 | public void UpdateReflectionProbe()
144 | {
145 | //if (!probeGameObject || !probeComponent)
146 | CreateReflectionProbe();
147 |
148 | probeComponent.resolution = GetProbeResolution(reflectionResolution);
149 | probeComponent.size = new Vector3(1, 1, 1);
150 | probeComponent.cullingMask = 0;
151 | probeComponent.clearFlags = ReflectionProbeClearFlags.Skybox;
152 | probeComponent.mode = ReflectionProbeMode.Realtime;
153 | probeComponent.refreshMode = ReflectionProbeRefreshMode.ViaScripting;
154 | probeComponent.timeSlicingMode = ReflectionProbeTimeSlicingMode.NoTimeSlicing;
155 |
156 | // A cubemap is used as a default specular reflection.
157 | blendedCubemap = new Cubemap(probeComponent.resolution, probeComponent.hdr ? TextureFormat.RGBAHalf : TextureFormat.RGBA32, true);
158 |
159 | //Set the render reflection mode to Custom
160 | RenderSettings.defaultReflectionMode = DefaultReflectionMode.Custom;
161 | RenderSettings.customReflection = blendedCubemap;
162 | }
163 |
164 | ///
165 | /// Update the scene environment lighting
166 | ///
167 | public void UpdateLighting()
168 | {
169 | DynamicGI.UpdateEnvironment();
170 | }
171 |
172 | ///
173 | /// Update the scene environment reflections
174 | ///
175 | public void UpdateReflections()
176 | {
177 | if (!probeGameObject || !probeComponent)
178 | UpdateReflectionProbe();
179 |
180 | // The Update function refreshes the Reflection Probe and copies the result to the default specular reflection Cubemap.
181 |
182 | // The texture associated with the real-time Reflection Probe is a render target and RenderSettings.customReflection is a Cubemap. We have to check the support if copying from render targets to Textures is supported.
183 | if ((SystemInfo.copyTextureSupport & CopyTextureSupport.RTToTexture) != 0)
184 | {
185 | // Wait until previous RenderProbe is finished before we refresh the Reflection Probe again.
186 | // renderId is a token used to figure out when the refresh of a Reflection Probe is finished. The refresh of a Reflection Probe can take mutiple frames when time-slicing is used.
187 | if (renderId == -1 || probeComponent.IsFinishedRendering(renderId))
188 | {
189 | if (probeComponent.IsFinishedRendering(renderId))
190 | {
191 | //Debug.Log("probeComponent.texture.width = " + probeComponent.texture.width + " blendedCubemap.width = "+ blendedCubemap.width);
192 | //Debug.Log("probeComponent.texture.height = " + probeComponent.texture.height + " blendedCubemap.height = " + blendedCubemap.height);
193 | //Debug.Log("probeComponent.resolution = " + probeComponent.resolution);
194 | // After the previous RenderProbe is finished, we copy the probe's texture to the cubemap and set it as a custom reflection in RenderSettings.
195 | if (probeComponent.texture.width == blendedCubemap.width && probeComponent.texture.height == blendedCubemap.height)
196 | {
197 | Graphics.CopyTexture(probeComponent.texture, blendedCubemap as Texture);
198 | //Debug.Log("Copying");
199 | }
200 |
201 | RenderSettings.customReflection = blendedCubemap;
202 | }
203 |
204 | renderId = probeComponent.RenderProbe();
205 | }
206 | }
207 | }
208 |
209 | ///
210 | /// Get the BlendMode index from the enumeration
211 | ///
212 | int GetBlendModeIndex(BlendMode blendMode)
213 | {
214 | switch (blendMode)
215 | {
216 | case BlendMode.Linear:
217 | return 0;
218 | case BlendMode.Smoothstep:
219 | return 5;
220 | case BlendMode.Maximum:
221 | return 1;
222 | case BlendMode.Add:
223 | return 2;
224 | case BlendMode.Substract:
225 | return 3;
226 | case BlendMode.Multiply:
227 | return 4;
228 | default:
229 | return 0;
230 | }
231 | }
232 |
233 | ///
234 | /// Bind the input skyboxes textures to the blended skybox
235 | ///
236 | public void BindTextures()
237 | {
238 | blendedSkybox.SetTexture("_FrontTex_1", skyBox1.GetTexture("_FrontTex"));
239 | blendedSkybox.SetTexture("_BackTex_1", skyBox1.GetTexture("_BackTex"));
240 | blendedSkybox.SetTexture("_LeftTex_1", skyBox1.GetTexture("_LeftTex"));
241 | blendedSkybox.SetTexture("_RightTex_1", skyBox1.GetTexture("_RightTex"));
242 | blendedSkybox.SetTexture("_UpTex_1", skyBox1.GetTexture("_UpTex"));
243 | blendedSkybox.SetTexture("_DownTex_1", skyBox1.GetTexture("_DownTex"));
244 |
245 | blendedSkybox.SetTexture("_FrontTex_2", skyBox2.GetTexture("_FrontTex"));
246 | blendedSkybox.SetTexture("_BackTex_2", skyBox2.GetTexture("_BackTex"));
247 | blendedSkybox.SetTexture("_LeftTex_2", skyBox2.GetTexture("_LeftTex"));
248 | blendedSkybox.SetTexture("_RightTex_2", skyBox2.GetTexture("_RightTex"));
249 | blendedSkybox.SetTexture("_UpTex_2", skyBox2.GetTexture("_UpTex"));
250 | blendedSkybox.SetTexture("_DownTex_2", skyBox2.GetTexture("_DownTex"));
251 | }
252 |
253 | ///
254 | /// Update the material parameters
255 | ///
256 | void UpdateBlendedMaterialParameters()
257 | {
258 | blendedSkybox.SetColor("_Tint", tint);
259 | blendedSkybox.SetFloat("_Exposure", exposure);
260 | blendedSkybox.SetFloat("_Rotation", rotation);
261 | blendedSkybox.SetFloat("_Blend", blend);
262 | blendedSkybox.SetInt("_BlendMode", GetBlendModeIndex(blendMode));
263 | blendedSkybox.SetFloat("_InvertColors", invertColors);
264 |
265 | }
266 |
267 | }
268 |
--------------------------------------------------------------------------------
/Scripts/SkyboxBlender.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2188c1e1a74fe3144880e8ca78fa7825
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Shaders.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d21e85467e6c73044befe96cb8a46690
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Shaders/SkyboxBlender.shader:
--------------------------------------------------------------------------------
1 | // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
2 |
3 | Shader "SkyboxBlender/BlendedSkybox" {
4 | Properties{
5 | _Tint("Tint Color", Color) = (.5, .5, .5, .5)
6 | [Gamma] _Exposure("Exposure", Range(0, 8)) = 1.0
7 | _Rotation("Rotation", Range(0, 360)) = 0
8 | _Blend("Blend", Range(0.0, 1.0)) = 0.0
9 | _BlendMode("Blend Mode", int) = 0
10 | _InvertColors("Invert Colors", Range(0,1)) = 0
11 |
12 | [NoScaleOffset] _FrontTex_1("Front_1 [+Z] (HDR)", 2D) = "grey" {}
13 | [NoScaleOffset] _BackTex_1("Back_1 [-Z] (HDR)", 2D) = "grey" {}
14 | [NoScaleOffset] _LeftTex_1("Left_1 [+X] (HDR)", 2D) = "grey" {}
15 | [NoScaleOffset] _RightTex_1("Right_1 [-X] (HDR)", 2D) = "grey" {}
16 | [NoScaleOffset] _UpTex_1("Up_1 [+Y] (HDR)", 2D) = "grey" {}
17 | [NoScaleOffset] _DownTex_1("Down_1 [-Y] (HDR)", 2D) = "grey" {}
18 |
19 | [NoScaleOffset] _FrontTex_2("Front_2 [+Z] (HDR)", 2D) = "grey" {}
20 | [NoScaleOffset] _BackTex_2("Back_2 [-Z] (HDR)", 2D) = "grey" {}
21 | [NoScaleOffset] _LeftTex_2("Left_2 [+X] (HDR)", 2D) = "grey" {}
22 | [NoScaleOffset] _RightTex_2("Right_2 [-X] (HDR)", 2D) = "grey" {}
23 | [NoScaleOffset] _UpTex_2("Up_2 [+Y] (HDR)", 2D) = "grey" {}
24 | [NoScaleOffset] _DownTex_2("Down_2 [-Y] (HDR)", 2D) = "grey" {}
25 | }
26 |
27 | SubShader{
28 | Tags{ "Queue" = "Background" "RenderType" = "Background" "PreviewType" = "Skybox" }
29 | Cull Off ZWrite Off
30 |
31 | CGINCLUDE
32 | #include "UnityCG.cginc"
33 |
34 | half4 _Tint;
35 | half _Exposure;
36 | float _Rotation;
37 | float _Blend;
38 | int _BlendMode;
39 | float _InvertColors;
40 |
41 | float4 RotateAroundYInDegrees(float4 vertex, float degrees)
42 | {
43 | float alpha = degrees * UNITY_PI / 180.0;
44 | float sina, cosa;
45 | sincos(alpha, sina, cosa);
46 | float2x2 m = float2x2(cosa, -sina, sina, cosa);
47 | return float4(mul(m, vertex.xz), vertex.yw).xzyw;
48 | }
49 |
50 | struct appdata_t {
51 | float4 vertex : POSITION;
52 | float2 texcoord : TEXCOORD0;
53 | };
54 |
55 | struct v2f {
56 | float4 vertex : SV_POSITION;
57 | float2 texcoord : TEXCOORD0;
58 | };
59 |
60 | v2f vert(appdata_t v)
61 | {
62 | v2f o;
63 | o.vertex = UnityObjectToClipPos(RotateAroundYInDegrees(v.vertex, _Rotation));
64 | o.texcoord = v.texcoord;
65 | return o;
66 | }
67 |
68 | half4 skybox_frag(v2f i, sampler2D smp1, half4 smpDecode1, sampler2D smp2, half4 smpDecode2)
69 | {
70 | half4 tex1 = tex2D(smp1, i.texcoord);
71 | half4 tex2 = tex2D(smp2, i.texcoord);
72 |
73 | half3 c1 = DecodeHDR(tex1, smpDecode1);
74 | half3 c2 = DecodeHDR(tex2, smpDecode2);
75 |
76 | half3 c = half3(0, 0, 0);
77 |
78 | if (_BlendMode == 0) {
79 | //Linear blend
80 | c = lerp(c1, c2, _Blend);
81 | } else if (_BlendMode == 1) {
82 | //Maximum
83 | c = max(c1 * (1 - _Blend), c2 * _Blend);
84 | } else if (_BlendMode == 2) {
85 | //Add
86 | c = c1 + c2 * _Blend;
87 | } else if (_BlendMode == 3) {
88 | //Substract
89 | c = max(0, c1 - c2 * _Blend);
90 | } else if (_BlendMode == 4) {
91 | //Multiply
92 | c = c1 * lerp(1, c2, _Blend);
93 | }
94 | else if (_BlendMode == 5) {
95 | //Smoothstep
96 | c = lerp(c1, c2, smoothstep(0, 1, _Blend));
97 | }
98 |
99 |
100 | c = c * _Tint.rgb * unity_ColorSpaceDouble;
101 | c = lerp(c, 1 - c, _InvertColors);
102 | c *= _Exposure;
103 | return half4(c, 1);
104 | }
105 | ENDCG
106 |
107 | Pass{
108 | CGPROGRAM
109 |
110 | #pragma vertex vert
111 | #pragma fragment frag
112 |
113 | sampler2D _FrontTex_1;
114 | sampler2D _FrontTex_2;
115 | half4 _FrontTex_1_HDR;
116 | half4 _FrontTex_2_HDR;
117 | half4 frag(v2f i) : SV_Target{ return skybox_frag(i,_FrontTex_1, _FrontTex_1_HDR, _FrontTex_2, _FrontTex_2_HDR); }
118 | ENDCG
119 | }
120 | Pass{
121 | CGPROGRAM
122 |
123 | #pragma vertex vert
124 | #pragma fragment frag
125 |
126 | sampler2D _BackTex_1;
127 | sampler2D _BackTex_2;
128 | half4 _BackTex_1_HDR;
129 | half4 _BackTex_2_HDR;
130 | half4 frag(v2f i) : SV_Target{ return skybox_frag(i,_BackTex_1, _BackTex_1_HDR, _BackTex_2, _BackTex_2_HDR); }
131 | ENDCG
132 | }
133 | Pass{
134 | CGPROGRAM
135 |
136 | #pragma vertex vert
137 | #pragma fragment frag
138 |
139 | sampler2D _LeftTex_1;
140 | sampler2D _LeftTex_2;
141 | half4 _LeftTex_1_HDR;
142 | half4 _LeftTex_2_HDR;
143 | half4 frag(v2f i) : SV_Target{ return skybox_frag(i,_LeftTex_1, _LeftTex_1_HDR, _LeftTex_2, _LeftTex_2_HDR); }
144 | ENDCG
145 | }
146 | Pass{
147 | CGPROGRAM
148 |
149 | #pragma vertex vert
150 | #pragma fragment frag
151 |
152 | sampler2D _RightTex_1;
153 | sampler2D _RightTex_2;
154 | half4 _RightTex_1_HDR;
155 | half4 _RightTex_2_HDR;
156 | half4 frag(v2f i) : SV_Target{ return skybox_frag(i,_RightTex_1, _RightTex_1_HDR, _RightTex_2, _RightTex_2_HDR); }
157 | ENDCG
158 | }
159 | Pass{
160 | CGPROGRAM
161 |
162 | #pragma vertex vert
163 | #pragma fragment frag
164 |
165 | sampler2D _UpTex_1;
166 | sampler2D _UpTex_2;
167 | half4 _UpTex_1_HDR;
168 | half4 _UpTex_2_HDR;
169 | half4 frag(v2f i) : SV_Target{ return skybox_frag(i,_UpTex_1, _UpTex_1_HDR, _UpTex_2, _UpTex_2_HDR); }
170 | ENDCG
171 | }
172 | Pass{
173 | CGPROGRAM
174 |
175 | #pragma vertex vert
176 | #pragma fragment frag
177 |
178 | sampler2D _DownTex_1;
179 | sampler2D _DownTex_2;
180 | half4 _DownTex_1_HDR;
181 | half4 _DownTex_2_HDR;
182 | half4 frag(v2f i) : SV_Target{ return skybox_frag(i,_DownTex_1, _DownTex_1_HDR, _DownTex_2, _DownTex_2_HDR); }
183 | ENDCG
184 | }
185 | }
186 | }
--------------------------------------------------------------------------------
/Shaders/SkyboxBlender.shader.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 70efe3856907a7843b5a544e58a7058c
3 | ShaderImporter:
4 | externalObjects: {}
5 | defaultTextures: []
6 | nonModifiableTextures: []
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------