@ -1,7 +0,0 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 490e8164148c52c468b633dcc1c12d57 | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -1,7 +0,0 @@ | |||||
fileFormatVersion: 2 | |||||
guid: af7de8b91a27c254fa1bd24c01ae6e8e | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -1,7 +0,0 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 191365b4aece81443875ae2bb7243b55 | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -1,7 +0,0 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 4dc1afbcc68875c4780502f5e6b80158 | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -1,7 +0,0 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 9a5e61a8b3421b944863d0946e32da0a | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -1,7 +0,0 @@ | |||||
fileFormatVersion: 2 | |||||
guid: b53d2f3b156ff104f90d4d7693d769c8 | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -1,7 +0,0 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 4c816894a3147d343891060451241bfe | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -1,5 +1,6 @@ | |||||
fileFormatVersion: 2 | fileFormatVersion: 2 | ||||
guid: 6ecbfd0a046659943a69328c98ff0442 | |||||
guid: f131538635f91d74f87c8a5a817902cd | |||||
folderAsset: yes | |||||
DefaultImporter: | DefaultImporter: | ||||
externalObjects: {} | externalObjects: {} | ||||
userData: | userData: |
@ -1,5 +1,6 @@ | |||||
fileFormatVersion: 2 | fileFormatVersion: 2 | ||||
guid: 88dfe89a073bdf748bf05396f5285cdd | |||||
guid: c47de40812d0e7247ac3fc16fa42eb4b | |||||
folderAsset: yes | |||||
DefaultImporter: | DefaultImporter: | ||||
externalObjects: {} | externalObjects: {} | ||||
userData: | userData: |
@ -0,0 +1,3 @@ | |||||
version https://git-lfs.github.com/spec/v1 | |||||
oid sha256:2dab8520d2b1e8fb214ed1a56e2b21107a59648e0e8eedfdd3bbd47db89cf6b9 | |||||
size 16777760 |
@ -0,0 +1,6 @@ | |||||
fileFormatVersion: 2 | |||||
guid: ce515a5a715cb574eb40037cfb1ab766 | |||||
NativeFormatImporter: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,142 @@ | |||||
Shader "Hidden/FogVolume" | |||||
{ | |||||
Properties | |||||
{ | |||||
[hideininspector]_SrcBlend("__src", Float) = 1.0 | |||||
[hideininspector]_NoiseVolume("_NoiseVolume", 3D)= "white" {} | |||||
[hideininspector]_NoiseVolume2("_NoiseVolume2", 3D) = "white" {} | |||||
[hideininspector]_Gradient("_Gradient", 2D) = "white" {} | |||||
[hideininspector]CoverageTex("CoverageTex", 2D) = "grey" {} | |||||
//[hideininspector]_ShadowTexture("_ShadowTexture", 2D) = "white" {} | |||||
} | |||||
CGINCLUDE | |||||
//#define COVERAGE | |||||
//#define EARTH_CLOUD_STYLE | |||||
//#define VOLUMETRIC_SHADOWS _VolumetricShadowsEnabled | |||||
//#define CONVOLVE_VOLUMETRIC_SHADOWS | |||||
//custom depth input | |||||
//#define ExternalDepth | |||||
#define AMBIENT_AFFECTS_FOG_COLOR _AmbientAffectsFogColor | |||||
//#define DEBUG_PRIMITIVES | |||||
#define VOLUMETRIC_SHADOWS _VolumetricShadowsEnabled | |||||
#define FOG_TINTS_INSCATTER VolumeFogInscatterColorAffectedWithFogColor | |||||
#include "UnityCG.cginc" | |||||
#include "CommonInputs.cginc" | |||||
#include "Integrations.cginc" | |||||
#define PROBES _ProxyVolume | |||||
half NoiseAtten = 1; | |||||
int _SrcBlend; | |||||
int _ztest; | |||||
#include "FogVolumeCommon.cginc" | |||||
#define DEBUG_ITERATIONS 1 | |||||
#define DEBUG_INSCATTERING 2 | |||||
#define DEBUG_VOLUMETRIC_SHADOWS 3 | |||||
#define DEBUG_VOLUME_FOG_INSCATTER_CLAMP 4 | |||||
#define DEBUG_VOLUME_FOG_PHASE 5 | |||||
#include "FogVolumeFragment.cginc" | |||||
ENDCG | |||||
//normal pass | |||||
SubShader | |||||
{ | |||||
Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "None" } | |||||
LOD 600 | |||||
//Blend SrcAlpha OneMinusSrcAlpha | |||||
//Blend One OneMinusSrcAlpha | |||||
Blend[_SrcBlend] OneMinusSrcAlpha | |||||
Fog{ Mode Off } | |||||
Cull Front | |||||
Lighting Off | |||||
ZWrite Off | |||||
ZTest [_ztest] | |||||
Pass | |||||
{ | |||||
CGPROGRAM | |||||
//#pragma multi_compile _ ExternalDepth | |||||
#pragma multi_compile _ _FOG_LOWRES_RENDERER | |||||
#pragma shader_feature _INSCATTERING | |||||
#pragma shader_feature VOLUME_FOG | |||||
#pragma shader_feature _VOLUME_FOG_INSCATTERING | |||||
#pragma shader_feature _FOG_GRADIENT | |||||
#pragma shader_feature _FOG_VOLUME_NOISE | |||||
// #pragma shader_feature _COLLISION | |||||
//#pragma multi_compile _ DEBUG | |||||
//#pragma shader_feature SAMPLING_METHOD_ViewAligned | |||||
#pragma shader_feature HEIGHT_GRAD | |||||
//#pragma shader_feature _TONEMAP | |||||
#pragma shader_feature JITTER | |||||
#pragma shader_feature ColorAdjust | |||||
#pragma shader_feature ABSORPTION | |||||
#pragma multi_compile _ Twirl_X Twirl_Y Twirl_Z | |||||
#pragma shader_feature _SHADE | |||||
#pragma shader_feature DF | |||||
#pragma shader_feature DIRECTIONAL_LIGHTING | |||||
#pragma multi_compile _ ATTEN_METHOD_1 ATTEN_METHOD_2 ATTEN_METHOD_3 | |||||
#pragma shader_feature SPHERICAL_FADE | |||||
//#pragma shader_feature _LAMBERT_SHADING | |||||
#pragma multi_compile _ VOLUME_SHADOWS | |||||
#pragma shader_feature LIGHT_ATTACHED | |||||
#pragma shader_feature HALO | |||||
//Unity define for stereo is not working. Had to do it manually | |||||
#pragma multi_compile _ FOG_VOLUME_STEREO_ON | |||||
#pragma exclude_renderers d3d9 | |||||
//#pragma only_renderers d3d11 | |||||
#pragma vertex vert | |||||
#pragma fragment frag | |||||
#pragma target 3.0 | |||||
ENDCG | |||||
} | |||||
} | |||||
//opacity pass . Only for shadow rt | |||||
SubShader | |||||
{ | |||||
Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "None" } | |||||
LOD 100 | |||||
Blend SrcAlpha OneMinusSrcAlpha | |||||
Fog{ Mode Off } | |||||
Cull Front | |||||
Lighting Off | |||||
ZWrite Off | |||||
ZTest Always | |||||
Pass | |||||
{ | |||||
Fog{ Mode Off } | |||||
CGPROGRAM | |||||
#define SHADOW_PASS | |||||
#pragma shader_feature _FOG_GRADIENT | |||||
#pragma shader_feature _FOG_VOLUME_NOISE | |||||
// #pragma shader_feature _COLLISION | |||||
#pragma shader_feature SAMPLING_METHOD_ViewAligned | |||||
#pragma shader_feature HEIGHT_GRAD | |||||
#pragma multi_compile Twirl_X Twirl_Y Twirl_Z | |||||
#pragma shader_feature DF | |||||
//#pragma multi_compile SHADOW_PASS | |||||
#pragma shader_feature SPHERICAL_FADE | |||||
#pragma exclude_renderers d3d9 | |||||
//#pragma only_renderers d3d11 | |||||
#pragma glsl | |||||
#pragma vertex vert | |||||
#pragma fragment frag | |||||
#pragma target 3.0 | |||||
ENDCG | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,7 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 6040e6c91df9d9d47b7e5426d41a7471 | |||||
ShaderImporter: | |||||
defaultTextures: [] | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,164 @@ | |||||
// Upgrade NOTE: removed variant '__' where variant LOD_FADE_PERCENTAGE is used. | |||||
Shader "Hidden/FogVolumeDirectionalLight" | |||||
{ | |||||
Properties | |||||
{ | |||||
_Cutoff("Alpha cutoff", Range(0,1)) = 0.5 | |||||
_MainTex("Base (RGB)", 2D) = "white" {} | |||||
_Color("Color", Color) = (1,1,1,1) | |||||
//_FogVolumeShadowMapEdgeSoftness("Edge size", Range(1, 100))=100 | |||||
} | |||||
SubShader | |||||
{ | |||||
Tags{ "RenderType" = "Opaque" } | |||||
Pass | |||||
{ | |||||
CGPROGRAM | |||||
#define EDGE_FIX | |||||
#pragma vertex vert | |||||
#pragma fragment frag | |||||
#include "UnityCG.cginc" | |||||
uniform sampler2D _MainTex; | |||||
float4 _ShadowCameraPosition; | |||||
uniform float _Cutoff = 1, _FogVolumeShadowMapEdgeSoftness; | |||||
struct v2f | |||||
{ | |||||
float4 pos : SV_POSITION; | |||||
float depth : DEPTH; | |||||
float2 uv : TEXCOORD0; | |||||
float4 screenUV : TEXCOORD1; | |||||
}; | |||||
v2f vert(appdata_base v) | |||||
{ | |||||
v2f o; | |||||
o.pos = UnityObjectToClipPos(v.vertex); | |||||
o.depth = length(mul(unity_ObjectToWorld, v.vertex).xyz - _ShadowCameraPosition.xyz); | |||||
o.uv = v.texcoord.xy; | |||||
o.screenUV = ComputeScreenPos(o.pos); | |||||
return o; | |||||
} | |||||
float4 frag(v2f i) : COLOR | |||||
{ | |||||
float2 uv = i.screenUV.xy / i.screenUV.w; | |||||
float d = i.depth; | |||||
#ifdef EDGE_FIX | |||||
half edges = saturate(dot(1-uv.r, 1-uv.g) * dot(uv.r, uv.g)*600); | |||||
d = lerp(10000, d, edges); | |||||
#endif | |||||
half fade = saturate(dot(1 - uv.r, 1 - uv.g) * dot(uv.r, uv.g)*_FogVolumeShadowMapEdgeSoftness); | |||||
fade *= fade*fade; | |||||
return float4(d, fade, 0.0f, 1); | |||||
} | |||||
ENDCG | |||||
} | |||||
} | |||||
SubShader | |||||
{ | |||||
Tags{ "RenderType" = "TransparentCutout" } | |||||
Pass | |||||
{ | |||||
CGPROGRAM | |||||
#define EDGE_FIX | |||||
#pragma vertex vert | |||||
#pragma fragment frag | |||||
#include "UnityCG.cginc" | |||||
uniform sampler2D _MainTex; | |||||
float4 _ShadowCameraPosition; | |||||
uniform float _Cutoff = 1, _FogVolumeShadowMapEdgeSoftness; | |||||
float4 _Color; | |||||
struct v2f | |||||
{ | |||||
float4 pos : SV_POSITION; | |||||
float depth : DEPTH; | |||||
float2 uv : TEXCOORD0; | |||||
float4 screenUV : TEXCOORD1; | |||||
}; | |||||
v2f vert(appdata_base v) | |||||
{ | |||||
v2f o; | |||||
o.pos = UnityObjectToClipPos(v.vertex); | |||||
o.depth = length(mul(unity_ObjectToWorld, v.vertex).xyz - _ShadowCameraPosition.xyz); | |||||
o.uv = v.texcoord.xy; | |||||
o.screenUV = ComputeScreenPos(o.pos); | |||||
return o; | |||||
} | |||||
float4 frag(v2f i) : COLOR | |||||
{ | |||||
half4 c = tex2D(_MainTex, i.uv)*_Color; | |||||
float2 uv = i.screenUV.xy / i.screenUV.w; | |||||
clip(c.a - _Cutoff); | |||||
float d = i.depth; | |||||
#ifdef EDGE_FIX | |||||
half edges = saturate(dot(1 - uv.r, 1 - uv.g) * dot(uv.r, uv.g) * 600); | |||||
d = lerp(10000, d, edges); | |||||
#endif | |||||
half fade = saturate(dot(1 - uv.r, 1 - uv.g) * dot(uv.r, uv.g)*_FogVolumeShadowMapEdgeSoftness); | |||||
fade *= fade*fade; | |||||
return float4(d, fade, 0.0f, 1); | |||||
} | |||||
ENDCG | |||||
} | |||||
} | |||||
SubShader | |||||
{ | |||||
Tags | |||||
{ | |||||
"Queue" = "Geometry" | |||||
"IgnoreProjector" = "True" | |||||
"RenderType" = "SpeedTree" | |||||
"DisableBatching" = "LODFading" | |||||
} | |||||
Cull[_Cull] | |||||
Fog{ Mode Off } | |||||
CGPROGRAM | |||||
uniform sampler2D _MainTex; | |||||
float4 /*_ShadowCameraPosition,*/ _Color; | |||||
uniform float _Cutoff = 1, _FogVolumeShadowMapEdgeSoftness; | |||||
#pragma surface surf Lambert vertex:SpeedTreeVert nolightmap | |||||
#pragma target 3.0 | |||||
#pragma multi_compile LOD_FADE_PERCENTAGE LOD_FADE_CROSSFADE | |||||
#pragma shader_feature GEOM_TYPE_BRANCH GEOM_TYPE_BRANCH_DETAIL GEOM_TYPE_FROND GEOM_TYPE_LEAF GEOM_TYPE_MESH | |||||
#define ENABLE_WIND | |||||
#define SPEEDTREE_ALPHATEST | |||||
#define EDGE_FIX | |||||
#include "SpeedTreeCommonDepth.cginc" | |||||
void surf(Input i, inout SurfaceOutput OUT) | |||||
{ | |||||
float2 uv = i.screenUV.xy / i.screenUV.w; | |||||
float d = i.ShadowDepth; | |||||
#ifdef EDGE_FIX | |||||
half edges = saturate(dot(1 - uv.r, 1 - uv.g) * dot(uv.r, uv.g) * 600); | |||||
d = lerp(10000, d, edges); | |||||
#endif | |||||
half fade = saturate(dot(1 - uv.r, 1 - uv.g) * dot(uv.r, uv.g)*_FogVolumeShadowMapEdgeSoftness); | |||||
fade *= fade*fade; | |||||
OUT.Emission = float3(d, fade, 0.0f); | |||||
SpeedTreeFragOut o; | |||||
SpeedTreeFrag(i, o); | |||||
SPEEDTREE_COPY_FRAG(OUT, o) | |||||
} | |||||
ENDCG | |||||
} | |||||
} |
@ -0,0 +1,9 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 4fc2932190d974a4887533f0e52baf6c | |||||
timeCreated: 1496863314 | |||||
licenseType: Store | |||||
ShaderImporter: | |||||
defaultTextures: [] | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,3 @@ | |||||
version https://git-lfs.github.com/spec/v1 | |||||
oid sha256:370f399cfed63c5021e519eebc8004f4a0eb7defeeccc42b980f935eb5023e0a | |||||
size 22653 |
@ -0,0 +1,84 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 925eb9f7b0e73dd438a616124964bba8 | |||||
timeCreated: 1488739538 | |||||
licenseType: Store | |||||
TextureImporter: | |||||
fileIDToRecycleName: {} | |||||
serializedVersion: 4 | |||||
mipmaps: | |||||
mipMapMode: 0 | |||||
enableMipMap: 1 | |||||
sRGBTexture: 0 | |||||
linearTexture: 0 | |||||
fadeOut: 0 | |||||
borderMipMap: 0 | |||||
mipMapFadeDistanceStart: 1 | |||||
mipMapFadeDistanceEnd: 3 | |||||
bumpmap: | |||||
convertToNormalMap: 0 | |||||
externalNormalMap: 0 | |||||
heightScale: 0.25 | |||||
normalMapFilter: 0 | |||||
isReadable: 0 | |||||
grayScaleToAlpha: 0 | |||||
generateCubemap: 6 | |||||
cubemapConvolution: 0 | |||||
seamlessCubemap: 0 | |||||
textureFormat: 1 | |||||
maxTextureSize: 2048 | |||||
textureSettings: | |||||
filterMode: -1 | |||||
aniso: -1 | |||||
mipBias: -1 | |||||
wrapMode: -1 | |||||
nPOTScale: 1 | |||||
lightmap: 0 | |||||
compressionQuality: 50 | |||||
spriteMode: 0 | |||||
spriteExtrude: 1 | |||||
spriteMeshType: 1 | |||||
alignment: 0 | |||||
spritePivot: {x: 0.5, y: 0.5} | |||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0} | |||||
spritePixelsToUnits: 100 | |||||
alphaUsage: 1 | |||||
alphaIsTransparency: 1 | |||||
spriteTessellationDetail: -1 | |||||
textureType: 0 | |||||
textureShape: 1 | |||||
maxTextureSizeSet: 0 | |||||
compressionQualitySet: 0 | |||||
textureFormatSet: 0 | |||||
platformSettings: | |||||
- buildTarget: DefaultTexturePlatform | |||||
maxTextureSize: 2048 | |||||
textureFormat: -1 | |||||
textureCompression: 0 | |||||
compressionQuality: 50 | |||||
crunchedCompression: 0 | |||||
allowsAlphaSplitting: 0 | |||||
overridden: 0 | |||||
- buildTarget: Standalone | |||||
maxTextureSize: 2048 | |||||
textureFormat: -1 | |||||
textureCompression: 0 | |||||
compressionQuality: 50 | |||||
crunchedCompression: 0 | |||||
allowsAlphaSplitting: 0 | |||||
overridden: 0 | |||||
- buildTarget: Android | |||||
maxTextureSize: 2048 | |||||
textureFormat: -1 | |||||
textureCompression: 0 | |||||
compressionQuality: 50 | |||||
crunchedCompression: 0 | |||||
allowsAlphaSplitting: 0 | |||||
overridden: 0 | |||||
spriteSheet: | |||||
serializedVersion: 2 | |||||
sprites: [] | |||||
outline: [] | |||||
spritePackingTag: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,3 @@ | |||||
version https://git-lfs.github.com/spec/v1 | |||||
oid sha256:e9a70fcd7af92becfcd3b8f83178460c104d8af6f7909e61fda245023e481cba | |||||
size 50381 |
@ -0,0 +1,84 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 5aac178e436d68546ae151ed5ba76b94 | |||||
timeCreated: 1493126559 | |||||
licenseType: Store | |||||
TextureImporter: | |||||
fileIDToRecycleName: {} | |||||
serializedVersion: 4 | |||||
mipmaps: | |||||
mipMapMode: 0 | |||||
enableMipMap: 1 | |||||
sRGBTexture: 1 | |||||
linearTexture: 0 | |||||
fadeOut: 0 | |||||
borderMipMap: 0 | |||||
mipMapFadeDistanceStart: 1 | |||||
mipMapFadeDistanceEnd: 3 | |||||
bumpmap: | |||||
convertToNormalMap: 0 | |||||
externalNormalMap: 0 | |||||
heightScale: 0.25 | |||||
normalMapFilter: 0 | |||||
isReadable: 0 | |||||
grayScaleToAlpha: 0 | |||||
generateCubemap: 6 | |||||
cubemapConvolution: 0 | |||||
seamlessCubemap: 0 | |||||
textureFormat: 1 | |||||
maxTextureSize: 2048 | |||||
textureSettings: | |||||
filterMode: -1 | |||||
aniso: -1 | |||||
mipBias: -1 | |||||
wrapMode: -1 | |||||
nPOTScale: 1 | |||||
lightmap: 0 | |||||
compressionQuality: 50 | |||||
spriteMode: 0 | |||||
spriteExtrude: 1 | |||||
spriteMeshType: 1 | |||||
alignment: 0 | |||||
spritePivot: {x: 0.5, y: 0.5} | |||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0} | |||||
spritePixelsToUnits: 100 | |||||
alphaUsage: 1 | |||||
alphaIsTransparency: 1 | |||||
spriteTessellationDetail: -1 | |||||
textureType: 0 | |||||
textureShape: 1 | |||||
maxTextureSizeSet: 0 | |||||
compressionQualitySet: 0 | |||||
textureFormatSet: 0 | |||||
platformSettings: | |||||
- buildTarget: DefaultTexturePlatform | |||||
maxTextureSize: 2048 | |||||
textureFormat: -1 | |||||
textureCompression: 1 | |||||
compressionQuality: 50 | |||||
crunchedCompression: 0 | |||||
allowsAlphaSplitting: 0 | |||||
overridden: 0 | |||||
- buildTarget: Standalone | |||||
maxTextureSize: 2048 | |||||
textureFormat: -1 | |||||
textureCompression: 1 | |||||
compressionQuality: 50 | |||||
crunchedCompression: 0 | |||||
allowsAlphaSplitting: 0 | |||||
overridden: 0 | |||||
- buildTarget: Android | |||||
maxTextureSize: 2048 | |||||
textureFormat: -1 | |||||
textureCompression: 1 | |||||
compressionQuality: 50 | |||||
crunchedCompression: 0 | |||||
allowsAlphaSplitting: 0 | |||||
overridden: 0 | |||||
spriteSheet: | |||||
serializedVersion: 2 | |||||
sprites: [] | |||||
outline: [] | |||||
spritePackingTag: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,3 @@ | |||||
version https://git-lfs.github.com/spec/v1 | |||||
oid sha256:3d1a1320d75a666ce746677cd81a3d3eada05308d62099b0e1462caa3ef012a7 | |||||
size 25508 |
@ -0,0 +1,76 @@ | |||||
fileFormatVersion: 2 | |||||
guid: f651c771afb96204b85e925622f5e2b9 | |||||
timeCreated: 1483987450 | |||||
licenseType: Store | |||||
TextureImporter: | |||||
fileIDToRecycleName: {} | |||||
serializedVersion: 4 | |||||
mipmaps: | |||||
mipMapMode: 0 | |||||
enableMipMap: 1 | |||||
sRGBTexture: 1 | |||||
linearTexture: 0 | |||||
fadeOut: 0 | |||||
borderMipMap: 0 | |||||
mipMapFadeDistanceStart: 1 | |||||
mipMapFadeDistanceEnd: 3 | |||||
bumpmap: | |||||
convertToNormalMap: 0 | |||||
externalNormalMap: 0 | |||||
heightScale: 0.25 | |||||
normalMapFilter: 0 | |||||
isReadable: 0 | |||||
grayScaleToAlpha: 0 | |||||
generateCubemap: 6 | |||||
cubemapConvolution: 0 | |||||
seamlessCubemap: 0 | |||||
textureFormat: 1 | |||||
maxTextureSize: 2048 | |||||
textureSettings: | |||||
filterMode: -1 | |||||
aniso: -1 | |||||
mipBias: -1 | |||||
wrapMode: 0 | |||||
nPOTScale: 1 | |||||
lightmap: 0 | |||||
compressionQuality: 50 | |||||
spriteMode: 0 | |||||
spriteExtrude: 1 | |||||
spriteMeshType: 1 | |||||
alignment: 0 | |||||
spritePivot: {x: 0.5, y: 0.5} | |||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0} | |||||
spritePixelsToUnits: 100 | |||||
alphaUsage: 1 | |||||
alphaIsTransparency: 0 | |||||
spriteTessellationDetail: -1 | |||||
textureType: 0 | |||||
textureShape: 1 | |||||
maxTextureSizeSet: 0 | |||||
compressionQualitySet: 0 | |||||
textureFormatSet: 0 | |||||
platformSettings: | |||||
- buildTarget: DefaultTexturePlatform | |||||
maxTextureSize: 2048 | |||||
textureFormat: -1 | |||||
textureCompression: 1 | |||||
compressionQuality: 50 | |||||
crunchedCompression: 0 | |||||
allowsAlphaSplitting: 0 | |||||
overridden: 0 | |||||
- buildTarget: Standalone | |||||
maxTextureSize: 2048 | |||||
textureFormat: -1 | |||||
textureCompression: 1 | |||||
compressionQuality: 50 | |||||
crunchedCompression: 0 | |||||
allowsAlphaSplitting: 0 | |||||
overridden: 0 | |||||
spriteSheet: | |||||
serializedVersion: 2 | |||||
sprites: [] | |||||
outline: [] | |||||
spritePackingTag: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,59 @@ | |||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' | |||||
// Shader created with Shader Forge v1.33 | |||||
// Shader Forge (c) Neat Corporation / Joachim Holmer - http://www.acegikmo.com/shaderforge/ | |||||
// Note: Manually altering this data may prevent you from opening it in Shader Forge | |||||
/*SF_DATA;ver:1.33;sub:START;pass:START;ps:flbk:,iptp:0,cusa:False,bamd:0,lico:1,lgpr:1,limd:0,spmd:1,trmd:0,grmd:0,uamb:True,mssp:True,bkdf:False,hqlp:False,rprd:False,enco:False,rmgx:True,rpth:0,vtps:0,hqsc:True,nrmq:1,nrsp:0,vomd:0,spxs:False,tesm:0,olmd:1,culm:0,bsrc:3,bdst:7,dpts:2,wrdp:False,dith:0,atcv:False,rfrpo:True,rfrpn:Refraction,coma:15,ufog:False,aust:True,igpj:True,qofs:0,qpre:3,rntp:2,fgom:False,fgoc:False,fgod:False,fgor:False,fgmd:0,fgcr:0.5,fgcg:0.5,fgcb:0.5,fgca:1,fgde:0.01,fgrn:0,fgrf:300,stcl:False,stva:128,stmr:255,stmw:255,stcp:6,stps:0,stfa:0,stfz:0,ofsf:0,ofsu:0,f2p0:False,fnsp:False,fnfb:False;n:type:ShaderForge.SFN_Final,id:3138,x:33057,y:32649,varname:node_3138,prsc:2|emission-7241-RGB,alpha-7241-A;n:type:ShaderForge.SFN_Color,id:7241,x:32471,y:32812,ptovrint:False,ptlb:Color,ptin:_Color,varname:_Color,prsc:2,glob:False,taghide:False,taghdr:False,tagprd:False,tagnsco:False,tagnrm:False,c1:0.07843138,c2:0.3921569,c3:0.7843137,c4:1;proporder:7241;pass:END;sub:END;*/ | |||||
Shader "Fog Volume/Primitive" { | |||||
Properties { | |||||
_Color ("Color", Color) = (0.07843138,0.3921569,0.7843137,1) | |||||
[HideInInspector]_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5 | |||||
} | |||||
SubShader { | |||||
Tags { | |||||
"IgnoreProjector"="True" | |||||
"Queue"="Transparent" | |||||
"RenderType"="Transparent" | |||||
} | |||||
Pass { | |||||
Name "FORWARD" | |||||
Tags { | |||||
"LightMode"="ForwardBase" | |||||
} | |||||
Blend SrcAlpha OneMinusSrcAlpha | |||||
ZWrite Off | |||||
Cull off | |||||
CGPROGRAM | |||||
#pragma vertex vert | |||||
#pragma fragment frag | |||||
//#define UNITY_PASS_FORWARDBASE | |||||
#include "UnityCG.cginc" | |||||
#pragma multi_compile_fwdbase | |||||
#pragma only_renderers d3d9 d3d11 glcore gles gles3 metal | |||||
#pragma target 3.0 | |||||
uniform float4 _Color; | |||||
struct VertexInput { | |||||
float4 vertex : POSITION; | |||||
}; | |||||
struct VertexOutput { | |||||
float4 pos : SV_POSITION; | |||||
}; | |||||
VertexOutput vert (VertexInput v) { | |||||
VertexOutput o = (VertexOutput)0; | |||||
o.pos = UnityObjectToClipPos(v.vertex ); | |||||
return o; | |||||
} | |||||
float4 frag(VertexOutput i) : COLOR { | |||||
////// Lighting: | |||||
////// Emissive: | |||||
float3 emissive = _Color.rgb; | |||||
float3 finalColor = emissive; | |||||
return fixed4(finalColor,_Color.a); | |||||
} | |||||
ENDCG | |||||
} | |||||
} | |||||
FallBack "Diffuse" | |||||
// CustomEditor "ShaderForgeMaterialInspector" | |||||
} |
@ -0,0 +1,9 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 972bc62358fe0b74390929ddcc7f76cc | |||||
timeCreated: 1487241739 | |||||
licenseType: Store | |||||
ShaderImporter: | |||||
defaultTextures: [] | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,136 @@ | |||||
%YAML 1.1 | |||||
%TAG !u! tag:unity3d.com,2011: | |||||
--- !u!21 &2100000 | |||||
Material: | |||||
serializedVersion: 6 | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 0} | |||||
m_Name: PrimitiveMaterial | |||||
m_Shader: {fileID: 4800000, guid: 972bc62358fe0b74390929ddcc7f76cc, type: 3} | |||||
m_ShaderKeywords: _EMISSION | |||||
m_LightmapFlags: 1 | |||||
m_CustomRenderQueue: -1 | |||||
stringTagMap: {} | |||||
m_SavedProperties: | |||||
serializedVersion: 2 | |||||
m_TexEnvs: | |||||
- first: | |||||
name: _BumpMap | |||||
second: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- first: | |||||
name: _DetailAlbedoMap | |||||
second: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- first: | |||||
name: _DetailMask | |||||
second: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- first: | |||||
name: _DetailNormalMap | |||||
second: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- first: | |||||
name: _EmissionMap | |||||
second: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- first: | |||||
name: _MainTex | |||||
second: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- first: | |||||
name: _MetallicGlossMap | |||||
second: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- first: | |||||
name: _OcclusionMap | |||||
second: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- first: | |||||
name: _ParallaxMap | |||||
second: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
m_Floats: | |||||
- first: | |||||
name: _BumpScale | |||||
second: 1 | |||||
- first: | |||||
name: _Cutoff | |||||
second: 0.5 | |||||
- first: | |||||
name: _DetailNormalMapScale | |||||
second: 1 | |||||
- first: | |||||
name: _DstBlend | |||||
second: 0 | |||||
- first: | |||||
name: _GlossMapScale | |||||
second: 1 | |||||
- first: | |||||
name: _Glossiness | |||||
second: 0.5 | |||||
- first: | |||||
name: _GlossyReflections | |||||
second: 1 | |||||
- first: | |||||
name: _Metallic | |||||
second: 0 | |||||
- first: | |||||
name: _Mode | |||||
second: 0 | |||||
- first: | |||||
name: _OcclusionStrength | |||||
second: 1 | |||||
- first: | |||||
name: _Parallax | |||||
second: 0.02 | |||||
- first: | |||||
name: _Shininess | |||||
second: 0.1 | |||||
- first: | |||||
name: _SmoothnessTextureChannel | |||||
second: 0 | |||||
- first: | |||||
name: _SpecularHighlights | |||||
second: 1 | |||||
- first: | |||||
name: _SrcBlend | |||||
second: 1 | |||||
- first: | |||||
name: _UVSec | |||||
second: 0 | |||||
- first: | |||||
name: _ZWrite | |||||
second: 1 | |||||
m_Colors: | |||||
- first: | |||||
name: _Color | |||||
second: {r: 1, g: 0, b: 0, a: 0.134} | |||||
- first: | |||||
name: _Emission | |||||
second: {r: 0, g: 0, b: 0, a: 0} | |||||
- first: | |||||
name: _EmissionColor | |||||
second: {r: 0, g: 0, b: 0, a: 1} | |||||
- first: | |||||
name: _SpecColor | |||||
second: {r: 1, g: 1, b: 1, a: 0} |
@ -0,0 +1,8 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 0429485e63d913a438bd171228fce857 | |||||
timeCreated: 1486134877 | |||||
licenseType: Store | |||||
NativeFormatImporter: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -1,5 +1,6 @@ | |||||
fileFormatVersion: 2 | fileFormatVersion: 2 | ||||
guid: 11f44bcb01ea56742bb7177b439b1a4f | |||||
guid: 86189be0758f7f7499751bc61477ef2c | |||||
folderAsset: yes | |||||
DefaultImporter: | DefaultImporter: | ||||
externalObjects: {} | externalObjects: {} | ||||
userData: | userData: |
@ -0,0 +1,8 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 8525f4488cca4974c8606fed359dfc9e | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,28 @@ | |||||
%YAML 1.1 | |||||
%TAG !u! tag:unity3d.com,2011: | |||||
--- !u!21 &2100000 | |||||
Material: | |||||
serializedVersion: 6 | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 0} | |||||
m_Name: RT_ShadowDepth | |||||
m_Shader: {fileID: 4800000, guid: 0e538740b46ab4446a93508d7ed08389, type: 3} | |||||
m_ShaderKeywords: | |||||
m_LightmapFlags: 5 | |||||
m_CustomRenderQueue: -1 | |||||
stringTagMap: {} | |||||
m_SavedProperties: | |||||
serializedVersion: 2 | |||||
m_TexEnvs: | |||||
- first: | |||||
name: _MainTex | |||||
second: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
m_Floats: | |||||
- first: | |||||
name: _Divide | |||||
second: 7303 | |||||
m_Colors: [] |
@ -0,0 +1,8 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 92dc32887d2555f469466609a34e858c | |||||
timeCreated: 1499305061 | |||||
licenseType: Store | |||||
NativeFormatImporter: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,58 @@ | |||||
Shader "Fog Volume/RT viewers/_ShadowTexture" | |||||
{ | |||||
Properties{ | |||||
_MainTex("Base", 2D) = "" {} | |||||
_Divide("Divide", Range(1, 30000))=1000 | |||||
} | |||||
SubShader | |||||
{ | |||||
Tags { "RenderType"="Opaque" } | |||||
LOD 100 | |||||
Pass | |||||
{ | |||||
CGPROGRAM | |||||
#pragma vertex vert | |||||
#pragma fragment frag | |||||
#include "UnityCG.cginc" | |||||
struct appdata | |||||
{ | |||||
float4 vertex : POSITION; | |||||
float2 uv : TEXCOORD0; | |||||
}; | |||||
struct v2f | |||||
{ | |||||
float2 uv : TEXCOORD0; | |||||
float4 vertex : SV_POSITION; | |||||
}; | |||||
sampler2D _ShadowTexture; | |||||
float4 _ShadowTexture_ST; | |||||
fixed _Divide; | |||||
v2f vert (appdata v) | |||||
{ | |||||
v2f o; | |||||
o.vertex = UnityObjectToClipPos(v.vertex); | |||||
o.uv = TRANSFORM_TEX(v.uv, _ShadowTexture); | |||||
return o; | |||||
} | |||||
fixed4 frag (v2f i) : SV_Target | |||||
{ | |||||
// sample the texture | |||||
//fixed4 col = tex2D(_ShadowTexture, i.uv).r/ _Divide; | |||||
fixed4 col = tex2D(_ShadowTexture, i.uv); | |||||
col.r = col.r / _Divide; | |||||
return col.r*col.g; | |||||
} | |||||
ENDCG | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,9 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 0e538740b46ab4446a93508d7ed08389 | |||||
timeCreated: 1488040482 | |||||
licenseType: Store | |||||
ShaderImporter: | |||||
defaultTextures: [] | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,8 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 4e658522ff42fbc42a2a05957d204a33 | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,8 @@ | |||||
public enum EFogVolumeLightType | |||||
{ | |||||
None = 0, | |||||
FogVolumePointLight, | |||||
FogVolumeSpotLight, | |||||
PointLight, | |||||
SpotLight | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: e821da77bc9507e4f902de699d582090 | |||||
timeCreated: 1501009162 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,8 @@ | |||||
public enum EFogVolumePrimitiveType | |||||
{ | |||||
Box = 0, | |||||
Sphere = 1, | |||||
None = 2 | |||||
} |
@ -0,0 +1,3 @@ | |||||
fileFormatVersion: 2 | |||||
guid: b565090fc25f4f07b7ef4625c6ac06a1 | |||||
timeCreated: 1512376752 |
@ -0,0 +1,8 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 3f5ea8f1dcc137848a4ed67a53b386d3 | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,62 @@ | |||||
using System.Collections; | |||||
using System.Collections.Generic; | |||||
using UnityEngine; | |||||
using UnityEditorInternal; | |||||
using UnityEditor; | |||||
[CustomEditor(typeof(FogVolumeData))] | |||||
public class FogVolumeDataEditor : Editor | |||||
{ | |||||
FogVolumeData _target; | |||||
void OnEnable() | |||||
{ | |||||
_target = (FogVolumeData)target; | |||||
} | |||||
private static bool SHOW_DEBUG_DATA | |||||
{ | |||||
get { return EditorPrefs.GetBool("SHOW_DEBUG_DATATab", false); } | |||||
set { EditorPrefs.SetBool("SHOW_DEBUG_DATATab", value); } | |||||
} | |||||
public override void OnInspectorGUI() | |||||
{ | |||||
serializedObject.Update(); | |||||
EditorGUI.BeginChangeCheck(); | |||||
GUILayout.Space(10); | |||||
_target.GameCamera = (Camera)EditorGUILayout.ObjectField("Game Camera", _target.GameCamera, typeof(Camera), true); | |||||
_target.ForceNoRenderer = EditorGUILayout.Toggle("Disable Camera script", _target.ForceNoRenderer); | |||||
GUILayout.Space(10); | |||||
if (GUILayout.Button("DEBUG DATA", EditorStyles.toolbarButton)) | |||||
SHOW_DEBUG_DATA = !SHOW_DEBUG_DATA; | |||||
if (SHOW_DEBUG_DATA) | |||||
{ | |||||
var FoundCameras = serializedObject.FindProperty("FoundCameras"); | |||||
GUILayout.BeginVertical("box"); | |||||
EditorGUI.indentLevel++; | |||||
EditorGUILayout.PropertyField(FoundCameras, new GUIContent("Available Cameras:"), true); | |||||
EditorGUI.indentLevel--; | |||||
GUILayout.EndVertical(); | |||||
var SceneFogVolumes = serializedObject.FindProperty("SceneFogVolumes"); | |||||
GUILayout.BeginVertical("box"); | |||||
EditorGUI.indentLevel++; | |||||
EditorGUILayout.PropertyField(SceneFogVolumes, new GUIContent("Available Fog Volumes:"), true); | |||||
EditorGUI.indentLevel--; | |||||
GUILayout.EndVertical(); | |||||
} | |||||
EditorGUI.EndChangeCheck(); | |||||
if (GUI.changed) | |||||
{ | |||||
Undo.RecordObject(target, "Fog volume Data modified"); | |||||
EditorUtility.SetDirty(target); | |||||
} | |||||
serializedObject.ApplyModifiedProperties(); | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 67c6279c882435349837b0230f66338b | |||||
timeCreated: 1490476289 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,162 @@ | |||||
using UnityEngine; | |||||
using UnityEditor; | |||||
[CustomEditor(typeof(FogVolumeDirectionalLight))] | |||||
public class FogVolumeDirectionalLightEditor : Editor | |||||
{ | |||||
FogVolumeDirectionalLight _target; | |||||
void OnEnable() | |||||
{ | |||||
_target = (FogVolumeDirectionalLight)target; | |||||
} | |||||
GUIContent VariableField(string VariableName, string Tooltip) | |||||
{ | |||||
return new GUIContent(VariableName, Tooltip); | |||||
} | |||||
private static bool SHOW_DEBUG_Options | |||||
{ | |||||
get { return EditorPrefs.GetBool("SHOW_FV_DIR_LIGHT_DEBUG_OptionsTab", false); } | |||||
set { EditorPrefs.SetBool("SHOW_FV_DIR_LIGHT_DEBUG_OptionsTab", value); } | |||||
} | |||||
public override void OnInspectorGUI() | |||||
{ | |||||
serializedObject.Update(); | |||||
EditorGUI.BeginChangeCheck(); | |||||
Undo.RecordObject(_target, "Fog volume directional light modified"); | |||||
GUILayout.Space(10); | |||||
GUILayout.BeginVertical("box"); | |||||
if (_target._ProminentFogVolume == null) | |||||
GUI.color = Color.red; | |||||
// _target._TargetFogVolume = (FogVolume)EditorGUILayout.ObjectField("Target Fog Volume", _target._TargetFogVolume, typeof(FogVolume), true); | |||||
var FogVolumes = serializedObject.FindProperty("_TargetFogVolumes"); | |||||
EditorGUI.indentLevel++; | |||||
EditorGUILayout.PropertyField(FogVolumes, new GUIContent("Target Fog Volume"), true); | |||||
EditorGUI.indentLevel--; | |||||
GUI.color = Color.white; | |||||
GUI.color = new Color(.9f, 1, .9f); | |||||
if (GUILayout.Button("Add all Fog Volumes" /*GUILayout.Width(100)*/)) | |||||
{ | |||||
_target.AddAllFogVolumesToThisLight(); | |||||
_target.Refresh(); | |||||
_target.Render(); | |||||
} | |||||
if (GUILayout.Button("Remove all Fog Volumes" /*GUILayout.Width(100)*/)) | |||||
{ | |||||
_target.RemoveAllFogVolumesFromThisLight(); | |||||
_target.Refresh(); | |||||
_target.Render(); | |||||
} | |||||
GUI.color = Color.white; | |||||
_target._CameraVerticalPosition = EditorGUILayout.FloatField(VariableField | |||||
("Shadow camera distance", "This is the distance from the shadow camera to the focus point. Increase it if the scene area you want to shade is not completely visible in the shadowmap"), _target._CameraVerticalPosition); | |||||
_target.Size = (FogVolumeDirectionalLight.Resolution)EditorGUILayout.EnumPopup("Resolution", _target.Size); | |||||
_target._Antialiasing = (FogVolumeDirectionalLight.Antialiasing)EditorGUILayout.EnumPopup("Antialiasing", _target._Antialiasing); | |||||
_target._UpdateMode = (FogVolumeDirectionalLight.UpdateMode)EditorGUILayout.EnumPopup(VariableField("Update mode", "OnStart: bake shadowmap on start\nInterleaved: skip frames"), _target._UpdateMode); | |||||
if (_target._UpdateMode == FogVolumeDirectionalLight.UpdateMode.Interleaved) | |||||
_target.SkipFrames = EditorGUILayout.IntSlider(VariableField("Skip frames", "Instead updating per-frame, we can skip frames before updating the shadow"), _target.SkipFrames, 0, 10); | |||||
else | |||||
{ | |||||
GUI.color = new Color(.9f, 1, .9f); | |||||
if (GUILayout.Button("Refresh" /*GUILayout.Width(100)*/)) | |||||
{ | |||||
_target.Refresh(); | |||||
_target.Render(); | |||||
_target.Render(); | |||||
} | |||||
GUI.color = Color.white; | |||||
} | |||||
Rect LayerFieldRect = GUILayoutUtility.GetRect(GUIContent.none, GUIStyle.none, GUILayout.Height(20)); | |||||
if (_target.ShadowCamera != null && _target.ShadowCamera.cullingMask == 0) | |||||
GUI.color = Color.red; | |||||
_target.LayersToRender = FogVolumeUtilities.EditorExtension.DrawLayerMaskField(LayerFieldRect, _target.LayersToRender, new GUIContent("Layers to render")); | |||||
GUI.color = Color.white; | |||||
_target._ScaleMode = (FogVolumeDirectionalLight.ScaleMode)EditorGUILayout.EnumPopup(VariableField("Scale mode", | |||||
"With VolumeX, the camera will take the volume scale.x to adjust its size\nSet it to manual to adjust this size yourself. Useful when you have a large volume and only want to have good shadows at the focus point"), _target._ScaleMode); | |||||
if (_target._ScaleMode == FogVolumeDirectionalLight.ScaleMode.Manual && _target._ProminentFogVolume != null) | |||||
_target.Scale = EditorGUILayout.Slider(VariableField("Zoom", "Scale the view range of the camera.\n It will use the volume size from position 0"), _target.Scale, 10, _target._ProminentFogVolume.fogVolumeScale.x); | |||||
_target._FocusMode = (FogVolumeDirectionalLight.FocusMode)EditorGUILayout.EnumPopup(VariableField("Focus mode", "The camera will focus on the given position. If the volume is not too large the best option would be Volume center"), _target._FocusMode); | |||||
if (_target._FocusMode == FogVolumeDirectionalLight.FocusMode.GameObject) | |||||
_target._GameObjectFocus = (Transform)EditorGUILayout.ObjectField(VariableField("Focus point", "Gameobject used to focus the shadow camera"), _target._GameObjectFocus, typeof(Transform), true); | |||||
_target._FogVolumeShadowMapEdgeSoftness = EditorGUILayout.Slider(VariableField("Edge softness", "Fading range for the edges of the shadowmap"), | |||||
_target._FogVolumeShadowMapEdgeSoftness, .001f, 1); | |||||
GUILayout.EndVertical();//end box | |||||
#region Debug | |||||
GUILayout.BeginVertical("box"); | |||||
if (GUILayout.Button("Debug options", EditorStyles.toolbarButton)) | |||||
SHOW_DEBUG_Options = !SHOW_DEBUG_Options; | |||||
if (SHOW_DEBUG_Options) | |||||
{ | |||||
_target.CameraVisible = EditorGUILayout.Toggle(VariableField("Show shadow map camera", "Not updating correctly until we click on the hierarchy window :/"), _target.CameraVisible); | |||||
if (_target.GOShadowCamera && _target.GOShadowCamera.hideFlags == HideFlags.HideInHierarchy && _target.CameraVisible) | |||||
{ | |||||
_target.GOShadowCamera.hideFlags = HideFlags.None; | |||||
EditorApplication.RepaintHierarchyWindow(); | |||||
EditorApplication.DirtyHierarchyWindowSorting(); | |||||
} | |||||
if (_target.GOShadowCamera && _target.GOShadowCamera.hideFlags == HideFlags.None && !_target.CameraVisible) | |||||
{ | |||||
_target.GOShadowCamera.hideFlags = HideFlags.HideInHierarchy; | |||||
EditorApplication.RepaintHierarchyWindow(); | |||||
EditorApplication.DirtyHierarchyWindowSorting(); | |||||
} | |||||
_target.ShowMiniature = EditorGUILayout.Toggle("View depth map", _target.ShowMiniature); | |||||
EditorGUI.indentLevel++; | |||||
if (_target.ShowMiniature) | |||||
_target.MiniaturePosition = EditorGUILayout.Vector2Field("Position", _target.MiniaturePosition); | |||||
EditorGUI.indentLevel--; | |||||
} | |||||
EditorGUI.EndChangeCheck(); | |||||
GUI.color = Color.green; | |||||
if (_target._ProminentFogVolume == null) | |||||
EditorGUILayout.HelpBox("Add a Fog Volume now", MessageType.Info); | |||||
if (_target._ProminentFogVolume != null && _target.ShadowCamera != null && _target.ShadowCamera.cullingMask == 0) | |||||
EditorGUILayout.HelpBox("Set the layers used to cast shadows", MessageType.Info); | |||||
GUI.color = Color.white; | |||||
GUI.color = Color.red; | |||||
if (_target._TargetFogVolumes != null) | |||||
{ | |||||
foreach (FogVolume fv in _target._TargetFogVolumes) | |||||
{ | |||||
if (fv != null) | |||||
if (fv._FogType == FogVolume.FogType.Uniform) | |||||
{ | |||||
EditorGUILayout.HelpBox(fv.name + | |||||
" Is not a valid Volume. It has to be textured (must use gradient or noise)", | |||||
MessageType.Info); | |||||
} | |||||
} | |||||
} | |||||
GUI.color = Color.white; | |||||
GUI.color = Color.red; | |||||
if (_target._FocusMode == FogVolumeDirectionalLight.FocusMode.GameObject && _target._GameObjectFocus == null) | |||||
EditorGUILayout.HelpBox("Set the focus point object", MessageType.Info); | |||||
GUI.color = Color.white; | |||||
EditorGUILayout.HelpBox("Initial version, experimental", MessageType.Info); | |||||
GUILayout.EndVertical();//end box | |||||
#endregion | |||||
if (GUI.changed) | |||||
{ | |||||
EditorUtility.SetDirty(target); | |||||
} | |||||
serializedObject.ApplyModifiedProperties(); | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 42de5d3f2cc8e2445a7b71d151382ce0 | |||||
timeCreated: 1499486407 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,816 @@ | |||||
using UnityEditor; | |||||
using UnityEngine; | |||||
using System.Collections; | |||||
using UnityEditorInternal; | |||||
using System.IO; | |||||
[CustomEditor(typeof(FogVolume))] | |||||
public class FogVolumeEditor : Editor | |||||
{ | |||||
#region Variables | |||||
private static bool ShowInspectorTooltips | |||||
{ | |||||
get { return EditorPrefs.GetBool("ShowInspectorTooltips", true); } | |||||
set { EditorPrefs.SetBool("ShowInspectorTooltips", value); } | |||||
} | |||||
FogVolume _target; | |||||
private const string _showCustomizationOptions = "showCustomizationOptions"; | |||||
private GUIStyle Theme1, ThemeFooter; | |||||
#endregion | |||||
//Texture2D[] _InspectorBackground; | |||||
void OnEnable() | |||||
{ | |||||
_target = (FogVolume)target; | |||||
string m_ScriptFilePath; | |||||
string BackgroundImagesPath; | |||||
MonoScript ms = MonoScript.FromScriptableObject(this); | |||||
m_ScriptFilePath = AssetDatabase.GetAssetPath(ms); | |||||
FileInfo fi = new FileInfo(m_ScriptFilePath); | |||||
BackgroundImagesPath = fi.Directory.ToString(); | |||||
BackgroundImagesPath= BackgroundImagesPath.Replace("\\", "/"); | |||||
BackgroundImagesPath += "/Themes/png"; | |||||
_target.BackgroundImagesPath = BackgroundImagesPath; | |||||
int ImageIndex = 0; | |||||
foreach (string filePath in System.IO.Directory.GetFiles(BackgroundImagesPath)) | |||||
{ | |||||
if (!filePath.Contains(".meta")) | |||||
// print(filePath); | |||||
ImageIndex++; | |||||
} | |||||
_target._InspectorBackground = null; | |||||
_target._InspectorBackground = new Texture2D[ImageIndex]; | |||||
// print(ImageIndex); | |||||
int i = 0; | |||||
foreach (string filePath in System.IO.Directory.GetFiles(BackgroundImagesPath)) | |||||
{ | |||||
if (!filePath.Contains(".meta")) | |||||
{ | |||||
byte[] fileData; | |||||
// print(filePath); | |||||
fileData = File.ReadAllBytes(filePath); | |||||
//init | |||||
Texture2D tex = new Texture2D(1, 32, TextureFormat.RHalf, false, true); | |||||
tex.filterMode = FilterMode.Trilinear; | |||||
tex.LoadImage(fileData); | |||||
_target._InspectorBackground[i] = tex; | |||||
i++; | |||||
} | |||||
} | |||||
Theme1 = new GUIStyle(); | |||||
ThemeFooter = new GUIStyle(); | |||||
// ThemeFooter.normal.background = MakeTex(new Color(.31f, 0.2f, .3f)); | |||||
if (EditorGUIUtility.isProSkin) | |||||
ThemeFooter.normal.background = (Texture2D)Resources.Load("RendererInspectorBodyBlack"); | |||||
else | |||||
ThemeFooter.normal.background = (Texture2D)Resources.Load("RendererInspectorBodyBright"); | |||||
} | |||||
GUIContent VariableField(string VariableName, string Tooltip) | |||||
{ | |||||
return new GUIContent(VariableName, ShowInspectorTooltips ? Tooltip : ""); | |||||
} | |||||
public override bool RequiresConstantRepaint() { return true; } | |||||
public override void OnInspectorGUI() | |||||
{ | |||||
GUILayout.Space(10); | |||||
serializedObject.Update(); | |||||
GUI.color = Color.white; | |||||
GUILayout.BeginVertical(Theme1); | |||||
//some info about fog type | |||||
EditorGUI.BeginChangeCheck(); | |||||
Undo.RecordObject(target, "Fog volume parameter"); | |||||
#region Basic | |||||
// _target.bias = EditorGUILayout.Slider("bias", _target.bias, 0, 1); | |||||
//_target.RenderableInSceneView Rod, lo moví pabajo, a other/rendering options | |||||
if (_target._FogType == FogVolume.FogType.Textured) | |||||
{ | |||||
_target.FogMainColor = EditorGUILayout.ColorField(new GUIContent("Light energy", ShowInspectorTooltips ? "Multiplies all lighting contributions" : ""), _target.FogMainColor); | |||||
_target.bVolumeFog = EditorGUILayout.Toggle(VariableField("Volume Fog", "Fills the empty space left by noise with volumetric fog. This fog allows the use of pointlights and shadows"), _target.bVolumeFog); | |||||
} | |||||
else | |||||
_target.FogMainColor = EditorGUILayout.ColorField("Color", _target.FogMainColor); | |||||
if (!_target.EnableNoise && !_target.EnableGradient || _target.bVolumeFog) | |||||
_target.Visibility = EditorGUILayout.FloatField(VariableField("Visibility", "Fog Visibility") , _target.Visibility); | |||||
_target.fogVolumeScale = EditorGUILayout.Vector3Field("Size", _target.fogVolumeScale); | |||||
if (_target._FogType == FogVolume.FogType.Textured) | |||||
{ | |||||
if (_target.bVolumeFog) | |||||
{ | |||||
GUILayout.BeginVertical("box"); | |||||
_target._FogColor = EditorGUILayout.ColorField("Volume Fog Color", _target._FogColor); | |||||
_target._AmbientAffectsFogColor = EditorGUILayout.Toggle(VariableField("Apply ambient color", "Use ambient color and proxy volume to multiply this color"), _target._AmbientAffectsFogColor); | |||||
GUILayout.EndVertical();//end box | |||||
} | |||||
} | |||||
if(_target._FogType == FogVolume.FogType.Textured)//3.1.9 Hide if Uniform. Its going to be hardcoded as "Traditional" | |||||
_target._BlendMode = (FogVolumeRenderer.BlendMode)EditorGUILayout.EnumPopup(VariableField("Blend Mode", "Choose between standard of premultiplied alpha blend"), _target._BlendMode); | |||||
#endregion | |||||
#region lighting | |||||
//GUILayout.BeginHorizontal("toolbarbutton"); | |||||
//EditorGUILayout.LabelField("Lighting"); | |||||
//showLighting = EditorGUILayout.Toggle("Show", showLighting); | |||||
//GUILayout.EndHorizontal(); | |||||
//if (_target.EnableNoise /*|| _target.EnableGradient*/) | |||||
if (GUILayout.Button("Lighting", EditorStyles.toolbarButton)) | |||||
_target.showLighting = !_target.showLighting; | |||||
if (_target.showLighting) | |||||
{ | |||||
if (_target._FogType == FogVolume.FogType.Textured) | |||||
{ | |||||
GUILayout.BeginVertical("box"); | |||||
_target._AmbientColor = EditorGUILayout.ColorField(VariableField("Ambient", "Ambient is added as first light contribution. Alpha is used for volumetric shadows ambient amount"), _target._AmbientColor); | |||||
_target.Absorption = EditorGUILayout.Slider(VariableField("Absorption", "How much ambient light is absorbed by noise. Depends on noise density"), _target.Absorption, 0, 1); | |||||
if (_target.useHeightGradient) | |||||
{ | |||||
_target.HeightAbsorption = EditorGUILayout.Slider(VariableField("Height Absorption", "Multiplies lighting contributoins with height gradient 1"), _target.HeightAbsorption, 0, 1); | |||||
} | |||||
GUILayout.EndVertical(); | |||||
if (_target.EnableNoise) | |||||
{ | |||||
string HeightAbsorptionTooltip = "Define a height gradient to attenuate lighting. To disable, set both sliders to -1"; | |||||
EditorGUILayout.LabelField(VariableField("Height absorption gradient", HeightAbsorptionTooltip), EditorStyles.boldLabel); | |||||
GUILayout.BeginVertical("box"); | |||||
_target.HeightAbsorptionMin = EditorGUILayout.Slider(VariableField("min", HeightAbsorptionTooltip), _target.HeightAbsorptionMin, -1, 1); | |||||
_target.HeightAbsorptionMax = EditorGUILayout.Slider(VariableField("max", HeightAbsorptionTooltip), _target.HeightAbsorptionMax, -1, 1); | |||||
GUILayout.EndVertical(); | |||||
} | |||||
// if( GUILayout.Button(_target.bAbsorption.ToString())) | |||||
// _target.bAbsorption = !_target.bAbsorption; | |||||
// else | |||||
// _target.bAbsorption = false; | |||||
// | |||||
// Debug.Log(_target.bAbsorption); | |||||
if (_target.Absorption == 0) | |||||
_target.bAbsorption = false; | |||||
else | |||||
_target.bAbsorption = true; | |||||
} | |||||
_target.Sun = (Light)EditorGUILayout.ObjectField("Sun Light", _target.Sun, typeof(Light), true); | |||||
if (_target.Sun != null) | |||||
{ | |||||
if (_target._FogType == FogVolume.FogType.Textured) | |||||
_target._LightExposure = EditorGUILayout.Slider(VariableField("Light Exposure", "Overrides light intensity"), _target._LightExposure, 1, 5); | |||||
if (_target.EnableNoise) | |||||
{ | |||||
GUILayout.BeginVertical("box"); | |||||
_target.Lambert = EditorGUILayout.Toggle(VariableField("Lambertian", "Computes lambert lighting. Disabled by default\n uncomment //#pragma shader_feature _LAMBERT_SHADING in FogVolume.shader to enable"), _target.Lambert); | |||||
if (_target.Lambert) | |||||
{ | |||||
_target.DirectLightingAmount = EditorGUILayout.Slider("Amount", _target.DirectLightingAmount, .01f, 10f); | |||||
_target.LambertianBias = EditorGUILayout.Slider("Lambertian Bias", _target.LambertianBias, .5f, 1); | |||||
_target.NormalDistance = EditorGUILayout.Slider("Normal detail", _target.NormalDistance, .01f, .0001f); | |||||
_target.DirectLightingDistance = EditorGUILayout.FloatField("Distance", _target.DirectLightingDistance); | |||||
} | |||||
GUILayout.EndVertical(); | |||||
} | |||||
#region VolumeFogInscattering | |||||
if (_target._FogType == FogVolume.FogType.Textured) | |||||
if (_target.bVolumeFog) | |||||
{ | |||||
GUILayout.BeginVertical("box"); | |||||
_target.VolumeFogInscattering = EditorGUILayout.Toggle(VariableField("Volume Fog Inscattering", "Computes phase function in fog"), _target.VolumeFogInscattering); | |||||
if (_target.VolumeFogInscattering && _target.bVolumeFog) | |||||
{ | |||||
_target.VolumeFogInscatteringColor = EditorGUILayout.ColorField("Color", _target.VolumeFogInscatteringColor); | |||||
_target.VolumeFogInscatterColorAffectedWithFogColor = EditorGUILayout.Toggle(VariableField("Tint with fog color", "Off: reacts additively\nOn: incident light is tinted with the given fog color"), _target.VolumeFogInscatterColorAffectedWithFogColor); | |||||
_target.VolumeFogInscatteringAnisotropy = EditorGUILayout.Slider(VariableField("Anisotropy", "Balance of forward and back scattering"), _target.VolumeFogInscatteringAnisotropy, -1, 1); | |||||
_target.VolumeFogInscatteringIntensity = EditorGUILayout.Slider("Intensity", _target.VolumeFogInscatteringIntensity, 0, 1); | |||||
_target.VolumeFogInscatteringStartDistance = EditorGUILayout.FloatField("Start Distance", _target.VolumeFogInscatteringStartDistance); | |||||
_target.VolumeFogInscatteringTransitionWideness = EditorGUILayout.FloatField("Transition Wideness", _target.VolumeFogInscatteringTransitionWideness); | |||||
} | |||||
GUILayout.EndVertical(); | |||||
} | |||||
#endregion | |||||
#region Inscattering | |||||
// if (_target.NoiseIntensity > 0) | |||||
// { | |||||
GUILayout.BeginVertical("box"); | |||||
_target.EnableInscattering = EditorGUILayout.Toggle(VariableField("Inscattering", "Computes phase function in noise. It is affected by absorption"), _target.EnableInscattering); | |||||
if (_target.EnableInscattering) | |||||
{ | |||||
_target.InscatteringColor = EditorGUILayout.ColorField("Color", _target.InscatteringColor); | |||||
_target.InscatteringShape = EditorGUILayout.Slider(VariableField("Anisotropy", "Balance of forward and back scattering"), _target.InscatteringShape, -1, 1); | |||||
_target.InscatteringIntensity = EditorGUILayout.Slider("Intensity", _target.InscatteringIntensity, 0, 1); | |||||
_target.InscatteringStartDistance = EditorGUILayout.FloatField("Start Distance", _target.InscatteringStartDistance); | |||||
_target.InscatteringTransitionWideness = EditorGUILayout.FloatField("Transition Wideness", _target.InscatteringTransitionWideness); | |||||
} | |||||
GUILayout.EndVertical(); | |||||
// } | |||||
// else | |||||
// _target.EnableInscattering = false; | |||||
#endregion | |||||
if (_target.EnableNoise && _target._NoiseVolume != null) | |||||
{ | |||||
GUILayout.BeginVertical("box"); | |||||
_target._DirectionalLighting = EditorGUILayout.Toggle(VariableField("Directional Lighting", "Light is absorbed along light direction. Looks like sub-surface scattering"), _target._DirectionalLighting); | |||||
if (_target._DirectionalLighting) | |||||
{ | |||||
_target.LightExtinctionColor = EditorGUILayout.ColorField(VariableField("Extinction Color", "The color of the light after full absorption"), _target.LightExtinctionColor); | |||||
// _target.DirectionalLightingClamp= EditorGUILayout.Slider(VariableField("Clamp", "Limit the maximum extiction"), _target.DirectionalLightingClamp, 1,5); | |||||
_target._DirectionalLightingDistance = EditorGUILayout.Slider(VariableField("Distance", "Distance between samples"), _target._DirectionalLightingDistance, 0, 2.0f); | |||||
_target.DirectLightingShadowDensity = EditorGUILayout.Slider(VariableField("Density", "Amount of light being absorbed"), _target.DirectLightingShadowDensity, 0, 15); | |||||
_target.DirectLightingShadowSteps = EditorGUILayout.IntSlider(VariableField("Iterations", "How many times to compute. Each iteration computes noise one more time causing dramatical performance hits"), _target.DirectLightingShadowSteps, 1, 5); | |||||
} | |||||
GUILayout.EndVertical(); | |||||
} | |||||
} | |||||
if (_target.EnableNoise && _target.Sun) | |||||
{ | |||||
GUILayout.BeginVertical("box"); | |||||
_target._ShadeNoise = EditorGUILayout.Toggle(VariableField("Self shadow", "Computes directional shadows. \n It has high performance impact"), _target._ShadeNoise); | |||||
if (_target._ShadeNoise) | |||||
{ | |||||
// _target.Shade = EditorGUILayout.Slider("Shadow intensity", _target.Shade, 0, 1); | |||||
_target.ShadowShift = EditorGUILayout.Slider(VariableField("Shadow distance", "Distance between samples"), _target.ShadowShift, .0f, 2); | |||||
_target._SelfShadowSteps = EditorGUILayout.IntSlider("Iterations", _target._SelfShadowSteps, 1, 20); | |||||
_target._SelfShadowColor = EditorGUILayout.ColorField(VariableField("Shadow color", "Ambient color x Shadow color"), _target._SelfShadowColor); | |||||
} | |||||
GUILayout.EndVertical(); | |||||
} | |||||
// | |||||
if (_target._FogType == FogVolume.FogType.Textured) | |||||
{ | |||||
if (_target.FogRenderer.shadowCastingMode == UnityEngine.Rendering.ShadowCastingMode.On || | |||||
_target.FogRenderer.receiveShadows == true) | |||||
{ | |||||
GUILayout.BeginVertical("box"); | |||||
EditorGUILayout.LabelField("Opacity shadow map", EditorStyles.boldLabel); | |||||
// _target.CastShadows = EditorGUILayout.Toggle("Cast Shadows", _target.CastShadows);//lets control it trough the renderer | |||||
if (_target.Sun && _target.CastShadows)//casi mejor que un droplist | |||||
{ | |||||
//tempShadowCaster = _target.CastShadows; | |||||
_target.ShadowCameraPosition = EditorGUILayout.IntField(VariableField("Vertical Offset", "Distance of the shadow camera. Use the prefab RT Viewer to see the result"), _target.ShadowCameraPosition); | |||||
_target.SunAttached = EditorGUILayout.Toggle(VariableField("Attach light", "The assigned light will inherit the volume rotation. This is useful to cast fake shadows with noise. Check the scene Sunset to see this in action"), _target.SunAttached); | |||||
_target.ShadowColor = EditorGUILayout.ColorField("Shadow Color", _target.ShadowColor); | |||||
_target._ShadowCamera.textureSize = (ShadowCamera.TextureSize)EditorGUILayout.EnumPopup(VariableField("Resolution", "Resolution of the shadow map"), _target._ShadowCamera.textureSize); | |||||
_target.ShadowCameraSkippedFrames = EditorGUILayout.IntSlider(VariableField("Skip frames", "Skip frames to reduce costs"), _target.ShadowCameraSkippedFrames, 0, 10); | |||||
GUILayout.BeginVertical("box"); | |||||
EditorGUILayout.LabelField("Convolution", EditorStyles.boldLabel); | |||||
_target._ShadowCamera.iterations = EditorGUILayout.IntSlider("Iterations", _target._ShadowCamera.iterations, 0, 5); | |||||
if (_target._ShadowCamera.iterations > 0) | |||||
_target._ShadowCamera.Downsampling = EditorGUILayout.IntSlider("Downsampling", _target._ShadowCamera.Downsampling, 0, 5); | |||||
if (_target._ShadowCamera.iterations > 1) | |||||
_target._ShadowCamera.blurSpread = EditorGUILayout.Slider("Radius", _target._ShadowCamera.blurSpread, 0, 1); | |||||
GUILayout.EndVertical(); | |||||
} | |||||
else | |||||
{ | |||||
if (_target.FogRenderer.receiveShadows) | |||||
_target.ShadowCaster = (FogVolume)EditorGUILayout.ObjectField(VariableField("Shadowmap coming from:", "Assign here the fog volume that is used to cast shadows"), _target.ShadowCaster, typeof(FogVolume), true); | |||||
if (_target.ShadowCaster != null) | |||||
_target.CastShadows = false; | |||||
// tempShadowCaster = _target.CastShadows; | |||||
} | |||||
if (_target.CastShadows == false && _target.FogRenderer.receiveShadows) | |||||
{ | |||||
_target.UseConvolvedLightshafts = EditorGUILayout.Toggle(VariableField("Use convolved lightshaft", "You can select here if you want to use the blurred shadow"), _target.UseConvolvedLightshafts); | |||||
_target.ShadowCutoff = EditorGUILayout.Slider(VariableField("Shadow Cutoff", "Apply contrast to the sampled shadow"), _target.ShadowCutoff, 0.001f, 1); | |||||
} | |||||
GUILayout.EndVertical(); | |||||
} | |||||
//_target.RT_Opacity = (RenderTexture)EditorGUILayout.ObjectField("LightMapRT", _target.RT_Opacity, typeof(RenderTexture), false); | |||||
//_target._LightMapTex = (Texture2D)EditorGUILayout.ObjectField("LightMapTex", _target._LightMapTex, typeof(Texture2D), false); | |||||
} | |||||
else | |||||
_target.CastShadows = false; | |||||
if (_target.Sun && _target.EnableNoise) | |||||
{ | |||||
GUILayout.BeginVertical("box"); | |||||
_target.LightHalo = EditorGUILayout.Toggle("Halo", _target.LightHalo); | |||||
if (_target.LightHalo && _target.EnableNoise) | |||||
{ | |||||
_target._LightHaloTexture = (Texture2D)EditorGUILayout.ObjectField("Halo texture", _target._LightHaloTexture, typeof(Texture2D), true); | |||||
_target._HaloWidth = EditorGUILayout.Slider("Width", _target._HaloWidth, 0, 1); | |||||
_target._HaloRadius = EditorGUILayout.Slider("Radius", _target._HaloRadius, -5, 1); | |||||
_target._HaloAbsorption = EditorGUILayout.Slider(VariableField("Absorption", "How much is absorption affecting"), _target._HaloAbsorption, 0, 1); | |||||
// _target._HaloOpticalDispersion = EditorGUILayout.Slider("OpticalDispersion", _target._HaloOpticalDispersion, 0, 8); | |||||
_target._HaloIntensity = EditorGUILayout.Slider("Intensity", _target._HaloIntensity, 0, 1); | |||||
} | |||||
GUILayout.EndVertical(); | |||||
}//TODO. Halo should be always available | |||||
} | |||||
#endregion | |||||
#region PointLights | |||||
string PointLightTittle = ""; | |||||
if (SystemInfo.graphicsShaderLevel > 30) | |||||
PointLightTittle = "Lights"; | |||||
else | |||||
PointLightTittle = "Lights not available on this platform ";// + SystemInfo.graphicsShaderLevel; | |||||
if (_target._FogType == FogVolume.FogType.Textured) | |||||
if (GUILayout.Button(PointLightTittle, EditorStyles.toolbarButton)) | |||||
_target.showPointLights = !_target.showPointLights; | |||||
if (_target.showPointLights && | |||||
SystemInfo.graphicsShaderLevel > 30) | |||||
{ | |||||
_target.PointLightsActive = EditorGUILayout.Toggle("Enable", _target.PointLightsActive); | |||||
} | |||||
if (_target.showPointLights && _target.PointLightsActive) | |||||
if (_target._FogType == FogVolume.FogType.Textured) | |||||
{ | |||||
_target.PointLightsRealTimeUpdate = EditorGUILayout.Toggle(VariableField("Real-time search", "Fog Volume will search for lights in the scene hierarchy. \nEnable this for a brief moment if lights were added to the scene."), _target.PointLightsRealTimeUpdate); | |||||
_target.PointLightBoxCheck = EditorGUILayout.Toggle(VariableField("Inside box only", "Computes only lights that are inside of the volume boundaries. Turn off to compute lights that are outside of the volume"), _target.PointLightBoxCheck); | |||||
//GUILayout.BeginHorizon=tal("toolbarbutton"); | |||||
//EditorGUILayout.LabelField("Point lights"); | |||||
//GUILayout.EndHorizontal(); | |||||
_target._LightScatterMethod = (FogVolume.LightScatterMethod)EditorGUILayout.EnumPopup("Attenuation Method", _target._LightScatterMethod); | |||||
_target.PointLightsIntensity = EditorGUILayout.Slider("Intensity", _target.PointLightsIntensity, 0, 50); | |||||
_target.PointLightingDistance = Mathf.Max(1, _target.PointLightingDistance); | |||||
_target.PointLightingDistance = EditorGUILayout.FloatField(VariableField("Range clamp", "Use this parameter to limit the spherical distance of the pointlight so that it is not computed when attenuation is zero. Use it to improve performance"), _target.PointLightingDistance); | |||||
_target.PointLightingDistance2Camera = Mathf.Max(1, _target.PointLightingDistance2Camera); | |||||
_target.PointLightingDistance2Camera = EditorGUILayout.FloatField(VariableField("Draw distance", "Point-light is attenuated at the given distance and turned off as soon as that distance is exceeded"), _target.PointLightingDistance2Camera); | |||||
//_target.PointLightScreenMargin = EditorGUILayout.Slider("Discard margin", _target.PointLightScreenMargin, 0, 5);deprecated | |||||
_target.PointLightScreenMargin = 0; | |||||
_target.PointLightCullSizeMultiplier = EditorGUILayout.FloatField(VariableField("Light visibility", "The higher this value, the further the lights need to be offscreen in order to be discarded by the renderer."), _target.PointLightCullSizeMultiplier); | |||||
/* | |||||
if (!_target.PointLightsRealTimeUpdate) | |||||
{ | |||||
var FogLights = serializedObject.FindProperty("FogLights"); | |||||
GUILayout.BeginVertical("box"); | |||||
EditorGUI.indentLevel++; | |||||
EditorGUILayout.PropertyField(FogLights, new GUIContent | |||||
("Editable array"), true); | |||||
EditorGUI.indentLevel--; | |||||
GUILayout.EndVertical(); | |||||
} | |||||
var PointLightsList = serializedObject.FindProperty("PointLightsList"); | |||||
GUILayout.BeginVertical("box"); | |||||
EditorGUI.indentLevel++; | |||||
EditorGUILayout.PropertyField(PointLightsList, new GUIContent("Currently computed:"), true); | |||||
EditorGUI.indentLevel--; | |||||
GUILayout.EndVertical(); | |||||
*/ | |||||
int totalLightCount = _target.GetTotalLightCount(); | |||||
int visibleLightCount = _target.GetVisibleLightCount(); | |||||
EditorGUILayout.HelpBox("Contains " + totalLightCount + " lights", MessageType.None); | |||||
EditorGUILayout.HelpBox("Rendering " + visibleLightCount + " lights", MessageType.None); | |||||
} | |||||
#endregion | |||||
#region ColorManagement | |||||
//GUILayout.BeginHorizontal("toolbarbutton"); | |||||
//_target.ColorAdjust = EditorGUILayout.Toggle("Color Settings", _target.ColorAdjust); | |||||
//showColorTab = EditorGUILayout.Toggle(" Show \t ", showColorTab); | |||||
//GUILayout.EndHorizontal(); | |||||
if (GUILayout.Button(new GUIContent("Color management", ShowInspectorTooltips? "Color postprocessing such as contrast, brightness and tonemapper":"") , EditorStyles.toolbarButton)) | |||||
_target.showColorTab = !_target.showColorTab; | |||||
if (/*_target.ColorAdjust && */_target.showColorTab) | |||||
{ | |||||
_target.ColorAdjust = EditorGUILayout.Toggle("Active", _target.ColorAdjust); | |||||
_target.Offset = EditorGUILayout.Slider("Offset", _target.Offset, -.5f, .5f); | |||||
_target.Gamma = EditorGUILayout.Slider("Gamma", _target.Gamma, .01f, 3); | |||||
if (_target.ColorAdjust) | |||||
_target.Tonemap = EditorGUILayout.Toggle("Tonemap", _target.Tonemap); | |||||
if (_target.Tonemap && _target.ColorAdjust) | |||||
_target.Exposure = EditorGUILayout.Slider("Exposure", _target.Exposure, 2.5f, 5); | |||||
} | |||||
#endregion | |||||
#region Renderer | |||||
if (_target._FogType == FogVolume.FogType.Textured) | |||||
{ | |||||
// GUILayout.BeginHorizontal("toolbarbutton"); | |||||
// EditorGUILayout.LabelField("Volume properties"); | |||||
//showVolumeProperties = EditorGUILayout.Toggle("Show", showVolumeProperties); | |||||
// GUILayout.EndHorizontal(); | |||||
if (GUILayout.Button("Renderer", EditorStyles.toolbarButton)) | |||||
_target.showVolumeProperties = !_target.showVolumeProperties; | |||||
if (_target.showVolumeProperties) | |||||
{ | |||||
_target.NoiseIntensity = EditorGUILayout.Slider(VariableField("Intensity", "Opacity of noise and gradients"), _target.NoiseIntensity, 0, 1); | |||||
GUILayout.BeginVertical("box"); | |||||
_target.SceneCollision = EditorGUILayout.Toggle(VariableField("Scene Collision", "Textured fog will collide with environment when set to ON. _CameraDepthTexture is requierd for Scene view collisions. Enable Depth in camera script to generate the depth map required for Game view collisions. Disable if the volume is rendered in the background to avoid unneded computation"), _target.SceneCollision); | |||||
if (_target.SceneCollision) | |||||
_target._SceneIntersectionSoftness = EditorGUILayout.Slider(VariableField("Softness", "Pixels that get in contact with scene elements are faded to black. Use this slider to control the softeness of this transition"), _target._SceneIntersectionSoftness, 50, .01f); | |||||
GUILayout.EndVertical(); | |||||
_target._jitter = EditorGUILayout.Slider(VariableField("Jitter", "Apply noise to the sample position. Use this in combination with DeNoise (camera script) to conceal the gaps between samples"), _target._jitter, 0, .1f); | |||||
_target._SamplingMethod = (FogVolume.SamplingMethod)EditorGUILayout.EnumPopup(VariableField("Sampling Method", "Choose between distance to camera or view aligned planes. Hidden by default: uncomment #pragma shader_feature SAMPLING_METHOD_ViewAligned in FogVolume.shader"), _target._SamplingMethod); | |||||
_target.Iterations = EditorGUILayout.IntSlider(VariableField("Max Iterations", "Set the max iterations to perform."), _target.Iterations, 10, 1000); | |||||
_target.IterationStep = EditorGUILayout.FloatField(VariableField("Iteration step size", "Distance between iterations"), _target.IterationStep); | |||||
_target.FadeDistance = EditorGUILayout.FloatField(VariableField("Draw distance", "Noise is faded to black at the given distance. Loop will stop then"), _target.FadeDistance); | |||||
_target._OptimizationFactor = EditorGUILayout.Slider(VariableField("Optimization Factor", "Used to increase the distance between iterations so that we can have more quality at close distances. Far distances will be less opaque"), _target._OptimizationFactor, 0, 5e-09f); | |||||
if (_target.EnableNoise) | |||||
{ | |||||
GUILayout.BeginVertical("box"); | |||||
_target.useHeightGradient = EditorGUILayout.Toggle(VariableField("Height Gradient", "Noise opacity is multiplied with a vertical gradient"), _target.useHeightGradient); | |||||
if (_target.useHeightGradient) | |||||
{ | |||||
GUILayout.BeginVertical("box"); | |||||
_target.GradMin = EditorGUILayout.Slider("Grad 1 Min", _target.GradMin, -1, 1); | |||||
_target.GradMax = EditorGUILayout.Slider("Grad 1 Max", _target.GradMax, -1, 1); | |||||
GUILayout.EndVertical(); | |||||
GUILayout.BeginVertical("box"); | |||||
_target.GradMin2 = EditorGUILayout.Slider("Grad 2 Min", _target.GradMin2, -1, 1); | |||||
_target.GradMax2 = EditorGUILayout.Slider("Grad 2 Max", _target.GradMax2, -1, 1); | |||||
GUILayout.EndVertical(); | |||||
} | |||||
EditorGUILayout.EndVertical(); | |||||
} | |||||
if (_target.EnableNoise) | |||||
{ | |||||
GUILayout.BeginVertical("box"); | |||||
_target.bSphericalFade = EditorGUILayout.Toggle(VariableField("Radius Fade", "Multiplies noise opacity with a spherical range. Disabled by default. Uncomment #pragma shader_feature SPHERICAL_FADE in FogVolume.shader to enable"), _target.bSphericalFade); | |||||
if (_target.bSphericalFade) | |||||
{ | |||||
_target.SphericalFadeDistance = EditorGUILayout.FloatField("Distance", _target.SphericalFadeDistance); | |||||
} | |||||
EditorGUILayout.EndVertical(); | |||||
} | |||||
_target._DebugMode = (FogVolume.DebugMode)EditorGUILayout.EnumPopup(VariableField("View mode: ", "Disabled by default. Uncomment #pragma multi_compile _ DEBUG in FogVolume.shader"), _target._DebugMode); | |||||
//Primitives | |||||
GUILayout.BeginHorizontal("toolbarbutton"); | |||||
_target.EnableDistanceFields = EditorGUILayout.Toggle("Enable Primitives", _target.EnableDistanceFields); | |||||
if (_target.EnableDistanceFields && _target.GetTotalPrimitiveCount() > 0) | |||||
EditorGUILayout.LabelField(_target.GetVisiblePrimitiveCount() + " primitives visible | " + _target.GetTotalPrimitiveCount() + " primitives in volume"); | |||||
else | |||||
EditorGUILayout.LabelField("0 primitives visible | 0 primitives in volume"); | |||||
GUILayout.EndHorizontal(); | |||||
if (_target.EnableDistanceFields) | |||||
{ | |||||
GUILayout.BeginVertical("box"); | |||||
_target.ShowPrimitives = EditorGUILayout.Toggle(VariableField("Show primitives", "Enables the primitive renderer component"), _target.ShowPrimitives); | |||||
_target.PrimitivesRealTimeUpdate = EditorGUILayout.Toggle(VariableField("Real-time search", "Searches primitives that are inside of the volume. Turn on only to refresh the list"), _target.PrimitivesRealTimeUpdate); | |||||
EditorGUILayout.EndVertical(); | |||||
_target.Constrain = EditorGUILayout.Slider(VariableField("Size", "Overrides the primitive original size"), _target.Constrain, 0, -150); | |||||
_target._PrimitiveEdgeSoftener = EditorGUILayout.Slider(VariableField("Softness", "Softens the primitive shape"), _target._PrimitiveEdgeSoftener, 1, 100); | |||||
_target._PrimitiveCutout = EditorGUILayout.Slider(VariableField("Cutout", "Cuts the distance field with the primitive boundaries"), _target._PrimitiveCutout, 0, .99999f); | |||||
/* | |||||
var PrimitivesList = serializedObject.FindProperty("PrimitivesList"); | |||||
GUILayout.BeginVertical("box"); | |||||
EditorGUI.indentLevel++; | |||||
EditorGUILayout.PropertyField(PrimitivesList, true); | |||||
EditorGUI.indentLevel--; | |||||
EditorGUILayout.EndVertical(); | |||||
*/ | |||||
} | |||||
} | |||||
} | |||||
#endregion | |||||
#region Noise | |||||
if (GUILayout.Button("Noise", EditorStyles.toolbarButton)) | |||||
_target.showNoiseProperties = !_target.showNoiseProperties; | |||||
// GUILayout.BeginHorizontal("toolbarbutton"); | |||||
//EditorGUILayout.LabelField(""); | |||||
// showNoiseProperties = EditorGUILayout.Toggle(" Show", showNoiseProperties); | |||||
//GUILayout.EndHorizontal(); | |||||
if (/*_target.EnableNoise && */_target.showNoiseProperties) | |||||
{ | |||||
_target.EnableNoise = EditorGUILayout.Toggle("Active", _target.EnableNoise); | |||||
if (_target.EnableNoise) | |||||
{ | |||||
GUILayout.BeginVertical("Box"); | |||||
EditorGUILayout.LabelField("Common", EditorStyles.boldLabel); | |||||
//var TexturesRect = GUILayoutUtility.GetRect(new GUIContent(""), GUIStyle.none); | |||||
//EditorGUI.indentLevel++; | |||||
//_target.TexturesGroup = EditorGUI.Foldout(TexturesRect, _target.TexturesGroup, "Noise textures"); | |||||
//if (_target.TexturesGroup) | |||||
//{ | |||||
// _target._NoiseVolume = (Texture3D)EditorGUILayout.ObjectField("Base", _target._NoiseVolume, typeof(Texture3D), false); | |||||
// // _target._NoiseVolume2 = (Texture3D)EditorGUILayout.ObjectField("Detail", _target._NoiseVolume2, typeof(Texture3D), false); | |||||
// _target.CoverageTex = (Texture2D)EditorGUILayout.ObjectField(VariableField("Coverage (Experimental)", | |||||
// "Input texture to add or multiply coverage. This texture is sampled in the vertical axis. Uncomment #define COVERAGE in FogVolume.shader and test scene: Ocean"), _target.CoverageTex, typeof(Texture2D), false); | |||||
//} | |||||
//EditorGUI.indentLevel--; | |||||
// _target.CastShadows = tempShadowCaster; | |||||
_target._3DNoiseScale = EditorGUILayout.FloatField(VariableField("Scale", "Global size of all the noise layers"), _target._3DNoiseScale); | |||||
//_target.Procedural = EditorGUILayout.Toggle("Procedural", _target.Procedural); | |||||
// | |||||
#region Coordinates&Deformers | |||||
GUILayout.BeginVertical("box"); | |||||
EditorGUILayout.LabelField("Coordinates", EditorStyles.boldLabel); | |||||
_target.Speed = EditorGUILayout.Vector3Field("Scroll", _target.Speed); | |||||
_target.Stretch = EditorGUILayout.Vector3Field("Stretch", _target.Stretch); | |||||
GUILayout.EndVertical(); | |||||
GUILayout.BeginVertical("box"); | |||||
EditorGUILayout.LabelField("Deformers", EditorStyles.boldLabel); | |||||
_target.Vortex = EditorGUILayout.Slider(VariableField("Swirl", "Twist the space. Very useful to break tiling"), _target.Vortex, 0, 3); | |||||
if (_target.Vortex > 0) | |||||
{ | |||||
_target.RotationSpeed = EditorGUILayout.Slider("Rotation Speed", _target.RotationSpeed, 0, 10); | |||||
_target.rotation = EditorGUILayout.Slider("Rotation", _target.rotation, 0, 360); | |||||
_target._VortexAxis = (FogVolume.VortexAxis)EditorGUILayout.EnumPopup("Axis", _target._VortexAxis); | |||||
} | |||||
GUILayout.EndVertical(); | |||||
// | |||||
GUILayout.EndVertical(); | |||||
// GUILayout.EndVertical(); | |||||
#endregion | |||||
GUILayout.BeginVertical("Box"); | |||||
EditorGUILayout.LabelField("Base layer", EditorStyles.boldLabel); | |||||
_target.Coverage = EditorGUILayout.Slider(VariableField("Coverage", "Multiplies the base layer intensity. Lighting is affected as density increases"), _target.Coverage, 0, 5); | |||||
_target.NoiseContrast = EditorGUILayout.Slider(VariableField("Contrast", "Apply contrast to noise. High values creates more empty space, which is good for performance"), _target.NoiseContrast, 0, 20); | |||||
_target.NoiseDensity = EditorGUILayout.Slider(VariableField( | |||||
"Density", "Opacity of the final noise. This won't change the shape of the noise as Intensity does. It only affects the density / opacity of the noise"), | |||||
_target.NoiseDensity, 0, 20); | |||||
_target.Octaves = EditorGUILayout.IntSlider(VariableField("Octaves", "How many layers of noise to use"), _target.Octaves, 1, 5); | |||||
_target.BaseTiling = EditorGUILayout.FloatField(VariableField("Base Tiling", "Independent scale for this layer"), _target.BaseTiling); | |||||
_target._BaseRelativeSpeed = EditorGUILayout.Slider(VariableField("Speed", "Independent speed multiplier for this layer"), _target._BaseRelativeSpeed, 0, 4); | |||||
GUILayout.EndVertical(); | |||||
GUILayout.BeginVertical("Box"); | |||||
EditorGUILayout.LabelField("Detail layer", EditorStyles.boldLabel); | |||||
_target.DetailTiling = EditorGUILayout.FloatField("Tiling", _target.DetailTiling); | |||||
_target._DetailRelativeSpeed = EditorGUILayout.Slider("Speed", _target._DetailRelativeSpeed, 0, 20); | |||||
_target.DetailDistance = EditorGUILayout.FloatField(VariableField("Draw Distance", "This layer is a lot more costly than the base. Limit the draw distance to incerase performance"), _target.DetailDistance); | |||||
if (_target.DetailDistance > 0) | |||||
{ | |||||
_target._NoiseDetailRange = EditorGUILayout.Slider(VariableField("Trim", | |||||
"The detail layer is used to cut the base layer at the edges. If contrast is not too high, this will be more effective"), _target._NoiseDetailRange, 0, 1); | |||||
_target._DetailMaskingThreshold = EditorGUILayout.Slider(VariableField | |||||
("Trim Threshold", "Detail layer is applied only at the edges of the base layer. Use this slider to control the size of this edge"), | |||||
_target._DetailMaskingThreshold, 1, 350); | |||||
//_target.DetailSamplingBaseOpacityLimit = EditorGUILayout.Slider(VariableField("Cutoff", "This is the threshold to stop the detail sampling. We don't compute detail when the base layer opacity is higher than this value"), _target.DetailSamplingBaseOpacityLimit, 0, 1); | |||||
if (_target.Octaves > 1) | |||||
_target._Curl = EditorGUILayout.Slider(VariableField("Curl", "Used to distort the edges. Check the 'Time of Day' demo to see this in action"), _target._Curl, 0, 1); | |||||
} | |||||
GUILayout.EndVertical(); | |||||
//_target.noise2D= (Texture2D)EditorGUILayout.ObjectField("noise2D", _target.noise2D, typeof(Texture2D), false); | |||||
} | |||||
} | |||||
#endregion | |||||
#region Gradient | |||||
if (GUILayout.Button("Gradient", EditorStyles.toolbarButton)) | |||||
_target.showGradient = !_target.showGradient; | |||||
if (_target.showGradient) | |||||
{ | |||||
_target.EnableGradient = EditorGUILayout.Toggle("Active", _target.EnableGradient); | |||||
if (_target.EnableGradient) | |||||
_target.Gradient = (Texture2D)EditorGUILayout.ObjectField("", _target.Gradient, typeof(Texture2D), true); | |||||
} | |||||
#endregion | |||||
#region Footer | |||||
GUILayout.EndVertical();//termina estilo anterior | |||||
EditorGUI.indentLevel++; | |||||
if (GUILayout.Button("Other", EditorStyles.toolbarButton)) | |||||
_target.OtherTAB = !_target.OtherTAB; | |||||
GUILayout.BeginVertical(ThemeFooter); | |||||
if (_target.OtherTAB) | |||||
{ | |||||
GUILayout.Space(10); | |||||
var OtherRect = GUILayoutUtility.GetRect(new GUIContent(""), GUIStyle.none); | |||||
_target.showOtherOptions = EditorGUI.Foldout(OtherRect, _target.showOtherOptions, "Rendering options"); | |||||
if (_target.showOtherOptions) | |||||
{ | |||||
//EditorGUI.indentLevel++; | |||||
// if(!_target.CreateSurrogate) | |||||
_target.DrawOrder = EditorGUILayout.IntField(new GUIContent("DrawOrder", "Ignored when surrogates are not created manually"), _target.DrawOrder); | |||||
_target._PushAlpha = EditorGUILayout.Slider(new GUIContent("Push Alpha", "Compensate opacity when samples are not enough"), _target._PushAlpha, 1, 2f); | |||||
_target._ztest = (UnityEngine.Rendering.CompareFunction)EditorGUILayout.EnumPopup("ZTest ", _target._ztest); | |||||
if (_target.GameCameraGO != null /*&& _target._FogType == FogVolume.FogType.Textured*/) | |||||
if (_target.GameCameraGO.GetComponent<FogVolumeRenderer>() && | |||||
_target.GameCameraGO.GetComponent<FogVolumeRenderer>()._Downsample > 0 && | |||||
_target._FogType == FogVolume.FogType.Textured) | |||||
_target.CreateSurrogate = EditorGUILayout.Toggle(VariableField("Create Surrogate mesh", | |||||
"A copy of the volume mesh is created to project the result of the low-res render. This is good for preview, but usually, we have to create surrogate meshes by hand to sort them manually"), _target.CreateSurrogate); | |||||
_target._VisibleByReflectionProbeStatic = EditorGUILayout.Toggle("Visible for static probe", _target._VisibleByReflectionProbeStatic); | |||||
_target.RenderableInSceneView = EditorGUILayout.Toggle(VariableField("Render In Scene View", "Volume is not visible in Scene view. Please not that it won't be visible for reflection probes either"), _target.RenderableInSceneView); | |||||
_target.ExcludeFromLowRes = EditorGUILayout.Toggle(VariableField("Exclude from low res", | |||||
"Exclude this fog volume from the main game camera low res process\n" + | |||||
"Enable and change the layer\n useful when rendering underwater fog with another camera\nA custom depth buffer can be injected uncommenting this line: #pragma multi_compile _ ExternalDepth"), _target.ExcludeFromLowRes); | |||||
if (_target.ExcludeFromLowRes) | |||||
_target.InjectCustomDepthBuffer = EditorGUILayout.Toggle(VariableField("External depth buffer", | |||||
"Feed this Volume with a custom depth buffer with name: _CustomCameraDepthTexture\n useful when rendering underwater fog with another camera that has horizontal clip plane\nUncomment this line: #pragma multi_compile _ ExternalDepth"), _target.InjectCustomDepthBuffer); | |||||
} | |||||
GUILayout.Space(10); | |||||
var DebugOptionsRect = GUILayoutUtility.GetRect(new GUIContent(""), GUIStyle.none); | |||||
_target.showDebugOptions = EditorGUI.Foldout(DebugOptionsRect, _target.showDebugOptions, "Debug options"); | |||||
if (_target.showDebugOptions) | |||||
{ | |||||
_target.ShowDebugGizmos = | |||||
EditorGUILayout.Toggle("Draw Debug Gizmos", _target.ShowDebugGizmos); | |||||
} | |||||
GUILayout.Space(10); | |||||
var CustomizationOptionsRect = GUILayoutUtility.GetRect(new GUIContent(""), GUIStyle.none); | |||||
_target.showCustomizationOptions = EditorGUI.Foldout(CustomizationOptionsRect, _target.showCustomizationOptions, "Customize look"); | |||||
if (_target.showCustomizationOptions) | |||||
{ | |||||
// EditorGUI.indentLevel++; | |||||
// _target._InspectorBackground = (Texture2D)EditorGUILayout.ObjectField("Background", _target._InspectorBackground, typeof(Texture2D), false); | |||||
if (EditorGUIUtility.isProSkin) | |||||
{ | |||||
if (_target._InspectorBackground.Length > 0) | |||||
_target._InspectorBackgroundIndex = | |||||
EditorGUILayout.IntSlider("Inspector background", | |||||
_target._InspectorBackgroundIndex, | |||||
0, | |||||
_target._InspectorBackground.Length - | |||||
1); | |||||
} | |||||
_target.HideWireframe = EditorGUILayout.Toggle("Scene view wireframe", _target.HideWireframe); | |||||
ShowInspectorTooltips = EditorGUILayout.Toggle(new GUIContent("Enable inspector tooltips", "Work in progress"), ShowInspectorTooltips); | |||||
// EditorGUI.indentLevel--; | |||||
} | |||||
GUILayout.Space(10); | |||||
bool prevSaveMaterials = _target.SaveMaterials; | |||||
_target.SaveMaterials = | |||||
EditorGUILayout.Toggle(new GUIContent("Save Materials", "Ensures that material shaders are built correctly when creating a platform specific build."), | |||||
_target.SaveMaterials); | |||||
if (prevSaveMaterials != _target.SaveMaterials && _target.SaveMaterials) | |||||
{ | |||||
_target.RequestSavingMaterials = true; | |||||
} | |||||
else | |||||
{ | |||||
_target.RequestSavingMaterials = false; | |||||
} | |||||
} | |||||
if (_target._InspectorBackground.Length > 0) | |||||
if (_target._InspectorBackground[_target._InspectorBackgroundIndex] != null && EditorGUIUtility.isProSkin) | |||||
Theme1.normal.background = _target._InspectorBackground[_target._InspectorBackgroundIndex]; | |||||
GUILayout.EndVertical();//end footer style | |||||
EditorGUI.indentLevel--; | |||||
//GUI.backgroundColor = new Color(.9f, .5f, .9f); | |||||
#endregion | |||||
#region Info | |||||
if (GUILayout.Button("Info", EditorStyles.toolbarButton)) | |||||
_target.generalInfo = !_target.generalInfo; | |||||
if (_target.generalInfo) | |||||
{ | |||||
GUILayout.BeginVertical("box"); | |||||
EditorGUILayout.LabelField("Description",EditorStyles.boldLabel); | |||||
_target.Description = EditorGUILayout.TextArea(_target.Description, GUILayout.MaxWidth(300)); | |||||
EditorGUILayout.LabelField("Version 3.4"); | |||||
EditorGUILayout.LabelField("Release date: May 2018"); | |||||
EditorGUILayout.LabelField("Fog type: " + _target._FogType.ToString()); | |||||
#region Camera | |||||
if (_target.GameCameraGO) | |||||
{ | |||||
EditorGUILayout.LabelField("Assigned camera: " + _target.GameCameraGO.name); | |||||
if (GUILayout.Button("Select " + _target.GameCameraGO.name, EditorStyles.toolbarButton)) | |||||
Selection.activeGameObject = _target.GameCameraGO; | |||||
} | |||||
else | |||||
GUILayout.Button("No valid camera found", EditorStyles.toolbarButton); | |||||
GUILayout.EndVertical(); | |||||
GUILayout.Space(10); | |||||
#endregion | |||||
} | |||||
#endregion | |||||
if (EditorGUI.EndChangeCheck()) | |||||
{ | |||||
EditorUtility.SetDirty(target); | |||||
} | |||||
serializedObject.ApplyModifiedProperties(); | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: d5459245959cecf4985c5fcc323f4000 | |||||
timeCreated: 1476952094 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,97 @@ | |||||
using System.Collections; | |||||
using System.Collections.Generic; | |||||
using UnityEngine; | |||||
using UnityEditor; | |||||
[CustomEditor(typeof(FogVolumeLight))] | |||||
public class FogVolumeLightEditor : Editor | |||||
{ | |||||
public override void OnInspectorGUI() | |||||
{ | |||||
GUILayout.Space(10.0f); | |||||
serializedObject.Update(); | |||||
GUILayout.BeginVertical("box"); | |||||
var usesNormalLight = serializedObject.FindProperty("IsAddedToNormalLight"); | |||||
if (usesNormalLight.boolValue) | |||||
{ | |||||
EditorGUILayout.HelpBox("This light will use the settings of the light on this GameObject.\n\nRemove this component if the light should not be recognized by Fog Volume 3", MessageType.Info); | |||||
} | |||||
else | |||||
{ | |||||
var enabled = serializedObject.FindProperty("Enabled"); | |||||
if (GUILayout.Button(enabled.boolValue ? "Disable the light" : "Enable the light")) | |||||
{ | |||||
enabled.boolValue = !enabled.boolValue; | |||||
} | |||||
if (enabled.boolValue == true) | |||||
{ | |||||
GUILayout.Space(10.0f); | |||||
var isPointLight = serializedObject.FindProperty("IsPointLight"); | |||||
int selectedLightType = isPointLight.boolValue ? 0 : 1; | |||||
selectedLightType = | |||||
EditorGUILayout.Popup("Light Type: ", | |||||
selectedLightType, | |||||
m_lightTypes, | |||||
EditorStyles.toolbarButton); | |||||
if (selectedLightType == 0) { isPointLight.boolValue = true; } | |||||
else { isPointLight.boolValue = false; } | |||||
GUILayout.Space(10.0f); | |||||
var color = serializedObject.FindProperty("Color"); | |||||
EditorGUILayout.PropertyField(color, new GUIContent("Color:")); | |||||
GUILayout.Space(10.0f); | |||||
var intensity = serializedObject.FindProperty("Intensity"); | |||||
EditorGUILayout.Slider(intensity, | |||||
MinIntensity, | |||||
MaxIntenstity, | |||||
new GUIContent("Intensity:")); | |||||
GUILayout.Space(10.0f); | |||||
var range = serializedObject.FindProperty("Range"); | |||||
EditorGUILayout.Slider(range, MinRange, MaxRange, new GUIContent("Range:")); | |||||
if (selectedLightType == 1) | |||||
{ | |||||
GUILayout.Space(10.0f); | |||||
var angle = serializedObject.FindProperty("Angle"); | |||||
EditorGUILayout.Slider(angle, | |||||
MinSpotAngle, | |||||
MaxSpotAngle, | |||||
new GUIContent("SpotAngle:")); | |||||
} | |||||
} | |||||
} | |||||
GUILayout.EndVertical(); | |||||
serializedObject.ApplyModifiedProperties(); | |||||
} | |||||
private const float MinIntensity = 0.0f; | |||||
private const float MaxIntenstity = 50.0f; | |||||
private const float MinRange = 0.0f; | |||||
private const float MaxRange = 500.0f; | |||||
private const float MinSpotAngle = 0.0f; | |||||
private const float MaxSpotAngle = 180.0f; | |||||
private readonly string[] m_lightTypes = new[] | |||||
{ | |||||
"Point Light", | |||||
"Spot Light" | |||||
}; | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: b93ef22c40098a942923df70f18d3f24 | |||||
timeCreated: 1501093543 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,63 @@ | |||||
using System.Collections; | |||||
using System.Collections.Generic; | |||||
using UnityEngine; | |||||
using UnityEditor; | |||||
[CustomEditor(typeof(FogVolumePrimitive))] | |||||
public class FogVolumePrimitiveEditor : Editor | |||||
{ | |||||
public override void OnInspectorGUI() | |||||
{ | |||||
GUILayout.Space(10.0f); | |||||
serializedObject.Update(); | |||||
GUILayout.BeginVertical("box"); | |||||
var enabled = serializedObject.FindProperty("IsSubtractive"); | |||||
int selectedActionType = enabled.boolValue ? 0 : 1; | |||||
selectedActionType = | |||||
EditorGUILayout.Popup("Action Type: ", | |||||
selectedActionType, | |||||
m_actionTypes, | |||||
EditorStyles.toolbarButton); | |||||
if (selectedActionType == 0) { enabled.boolValue = true; } | |||||
else { enabled.boolValue = false; } | |||||
var persistent = serializedObject.FindProperty("IsPersistent"); | |||||
int selectedPersistenceType = persistent.boolValue ? 0 : 1; | |||||
selectedPersistenceType = | |||||
EditorGUILayout.Popup("Persistence Type:", | |||||
selectedPersistenceType, | |||||
m_persistenceType, | |||||
EditorStyles.toolbarButton); | |||||
if (selectedPersistenceType == 0) { persistent.boolValue = true; } | |||||
else { persistent.boolValue = false; } | |||||
GUILayout.Space(2.0f); | |||||
GUILayout.EndVertical(); | |||||
serializedObject.ApplyModifiedProperties(); | |||||
} | |||||
private readonly string[] m_actionTypes = new[] | |||||
{ | |||||
"Subtractive", | |||||
"Additive" | |||||
}; | |||||
private readonly string[] m_persistenceType = new[] | |||||
{ | |||||
"Persistent", | |||||
"Cullable" | |||||
}; | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 00e0f071df3efac4a8069752c25cf053 | |||||
timeCreated: 1512414546 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,176 @@ | |||||
using System.Collections.Generic; | |||||
using UnityEngine; | |||||
using UnityEditor; | |||||
using UnityEditorInternal; | |||||
[CustomEditor(typeof(FogVolumeRenderer))] | |||||
public class FogVolumeRendererEditor : Editor | |||||
{ | |||||
SerializedProperty ShowCamera; | |||||
FogVolumeRenderer _target; | |||||
private Texture2D InspectorImage; | |||||
private GUIStyle HeaderStyle, BodyStyle; | |||||
private static bool DebugTab | |||||
{ | |||||
get { return EditorPrefs.GetBool("fvDebugTab"); } | |||||
set { EditorPrefs.SetBool("fvDebugTab", value); } | |||||
} | |||||
private static bool ShowInspectorTooltips | |||||
{ | |||||
get { return EditorPrefs.GetBool("ShowInspectorTooltips"); } | |||||
set { EditorPrefs.SetBool("ShowInspectorTooltips", value); } | |||||
} | |||||
GUIContent VariableField(string VariableName, string Tooltip) | |||||
{ | |||||
return new GUIContent(VariableName, ShowInspectorTooltips ? Tooltip : ""); | |||||
} | |||||
string[] layerMaskName; | |||||
//int layerMaskNameIndex = 0; | |||||
void OnEnable() | |||||
{ | |||||
_target = (FogVolumeRenderer)target; | |||||
ShowCamera = serializedObject.FindProperty("ShowCamera"); | |||||
InspectorImage = Resources.Load("InspectorImage", typeof(Texture2D)) as Texture2D; | |||||
HeaderStyle = new GUIStyle(); | |||||
HeaderStyle.normal.background = InspectorImage; | |||||
BodyStyle = new GUIStyle(); | |||||
// BodyStyle.normal.background = (Texture2D)Resources.Load("RendererInspectorBody"); | |||||
if (EditorGUIUtility.isProSkin) | |||||
BodyStyle.normal.background = (Texture2D)Resources.Load("RendererInspectorBodyBlack"); | |||||
else | |||||
BodyStyle.normal.background = (Texture2D)Resources.Load("RendererInspectorBodyBright"); | |||||
List<string> layerMaskList = new List<string>(); | |||||
for (int i = 0; i < 32; i++) | |||||
{ | |||||
string layerName = LayerMask.LayerToName(i); | |||||
//if (layerName != "") | |||||
//{ | |||||
// if (layerName == _target.DepthLayersName) | |||||
// layerMaskNameIndex = layerMaskList.Count; | |||||
layerMaskList.Add(layerName); | |||||
//} | |||||
} | |||||
layerMaskName = layerMaskList.ToArray(); | |||||
} | |||||
public override void OnInspectorGUI() | |||||
{ | |||||
serializedObject.Update(); | |||||
GUILayout.Space(10); | |||||
// GUILayout.Box(InspectorImage, GUILayout.ExpandWidth(true)); | |||||
GUILayout.BeginVertical(HeaderStyle); | |||||
// EditorGUILayout.HelpBox(BodyStyle.name, MessageType.None); | |||||
GUILayout.Space(EditorGUIUtility.currentViewWidth / 4 - 10); | |||||
//end header | |||||
GUILayout.EndVertical(); | |||||
//begin body | |||||
GUILayout.Space(1); | |||||
GUILayout.BeginVertical(BodyStyle); | |||||
EditorGUI.BeginChangeCheck(); | |||||
Undo.RecordObject(_target, "Fog volume Renderer parameter"); | |||||
GUILayout.Space(20); | |||||
// GUILayout.BeginVertical("box"); | |||||
_target._Downsample = EditorGUILayout.IntSlider("Downscale", _target._Downsample, 1, 16); | |||||
//if (_target._Downsample>1) | |||||
// _target.RenderableInSceneView = EditorGUILayout.Toggle(VariableField("Render In Scene View", "Makes it visible for reflection probes and Scene viewport"), _target.RenderableInSceneView); | |||||
//GUILayout.EndVertical();//end box | |||||
if (_target._Downsample > 1) | |||||
_target._BlendMode = (FogVolumeRenderer.BlendMode)EditorGUILayout.EnumPopup("Blend Mode", _target._BlendMode); | |||||
EditorGUILayout.HelpBox("Resolution: " + _target.FogVolumeResolution, MessageType.None); | |||||
if (_target._Downsample > 1) | |||||
{ | |||||
GUILayout.BeginVertical("box"); | |||||
_target.GenerateDepth = EditorGUILayout.Toggle(VariableField("Depth", "Compute Depth when rendered in low-res and textured volumes collide with scene elements"), _target.GenerateDepth); | |||||
if (_target.GenerateDepth) | |||||
{ | |||||
//GUILayout.BeginHorizontal(); | |||||
//EditorGUILayout.LabelField("Exclude layer"); | |||||
//int newLayerMaskNameIndex = EditorGUILayout.Popup(layerMaskNameIndex, layerMaskName); | |||||
//if (newLayerMaskNameIndex != layerMaskNameIndex) | |||||
//{ | |||||
// layerMaskNameIndex = newLayerMaskNameIndex; | |||||
// _target.DepthLayersName = layerMaskName[layerMaskNameIndex]; | |||||
//} | |||||
//GUILayout.EndHorizontal(); | |||||
// GUILayout.BeginHorizontal(); | |||||
// EditorGUILayout.LabelField("Depth layers"); | |||||
_target.DepthLayer2 = EditorGUILayout.MaskField(VariableField("Depth layers", "Select the layers used to collide with FV\n(Experimental feature)"), _target.DepthLayer2, layerMaskName); | |||||
//_target.DepthLayer2 = EditorGUILayout.LayerField("Depth layers", _target.DepthLayer2); | |||||
//GUILayout.EndHorizontal(); | |||||
GUILayout.BeginVertical("box"); | |||||
_target.useBilateralUpsampling = EditorGUILayout.Toggle(VariableField("Edge-aware upscale", "Minimize the aliasing at the edges of colliding elements"), _target.useBilateralUpsampling); | |||||
if (_target.useBilateralUpsampling) | |||||
{ | |||||
_target.upsampleDepthThreshold = EditorGUILayout.Slider("Depth Threshold", _target.upsampleDepthThreshold, 0, .01f); | |||||
_target.showBilateralEdge = EditorGUILayout.Toggle("Show edge mask", _target.showBilateralEdge); | |||||
_target.upsampleMode = (FogVolumeRenderer.UpsampleMode)EditorGUILayout.EnumPopup("Method", _target.upsampleMode); | |||||
} | |||||
GUILayout.EndVertical();//end box | |||||
} | |||||
GUILayout.EndVertical();//end box | |||||
#region DeNoise | |||||
if (_target._Downsample > 1) | |||||
{ | |||||
GUILayout.BeginVertical("box"); | |||||
_target.TAA = EditorGUILayout.Toggle(VariableField("DeNoise", "Performs Playdead's TAA to minimize noise when using jitter. Note: effect works only in 5.5"), _target.TAA); | |||||
if (_target.TAA && _target.HDR) | |||||
EditorGUILayout.HelpBox("Color output is in LDR", MessageType.None); | |||||
GUILayout.EndVertical();//end box | |||||
} | |||||
#endregion | |||||
// #region Stereo | |||||
//if ( _target._Downsample > 0) | |||||
//{ | |||||
// GUILayout.BeginVertical("box"); | |||||
// _target.useRectangularStereoRT = EditorGUILayout.Toggle("Rectangular stereo", _target.useRectangularStereoRT); | |||||
// GUILayout.EndVertical();//end box | |||||
//} | |||||
// #endregion | |||||
if (GUILayout.Button("Debug", EditorStyles.toolbarButton)) | |||||
DebugTab = !DebugTab; | |||||
if (DebugTab) | |||||
{ | |||||
GUILayout.BeginVertical("box"); | |||||
{ | |||||
EditorGUILayout.PropertyField(ShowCamera, new GUIContent("Show camera", "Unhide the camera used to render FV in low resolution")); | |||||
} | |||||
GUILayout.EndVertical(); | |||||
} | |||||
} | |||||
EditorGUI.EndChangeCheck(); | |||||
EditorGUILayout.HelpBox("Fog Volume 3.4 July 2018", MessageType.None); | |||||
GUILayout.EndVertical(); | |||||
if (GUI.changed) | |||||
{ | |||||
EditorUtility.SetDirty(_target); | |||||
} | |||||
serializedObject.ApplyModifiedProperties(); | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: cc84cfc3ca565c246a1dfa0e6ce47919 | |||||
timeCreated: 1488719253 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,49 @@ | |||||
using UnityEditor; | |||||
using UnityEngine; | |||||
using System.Collections; | |||||
using System.Collections.Generic; | |||||
[CustomEditor(typeof(FogVolumeScreen))] | |||||
[ExecuteInEditMode] | |||||
public class FogVolumeScreenEditor : Editor | |||||
{ | |||||
string[] layerMaskName; | |||||
int layerMaskNameIndex = 0; | |||||
void OnEnable() | |||||
{ | |||||
FogVolumeScreen _target = (FogVolumeScreen)target; | |||||
List<string> layerMaskList = new List<string>(); | |||||
for (int i = 0; i < 32; i++) | |||||
{ | |||||
string layerName = LayerMask.LayerToName(i); | |||||
if (layerName != "") | |||||
{ | |||||
if (layerName == _target.FogVolumeLayerName) | |||||
layerMaskNameIndex = layerMaskList.Count; | |||||
layerMaskList.Add(layerName); | |||||
} | |||||
} | |||||
layerMaskName = layerMaskList.ToArray(); | |||||
} | |||||
public override void OnInspectorGUI() | |||||
{ | |||||
FogVolumeScreen _target = (FogVolumeScreen)target; | |||||
GUILayout.BeginHorizontal(); | |||||
EditorGUILayout.LabelField("Density layer"); | |||||
int newLayerMaskNameIndex = EditorGUILayout.Popup(layerMaskNameIndex, layerMaskName); | |||||
if (newLayerMaskNameIndex != layerMaskNameIndex) | |||||
{ | |||||
layerMaskNameIndex = newLayerMaskNameIndex; | |||||
_target.FogVolumeLayerName = layerMaskName[layerMaskNameIndex]; | |||||
} | |||||
GUILayout.EndHorizontal(); | |||||
// Draw the default inspector | |||||
DrawDefaultInspector(); | |||||
EditorGUILayout.HelpBox("Work in progress!", MessageType.None); | |||||
EditorUtility.SetDirty(target); | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: a114e1e498c1c184eb874bf8356208d5 | |||||
timeCreated: 1493151842 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,29 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 5e7a52d786954b246ab3797052502655 | |||||
timeCreated: 1503131861 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: | |||||
- ShadowCaster: {instanceID: 0} | |||||
- _PerformanceLUT: {fileID: 2800000, guid: f651c771afb96204b85e925622f5e2b9, type: 3} | |||||
- Sun: {instanceID: 0} | |||||
- _LightHaloTexture: {fileID: 2800000, guid: fa2064f3c8dffc04f93f4f74eae0d72f, type: 3} | |||||
- CoverageTex: {instanceID: 0} | |||||
- GameCameraGO: {instanceID: 0} | |||||
- _NoiseVolume2: {fileID: 11700000, guid: ce515a5a715cb574eb40037cfb1ab766, type: 2} | |||||
- _NoiseVolume: {fileID: 11700000, guid: ce515a5a715cb574eb40037cfb1ab766, type: 2} | |||||
- FogRenderer: {instanceID: 0} | |||||
- Gradient: {fileID: 2800000, guid: 132bd45e1d3746f4ba36d53d9e19b1c9, type: 3} | |||||
- RT_Opacity: {instanceID: 0} | |||||
- RT_OpacityBlur: {instanceID: 0} | |||||
- ShadowCameraGO: {instanceID: 0} | |||||
- _ShadowCamera: {instanceID: 0} | |||||
- FogVolumeShader: {fileID: 4800000, guid: 6040e6c91df9d9d47b7e5426d41a7471, type: 3} | |||||
- ShadowProjector: {instanceID: 0} | |||||
- ShadowProjectorMesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} | |||||
executionOrder: 0 | |||||
icon: {fileID: 2800000, guid: 925eb9f7b0e73dd438a616124964bba8, type: 3} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,183 @@ | |||||
#if UNITY_EDITOR | |||||
using UnityEngine; | |||||
using UnityEditor; | |||||
using System.Reflection; | |||||
public class FogVolumeCreator : Editor | |||||
{ | |||||
[MenuItem("GameObject/Create Other/Fog Volume")] | |||||
[MenuItem("Fog Volume/Create Fog Volume")] | |||||
public static void CreateFogVolume() | |||||
{ | |||||
var FogVolume = new GameObject(); | |||||
//Icon stuff | |||||
var Icon = Resources.Load("FogVolumeIcon") as Texture; | |||||
//Icon.hideFlags = HideFlags.HideAndDontSave; | |||||
var editorGUI = typeof(EditorGUIUtility); | |||||
var bindingFlags = BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.NonPublic; | |||||
var args = new object[] | |||||
{ | |||||
FogVolume, | |||||
Icon | |||||
}; | |||||
editorGUI.InvokeMember("SetIconForObject", bindingFlags, null, null, args); | |||||
FogVolume.name = "Fog Volume"; | |||||
FogVolume.AddComponent<MeshRenderer>(); | |||||
FogVolume.AddComponent<FogVolume>(); | |||||
FogVolume.GetComponent<Renderer>().shadowCastingMode = | |||||
UnityEngine.Rendering.ShadowCastingMode.Off; | |||||
FogVolume.GetComponent<Renderer>().receiveShadows = false; | |||||
FogVolume.GetComponent<Renderer>().reflectionProbeUsage = | |||||
UnityEngine.Rendering.ReflectionProbeUsage.Off; | |||||
FogVolume.GetComponent<Renderer>().lightProbeUsage = | |||||
UnityEngine.Rendering.LightProbeUsage.Off; | |||||
Selection.activeObject = FogVolume; | |||||
if (SceneView.currentDrawingSceneView) | |||||
{ | |||||
SceneView.currentDrawingSceneView.MoveToView(FogVolume.transform); | |||||
} | |||||
} | |||||
//============================================================================================= | |||||
// L I G H T S | |||||
//============================================================================================= | |||||
[MenuItem("GameObject/Create Other/Fog Volume Light/Fog Volume Point Light")] | |||||
[MenuItem("Fog Volume/Create Light/Fog Volume Point Light")] | |||||
public static void CreateFogVolumePointLight() | |||||
{ | |||||
var fogVolumeLight = new GameObject("FogVolumePointLight"); | |||||
var light = fogVolumeLight.AddComponent<FogVolumeLight>(); | |||||
light.IsPointLight = true; | |||||
light.IsAddedToNormalLight = false; | |||||
} | |||||
[MenuItem("GameObject/Create Other/Fog Volume Light/Fog Volume Spot Light")] | |||||
[MenuItem("Fog Volume/Create Light/Fog Volume Spot Light")] | |||||
public static void CreateFogVolumeSpotLight() | |||||
{ | |||||
var fogVolumeLight = new GameObject("FogVolumeSpotLight"); | |||||
var light = fogVolumeLight.AddComponent<FogVolumeLight>(); | |||||
light.IsPointLight = false; | |||||
light.IsAddedToNormalLight = false; | |||||
} | |||||
[MenuItem("Fog Volume/Create Light/Fog Volume Directional Light")] | |||||
public static void AutoCreateFogVolumeDirectionalLight() | |||||
{ | |||||
var lights = FindObjectsOfType<Light>(); | |||||
for (var i = 0; i < lights.Length; i++) | |||||
{ | |||||
var light = lights[i]; | |||||
if (light.type == LightType.Directional) | |||||
{ | |||||
if (light.GetComponent<FogVolumeDirectionalLight>() == null) | |||||
{ | |||||
var dirLight = light.gameObject.AddComponent<FogVolumeDirectionalLight>(); | |||||
var fogVolumes = FindObjectsOfType<FogVolume>(); | |||||
dirLight._TargetFogVolumes = new FogVolume[fogVolumes.Length]; | |||||
for (var k = 0; k < fogVolumes.Length; k++) | |||||
{ | |||||
dirLight._TargetFogVolumes[k] = fogVolumes[k]; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
[MenuItem("Fog Volume/Create Light/Fog Volume Directional Light", true)] | |||||
public static bool EnableCreateFogVolumeDirectionalLight() | |||||
{ | |||||
return FindObjectOfType<FogVolumeDirectionalLight>() == null && | |||||
FindObjectOfType<FogVolume>() != null; | |||||
} | |||||
[MenuItem("GameObject/Create Other/Fog Volume Light/Normal Point Light")] | |||||
[MenuItem("Fog Volume/Create Light/Normal Point Light")] | |||||
public static void CreateNormalPointLight() | |||||
{ | |||||
var normalPointLight = new GameObject("Point light"); | |||||
var light = normalPointLight.AddComponent<Light>(); | |||||
light.type = LightType.Point; | |||||
var fvLight = normalPointLight.AddComponent<FogVolumeLight>(); | |||||
fvLight.IsPointLight = true; | |||||
fvLight.IsAddedToNormalLight = true; | |||||
} | |||||
[MenuItem("GameObject/Create Other/Fog Volume Light/Normal Spot Light")] | |||||
[MenuItem("Fog Volume/Create Light/Normal Spot Light")] | |||||
public static void CreateNormalSpotLight() | |||||
{ | |||||
var normalPointLight = new GameObject("Spot light"); | |||||
var light = normalPointLight.AddComponent<Light>(); | |||||
light.type = LightType.Spot; | |||||
var fvLight = normalPointLight.AddComponent<FogVolumeLight>(); | |||||
fvLight.IsPointLight = false; | |||||
fvLight.IsAddedToNormalLight = true; | |||||
} | |||||
//============================================================================================= | |||||
// P R I M I T I V E S | |||||
//============================================================================================= | |||||
[MenuItem("Fog Volume/Create Primitive/Fog Volume Primitive Box")] | |||||
[MenuItem("GameObject/Create Other/Fog Volume Primitive/Box")] | |||||
static public void CreateFogVolumePrimitiveBox() | |||||
{ | |||||
GameObject FogVolumePrimitive = GameObject.CreatePrimitive(PrimitiveType.Cube); | |||||
//Icon stuff | |||||
//Texture Icon = Resources.Load("FogVolumePrimitiveIcon") as Texture; | |||||
//Icon.hideFlags = HideFlags.HideAndDontSave; | |||||
// var editorGUI = typeof(EditorGUIUtility); | |||||
// var bindingFlags = BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.NonPublic; | |||||
//var args = new object[] { FogVolumePrimitive, Icon }; | |||||
//editorGUI.InvokeMember("SetIconForObject", bindingFlags, null, null, args); | |||||
FogVolumePrimitive.name = "Fog Volume Primitive Box"; | |||||
FogVolumePrimitive.GetComponent<BoxCollider>().isTrigger = true; | |||||
FogVolumePrimitive.GetComponent<Renderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; | |||||
FogVolumePrimitive.GetComponent<Renderer>().receiveShadows = false; | |||||
FogVolumePrimitive.GetComponent<Renderer>().reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off; | |||||
FogVolumePrimitive.GetComponent<Renderer>().lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off; | |||||
Selection.activeObject = FogVolumePrimitive; | |||||
if (UnityEditor.SceneView.currentDrawingSceneView) UnityEditor.SceneView.currentDrawingSceneView.MoveToView(FogVolumePrimitive.transform); | |||||
FogVolumePrimitive.AddComponent<FogVolumePrimitive>(); | |||||
} | |||||
[MenuItem("Fog Volume/Create Primitive/Fog Volume Primitive Sphere")] | |||||
[MenuItem("GameObject/Create Other/Fog Volume Primitive/Sphere")] | |||||
static public void CreateFogVolumePrimitiveSphere() | |||||
{ | |||||
GameObject FogVolumePrimitive = GameObject.CreatePrimitive(PrimitiveType.Sphere); | |||||
//Icon stuff | |||||
//Texture Icon = Resources.Load("FogVolumePrimitiveIcon") as Texture; | |||||
//Icon.hideFlags = HideFlags.HideAndDontSave; | |||||
// var editorGUI = typeof(EditorGUIUtility); | |||||
// var bindingFlags = BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.NonPublic; | |||||
//var args = new object[] { FogVolumePrimitive, Icon }; | |||||
//editorGUI.InvokeMember("SetIconForObject", bindingFlags, null, null, args); | |||||
FogVolumePrimitive.name = "Fog Volume Primitive Sphere"; | |||||
FogVolumePrimitive.GetComponent<SphereCollider>().isTrigger = true; | |||||
FogVolumePrimitive.GetComponent<Renderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; | |||||
FogVolumePrimitive.GetComponent<Renderer>().receiveShadows = false; | |||||
FogVolumePrimitive.GetComponent<Renderer>().reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off; | |||||
FogVolumePrimitive.GetComponent<Renderer>().lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off; | |||||
Selection.activeObject = FogVolumePrimitive; | |||||
if (UnityEditor.SceneView.currentDrawingSceneView) UnityEditor.SceneView.currentDrawingSceneView.MoveToView(FogVolumePrimitive.transform); | |||||
FogVolumePrimitive.AddComponent<FogVolumePrimitive>(); | |||||
} | |||||
} | |||||
#endif |
@ -0,0 +1,10 @@ | |||||
fileFormatVersion: 2 | |||||
guid: e1ca8118fc675de46aaadaf22b652071 | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,205 @@ | |||||
using System.Collections.Generic; | |||||
using UnityEngine; | |||||
[ExecuteInEditMode] | |||||
public class FogVolumeData : MonoBehaviour | |||||
{ | |||||
[SerializeField] | |||||
bool _ForceNoRenderer; | |||||
public bool ForceNoRenderer | |||||
{ | |||||
get { return _ForceNoRenderer; } | |||||
set | |||||
{ | |||||
if (_ForceNoRenderer != value) | |||||
{ | |||||
_ForceNoRenderer = value; | |||||
ToggleFogVolumeRenderers(); | |||||
} | |||||
} | |||||
} | |||||
[SerializeField] | |||||
Camera _GameCamera; | |||||
public Camera GameCamera | |||||
{ | |||||
get { return _GameCamera; } | |||||
set | |||||
{ | |||||
if (_GameCamera != value) | |||||
{ | |||||
_GameCamera = value; | |||||
RefreshCamera(); | |||||
} | |||||
} | |||||
} | |||||
public void setDownsample(int val) | |||||
{ | |||||
if (_GameCamera.GetComponent<FogVolumeRenderer>()) | |||||
_GameCamera.GetComponent<FogVolumeRenderer>()._Downsample = val; | |||||
} | |||||
void RefreshCamera() | |||||
{ | |||||
//refresh all fog folumes assigned camera | |||||
//print("Refresh"); | |||||
FindFogVolumes(); | |||||
foreach (FogVolume _FogVolumes in SceneFogVolumes) | |||||
{ | |||||
_FogVolumes.AssignCamera(); | |||||
} | |||||
ToggleFogVolumeRenderers(); | |||||
} | |||||
[SerializeField] | |||||
List<Camera> FoundCameras; | |||||
void OnEnable() | |||||
{ | |||||
Initialize(); | |||||
} | |||||
void Initialize() | |||||
{ | |||||
if (FoundCameras == null) | |||||
FoundCameras = new List<Camera>(); | |||||
FindCamera(); | |||||
RefreshCamera(); | |||||
if (FoundCameras.Count == 0) | |||||
Debug.Log("Definetly, no camera available for Fog Volume"); | |||||
} | |||||
[SerializeField] | |||||
FogVolume[] SceneFogVolumes; | |||||
public void FindFogVolumes() | |||||
{ | |||||
SceneFogVolumes = (FogVolume[])FindObjectsOfType(typeof(FogVolume)); | |||||
} | |||||
void Update() | |||||
{ | |||||
if (GameCamera == null) | |||||
{ | |||||
Debug.Log("No Camera available for Fog Volume. Trying to find another one"); | |||||
Initialize(); | |||||
} | |||||
#if UNITY_EDITOR | |||||
for (int i = 0; i < SceneFogVolumes.Length; i++) | |||||
{ | |||||
FogVolume SlotFogVolume = SceneFogVolumes[i]; | |||||
if(SlotFogVolume==null) | |||||
{ | |||||
//reset and rebuild | |||||
SceneFogVolumes = null; | |||||
FindFogVolumes(); | |||||
} | |||||
} | |||||
if (SceneFogVolumes.Length == 0) | |||||
DestroyImmediate(gameObject); | |||||
#endif | |||||
} | |||||
void ToggleFogVolumeRenderers() | |||||
{ | |||||
if (FoundCameras != null) | |||||
for (int i = 0; i < FoundCameras.Count; i++) | |||||
{ | |||||
if (FoundCameras[i] != _GameCamera) | |||||
{ | |||||
if (FoundCameras[i].GetComponent<FogVolumeRenderer>()) | |||||
FoundCameras[i].GetComponent<FogVolumeRenderer>().enabled = false; | |||||
} | |||||
else if (FoundCameras[i].GetComponent<FogVolumeRenderer>() && | |||||
!_ForceNoRenderer) | |||||
{ | |||||
FoundCameras[i].GetComponent<FogVolumeRenderer>().enabled = true; | |||||
} | |||||
else | |||||
{ | |||||
var FVRenderer = FoundCameras[i].GetComponent<FogVolumeRenderer>(); | |||||
if (FVRenderer == null) | |||||
{ | |||||
if (ForceNoRenderer) { continue; } | |||||
FVRenderer = FoundCameras[i].gameObject.AddComponent<FogVolumeRenderer>(); | |||||
} | |||||
if(ForceNoRenderer) | |||||
{ | |||||
FVRenderer.enabled = false; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
public void FindCamera() | |||||
{ | |||||
//We will try to assign the typical MainCamera first. This search will be performed only when the field is null | |||||
//This is just an initial attempt on assigning any camera available when the field 'Camera' is null. | |||||
//We will be able to select any other camera later | |||||
if (FoundCameras != null && FoundCameras.Count > 0) FoundCameras.Clear(); | |||||
//Find all cameras in scene and store | |||||
Camera[] CamerasFound = (Camera[])FindObjectsOfType(typeof(Camera)); | |||||
for (int i = 0; i < CamerasFound.Length; i++) | |||||
if ( | |||||
!CamerasFound[i].name.Contains("FogVolumeCamera") | |||||
&& | |||||
!CamerasFound[i].name.Contains("Shadow Camera") | |||||
&& | |||||
CamerasFound[i].gameObject.hideFlags == HideFlags.None)//not you! | |||||
FoundCameras.Add(CamerasFound[i]); | |||||
if (GameCamera == null) | |||||
GameCamera = Camera.main; | |||||
//No MainCamera? Try to find any! | |||||
if (GameCamera == null) | |||||
{ | |||||
foreach (Camera FoundCamera in FoundCameras) | |||||
{ | |||||
// Many effects may use hidden cameras, so let's filter a little bit until we get something valid | |||||
if (FoundCamera.isActiveAndEnabled) | |||||
if (FoundCamera.gameObject.activeInHierarchy) | |||||
if (FoundCamera.gameObject.hideFlags == HideFlags.None) | |||||
{ | |||||
GameCamera = FoundCamera; | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
if (GameCamera != null) | |||||
{ | |||||
// Debug.Log("Fog Volume has been assigned with camera: " + GameCamera); | |||||
//if (FindObjectOfType<FogVolumeCamera>()) | |||||
// FindObjectOfType<FogVolumeCamera>().SceneCamera = GameCamera; | |||||
//NOTE: This makes sure we have a depth texture which will be either free (deferred, etc) or internally generated through a replacement shader | |||||
//Now, objects must be able to do shadow casting. If you’re using surface shaders, add the "addshadow" directive | |||||
//only “opaque” objects (that which have their materials and shaders setup to use render queue <= 2500) are rendered into the depth texture. | |||||
//GameCamera.depthTextureMode = DepthTextureMode.Depth; | |||||
} | |||||
} | |||||
public Camera GetFogVolumeCamera | |||||
{ | |||||
get | |||||
{ | |||||
return GameCamera; | |||||
} | |||||
} | |||||
void OnDisable() | |||||
{ | |||||
FoundCameras.Clear(); | |||||
SceneFogVolumes = null; | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 9b5fee381bc7db44db761f5cc13c71d5 | |||||
timeCreated: 1491065420 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,521 @@ | |||||
using UnityEngine; | |||||
using UnityEngine.UI; | |||||
/*not working on android*/ | |||||
[ExecuteInEditMode] | |||||
public class FogVolumeDirectionalLight : MonoBehaviour | |||||
{ | |||||
public FogVolume[] _TargetFogVolumes; | |||||
public Vector2 MiniaturePosition = new Vector2(110, 320); | |||||
public FogVolume _ProminentFogVolume = null; | |||||
// [HideInInspector] | |||||
public Material FogVolumeMaterial; | |||||
public float _CameraVerticalPosition = 500; | |||||
RenderTexture depthRT; | |||||
public enum Resolution | |||||
{ | |||||
_256 = 256, | |||||
_512 = 512, | |||||
_1024 = 1024, | |||||
_2048 = 2048, | |||||
_4096 = 4096 | |||||
}; | |||||
public enum Antialiasing | |||||
{ | |||||
_1 = 1, | |||||
_2 = 2, | |||||
_4 = 4, | |||||
_8 = 8 | |||||
}; | |||||
public Antialiasing _Antialiasing = Antialiasing._1; | |||||
public Resolution Size = Resolution._512; | |||||
// [Range(10, 300)] | |||||
// float CameraSize = 100; | |||||
//public bool ToggleKeyword = true; | |||||
// [HideInInspector] | |||||
public Camera ShadowCamera; | |||||
public enum ScaleMode | |||||
{ | |||||
VolumeMaxAxis, | |||||
Manual | |||||
}; | |||||
public float _FogVolumeShadowMapEdgeSoftness = 0.001f; | |||||
public ScaleMode _ScaleMode = ScaleMode.VolumeMaxAxis; | |||||
public LayerMask LayersToRender; | |||||
[HideInInspector] | |||||
public Shader outputDepth; | |||||
[HideInInspector] | |||||
public GameObject GOShadowCamera; | |||||
public bool CameraVisible; | |||||
public enum UpdateMode | |||||
{ | |||||
OnStart, | |||||
Interleaved | |||||
}; | |||||
Image _CanvasImage; | |||||
public UpdateMode _UpdateMode = UpdateMode.Interleaved; | |||||
public float Scale = 50; | |||||
[Range(0, 100)] | |||||
public int SkipFrames = 2; | |||||
// CanvasRenderer DebugCanvas; | |||||
public bool ShowMiniature = false; | |||||
GameObject _GO_Canvas, _GO_Image; | |||||
Canvas _Canvas; | |||||
public Material DebugViewMaterial; | |||||
GameObject Quad; | |||||
Vector3 FocusPosition; | |||||
FogVolumeData _FogVolumeData; | |||||
Camera _GameCamera; | |||||
public enum FocusMode | |||||
{ | |||||
VolumeCenter, | |||||
GameCameraPosition, | |||||
GameObject | |||||
}; | |||||
public Transform _GameObjectFocus; | |||||
public FocusMode _FocusMode = FocusMode.VolumeCenter; | |||||
Material quadMaterial = null; | |||||
public Material QuadMaterial | |||||
{ | |||||
get | |||||
{ | |||||
if (quadMaterial == null) { CreateMaterial(); } | |||||
return quadMaterial; | |||||
} | |||||
} | |||||
public Shader quadShader; | |||||
void OnEnable() | |||||
{ | |||||
_GO_Canvas = GameObject.Find("FogVolume Debug Canvas"); | |||||
if (!_GO_Canvas) _GO_Canvas = new GameObject("FogVolume Debug Canvas"); | |||||
_GO_Image = GameObject.Find("FogVolume Image"); | |||||
if (!_GO_Image) | |||||
{ | |||||
_GO_Image = new GameObject("FogVolume Image"); | |||||
_CanvasImage = _GO_Image.AddComponent<Image>(); | |||||
_CanvasImage.material = DebugViewMaterial; | |||||
_CanvasImage.rectTransform.position = new Vector3(MiniaturePosition.x, MiniaturePosition.y, 0); | |||||
_CanvasImage.rectTransform.pivot = new Vector2(.5f, .5f); | |||||
_CanvasImage.rectTransform.anchorMax = new Vector2(0, 0); | |||||
_CanvasImage.rectTransform.anchorMin = new Vector2(0, 0); | |||||
_CanvasImage.rectTransform.localScale = new Vector3(2, 2, 2); | |||||
} | |||||
if (!_CanvasImage) _CanvasImage = _GO_Image.GetComponent<Image>(); | |||||
_CanvasImage.material = DebugViewMaterial; | |||||
_GO_Image.transform.SetParent(_GO_Canvas.transform); | |||||
_GO_Canvas.AddComponent<CanvasScaler>(); | |||||
_GO_Canvas.GetComponent<CanvasScaler>().scaleFactor = 1; | |||||
_GO_Canvas.GetComponent<CanvasScaler>().referencePixelsPerUnit = 100; | |||||
_Canvas = _GO_Canvas.GetComponent<Canvas>(); // ("Debug view canvas"); | |||||
_GO_Canvas.hideFlags = HideFlags.HideInHierarchy; | |||||
// DebugCanvas = _GO_Canvas.AddComponent<CanvasRenderer>(); | |||||
_GO_Canvas.layer = LayerMask.NameToLayer("UI"); | |||||
_GO_Image.layer = LayerMask.NameToLayer("UI"); | |||||
_Canvas.renderMode = RenderMode.ScreenSpaceOverlay; | |||||
Initialize(); | |||||
if (_UpdateMode == UpdateMode.OnStart) { Render(); } | |||||
} | |||||
void CreateMaterial() | |||||
{ | |||||
DestroyImmediate(quadMaterial); | |||||
quadShader = Shader.Find("Hidden/DepthMapQuad"); | |||||
// | |||||
quadMaterial = new Material(quadShader); | |||||
quadMaterial.name = "Depth camera quad material"; | |||||
quadMaterial.hideFlags = HideFlags.HideAndDontSave; | |||||
} | |||||
RenderTextureFormat rt_DepthFormat; | |||||
void Initialize() | |||||
{ | |||||
CreateMaterial(); | |||||
if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RGFloat)) | |||||
rt_DepthFormat = RenderTextureFormat.RGFloat; | |||||
else | |||||
rt_DepthFormat = RenderTextureFormat.DefaultHDR; | |||||
GameObject FogVolumeDataGO = GameObject.Find("Fog Volume Data"); | |||||
if (FogVolumeDataGO) _FogVolumeData = FogVolumeDataGO.GetComponent<FogVolumeData>(); | |||||
else return; | |||||
_GameCamera = _FogVolumeData.GameCamera; | |||||
GOShadowCamera = GameObject.Find("FogVolumeShadowCamera"); | |||||
if (!GOShadowCamera) | |||||
{ | |||||
GOShadowCamera = new GameObject(); | |||||
GOShadowCamera.name = "FogVolumeShadowCamera"; | |||||
} | |||||
if (!GOShadowCamera) print("Shadow camera is lost"); | |||||
else ShadowCamera = GOShadowCamera.GetComponent<Camera>(); | |||||
if (!depthRT) | |||||
{ | |||||
depthRT = new RenderTexture((int) Size, (int) Size, 16, rt_DepthFormat); | |||||
depthRT.antiAliasing = (int) _Antialiasing; | |||||
depthRT.filterMode = FilterMode.Bilinear; | |||||
depthRT.name = "FogVolumeShadowMap"; | |||||
depthRT.wrapMode = TextureWrapMode.Clamp; | |||||
} | |||||
if (!ShadowCamera) ShadowCamera = GOShadowCamera.AddComponent<Camera>(); | |||||
else ShadowCamera = GOShadowCamera.GetComponent<Camera>(); | |||||
ShadowCamera.clearFlags = CameraClearFlags.Color; | |||||
ShadowCamera.backgroundColor = Color.black; | |||||
ShadowCamera.orthographic = true; | |||||
ShadowCamera.farClipPlane = 10000.0f; | |||||
ShadowCamera.enabled = false; | |||||
ShadowCamera.stereoTargetEye = StereoTargetEyeMask.None; | |||||
ShadowCamera.targetTexture = depthRT; | |||||
ShadowCamera.cullingMask &= ~(1 << LayerMask.NameToLayer("FogVolume")); | |||||
ShadowCamera.cullingMask &= ~(1 << LayerMask.NameToLayer("FogVolumeUniform")); | |||||
ShadowCamera.cullingMask &= ~(1 << LayerMask.NameToLayer("FogVolumeSurrogate")); | |||||
ShadowCamera.cullingMask &= ~(1 << LayerMask.NameToLayer("FogVolumeShadowCaster")); | |||||
//make it child | |||||
ShadowCamera.transform.parent = gameObject.transform; | |||||
Quad = GameObject.Find("Depth map background"); | |||||
if (!Quad) Quad = GameObject.CreatePrimitive(PrimitiveType.Quad); | |||||
Quad.name = "Depth map background"; | |||||
Quad.GetComponent<MeshRenderer>().sharedMaterial = QuadMaterial; | |||||
Quad.transform.parent = ShadowCamera.transform; | |||||
//remnove the collider | |||||
DestroyImmediate(Quad.GetComponent<MeshCollider>()); | |||||
Quad.hideFlags = HideFlags.HideInHierarchy; | |||||
} | |||||
void EnableVolumetricShadow(bool b) | |||||
{ | |||||
if (_TargetFogVolumes == null) { return; } | |||||
if (_TargetFogVolumes.Length > 0) | |||||
{ | |||||
float largestAxis = 0.0f; | |||||
int largestIndex = 0; | |||||
for (int FVindex = 0; FVindex < _TargetFogVolumes.Length; FVindex++) | |||||
{ | |||||
var fogVolume = _TargetFogVolumes[FVindex]; | |||||
if ((fogVolume != null) && (fogVolume._FogType == FogVolume.FogType.Textured)) | |||||
{ | |||||
if (fogVolume.enabled) | |||||
{ | |||||
FogVolumeMaterial = fogVolume.FogMaterial; | |||||
FogVolumeMaterial.SetInt("_VolumetricShadowsEnabled", b ? 1 : 0); | |||||
} | |||||
float largest = _MaxOf(fogVolume.fogVolumeScale.x, | |||||
fogVolume.fogVolumeScale.y, | |||||
fogVolume.fogVolumeScale.z); | |||||
if (largest > largestAxis) | |||||
{ | |||||
largestAxis = largest; | |||||
largestIndex = FVindex; | |||||
} | |||||
} | |||||
} | |||||
_ProminentFogVolume = _TargetFogVolumes[largestIndex]; | |||||
} | |||||
} | |||||
void Update() | |||||
{ | |||||
if (_CanvasImage.material != null) _CanvasImage.material = DebugViewMaterial; | |||||
if (!ShadowCamera) Initialize(); | |||||
if (_TargetFogVolumes != null && _AtLeastOneFogVolumeInArray()) | |||||
{ | |||||
EnableVolumetricShadow(depthRT); | |||||
LayersToRender &= ~(1 << LayerMask.NameToLayer("FogVolume")); | |||||
LayersToRender &= ~(1 << LayerMask.NameToLayer("FogVolumeUniform")); | |||||
LayersToRender &= ~(1 << LayerMask.NameToLayer("FogVolumeSurrogate")); | |||||
LayersToRender &= ~(1 << LayerMask.NameToLayer("FogVolumeShadowCaster")); | |||||
ShadowCamera.cullingMask = LayersToRender; | |||||
Refresh(); | |||||
// | |||||
//now, adjust camera size to make it see the whole volume | |||||
if (_ScaleMode == ScaleMode.VolumeMaxAxis) | |||||
{ | |||||
if (_ProminentFogVolume != null) | |||||
{ | |||||
ShadowCamera.orthographicSize = | |||||
_MaxOf(_ProminentFogVolume.fogVolumeScale.x, | |||||
_ProminentFogVolume.fogVolumeScale.y, | |||||
_ProminentFogVolume.fogVolumeScale.z) * .5f; | |||||
} | |||||
} | |||||
else ShadowCamera.orthographicSize = Scale; | |||||
// ShadowCamera.orthographicSize = CameraSize; | |||||
if (ShadowCamera.cullingMask != 0 && | |||||
_ProminentFogVolume != null && | |||||
_UpdateMode == UpdateMode.Interleaved) | |||||
{ | |||||
if (FogVolumeUtilities.ExtensionMethods.TimeSnap(SkipFrames)) | |||||
{ | |||||
Render(); | |||||
} | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
if (depthRT) | |||||
{ | |||||
DestroyImmediate(depthRT); | |||||
DestroyImmediate(GOShadowCamera); | |||||
} | |||||
} | |||||
if (!ShowMiniature && | |||||
_GO_Canvas.activeInHierarchy) _GO_Canvas.SetActive(ShowMiniature); | |||||
if (ShowMiniature && !_GO_Canvas.activeInHierarchy) _GO_Canvas.SetActive(ShowMiniature); | |||||
#if UNITY_EDITOR | |||||
if(ShowMiniature) | |||||
_CanvasImage.rectTransform.position = new Vector3(MiniaturePosition.x, MiniaturePosition.y, 0); | |||||
#endif | |||||
} | |||||
public void Refresh() | |||||
{ | |||||
if (_TargetFogVolumes == null) | |||||
{ | |||||
_ProminentFogVolume = null; | |||||
return; | |||||
} | |||||
for (int i = 0; i < _TargetFogVolumes.Length; i++) | |||||
{ | |||||
var fogVolume = _TargetFogVolumes[i]; | |||||
if ((fogVolume != null) && | |||||
(fogVolume._FogType == FogVolume.FogType.Textured)) | |||||
{ | |||||
if (fogVolume.HasUpdatedBoxMesh) | |||||
{ | |||||
float largestOfProminent = (_ProminentFogVolume != null) | |||||
? _MaxOf(_ProminentFogVolume.fogVolumeScale.x, | |||||
_ProminentFogVolume.fogVolumeScale.y, | |||||
_ProminentFogVolume.fogVolumeScale.z) | |||||
: 0.0f; | |||||
float largest = _MaxOf(fogVolume.fogVolumeScale.x, | |||||
fogVolume.fogVolumeScale.y, | |||||
fogVolume.fogVolumeScale.z); | |||||
if (largest > largestOfProminent) { _ProminentFogVolume = fogVolume; } | |||||
} | |||||
} | |||||
} | |||||
} | |||||
public void Render() | |||||
{ | |||||
if (!depthRT) | |||||
{ | |||||
Initialize(); | |||||
} | |||||
if (depthRT.height != (int) Size) | |||||
{ | |||||
DestroyImmediate(depthRT); | |||||
Initialize(); | |||||
// Debug.Log("A tomar por culo la textura"); | |||||
} | |||||
if ((int) _Antialiasing != depthRT.antiAliasing) | |||||
{ | |||||
DestroyImmediate(depthRT); | |||||
Initialize(); | |||||
} | |||||
if (!ShadowCamera) | |||||
{ | |||||
Initialize(); | |||||
} | |||||
switch (_FocusMode) | |||||
{ | |||||
case FocusMode.GameCameraPosition: | |||||
FocusPosition = _GameCamera.transform.position; | |||||
break; | |||||
case FocusMode.VolumeCenter: | |||||
if (_ProminentFogVolume != null) | |||||
{ | |||||
FocusPosition = _ProminentFogVolume.transform.position; | |||||
} | |||||
else | |||||
{ | |||||
FocusPosition = Vector3.zero; | |||||
} | |||||
break; | |||||
case FocusMode.GameObject: | |||||
if (_GameObjectFocus) FocusPosition = _GameObjectFocus.transform.position; | |||||
break; | |||||
} | |||||
//move the camera to the target center | |||||
Vector3 VerticalTranslate = new Vector3(0, | |||||
0, /* _TargetFogVolume.fogVolumeScale.y / 2*/ | |||||
FocusPosition.y - _CameraVerticalPosition); | |||||
ShadowCamera.transform.position = FocusPosition; | |||||
ShadowCamera.transform.Translate(VerticalTranslate, Space.Self); | |||||
Vector3 QuadScale = new Vector3(ShadowCamera.orthographicSize * 2, | |||||
ShadowCamera.orthographicSize * 2, | |||||
ShadowCamera.orthographicSize * 2); | |||||
Quad.transform.localScale = QuadScale; | |||||
//move it to the farclip | |||||
Quad.transform.position = ShadowCamera.transform.position; | |||||
Vector3 QuadTranslate = new Vector3(0, 0, ShadowCamera.farClipPlane - 50); | |||||
Quad.transform.Translate(QuadTranslate, Space.Self); | |||||
ShadowCamera.transform.rotation = Quaternion.LookRotation(transform.forward); | |||||
; | |||||
Shader.SetGlobalVector("_ShadowCameraPosition", ShadowCamera.transform.position); | |||||
Shader.SetGlobalMatrix("_ShadowCameraProjection", ShadowCamera.worldToCameraMatrix); | |||||
Shader.SetGlobalFloat("_ShadowCameraSize", ShadowCamera.orthographicSize); | |||||
Shader.SetGlobalVector("_ShadowLightDir", ShadowCamera.transform.forward); | |||||
//depthRT.DiscardContents(); | |||||
quadShader.maximumLOD = 1; | |||||
Shader.SetGlobalFloat("_FogVolumeShadowMapEdgeSoftness", | |||||
20.0f / _FogVolumeShadowMapEdgeSoftness); | |||||
ShadowCamera.RenderWithShader(outputDepth, "RenderType"); | |||||
quadShader.maximumLOD = 100; | |||||
Shader.SetGlobalTexture("_ShadowTexture", depthRT); | |||||
} | |||||
void OnDisable() | |||||
{ | |||||
DestroyImmediate(depthRT); | |||||
if (_GO_Canvas) _GO_Canvas.SetActive(false); | |||||
// DestroyImmediate(_Canvas); | |||||
// DestroyImmediate(GOShadowCamera); | |||||
// if (FogVolumeMaterial) | |||||
// FogVolumeUtilities.Rendering.EnsureKeyword(FogVolumeMaterial, "VOLUMETRIC_SHADOWS", false); | |||||
// FogVolumeMaterial.SetInt("_VolumetricShadowsEnabled", 0); | |||||
EnableVolumetricShadow(false); | |||||
} | |||||
private void OnDestroy() | |||||
{ | |||||
DestroyImmediate(GOShadowCamera); | |||||
// print("A la mierda!"); | |||||
DestroyImmediate(_GO_Canvas); | |||||
DestroyImmediate(Quad); | |||||
} | |||||
private bool _AtLeastOneFogVolumeInArray() | |||||
{ | |||||
if (_TargetFogVolumes != null) | |||||
{ | |||||
for (int i = 0; i < _TargetFogVolumes.Length; i++) | |||||
{ | |||||
if (_TargetFogVolumes[i] != null) { return true; } | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
public void AddAllFogVolumesToThisLight() | |||||
{ | |||||
_ProminentFogVolume = null; | |||||
var fogVolumes = FindObjectsOfType<FogVolume>(); | |||||
int validFogVolumeCount = 0; | |||||
for (int i = 0; i < fogVolumes.Length; i++) | |||||
{ | |||||
if ((fogVolumes[i] != null) && | |||||
(fogVolumes[i]._FogType == FogVolume.FogType.Textured)) { validFogVolumeCount++; } | |||||
} | |||||
_TargetFogVolumes = new FogVolume[validFogVolumeCount]; | |||||
int k = 0; | |||||
for (var i = 0; i < fogVolumes.Length; i++) | |||||
{ | |||||
var fogVolume = fogVolumes[i]; | |||||
if ((fogVolume != null) && (fogVolume._FogType == FogVolume.FogType.Textured)) | |||||
{ | |||||
_TargetFogVolumes[k++] = fogVolumes[i]; | |||||
} | |||||
} | |||||
} | |||||
public void RemoveAllFogVolumesFromThisLight() | |||||
{ | |||||
_ProminentFogVolume = null; | |||||
_TargetFogVolumes = null; | |||||
} | |||||
private float _MaxOf(float _a, float _b) { return _a >= _b ? _a : _b; } | |||||
private float _MaxOf(float _a, float _b, float _c) { return _MaxOf(_MaxOf(_a, _b), _c); } | |||||
} |
@ -0,0 +1,18 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 90a0ecd4363b0a547a4c174b9a95dd5d | |||||
timeCreated: 1499495303 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: | |||||
- _TargetFogVolume: {instanceID: 0} | |||||
- FogVolumeMaterial: {instanceID: 0} | |||||
- ShadowCamera: {instanceID: 0} | |||||
- outputDepth: {fileID: 4800000, guid: 4fc2932190d974a4887533f0e52baf6c, type: 3} | |||||
- GOShadowCamera: {instanceID: 0} | |||||
- DebugViewMaterial: {fileID: 2100000, guid: 92dc32887d2555f469466609a34e858c, type: 2} | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,381 @@ | |||||
#if GAIA_PRESENT && UNITY_EDITOR | |||||
using UnityEngine; | |||||
using System; | |||||
using UnityEditor; | |||||
using UnityEngine.Rendering; | |||||
namespace Gaia.GX.FogVolume3 | |||||
{ | |||||
/// <summary> | |||||
/// Fog Volume 3 creator for Gaia. | |||||
/// </summary> | |||||
public class FogVolumeGaiaIntegration : MonoBehaviour | |||||
{ | |||||
#region Generic informational methods | |||||
/// <summary> | |||||
/// Returns the publisher name if provided. | |||||
/// This will override the publisher name in the namespace ie Gaia.GX.PublisherName | |||||
/// </summary> | |||||
/// <returns>Publisher name</returns> | |||||
public static string GetPublisherName() | |||||
{ | |||||
return "David Miranda"; | |||||
} | |||||
/// <summary> | |||||
/// Returns the package name if provided | |||||
/// This will override the package name in the class name ie public class PackageName. | |||||
/// </summary> | |||||
/// <returns>Package name</returns> | |||||
public static string GetPackageName() | |||||
{ | |||||
return "Fog Volume 3"; | |||||
} | |||||
#endregion | |||||
#region Methods exposed by Gaia as buttons must be prefixed with GX_ | |||||
public static void GX_About() | |||||
{ | |||||
EditorUtility.DisplayDialog("About Fog Volume 3", "This integration adds Fog Volume 3 to your scene. After adding your Fog Volume components adjust their Y positions to better suit your scene. Also pay attention to the Fog Volume settings on your main camera. For example changing falloff will reduce the blur applied to distant clouds.", "OK"); | |||||
} | |||||
public static void GX_Setup_AddGroundFog() | |||||
{ | |||||
//Pick colour of main light | |||||
GameObject goLight = GameObject.Find("Directional Light"); | |||||
Light mainLight = null; | |||||
if (goLight != null) | |||||
{ | |||||
mainLight = goLight.GetComponent<Light>(); | |||||
} | |||||
else | |||||
{ | |||||
mainLight = GameObject.FindObjectOfType<Light>(); | |||||
} | |||||
Color mainLightColor = Color.white; | |||||
if (mainLight != null) | |||||
{ | |||||
mainLightColor = mainLight.color; | |||||
} | |||||
//First make sure its not already in scene | |||||
GameObject fvGroundFog = GameObject.Find("Fog Volume [Ground Fog]"); | |||||
if (fvGroundFog == null) | |||||
{ | |||||
fvGroundFog = new GameObject(); | |||||
fvGroundFog.name = "Fog Volume [Ground Fog]"; | |||||
fvGroundFog.AddComponent<MeshRenderer>(); | |||||
fvGroundFog.AddComponent<FogVolume>(); | |||||
fvGroundFog.GetComponent<Renderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; | |||||
fvGroundFog.GetComponent<Renderer>().receiveShadows = false; | |||||
fvGroundFog.GetComponent<Renderer>().reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off; | |||||
fvGroundFog.GetComponent<Renderer>().lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off; | |||||
} | |||||
//Adjust its position and size | |||||
FogVolume fvVolume = fvGroundFog.GetComponent<FogVolume>(); | |||||
if (fvVolume != null) | |||||
{ | |||||
GaiaSceneInfo info = GaiaSceneInfo.GetSceneInfo(); | |||||
Debug.Log(info.m_seaLevel); | |||||
fvVolume.transform.position = new Vector3(info.m_sceneBounds.center.x, info.m_seaLevel + 0.01f + (info.m_sceneBounds.extents.y / 4f), info.m_sceneBounds.center.z );// info.m_sceneBounds.center; | |||||
fvVolume.fogVolumeScale = new Vector3(info.m_sceneBounds.size.x * 3, info.m_sceneBounds.extents.y / 2f, info.m_sceneBounds.size.z * 3); | |||||
//And adjust camera far clip as well | |||||
float maxClip = Math.Max(info.m_sceneBounds.size.x, info.m_sceneBounds.size.z) * 3f; | |||||
Camera mainCamera = Camera.main; | |||||
if (mainCamera != null) | |||||
{ | |||||
if (mainCamera.farClipPlane < maxClip) | |||||
{ | |||||
mainCamera.farClipPlane = maxClip + 200f; | |||||
} | |||||
} | |||||
fvVolume.FogMainColor = new Color(53f/255f, 76f/255f, 114f/255f); | |||||
//fvVolume.Visibility = maxClip; | |||||
fvVolume.Visibility = 800f; | |||||
fvVolume.EnableInscattering = true; | |||||
fvVolume.InscatteringColor = Color.Lerp(mainLightColor, Color.black, 0.8f); | |||||
fvVolume.VolumeFogInscatteringAnisotropy = 0.59f; | |||||
fvVolume.InscatteringIntensity = 0.07f; | |||||
fvVolume.InscatteringStartDistance = 5f; | |||||
fvVolume.InscatteringTransitionWideness = 300f; | |||||
//Other | |||||
fvVolume.DrawOrder = 3; | |||||
fvVolume._PushAlpha = 1.0025f; | |||||
fvVolume._ztest = CompareFunction.Always; | |||||
} | |||||
} | |||||
public static void GX_Setup_AddClouds() | |||||
{ | |||||
//Pick colour of main light | |||||
Color mainLightColor = Color.white; | |||||
GameObject goLight = GameObject.Find("Directional Light"); | |||||
Light mainLight; | |||||
if (goLight != null) | |||||
{ | |||||
mainLight = goLight.GetComponent<Light>(); | |||||
} | |||||
else | |||||
{ | |||||
mainLight = GameObject.FindObjectOfType<Light>(); | |||||
} | |||||
if (mainLight != null) | |||||
{ | |||||
mainLightColor = mainLight.color; | |||||
} | |||||
//Get the main camera | |||||
Camera mainCamera = Camera.main; | |||||
//First make sure its not already in scene - if it isnt then add it | |||||
FogVolume fvVolume; | |||||
GameObject goClouds = GameObject.Find("Fog Volume [Clouds]"); | |||||
if (goClouds == null) | |||||
{ | |||||
goClouds = new GameObject(); | |||||
goClouds.name = "Fog Volume [Clouds]"; | |||||
goClouds.AddComponent<MeshRenderer>(); | |||||
fvVolume = goClouds.AddComponent<FogVolume>(); | |||||
goClouds.GetComponent<Renderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; | |||||
goClouds.GetComponent<Renderer>().receiveShadows = false; | |||||
goClouds.GetComponent<Renderer>().reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off; | |||||
goClouds.GetComponent<Renderer>().lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off; | |||||
//Create the horizon | |||||
GameObject goHorizon = GameObject.CreatePrimitive(PrimitiveType.Plane); | |||||
goHorizon.name = "Horizon"; | |||||
goHorizon.transform.parent = goClouds.transform; | |||||
goHorizon.transform.localPosition = new Vector3(0f, -79f, 0f); | |||||
goHorizon.GetComponent<MeshRenderer>().enabled = false; | |||||
goHorizon.GetComponent<MeshCollider>().enabled = false; | |||||
//Create the priority script | |||||
FogVolumePriority fvPriority = goClouds.AddComponent<FogVolumePriority>(); | |||||
fvPriority.GameCamera = mainCamera; | |||||
fvPriority.FogOrderCameraAbove = 4; | |||||
fvPriority.FogOrderCameraBelow = -1; | |||||
fvPriority.thisFog = fvVolume; | |||||
fvPriority.Horizon = goHorizon; | |||||
} | |||||
//Adjust its position and size | |||||
fvVolume = goClouds.GetComponent<FogVolume>(); | |||||
if (fvVolume != null) | |||||
{ | |||||
GaiaSceneInfo info = GaiaSceneInfo.GetSceneInfo(); | |||||
//Location and scale | |||||
fvVolume.transform.position = new Vector3(info.m_sceneBounds.center.x, info.m_seaLevel + 200f, info.m_sceneBounds.center.z);// info.m_sceneBounds.center; | |||||
fvVolume.fogVolumeScale = new Vector3(info.m_sceneBounds.size.x * 3, 100f, info.m_sceneBounds.size.z * 3); | |||||
//Camera far clip | |||||
float maxClip = Math.Max(info.m_sceneBounds.size.x, info.m_sceneBounds.size.z) * 3f; | |||||
if (mainCamera != null) | |||||
{ | |||||
if (mainCamera.farClipPlane < maxClip) | |||||
{ | |||||
mainCamera.farClipPlane = maxClip + 200f; | |||||
} | |||||
} | |||||
//Fog type and blend mode | |||||
fvVolume._FogType = FogVolume.FogType.Textured; | |||||
fvVolume._BlendMode = FogVolumeRenderer.BlendMode.PremultipliedTransparency; | |||||
//Lighting | |||||
fvVolume._AmbientColor = Color.Lerp(mainLightColor, Color.black, 0.1f); | |||||
fvVolume.useHeightGradient = true; | |||||
fvVolume.Absorption = 0.8f; | |||||
fvVolume.HeightAbsorption = 0.185f; | |||||
fvVolume.bAbsorption = true; | |||||
fvVolume.EnableInscattering = true; | |||||
fvVolume.InscatteringColor = mainLightColor; | |||||
fvVolume.InscatteringShape = 0.05f; | |||||
fvVolume.InscatteringIntensity = 0.882f; | |||||
fvVolume.InscatteringStartDistance = 0f; | |||||
fvVolume.InscatteringTransitionWideness = 1f; | |||||
fvVolume._DirectionalLighting = true; | |||||
fvVolume.LightExtinctionColor = Color.Lerp(mainLightColor, Color.black, 0.8f); | |||||
fvVolume._DirectionalLightingDistance = 0.0008f; | |||||
fvVolume.DirectLightingShadowDensity = 6f; | |||||
fvVolume.DirectLightingShadowSteps = 1; | |||||
//Renderer | |||||
fvVolume.NoiseIntensity = 1f; | |||||
fvVolume.SceneCollision = false; //Faster i suppose ? | |||||
fvVolume.Iterations = 500; | |||||
fvVolume.IterationStep = 100; | |||||
fvVolume._OptimizationFactor = 0.0000005f; | |||||
fvVolume.GradMin = 0.19f; | |||||
fvVolume.GradMax = 0.06f; | |||||
fvVolume.GradMin2 = -0.25f; | |||||
fvVolume.GradMax2 = 0.21f; | |||||
//Noise | |||||
fvVolume.EnableNoise = true; | |||||
fvVolume._3DNoiseScale = 0.15f; | |||||
fvVolume.Speed = new Vector4(0.49f, 0f, 0f, 0f); | |||||
fvVolume.Vortex = 0.47f; | |||||
fvVolume.RotationSpeed = 0f; | |||||
fvVolume.rotation = 324f; | |||||
fvVolume._VortexAxis = FogVolume.VortexAxis.Y; | |||||
fvVolume.Coverage = 2.44f; | |||||
fvVolume.NoiseContrast = 12.9f; | |||||
fvVolume.NoiseDensity = 0.2f; | |||||
fvVolume.Octaves = 3; | |||||
fvVolume.BaseTiling = 150f; | |||||
fvVolume._BaseRelativeSpeed = 0.85f; | |||||
fvVolume.DetailTiling = 285.3f; | |||||
fvVolume._DetailRelativeSpeed = 16.6f; | |||||
fvVolume.DetailDistance = 5000f; | |||||
fvVolume._NoiseDetailRange = 0.337f; | |||||
fvVolume._DetailMaskingThreshold = 8f; | |||||
fvVolume._Curl = 0.364f; | |||||
//Other | |||||
fvVolume.DrawOrder = 4; | |||||
fvVolume._ztest = CompareFunction.LessEqual; | |||||
fvVolume.CreateSurrogate = true; | |||||
} | |||||
} | |||||
public static void GX_Setup_AddPostEffects() | |||||
{ | |||||
//Update renderer settings to dampen things down a bit for newcomers | |||||
FogVolumeRenderer fvRenderer = GameObject.FindObjectOfType<FogVolumeRenderer>(); | |||||
if (fvRenderer != null) | |||||
{ | |||||
fvRenderer._Downsample = 3; | |||||
fvRenderer._BlendMode = FogVolumeRenderer.BlendMode.PremultipliedTransparency; | |||||
fvRenderer.GenerateDepth = false; | |||||
} | |||||
//Add screen if missing | |||||
FogVolumeScreen fvScreen = GameObject.FindObjectOfType<FogVolumeScreen>(); | |||||
if (fvScreen == null && Camera.main != null) | |||||
{ | |||||
fvScreen = Camera.main.gameObject.AddComponent<FogVolumeScreen>(); | |||||
fvScreen.Downsample = 3; | |||||
fvScreen.iterations = 3; | |||||
fvScreen.blurSpread = 0.2f; | |||||
} | |||||
} | |||||
public static void GX_Quality_Low() | |||||
{ | |||||
//What about ground fog and cloud settings ? | |||||
GameObject goGroundFog = GameObject.Find("Fog Volume [Ground Fog]"); | |||||
if (goGroundFog != null) | |||||
{ | |||||
FogVolume fvGroundFog = goGroundFog.GetComponent<FogVolume>(); | |||||
if (fvGroundFog != null) | |||||
{ | |||||
//Make adjustments | |||||
} | |||||
} | |||||
GameObject goClouds = GameObject.Find("Fog Volume [Clouds]"); | |||||
if (goClouds != null) | |||||
{ | |||||
FogVolume fvClouds = goClouds.GetComponent<FogVolume>(); | |||||
if (fvClouds != null) | |||||
{ | |||||
//Make adjustments | |||||
} | |||||
} | |||||
//Update renderer settings | |||||
FogVolumeRenderer fvRenderer = GameObject.FindObjectOfType<FogVolumeRenderer>(); | |||||
if (fvRenderer != null) | |||||
{ | |||||
fvRenderer._Downsample = 8; | |||||
fvRenderer._BlendMode = FogVolumeRenderer.BlendMode.PremultipliedTransparency; | |||||
} | |||||
//Update screen settings | |||||
FogVolumeScreen fvScreen = GameObject.FindObjectOfType<FogVolumeScreen>(); | |||||
if (fvScreen != null) | |||||
{ | |||||
} | |||||
} | |||||
public static void GX_Quality_Medium() | |||||
{ | |||||
//What about ground fog and cloud settings ? | |||||
//Update renderer settings | |||||
FogVolumeRenderer fvRenderer = GameObject.FindObjectOfType<FogVolumeRenderer>(); | |||||
if (fvRenderer != null) | |||||
{ | |||||
fvRenderer._Downsample = 4; | |||||
} | |||||
//Update screen settings | |||||
FogVolumeScreen fvScreen = GameObject.FindObjectOfType<FogVolumeScreen>(); | |||||
if (fvScreen != null) | |||||
{ | |||||
} | |||||
} | |||||
public static void GX_Quality_High() | |||||
{ | |||||
//What about ground fog and cloud settings ? | |||||
//Update renderer settings | |||||
FogVolumeRenderer fvRenderer = GameObject.FindObjectOfType<FogVolumeRenderer>(); | |||||
if (fvRenderer != null) | |||||
{ | |||||
fvRenderer._Downsample = 2; | |||||
} | |||||
//Update screen settings | |||||
FogVolumeScreen fvScreen = GameObject.FindObjectOfType<FogVolumeScreen>(); | |||||
if (fvScreen != null) | |||||
{ | |||||
} | |||||
} | |||||
public static void GX_Quality_Epic() | |||||
{ | |||||
//What about ground fog and cloud settings ? | |||||
//Update renderer settings | |||||
FogVolumeRenderer fvRenderer = GameObject.FindObjectOfType<FogVolumeRenderer>(); | |||||
if (fvRenderer != null) | |||||
{ | |||||
fvRenderer._Downsample = 0; | |||||
} | |||||
//Update screen settings | |||||
FogVolumeScreen fvScreen = GameObject.FindObjectOfType<FogVolumeScreen>(); | |||||
if (fvScreen != null) | |||||
{ | |||||
} | |||||
} | |||||
#endregion | |||||
} | |||||
} | |||||
#endif |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 3a51fd1c984059a439eca4d3320cbeca | |||||
timeCreated: 1502613915 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,26 @@ | |||||
using System.Collections; | |||||
using System.Collections.Generic; | |||||
using UnityEngine; | |||||
[ExecuteInEditMode] | |||||
public class FogVolumeLight : MonoBehaviour | |||||
{ | |||||
private void OnEnable() | |||||
{ | |||||
SphereCollider collider = GetComponent<SphereCollider>(); | |||||
#if UNITY_EDITOR | |||||
if (collider != null) { DestroyImmediate(collider); } | |||||
#else | |||||
if (collider != null) { Destroy(collider); } | |||||
#endif | |||||
} | |||||
public bool IsAddedToNormalLight; | |||||
public bool IsPointLight; | |||||
public bool Enabled = true; | |||||
public Color Color = Color.white; | |||||
public float Intensity = 1.0f; | |||||
public float Range = 10.0f; | |||||
public float Angle = 30.0f; | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 11fa16dd62c21c54189e4e55b0bd978c | |||||
timeCreated: 1489615659 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {fileID: 2800000, guid: 925eb9f7b0e73dd438a616124964bba8, type: 3} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,845 @@ | |||||
using System; | |||||
using System.Collections; | |||||
using System.Collections.Generic; | |||||
using UnityEngine; | |||||
using UnityEngine.Assertions; | |||||
//================================================================================================= | |||||
/** | |||||
* @brief This class manages all lights for a particular FogVolume. | |||||
* | |||||
*************************************************************************************************/ | |||||
public class FogVolumeLightManager : MonoBehaviour | |||||
{ | |||||
public int CurrentLightCount { get; private set; } | |||||
public int VisibleLightCount { get; private set; } | |||||
public bool DrawDebugData { get; set; } | |||||
public bool AlreadyUsesTransformForPoI { get { return m_pointOfInterestTf != null; } } | |||||
// Very slow and garbage allocating. Only call this once! | |||||
public void FindLightsInScene() | |||||
{ | |||||
CurrentLightCount = 0; | |||||
VisibleLightCount = 0; | |||||
m_lights.Clear(); | |||||
m_lightsInFrustum.Clear(); | |||||
for (int i = 0; i < MaxLightCount; i++) | |||||
{ | |||||
m_lights.Add(new LightData()); | |||||
m_lightsInFrustum.Add(new LightData()); | |||||
} | |||||
FogVolumeLight[] lights = FindObjectsOfType<FogVolumeLight>(); | |||||
for (int i = 0; i < lights.Length; i++) | |||||
{ | |||||
Light unityLight = lights[i].GetComponent<Light>(); | |||||
if (unityLight != null) | |||||
{ | |||||
switch (unityLight.type) | |||||
{ | |||||
case LightType.Point: | |||||
{ | |||||
AddPointLight(unityLight); | |||||
lights[i].IsAddedToNormalLight = true; | |||||
break; | |||||
} | |||||
case LightType.Spot: | |||||
{ | |||||
AddSpotLight(unityLight); | |||||
lights[i].IsAddedToNormalLight = true; | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
if (lights[i].IsPointLight) | |||||
{ | |||||
AddSimulatedPointLight(lights[i]); | |||||
lights[i].IsAddedToNormalLight = false; | |||||
} | |||||
else | |||||
{ | |||||
AddSimulatedSpotLight(lights[i]); | |||||
lights[i].IsAddedToNormalLight = false; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
// Very slow and garbage allocating. Only call this once! | |||||
public void FindLightsInFogVolume() | |||||
{ | |||||
CurrentLightCount = 0; | |||||
VisibleLightCount = 0; | |||||
m_lights.Clear(); | |||||
m_lightsInFrustum.Clear(); | |||||
for (int i = 0; i < MaxLightCount; i++) | |||||
{ | |||||
m_lights.Add(new LightData()); | |||||
m_lightsInFrustum.Add(new LightData()); | |||||
} | |||||
if (m_boxCollider == null) { m_boxCollider = gameObject.GetComponent<BoxCollider>(); } | |||||
Bounds boundingBox = m_boxCollider.bounds; | |||||
FogVolumeLight[] lights = FindObjectsOfType<FogVolumeLight>(); | |||||
for (int i = 0; i < lights.Length; i++) | |||||
{ | |||||
if (boundingBox.Intersects(new Bounds(lights[i].gameObject.transform.position, | |||||
Vector3.one * LightInVolumeBoundsSize))) | |||||
{ | |||||
Light unityLight = lights[i].GetComponent<Light>(); | |||||
if (unityLight != null) | |||||
{ | |||||
switch (unityLight.type) | |||||
{ | |||||
case LightType.Point: | |||||
{ | |||||
AddPointLight(unityLight); | |||||
lights[i].IsAddedToNormalLight = true; | |||||
break; | |||||
} | |||||
case LightType.Spot: | |||||
{ | |||||
AddSpotLight(unityLight); | |||||
lights[i].IsAddedToNormalLight = true; | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
if (lights[i].IsPointLight) | |||||
{ | |||||
AddSimulatedPointLight(lights[i]); | |||||
lights[i].IsAddedToNormalLight = false; | |||||
} | |||||
else | |||||
{ | |||||
AddSimulatedSpotLight(lights[i]); | |||||
lights[i].IsAddedToNormalLight = false; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Add a simulated point light to the manager. | |||||
* | |||||
* Note that a simulated point light is any GameObject with a SimulatedPointLight component on | |||||
* it. | |||||
* | |||||
* @param _light The SimulatedPointLight component of an existing GameObject. | |||||
* | |||||
* @return True if the light was added to the managers list of lights. | |||||
* @return False if the manager already contains the maximum amount of lights that was | |||||
* specified in the constructor. | |||||
* | |||||
*********************************************************************************************/ | |||||
public bool AddSimulatedPointLight(FogVolumeLight _light) | |||||
{ | |||||
Assert.IsTrue(CurrentLightCount < MaxLightCount, | |||||
"The maximum number of lights is already reached!"); | |||||
int index = _FindFirstFreeLight(); | |||||
if (index != InvalidIndex) | |||||
{ | |||||
LightData data = m_lights[index]; | |||||
CurrentLightCount++; | |||||
data.LightType = EFogVolumeLightType.FogVolumePointLight; | |||||
data.Transform = _light.transform; | |||||
data.Light = null; | |||||
data.FogVolumeLight = _light; | |||||
data.Bounds = new Bounds(data.Transform.position, | |||||
Vector3.one * data.FogVolumeLight.Range * 2.5f); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Add a simulated spot light to the manager. | |||||
* | |||||
* Note that a simulated spot light is any GameObject with a SimulatedSpotLight component on | |||||
* it. | |||||
* | |||||
* @param _light The SimulatedSpotLight component of an existing GameObject. | |||||
* | |||||
* @return True if the light was added to the managers list of lights. | |||||
* @return False if the manager already contains the maximum amount of lights that was | |||||
* specified in the constructor. | |||||
* | |||||
*********************************************************************************************/ | |||||
public bool AddSimulatedSpotLight(FogVolumeLight _light) | |||||
{ | |||||
Assert.IsTrue(CurrentLightCount < MaxLightCount, | |||||
"The maximum number of lights is already reached!"); | |||||
int index = _FindFirstFreeLight(); | |||||
if (index != InvalidIndex) | |||||
{ | |||||
LightData data = m_lights[index]; | |||||
CurrentLightCount++; | |||||
data.LightType = EFogVolumeLightType.FogVolumeSpotLight; | |||||
data.Transform = _light.transform; | |||||
data.Light = null; | |||||
data.FogVolumeLight = _light; | |||||
Vector3 center = data.Transform.position + | |||||
data.Transform.forward * data.FogVolumeLight.Range * 0.5f; | |||||
data.Bounds = new Bounds(center, | |||||
Vector3.one * data.FogVolumeLight.Range * | |||||
(0.75f + data.FogVolumeLight.Angle * 0.03f)); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Add an existing point light to the manager. | |||||
* | |||||
* @param _light The light component of an existing point light. | |||||
* | |||||
* @return True if the light was added to the managers list of lights. | |||||
* @return False if the manager already contains the maximum amount of lights that was | |||||
* specified in the constructor. | |||||
* | |||||
*********************************************************************************************/ | |||||
public bool AddPointLight(Light _light) | |||||
{ | |||||
Assert.IsTrue(CurrentLightCount < MaxLightCount, | |||||
"The maximum number of lights is already reached!"); | |||||
int index = _FindFirstFreeLight(); | |||||
if (index != InvalidIndex) | |||||
{ | |||||
LightData data = m_lights[index]; | |||||
CurrentLightCount++; | |||||
data.LightType = EFogVolumeLightType.PointLight; | |||||
data.Transform = _light.transform; | |||||
data.Light = _light; | |||||
data.FogVolumeLight = null; | |||||
data.Bounds = new Bounds(data.Transform.position, | |||||
Vector3.one * data.Light.range * 2.5f); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Add an existing spot light to the manager. | |||||
* | |||||
* @param _light The light component of an existing spot light. | |||||
* | |||||
* @return True if the light was added to the managers list of lights. | |||||
* @return False if the manager already contains the maximum amount of lights that was | |||||
* specified in the constructor. | |||||
* | |||||
*********************************************************************************************/ | |||||
public bool AddSpotLight(Light _light) | |||||
{ | |||||
Assert.IsTrue(CurrentLightCount < MaxLightCount, | |||||
"The maximum number of lights is already reached!"); | |||||
int index = _FindFirstFreeLight(); | |||||
if (index != InvalidIndex) | |||||
{ | |||||
LightData data = m_lights[index]; | |||||
CurrentLightCount++; | |||||
data.LightType = EFogVolumeLightType.SpotLight; | |||||
data.Transform = _light.transform; | |||||
data.Light = _light; | |||||
data.FogVolumeLight = null; | |||||
Vector3 center = data.Transform.position + | |||||
data.Transform.forward * data.Light.range * 0.5f; | |||||
data.Bounds = new Bounds(center, | |||||
Vector3.one * data.Light.range * | |||||
(0.75f + data.Light.spotAngle * 0.03f)); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Removes the light with the specified transform. | |||||
* | |||||
* Note that nothing will happen if the light is not currently present in the manager. | |||||
* | |||||
* @param _lightToRemove The light that will be removed from this manager. | |||||
* | |||||
* @return True if the light was found inside the manager and removed successfully. | |||||
* @return False if the light was not found an thus not removed. | |||||
* | |||||
*********************************************************************************************/ | |||||
public bool RemoveLight(Transform _lightToRemove) | |||||
{ | |||||
int count = m_lights.Count; | |||||
for (int i = 0; i < count; i++) | |||||
{ | |||||
if (ReferenceEquals(m_lights[i].Transform, _lightToRemove)) | |||||
{ | |||||
m_lights[i].LightType = EFogVolumeLightType.None; | |||||
CurrentLightCount--; | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Updates the lights that will be rendered. | |||||
* | |||||
* Note that this method should be called once per frame, before any data is sent to the | |||||
* shaders. | |||||
* | |||||
*********************************************************************************************/ | |||||
public void ManualUpdate(ref Plane[] _frustumPlanes) | |||||
{ | |||||
FrustumPlanes = _frustumPlanes; | |||||
m_camera = m_fogVolumeData != null ? m_fogVolumeData.GameCamera : null; | |||||
if (m_camera == null) { return; } | |||||
if (m_boxCollider == null) { m_boxCollider = m_fogVolume.GetComponent<BoxCollider>(); } | |||||
if (m_pointOfInterestTf != null) { m_pointOfInterest = m_pointOfInterestTf.position; } | |||||
_UpdateBounds(); | |||||
_FindLightsInFrustum(); | |||||
if (m_lightsInFrustum.Count > MaxVisibleLights) { _SortLightsInFrustum(); } | |||||
_PrepareShaderArrays(); | |||||
} | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Draws the gizmos if the user wants to see debug data. | |||||
* | |||||
*********************************************************************************************/ | |||||
public void OnDrawGizmos() | |||||
{ | |||||
hideFlags = HideFlags.HideInInspector; | |||||
if (m_camera == null) { return; } | |||||
if (!DrawDebugData) { return; } | |||||
Color tempColor = Gizmos.color; | |||||
Gizmos.color = Color.green; | |||||
for (int i = 0; i < VisibleLightCount; i++) | |||||
{ | |||||
Gizmos.DrawWireCube(m_lightsInFrustum[i].Bounds.center, | |||||
m_lightsInFrustum[i].Bounds.size); | |||||
} | |||||
Gizmos.color = Color.magenta; | |||||
Matrix4x4 currentMatrix = Gizmos.matrix; | |||||
Gizmos.matrix = Matrix4x4.TRS(m_camera.transform.position, | |||||
m_camera.transform.rotation, | |||||
Vector3.one); | |||||
//Gizmos.matrix = transform.localToWorldMatrix; | |||||
Gizmos.DrawFrustum(m_camera.transform.position, | |||||
m_camera.fieldOfView, | |||||
m_camera.nearClipPlane, | |||||
m_fogVolume.PointLightingDistance2Camera, | |||||
m_camera.aspect); | |||||
Gizmos.color = tempColor; | |||||
Gizmos.matrix = currentMatrix; | |||||
} | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Sets the multiplier that is applied to the bounding box size of point lights. | |||||
* | |||||
* @param _cullSizeMultiplier The multiplier that is applied to the AABB of point lights. | |||||
* | |||||
*********************************************************************************************/ | |||||
public void SetPointLightCullSizeMultiplier(float _cullSizeMultiplier) | |||||
{ | |||||
m_pointLightCullSizeMultiplier = _cullSizeMultiplier; | |||||
} | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Sets the point of interest to a fixed position. | |||||
* | |||||
* @param _pointOfInterest The point that will be used for prioritizing which lights need to | |||||
* be rendered. | |||||
* | |||||
*********************************************************************************************/ | |||||
public void SetPointOfInterest(Vector3 _pointOfInterest) | |||||
{ | |||||
m_pointOfInterestTf = null; | |||||
m_pointOfInterest = _pointOfInterest; | |||||
} | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Sets the point of interest to the specified transform. | |||||
* | |||||
* The point of interest will be updated from the position of the transform. It is therefore | |||||
* not necessary to call this method more than once. | |||||
* | |||||
*********************************************************************************************/ | |||||
public void SetPointOfInterest(Transform _pointOfInterest) | |||||
{ | |||||
Assert.IsTrue(_pointOfInterest != null, "_pointOfInterest must not be null!"); | |||||
m_pointOfInterestTf = _pointOfInterest; | |||||
} | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Returns the array that contains all light positions. | |||||
* | |||||
* Remember to call Update() before using this method, otherwise old data will be sent to the | |||||
* shaders. | |||||
* | |||||
*********************************************************************************************/ | |||||
public Vector4[] GetLightPositionArray() { return m_lightPos; } | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Returns the array that contains all light rotations. | |||||
* | |||||
* Remember to call Update() before using this method, otherwise old data will be sent to the | |||||
* shaders. | |||||
* | |||||
*********************************************************************************************/ | |||||
public Vector4[] GetLightRotationArray() { return m_lightRot; } | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Returns the array that contains all light colors. | |||||
* | |||||
* Remember to call Update() before using this method, otherwise old data will be sent to the | |||||
* shaders. | |||||
*********************************************************************************************/ | |||||
public Color[] GetLightColorArray() { return m_lightColor; } | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Returns the array that contains all light data (intensity, range, spotlight angle, | |||||
* none). | |||||
* | |||||
* Remember to call Update() before using this method, otherwise old data will be sent to the | |||||
* shaders. | |||||
* | |||||
*********************************************************************************************/ | |||||
public Vector4[] GetLightData() { return m_lightData; } | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Initializes the LightManager with default values. | |||||
* | |||||
*********************************************************************************************/ | |||||
public void Initialize() | |||||
{ | |||||
m_fogVolume = gameObject.GetComponent<FogVolume>(); | |||||
m_fogVolumeData = FindObjectOfType<FogVolumeData>(); | |||||
m_camera = null; | |||||
m_boxCollider = null; | |||||
CurrentLightCount = 0; | |||||
DrawDebugData = false; | |||||
if (m_lights == null) | |||||
{ | |||||
m_lights = new List<LightData>(MaxLightCount); | |||||
m_lightsInFrustum = new List<LightData>(MaxLightCount); | |||||
for (int i = 0; i < MaxLightCount; i++) | |||||
{ | |||||
m_lights.Add(new LightData()); | |||||
m_lightsInFrustum.Add(new LightData()); | |||||
} | |||||
} | |||||
} | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Clears the LightManager and prepares it toi be reinitialized. | |||||
* | |||||
*********************************************************************************************/ | |||||
public void Deinitialize() | |||||
{ | |||||
VisibleLightCount = 0; | |||||
DrawDebugData = false; | |||||
} | |||||
public void SetFrustumPlanes(ref Plane[] _frustumPlanes) { FrustumPlanes = _frustumPlanes; } | |||||
#if UNITY_EDITOR | |||||
private void Update() { hideFlags = HideFlags.HideInInspector; } | |||||
#endif | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Updates the axis aligned bounding boxes of all registered lights. | |||||
* | |||||
*********************************************************************************************/ | |||||
private void _UpdateBounds() | |||||
{ | |||||
int count = m_lights.Count; | |||||
for (int i = 0; i < count; i++) | |||||
{ | |||||
LightData data = m_lights[i]; | |||||
if (data.LightType == EFogVolumeLightType.None) { continue; } | |||||
switch (data.LightType) | |||||
{ | |||||
case EFogVolumeLightType.None: | |||||
{ | |||||
break; | |||||
} | |||||
case EFogVolumeLightType.PointLight: | |||||
{ | |||||
data.Bounds = new Bounds(data.Transform.position, | |||||
Vector3.one * data.Light.range * | |||||
m_pointLightCullSizeMultiplier); | |||||
break; | |||||
} | |||||
case EFogVolumeLightType.SpotLight: | |||||
{ | |||||
Vector3 center = data.Transform.position + | |||||
data.Transform.forward * data.Light.range * 0.5f; | |||||
data.Bounds = new Bounds(center, | |||||
Vector3.one * data.Light.range * | |||||
m_pointLightCullSizeMultiplier * 1.25f); | |||||
break; | |||||
} | |||||
case EFogVolumeLightType.FogVolumePointLight: | |||||
{ | |||||
data.Bounds = new Bounds(data.Transform.position, | |||||
Vector3.one * data.FogVolumeLight.Range * | |||||
m_pointLightCullSizeMultiplier); | |||||
break; | |||||
} | |||||
case EFogVolumeLightType.FogVolumeSpotLight: | |||||
{ | |||||
Vector3 center = data.Transform.position + | |||||
data.Transform.forward * data.FogVolumeLight.Range * 0.5f; | |||||
data.Bounds = new Bounds(center, | |||||
Vector3.one * data.FogVolumeLight.Range * | |||||
m_pointLightCullSizeMultiplier * 1.25f); | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Finds the first free light in the list of all lights. | |||||
* | |||||
* Note that this method is necessary to ensure that adding/removing lights does not allocate | |||||
* any garbage. | |||||
* | |||||
*********************************************************************************************/ | |||||
private int _FindFirstFreeLight() | |||||
{ | |||||
if (CurrentLightCount < MaxLightCount) | |||||
{ | |||||
int count = m_lights.Count; | |||||
for (int i = 0; i < count; i++) | |||||
{ | |||||
if (m_lights[i].LightType == EFogVolumeLightType.None) { return i; } | |||||
} | |||||
} | |||||
return InvalidIndex; | |||||
} | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Finds all lights that are currently in the view frustum of the camera and calculates | |||||
* all necessary data for them. | |||||
* | |||||
*********************************************************************************************/ | |||||
private void _FindLightsInFrustum() | |||||
{ | |||||
m_inFrustumCount = 0; | |||||
Vector3 CameraPos = m_camera.gameObject.transform.position; | |||||
int count = m_lights.Count; | |||||
for (int i = 0; i < count; i++) | |||||
{ | |||||
if (m_lights[i].Transform == null) { m_lights[i].LightType = EFogVolumeLightType.None; } | |||||
if (m_lights[i].LightType == EFogVolumeLightType.None) { continue; } | |||||
float distanceToCamera = (m_lights[i].Transform.position - CameraPos).magnitude; | |||||
if (distanceToCamera > m_fogVolume.PointLightingDistance2Camera) { continue; } | |||||
switch (m_lights[i].LightType) | |||||
{ | |||||
case EFogVolumeLightType.None: | |||||
{ | |||||
continue; | |||||
} | |||||
case EFogVolumeLightType.PointLight: | |||||
case EFogVolumeLightType.SpotLight: | |||||
{ | |||||
if (m_lights[i].Light.enabled == false) { continue; } | |||||
break; | |||||
} | |||||
case EFogVolumeLightType.FogVolumePointLight: | |||||
{ | |||||
if (m_lights[i].FogVolumeLight.Enabled == false) { continue; } | |||||
break; | |||||
} | |||||
case EFogVolumeLightType.FogVolumeSpotLight: | |||||
{ | |||||
if (m_lights[i].FogVolumeLight.Enabled == false) { continue; } | |||||
break; | |||||
} | |||||
} | |||||
if (GeometryUtility.TestPlanesAABB(FrustumPlanes, m_lights[i].Bounds)) | |||||
{ | |||||
LightData light = m_lights[i]; | |||||
Vector3 lightPos = light.Transform.position; | |||||
light.SqDistance = (lightPos - m_pointOfInterest).sqrMagnitude; | |||||
light.Distance2Camera = (lightPos - CameraPos).magnitude; | |||||
m_lightsInFrustum[m_inFrustumCount++] = light; | |||||
if (light.FogVolumeLight != null) | |||||
{ | |||||
if (light.LightType == EFogVolumeLightType.FogVolumePointLight && | |||||
!light.FogVolumeLight.IsPointLight) | |||||
{ | |||||
light.LightType = EFogVolumeLightType.FogVolumeSpotLight; | |||||
} | |||||
else if (light.LightType == EFogVolumeLightType.FogVolumeSpotLight && | |||||
light.FogVolumeLight.IsPointLight) | |||||
{ | |||||
light.LightType = EFogVolumeLightType.FogVolumePointLight; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Sorts the lights that are currently within the view frustum of the camera by | |||||
* distance to the camera. | |||||
* | |||||
* This method will only be called when there are more than MaxVisibleLights in the view | |||||
* frustum of the camera. | |||||
* | |||||
*********************************************************************************************/ | |||||
private void _SortLightsInFrustum() | |||||
{ | |||||
bool finishedSorting = false; | |||||
do | |||||
{ | |||||
finishedSorting = true; | |||||
for (int i = 0; i < m_inFrustumCount - 1; i++) | |||||
{ | |||||
if (m_lightsInFrustum[i].SqDistance > m_lightsInFrustum[i + 1].SqDistance) | |||||
{ | |||||
LightData tempData = m_lightsInFrustum[i]; | |||||
m_lightsInFrustum[i] = m_lightsInFrustum[i + 1]; | |||||
m_lightsInFrustum[i + 1] = tempData; | |||||
finishedSorting = false; | |||||
} | |||||
} | |||||
} | |||||
while (!finishedSorting); | |||||
} | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Prepares the data of the currently visible light and writes it to the arrays that | |||||
* can then be sent to the shaders. | |||||
* | |||||
*********************************************************************************************/ | |||||
private void _PrepareShaderArrays() | |||||
{ | |||||
VisibleLightCount = 0; | |||||
for (int i = 0; i < MaxVisibleLights; i++) | |||||
{ | |||||
if (i >= m_inFrustumCount) { break; } | |||||
LightData data = m_lightsInFrustum[i]; | |||||
switch (data.LightType) | |||||
{ | |||||
case EFogVolumeLightType.FogVolumePointLight: | |||||
{ | |||||
FogVolumeLight light = data.FogVolumeLight; | |||||
m_lightPos[i] = | |||||
gameObject.transform.InverseTransformPoint(data.Transform.position); | |||||
m_lightRot[i] = | |||||
gameObject.transform.InverseTransformVector(data.Transform.forward); | |||||
m_lightColor[i] = light.Color; | |||||
m_lightData[i] = | |||||
new Vector4(light.Intensity * m_fogVolume.PointLightsIntensity * | |||||
(1.0f - Mathf.Clamp01(data.Distance2Camera / m_fogVolume | |||||
.PointLightingDistance2Camera) | |||||
), | |||||
light.Range / PointLightRangeDivider, | |||||
InvalidSpotLightAngle, | |||||
NoData); | |||||
VisibleLightCount++; | |||||
break; | |||||
} | |||||
case EFogVolumeLightType.FogVolumeSpotLight: | |||||
{ | |||||
FogVolumeLight light = data.FogVolumeLight; | |||||
m_lightPos[i] = | |||||
gameObject.transform.InverseTransformPoint(data.Transform.position); | |||||
m_lightRot[i] = | |||||
gameObject.transform.InverseTransformVector(data.Transform.forward); | |||||
m_lightColor[i] = light.Color; | |||||
m_lightData[i] = | |||||
new Vector4(light.Intensity * m_fogVolume.PointLightsIntensity * | |||||
(1.0f - Mathf.Clamp01(data.Distance2Camera / m_fogVolume | |||||
.PointLightingDistance2Camera) | |||||
), | |||||
light.Range / SpotLightRangeDivider, | |||||
light.Angle, | |||||
NoData); | |||||
VisibleLightCount++; | |||||
break; | |||||
} | |||||
case EFogVolumeLightType.PointLight: | |||||
{ | |||||
Light light = data.Light; | |||||
m_lightPos[i] = | |||||
gameObject.transform.InverseTransformPoint(data.Transform.position); | |||||
m_lightRot[i] = | |||||
gameObject.transform.InverseTransformVector(data.Transform.forward); | |||||
m_lightColor[i] = light.color; | |||||
m_lightData[i] = | |||||
new Vector4(light.intensity * m_fogVolume.PointLightsIntensity * | |||||
(1.0f - Mathf.Clamp01(data.Distance2Camera / m_fogVolume | |||||
.PointLightingDistance2Camera) | |||||
), | |||||
light.range / PointLightRangeDivider, | |||||
InvalidSpotLightAngle, | |||||
NoData); | |||||
VisibleLightCount++; | |||||
break; | |||||
} | |||||
case EFogVolumeLightType.SpotLight: | |||||
{ | |||||
Light light = data.Light; | |||||
m_lightPos[i] = | |||||
gameObject.transform.InverseTransformPoint(data.Transform.position); | |||||
m_lightRot[i] = | |||||
gameObject.transform.InverseTransformVector(data.Transform.forward); | |||||
m_lightColor[i] = light.color; | |||||
m_lightData[i] = | |||||
new Vector4(light.intensity * m_fogVolume.PointLightsIntensity * | |||||
(1.0f - Mathf.Clamp01(data.Distance2Camera / m_fogVolume | |||||
.PointLightingDistance2Camera) | |||||
), | |||||
light.range / SpotLightRangeDivider, | |||||
light.spotAngle, | |||||
NoData); | |||||
VisibleLightCount++; | |||||
break; | |||||
} | |||||
case EFogVolumeLightType.None: | |||||
{ | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
private float m_pointLightCullSizeMultiplier = 1.0f; | |||||
private FogVolume m_fogVolume = null; | |||||
private FogVolumeData m_fogVolumeData = null; | |||||
private Camera m_camera = null; | |||||
private BoxCollider m_boxCollider = null; | |||||
private Transform m_pointOfInterestTf = null; | |||||
private Vector3 m_pointOfInterest = Vector3.zero; | |||||
private readonly Vector4[] m_lightPos = new Vector4[MaxVisibleLights]; | |||||
private readonly Vector4[] m_lightRot = new Vector4[MaxVisibleLights]; | |||||
private readonly Color[] m_lightColor = new Color[MaxVisibleLights]; | |||||
private readonly Vector4[] m_lightData = new Vector4[MaxVisibleLights]; | |||||
private List<LightData> m_lights = null; | |||||
private List<LightData> m_lightsInFrustum = null; | |||||
private int m_inFrustumCount = 0; | |||||
private Plane[] FrustumPlanes = null; | |||||
private const int InvalidIndex = -1; | |||||
private const int MaxVisibleLights = 64; | |||||
private const float InvalidSpotLightAngle = -1.0f; | |||||
private const float NoData = 0.0f; | |||||
private const float PointLightRangeDivider = 5.0f; | |||||
private const float SpotLightRangeDivider = 5.0f; | |||||
private const int MaxLightCount = 1000; | |||||
/// The assumed size of a light. Used by realtime search when searching for lights inside a FV. | |||||
private const float LightInVolumeBoundsSize = 5.0f; | |||||
protected class LightData | |||||
{ | |||||
public LightData() | |||||
{ | |||||
LightType = EFogVolumeLightType.None; | |||||
Light = null; | |||||
FogVolumeLight = null; | |||||
Transform = null; | |||||
SqDistance = 0.0f; | |||||
Distance2Camera = 0.0f; | |||||
Bounds = new Bounds(); | |||||
} | |||||
public EFogVolumeLightType LightType { get; set; } | |||||
public Light Light { get; set; } | |||||
public FogVolumeLight FogVolumeLight { get; set; } | |||||
public Transform Transform { get; set; } | |||||
public float SqDistance { get; set; } | |||||
public float Distance2Camera { get; set; } | |||||
public Bounds Bounds { get; set; } | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 28ead9d9608fc8d43827ac46c26c6dae | |||||
timeCreated: 1501009496 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,110 @@ | |||||
| |||||
using UnityEngine; | |||||
[ExecuteInEditMode] | |||||
public class FogVolumePrimitive : MonoBehaviour | |||||
{ | |||||
public FogVolumePrimitive() | |||||
{ | |||||
SphereColl = null; | |||||
BoxColl = null; | |||||
} | |||||
public Transform GetTransform { get { return gameObject.transform; } } | |||||
public Vector3 GetPrimitiveScale | |||||
{ | |||||
get | |||||
{ | |||||
return new Vector3(Mathf.Max(MinScale, transform.lossyScale.x), | |||||
Mathf.Max(MinScale, transform.lossyScale.y), | |||||
Mathf.Max(MinScale, transform.lossyScale.z)); | |||||
} | |||||
} | |||||
public Bounds Bounds | |||||
{ | |||||
get | |||||
{ | |||||
if (BoxColl != null) { return BoxColl.bounds; } | |||||
else if (SphereColl != null) { return SphereColl.bounds; } | |||||
else | |||||
{ | |||||
return new Bounds(gameObject.transform.position, gameObject.transform.lossyScale); | |||||
} | |||||
} | |||||
} | |||||
public void AddColliderIfNeccessary(EFogVolumePrimitiveType _type) | |||||
{ | |||||
Type = _type; | |||||
switch (Type) | |||||
{ | |||||
case EFogVolumePrimitiveType.None: | |||||
{ | |||||
break; | |||||
} | |||||
case EFogVolumePrimitiveType.Box: | |||||
{ | |||||
if (BoxColl == null) { BoxColl = gameObject.AddComponent<BoxCollider>(); } | |||||
break; | |||||
} | |||||
case EFogVolumePrimitiveType.Sphere: | |||||
{ | |||||
if (SphereColl == null) { SphereColl = gameObject.AddComponent<SphereCollider>(); } | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
private void OnEnable() | |||||
{ | |||||
Primitive = gameObject; | |||||
_Renderer = Primitive.GetComponent<MeshRenderer>(); | |||||
if (!PrimitiveMaterial) | |||||
{ | |||||
PrimitiveMaterial = (Material) Resources.Load("PrimitiveMaterial"); | |||||
} | |||||
_Renderer.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off; | |||||
_Renderer.lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off; | |||||
_Renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; | |||||
_Renderer.receiveShadows = false; | |||||
GetComponent<MeshRenderer>().material = PrimitiveMaterial; | |||||
BoxColl = GetComponent<BoxCollider>(); | |||||
SphereColl = GetComponent<SphereCollider>(); | |||||
if (BoxColl == null && | |||||
SphereColl == null) | |||||
{ | |||||
BoxColl = gameObject.AddComponent<BoxCollider>(); | |||||
Type = EFogVolumePrimitiveType.Box; | |||||
} | |||||
else | |||||
{ | |||||
if (BoxColl != null) { Type = EFogVolumePrimitiveType.Box; } | |||||
else if (SphereColl != null) { Type = EFogVolumePrimitiveType.Sphere; } | |||||
else { Type = EFogVolumePrimitiveType.None; } | |||||
} | |||||
} | |||||
public BoxCollider BoxColl; | |||||
public SphereCollider SphereColl; | |||||
public bool IsPersistent = true; | |||||
public EFogVolumePrimitiveType Type; | |||||
public bool IsSubtractive; | |||||
public Material PrimitiveMaterial; | |||||
private GameObject Primitive; | |||||
private Renderer _Renderer; | |||||
private readonly float MinScale = .0001f; | |||||
} |
@ -0,0 +1,13 @@ | |||||
fileFormatVersion: 2 | |||||
guid: ea6605193e9715e449050736b7efaea1 | |||||
timeCreated: 1492381964 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: | |||||
- PrimitiveMaterial: {fileID: 2100000, guid: 0429485e63d913a438bd171228fce857, type: 2} | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,415 @@ | |||||
using System.Collections; | |||||
using System.Collections.Generic; | |||||
using UnityEngine; | |||||
using UnityEngine.Assertions; | |||||
public class FogVolumePrimitiveManager : MonoBehaviour | |||||
{ | |||||
public int CurrentPrimitiveCount { get; private set; } | |||||
public int VisiblePrimitiveCount { get; private set; } | |||||
public bool AlreadyUsesTransformForPoI { get { return m_pointOfInterestTf != null; } } | |||||
public void FindPrimitivesInFogVolume() | |||||
{ | |||||
CurrentPrimitiveCount = 0; | |||||
VisiblePrimitiveCount = 0; | |||||
m_primitives.Clear(); | |||||
m_primitivesInFrustum.Clear(); | |||||
for (int i = 0; i < MaxPrimitivesCount; i++) | |||||
{ | |||||
m_primitives.Add(new PrimitiveData()); | |||||
m_primitivesInFrustum.Add(new PrimitiveData()); | |||||
} | |||||
if (m_boxCollider == null) { m_boxCollider = gameObject.GetComponent<BoxCollider>(); } | |||||
Bounds boundingBox = m_boxCollider.bounds; | |||||
FogVolumePrimitive[] primitives = FindObjectsOfType<FogVolumePrimitive>(); | |||||
for (int i = 0; i < primitives.Length; i++) | |||||
{ | |||||
var data = primitives[i]; | |||||
if (boundingBox.Intersects(data.Bounds)) | |||||
{ | |||||
if (data.BoxColl != null) { data.Type = EFogVolumePrimitiveType.Box; } | |||||
else if (data.SphereColl != null) { data.Type = EFogVolumePrimitiveType.Sphere; } | |||||
else | |||||
{ | |||||
data.BoxColl = data.GetTransform.gameObject.AddComponent<BoxCollider>(); | |||||
data.Type = EFogVolumePrimitiveType.Box; | |||||
} | |||||
if (data.Type == EFogVolumePrimitiveType.Box) | |||||
{ | |||||
AddPrimitiveBox(data); | |||||
} | |||||
else if (data.Type == EFogVolumePrimitiveType.Sphere) | |||||
{ | |||||
AddPrimitiveSphere(data); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
public bool AddPrimitiveBox(FogVolumePrimitive _box) | |||||
{ | |||||
Assert.IsTrue(CurrentPrimitiveCount < MaxPrimitivesCount, | |||||
"The maximum amount of primitives is already reached!"); | |||||
int index = _FindFirstFreePrimitive(); | |||||
if (index != InvalidIndex) | |||||
{ | |||||
PrimitiveData data = m_primitives[index]; | |||||
CurrentPrimitiveCount++; | |||||
data.PrimitiveType = EFogVolumePrimitiveType.Box; | |||||
data.Transform = _box.transform; | |||||
data.Renderer = _box.GetComponent<Renderer>(); | |||||
data.Primitive = _box; | |||||
data.Bounds = new Bounds(data.Transform.position, _box.GetPrimitiveScale); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
public bool AddPrimitiveSphere(FogVolumePrimitive _sphere) | |||||
{ | |||||
Assert.IsTrue(CurrentPrimitiveCount < MaxPrimitivesCount, | |||||
"The maximum amount of primitives is already reached!"); | |||||
int index = _FindFirstFreePrimitive(); | |||||
if (index != InvalidIndex) | |||||
{ | |||||
PrimitiveData data = m_primitives[index]; | |||||
CurrentPrimitiveCount++; | |||||
data.PrimitiveType = EFogVolumePrimitiveType.Sphere; | |||||
data.Transform = _sphere.transform; | |||||
data.Renderer = _sphere.GetComponent<Renderer>(); | |||||
data.Primitive = _sphere; | |||||
data.Bounds = new Bounds(data.Transform.position, _sphere.GetPrimitiveScale); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
public bool RemovePrimitive(Transform _primitiveToRemove) | |||||
{ | |||||
int count = m_primitives.Count; | |||||
for (int i = 0; i < count; i++) | |||||
{ | |||||
PrimitiveData data = m_primitives[i]; | |||||
if (ReferenceEquals(m_primitives[i].Transform, _primitiveToRemove)) | |||||
{ | |||||
data.Reset(); | |||||
CurrentPrimitiveCount--; | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Sets the point of interest to a fixed position. | |||||
* | |||||
* @param _pointOfInterest The point that will be used for prioritizing which primitives need | |||||
* to be rendered. | |||||
* | |||||
*********************************************************************************************/ | |||||
public void SetPointOfInterest(Vector3 _pointOfInterest) | |||||
{ | |||||
m_pointOfInterestTf = null; | |||||
m_pointOfInterest = _pointOfInterest; | |||||
} | |||||
//============================================================================================= | |||||
/** | |||||
* @brief Sets the point of interest to the specified transform. | |||||
* | |||||
* The point of interest will be updated from the position of the transform. It is therefore | |||||
* not necessary to call this method more than once. | |||||
* | |||||
*********************************************************************************************/ | |||||
public void SetPointOfInterest(Transform _pointOfInterest) | |||||
{ | |||||
Assert.IsTrue(_pointOfInterest != null, "_pointOfInterest must not be null!"); | |||||
m_pointOfInterestTf = _pointOfInterest; | |||||
} | |||||
public void OnDrawGizmos() { hideFlags = HideFlags.HideInInspector; } | |||||
public void ManualUpdate(ref Plane[] _frustumPlanes) | |||||
{ | |||||
m_camera = m_fogVolumeData != null ? m_fogVolumeData.GameCamera : null; | |||||
if (m_camera == null) { return; } | |||||
FrustumPlanes = _frustumPlanes; | |||||
if (m_boxCollider == null) { m_boxCollider = m_fogVolume.GetComponent<BoxCollider>(); } | |||||
_UpdateBounds(); | |||||
_FindPrimitivesInFrustum(); | |||||
if (m_primitivesInFrustum.Count > MaxVisiblePrimitives) { _SortPrimitivesInFrustum(); } | |||||
_PrepareShaderArrays(); | |||||
} | |||||
public void SetVisibility(bool _enabled) | |||||
{ | |||||
int count = m_primitives.Count; | |||||
for (int i = 0; i < count; i++) | |||||
{ | |||||
if (m_primitives[i].Renderer != null) { m_primitives[i].Renderer.enabled = _enabled; } | |||||
} | |||||
} | |||||
public void Initialize() | |||||
{ | |||||
m_fogVolume = gameObject.GetComponent<FogVolume>(); | |||||
m_fogVolumeData = FindObjectOfType<FogVolumeData>(); | |||||
m_camera = null; | |||||
m_boxCollider = null; | |||||
CurrentPrimitiveCount = 0; | |||||
if (m_primitives == null) | |||||
{ | |||||
m_primitives = new List<PrimitiveData>(MaxPrimitivesCount); | |||||
m_primitivesInFrustum = new List<PrimitiveData>(); | |||||
for (int i = 0; i < MaxPrimitivesCount; i++) | |||||
{ | |||||
m_primitives.Add(new PrimitiveData()); | |||||
m_primitivesInFrustum.Add(new PrimitiveData()); | |||||
} | |||||
} | |||||
} | |||||
public void Deinitialize() { VisiblePrimitiveCount = 0; } | |||||
public Vector4[] GetPrimitivePositionArray() { return m_primitivePos; } | |||||
public Vector4[] GetPrimitiveScaleArray() { return m_primitiveScale; } | |||||
public Matrix4x4[] GetPrimitiveTransformArray() { return m_primitiveTf; } | |||||
public Vector4[] GetPrimitiveDataArray() { return m_primitiveData; } | |||||
private void _UpdateBounds() | |||||
{ | |||||
int count = m_primitives.Count; | |||||
for (int i = 0; i < count; i++) | |||||
{ | |||||
PrimitiveData data = m_primitives[i]; | |||||
if (data.PrimitiveType == EFogVolumePrimitiveType.None) { continue; } | |||||
if (data.Primitive == null) | |||||
{ | |||||
RemovePrimitive(data.Transform); | |||||
continue; | |||||
} | |||||
if (data.PrimitiveType == EFogVolumePrimitiveType.Box) | |||||
{ | |||||
// Check if collider was removed by the user and add it again. | |||||
if (data.Primitive.BoxColl == null) | |||||
{ | |||||
Debug.LogWarning("FogVolumePrimitive requires a collider.\nThe collider will be automatically created."); | |||||
data.Primitive.AddColliderIfNeccessary(EFogVolumePrimitiveType.Box); | |||||
} | |||||
data.Bounds = data.Primitive.BoxColl.bounds; | |||||
} | |||||
else if (data.PrimitiveType == EFogVolumePrimitiveType.Sphere) | |||||
{ | |||||
// Check if collider was removed by the user and add it again. | |||||
if (data.Primitive.SphereColl == null) | |||||
{ | |||||
Debug.LogWarning("FogVolumePrimitive requires a collider.\nThe collider will be automatically created."); | |||||
data.Primitive.AddColliderIfNeccessary(EFogVolumePrimitiveType.Sphere); | |||||
} | |||||
data.Bounds = data.Primitive.SphereColl.bounds; | |||||
} | |||||
} | |||||
} | |||||
private int _FindFirstFreePrimitive() | |||||
{ | |||||
if (CurrentPrimitiveCount < MaxPrimitivesCount) | |||||
{ | |||||
int count = m_primitives.Count; | |||||
for (int i = 0; i < count; i++) | |||||
{ | |||||
if (m_primitives[i].PrimitiveType == EFogVolumePrimitiveType.None) { return i; } | |||||
} | |||||
} | |||||
return InvalidIndex; | |||||
} | |||||
private void _FindPrimitivesInFrustum() | |||||
{ | |||||
m_inFrustumCount = 0; | |||||
Vector3 cameraPos = m_camera.gameObject.transform.position; | |||||
int count = m_primitives.Count; | |||||
for (int i = 0; i < count; i++) | |||||
{ | |||||
PrimitiveData primitive = m_primitives[i]; | |||||
if (primitive.Transform == null) | |||||
{ | |||||
primitive.PrimitiveType = EFogVolumePrimitiveType.None; | |||||
} | |||||
if (primitive.PrimitiveType == EFogVolumePrimitiveType.None) { continue; } | |||||
if (primitive.Primitive.IsPersistent) | |||||
{ | |||||
Vector3 pos = primitive.Transform.position; | |||||
primitive.SqDistance = (pos - m_pointOfInterest).sqrMagnitude; | |||||
primitive.Distance2Camera = (pos - cameraPos).magnitude; | |||||
m_primitivesInFrustum[m_inFrustumCount++] = primitive; | |||||
} | |||||
else if (GeometryUtility.TestPlanesAABB(FrustumPlanes, m_primitives[i].Bounds)) | |||||
{ | |||||
Vector3 pos = primitive.Transform.position; | |||||
primitive.SqDistance = (pos - m_pointOfInterest).sqrMagnitude; | |||||
primitive.Distance2Camera = (pos - cameraPos).magnitude; | |||||
m_primitivesInFrustum[m_inFrustumCount++] = primitive; | |||||
} | |||||
} | |||||
} | |||||
private void _SortPrimitivesInFrustum() | |||||
{ | |||||
bool finishedSorting = false; | |||||
do | |||||
{ | |||||
finishedSorting = true; | |||||
for (int i = 0; i < m_inFrustumCount - 1; i++) | |||||
{ | |||||
if (m_primitivesInFrustum[i].SqDistance > m_primitivesInFrustum[i + 1].SqDistance) | |||||
{ | |||||
PrimitiveData tempData = m_primitivesInFrustum[i]; | |||||
m_primitivesInFrustum[i] = m_primitivesInFrustum[i + 1]; | |||||
m_primitivesInFrustum[i + 1] = tempData; | |||||
finishedSorting = false; | |||||
} | |||||
} | |||||
} | |||||
while (!finishedSorting); | |||||
} | |||||
private void _PrepareShaderArrays() | |||||
{ | |||||
VisiblePrimitiveCount = 0; | |||||
Quaternion fogVolumeRotation = m_fogVolume.gameObject.transform.rotation; | |||||
for (int i = 0; i < MaxVisiblePrimitives; i++) | |||||
{ | |||||
if (i >= m_inFrustumCount) { break; } | |||||
PrimitiveData data = m_primitivesInFrustum[i]; | |||||
Vector3 position = data.Transform.position; | |||||
m_primitivePos[i] = gameObject.transform.InverseTransformPoint(position); | |||||
m_primitiveTf[i].SetTRS(position, | |||||
Quaternion.Inverse(data.Transform.rotation) * fogVolumeRotation, | |||||
Vector3.one); | |||||
m_primitiveScale[i] = data.Primitive.GetPrimitiveScale; | |||||
m_primitiveData[i] = | |||||
new Vector4(data.PrimitiveType == EFogVolumePrimitiveType.Box ? 0.5f : 1.5f, | |||||
data.Primitive.IsSubtractive ? 1.5f : 0.5f, | |||||
0.0f, | |||||
0.0f); | |||||
VisiblePrimitiveCount++; | |||||
} | |||||
} | |||||
#if UNITY_EDITOR | |||||
private void Update() { hideFlags = HideFlags.HideInInspector; } | |||||
#endif | |||||
private FogVolume m_fogVolume = null; | |||||
private FogVolumeData m_fogVolumeData = null; | |||||
private Camera m_camera = null; | |||||
private BoxCollider m_boxCollider = null; | |||||
private Transform m_pointOfInterestTf = null; | |||||
private Vector3 m_pointOfInterest = Vector3.zero; | |||||
private List<PrimitiveData> m_primitives = null; | |||||
private List<PrimitiveData> m_primitivesInFrustum = null; | |||||
private int m_inFrustumCount = 0; | |||||
private Plane[] FrustumPlanes = null; | |||||
private readonly Vector4[] m_primitivePos = new Vector4[MaxVisiblePrimitives]; | |||||
private readonly Vector4[] m_primitiveScale = new Vector4[MaxVisiblePrimitives]; | |||||
private readonly Matrix4x4[] m_primitiveTf = new Matrix4x4[MaxVisiblePrimitives]; | |||||
private readonly Vector4[] m_primitiveData = new Vector4[MaxVisiblePrimitives]; | |||||
private const int InvalidIndex = -1; | |||||
private const int MaxVisiblePrimitives = 20; | |||||
private const int MaxPrimitivesCount = 1000; | |||||
protected class PrimitiveData | |||||
{ | |||||
public PrimitiveData() | |||||
{ | |||||
PrimitiveType = EFogVolumePrimitiveType.None; | |||||
Primitive = null; | |||||
Transform = null; | |||||
Renderer = null; | |||||
SqDistance = 0.0f; | |||||
Distance2Camera = 0.0f; | |||||
Bounds = new Bounds(); | |||||
} | |||||
public EFogVolumePrimitiveType PrimitiveType { get; set; } | |||||
public FogVolumePrimitive Primitive { get; set; } | |||||
public Transform Transform { get; set; } | |||||
public Renderer Renderer { get; set; } | |||||
public float SqDistance { get; set; } | |||||
public float Distance2Camera { get; set; } | |||||
public Bounds Bounds { get; set; } | |||||
public void Reset() | |||||
{ | |||||
PrimitiveType = EFogVolumePrimitiveType.None; | |||||
Primitive = null; | |||||
Transform = null; | |||||
Renderer = null; | |||||
SqDistance = 0.0f; | |||||
Distance2Camera = 0.0f; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: a8340c6d549ef1c4099a619f31eef29e | |||||
timeCreated: 1512373111 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,901 @@ | |||||
using UnityEngine; | |||||
using UnityEngine.Profiling; | |||||
using FogVolumeUtilities; | |||||
using UnityEngine.XR; | |||||
#if UNITY_EDITOR | |||||
using UnityEditor; | |||||
#endif | |||||
[ExecuteInEditMode] | |||||
public class FogVolumeRenderer : MonoBehaviour | |||||
{ | |||||
bool ShowCamerasBack = true; | |||||
public bool ShowCamera; | |||||
//public bool DestroyOnDisable; | |||||
private int m_screenWidth = 0; | |||||
private int m_screenHeight = 0; | |||||
public string FogVolumeResolution; | |||||
// public bool RenderableInSceneView = true; | |||||
public enum BlendMode | |||||
{ | |||||
PremultipliedTransparency = (int)UnityEngine.Rendering.BlendMode.One, | |||||
TraditionalTransparency = (int)UnityEngine.Rendering.BlendMode.SrcAlpha, | |||||
}; | |||||
RenderTextureFormat rt_DepthFormat; | |||||
public BlendMode _BlendMode = BlendMode.PremultipliedTransparency; | |||||
public bool GenerateDepth = true; | |||||
RenderTexture RT_FogVolume, RT_FogVolumeR; | |||||
[SerializeField] | |||||
[Range(0, 8)] | |||||
public int _Downsample = 1; | |||||
public void setDownsample(int val) { _Downsample = val; } | |||||
//public bool useRectangularStereoRT = false; | |||||
public bool _showBilateralEdge = false; | |||||
public bool showBilateralEdge | |||||
{ | |||||
set | |||||
{ | |||||
if (value != _showBilateralEdge) | |||||
ShowBilateralEdge(value); | |||||
} | |||||
get | |||||
{ | |||||
return _showBilateralEdge; | |||||
} | |||||
} | |||||
public void ShowBilateralEdge(bool b) | |||||
{ | |||||
_showBilateralEdge = b; | |||||
if (bilateralMaterial) | |||||
{ | |||||
if (showBilateralEdge) | |||||
bilateralMaterial.EnableKeyword("VISUALIZE_EDGE"); | |||||
else | |||||
bilateralMaterial.DisableKeyword("VISUALIZE_EDGE"); | |||||
} | |||||
} | |||||
[SerializeField] | |||||
//public FogVolumeCamera.UpsampleMode USMode = FogVolumeCamera.UpsampleMode.DOWNSAMPLE_CHESSBOARD; | |||||
[System.Serializable] | |||||
public enum UpsampleMode | |||||
{ | |||||
DOWNSAMPLE_MIN, | |||||
DOWNSAMPLE_MAX, | |||||
DOWNSAMPLE_CHESSBOARD | |||||
}; | |||||
public enum UpsampleMaterialPass | |||||
{ | |||||
DEPTH_DOWNSAMPLE = 0, | |||||
BILATERAL_UPSAMPLE = 1 | |||||
}; | |||||
Material bilateralMaterial; | |||||
public bool _useBilateralUpsampling = true; | |||||
public bool useBilateralUpsampling | |||||
{ | |||||
get { return _useBilateralUpsampling; } | |||||
set | |||||
{ | |||||
if (_useBilateralUpsampling != value) | |||||
SetUseBilateralUpsampling(value); | |||||
} | |||||
} | |||||
void SetUseBilateralUpsampling(bool b) | |||||
{ | |||||
_useBilateralUpsampling = b /*&& BilateralUpsamplingEnabled()*/;//works on dx9 | |||||
if (_useBilateralUpsampling) | |||||
{ | |||||
if (bilateralMaterial == null) | |||||
{ | |||||
bilateralMaterial = new Material(Shader.Find("Hidden/Upsample")); | |||||
if (bilateralMaterial == null) | |||||
Debug.Log("#ERROR# Hidden/Upsample"); | |||||
// refresh keywords | |||||
UpdateBilateralDownsampleModeSwitch(); | |||||
ShowBilateralEdge(_showBilateralEdge); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
// release resources | |||||
bilateralMaterial = null; | |||||
} | |||||
} | |||||
// [SerializeField] | |||||
public UpsampleMode _upsampleMode = UpsampleMode.DOWNSAMPLE_MAX; | |||||
public UpsampleMode upsampleMode | |||||
{ | |||||
set | |||||
{ | |||||
if (value != _upsampleMode) | |||||
SetUpsampleMode(value); | |||||
} | |||||
get | |||||
{ | |||||
return _upsampleMode; | |||||
} | |||||
} | |||||
void UpdateBilateralDownsampleModeSwitch() | |||||
{ | |||||
if (bilateralMaterial != null) | |||||
{ | |||||
switch (_upsampleMode) | |||||
{ | |||||
case UpsampleMode.DOWNSAMPLE_MIN: | |||||
bilateralMaterial.EnableKeyword("DOWNSAMPLE_DEPTH_MODE_MIN"); | |||||
bilateralMaterial.DisableKeyword("DOWNSAMPLE_DEPTH_MODE_MAX"); | |||||
bilateralMaterial.DisableKeyword("DOWNSAMPLE_DEPTH_MODE_CHESSBOARD"); | |||||
break; | |||||
case UpsampleMode.DOWNSAMPLE_MAX: | |||||
bilateralMaterial.DisableKeyword("DOWNSAMPLE_DEPTH_MODE_MIN"); | |||||
bilateralMaterial.EnableKeyword("DOWNSAMPLE_DEPTH_MODE_MAX"); | |||||
bilateralMaterial.DisableKeyword("DOWNSAMPLE_DEPTH_MODE_CHESSBOARD"); | |||||
break; | |||||
case UpsampleMode.DOWNSAMPLE_CHESSBOARD: | |||||
bilateralMaterial.DisableKeyword("DOWNSAMPLE_DEPTH_MODE_MIN"); | |||||
bilateralMaterial.DisableKeyword("DOWNSAMPLE_DEPTH_MODE_MAX"); | |||||
bilateralMaterial.EnableKeyword("DOWNSAMPLE_DEPTH_MODE_CHESSBOARD"); | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
void SetUpsampleMode(UpsampleMode value) | |||||
{ | |||||
_upsampleMode = value; | |||||
UpdateBilateralDownsampleModeSwitch(); | |||||
} | |||||
Camera ThisCamera = null; | |||||
RenderTexture RT_Depth, RT_DepthR; | |||||
Shader depthShader = null; | |||||
[HideInInspector] | |||||
Camera _FogVolumeCamera; | |||||
// [SerializeField] | |||||
GameObject _FogVolumeCameraGO; | |||||
[SerializeField] | |||||
[Range(0, .01f)] | |||||
public float upsampleDepthThreshold = 0.00187f; | |||||
public bool HDR; | |||||
public bool TAA = false; | |||||
public FogVolumeTAA _TAA = null; | |||||
private FogVolumePlaydeadTAA.VelocityBuffer _TAAvelocity = null; | |||||
private FogVolumePlaydeadTAA.FrustumJitter _TAAjitter = null; | |||||
//[HideInInspector] | |||||
//public LayerMask DepthLayer = -1; | |||||
[SerializeField] | |||||
// [HideInInspector] | |||||
//string _DepthLayersName = "Water"; | |||||
public int DepthLayer2 = 0; | |||||
//public string DepthLayersName | |||||
//{ | |||||
// get { return _DepthLayersName; } | |||||
// set | |||||
// { | |||||
// if (_DepthLayersName != value) | |||||
// SetDepthLayer(value); | |||||
// } | |||||
//} | |||||
//void SetDepthLayer(string NewDepthLayersName) | |||||
//{ | |||||
// _DepthLayersName = NewDepthLayersName; | |||||
// DepthLayer = ThisCamera.cullingMask; | |||||
// DepthLayer &= ~(1 << LayerMask.NameToLayer(_DepthLayersName)); | |||||
// //DepthLayer = LayerMask.NameToLayer(_DepthLayersName); | |||||
//} | |||||
//void OnValidate() | |||||
//{ | |||||
// SetDepthLayer(_DepthLayersName); | |||||
//} | |||||
public RenderTextureReadWrite GetRTReadWrite() | |||||
{ | |||||
//return RenderTextureReadWrite.Default; | |||||
return (ThisCamera.allowHDR) ? RenderTextureReadWrite.Default : RenderTextureReadWrite.Linear; | |||||
} | |||||
public RenderTextureFormat GetRTFormat() | |||||
{ | |||||
return (ThisCamera.allowHDR == true) ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default; | |||||
} | |||||
protected void GetRT(ref RenderTexture rt, int2 size, string name) | |||||
{ | |||||
// Release existing one | |||||
ReleaseRT(rt); | |||||
rt = RenderTexture.GetTemporary(size.x, size.y, 0, GetRTFormat(), GetRTReadWrite()); | |||||
rt.filterMode = FilterMode.Bilinear; | |||||
rt.name = name; | |||||
rt.wrapMode = TextureWrapMode.Clamp; | |||||
} | |||||
public void ReleaseRT(RenderTexture rt) | |||||
{ | |||||
if (rt != null) | |||||
{ | |||||
RenderTexture.ReleaseTemporary(rt); | |||||
rt = null; | |||||
} | |||||
} | |||||
protected void Get_RT_Depth(ref RenderTexture rt, int2 size, string name) | |||||
{ | |||||
// Release existing one | |||||
ReleaseRT(rt); | |||||
rt = RenderTexture.GetTemporary(size.x, size.y, 16, rt_DepthFormat); | |||||
rt.filterMode = FilterMode.Bilinear; | |||||
rt.name = name; | |||||
rt.wrapMode = TextureWrapMode.Clamp; | |||||
} | |||||
void RenderDepth() | |||||
{ | |||||
if (GenerateDepth && _FogVolumeCamera) | |||||
{ | |||||
if (_TAAjitter) | |||||
{ | |||||
//_TAA.enabled = false; | |||||
_TAAjitter.patternScale = 0; | |||||
} | |||||
Profiler.BeginSample("FogVolume Depth"); | |||||
//Gimme scene depth | |||||
// ThisCamera.cullingMask = _FogVolumeCamera.cullingMask;//Render the same than scene camera | |||||
//3.2.1p2 | |||||
_FogVolumeCamera.cullingMask = DepthLayer2; | |||||
#region Stereo | |||||
if (ThisCamera.stereoEnabled) | |||||
{ | |||||
Shader.EnableKeyword("FOG_VOLUME_STEREO_ON"); | |||||
//Left eye | |||||
if (ThisCamera.stereoTargetEye == StereoTargetEyeMask.Both || ThisCamera.stereoTargetEye == StereoTargetEyeMask.Left) | |||||
{ | |||||
_FogVolumeCamera.worldToCameraMatrix = ThisCamera.GetStereoViewMatrix(Camera.StereoscopicEye.Left); | |||||
_FogVolumeCamera.projectionMatrix = ThisCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left); | |||||
Get_RT_Depth(ref RT_Depth, new int2(m_screenWidth, m_screenHeight), "RT_DepthLeft"); | |||||
_FogVolumeCamera.targetTexture = RT_Depth; | |||||
_FogVolumeCamera.RenderWithShader(depthShader, "RenderType"); | |||||
} | |||||
//Right eye | |||||
if (ThisCamera.stereoTargetEye == StereoTargetEyeMask.Both || ThisCamera.stereoTargetEye == StereoTargetEyeMask.Right) | |||||
{ | |||||
_FogVolumeCamera.worldToCameraMatrix = ThisCamera.GetStereoViewMatrix(Camera.StereoscopicEye.Right); | |||||
_FogVolumeCamera.projectionMatrix = ThisCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right); | |||||
Get_RT_Depth(ref RT_DepthR, new int2(m_screenWidth, m_screenHeight), "RT_DepthRight"); | |||||
_FogVolumeCamera.targetTexture = RT_DepthR; | |||||
_FogVolumeCamera.RenderWithShader(depthShader, "RenderType"); | |||||
Shader.SetGlobalTexture("RT_DepthR", RT_DepthR); | |||||
} | |||||
} | |||||
#endregion | |||||
//MONO | |||||
else | |||||
{ | |||||
Shader.DisableKeyword("FOG_VOLUME_STEREO_ON"); | |||||
Get_RT_Depth(ref RT_Depth, new int2(m_screenWidth, m_screenHeight), "RT_Depth"); | |||||
//pepe | |||||
_FogVolumeCamera.projectionMatrix = ThisCamera.projectionMatrix; | |||||
_FogVolumeCamera.targetTexture = RT_Depth; | |||||
_FogVolumeCamera.RenderWithShader(depthShader, "RenderType"); | |||||
} | |||||
Shader.SetGlobalTexture("RT_Depth", RT_Depth); | |||||
Profiler.EndSample(); | |||||
} | |||||
} | |||||
public RenderTexture[] lowProfileDepthRT; | |||||
void ReleaseLowProfileDepthRT() | |||||
{ | |||||
if (lowProfileDepthRT != null) | |||||
{ | |||||
for (int i = 0; i < lowProfileDepthRT.Length; i++) | |||||
RenderTexture.ReleaseTemporary(lowProfileDepthRT[i]); | |||||
lowProfileDepthRT = null; | |||||
} | |||||
} | |||||
public RenderTexture[] lowProfileDepthRRT; | |||||
void ReleaseLowProfileDepthRRT() | |||||
{ | |||||
if (lowProfileDepthRRT != null) | |||||
{ | |||||
for (int i = 0; i < lowProfileDepthRRT.Length; i++) | |||||
RenderTexture.ReleaseTemporary(lowProfileDepthRRT[i]); | |||||
lowProfileDepthRRT = null; | |||||
} | |||||
} | |||||
void RenderColor() | |||||
{ | |||||
if (_TAA && _TAAjitter) | |||||
{ | |||||
_TAA.enabled = TAA; | |||||
_TAAvelocity.enabled = false; | |||||
_TAAjitter.enabled = TAA; | |||||
_TAAjitter.patternScale = 0.2f; | |||||
} | |||||
//Textured Fog | |||||
_FogVolumeCamera.cullingMask = 1 << LayerMask.NameToLayer("FogVolume");//show Fog volume | |||||
_FogVolumeCamera.cullingMask |= 1 << LayerMask.NameToLayer("FogVolumeShadowCaster");//show FogVolumeShadowCaster | |||||
int2 resolution = new int2(m_screenWidth / _Downsample, m_screenHeight / _Downsample); | |||||
FogVolumeResolution = resolution.x + " X " + resolution.y; | |||||
if (ThisCamera.stereoEnabled) | |||||
{ | |||||
Profiler.BeginSample("FogVolume Render Stereo"); | |||||
Shader.EnableKeyword("FOG_VOLUME_STEREO_ON"); | |||||
//Left eye | |||||
if (ThisCamera.stereoTargetEye == StereoTargetEyeMask.Both || ThisCamera.stereoTargetEye == StereoTargetEyeMask.Left) | |||||
{ | |||||
_FogVolumeCamera.projectionMatrix = ThisCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left); | |||||
_FogVolumeCamera.worldToCameraMatrix = ThisCamera.GetStereoViewMatrix(Camera.StereoscopicEye.Left); | |||||
GetRT(ref RT_FogVolume, resolution, "RT_FogVolumeLeft"); | |||||
_FogVolumeCamera.targetTexture = RT_FogVolume; | |||||
_FogVolumeCamera.Render(); | |||||
} | |||||
//Right eye | |||||
if (ThisCamera.stereoTargetEye == StereoTargetEyeMask.Both || ThisCamera.stereoTargetEye == StereoTargetEyeMask.Right) | |||||
{ | |||||
_FogVolumeCamera.projectionMatrix = ThisCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right); | |||||
_FogVolumeCamera.worldToCameraMatrix = ThisCamera.GetStereoViewMatrix(Camera.StereoscopicEye.Right); | |||||
GetRT(ref RT_FogVolumeR, resolution, "RT_FogVolumeRight"); | |||||
_FogVolumeCamera.targetTexture = RT_FogVolumeR; | |||||
_FogVolumeCamera.Render(); | |||||
} | |||||
Profiler.EndSample(); | |||||
} | |||||
else | |||||
{ | |||||
Profiler.BeginSample("FogVolume Render"); | |||||
Shader.DisableKeyword("FOG_VOLUME_STEREO_ON"); | |||||
_FogVolumeCamera.projectionMatrix = ThisCamera.projectionMatrix; | |||||
GetRT(ref RT_FogVolume, resolution, "RT_FogVolume"); | |||||
_FogVolumeCamera.targetTexture = RT_FogVolume; | |||||
_FogVolumeCamera.Render(); | |||||
Profiler.EndSample(); | |||||
} | |||||
if (TAA) | |||||
_TAA.TAA(ref RT_FogVolume); | |||||
if (ThisCamera.stereoEnabled) | |||||
{ | |||||
if (TAA) | |||||
_TAA.TAA(ref RT_FogVolumeR); | |||||
} | |||||
if (useBilateralUpsampling && GenerateDepth) | |||||
{ | |||||
//MONO | |||||
#region BILATERAL_DEPTH_DOWNSAMPLE | |||||
Profiler.BeginSample("FogVolume Upsample"); | |||||
// Compute downsampled depth-buffer for bilateral upsampling | |||||
if (bilateralMaterial) | |||||
{ | |||||
bilateralMaterial.SetInt("RightSide", 0); | |||||
ReleaseLowProfileDepthRT(); | |||||
lowProfileDepthRT = new RenderTexture[_Downsample]; | |||||
for (int downsampleStep = 0; downsampleStep < _Downsample; downsampleStep++) | |||||
{ | |||||
int targetWidth = m_screenWidth / (downsampleStep + 1); | |||||
int targetHeight = m_screenHeight / (downsampleStep + 1); | |||||
int stepWidth = m_screenWidth / Mathf.Max(downsampleStep, 1); | |||||
int stepHeight = m_screenHeight / Mathf.Max(downsampleStep, 1); | |||||
Vector4 texelSize = new Vector4(1.0f / stepWidth, 1.0f / stepHeight, 0.0f, 0.0f); | |||||
bilateralMaterial.SetFloat("_UpsampleDepthThreshold", upsampleDepthThreshold); | |||||
bilateralMaterial.SetVector("_TexelSize", texelSize); | |||||
bilateralMaterial.SetTexture("_HiResDepthBuffer", RT_Depth); | |||||
lowProfileDepthRT[downsampleStep] = | |||||
RenderTexture.GetTemporary(targetWidth, targetHeight, 0, rt_DepthFormat, GetRTReadWrite()); | |||||
lowProfileDepthRT[downsampleStep].name = "lowProfileDepthRT_" + downsampleStep; | |||||
Graphics.Blit(null, lowProfileDepthRT[downsampleStep], bilateralMaterial, (int)UpsampleMaterialPass.DEPTH_DOWNSAMPLE); | |||||
} | |||||
Shader.SetGlobalTexture("RT_Depth", lowProfileDepthRT[lowProfileDepthRT.Length - 1]); | |||||
} | |||||
#endregion | |||||
#region BILATERAL_UPSAMPLE | |||||
// Upsample convolution RT | |||||
if (bilateralMaterial) | |||||
{ | |||||
for (int downsampleStep = _Downsample - 1; downsampleStep >= 0; downsampleStep--) | |||||
{ | |||||
int targetWidth = m_screenWidth / Mathf.Max(downsampleStep, 1); | |||||
int targetHeight = m_screenHeight / Mathf.Max(downsampleStep, 1); | |||||
// compute Low-res texel size | |||||
int stepWidth = m_screenWidth / (downsampleStep + 1); | |||||
int stepHeight = m_screenHeight / (downsampleStep + 1); | |||||
Vector4 texelSize = new Vector4(1.0f / stepWidth, 1.0f / stepHeight, 0.0f, 0.0f); | |||||
bilateralMaterial.SetVector("_TexelSize", texelSize); | |||||
bilateralMaterial.SetVector("_InvdUV", new Vector4(RT_FogVolume.width, RT_FogVolume.height, 0, 0)); | |||||
// High-res depth texture | |||||
bilateralMaterial.SetTexture("_HiResDepthBuffer", RT_Depth); | |||||
bilateralMaterial.SetTexture("_LowResDepthBuffer", lowProfileDepthRT[downsampleStep]); | |||||
bilateralMaterial.SetTexture("_LowResColor", RT_FogVolume); | |||||
RenderTexture newRT = RenderTexture.GetTemporary(targetWidth, targetHeight, 0, GetRTFormat(), GetRTReadWrite()); | |||||
newRT.filterMode = FilterMode.Bilinear; | |||||
Graphics.Blit(null, newRT, bilateralMaterial, (int)UpsampleMaterialPass.BILATERAL_UPSAMPLE); | |||||
// Swap and release | |||||
RenderTexture swapRT = RT_FogVolume; | |||||
RT_FogVolume = newRT; | |||||
RenderTexture.ReleaseTemporary(swapRT); | |||||
} | |||||
} | |||||
ReleaseLowProfileDepthRT(); | |||||
#endregion | |||||
//Stereo right side | |||||
if (ThisCamera.stereoEnabled) | |||||
{ | |||||
#region BILATERAL_DEPTH_DOWNSAMPLE | |||||
Profiler.BeginSample("FogVolume Upsample Right"); | |||||
// Compute downsampled depth-buffer for bilateral upsampling | |||||
if (bilateralMaterial) | |||||
{ | |||||
bilateralMaterial.EnableKeyword("FOG_VOLUME_STEREO_ON"); | |||||
bilateralMaterial.SetInt("RightSide", 1); | |||||
ReleaseLowProfileDepthRRT(); | |||||
lowProfileDepthRRT = new RenderTexture[_Downsample]; | |||||
for (int downsampleStep = 0; downsampleStep < _Downsample; downsampleStep++) | |||||
{ | |||||
int targetWidth = m_screenWidth / (downsampleStep + 1); | |||||
int targetHeight = m_screenHeight / (downsampleStep + 1); | |||||
int stepWidth = m_screenWidth / Mathf.Max(downsampleStep, 1); | |||||
int stepHeight = m_screenHeight / Mathf.Max(downsampleStep, 1); | |||||
Vector4 texelSize = new Vector4(1.0f / stepWidth, 1.0f / stepHeight, 0.0f, 0.0f); | |||||
bilateralMaterial.SetFloat("_UpsampleDepthThreshold", upsampleDepthThreshold); | |||||
bilateralMaterial.SetVector("_TexelSize", texelSize); | |||||
bilateralMaterial.SetTexture("_HiResDepthBufferR", RT_DepthR); | |||||
lowProfileDepthRRT[downsampleStep] = | |||||
RenderTexture.GetTemporary(targetWidth, targetHeight, 0, rt_DepthFormat, GetRTReadWrite()); | |||||
lowProfileDepthRRT[downsampleStep].name = "lowProfileDepthRRT_" + downsampleStep; | |||||
Graphics.Blit(null, lowProfileDepthRRT[downsampleStep], bilateralMaterial, (int)UpsampleMaterialPass.DEPTH_DOWNSAMPLE); | |||||
} | |||||
Shader.SetGlobalTexture("RT_DepthR", lowProfileDepthRRT[lowProfileDepthRRT.Length - 1]); | |||||
} | |||||
#endregion | |||||
#region BILATERAL_UPSAMPLE | |||||
// Upsample convolution RT | |||||
if (bilateralMaterial) | |||||
{ | |||||
for (int downsampleStep = _Downsample - 1; downsampleStep >= 0; downsampleStep--) | |||||
{ | |||||
int targetWidth = m_screenWidth / Mathf.Max(downsampleStep, 1); | |||||
int targetHeight = m_screenHeight / Mathf.Max(downsampleStep, 1); | |||||
// compute Low-res texel size | |||||
int stepWidth = m_screenWidth / (downsampleStep + 1); | |||||
int stepHeight = m_screenHeight / (downsampleStep + 1); | |||||
Vector4 texelSize = new Vector4(1.0f / stepWidth, 1.0f / stepHeight, 0.0f, 0.0f); | |||||
bilateralMaterial.SetVector("_TexelSize", texelSize); | |||||
bilateralMaterial.SetVector("_InvdUV", new Vector4(RT_FogVolumeR.width, RT_FogVolumeR.height, 0, 0)); | |||||
// High-res depth texture | |||||
bilateralMaterial.SetTexture("_HiResDepthBufferR", RT_DepthR); | |||||
bilateralMaterial.SetTexture("_LowResDepthBufferR", lowProfileDepthRRT[downsampleStep]); | |||||
bilateralMaterial.SetTexture("_LowResColorR", RT_FogVolumeR); | |||||
RenderTexture newRT = RenderTexture.GetTemporary(targetWidth, targetHeight, 0, GetRTFormat(), GetRTReadWrite()); | |||||
newRT.filterMode = FilterMode.Bilinear; | |||||
Graphics.Blit(null, newRT, bilateralMaterial, (int)UpsampleMaterialPass.BILATERAL_UPSAMPLE); | |||||
// Swap and release | |||||
RenderTexture swapRT = RT_FogVolumeR; | |||||
RT_FogVolumeR = newRT; | |||||
RenderTexture.ReleaseTemporary(swapRT); | |||||
} | |||||
} | |||||
ReleaseLowProfileDepthRRT(); | |||||
#endregion | |||||
} | |||||
else | |||||
bilateralMaterial.DisableKeyword("FOG_VOLUME_STEREO_ON"); | |||||
Profiler.EndSample(); | |||||
} | |||||
if (ThisCamera.stereoEnabled) | |||||
Shader.SetGlobalTexture("RT_FogVolumeR", RT_FogVolumeR); | |||||
Shader.SetGlobalTexture("RT_FogVolume", RT_FogVolume); | |||||
} | |||||
void CameraUpdateSharedProperties() | |||||
{ | |||||
//AspectRatio = (float)m_screenWidth / m_screenHeight; | |||||
if (_FogVolumeCamera) | |||||
{ | |||||
_FogVolumeCamera.farClipPlane = ThisCamera.farClipPlane; | |||||
_FogVolumeCamera.nearClipPlane = ThisCamera.nearClipPlane; | |||||
_FogVolumeCamera.allowHDR = ThisCamera.allowHDR; | |||||
if (_FogVolumeCamera.stereoEnabled == false) | |||||
_FogVolumeCamera.fieldOfView = ThisCamera.fieldOfView; | |||||
} | |||||
} | |||||
void TAASetup() | |||||
{ | |||||
if (_Downsample > 1 && TAA) | |||||
{ | |||||
if (_FogVolumeCameraGO.GetComponent<FogVolumeTAA>() == null) | |||||
_FogVolumeCameraGO.AddComponent<FogVolumeTAA>(); | |||||
_TAA = _FogVolumeCameraGO.GetComponent<FogVolumeTAA>(); | |||||
_TAAvelocity = _FogVolumeCameraGO.GetComponent<FogVolumePlaydeadTAA.VelocityBuffer>(); | |||||
_TAAjitter = _FogVolumeCameraGO.GetComponent<FogVolumePlaydeadTAA.FrustumJitter>(); | |||||
} | |||||
} | |||||
void CreateFogCamera() | |||||
{ | |||||
//if (_Downsample > 1) | |||||
{ | |||||
_FogVolumeCameraGO = new GameObject(); | |||||
_FogVolumeCameraGO.transform.parent = gameObject.transform; | |||||
_FogVolumeCameraGO.transform.localEulerAngles = Vector3.zero; | |||||
_FogVolumeCameraGO.transform.localPosition = Vector3.zero; | |||||
_FogVolumeCameraGO.name = "FogVolumeCamera"; | |||||
//_FogVolumeCamera = _FogVolumeCameraGO.AddComponent<FogVolumeCamera>(); | |||||
_FogVolumeCamera = _FogVolumeCameraGO.AddComponent<Camera>(); | |||||
_FogVolumeCamera.depth = -666; | |||||
_FogVolumeCamera.clearFlags = CameraClearFlags.SolidColor; | |||||
_FogVolumeCamera.backgroundColor = new Color(0, 0, 0, 0); | |||||
// _FogVolumeCameraGO.hideFlags = HideFlags.HideInHierarchy; | |||||
_FogVolumeCamera.enabled = false; | |||||
_FogVolumeCamera.renderingPath = RenderingPath.Forward; | |||||
_FogVolumeCamera.allowMSAA = false; | |||||
#if UNITY_EDITOR | |||||
EditorExtension.ToggleInHierarchy(_FogVolumeCameraGO, ShowCamera); | |||||
#endif | |||||
} | |||||
} | |||||
void FindFogCamera() | |||||
{ | |||||
_FogVolumeCameraGO = GameObject.Find("FogVolumeCamera"); | |||||
if (_FogVolumeCameraGO) | |||||
{ | |||||
_FogVolumeCamera = _FogVolumeCameraGO.GetComponent<Camera>(); | |||||
//_FogVolumeCameraGO.transform.parent = gameObject.transform; | |||||
} | |||||
//if (_FogVolumeCameraGO) | |||||
// DestroyImmediate(_FogVolumeCameraGO);//the RT is not created in VR on start. Resetting here for now | |||||
if (_FogVolumeCameraGO == null) | |||||
CreateFogCamera(); | |||||
//_FV_Baker = _FogVolumeCameraGO.GetComponent<FogVolumeCamera>(); | |||||
TAASetup(); | |||||
} | |||||
Vector4 TexelSize = Vector4.zero; | |||||
void TexelUpdate() | |||||
{ | |||||
//if (_FogVolumeCamera.RT_FogVolume) | |||||
{ | |||||
TexelSize.x = 1.0f / ThisCamera.pixelWidth; | |||||
TexelSize.y = 1.0f / ThisCamera.pixelHeight; | |||||
TexelSize.z = ThisCamera.pixelWidth; | |||||
TexelSize.w = ThisCamera.pixelHeight; | |||||
Shader.SetGlobalVector("RT_FogVolume_TexelSize", TexelSize); | |||||
} | |||||
// print(TexelSize); | |||||
} | |||||
void OnEnable() | |||||
{ | |||||
SetUseBilateralUpsampling(_useBilateralUpsampling); | |||||
SetUpsampleMode(_upsampleMode); | |||||
ShowBilateralEdge(_showBilateralEdge); | |||||
ThisCamera = gameObject.GetComponent<Camera>(); | |||||
depthShader = Shader.Find("Hidden/Fog Volume/Depth"); | |||||
if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RFloat)) | |||||
rt_DepthFormat = RenderTextureFormat.RFloat; | |||||
else | |||||
rt_DepthFormat = RenderTextureFormat.DefaultHDR; | |||||
if (depthShader == null) print("Hidden/Fog Volume/Depth #SHADER ERROR#"); | |||||
FindFogCamera(); | |||||
//clean old scenes . In 3.4 things are different. Find the existing camera and remove the unused scripts: | |||||
Component[] components = _FogVolumeCameraGO.GetComponents<Component>(); | |||||
if (_FogVolumeCamera.GetComponent("FogVolumeCamera")) | |||||
{ | |||||
print("Destroyed Old Camera"); | |||||
SafeDestroy(_FogVolumeCameraGO); | |||||
CreateFogCamera(); | |||||
} | |||||
for (int i = 0; i < components.Length; i++) | |||||
{ | |||||
if (components[i] == null) | |||||
{ | |||||
print("Destroyed Old Camera"); | |||||
SafeDestroy(_FogVolumeCameraGO); | |||||
CreateFogCamera(); | |||||
break; | |||||
} | |||||
} | |||||
//3.2.2 clean meshes. Some users pretends to add FogVolume.cs here ¬¬ | |||||
if (GetComponent<FogVolume>()) | |||||
{ | |||||
print("Don't add FogVolume here. Create a new one using the menu buttons and follow the instructions"); | |||||
DestroyImmediate(GetComponent<FogVolume>()); | |||||
} | |||||
if (ThisCamera.GetComponent<MeshFilter>()) | |||||
DestroyImmediate(ThisCamera.GetComponent<MeshFilter>()); | |||||
if (ThisCamera.GetComponent<MeshRenderer>()) | |||||
DestroyImmediate(ThisCamera.GetComponent<MeshRenderer>()); | |||||
SurrogateMaterial = (Material)Resources.Load("Fog Volume Surrogate"); | |||||
//UpdateParams(); | |||||
if (DepthLayer2 == 0) | |||||
DepthLayer2 = 1; | |||||
//DepthLayer2 = ThisCamera.cullingMask; | |||||
} | |||||
void UpdateParams() | |||||
{ | |||||
//_FV_Baker._Downsample = _Downsample; | |||||
// if (_FogVolumeCamera && _Downsample > 1) | |||||
{ | |||||
// _FV_Baker.useBilateralUpsampling = BilateralUpsampling; | |||||
if (useBilateralUpsampling && GenerateDepth) | |||||
{ | |||||
// _FV_Baker.upsampleMode = USMode; | |||||
// _FV_Baker.showBilateralEdge = ShowBilateralEdge; | |||||
// _FV_Baker.upsampleDepthThreshold = upsampleDepthThreshold; | |||||
} | |||||
if (GenerateDepth) | |||||
{ | |||||
SurrogateMaterial.SetInt("_ztest", (int)UnityEngine.Rendering.CompareFunction.Always); | |||||
//_FogVolumeCamera.DepthMask = instance.DepthLayer; | |||||
// _FogVolumeCamera.DepthMask = ThisCamera.cullingMask; | |||||
//_FogVolumeCamera.DepthMask &= ~(1 << DepthLayer2); | |||||
DepthLayer2 &= ~(1 << LayerMask.NameToLayer("FogVolume"));//hide FogVolume | |||||
DepthLayer2 &= ~(1 << LayerMask.NameToLayer("FogVolumeShadowCaster"));//hide FogVolumeShadowCaster | |||||
DepthLayer2 &= ~(1 << LayerMask.NameToLayer("FogVolumeSurrogate"));//hide FogVolumeSurrogate | |||||
DepthLayer2 &= ~(1 << LayerMask.NameToLayer("FogVolumeUniform"));//hide FogVolumeUniform | |||||
DepthLayer2 &= ~(1 << LayerMask.NameToLayer("UI"));//hide UI | |||||
//_FV_Baker.DepthMask = DepthLayer2; | |||||
} | |||||
else | |||||
SurrogateMaterial.SetInt("_ztest", (int)UnityEngine.Rendering.CompareFunction.LessEqual); | |||||
if (!_TAA) | |||||
TAASetup(); | |||||
#if UNITY_5_6_OR_NEWER | |||||
HDR = ThisCamera.allowHDR; | |||||
#else | |||||
HDR = ThisCamera.hdr; | |||||
#endif | |||||
} | |||||
} | |||||
Material SurrogateMaterial; | |||||
public bool SceneBlur = true; | |||||
void OnPreRender() | |||||
{ | |||||
m_screenWidth = ThisCamera.pixelWidth; | |||||
m_screenHeight = ThisCamera.pixelHeight; | |||||
#if UNITY_EDITOR | |||||
if (ThisCamera == null) | |||||
ThisCamera = gameObject.GetComponent<Camera>(); | |||||
#endif | |||||
//#if UNITY_EDITOR | |||||
// // if destroyed... | |||||
// FindFogCamera(); | |||||
//#endif | |||||
if (_FogVolumeCamera == null | |||||
&& _Downsample > 1)//3.2.1 | |||||
FindFogCamera(); | |||||
if (_Downsample == 1) SafeDestroy(_FogVolumeCameraGO); | |||||
CameraUpdateSharedProperties(); | |||||
if (_Downsample > 0 && _FogVolumeCameraGO && this.isActiveAndEnabled) | |||||
{ | |||||
ThisCamera.cullingMask &= ~(1 << LayerMask.NameToLayer("FogVolume"));//hide FogVolume | |||||
ThisCamera.cullingMask &= ~(1 << LayerMask.NameToLayer("FogVolumeShadowCaster"));//hide FogVolumeShadowCaster | |||||
FogVolumeResolution = m_screenWidth + " X " + m_screenHeight; | |||||
ThisCamera.cullingMask |= 1 << LayerMask.NameToLayer("FogVolumeSurrogate");//show surrogate | |||||
} | |||||
else | |||||
{ | |||||
ThisCamera.cullingMask &= ~(1 << LayerMask.NameToLayer("FogVolumeSurrogate"));//hide surrogate | |||||
ThisCamera.cullingMask |= 1 << LayerMask.NameToLayer("FogVolume");//show FogVolume | |||||
ThisCamera.cullingMask |= 1 << LayerMask.NameToLayer("FogVolumeShadowCaster");//show FogVolumeShadowCaster | |||||
} | |||||
int InitialpixelLights = QualitySettings.pixelLightCount; | |||||
ShadowQuality InitialShadows = QualitySettings.shadows; | |||||
QualitySettings.pixelLightCount = 0; | |||||
QualitySettings.shadows = ShadowQuality.Disable; | |||||
#if UNITY_EDITOR | |||||
if (ThisCamera == null) | |||||
ThisCamera = gameObject.GetComponent<Camera>(); | |||||
#endif | |||||
UpdateParams(); | |||||
SurrogateMaterial.SetInt("_SrcBlend", (int)_BlendMode); | |||||
if (_Downsample > 1 && _FogVolumeCamera) | |||||
{ | |||||
//SurrogateMaterial.SetInt("_SrcBlend", (int)_BlendMode); | |||||
Shader.EnableKeyword("_FOG_LOWRES_RENDERER"); | |||||
Profiler.BeginSample("FogVolume Render"); | |||||
RenderDepth(); | |||||
RenderColor(); | |||||
Profiler.EndSample(); | |||||
// TexelUpdate(); | |||||
Shader.DisableKeyword("_FOG_LOWRES_RENDERER"); | |||||
} | |||||
else | |||||
{ | |||||
Shader.DisableKeyword("_FOG_LOWRES_RENDERER"); | |||||
} | |||||
QualitySettings.pixelLightCount = InitialpixelLights; | |||||
QualitySettings.shadows = InitialShadows; | |||||
} | |||||
void Update() | |||||
{ | |||||
#if UNITY_EDITOR | |||||
if (ShowCamerasBack != ShowCamera) | |||||
{ | |||||
EditorExtension.ToggleInHierarchy(_FogVolumeCameraGO, ShowCamera); | |||||
ShowCamerasBack = ShowCamera; | |||||
} | |||||
#endif | |||||
} | |||||
void SafeDestroy(Object obj) | |||||
{ | |||||
if (obj != null) | |||||
{ | |||||
//print("Destroyed " + obj); | |||||
DestroyImmediate(obj); | |||||
} | |||||
obj = null; | |||||
} | |||||
void OnDisable() | |||||
{ | |||||
// Shader.DisableKeyword("RENDER_SCENE_VIEW"); | |||||
Shader.DisableKeyword("_FOG_LOWRES_RENDERER"); | |||||
ThisCamera.cullingMask |= (1 << LayerMask.NameToLayer("FogVolume")); | |||||
ThisCamera.cullingMask |= 1 << LayerMask.NameToLayer("FogVolumeShadowCaster"); | |||||
ThisCamera.cullingMask &= ~(1 << LayerMask.NameToLayer("FogVolumeSurrogate"));//hide surrogate | |||||
SafeDestroy(_TAA); | |||||
SafeDestroy(_TAAvelocity); | |||||
SafeDestroy(_TAAjitter); | |||||
SafeDestroy(_FogVolumeCameraGO); | |||||
SafeDestroy(RT_FogVolume); | |||||
SafeDestroy(RT_FogVolumeR); | |||||
SafeDestroy(RT_Depth); | |||||
SafeDestroy(RT_DepthR); | |||||
//if (ThisCamera.depthTextureMode == DepthTextureMode.None) | |||||
// Debug.LogWarning("............ATTENTION, this camera is not generating the required Depth for Fog Volume. " + | |||||
// "Add -EnableDepthInForwardCamera.cs- to this camera"); | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: e5367b3334ceb84458088c8e4f026f0e | |||||
timeCreated: 1488739662 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {fileID: 2800000, guid: 925eb9f7b0e73dd438a616124964bba8, type: 3} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,385 @@ | |||||
using UnityEngine; | |||||
using FogVolumeUtilities; | |||||
[ExecuteInEditMode] | |||||
public class FogVolumeScreen : MonoBehaviour | |||||
{ | |||||
[Header("Scene blur")] | |||||
[Range(1, 8)] | |||||
public int Downsample = 8; | |||||
[SerializeField] | |||||
[Range(.001f, 15)] | |||||
float _Falloff = 1; | |||||
public int screenX | |||||
{ | |||||
get | |||||
{ | |||||
return SceneCamera.pixelWidth; | |||||
} | |||||
} | |||||
float FOV_compensation = 0; | |||||
public int screenY | |||||
{ | |||||
get | |||||
{ | |||||
return SceneCamera.pixelHeight; | |||||
} | |||||
} | |||||
Shader _BlurShader = null; | |||||
Camera UniformFogCamera; | |||||
GameObject UniformFogCameraGO; | |||||
[HideInInspector] | |||||
public Camera SceneCamera; | |||||
//[SerializeField] | |||||
RenderTexture RT_FogVolumeConvolution; | |||||
// [SerializeField] | |||||
RenderTextureFormat RT_Format; | |||||
[HideInInspector] | |||||
public int FogVolumeLayer = -1; | |||||
[SerializeField] | |||||
[HideInInspector] | |||||
string _FogVolumeLayerName = "FogVolumeUniform"; | |||||
public string FogVolumeLayerName | |||||
{ | |||||
get { return _FogVolumeLayerName; } | |||||
set | |||||
{ | |||||
if (_FogVolumeLayerName != value) | |||||
SetFogVolumeLayer(value); | |||||
} | |||||
} | |||||
void SetFogVolumeLayer(string NewFogVolumeLayerName) | |||||
{ | |||||
_FogVolumeLayerName = NewFogVolumeLayerName; | |||||
FogVolumeLayer = LayerMask.NameToLayer(_FogVolumeLayerName); | |||||
} | |||||
void OnValidate() | |||||
{ | |||||
SetFogVolumeLayer(_FogVolumeLayerName); | |||||
} | |||||
Material _BlurMaterial = null; | |||||
Material BlurMaterial | |||||
{ | |||||
get | |||||
{ | |||||
if (_BlurMaterial == null) | |||||
{ | |||||
_BlurMaterial = new Material(_BlurShader); | |||||
_BlurMaterial.hideFlags = HideFlags.HideAndDontSave; | |||||
} | |||||
return _BlurMaterial; | |||||
} | |||||
} | |||||
[Range(0, 10)] | |||||
public int iterations = 3; | |||||
// [Range(0, 1)] | |||||
// public float _Dither = .8f; | |||||
[Range(0.0f, 1.0f)] | |||||
public float blurSpread = 0.6f; | |||||
// [Range(0, 1)] | |||||
// public float ImageDistortion = 0; | |||||
//BLOOM stuff | |||||
public enum BlurType | |||||
{ | |||||
Standard = 0, | |||||
Sgx = 1, | |||||
} | |||||
[Header("Bloom")] | |||||
[Range(1, 5)] | |||||
public int _BloomDowsample = 8; | |||||
[Range(0.0f, 1.5f)] | |||||
public float threshold = 0.35f; | |||||
[Range(0.0f, 10)] | |||||
public float intensity = 2.5f; | |||||
[Range(0, 1)] | |||||
public float _Saturation = 1; | |||||
[Range(0, 5f)] | |||||
public float blurSize = 1; | |||||
[Range(1, 10)] | |||||
public int blurIterations = 4; | |||||
BlurType blurType = BlurType.Standard; | |||||
Shader fastBloomShader = null; | |||||
Material _fastBloomMaterial = null; | |||||
Material fastBloomMaterial | |||||
{ | |||||
get | |||||
{ | |||||
if (_fastBloomMaterial == null) | |||||
{ | |||||
_fastBloomMaterial = new Material(fastBloomShader); | |||||
_fastBloomMaterial.hideFlags = HideFlags.HideAndDontSave; | |||||
} | |||||
return _fastBloomMaterial; | |||||
} | |||||
} | |||||
void CreateUniformFogCamera() | |||||
{ | |||||
UniformFogCameraGO = GameObject.Find("Uniform Fog Volume Camera"); | |||||
if (UniformFogCameraGO == null) | |||||
{ | |||||
UniformFogCameraGO = new GameObject(); | |||||
UniformFogCameraGO.name = "Uniform Fog Volume Camera"; | |||||
if (UniformFogCamera == null) | |||||
UniformFogCamera = UniformFogCameraGO.AddComponent<Camera>(); | |||||
UniformFogCamera.backgroundColor = new Color(0, 0, 0, 0); | |||||
UniformFogCamera.clearFlags = CameraClearFlags.SolidColor; | |||||
UniformFogCamera.renderingPath = RenderingPath.Forward; | |||||
UniformFogCamera.enabled = false; | |||||
UniformFogCamera.farClipPlane = SceneCamera.farClipPlane; | |||||
#if UNITY_5_6_OR_NEWER | |||||
UniformFogCamera.GetComponent<Camera>().allowMSAA = false; | |||||
#endif | |||||
} | |||||
else | |||||
{ | |||||
UniformFogCamera = UniformFogCameraGO.GetComponent<Camera>(); | |||||
} | |||||
//UniformFogCameraGO.hideFlags = HideFlags.None; | |||||
UniformFogCameraGO.hideFlags = HideFlags.HideInHierarchy; | |||||
initFOV = SceneCamera.fieldOfView; | |||||
} | |||||
float initFOV; | |||||
void OnEnable() | |||||
{ | |||||
SceneCamera = gameObject.GetComponent<Camera>(); | |||||
_BlurShader = Shader.Find("Hidden/FogVolumeDensityFilter"); | |||||
if (_BlurShader == null) print("Hidden/FogVolumeDensityFilter #SHADER ERROR#"); | |||||
fastBloomShader = Shader.Find("Hidden/FogVolumeBloom"); | |||||
if (fastBloomShader == null) print("Hidden/FogVolumeBloom #SHADER ERROR#"); | |||||
CreateUniformFogCamera(); | |||||
} | |||||
protected void OnDisable() | |||||
{ | |||||
if (_BlurMaterial) | |||||
{ | |||||
DestroyImmediate(_BlurMaterial); | |||||
} | |||||
if (_fastBloomMaterial) | |||||
{ | |||||
DestroyImmediate(_fastBloomMaterial); | |||||
} | |||||
//3.2.1 lets destroy it | |||||
if (UniformFogCameraGO) | |||||
DestroyImmediate(UniformFogCameraGO); | |||||
} | |||||
public void FourTapCone(RenderTexture source, RenderTexture dest, int iteration) | |||||
{ | |||||
float off = 0.5f + iteration * blurSpread; | |||||
Graphics.BlitMultiTap(source, dest, BlurMaterial, | |||||
new Vector2(-off, -off), | |||||
new Vector2(-off, off), | |||||
new Vector2(off, off), | |||||
new Vector2(off, -off) | |||||
); | |||||
} | |||||
// Downsamples the texture to a quarter resolution. | |||||
private void DownSample4x(RenderTexture source, RenderTexture dest) | |||||
{ | |||||
float off = 1.0f; | |||||
Graphics.BlitMultiTap(source, dest, BlurMaterial, | |||||
new Vector2(-off, -off), | |||||
new Vector2(-off, off), | |||||
new Vector2(off, off), | |||||
new Vector2(off, -off) | |||||
); | |||||
} | |||||
public RenderTextureFormat GetRTFormat() | |||||
{ | |||||
#if UNITY_5_6_OR_NEWER | |||||
RT_Format=(SceneCamera.allowHDR == true) ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default; | |||||
return RT_Format; | |||||
#else | |||||
RT_Format = (SceneCamera.hdr == true) ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.ARGBHalf; | |||||
return RT_Format; | |||||
#endif | |||||
//return RT_Format; | |||||
} | |||||
public void ReleaseRT(RenderTexture rt) | |||||
{ | |||||
if (rt != null) | |||||
{ | |||||
RenderTexture.ReleaseTemporary(rt); | |||||
rt = null; | |||||
} | |||||
} | |||||
public RenderTextureReadWrite GetRTReadWrite() | |||||
{ | |||||
//return RenderTextureReadWrite.Default; | |||||
#if UNITY_5_6_OR_NEWER | |||||
return (SceneCamera.allowHDR) ? RenderTextureReadWrite.Default : RenderTextureReadWrite.Linear; | |||||
#else | |||||
return (SceneCamera.hdr) ? RenderTextureReadWrite.Default : RenderTextureReadWrite.Linear; | |||||
#endif | |||||
} | |||||
protected void GetRT(ref RenderTexture rt, int2 size, string name) | |||||
{ | |||||
// Release existing one | |||||
ReleaseRT(rt); | |||||
rt = RenderTexture.GetTemporary(size.x, size.y, 0, GetRTFormat(), GetRTReadWrite()); | |||||
rt.filterMode = FilterMode.Bilinear; | |||||
rt.name = name; | |||||
rt.wrapMode = TextureWrapMode.Repeat; | |||||
} | |||||
public void ConvolveFogVolume() | |||||
{ | |||||
if (UniformFogCameraGO == null) CreateUniformFogCamera(); | |||||
int2 resolution = new int2(screenX, screenY); | |||||
UniformFogCamera.projectionMatrix = SceneCamera.projectionMatrix; | |||||
UniformFogCamera.transform.position = SceneCamera.transform.position; | |||||
UniformFogCamera.transform.rotation = SceneCamera.transform.rotation; | |||||
GetRT(ref RT_FogVolumeConvolution, resolution, "RT_FogVolumeConvolution"); | |||||
UniformFogCamera.targetTexture = RT_FogVolumeConvolution; | |||||
UniformFogCamera.Render(); | |||||
Shader.SetGlobalTexture("RT_FogVolumeConvolution", RT_FogVolumeConvolution); | |||||
} | |||||
public bool SceneBloom = false; | |||||
#region instance | |||||
private static FogVolumeScreen _instance; | |||||
public static FogVolumeScreen instance | |||||
{ | |||||
get | |||||
{ | |||||
if (_instance == null) | |||||
{ | |||||
_instance = FindObjectOfType<FogVolumeScreen>(); | |||||
} | |||||
return _instance; | |||||
} | |||||
} | |||||
#endregion | |||||
RenderTexture _source; | |||||
void OnRenderImage(RenderTexture source, RenderTexture destination) | |||||
{ | |||||
ConvolveFogVolume(); | |||||
GetRT(ref _source, new int2(Screen.width, Screen.height), "_source"); | |||||
Graphics.Blit(source, _source); | |||||
fastBloomMaterial.SetTexture("_source", _source); | |||||
BlurMaterial.SetTexture("_source", _source); | |||||
//Graphics.Blit(_source, destination, BlurMaterial); | |||||
// RT_Format = source.format; | |||||
#region Density convolution | |||||
UniformFogCamera.cullingMask = 1 << instance.FogVolumeLayer; | |||||
//UniformFogCamera.cullingMask |= 1 << LayerMask.NameToLayer("FogVolumeUniform");//add Fog volume uniforms | |||||
FOV_compensation = initFOV / SceneCamera.fieldOfView; | |||||
Shader.SetGlobalFloat("FOV_compensation", FOV_compensation); | |||||
fastBloomMaterial.SetFloat("_Falloff", _Falloff); | |||||
// BlurMaterial.SetFloat("_Dither", _Dither); | |||||
// BlurMaterial.SetFloat("_Distortion", ImageDistortion * -.08f); | |||||
RenderTexture RT_DensityBlur = RenderTexture.GetTemporary(screenX / Downsample, screenY / Downsample, 0, RT_Format); | |||||
DownSample4x(source, RT_DensityBlur); | |||||
for (int i = 0; i < iterations; i++) | |||||
{ | |||||
RenderTexture RT_DensityBlur2 = RenderTexture.GetTemporary(screenX / Downsample, screenY / Downsample, 0, RT_Format); | |||||
FourTapCone(RT_DensityBlur, RT_DensityBlur2, i); | |||||
RenderTexture.ReleaseTemporary(RT_DensityBlur); | |||||
RT_DensityBlur = RT_DensityBlur2; | |||||
} | |||||
// Graphics.Blit(RT_DensityBlur, destination); | |||||
#endregion | |||||
#region Bloom | |||||
if (intensity > 0) | |||||
{ | |||||
Rendering.EnsureKeyword(fastBloomMaterial, "BLOOM", true); | |||||
float widthMod = 2.0f / (float)_BloomDowsample; | |||||
fastBloomMaterial.SetFloat("_Saturation", _Saturation); | |||||
fastBloomMaterial.SetVector("_Parameter", new Vector4(blurSize * widthMod, 0.0f, threshold, intensity)); | |||||
var rtW = source.width / _BloomDowsample; | |||||
var rtH = source.height / _BloomDowsample; | |||||
// downsample | |||||
RenderTexture rt = RenderTexture.GetTemporary(rtW, rtH, 0, RT_Format); | |||||
rt.filterMode = FilterMode.Bilinear; | |||||
if (SceneBloom) | |||||
Graphics.Blit(source, rt, fastBloomMaterial, 1); | |||||
else | |||||
Graphics.Blit(RT_DensityBlur, rt, fastBloomMaterial, 1); | |||||
var passOffs = blurType == BlurType.Standard ? 0 : 2; | |||||
for (int i = 1; i < blurIterations; i++) | |||||
{ | |||||
fastBloomMaterial.SetVector("_Parameter", new Vector4(blurSize * widthMod + (i * 1.0f), 0.0f, threshold, intensity)); | |||||
// vertical blur | |||||
RenderTexture rt2 = RenderTexture.GetTemporary(rtW, rtH, 0, RT_Format); | |||||
rt2.filterMode = FilterMode.Bilinear; | |||||
Graphics.Blit(rt, rt2, fastBloomMaterial, 2 + passOffs); | |||||
RenderTexture.ReleaseTemporary(rt); | |||||
rt = rt2; | |||||
// horizontal blur | |||||
rt2 = RenderTexture.GetTemporary(rtW, rtH, 0, RT_Format); | |||||
rt2.filterMode = FilterMode.Bilinear; | |||||
Graphics.Blit(rt, rt2, fastBloomMaterial, 3 + passOffs); | |||||
RenderTexture.ReleaseTemporary(rt); | |||||
rt = rt2; | |||||
} | |||||
fastBloomMaterial.SetTexture("_Bloom", rt); | |||||
RenderTexture.ReleaseTemporary(rt); | |||||
} | |||||
else | |||||
Rendering.EnsureKeyword(fastBloomMaterial, "BLOOM", false); | |||||
#endregion | |||||
Graphics.Blit(RT_DensityBlur, destination, fastBloomMaterial, 0); | |||||
RenderTexture.ReleaseTemporary(RT_DensityBlur); | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: ae4521adbf26e2a4c952cc03f6ffdb34 | |||||
timeCreated: 1493126607 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {fileID: 2800000, guid: 5aac178e436d68546ae151ed5ba76b94, type: 3} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,217 @@ | |||||
// Copyright (c) <2015> <Playdead> | |||||
// This file is subject to the MIT License as seen in the root of this folder structure (LICENSE.TXT) | |||||
// AUTHOR: Lasse Jon Fuglsang Pedersen <lasse@playdead.com> | |||||
#if UNITY_5_5_OR_NEWER | |||||
#define SUPPORT_STEREO | |||||
#endif | |||||
using UnityEngine; | |||||
[ExecuteInEditMode] | |||||
[RequireComponent(typeof(Camera), typeof(FogVolumePlaydeadTAA.FrustumJitter), typeof(FogVolumePlaydeadTAA.VelocityBuffer))] | |||||
//[AddComponentMenu("Playdead/TemporalReprojection")] | |||||
public class FogVolumeTAA : FogVolumePlaydeadTAA.EffectBase | |||||
{ | |||||
private static RenderBuffer[] mrt = new RenderBuffer[2]; | |||||
private Camera _FogVolumeCamera; | |||||
private FogVolumePlaydeadTAA.FrustumJitter _frustumJitter; | |||||
private FogVolumePlaydeadTAA.VelocityBuffer _velocityBuffer; | |||||
public Shader reprojectionShader; | |||||
private Material reprojectionMaterial; | |||||
private RenderTexture[,] reprojectionBuffer; | |||||
private int[] reprojectionIndex = new int[2] { -1, -1 }; | |||||
public enum Neighborhood | |||||
{ | |||||
MinMax3x3, | |||||
MinMax3x3Rounded, | |||||
MinMax4TapVarying, | |||||
}; | |||||
public Neighborhood neighborhood = Neighborhood.MinMax4TapVarying; | |||||
public bool unjitterColorSamples = true; | |||||
public bool unjitterNeighborhood = true; | |||||
public bool unjitterReprojection = true; | |||||
public bool useYCoCg = true; | |||||
public bool useClipping = true; | |||||
public bool useDilation = false; | |||||
public bool useMotionBlur = false; | |||||
public bool useOptimizations = false; | |||||
[Range(0.0f, 1.0f)] | |||||
public float feedbackMin = 0.88f; | |||||
[Range(0.0f, 1.0f)] | |||||
public float feedbackMax = 0.97f; | |||||
public float motionBlurStrength = 1.0f; | |||||
public bool motionBlurIgnoreFF = false; | |||||
void Reset() | |||||
{ | |||||
_FogVolumeCamera = GetComponent<Camera>(); | |||||
reprojectionShader = Shader.Find("Hidden/TAA"); | |||||
_FogVolumeCamera = GetComponent<Camera>(); | |||||
_frustumJitter = GetComponent<FogVolumePlaydeadTAA.FrustumJitter>(); | |||||
//_frustumJitter.enabled = false; | |||||
_velocityBuffer = GetComponent<FogVolumePlaydeadTAA.VelocityBuffer>(); | |||||
_velocityBuffer.velocityShader= Shader.Find("Hidden/VelocityBuffer"); | |||||
} | |||||
void Clear() | |||||
{ | |||||
EnsureArray(ref reprojectionIndex, 2); | |||||
reprojectionIndex[0] = -1; | |||||
reprojectionIndex[1] = -1; | |||||
} | |||||
void Awake() | |||||
{ | |||||
Reset(); | |||||
Clear(); | |||||
} | |||||
void Resolve(RenderTexture source, RenderTexture destination) | |||||
{ | |||||
_velocityBuffer.GenerateVelocityBuffer(); | |||||
EnsureArray(ref reprojectionBuffer, 2, 2); | |||||
EnsureArray(ref reprojectionIndex, 2, initialValue: -1); | |||||
EnsureMaterial(ref reprojectionMaterial, reprojectionShader); | |||||
if (reprojectionMaterial == null) | |||||
{ | |||||
Graphics.Blit(source, destination); | |||||
return; | |||||
} | |||||
#if SUPPORT_STEREO | |||||
int eyeIndex = (_FogVolumeCamera.stereoActiveEye == Camera.MonoOrStereoscopicEye.Right) ? 1 : 0; | |||||
#else | |||||
int eyeIndex = 0; | |||||
#endif | |||||
int bufferW = source.width; | |||||
int bufferH = source.height; | |||||
if (EnsureRenderTarget(ref reprojectionBuffer[eyeIndex, 0], bufferW, bufferH, source.format, FilterMode.Bilinear, antiAliasing: source.antiAliasing)) | |||||
Clear(); | |||||
if (EnsureRenderTarget(ref reprojectionBuffer[eyeIndex, 1], bufferW, bufferH, source.format, FilterMode.Bilinear, antiAliasing: source.antiAliasing)) | |||||
Clear(); | |||||
#if SUPPORT_STEREO | |||||
bool stereoEnabled = _FogVolumeCamera.stereoEnabled; | |||||
#else | |||||
bool stereoEnabled = false; | |||||
#endif | |||||
#if UNITY_EDITOR | |||||
bool allowMotionBlur = !stereoEnabled && Application.isPlaying; | |||||
#else | |||||
bool allowMotionBlur = !stereoEnabled; | |||||
#endif | |||||
EnsureKeyword(reprojectionMaterial, "CAMERA_PERSPECTIVE", !_FogVolumeCamera.orthographic); | |||||
EnsureKeyword(reprojectionMaterial, "CAMERA_ORTHOGRAPHIC", _FogVolumeCamera.orthographic); | |||||
EnsureKeyword(reprojectionMaterial, "MINMAX_3X3", neighborhood == Neighborhood.MinMax3x3); | |||||
EnsureKeyword(reprojectionMaterial, "MINMAX_3X3_ROUNDED", neighborhood == Neighborhood.MinMax3x3Rounded); | |||||
EnsureKeyword(reprojectionMaterial, "MINMAX_4TAP_VARYING", neighborhood == Neighborhood.MinMax4TapVarying); | |||||
EnsureKeyword(reprojectionMaterial, "UNJITTER_COLORSAMPLES", unjitterColorSamples); | |||||
EnsureKeyword(reprojectionMaterial, "UNJITTER_NEIGHBORHOOD", unjitterNeighborhood); | |||||
EnsureKeyword(reprojectionMaterial, "UNJITTER_REPROJECTION", unjitterReprojection); | |||||
EnsureKeyword(reprojectionMaterial, "USE_YCOCG", useYCoCg); | |||||
EnsureKeyword(reprojectionMaterial, "USE_CLIPPING", useClipping); | |||||
EnsureKeyword(reprojectionMaterial, "USE_DILATION", useDilation); | |||||
EnsureKeyword(reprojectionMaterial, "USE_MOTION_BLUR", useMotionBlur && allowMotionBlur); | |||||
EnsureKeyword(reprojectionMaterial, "USE_MOTION_BLUR_NEIGHBORMAX", _velocityBuffer.activeVelocityNeighborMax != null); | |||||
EnsureKeyword(reprojectionMaterial, "USE_OPTIMIZATIONS", useOptimizations); | |||||
if (reprojectionIndex[eyeIndex] == -1)// bootstrap | |||||
{ | |||||
reprojectionIndex[eyeIndex] = 0; | |||||
reprojectionBuffer[eyeIndex, reprojectionIndex[eyeIndex]].DiscardContents(); | |||||
Graphics.Blit(source, reprojectionBuffer[eyeIndex, reprojectionIndex[eyeIndex]]); | |||||
} | |||||
int indexRead = reprojectionIndex[eyeIndex]; | |||||
int indexWrite = (reprojectionIndex[eyeIndex] + 1) % 2; | |||||
Vector4 jitterUV = _frustumJitter.activeSample; | |||||
jitterUV.x /= bufferW; | |||||
jitterUV.y /= bufferH; | |||||
jitterUV.z /= bufferW; | |||||
jitterUV.w /= bufferH; | |||||
reprojectionMaterial.SetVector("_JitterUV", jitterUV); | |||||
reprojectionMaterial.SetTexture("_VelocityBuffer", _velocityBuffer.activeVelocityBuffer); | |||||
reprojectionMaterial.SetTexture("_VelocityNeighborMax", _velocityBuffer.activeVelocityNeighborMax); | |||||
reprojectionMaterial.SetTexture("_MainTex", source); | |||||
reprojectionMaterial.SetTexture("_PrevTex", reprojectionBuffer[eyeIndex, indexRead]); | |||||
reprojectionMaterial.SetFloat("_FeedbackMin", feedbackMin); | |||||
reprojectionMaterial.SetFloat("_FeedbackMax", feedbackMax); | |||||
// reprojectionMaterial.SetFloat("_MotionScale", motionBlurStrength * (motionBlurIgnoreFF ? Mathf.Min(1.0f, 1.0f / _velocityBuffer.timeScale) : 1.0f)); | |||||
// reproject frame n-1 into output + history buffer | |||||
{ | |||||
mrt[0] = reprojectionBuffer[eyeIndex, indexWrite].colorBuffer; | |||||
mrt[1] = destination.colorBuffer; | |||||
Graphics.SetRenderTarget(mrt, source.depthBuffer); | |||||
reprojectionMaterial.SetPass(0); | |||||
reprojectionBuffer[eyeIndex, indexWrite].DiscardContents(); | |||||
DrawFullscreenQuad(); | |||||
reprojectionIndex[eyeIndex] = indexWrite; | |||||
} | |||||
} | |||||
/* | |||||
void OnRenderImage(RenderTexture source, RenderTexture destination) | |||||
{ | |||||
//if (destination != null && source.antiAliasing == destination.antiAliasing)// resolve without additional blit when not end of chain | |||||
//{ | |||||
// Resolve(source, destination); | |||||
//} | |||||
//else | |||||
//{ | |||||
RenderTexture internalDestination = RenderTexture.GetTemporary(bufferW, bufferH, 0, _FogVolumeCamera.GetRTFormat(), RenderTextureReadWrite.Default, source.antiAliasing); | |||||
{ | |||||
Resolve(source, internalDestination); | |||||
Graphics.Blit(internalDestination, destination); | |||||
} | |||||
RenderTexture.ReleaseTemporary(internalDestination); | |||||
// } | |||||
} | |||||
*/ | |||||
public void TAA(ref RenderTexture source) | |||||
{ | |||||
// _FogVolumeCamera.depthTextureMode = DepthTextureMode.Depth; | |||||
RenderTexture internalDestination = RenderTexture.GetTemporary(source.width, source.height, 0, source.format); | |||||
{ | |||||
Resolve(source, internalDestination); | |||||
Graphics.Blit(internalDestination, source); | |||||
} | |||||
RenderTexture.ReleaseTemporary(internalDestination); | |||||
} | |||||
void OnDisable() | |||||
{ | |||||
if (reprojectionBuffer != null) | |||||
{ | |||||
ReleaseRenderTarget(ref reprojectionBuffer[0, 0]); | |||||
ReleaseRenderTarget(ref reprojectionBuffer[0, 1]); | |||||
ReleaseRenderTarget(ref reprojectionBuffer[1, 0]); | |||||
ReleaseRenderTarget(ref reprojectionBuffer[1, 1]); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 67bc9e87f0248cc498e6a2a2051daf01 | |||||
timeCreated: 1491815962 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,8 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 1fce8c816fd62134697c7793df29e3fd | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,3 @@ | |||||
version https://git-lfs.github.com/spec/v1 | |||||
oid sha256:bce2384086a9b6e2974e4c95a5d4a0f0e40615b9b742ba8e67643540ae3b526a | |||||
size 37012 |
@ -0,0 +1,84 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 132bd45e1d3746f4ba36d53d9e19b1c9 | |||||
timeCreated: 1489060890 | |||||
licenseType: Store | |||||
TextureImporter: | |||||
fileIDToRecycleName: {} | |||||
serializedVersion: 4 | |||||
mipmaps: | |||||
mipMapMode: 0 | |||||
enableMipMap: 0 | |||||
sRGBTexture: 1 | |||||
linearTexture: 0 | |||||
fadeOut: 0 | |||||
borderMipMap: 0 | |||||
mipMapFadeDistanceStart: 1 | |||||
mipMapFadeDistanceEnd: 3 | |||||
bumpmap: | |||||
convertToNormalMap: 0 | |||||
externalNormalMap: 0 | |||||
heightScale: 0.25 | |||||
normalMapFilter: 0 | |||||
isReadable: 0 | |||||
grayScaleToAlpha: 0 | |||||
generateCubemap: 6 | |||||
cubemapConvolution: 0 | |||||
seamlessCubemap: 0 | |||||
textureFormat: 1 | |||||
maxTextureSize: 2048 | |||||
textureSettings: | |||||
filterMode: 0 | |||||
aniso: -1 | |||||
mipBias: -1 | |||||
wrapMode: -1 | |||||
nPOTScale: 1 | |||||
lightmap: 0 | |||||
compressionQuality: 50 | |||||
spriteMode: 0 | |||||
spriteExtrude: 1 | |||||
spriteMeshType: 1 | |||||
alignment: 0 | |||||
spritePivot: {x: 0.5, y: 0.5} | |||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0} | |||||
spritePixelsToUnits: 100 | |||||
alphaUsage: 1 | |||||
alphaIsTransparency: 0 | |||||
spriteTessellationDetail: -1 | |||||
textureType: 0 | |||||
textureShape: 1 | |||||
maxTextureSizeSet: 0 | |||||
compressionQualitySet: 0 | |||||
textureFormatSet: 0 | |||||
platformSettings: | |||||
- buildTarget: DefaultTexturePlatform | |||||
maxTextureSize: 2048 | |||||
textureFormat: -1 | |||||
textureCompression: 0 | |||||
compressionQuality: 50 | |||||
crunchedCompression: 0 | |||||
allowsAlphaSplitting: 0 | |||||
overridden: 0 | |||||
- buildTarget: Standalone | |||||
maxTextureSize: 2048 | |||||
textureFormat: -1 | |||||
textureCompression: 0 | |||||
compressionQuality: 50 | |||||
crunchedCompression: 0 | |||||
allowsAlphaSplitting: 0 | |||||
overridden: 0 | |||||
- buildTarget: Android | |||||
maxTextureSize: 2048 | |||||
textureFormat: -1 | |||||
textureCompression: 0 | |||||
compressionQuality: 50 | |||||
crunchedCompression: 0 | |||||
allowsAlphaSplitting: 0 | |||||
overridden: 0 | |||||
spriteSheet: | |||||
serializedVersion: 2 | |||||
sprites: [] | |||||
outline: [] | |||||
spritePackingTag: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,3 @@ | |||||
version https://git-lfs.github.com/spec/v1 | |||||
oid sha256:6d1663b06c7f78d2ad57a608a17d83123cc9b0c95269f124798c0b0846a5f384 | |||||
size 47030 |
@ -0,0 +1,76 @@ | |||||
fileFormatVersion: 2 | |||||
guid: fa2064f3c8dffc04f93f4f74eae0d72f | |||||
timeCreated: 1483799594 | |||||
licenseType: Store | |||||
TextureImporter: | |||||
fileIDToRecycleName: {} | |||||
serializedVersion: 4 | |||||
mipmaps: | |||||
mipMapMode: 0 | |||||
enableMipMap: 1 | |||||
sRGBTexture: 1 | |||||
linearTexture: 0 | |||||
fadeOut: 0 | |||||
borderMipMap: 0 | |||||
mipMapFadeDistanceStart: 1 | |||||
mipMapFadeDistanceEnd: 3 | |||||
bumpmap: | |||||
convertToNormalMap: 0 | |||||
externalNormalMap: 0 | |||||
heightScale: 0.25 | |||||
normalMapFilter: 0 | |||||
isReadable: 0 | |||||
grayScaleToAlpha: 0 | |||||
generateCubemap: 6 | |||||
cubemapConvolution: 0 | |||||
seamlessCubemap: 0 | |||||
textureFormat: 1 | |||||
maxTextureSize: 2048 | |||||
textureSettings: | |||||
filterMode: -1 | |||||
aniso: -1 | |||||
mipBias: -1 | |||||
wrapMode: -1 | |||||
nPOTScale: 1 | |||||
lightmap: 0 | |||||
compressionQuality: 50 | |||||
spriteMode: 0 | |||||
spriteExtrude: 1 | |||||
spriteMeshType: 1 | |||||
alignment: 0 | |||||
spritePivot: {x: 0.5, y: 0.5} | |||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0} | |||||
spritePixelsToUnits: 100 | |||||
alphaUsage: 1 | |||||
alphaIsTransparency: 1 | |||||
spriteTessellationDetail: -1 | |||||
textureType: 0 | |||||
textureShape: 1 | |||||
maxTextureSizeSet: 0 | |||||
compressionQualitySet: 0 | |||||
textureFormatSet: 0 | |||||
platformSettings: | |||||
- buildTarget: DefaultTexturePlatform | |||||
maxTextureSize: 2048 | |||||
textureFormat: -1 | |||||
textureCompression: 0 | |||||
compressionQuality: 50 | |||||
crunchedCompression: 0 | |||||
allowsAlphaSplitting: 0 | |||||
overridden: 0 | |||||
- buildTarget: Standalone | |||||
maxTextureSize: 2048 | |||||
textureFormat: -1 | |||||
textureCompression: 0 | |||||
compressionQuality: 50 | |||||
crunchedCompression: 0 | |||||
allowsAlphaSplitting: 0 | |||||
overridden: 0 | |||||
spriteSheet: | |||||
serializedVersion: 2 | |||||
sprites: [] | |||||
outline: [] | |||||
spritePackingTag: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,8 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 9fac23f9a9693e04f8ad00233986bf9e | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,33 @@ | |||||
using System.Collections; | |||||
using System.Collections.Generic; | |||||
using UnityEngine; | |||||
[ExecuteInEditMode] | |||||
public class ColorAnimation : MonoBehaviour { | |||||
float X, Y, Z; | |||||
[Range(0, 10)] | |||||
public float _ColorSpeed = 6; | |||||
float ColorSpeed; | |||||
Vector3 RandomRangeXYZ; | |||||
[SerializeField] | |||||
[Range(1, 300)] | |||||
float Intensity=8; | |||||
void OnEnable () | |||||
{ | |||||
RandomRangeXYZ.x = Random.Range(0f, 1f); | |||||
RandomRangeXYZ.y = Random.Range(0f, 1f); | |||||
RandomRangeXYZ.z = Random.Range(0f, 1f); | |||||
} | |||||
// Update is called once per frame | |||||
void Update () { | |||||
ColorSpeed += Time.deltaTime * _ColorSpeed; | |||||
X = Mathf.Sin(ColorSpeed * RandomRangeXYZ.x) * 0.5f + 0.5f; | |||||
Y = Mathf.Sin(ColorSpeed * RandomRangeXYZ.y) * 0.5f + 0.5f; | |||||
Z = Mathf.Sin(ColorSpeed * RandomRangeXYZ.z) * 0.5f + 0.5f; | |||||
float IntensityVariable = Mathf.Sin(ColorSpeed * RandomRangeXYZ.z) * 0.5f + 0.5f; | |||||
Color RandomColor = new Color(X, Y, Z, 1); | |||||
GetComponent<Renderer>().sharedMaterial.SetColor("_EmissionColor", IntensityVariable*Intensity * RandomColor); | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: f5d2330daeaa77e498d5ce30be3c3c4d | |||||
timeCreated: 1500080234 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,21 @@ | |||||
using UnityEngine; | |||||
using System.Collections; | |||||
[ExecuteInEditMode] | |||||
public class EnableDepthInForwardCamera : MonoBehaviour { | |||||
public string Message = "Add this script to generate depth if Fog Volume rendered is not used and rendering path is forward"; | |||||
// Use this for initialization | |||||
void OnEnable() { | |||||
} | |||||
// Update is called once per frame | |||||
void Update() | |||||
{ | |||||
if (GetComponent<Camera>().depthTextureMode != DepthTextureMode.Depth) | |||||
GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth; | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 9171b3ee906d3e140b7dab42245bd3d3 | |||||
timeCreated: 1485265329 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,277 @@ | |||||
using UnityEngine; | |||||
using System.Collections; | |||||
public class ExplorationCamera : MonoBehaviour | |||||
{ | |||||
//Turn | |||||
[Range(1f, 50)] | |||||
public float sensitivity = 30; | |||||
[Range(.1f, 50)] | |||||
public float smoothing = 5f; | |||||
//Movement | |||||
private float speedZ; | |||||
private float speedX; | |||||
private float speedY; | |||||
[Range(.1f, 10)] | |||||
public float Speed = .1f; | |||||
[HideInInspector] | |||||
public float InitialSpeed = .1f; | |||||
[HideInInspector] | |||||
public float FOV; | |||||
private float initialFOV; | |||||
Vector2 initialLook; | |||||
Vector2 Look; | |||||
private Vector3 MovementDirection; | |||||
public float MaxAcceleration = 4; | |||||
[Range(1f, 10)] | |||||
public float AccelerationSmoothing = 10, SpeedSmooth = 1; | |||||
Vector2 _smoothMouse; | |||||
public bool HideCursor = false; | |||||
float focalLength = 0, focalSize = 1; | |||||
public bool ConstantMove = false; | |||||
Camera ThisCamera; | |||||
[HideInInspector] | |||||
public float tilt; | |||||
void Start() | |||||
{ | |||||
try | |||||
{ | |||||
//gamepad | |||||
Input.GetAxis("LookHorizontal"); | |||||
} | |||||
catch | |||||
{ | |||||
print("Import the custom input to support gamepad in this camera script\n http://davidmiranda.me/files/FogVolume3/InputManager.asset"); | |||||
} | |||||
//if (this.GetComponent<UnityStandardAssets.ImageEffects.DepthOfField>()) | |||||
//{ | |||||
// focalLength = this.GetComponent<UnityStandardAssets.ImageEffects.DepthOfField>().focalLength; | |||||
// focalSize = this.GetComponent<UnityStandardAssets.ImageEffects.DepthOfField>().focalSize; | |||||
//} | |||||
} | |||||
Vector2 lastPos; | |||||
void OnGUI() | |||||
{ | |||||
//ratón | |||||
if (Event.current.type == EventType.MouseDown) | |||||
{ | |||||
lastPos = Event.current.mousePosition; | |||||
} | |||||
else if (Event.current.type == EventType.MouseDrag || Event.current.type == EventType.MouseMove) | |||||
{ | |||||
Vector3 diff = Event.current.mousePosition - lastPos; | |||||
Look += new Vector2(diff.x * sensitivity / 50, -diff.y * sensitivity / 50); | |||||
lastPos = Event.current.mousePosition; | |||||
} | |||||
} | |||||
public float tiltSmoothing = 50, FOVTransitionSpeed = .1f; | |||||
public float inclination = 13; | |||||
public bool ApplyGravity; | |||||
[Range(0f, 1)] | |||||
public float gravityAccelerationScale = .1f; | |||||
void OnDestroy() | |||||
{ Cursor.visible = true; } | |||||
void FixedUpdate() | |||||
{ | |||||
// if (Input.GetKey(KeyCode.Escape)) Application.Quit(); | |||||
try | |||||
{ | |||||
//gamepad | |||||
if (Mathf.Abs(Input.GetAxis("LookHorizontal")) > 0.017f || Mathf.Abs(Input.GetAxis("LookVertical")) > 0.017f) | |||||
{ | |||||
Look += new Vector2(Input.GetAxis("LookHorizontal"), -Input.GetAxis("LookVertical")) * sensitivity; | |||||
if (Input.GetAxis("LookHorizontal") > 0) | |||||
tilt = Mathf.Lerp(tilt, -inclination * Mathf.Abs(Input.GetAxis("LookHorizontal")) * sensitivity, 1f / tiltSmoothing); | |||||
else | |||||
tilt = Mathf.Lerp(tilt, inclination * Mathf.Abs(Input.GetAxis("LookHorizontal")) * sensitivity, 1f / tiltSmoothing); | |||||
} | |||||
} | |||||
catch | |||||
{ | |||||
// | |||||
} | |||||
tilt = Mathf.Lerp(tilt, 0, 1f / tiltSmoothing); | |||||
//DOF | |||||
if (Input.GetKey(KeyCode.PageDown)) | |||||
focalLength -= .05f; | |||||
if (Input.GetKey(KeyCode.PageUp)) | |||||
focalLength += .05f; | |||||
if (Input.GetKey(KeyCode.End)) | |||||
focalSize -= .05f; | |||||
if (Input.GetKey(KeyCode.Home)) | |||||
focalSize += .05f; | |||||
//if (this.GetComponent<UnityStandardAssets.ImageEffects.DepthOfField>()) | |||||
//{ | |||||
// this.GetComponent<UnityStandardAssets.ImageEffects.DepthOfField>().focalLength = focalLength; | |||||
// this.GetComponent<UnityStandardAssets.ImageEffects.DepthOfField>().focalSize = focalSize; | |||||
//} | |||||
//Turn interpolation | |||||
_smoothMouse.x = Mathf.Lerp(_smoothMouse.x, Look.x, 1f / smoothing); | |||||
_smoothMouse.y = Mathf.Lerp(_smoothMouse.y, Look.y, 1f / smoothing); | |||||
//Aplica giro suave | |||||
transform.localEulerAngles = new Vector3(-_smoothMouse.y, _smoothMouse.x, tilt); | |||||
//Traslación: | |||||
if (Input.GetKey(KeyCode.W) || Input.GetAxis("Vertical") > 0 || ConstantMove) | |||||
{ | |||||
MovementDirection = new Vector3(0, 0, 1); | |||||
speedZ = Mathf.Lerp(speedZ, Speed, 1f / smoothing); | |||||
} | |||||
if (Input.GetKey(KeyCode.S) || Input.GetAxis("Vertical") < 0) | |||||
{ | |||||
MovementDirection = new Vector3(0, 0, -1); | |||||
speedZ = Mathf.Lerp(speedZ, -Speed, 1f / smoothing); | |||||
} | |||||
if (Input.GetKey(KeyCode.A) || Input.GetAxis("Horizontal") < 0) | |||||
{ | |||||
MovementDirection = new Vector3(-1, 0, 0); | |||||
speedX = Mathf.Lerp(speedX, -Speed, 1f / smoothing); | |||||
} | |||||
if (Input.GetKey(KeyCode.D) || Input.GetAxis("Horizontal") > 0) | |||||
{ | |||||
MovementDirection = new Vector3(1, 0, 0); | |||||
speedX = Mathf.Lerp(speedX, Speed, 1f / smoothing); | |||||
} | |||||
if (Input.GetKey(KeyCode.Q) || Input.GetKey(KeyCode.JoystickButton4)) | |||||
{ | |||||
MovementDirection = new Vector3(0, -1, 0); | |||||
speedY = Mathf.Lerp(speedY, -Speed, 1f / smoothing); | |||||
} | |||||
if (Input.GetKey(KeyCode.E) || Input.GetKey(KeyCode.JoystickButton5)) | |||||
{ | |||||
MovementDirection = new Vector3(0, 1, 0); | |||||
speedY = Mathf.Lerp(speedY, Speed, 1f / smoothing); | |||||
} | |||||
//desaceleración | |||||
speedZ = Mathf.Lerp(speedZ, 0, 1f / smoothing); | |||||
MovementDirection.z = speedZ; | |||||
speedY = Mathf.Lerp(speedY, 0, 1f / smoothing); | |||||
MovementDirection.y = speedY; | |||||
speedX = Mathf.Lerp(speedX, 0, 1f / smoothing); | |||||
MovementDirection = new Vector3(speedX, speedY, speedZ); | |||||
if (ApplyGravity) | |||||
{ | |||||
MovementDirection += Physics.gravity * gravityAccelerationScale; | |||||
} | |||||
transform.Translate(MovementDirection); | |||||
// transform.Rotate(Vector3.forward, tilt * 150); | |||||
//Speed Ratón | |||||
Speed = Mathf.Clamp(Speed, .001f, 100f); | |||||
if (Input.GetMouseButton(1)) | |||||
{ | |||||
InitialSpeed += Input.GetAxis("Mouse ScrollWheel") * .5f; | |||||
InitialSpeed = Mathf.Max(.1f, InitialSpeed); | |||||
} | |||||
//FOV | |||||
if (Input.GetMouseButton(1) & Input.GetKey(KeyCode.C) & FOV > 5) | |||||
{ | |||||
FOV -= 1; | |||||
} | |||||
if (Input.GetMouseButton(1) & Input.GetKey(KeyCode.Z) & FOV < 120) | |||||
{ | |||||
FOV += 1; | |||||
} | |||||
//Al soltar la tecla: | |||||
if (Input.GetMouseButton(1) == false) | |||||
{ | |||||
FOV = Mathf.Lerp(FOV, initialFOV, FOVTransitionSpeed);//El último valor sería la velocidad a la que vuelve al fov original | |||||
//Rueda: | |||||
// speedZ += Input.GetAxis("Mouse ScrollWheel"); | |||||
} | |||||
//Aplicar | |||||
// | |||||
// | |||||
if (ThisCamera) | |||||
if (ThisCamera.stereoEnabled == false) | |||||
GetComponent<Camera>().fieldOfView = FOV; | |||||
} | |||||
float TriggerValue = 0; | |||||
void Update() | |||||
{ | |||||
//Extra velocidad: | |||||
try | |||||
{ | |||||
TriggerValue = Mathf.Pow(Input.GetAxis("FasterCamera") * 1 / AccelerationSmoothing + 1, 2); | |||||
} | |||||
catch { } | |||||
//print(Speed); | |||||
if (Input.GetKeyDown(KeyCode.LeftShift)) | |||||
{ | |||||
Speed *= MaxAcceleration; | |||||
} | |||||
try | |||||
{ | |||||
if (Input.GetAxis("FasterCamera") > 0 && Speed < InitialSpeed * MaxAcceleration) | |||||
{ | |||||
Speed *= TriggerValue; | |||||
} | |||||
else | |||||
if (!Input.GetKey(KeyCode.LeftShift)) | |||||
Speed = Mathf.Lerp(Speed, InitialSpeed, 1 / AccelerationSmoothing); | |||||
} | |||||
catch | |||||
{ | |||||
if (!Input.GetKey(KeyCode.LeftShift)) | |||||
Speed = Mathf.Lerp(Speed, InitialSpeed, 1 / AccelerationSmoothing); | |||||
} | |||||
// print(Speed); | |||||
if (Input.GetKeyUp(KeyCode.LeftShift)) | |||||
{ | |||||
Speed /= MaxAcceleration; | |||||
} | |||||
} | |||||
void OnEnable() | |||||
{ | |||||
if (GetComponent<Camera>()) | |||||
ThisCamera = GetComponent<Camera>(); | |||||
InitialSpeed = Speed; | |||||
if (HideCursor) | |||||
Cursor.visible = false; | |||||
if(ThisCamera) | |||||
FOV = this.gameObject.GetComponent<Camera>().fieldOfView; | |||||
initialFOV = FOV; | |||||
initialLook = new Vector2(transform.eulerAngles.y, transform.eulerAngles.x * -1); | |||||
// Debug.Log (transform.eulerAngles); | |||||
Look = initialLook; | |||||
_smoothMouse = initialLook; | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 857bc2eca15f6a442b001c052ebee65a | |||||
timeCreated: 1466361682 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,8 @@ | |||||
fileFormatVersion: 2 | |||||
guid: c91887ea09ff1024ab4002ea6579a380 | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,38 @@ | |||||
using System; | |||||
using UnityEngine; | |||||
using UnityEngine.UI; | |||||
namespace FogVolumeUtils.FPSCounter | |||||
{ | |||||
[RequireComponent(typeof(Text))] | |||||
public class FPSCounter : MonoBehaviour | |||||
{ | |||||
const float fpsMeasurePeriod = 0.5f; | |||||
private int m_FpsAccumulator = 0; | |||||
private float m_FpsNextPeriod = 0; | |||||
private int m_CurrentFps; | |||||
const string display = "{0} FPS"; | |||||
private Text m_Text; | |||||
private void Start() | |||||
{ | |||||
m_FpsNextPeriod = Time.realtimeSinceStartup + fpsMeasurePeriod; | |||||
m_Text = GetComponent<Text>(); | |||||
} | |||||
private void Update() | |||||
{ | |||||
// measure average frames per second | |||||
m_FpsAccumulator++; | |||||
if (Time.realtimeSinceStartup > m_FpsNextPeriod) | |||||
{ | |||||
m_CurrentFps = (int)(m_FpsAccumulator / fpsMeasurePeriod); | |||||
m_FpsAccumulator = 0; | |||||
m_FpsNextPeriod += fpsMeasurePeriod; | |||||
m_Text.text = string.Format(display, m_CurrentFps); | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: c7990fff9467341408ccc3feaad062a4 | |||||
timeCreated: 1492927761 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,53 @@ | |||||
using System.Collections; | |||||
using System.Collections.Generic; | |||||
using UnityEngine; | |||||
[ExecuteInEditMode] | |||||
public class FogVolumePriority : MonoBehaviour { | |||||
public Camera GameCamera; | |||||
public int FogOrderCameraAbove=1; | |||||
public int FogOrderCameraBelow=-1; | |||||
public float HeightThreshold=30; | |||||
public FogVolume thisFog; | |||||
FogVolumeData _FogVolumeData; | |||||
public float CurrentHeight; | |||||
// public bool AutoAssignCameraCurrent = true; | |||||
public GameObject Horizon; | |||||
// Use this for initialization | |||||
void OnEnable () { | |||||
thisFog = GetComponent<FogVolume>(); | |||||
_FogVolumeData = thisFog._FogVolumeData; | |||||
} | |||||
// Update is called once per frame | |||||
void Update() | |||||
{ | |||||
// if (AutoAssignCameraCurrent) | |||||
// GameCamera = Camera.current; | |||||
if(Horizon) | |||||
HeightThreshold = Horizon.transform.position.y; | |||||
//if(!Application.isPlaying) | |||||
// GameCamera = Camera.current; | |||||
if (_FogVolumeData) | |||||
GameCamera = _FogVolumeData.GameCamera; | |||||
else | |||||
GameCamera = Camera.main; | |||||
if (GameCamera) | |||||
{ | |||||
if (!Application.isPlaying) | |||||
{ | |||||
if (Camera.current != null) | |||||
CurrentHeight = Camera.current.gameObject.transform.position.y; | |||||
} | |||||
else | |||||
CurrentHeight = GameCamera.gameObject.transform.position.y; | |||||
if (HeightThreshold > CurrentHeight && Horizon != null) | |||||
thisFog.DrawOrder = FogOrderCameraBelow; | |||||
else | |||||
thisFog.DrawOrder = FogOrderCameraAbove; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: a65425c0575171a49b832f4d0a8cc88c | |||||
timeCreated: 1486352719 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,21 @@ | |||||
using UnityEngine; | |||||
using System.Collections; | |||||
namespace FogVolumeRenderPriority | |||||
{ | |||||
[ExecuteInEditMode] | |||||
public class RenderPriority : MonoBehaviour { | |||||
public int DrawOrder = 0; | |||||
public bool UpdateRealTime = false; | |||||
// Use this for initialization | |||||
void OnEnable () { | |||||
gameObject.GetComponent<Renderer>().sortingOrder = DrawOrder; | |||||
} | |||||
// Update is called once per frame | |||||
void Update () { | |||||
if(UpdateRealTime) | |||||
gameObject.GetComponent<Renderer>().sortingOrder = DrawOrder; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 7fa1d7ed39f67024f9b90b2b4a365d3b | |||||
timeCreated: 1486352366 | |||||
licenseType: Store | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |