283 lines
8.3 KiB
C#
283 lines
8.3 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
#endif
|
|
|
|
namespace LuxURPEssentials
|
|
{
|
|
|
|
[System.Serializable]
|
|
public enum RTSize {
|
|
_128 = 128,
|
|
_256 = 256,
|
|
_512 = 512
|
|
}
|
|
|
|
[System.Serializable]
|
|
public enum RTFormat {
|
|
ARGB32 = 0,
|
|
ARGBHalf = 1
|
|
}
|
|
|
|
[System.Serializable]
|
|
public enum GustMixLayer {
|
|
Layer_0 = 0,
|
|
Layer_1 = 1,
|
|
Layer_2 = 2
|
|
}
|
|
|
|
[ExecuteInEditMode]
|
|
//[ExecuteAlways]
|
|
[RequireComponent(typeof(WindZone))]
|
|
//[HelpURL("https://docs.google.com/document/d/1ck3hmPzKUdewHfwsvmPYwSPCP8azwtpzN7aOLJHvMqE/edit#heading=h.wnnhm4pxp610")]
|
|
public class LuxURP_Wind : MonoBehaviour {
|
|
// using order to fix header/button issue
|
|
[Space(5)]
|
|
[LuxURP_HelpBtn("h.wnnhm4pxp610")]
|
|
[Space(-5)]
|
|
|
|
public bool UpdateInEditMode = false;
|
|
|
|
[Header("Render Texture Settings")]
|
|
|
|
public RTSize Resolution = RTSize._256;
|
|
public RTFormat Format = RTFormat.ARGB32;
|
|
public Texture WindBaseTex;
|
|
public Shader WindCompositeShader;
|
|
|
|
[Header("Wind Multipliers")]
|
|
public float Grass = 1.0f;
|
|
public float Foliage = 1.0f;
|
|
|
|
[Header("Wind Speed and Size")]
|
|
[Tooltip("Base Wind Speed in km/h at Main = 1 (WindZone)")]
|
|
public float BaseWindSpeed = 15;
|
|
[Tooltip("Size of the Wind RenderTexture in World Space")]
|
|
public float SizeInWorldSpace = 50;
|
|
[Space(5)]
|
|
public float speedLayer0 = 1.0f;
|
|
public float speedLayer1 = 1.137f;
|
|
public float speedLayer2 = 1.376f;
|
|
|
|
[Header("Noise")]
|
|
public int GrassGustTiling = 4;
|
|
public float GrassGustSpeed = 0.278f;
|
|
public GustMixLayer LayerToMixWith = GustMixLayer.Layer_1;
|
|
|
|
[Header("Jitter")]
|
|
public float JitterFrequency = 3.127f;
|
|
public float JitterHighFrequency = 21.0f;
|
|
|
|
|
|
private RenderTexture WindRenderTexture;
|
|
private Material m_material;
|
|
|
|
private Vector2 uvs = new Vector2(0,0);
|
|
private Vector2 uvs1 = new Vector2(0,0);
|
|
private Vector2 uvs2 = new Vector2(0,0);
|
|
private Vector2 uvs3 = new Vector2(0,0);
|
|
|
|
private int WindRTPID;
|
|
|
|
private Transform trans;
|
|
private WindZone windZone;
|
|
private float mainWind;
|
|
private float turbulence;
|
|
|
|
private int LuxLWRPWindDirSizePID;
|
|
private int LuxLWRPWindStrengthMultipliersPID;
|
|
private int LuxLWRPSinTimePID;
|
|
private int LuxLWRPGustPID;
|
|
private int LuxLWRPGustMixLayerPID;
|
|
|
|
private int LuxLWRPWindUVsPID;
|
|
private int LuxLWRPWindUVs1PID;
|
|
private int LuxLWRPWindUVs2PID;
|
|
private int LuxLWRPWindUVs3PID;
|
|
|
|
private int previousRTSize;
|
|
private int previousRTFormat;
|
|
|
|
private Vector4 WindDirectionSize = Vector4.zero;
|
|
|
|
private static Vector3[] MixLayers = new [] { new Vector3(1f,0f,0f), new Vector3(0f,1f,0f), new Vector3(0f,0f,1f) };
|
|
|
|
#if UNITY_EDITOR
|
|
private double lastTimeStamp = 0.0;
|
|
#endif
|
|
|
|
void OnEnable () {
|
|
if(WindCompositeShader == null) {
|
|
WindCompositeShader = Shader.Find("Hidden/Lux URP WindComposite");
|
|
}
|
|
if (WindBaseTex == null ) {
|
|
WindBaseTex = Resources.Load("Lux URP default wind base texture") as Texture;
|
|
}
|
|
SetupRT();
|
|
GetPIDs();
|
|
trans = this.transform;
|
|
windZone = trans.GetComponent<WindZone>();
|
|
|
|
previousRTSize = (int)Resolution;
|
|
previousRTFormat = (int)Format;
|
|
|
|
#if UNITY_EDITOR
|
|
EditorApplication.update += OnEditorUpdate;
|
|
#endif
|
|
}
|
|
|
|
|
|
void OnDisable () {
|
|
if (WindRenderTexture != null) {
|
|
WindRenderTexture.Release();
|
|
UnityEngine.Object.DestroyImmediate(WindRenderTexture);
|
|
}
|
|
if (m_material != null) {
|
|
UnityEngine.Object.DestroyImmediate(m_material);
|
|
m_material = null;
|
|
}
|
|
if (WindBaseTex != null) {
|
|
WindBaseTex = null;
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
EditorApplication.update -= OnEditorUpdate;
|
|
#endif
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
void OnEditorUpdate() {
|
|
if(!Application.isPlaying && UpdateInEditMode) {
|
|
Update();
|
|
// Unity 2019.1.10 on macOS using Metal also needs this
|
|
SceneView.RepaintAll();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void SetupRT () {
|
|
if (WindRenderTexture == null || m_material == null)
|
|
{
|
|
var rtf = ((int)Format == 0) ? RenderTextureFormat.ARGB32 : RenderTextureFormat.ARGBHalf;
|
|
WindRenderTexture = new RenderTexture((int)Resolution, (int)Resolution, 0, rtf, RenderTextureReadWrite.Linear );
|
|
WindRenderTexture.useMipMap = true;
|
|
WindRenderTexture.wrapMode = TextureWrapMode.Repeat;
|
|
m_material = new Material(WindCompositeShader);
|
|
}
|
|
}
|
|
|
|
void GetPIDs () {
|
|
WindRTPID = Shader.PropertyToID("_LuxLWRPWindRT");
|
|
LuxLWRPWindDirSizePID = Shader.PropertyToID("_LuxLWRPWindDirSize");
|
|
LuxLWRPWindStrengthMultipliersPID = Shader.PropertyToID("_LuxLWRPWindStrengthMultipliers");
|
|
LuxLWRPSinTimePID = Shader.PropertyToID("_LuxLWRPSinTime");
|
|
LuxLWRPGustPID = Shader.PropertyToID("_LuxLWRPGust");
|
|
LuxLWRPWindUVsPID = Shader.PropertyToID("_LuxLWRPWindUVs");
|
|
LuxLWRPWindUVs1PID = Shader.PropertyToID("_LuxLWRPWindUVs1");
|
|
LuxLWRPWindUVs2PID = Shader.PropertyToID("_LuxLWRPWindUVs2");
|
|
LuxLWRPWindUVs3PID = Shader.PropertyToID("_LuxLWRPWindUVs3");
|
|
LuxLWRPGustMixLayerPID = Shader.PropertyToID("_GustMixLayer");
|
|
}
|
|
|
|
void OnValidate () {
|
|
if(WindCompositeShader == null) {
|
|
WindCompositeShader = Shader.Find("Hidden/Lux LWRP WindComposite");
|
|
}
|
|
if (WindBaseTex == null ) {
|
|
WindBaseTex = Resources.Load("Default wind base texture") as Texture;
|
|
}
|
|
if ( (previousRTSize != (int)Resolution ) || ( previousRTFormat != (int)Format ) ) {
|
|
var rtf = ((int)Format == 0) ? RenderTextureFormat.ARGB32 : RenderTextureFormat.ARGBHalf;
|
|
WindRenderTexture = new RenderTexture((int)Resolution, (int)Resolution, 0, rtf, RenderTextureReadWrite.Linear );
|
|
WindRenderTexture.useMipMap = true;
|
|
WindRenderTexture.wrapMode = TextureWrapMode.Repeat;
|
|
}
|
|
}
|
|
|
|
void Update () {
|
|
|
|
// Get wind settings from WindZone
|
|
mainWind = windZone.windMain;
|
|
turbulence = windZone.windTurbulence;
|
|
|
|
float delta = Time.deltaTime;
|
|
|
|
#if UNITY_EDITOR
|
|
if(!Application.isPlaying) {
|
|
delta = (float)(EditorApplication.timeSinceStartup - lastTimeStamp);
|
|
lastTimeStamp = EditorApplication.timeSinceStartup;
|
|
}
|
|
#endif
|
|
|
|
WindDirectionSize.x = trans.forward.x;
|
|
WindDirectionSize.y = trans.forward.y;
|
|
WindDirectionSize.z = trans.forward.z;
|
|
WindDirectionSize.w = 1.0f / SizeInWorldSpace;
|
|
|
|
var windVec = new Vector2(WindDirectionSize.x, WindDirectionSize.z ) * delta * (BaseWindSpeed * 0.2777f * WindDirectionSize.w); // * mainWind);
|
|
|
|
uvs -= windVec * speedLayer0;
|
|
uvs.x = uvs.x - (int)uvs.x;
|
|
uvs.y = uvs.y - (int)uvs.y;
|
|
|
|
uvs1 -= windVec * speedLayer1;
|
|
uvs1.x = uvs1.x - (int)uvs1.x;
|
|
uvs1.y = uvs1.y - (int)uvs1.y;
|
|
|
|
uvs2 -= windVec * speedLayer2;
|
|
uvs2.x = uvs2.x - (int)uvs2.x;
|
|
uvs2.y = uvs2.y - (int)uvs2.y;
|
|
|
|
uvs3 -= windVec * GrassGustSpeed * turbulence;
|
|
uvs3.x = uvs3.x - (int)uvs3.x;
|
|
uvs3.y = uvs3.y - (int)uvs3.y;
|
|
|
|
// Set global shader variables for grass and foliage shaders
|
|
Shader.SetGlobalVector(LuxLWRPWindDirSizePID, WindDirectionSize);
|
|
|
|
Vector2 tempWindstrengths;
|
|
tempWindstrengths.x = Grass * mainWind;
|
|
tempWindstrengths.y = Foliage * mainWind;
|
|
Shader.SetGlobalVector(LuxLWRPWindStrengthMultipliersPID, tempWindstrengths );
|
|
// Use clamped turbulence as otherwise wind direction might get "reversed"
|
|
Shader.SetGlobalVector(LuxLWRPGustPID, new Vector2(GrassGustTiling, Mathf.Clamp( turbulence + 0.5f, 0.0f, 1.5f)) );
|
|
// Jitter frequncies and strength
|
|
Shader.SetGlobalVector(LuxLWRPSinTimePID, new Vector4(
|
|
(float)Math.Sin(Time.time * JitterFrequency),
|
|
(float)Math.Sin(Time.time * JitterFrequency * 0.2317f + 2.0f * Mathf.PI),
|
|
(float)Math.Sin(Time.time * JitterHighFrequency),
|
|
turbulence * 0.1f
|
|
));
|
|
|
|
|
|
// Set UVs
|
|
Shader.SetGlobalVector(LuxLWRPWindUVsPID, uvs);
|
|
Shader.SetGlobalVector(LuxLWRPWindUVs1PID, uvs1);
|
|
Shader.SetGlobalVector(LuxLWRPWindUVs2PID, uvs2);
|
|
Shader.SetGlobalVector(LuxLWRPWindUVs3PID, uvs3);
|
|
|
|
// Set Mix Layer
|
|
Shader.SetGlobalVector(LuxLWRPGustMixLayerPID, MixLayers[(int)LayerToMixWith]);
|
|
|
|
#if UNITY_EDITOR
|
|
if (m_material != null && WindRenderTexture != null ) {
|
|
#endif
|
|
Graphics.Blit(WindBaseTex, WindRenderTexture, m_material);
|
|
WindRenderTexture.SetGlobalShaderProperty("_LuxLWRPWindRT"); // only accepts strings...
|
|
#if UNITY_EDITOR
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
void OnRenderObject() {
|
|
//Update();
|
|
}
|
|
#endif
|
|
}
|
|
} |