mirror of
https://github.com/celisej567/metaballs.git
synced 2026-09-21 20:15:02 +03:00
Initial code commit
This commit is contained in:
9
Assets/Materials.meta
Normal file
9
Assets/Materials.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e4186954fe061e749908eedf2d0f7024
|
||||
folderAsset: yes
|
||||
timeCreated: 1471974501
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
127
Assets/Materials/MetaballMaterial.mat
Normal file
127
Assets/Materials/MetaballMaterial.mat
Normal file
@@ -0,0 +1,127 @@
|
||||
%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: MetaballMaterial
|
||||
m_Shader: {fileID: 4800000, guid: 9a51496bc11f7b54ab026c8a4cbef208, 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
|
||||
- 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: _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: 0.14987026, g: 0.9705882, b: 0.25741273, a: 0}
|
||||
- first:
|
||||
name: _EmissionColor
|
||||
second: {r: 0.13516438, g: 0.9191176, b: 0.2378894, a: 1}
|
||||
8
Assets/Materials/MetaballMaterial.mat.meta
Normal file
8
Assets/Materials/MetaballMaterial.mat.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 23c5ccb8ec7586243997aa73d584582d
|
||||
timeCreated: 1471974510
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Models.meta
Normal file
9
Assets/Models.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f5e37e6856cd534c9c799f071b89737
|
||||
folderAsset: yes
|
||||
timeCreated: 1472225326
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Models/3.skp
Normal file
BIN
Assets/Models/3.skp
Normal file
Binary file not shown.
96
Assets/Models/3.skp.meta
Normal file
96
Assets/Models/3.skp.meta
Normal file
@@ -0,0 +1,96 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c5bba6be1fcdea4495ee17c17a605b2
|
||||
timeCreated: 1474022078
|
||||
licenseType: Free
|
||||
SketchUpImporter:
|
||||
generateBackFace: 0
|
||||
mergeCoplanarFaces: 0
|
||||
selectedNodes: 0000000001000000
|
||||
assetHash:
|
||||
serializedVersion: 2
|
||||
Hash: 1f08fed05ca6dbb7e00630407281a187
|
||||
longitude: -105.242139
|
||||
latitude: 40.018309
|
||||
northCorrection: -0
|
||||
fileUnit: 0
|
||||
sketchUpImportData:
|
||||
defaultCamera:
|
||||
position: {x: 12.186621, y: 88.965004, z: -9.949007}
|
||||
lookAt: {x: 12.062738, y: 70.91876, z: -5.746629}
|
||||
up: {x: -0.028697615, y: 0.22689252, z: 0.9734969}
|
||||
fov: 35
|
||||
aspectRatio: 0
|
||||
orthoSize: 1
|
||||
isPerspective: 1
|
||||
scenes: []
|
||||
serializedVersion: 19
|
||||
fileIDToRecycleName:
|
||||
100000: //RootNode
|
||||
400000: //RootNode
|
||||
2300000: //RootNode
|
||||
3300000: //RootNode
|
||||
4300000: Mesh 3
|
||||
materials:
|
||||
importMaterials: 1
|
||||
materialName: 2
|
||||
materialSearch: 0
|
||||
animations:
|
||||
legacyGenerateAnimations: 4
|
||||
bakeSimulation: 0
|
||||
resampleCurves: 1
|
||||
optimizeGameObjects: 0
|
||||
motionNodeName:
|
||||
animationImportErrors:
|
||||
animationImportWarnings:
|
||||
animationRetargetingWarnings:
|
||||
animationDoRetargetingWarnings: 0
|
||||
animationCompression: 1
|
||||
animationRotationError: 0.5
|
||||
animationPositionError: 0.5
|
||||
animationScaleError: 0.5
|
||||
animationWrapMode: 0
|
||||
extraExposedTransformPaths: []
|
||||
clipAnimations: []
|
||||
isReadable: 1
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
globalScale: 0.0508
|
||||
meshCompression: 0
|
||||
addColliders: 0
|
||||
importBlendShapes: 1
|
||||
swapUVChannels: 0
|
||||
generateSecondaryUV: 0
|
||||
useFileUnits: 1
|
||||
optimizeMeshForGPU: 1
|
||||
keepQuads: 0
|
||||
weldVertices: 1
|
||||
secondaryUVAngleDistortion: 8
|
||||
secondaryUVAreaDistortion: 15.000001
|
||||
secondaryUVHardAngle: 88
|
||||
secondaryUVPackMargin: 4
|
||||
useFileScale: 1
|
||||
tangentSpace:
|
||||
normalSmoothAngle: 60
|
||||
normalImportMode: 0
|
||||
tangentImportMode: 3
|
||||
importAnimation: 0
|
||||
copyAvatar: 0
|
||||
humanDescription:
|
||||
human: []
|
||||
skeleton: []
|
||||
armTwist: 0.5
|
||||
foreArmTwist: 0.5
|
||||
upperLegTwist: 0.5
|
||||
legTwist: 0.5
|
||||
armStretch: 0.05
|
||||
legStretch: 0.05
|
||||
feetSpacing: 0
|
||||
rootMotionBoneName:
|
||||
hasTranslationDoF: 0
|
||||
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||
animationType: 0
|
||||
humanoidOversampling: 1
|
||||
additionalBone: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Models/Materials.meta
Normal file
9
Assets/Models/Materials.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f00d4f111c860054a870a48b7c8e8800
|
||||
folderAsset: yes
|
||||
timeCreated: 1472225330
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
127
Assets/Models/Materials/3-Burnt Sienna.mat
Normal file
127
Assets/Models/Materials/3-Burnt Sienna.mat
Normal file
@@ -0,0 +1,127 @@
|
||||
%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: 3-Burnt Sienna
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
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: _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: 0.5411765, g: 0.3137255, b: 0.29803923, a: 1}
|
||||
- first:
|
||||
name: _EmissionColor
|
||||
second: {r: 0, g: 0, b: 0, a: 1}
|
||||
8
Assets/Models/Materials/3-Burnt Sienna.mat.meta
Normal file
8
Assets/Models/Materials/3-Burnt Sienna.mat.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3df128a00cd60034a84abd4af03493ea
|
||||
timeCreated: 1474022078
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
127
Assets/Models/Materials/3-Gray3.mat
Normal file
127
Assets/Models/Materials/3-Gray3.mat
Normal file
@@ -0,0 +1,127 @@
|
||||
%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: 3-Gray3
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
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.507
|
||||
- first:
|
||||
name: _GlossyReflections
|
||||
second: 1
|
||||
- first:
|
||||
name: _Metallic
|
||||
second: 0.122
|
||||
- first:
|
||||
name: _Mode
|
||||
second: 0
|
||||
- first:
|
||||
name: _OcclusionStrength
|
||||
second: 1
|
||||
- first:
|
||||
name: _Parallax
|
||||
second: 0.02
|
||||
- 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: 0.8392157, g: 0.8392157, b: 0.8392157, a: 1}
|
||||
- first:
|
||||
name: _EmissionColor
|
||||
second: {r: 0, g: 0, b: 0, a: 1}
|
||||
8
Assets/Models/Materials/3-Gray3.mat.meta
Normal file
8
Assets/Models/Materials/3-Gray3.mat.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6e29a58e1dd5a04fa36b5391e1e08ce
|
||||
timeCreated: 1474022078
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
127
Assets/Models/Materials/lambert1.mat
Normal file
127
Assets/Models/Materials/lambert1.mat
Normal file
@@ -0,0 +1,127 @@
|
||||
%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: lambert1
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
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: _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: 0.9044118, g: 0.9044118, b: 0.9044118, a: 1}
|
||||
- first:
|
||||
name: _EmissionColor
|
||||
second: {r: 0, g: 0, b: 0, a: 1}
|
||||
8
Assets/Models/Materials/lambert1.mat.meta
Normal file
8
Assets/Models/Materials/lambert1.mat.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a27f6a86443ed324b9b2b33f454362d5
|
||||
timeCreated: 1472225330
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Models/Oltar.fbx
Normal file
BIN
Assets/Models/Oltar.fbx
Normal file
Binary file not shown.
76
Assets/Models/Oltar.fbx.meta
Normal file
76
Assets/Models/Oltar.fbx.meta
Normal file
@@ -0,0 +1,76 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 383074ff06605fc4fb7a07e2ab971c02
|
||||
timeCreated: 1472225330
|
||||
licenseType: Free
|
||||
ModelImporter:
|
||||
serializedVersion: 19
|
||||
fileIDToRecycleName:
|
||||
100000: //RootNode
|
||||
400000: //RootNode
|
||||
2300000: //RootNode
|
||||
3300000: //RootNode
|
||||
4300000: OltarMesh
|
||||
materials:
|
||||
importMaterials: 1
|
||||
materialName: 0
|
||||
materialSearch: 1
|
||||
animations:
|
||||
legacyGenerateAnimations: 4
|
||||
bakeSimulation: 0
|
||||
resampleRotations: 1
|
||||
optimizeGameObjects: 0
|
||||
motionNodeName:
|
||||
animationImportErrors:
|
||||
animationImportWarnings:
|
||||
animationRetargetingWarnings:
|
||||
animationDoRetargetingWarnings: 0
|
||||
animationCompression: 1
|
||||
animationRotationError: 0.5
|
||||
animationPositionError: 0.5
|
||||
animationScaleError: 0.5
|
||||
animationWrapMode: 0
|
||||
extraExposedTransformPaths: []
|
||||
clipAnimations: []
|
||||
isReadable: 1
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
globalScale: 25
|
||||
meshCompression: 0
|
||||
addColliders: 0
|
||||
importBlendShapes: 1
|
||||
swapUVChannels: 0
|
||||
generateSecondaryUV: 0
|
||||
useFileUnits: 1
|
||||
optimizeMeshForGPU: 1
|
||||
keepQuads: 0
|
||||
weldVertices: 1
|
||||
secondaryUVAngleDistortion: 8
|
||||
secondaryUVAreaDistortion: 15.000001
|
||||
secondaryUVHardAngle: 88
|
||||
secondaryUVPackMargin: 4
|
||||
useFileScale: 1
|
||||
tangentSpace:
|
||||
normalSmoothAngle: 60
|
||||
normalImportMode: 0
|
||||
tangentImportMode: 3
|
||||
importAnimation: 0
|
||||
copyAvatar: 0
|
||||
humanDescription:
|
||||
human: []
|
||||
skeleton: []
|
||||
armTwist: 0.5
|
||||
foreArmTwist: 0.5
|
||||
upperLegTwist: 0.5
|
||||
legTwist: 0.5
|
||||
armStretch: 0.05
|
||||
legStretch: 0.05
|
||||
feetSpacing: 0
|
||||
rootMotionBoneName:
|
||||
hasTranslationDoF: 0
|
||||
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||
animationType: 0
|
||||
humanoidOversampling: 1
|
||||
additionalBone: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Models/Textures.meta
Normal file
9
Assets/Models/Textures.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd4326a54be5ab245af6008221a5aed7
|
||||
folderAsset: yes
|
||||
timeCreated: 1474041413
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Scripts.meta
Normal file
9
Assets/Scripts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd395249592eeea429cb71ee8a9d37b8
|
||||
folderAsset: yes
|
||||
timeCreated: 1471956398
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
14
Assets/Scripts/Ball.cs
Normal file
14
Assets/Scripts/Ball.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
public class Ball : MonoBehaviour {
|
||||
public float radius;
|
||||
public bool negativeBall;
|
||||
|
||||
[HideInInspector]
|
||||
public float radiusSq;
|
||||
|
||||
public virtual void Start() {
|
||||
this.radiusSq = (this.negativeBall ? -1 : 1) * this.radius * this.radius;
|
||||
}
|
||||
}
|
||||
12
Assets/Scripts/Ball.cs.meta
Normal file
12
Assets/Scripts/Ball.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52cdb97a770131b4fbea6f0f0c9454b9
|
||||
timeCreated: 1471956415
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
51
Assets/Scripts/BouncingBall.cs
Normal file
51
Assets/Scripts/BouncingBall.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
public class BouncingBall : Ball {
|
||||
public float speed;
|
||||
|
||||
private Container container;
|
||||
private Vector3 direction;
|
||||
|
||||
public override void Start() {
|
||||
base.Start();
|
||||
this.direction = Random.onUnitSphere;
|
||||
this.container = this.GetComponentInParent<Container>();
|
||||
}
|
||||
|
||||
public void Update() {
|
||||
this.updatePosition(Time.deltaTime);
|
||||
}
|
||||
|
||||
public void updatePosition(float dt) {
|
||||
float posX = this.transform.position.x, posY = this.transform.position.y, posZ = this.transform.position.z;
|
||||
Vector3 containerPosition = this.container.transform.position;
|
||||
Vector3 containerScale = this.container.transform.localScale;
|
||||
|
||||
if(posX + this.radius + this.container.safeZone > containerPosition.x + containerScale.x / 2) {
|
||||
posX -= 0.01f;
|
||||
this.direction = Vector3.Reflect(this.direction, Vector3.left);
|
||||
} else if(posX - this.radius - this.container.safeZone < containerPosition.x - containerScale.x / 2) {
|
||||
posX += 0.01f;
|
||||
this.direction = Vector3.Reflect(this.direction, Vector3.right);
|
||||
}
|
||||
|
||||
if(posY + this.radius + this.container.safeZone > containerPosition.y + containerScale.y / 2) {
|
||||
posY -= 0.01f;
|
||||
this.direction = Vector3.Reflect(this.direction, Vector3.down);
|
||||
} else if(posY - this.radius - this.container.safeZone < containerPosition.y - containerScale.y / 2) {
|
||||
posY += 0.01f;
|
||||
this.direction = Vector3.Reflect(this.direction, Vector3.up);
|
||||
}
|
||||
|
||||
if(posZ + this.radius + this.container.safeZone > containerPosition.z + containerScale.z / 2) {
|
||||
posZ -= 0.01f;
|
||||
this.direction = Vector3.Reflect(this.direction, Vector3.back);
|
||||
} else if(posZ - this.radius - this.container.safeZone < containerPosition.z - containerScale.z / 2) {
|
||||
posZ += 0.01f;
|
||||
this.direction = Vector3.Reflect(this.direction, Vector3.forward);
|
||||
}
|
||||
|
||||
this.transform.position = new Vector3(posX, posY, posZ) + this.direction * speed * dt;
|
||||
}
|
||||
}
|
||||
12
Assets/Scripts/BouncingBall.cs.meta
Normal file
12
Assets/Scripts/BouncingBall.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d48da6326ea96f42bdc7e5971aca19a
|
||||
timeCreated: 1472227985
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
27
Assets/Scripts/Container.cs
Normal file
27
Assets/Scripts/Container.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class Container : MonoBehaviour {
|
||||
public float safeZone;
|
||||
public float resolution;
|
||||
public float threshold;
|
||||
public ComputeShader computeShader;
|
||||
|
||||
private CubeGrid grid;
|
||||
|
||||
public void Start() {
|
||||
Ball[] metaballs = this.GetComponentsInChildren<Ball>();
|
||||
|
||||
this.grid = new CubeGrid(this, this.resolution, this.threshold, this.computeShader, metaballs);
|
||||
}
|
||||
|
||||
public void Update() {
|
||||
this.grid.evaluateAll();
|
||||
|
||||
Mesh mesh = this.GetComponent<MeshFilter>().mesh;
|
||||
mesh.Clear();
|
||||
mesh.vertices = this.grid.vertices.ToArray();
|
||||
mesh.triangles = this.grid.getTriangles();
|
||||
}
|
||||
}
|
||||
12
Assets/Scripts/Container.cs.meta
Normal file
12
Assets/Scripts/Container.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19661b331d4afbb4b88ebebaed28c66b
|
||||
timeCreated: 1471957241
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
644
Assets/Scripts/CubeGrid.cs
Normal file
644
Assets/Scripts/CubeGrid.cs
Normal file
@@ -0,0 +1,644 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
struct GPUEdgeValues {
|
||||
public float edge0Val, edge1Val, edge2Val, edge3Val, edge4Val, edge5Val, edge6Val, edge7Val;
|
||||
}
|
||||
|
||||
struct GPUPositions {
|
||||
public Vector3 edge0Pos, edge1Pos, edge2Pos, edge3Pos, edge4Pos, edge5Pos, edge6Pos, edge7Pos;
|
||||
}
|
||||
|
||||
struct GPUBall {
|
||||
public float radiusSq;
|
||||
public Vector3 position;
|
||||
}
|
||||
|
||||
public class CubeGrid {
|
||||
public List<Vector3> vertices;
|
||||
public int width, height, depth;
|
||||
public float resolution;
|
||||
|
||||
private Container container;
|
||||
private Ball[] metaballs;
|
||||
private float threshold;
|
||||
|
||||
private ComputeShader shader;
|
||||
private int shaderKernel;
|
||||
private GPUPositions[] precomputedPositions;
|
||||
private ComputeBuffer positionsBuffer;
|
||||
private ComputeBuffer outputBuffer;
|
||||
private ComputeBuffer metaballsBuffer;
|
||||
|
||||
public const bool useGPU = true;
|
||||
|
||||
public CubeGrid(Container container, float resolution, float threshold, ComputeShader shader, Ball[] metaballs) {
|
||||
this.width = Mathf.RoundToInt(container.transform.localScale.x / resolution);
|
||||
this.height = Mathf.RoundToInt(container.transform.localScale.y / resolution);
|
||||
this.depth = Mathf.RoundToInt(container.transform.localScale.z / resolution);
|
||||
|
||||
this.vertices = new List<Vector3>();
|
||||
|
||||
this.container = container;
|
||||
this.resolution = resolution;
|
||||
this.threshold = threshold;
|
||||
this.shader = shader;
|
||||
this.metaballs = metaballs;
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
public void evaluateAll() {
|
||||
this.vertices.Clear();
|
||||
|
||||
if(CubeGrid.useGPU) {
|
||||
GPUBall[] gpuBalls = new GPUBall[this.metaballs.Length];
|
||||
|
||||
for(int i = 0; i < this.metaballs.Length; i++) {
|
||||
Ball metaball = this.metaballs[i];
|
||||
gpuBalls[i].position = metaball.transform.localPosition;
|
||||
gpuBalls[i].radiusSq = metaball.radiusSq;
|
||||
}
|
||||
|
||||
GPUEdgeValues[] edgeValues = this.runComputeShader(gpuBalls);
|
||||
|
||||
for(int x = 0; x < this.width; x++) {
|
||||
for(int y = 0; y < this.height; y++) {
|
||||
for(int z = 0; z < this.depth; z++) {
|
||||
GPUEdgeValues edgeVal = edgeValues[x + this.width * (y + this.height * z)];
|
||||
float[] edges = { edgeVal.edge0Val, edgeVal.edge1Val, edgeVal.edge2Val, edgeVal.edge3Val,
|
||||
edgeVal.edge4Val, edgeVal.edge5Val, edgeVal.edge6Val, edgeVal.edge7Val};
|
||||
|
||||
this.updateVertices(edges, this.positionMap[x, y, z]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(int x = 0; x < this.width; x++) {
|
||||
for(int y = 0; y < this.height; y++) {
|
||||
for(int z = 0; z < this.depth; z++) {
|
||||
Vector3 relativePosition = this.positionMap[x, y, z];
|
||||
float[] edges = this.evaluateCube(relativePosition);
|
||||
this.updateVertices(edges, relativePosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getTriangles() {
|
||||
int num = this.vertices.Count;
|
||||
|
||||
if(this.triangleBuffer == null) {
|
||||
// nothing in buffer, create it
|
||||
this.triangleBuffer = new List<int>();
|
||||
for(int i = 0; i < num; i++) {
|
||||
this.triangleBuffer.Add(i);
|
||||
}
|
||||
|
||||
return this.triangleBuffer.ToArray();
|
||||
} else if(this.triangleBuffer.Count < num) {
|
||||
// missing elements in buffer, add them
|
||||
for(int i = this.triangleBuffer.Count; i < num; i++) {
|
||||
this.triangleBuffer.Add(i);
|
||||
}
|
||||
|
||||
return this.triangleBuffer.ToArray();
|
||||
} else if(this.triangleBuffer.Count == num) {
|
||||
// buffer is of perfect size, just return it
|
||||
|
||||
return this.triangleBuffer.ToArray();
|
||||
} else {
|
||||
// buffer is too long, return slice
|
||||
|
||||
return this.triangleBuffer.GetRange(0, num).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
this.positionsBuffer.Release();
|
||||
this.outputBuffer.Release();
|
||||
this.metaballsBuffer.Release();
|
||||
this.triangleBuffer = null;
|
||||
}
|
||||
|
||||
//
|
||||
// Setup
|
||||
//
|
||||
|
||||
private void init() {
|
||||
this.instantiateEdgeMap();
|
||||
this.instantiatePositionMap();
|
||||
|
||||
if(CubeGrid.useGPU) {
|
||||
this.instantiateGPUPositions();
|
||||
this.instantiateComputeShader();
|
||||
}
|
||||
}
|
||||
|
||||
private void instantiateEdgeMap() {
|
||||
this.edgeMap = new Vector3[] {
|
||||
new Vector3(-1, -1, -1),
|
||||
new Vector3(1, -1, -1),
|
||||
new Vector3(1, 1, -1),
|
||||
new Vector3(-1, 1, -1),
|
||||
new Vector3(-1, -1, 1),
|
||||
new Vector3(1, -1, 1),
|
||||
new Vector3(1, 1, 1),
|
||||
new Vector3(-1, 1, 1)
|
||||
};
|
||||
|
||||
for(int i = 0; i < 8; i++) {
|
||||
this.edgeMap[i] /= 2;
|
||||
this.edgeMap[i] = new Vector3(this.edgeMap[i].x / ((float) this.width),
|
||||
this.edgeMap[i].y / ((float) this.height),
|
||||
this.edgeMap[i].z / ((float) this.depth));
|
||||
}
|
||||
}
|
||||
|
||||
private void instantiatePositionMap() {
|
||||
this.positionMap = new Vector3[this.width, this.height, this.depth];
|
||||
|
||||
for(int x = 0; x < this.width; x++) {
|
||||
for(int y = 0; y < this.height; y++) {
|
||||
for(int z = 0; z < this.depth; z++) {
|
||||
|
||||
float xCoord = (((float) x) / ((float) this.width)) - 0.5f;
|
||||
float yCoord = (((float) y) / ((float) this.height)) - 0.5f;
|
||||
float zCoord = (((float) z) / ((float) this.depth)) - 0.5f;
|
||||
|
||||
this.positionMap[x, y, z] = new Vector3(xCoord, yCoord, zCoord);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void instantiateGPUPositions() {
|
||||
this.precomputedPositions = new GPUPositions[this.width*this.height*this.depth];
|
||||
|
||||
for(int x = 0; x < this.width; x++) {
|
||||
for(int y = 0; y < this.height; y++) {
|
||||
for(int z = 0; z < this.depth; z++) {
|
||||
Vector3 centerPoint = this.positionMap[x, y, z];
|
||||
|
||||
this.precomputedPositions[x + this.width * (y + this.height * z)].edge0Pos = centerPoint + this.edgeMap[0];
|
||||
this.precomputedPositions[x + this.width * (y + this.height * z)].edge1Pos = centerPoint + this.edgeMap[1];
|
||||
this.precomputedPositions[x + this.width * (y + this.height * z)].edge2Pos = centerPoint + this.edgeMap[2];
|
||||
this.precomputedPositions[x + this.width * (y + this.height * z)].edge3Pos = centerPoint + this.edgeMap[3];
|
||||
this.precomputedPositions[x + this.width * (y + this.height * z)].edge4Pos = centerPoint + this.edgeMap[4];
|
||||
this.precomputedPositions[x + this.width * (y + this.height * z)].edge5Pos = centerPoint + this.edgeMap[5];
|
||||
this.precomputedPositions[x + this.width * (y + this.height * z)].edge6Pos = centerPoint + this.edgeMap[6];
|
||||
this.precomputedPositions[x + this.width * (y + this.height * z)].edge7Pos = centerPoint + this.edgeMap[7];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void instantiateComputeShader() {
|
||||
this.positionsBuffer = new ComputeBuffer(this.precomputedPositions.Length, 96);
|
||||
this.positionsBuffer.SetData(this.precomputedPositions);
|
||||
|
||||
this.outputBuffer = new ComputeBuffer(this.precomputedPositions.Length, 32);
|
||||
|
||||
this.metaballsBuffer = new ComputeBuffer(this.precomputedPositions.Length, 16);
|
||||
|
||||
this.shaderKernel = shader.FindKernel("Calculate");
|
||||
this.shader.SetBuffer(this.shaderKernel, "positions", this.positionsBuffer);
|
||||
this.shader.SetBuffer(this.shaderKernel, "outputBuffer", this.outputBuffer);
|
||||
|
||||
this.shader.SetInt("width", this.width);
|
||||
this.shader.SetInt("height", this.height);
|
||||
}
|
||||
|
||||
//
|
||||
// GPU metaball falloff function summator
|
||||
//
|
||||
|
||||
private GPUEdgeValues[] runComputeShader(GPUBall[] gpuBalls) {
|
||||
this.metaballsBuffer.SetData(gpuBalls);
|
||||
this.shader.SetBuffer(this.shaderKernel, "metaballs", this.metaballsBuffer);
|
||||
|
||||
this.shader.SetInt("numMetaballs", this.metaballs.Length);
|
||||
|
||||
this.shader.Dispatch(this.shaderKernel, this.width / 8, this.height / 8, this.depth / 8);
|
||||
|
||||
GPUEdgeValues[] output = new GPUEdgeValues[this.precomputedPositions.Length];
|
||||
this.outputBuffer.GetData(output);
|
||||
return output;
|
||||
}
|
||||
|
||||
//
|
||||
// CPU metaball falloff function summator
|
||||
//
|
||||
|
||||
private float[] evaluateCube(Vector3 centerPoint) {
|
||||
float[] edges = new float[8];
|
||||
|
||||
for(int i = 0; i < 8; i++) {
|
||||
edges[i] = this.evaluatePoint(centerPoint + this.edgeMap[i]);
|
||||
}
|
||||
|
||||
return edges;
|
||||
}
|
||||
|
||||
private float evaluatePoint(Vector3 point) {
|
||||
float value = 0;
|
||||
|
||||
foreach(Ball ball in this.metaballs) {
|
||||
Vector3 ballPosition = ball.transform.localPosition;
|
||||
float distX = point.x - ballPosition.x,
|
||||
distY = point.y - ballPosition.y,
|
||||
distZ = point.z - ballPosition.z;
|
||||
value += ball.radiusSq / (distX * distX + distY * distY + distZ * distZ);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
//
|
||||
// Marching cubes algorithm
|
||||
//
|
||||
|
||||
private void updateVertices(float[] edges, Vector3 relativePosition) {
|
||||
int cubeIndex = this.findIndex(edges);
|
||||
int pattern = this.edgeTable[cubeIndex];
|
||||
|
||||
Vector3[] edgeVertices = new Vector3[12];
|
||||
|
||||
for(int edge = 0; edge < 12; edge++) {
|
||||
if((pattern & 1 << edge) != 0) {
|
||||
int vertIndex0 = this.verticesAtEndsOfEdges[edge * 2];
|
||||
int vertIndex1 = this.verticesAtEndsOfEdges[edge * 2 + 1];
|
||||
|
||||
float vertValue0 = edges[vertIndex0];
|
||||
float vertValue1 = edges[vertIndex1];
|
||||
|
||||
Vector3 vertPosition0 = relativePosition + this.edgeMap[vertIndex0];
|
||||
Vector3 vertPosition1 = relativePosition + this.edgeMap[vertIndex1];
|
||||
|
||||
float delta = (threshold - vertValue0) / (vertValue1 - vertValue0);
|
||||
|
||||
// lineary interpolate positions
|
||||
edgeVertices[edge] = vertPosition0 + delta * (vertPosition1 - vertPosition0);
|
||||
}
|
||||
}
|
||||
|
||||
for(int k = 0; triTable[cubeIndex][k] != -1; k += 3) {
|
||||
this.vertices.Add(edgeVertices[this.triTable[cubeIndex][k]]);
|
||||
this.vertices.Add(edgeVertices[this.triTable[cubeIndex][k + 2]]);
|
||||
this.vertices.Add(edgeVertices[this.triTable[cubeIndex][k + 1]]);
|
||||
}
|
||||
}
|
||||
|
||||
private int findIndex(float[] edges) {
|
||||
byte cubeIndex = 0;
|
||||
|
||||
if(edges[0] > this.threshold) {
|
||||
cubeIndex |= 1;
|
||||
}
|
||||
if(edges[1] > this.threshold) {
|
||||
cubeIndex |= 2;
|
||||
}
|
||||
if(edges[2] > this.threshold) {
|
||||
cubeIndex |= 4;
|
||||
}
|
||||
if(edges[3] > this.threshold) {
|
||||
cubeIndex |= 8;
|
||||
}
|
||||
if(edges[4] > this.threshold) {
|
||||
cubeIndex |= 16;
|
||||
}
|
||||
if(edges[5] > this.threshold) {
|
||||
cubeIndex |= 32;
|
||||
}
|
||||
if(edges[6] > this.threshold) {
|
||||
cubeIndex |= 64;
|
||||
}
|
||||
if(edges[7] > this.threshold) {
|
||||
cubeIndex |= 128;
|
||||
}
|
||||
|
||||
// return index
|
||||
return cubeIndex;
|
||||
}
|
||||
|
||||
//
|
||||
// LOOKUP TABLES
|
||||
//
|
||||
|
||||
private List<int> triangleBuffer;
|
||||
|
||||
private Vector3[,,] positionMap;
|
||||
|
||||
private Vector3[] edgeMap;
|
||||
|
||||
private int[] edgeTable = {
|
||||
0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
|
||||
0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
|
||||
0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
|
||||
0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
|
||||
0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
|
||||
0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
|
||||
0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
|
||||
0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
|
||||
0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
|
||||
0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
|
||||
0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
|
||||
0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
|
||||
0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
|
||||
0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
|
||||
0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
|
||||
0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
|
||||
0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
|
||||
0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
|
||||
0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
|
||||
0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
|
||||
0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
|
||||
0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
|
||||
0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
|
||||
0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
|
||||
0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
|
||||
0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
|
||||
0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
|
||||
0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
|
||||
0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
|
||||
0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
|
||||
0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
|
||||
0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0
|
||||
};
|
||||
|
||||
private int[] verticesAtEndsOfEdges = {
|
||||
0, 1,
|
||||
1, 2,
|
||||
2, 3,
|
||||
3, 0,
|
||||
4, 5,
|
||||
5, 6,
|
||||
6, 7,
|
||||
7, 4,
|
||||
0, 4,
|
||||
1, 5,
|
||||
2, 6,
|
||||
3, 7
|
||||
};
|
||||
|
||||
private int[][] triTable = {
|
||||
new int[] {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
|
||||
new int[] {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
|
||||
new int[] {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
|
||||
new int[] {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
|
||||
new int[] {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
|
||||
new int[] {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
|
||||
new int[] {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
|
||||
new int[] {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
|
||||
new int[] {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
|
||||
new int[] {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
|
||||
new int[] {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
|
||||
new int[] {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
|
||||
new int[] {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
|
||||
new int[] {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
|
||||
new int[] {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
|
||||
new int[] {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
|
||||
new int[] {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
|
||||
new int[] {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
|
||||
new int[] {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
|
||||
new int[] {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
|
||||
new int[] {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
|
||||
new int[] {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
|
||||
new int[] {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
|
||||
new int[] {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
|
||||
new int[] {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
|
||||
new int[] {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
|
||||
new int[] {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
|
||||
new int[] {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
|
||||
new int[] {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
|
||||
new int[] {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
|
||||
new int[] {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
|
||||
new int[] {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
|
||||
new int[] {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
|
||||
new int[] {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
|
||||
new int[] {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
|
||||
new int[] {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
|
||||
new int[] {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
|
||||
new int[] {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
|
||||
new int[] {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
|
||||
new int[] {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
|
||||
new int[] {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
|
||||
new int[] {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
|
||||
new int[] {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
|
||||
new int[] {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
|
||||
new int[] {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
|
||||
new int[] {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
|
||||
new int[] {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
|
||||
new int[] {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
|
||||
new int[] {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
|
||||
new int[] {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
|
||||
new int[] {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
|
||||
new int[] {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
|
||||
new int[] {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
|
||||
new int[] {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
|
||||
new int[] {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
|
||||
new int[] {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
|
||||
new int[] {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
|
||||
new int[] {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
|
||||
new int[] {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
|
||||
new int[] {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
|
||||
new int[] {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
|
||||
new int[] {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
|
||||
new int[] {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
|
||||
new int[] {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
|
||||
new int[] {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
|
||||
new int[] {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
|
||||
new int[] {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
|
||||
new int[] {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
|
||||
new int[] {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
|
||||
new int[] {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
|
||||
new int[] {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
|
||||
new int[] {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
|
||||
new int[] {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
|
||||
new int[] {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
|
||||
new int[] {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
|
||||
new int[] {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
|
||||
new int[] {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
|
||||
new int[] {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
|
||||
new int[] {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
|
||||
new int[] {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
|
||||
new int[] {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
|
||||
new int[] {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
|
||||
new int[] {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
|
||||
new int[] {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
|
||||
new int[] {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
|
||||
new int[] {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
|
||||
new int[] {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
|
||||
new int[] {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
|
||||
new int[] {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
|
||||
new int[] {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
|
||||
new int[] {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
|
||||
new int[] {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
|
||||
new int[] {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
|
||||
new int[] {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
|
||||
new int[] {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
|
||||
new int[] {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
|
||||
new int[] {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
|
||||
new int[] {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
|
||||
new int[] {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
|
||||
new int[] {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
|
||||
new int[] {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
|
||||
new int[] {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
|
||||
new int[] {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
|
||||
new int[] {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
|
||||
new int[] {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
|
||||
new int[] {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
|
||||
new int[] {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
|
||||
new int[] {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
|
||||
new int[] {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
new int[] {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
|
||||
};
|
||||
}
|
||||
12
Assets/Scripts/CubeGrid.cs.meta
Normal file
12
Assets/Scripts/CubeGrid.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32a94152fc858be4591f8bc75537cd4a
|
||||
timeCreated: 1471961094
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
32
Assets/Scripts/Draggable.cs
Normal file
32
Assets/Scripts/Draggable.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
public class Draggable : MonoBehaviour {
|
||||
private Rigidbody rigid;
|
||||
private float zDist;
|
||||
|
||||
void Start () {
|
||||
this.rigid = this.GetComponent<Rigidbody>();
|
||||
}
|
||||
|
||||
void Update () {
|
||||
|
||||
}
|
||||
|
||||
void OnMouseDown() {
|
||||
this.rigid.useGravity = false;
|
||||
this.zDist = Vector3.Distance(Camera.main.transform.position, this.transform.position);
|
||||
}
|
||||
|
||||
void OnMouseDrag() {
|
||||
Vector3 mousePos = Input.mousePosition;
|
||||
mousePos.z = zDist;
|
||||
this.transform.position = Camera.main.ScreenToWorldPoint(mousePos);
|
||||
}
|
||||
|
||||
void OnMouseUp() {
|
||||
this.rigid.useGravity = true;
|
||||
this.rigid.velocity = Vector3.zero;
|
||||
this.rigid.angularVelocity = Vector3.zero;
|
||||
}
|
||||
}
|
||||
12
Assets/Scripts/Draggable.cs.meta
Normal file
12
Assets/Scripts/Draggable.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a2531f70d23d81468bd48d3d7bee962
|
||||
timeCreated: 1472299829
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
20
Assets/Scripts/MetaLight.cs
Normal file
20
Assets/Scripts/MetaLight.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
[RequireComponent(typeof(Light))]
|
||||
public class MetaLight : MonoBehaviour {
|
||||
public Ball linkedMetaball;
|
||||
public float intensity;
|
||||
|
||||
private float phaseShift;
|
||||
private Light lightComponent;
|
||||
|
||||
void Start () {
|
||||
this.phaseShift = Random.Range(0, Mathf.PI);
|
||||
this.lightComponent = this.GetComponent<Light>();
|
||||
}
|
||||
|
||||
void Update () {
|
||||
this.lightComponent.intensity = this.intensity * (this.linkedMetaball.transform.localPosition.magnitude + (1 + Mathf.Sin(this.phaseShift + Time.time/2)));
|
||||
}
|
||||
}
|
||||
12
Assets/Scripts/MetaLight.cs.meta
Normal file
12
Assets/Scripts/MetaLight.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b69bb43ffc00494d9de7a13db699013
|
||||
timeCreated: 1472296882
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Shaders.meta
Normal file
9
Assets/Shaders.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5e9650e36eaf5ed409fc088bfa3794bb
|
||||
folderAsset: yes
|
||||
timeCreated: 1471974557
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
64
Assets/Shaders/FalloffFunctionComputeShader.compute
Normal file
64
Assets/Shaders/FalloffFunctionComputeShader.compute
Normal file
@@ -0,0 +1,64 @@
|
||||
#pragma kernel Calculate
|
||||
|
||||
struct Values {
|
||||
float edge0Val, edge1Val, edge2Val, edge3Val, edge4Val, edge5Val, edge6Val, edge7Val;
|
||||
};
|
||||
|
||||
struct Positions {
|
||||
float3 edge0Pos, edge1Pos, edge2Pos, edge3Pos, edge4Pos, edge5Pos, edge6Pos, edge7Pos;
|
||||
};
|
||||
|
||||
struct Ball {
|
||||
float radiusSq;
|
||||
float3 position;
|
||||
};
|
||||
|
||||
StructuredBuffer<Positions> positions;
|
||||
StructuredBuffer<Ball> metaballs;
|
||||
RWStructuredBuffer<Values> outputBuffer;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
int numMetaballs;
|
||||
|
||||
[numthreads(8,8,8)]
|
||||
void Calculate(uint3 id : SV_DispatchThreadID)
|
||||
{
|
||||
int pos = id.x + width * (id.y + height * id.z);
|
||||
|
||||
outputBuffer[pos].edge0Val = 0;
|
||||
outputBuffer[pos].edge1Val = 0;
|
||||
outputBuffer[pos].edge2Val = 0;
|
||||
outputBuffer[pos].edge3Val = 0;
|
||||
outputBuffer[pos].edge4Val = 0;
|
||||
outputBuffer[pos].edge5Val = 0;
|
||||
outputBuffer[pos].edge6Val = 0;
|
||||
outputBuffer[pos].edge7Val = 0;
|
||||
|
||||
for (int i = 0; i < numMetaballs; i++) {
|
||||
float3 dist = positions[pos].edge0Pos - metaballs[i].position;
|
||||
outputBuffer[pos].edge0Val += metaballs[i].radiusSq / (dist.x * dist.x + dist.y * dist.y + dist.z * dist.z);
|
||||
|
||||
dist = positions[pos].edge1Pos - metaballs[i].position;
|
||||
outputBuffer[pos].edge1Val += metaballs[i].radiusSq / (dist.x * dist.x + dist.y * dist.y + dist.z * dist.z);
|
||||
|
||||
dist = positions[pos].edge2Pos - metaballs[i].position;
|
||||
outputBuffer[pos].edge2Val += metaballs[i].radiusSq / (dist.x * dist.x + dist.y * dist.y + dist.z * dist.z);
|
||||
|
||||
dist = positions[pos].edge3Pos - metaballs[i].position;
|
||||
outputBuffer[pos].edge3Val += metaballs[i].radiusSq / (dist.x * dist.x + dist.y * dist.y + dist.z * dist.z);
|
||||
|
||||
dist = positions[pos].edge4Pos - metaballs[i].position;
|
||||
outputBuffer[pos].edge4Val += metaballs[i].radiusSq / (dist.x * dist.x + dist.y * dist.y + dist.z * dist.z);
|
||||
|
||||
dist = positions[pos].edge5Pos - metaballs[i].position;
|
||||
outputBuffer[pos].edge5Val += metaballs[i].radiusSq / (dist.x * dist.x + dist.y * dist.y + dist.z * dist.z);
|
||||
|
||||
dist = positions[pos].edge6Pos - metaballs[i].position;
|
||||
outputBuffer[pos].edge6Val += metaballs[i].radiusSq / (dist.x * dist.x + dist.y * dist.y + dist.z * dist.z);
|
||||
|
||||
dist = positions[pos].edge7Pos - metaballs[i].position;
|
||||
outputBuffer[pos].edge7Val += metaballs[i].radiusSq / (dist.x * dist.x + dist.y * dist.y + dist.z * dist.z);
|
||||
}
|
||||
}
|
||||
9
Assets/Shaders/FalloffFunctionComputeShader.compute.meta
Normal file
9
Assets/Shaders/FalloffFunctionComputeShader.compute.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd5d7027d3c30804a9dd9ea57ed5f351
|
||||
timeCreated: 1474039237
|
||||
licenseType: Free
|
||||
ComputeShaderImporter:
|
||||
currentAPIMask: 4
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
29
Assets/Shaders/MetaballShader.shader
Normal file
29
Assets/Shaders/MetaballShader.shader
Normal file
@@ -0,0 +1,29 @@
|
||||
Shader "Custom/MetaballShader" {
|
||||
Properties {
|
||||
_Color("Color", Color) = (1,1,1,1)
|
||||
}
|
||||
|
||||
SubShader {
|
||||
Tags{ "RenderType" = "Opaque" }
|
||||
|
||||
Cull Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma surface surf Lambert
|
||||
|
||||
float4 _Color;
|
||||
|
||||
struct Input {
|
||||
float4 uv_MainTex;
|
||||
};
|
||||
|
||||
void surf(Input IN, inout SurfaceOutput o) {
|
||||
o.Emission = _Color.rgb;
|
||||
}
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
FallBack "Diffuse"
|
||||
}
|
||||
9
Assets/Shaders/MetaballShader.shader.meta
Normal file
9
Assets/Shaders/MetaballShader.shader.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a51496bc11f7b54ab026c8a4cbef208
|
||||
timeCreated: 1471974569
|
||||
licenseType: Free
|
||||
ShaderImporter:
|
||||
defaultTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Standard Assets.meta
Normal file
9
Assets/Standard Assets.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 68709f178f71592488678b46cf3b6479
|
||||
folderAsset: yes
|
||||
timeCreated: 1472296452
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
6
Assets/Standard Assets/Effects.meta
Normal file
6
Assets/Standard Assets/Effects.meta
Normal file
@@ -0,0 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 115d1f9d9bd29064ab981e57c8fc8cdf
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
6
Assets/Standard Assets/Effects/ImageEffects.meta
Normal file
6
Assets/Standard Assets/Effects/ImageEffects.meta
Normal file
@@ -0,0 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d6e0c95a128e14227939c51b5d9ad74e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
6
Assets/Standard Assets/Effects/ImageEffects/Scripts.meta
Normal file
6
Assets/Standard Assets/Effects/ImageEffects/Scripts.meta
Normal file
@@ -0,0 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd3e1490c3d9a7a498538315414d5129
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,177 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
public enum AAMode
|
||||
{
|
||||
FXAA2 = 0,
|
||||
FXAA3Console = 1,
|
||||
FXAA1PresetA = 2,
|
||||
FXAA1PresetB = 3,
|
||||
NFAA = 4,
|
||||
SSAA = 5,
|
||||
DLAA = 6,
|
||||
}
|
||||
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof (Camera))]
|
||||
[AddComponentMenu("Image Effects/Other/Antialiasing")]
|
||||
public class Antialiasing : PostEffectsBase
|
||||
{
|
||||
public AAMode mode = AAMode.FXAA3Console;
|
||||
|
||||
public bool showGeneratedNormals = false;
|
||||
public float offsetScale = 0.2f;
|
||||
public float blurRadius = 18.0f;
|
||||
|
||||
public float edgeThresholdMin = 0.05f;
|
||||
public float edgeThreshold = 0.2f;
|
||||
public float edgeSharpness = 4.0f;
|
||||
|
||||
public bool dlaaSharp = false;
|
||||
|
||||
public Shader ssaaShader;
|
||||
private Material ssaa;
|
||||
public Shader dlaaShader;
|
||||
private Material dlaa;
|
||||
public Shader nfaaShader;
|
||||
private Material nfaa;
|
||||
public Shader shaderFXAAPreset2;
|
||||
private Material materialFXAAPreset2;
|
||||
public Shader shaderFXAAPreset3;
|
||||
private Material materialFXAAPreset3;
|
||||
public Shader shaderFXAAII;
|
||||
private Material materialFXAAII;
|
||||
public Shader shaderFXAAIII;
|
||||
private Material materialFXAAIII;
|
||||
|
||||
|
||||
public Material CurrentAAMaterial()
|
||||
{
|
||||
Material returnValue = null;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case AAMode.FXAA3Console:
|
||||
returnValue = materialFXAAIII;
|
||||
break;
|
||||
case AAMode.FXAA2:
|
||||
returnValue = materialFXAAII;
|
||||
break;
|
||||
case AAMode.FXAA1PresetA:
|
||||
returnValue = materialFXAAPreset2;
|
||||
break;
|
||||
case AAMode.FXAA1PresetB:
|
||||
returnValue = materialFXAAPreset3;
|
||||
break;
|
||||
case AAMode.NFAA:
|
||||
returnValue = nfaa;
|
||||
break;
|
||||
case AAMode.SSAA:
|
||||
returnValue = ssaa;
|
||||
break;
|
||||
case AAMode.DLAA:
|
||||
returnValue = dlaa;
|
||||
break;
|
||||
default:
|
||||
returnValue = null;
|
||||
break;
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
public override bool CheckResources()
|
||||
{
|
||||
CheckSupport(false);
|
||||
|
||||
materialFXAAPreset2 = CreateMaterial(shaderFXAAPreset2, materialFXAAPreset2);
|
||||
materialFXAAPreset3 = CreateMaterial(shaderFXAAPreset3, materialFXAAPreset3);
|
||||
materialFXAAII = CreateMaterial(shaderFXAAII, materialFXAAII);
|
||||
materialFXAAIII = CreateMaterial(shaderFXAAIII, materialFXAAIII);
|
||||
nfaa = CreateMaterial(nfaaShader, nfaa);
|
||||
ssaa = CreateMaterial(ssaaShader, ssaa);
|
||||
dlaa = CreateMaterial(dlaaShader, dlaa);
|
||||
|
||||
if (!ssaaShader.isSupported)
|
||||
{
|
||||
NotSupported();
|
||||
ReportAutoDisable();
|
||||
}
|
||||
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
|
||||
public void OnRenderImage(RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources() == false)
|
||||
{
|
||||
Graphics.Blit(source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// FXAA antialiasing modes
|
||||
|
||||
if (mode == AAMode.FXAA3Console && (materialFXAAIII != null))
|
||||
{
|
||||
materialFXAAIII.SetFloat("_EdgeThresholdMin", edgeThresholdMin);
|
||||
materialFXAAIII.SetFloat("_EdgeThreshold", edgeThreshold);
|
||||
materialFXAAIII.SetFloat("_EdgeSharpness", edgeSharpness);
|
||||
|
||||
Graphics.Blit(source, destination, materialFXAAIII);
|
||||
}
|
||||
else if (mode == AAMode.FXAA1PresetB && (materialFXAAPreset3 != null))
|
||||
{
|
||||
Graphics.Blit(source, destination, materialFXAAPreset3);
|
||||
}
|
||||
else if (mode == AAMode.FXAA1PresetA && materialFXAAPreset2 != null)
|
||||
{
|
||||
source.anisoLevel = 4;
|
||||
Graphics.Blit(source, destination, materialFXAAPreset2);
|
||||
source.anisoLevel = 0;
|
||||
}
|
||||
else if (mode == AAMode.FXAA2 && materialFXAAII != null)
|
||||
{
|
||||
Graphics.Blit(source, destination, materialFXAAII);
|
||||
}
|
||||
else if (mode == AAMode.SSAA && ssaa != null)
|
||||
{
|
||||
// ----------------------------------------------------------------
|
||||
// SSAA antialiasing
|
||||
Graphics.Blit(source, destination, ssaa);
|
||||
}
|
||||
else if (mode == AAMode.DLAA && dlaa != null)
|
||||
{
|
||||
// ----------------------------------------------------------------
|
||||
// DLAA antialiasing
|
||||
|
||||
source.anisoLevel = 0;
|
||||
RenderTexture interim = RenderTexture.GetTemporary(source.width, source.height);
|
||||
Graphics.Blit(source, interim, dlaa, 0);
|
||||
Graphics.Blit(interim, destination, dlaa, dlaaSharp ? 2 : 1);
|
||||
RenderTexture.ReleaseTemporary(interim);
|
||||
}
|
||||
else if (mode == AAMode.NFAA && nfaa != null)
|
||||
{
|
||||
// ----------------------------------------------------------------
|
||||
// nfaa antialiasing
|
||||
|
||||
source.anisoLevel = 0;
|
||||
|
||||
nfaa.SetFloat("_OffsetScale", offsetScale);
|
||||
nfaa.SetFloat("_BlurRadius", blurRadius);
|
||||
|
||||
Graphics.Blit(source, destination, nfaa, showGeneratedNormals ? 1 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// none of the AA is supported, fallback to a simple blit
|
||||
Graphics.Blit(source, destination);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 646b5bc27a658f447b1d929fd5ffbd70
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- ssaaShader: {fileID: 4800000, guid: b3728d1488b02490cbd196c7941bf1f8, type: 3}
|
||||
- dlaaShader: {fileID: 4800000, guid: 017ca72b9e8a749058d13ebd527e98fa, type: 3}
|
||||
- nfaaShader: {fileID: 4800000, guid: ce0cb2621f6d84e21a87414e471a3cce, type: 3}
|
||||
- shaderFXAAPreset2: {fileID: 4800000, guid: 6f1418cffd12146f2a83be795f6fa5a7, type: 3}
|
||||
- shaderFXAAPreset3: {fileID: 4800000, guid: c182fa94a5a0a4c02870641efcd38cd5, type: 3}
|
||||
- shaderFXAAII: {fileID: 4800000, guid: cd5b323dcc592457790ff18b528f5e67, type: 3}
|
||||
- shaderFXAAIII: {fileID: 4800000, guid: c547503fff0e8482ea5793727057041c, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
358
Assets/Standard Assets/Effects/ImageEffects/Scripts/Bloom.cs
Normal file
358
Assets/Standard Assets/Effects/ImageEffects/Scripts/Bloom.cs
Normal file
@@ -0,0 +1,358 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Bloom and Glow/Bloom")]
|
||||
public class Bloom : PostEffectsBase
|
||||
{
|
||||
public enum LensFlareStyle
|
||||
{
|
||||
Ghosting = 0,
|
||||
Anamorphic = 1,
|
||||
Combined = 2,
|
||||
}
|
||||
|
||||
public enum TweakMode
|
||||
{
|
||||
Basic = 0,
|
||||
Complex = 1,
|
||||
}
|
||||
|
||||
public enum HDRBloomMode
|
||||
{
|
||||
Auto = 0,
|
||||
On = 1,
|
||||
Off = 2,
|
||||
}
|
||||
|
||||
public enum BloomScreenBlendMode
|
||||
{
|
||||
Screen = 0,
|
||||
Add = 1,
|
||||
}
|
||||
|
||||
public enum BloomQuality
|
||||
{
|
||||
Cheap = 0,
|
||||
High = 1,
|
||||
}
|
||||
|
||||
public TweakMode tweakMode = 0;
|
||||
public BloomScreenBlendMode screenBlendMode = BloomScreenBlendMode.Add;
|
||||
|
||||
public HDRBloomMode hdr = HDRBloomMode.Auto;
|
||||
private bool doHdr = false;
|
||||
public float sepBlurSpread = 2.5f;
|
||||
|
||||
public BloomQuality quality = BloomQuality.High;
|
||||
|
||||
public float bloomIntensity = 0.5f;
|
||||
public float bloomThreshold = 0.5f;
|
||||
public Color bloomThresholdColor = Color.white;
|
||||
public int bloomBlurIterations = 2;
|
||||
|
||||
public int hollywoodFlareBlurIterations = 2;
|
||||
public float flareRotation = 0.0f;
|
||||
public LensFlareStyle lensflareMode = (LensFlareStyle) 1;
|
||||
public float hollyStretchWidth = 2.5f;
|
||||
public float lensflareIntensity = 0.0f;
|
||||
public float lensflareThreshold = 0.3f;
|
||||
public float lensFlareSaturation = 0.75f;
|
||||
public Color flareColorA = new Color (0.4f, 0.4f, 0.8f, 0.75f);
|
||||
public Color flareColorB = new Color (0.4f, 0.8f, 0.8f, 0.75f);
|
||||
public Color flareColorC = new Color (0.8f, 0.4f, 0.8f, 0.75f);
|
||||
public Color flareColorD = new Color (0.8f, 0.4f, 0.0f, 0.75f);
|
||||
public Texture2D lensFlareVignetteMask;
|
||||
|
||||
public Shader lensFlareShader;
|
||||
private Material lensFlareMaterial;
|
||||
|
||||
public Shader screenBlendShader;
|
||||
private Material screenBlend;
|
||||
|
||||
public Shader blurAndFlaresShader;
|
||||
private Material blurAndFlaresMaterial;
|
||||
|
||||
public Shader brightPassFilterShader;
|
||||
private Material brightPassFilterMaterial;
|
||||
|
||||
|
||||
public override bool CheckResources ()
|
||||
{
|
||||
CheckSupport (false);
|
||||
|
||||
screenBlend = CheckShaderAndCreateMaterial (screenBlendShader, screenBlend);
|
||||
lensFlareMaterial = CheckShaderAndCreateMaterial(lensFlareShader,lensFlareMaterial);
|
||||
blurAndFlaresMaterial = CheckShaderAndCreateMaterial (blurAndFlaresShader, blurAndFlaresMaterial);
|
||||
brightPassFilterMaterial = CheckShaderAndCreateMaterial(brightPassFilterShader, brightPassFilterMaterial);
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
public void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources()==false)
|
||||
{
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
// screen blend is not supported when HDR is enabled (will cap values)
|
||||
|
||||
doHdr = false;
|
||||
if (hdr == HDRBloomMode.Auto)
|
||||
doHdr = source.format == RenderTextureFormat.ARGBHalf && GetComponent<Camera>().hdr;
|
||||
else {
|
||||
doHdr = hdr == HDRBloomMode.On;
|
||||
}
|
||||
|
||||
doHdr = doHdr && supportHDRTextures;
|
||||
|
||||
BloomScreenBlendMode realBlendMode = screenBlendMode;
|
||||
if (doHdr)
|
||||
realBlendMode = BloomScreenBlendMode.Add;
|
||||
|
||||
var rtFormat= (doHdr) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.Default;
|
||||
var rtW2= source.width/2;
|
||||
var rtH2= source.height/2;
|
||||
var rtW4= source.width/4;
|
||||
var rtH4= source.height/4;
|
||||
|
||||
float widthOverHeight = (1.0f * source.width) / (1.0f * source.height);
|
||||
float oneOverBaseSize = 1.0f / 512.0f;
|
||||
|
||||
// downsample
|
||||
RenderTexture quarterRezColor = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat);
|
||||
RenderTexture halfRezColorDown = RenderTexture.GetTemporary (rtW2, rtH2, 0, rtFormat);
|
||||
if (quality > BloomQuality.Cheap) {
|
||||
Graphics.Blit (source, halfRezColorDown, screenBlend, 2);
|
||||
RenderTexture rtDown4 = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat);
|
||||
Graphics.Blit (halfRezColorDown, rtDown4, screenBlend, 2);
|
||||
Graphics.Blit (rtDown4, quarterRezColor, screenBlend, 6);
|
||||
RenderTexture.ReleaseTemporary(rtDown4);
|
||||
}
|
||||
else {
|
||||
Graphics.Blit (source, halfRezColorDown);
|
||||
Graphics.Blit (halfRezColorDown, quarterRezColor, screenBlend, 6);
|
||||
}
|
||||
RenderTexture.ReleaseTemporary (halfRezColorDown);
|
||||
|
||||
// cut colors (thresholding)
|
||||
RenderTexture secondQuarterRezColor = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat);
|
||||
BrightFilter (bloomThreshold * bloomThresholdColor, quarterRezColor, secondQuarterRezColor);
|
||||
|
||||
// blurring
|
||||
|
||||
if (bloomBlurIterations < 1) bloomBlurIterations = 1;
|
||||
else if (bloomBlurIterations > 10) bloomBlurIterations = 10;
|
||||
|
||||
for (int iter = 0; iter < bloomBlurIterations; iter++)
|
||||
{
|
||||
float spreadForPass = (1.0f + (iter * 0.25f)) * sepBlurSpread;
|
||||
|
||||
// vertical blur
|
||||
RenderTexture blur4 = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat);
|
||||
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 (0.0f, spreadForPass * oneOverBaseSize, 0.0f, 0.0f));
|
||||
Graphics.Blit (secondQuarterRezColor, blur4, blurAndFlaresMaterial, 4);
|
||||
RenderTexture.ReleaseTemporary(secondQuarterRezColor);
|
||||
secondQuarterRezColor = blur4;
|
||||
|
||||
// horizontal blur
|
||||
blur4 = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat);
|
||||
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 ((spreadForPass / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
|
||||
Graphics.Blit (secondQuarterRezColor, blur4, blurAndFlaresMaterial, 4);
|
||||
RenderTexture.ReleaseTemporary (secondQuarterRezColor);
|
||||
secondQuarterRezColor = blur4;
|
||||
|
||||
if (quality > BloomQuality.Cheap)
|
||||
{
|
||||
if (iter == 0)
|
||||
{
|
||||
Graphics.SetRenderTarget(quarterRezColor);
|
||||
GL.Clear(false, true, Color.black); // Clear to avoid RT restore
|
||||
Graphics.Blit (secondQuarterRezColor, quarterRezColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
quarterRezColor.MarkRestoreExpected(); // using max blending, RT restore expected
|
||||
Graphics.Blit (secondQuarterRezColor, quarterRezColor, screenBlend, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (quality > BloomQuality.Cheap)
|
||||
{
|
||||
Graphics.SetRenderTarget(secondQuarterRezColor);
|
||||
GL.Clear(false, true, Color.black); // Clear to avoid RT restore
|
||||
Graphics.Blit (quarterRezColor, secondQuarterRezColor, screenBlend, 6);
|
||||
}
|
||||
|
||||
// lens flares: ghosting, anamorphic or both (ghosted anamorphic flares)
|
||||
|
||||
if (lensflareIntensity > Mathf.Epsilon)
|
||||
{
|
||||
|
||||
RenderTexture rtFlares4 = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat);
|
||||
|
||||
if (lensflareMode == 0)
|
||||
{
|
||||
// ghosting only
|
||||
|
||||
BrightFilter (lensflareThreshold, secondQuarterRezColor, rtFlares4);
|
||||
|
||||
if (quality > BloomQuality.Cheap)
|
||||
{
|
||||
// smooth a little
|
||||
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 (0.0f, (1.5f) / (1.0f * quarterRezColor.height), 0.0f, 0.0f));
|
||||
Graphics.SetRenderTarget(quarterRezColor);
|
||||
GL.Clear(false, true, Color.black); // Clear to avoid RT restore
|
||||
Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 4);
|
||||
|
||||
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 ((1.5f) / (1.0f * quarterRezColor.width), 0.0f, 0.0f, 0.0f));
|
||||
Graphics.SetRenderTarget(rtFlares4);
|
||||
GL.Clear(false, true, Color.black); // Clear to avoid RT restore
|
||||
Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial, 4);
|
||||
}
|
||||
|
||||
// no ugly edges!
|
||||
Vignette (0.975f, rtFlares4, rtFlares4);
|
||||
BlendFlares (rtFlares4, secondQuarterRezColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//Vignette (0.975ff, rtFlares4, rtFlares4);
|
||||
//DrawBorder(rtFlares4, screenBlend, 8);
|
||||
|
||||
float flareXRot = 1.0f * Mathf.Cos(flareRotation);
|
||||
float flareyRot = 1.0f * Mathf.Sin(flareRotation);
|
||||
|
||||
float stretchWidth = (hollyStretchWidth * 1.0f / widthOverHeight) * oneOverBaseSize;
|
||||
|
||||
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 (flareXRot, flareyRot, 0.0f, 0.0f));
|
||||
blurAndFlaresMaterial.SetVector ("_Threshhold", new Vector4 (lensflareThreshold, 1.0f, 0.0f, 0.0f));
|
||||
blurAndFlaresMaterial.SetVector ("_TintColor", new Vector4 (flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * flareColorA.a * lensflareIntensity);
|
||||
blurAndFlaresMaterial.SetFloat ("_Saturation", lensFlareSaturation);
|
||||
|
||||
// "pre and cut"
|
||||
quarterRezColor.DiscardContents();
|
||||
Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 2);
|
||||
// "post"
|
||||
rtFlares4.DiscardContents();
|
||||
Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial, 3);
|
||||
|
||||
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 (flareXRot * stretchWidth, flareyRot * stretchWidth, 0.0f, 0.0f));
|
||||
// stretch 1st
|
||||
blurAndFlaresMaterial.SetFloat ("_StretchWidth", hollyStretchWidth);
|
||||
quarterRezColor.DiscardContents();
|
||||
Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 1);
|
||||
// stretch 2nd
|
||||
blurAndFlaresMaterial.SetFloat ("_StretchWidth", hollyStretchWidth * 2.0f);
|
||||
rtFlares4.DiscardContents();
|
||||
Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial, 1);
|
||||
// stretch 3rd
|
||||
blurAndFlaresMaterial.SetFloat ("_StretchWidth", hollyStretchWidth * 4.0f);
|
||||
quarterRezColor.DiscardContents();
|
||||
Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 1);
|
||||
|
||||
// additional blur passes
|
||||
for (int iter = 0; iter < hollywoodFlareBlurIterations; iter++)
|
||||
{
|
||||
stretchWidth = (hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize;
|
||||
|
||||
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 (stretchWidth * flareXRot, stretchWidth * flareyRot, 0.0f, 0.0f));
|
||||
rtFlares4.DiscardContents();
|
||||
Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial, 4);
|
||||
|
||||
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 (stretchWidth * flareXRot, stretchWidth * flareyRot, 0.0f, 0.0f));
|
||||
quarterRezColor.DiscardContents();
|
||||
Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 4);
|
||||
}
|
||||
|
||||
if (lensflareMode == (LensFlareStyle) 1)
|
||||
// anamorphic lens flares
|
||||
AddTo (1.0f, quarterRezColor, secondQuarterRezColor);
|
||||
else
|
||||
{
|
||||
// "combined" lens flares
|
||||
|
||||
Vignette (1.0f, quarterRezColor, rtFlares4);
|
||||
BlendFlares (rtFlares4, quarterRezColor);
|
||||
AddTo (1.0f, quarterRezColor, secondQuarterRezColor);
|
||||
}
|
||||
}
|
||||
RenderTexture.ReleaseTemporary (rtFlares4);
|
||||
}
|
||||
|
||||
int blendPass = (int) realBlendMode;
|
||||
//if (Mathf.Abs(chromaticBloom) < Mathf.Epsilon)
|
||||
// blendPass += 4;
|
||||
|
||||
screenBlend.SetFloat ("_Intensity", bloomIntensity);
|
||||
screenBlend.SetTexture ("_ColorBuffer", source);
|
||||
|
||||
if (quality > BloomQuality.Cheap)
|
||||
{
|
||||
RenderTexture halfRezColorUp = RenderTexture.GetTemporary (rtW2, rtH2, 0, rtFormat);
|
||||
Graphics.Blit (secondQuarterRezColor, halfRezColorUp);
|
||||
Graphics.Blit (halfRezColorUp, destination, screenBlend, blendPass);
|
||||
RenderTexture.ReleaseTemporary (halfRezColorUp);
|
||||
}
|
||||
else
|
||||
Graphics.Blit (secondQuarterRezColor, destination, screenBlend, blendPass);
|
||||
|
||||
RenderTexture.ReleaseTemporary (quarterRezColor);
|
||||
RenderTexture.ReleaseTemporary (secondQuarterRezColor);
|
||||
}
|
||||
|
||||
private void AddTo (float intensity_, RenderTexture from, RenderTexture to)
|
||||
{
|
||||
screenBlend.SetFloat ("_Intensity", intensity_);
|
||||
to.MarkRestoreExpected(); // additive blending, RT restore expected
|
||||
Graphics.Blit (from, to, screenBlend, 9);
|
||||
}
|
||||
|
||||
private void BlendFlares (RenderTexture from, RenderTexture to)
|
||||
{
|
||||
lensFlareMaterial.SetVector ("colorA", new Vector4 (flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * lensflareIntensity);
|
||||
lensFlareMaterial.SetVector ("colorB", new Vector4 (flareColorB.r, flareColorB.g, flareColorB.b, flareColorB.a) * lensflareIntensity);
|
||||
lensFlareMaterial.SetVector ("colorC", new Vector4 (flareColorC.r, flareColorC.g, flareColorC.b, flareColorC.a) * lensflareIntensity);
|
||||
lensFlareMaterial.SetVector ("colorD", new Vector4 (flareColorD.r, flareColorD.g, flareColorD.b, flareColorD.a) * lensflareIntensity);
|
||||
to.MarkRestoreExpected(); // additive blending, RT restore expected
|
||||
Graphics.Blit (from, to, lensFlareMaterial);
|
||||
}
|
||||
|
||||
private void BrightFilter (float thresh, RenderTexture from, RenderTexture to)
|
||||
{
|
||||
brightPassFilterMaterial.SetVector ("_Threshhold", new Vector4 (thresh, thresh, thresh, thresh));
|
||||
Graphics.Blit (from, to, brightPassFilterMaterial, 0);
|
||||
}
|
||||
|
||||
private void BrightFilter (Color threshColor, RenderTexture from, RenderTexture to)
|
||||
{
|
||||
brightPassFilterMaterial.SetVector ("_Threshhold", threshColor);
|
||||
Graphics.Blit (from, to, brightPassFilterMaterial, 1);
|
||||
}
|
||||
|
||||
private void Vignette (float amount, RenderTexture from, RenderTexture to)
|
||||
{
|
||||
if (lensFlareVignetteMask)
|
||||
{
|
||||
screenBlend.SetTexture ("_ColorBuffer", lensFlareVignetteMask);
|
||||
to.MarkRestoreExpected(); // using blending, RT restore expected
|
||||
Graphics.Blit (from == to ? null : from, to, screenBlend, from == to ? 7 : 3);
|
||||
}
|
||||
else if (from != to)
|
||||
{
|
||||
Graphics.SetRenderTarget (to);
|
||||
GL.Clear(false, true, Color.black); // clear destination to avoid RT restore
|
||||
Graphics.Blit (from, to);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7fceaeb339b971b429c4cc600acabd13
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- lensFlareVignetteMask: {fileID: 2800000, guid: 95ef4804fe0be4c999ddaa383536cde8,
|
||||
type: 3}
|
||||
- lensFlareShader: {fileID: 4800000, guid: 459fe69d2f6d74ddb92f04dbf45a866b, type: 3}
|
||||
- screenBlendShader: {fileID: 4800000, guid: 7856cbff0a0ca45c787d5431eb805bb0, type: 3}
|
||||
- blurAndFlaresShader: {fileID: 4800000, guid: be6e39cf196f146d5be72fbefb18ed75,
|
||||
type: 3}
|
||||
- brightPassFilterShader: {fileID: 4800000, guid: 0aeaa4cb29f5d4e9c8455f04c8575c8c,
|
||||
type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,314 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
public enum LensflareStyle34
|
||||
{
|
||||
Ghosting = 0,
|
||||
Anamorphic = 1,
|
||||
Combined = 2,
|
||||
}
|
||||
|
||||
public enum TweakMode34
|
||||
{
|
||||
Basic = 0,
|
||||
Complex = 1,
|
||||
}
|
||||
|
||||
public enum HDRBloomMode
|
||||
{
|
||||
Auto = 0,
|
||||
On = 1,
|
||||
Off = 2,
|
||||
}
|
||||
|
||||
public enum BloomScreenBlendMode
|
||||
{
|
||||
Screen = 0,
|
||||
Add = 1,
|
||||
}
|
||||
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(Camera))]
|
||||
[AddComponentMenu("Image Effects/Bloom and Glow/BloomAndFlares (3.5, Deprecated)")]
|
||||
public class BloomAndFlares : PostEffectsBase
|
||||
{
|
||||
public TweakMode34 tweakMode = 0;
|
||||
public BloomScreenBlendMode screenBlendMode = BloomScreenBlendMode.Add;
|
||||
|
||||
public HDRBloomMode hdr = HDRBloomMode.Auto;
|
||||
private bool doHdr = false;
|
||||
public float sepBlurSpread = 1.5f;
|
||||
public float useSrcAlphaAsMask = 0.5f;
|
||||
|
||||
public float bloomIntensity = 1.0f;
|
||||
public float bloomThreshold = 0.5f;
|
||||
public int bloomBlurIterations = 2;
|
||||
|
||||
public bool lensflares = false;
|
||||
public int hollywoodFlareBlurIterations = 2;
|
||||
public LensflareStyle34 lensflareMode = (LensflareStyle34)1;
|
||||
public float hollyStretchWidth = 3.5f;
|
||||
public float lensflareIntensity = 1.0f;
|
||||
public float lensflareThreshold = 0.3f;
|
||||
public Color flareColorA = new Color(0.4f, 0.4f, 0.8f, 0.75f);
|
||||
public Color flareColorB = new Color(0.4f, 0.8f, 0.8f, 0.75f);
|
||||
public Color flareColorC = new Color(0.8f, 0.4f, 0.8f, 0.75f);
|
||||
public Color flareColorD = new Color(0.8f, 0.4f, 0.0f, 0.75f);
|
||||
public Texture2D lensFlareVignetteMask;
|
||||
|
||||
public Shader lensFlareShader;
|
||||
private Material lensFlareMaterial;
|
||||
|
||||
public Shader vignetteShader;
|
||||
private Material vignetteMaterial;
|
||||
|
||||
public Shader separableBlurShader;
|
||||
private Material separableBlurMaterial;
|
||||
|
||||
public Shader addBrightStuffOneOneShader;
|
||||
private Material addBrightStuffBlendOneOneMaterial;
|
||||
|
||||
public Shader screenBlendShader;
|
||||
private Material screenBlend;
|
||||
|
||||
public Shader hollywoodFlaresShader;
|
||||
private Material hollywoodFlaresMaterial;
|
||||
|
||||
public Shader brightPassFilterShader;
|
||||
private Material brightPassFilterMaterial;
|
||||
|
||||
|
||||
public override bool CheckResources()
|
||||
{
|
||||
CheckSupport(false);
|
||||
|
||||
screenBlend = CheckShaderAndCreateMaterial(screenBlendShader, screenBlend);
|
||||
lensFlareMaterial = CheckShaderAndCreateMaterial(lensFlareShader, lensFlareMaterial);
|
||||
vignetteMaterial = CheckShaderAndCreateMaterial(vignetteShader, vignetteMaterial);
|
||||
separableBlurMaterial = CheckShaderAndCreateMaterial(separableBlurShader, separableBlurMaterial);
|
||||
addBrightStuffBlendOneOneMaterial = CheckShaderAndCreateMaterial(addBrightStuffOneOneShader, addBrightStuffBlendOneOneMaterial);
|
||||
hollywoodFlaresMaterial = CheckShaderAndCreateMaterial(hollywoodFlaresShader, hollywoodFlaresMaterial);
|
||||
brightPassFilterMaterial = CheckShaderAndCreateMaterial(brightPassFilterShader, brightPassFilterMaterial);
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnRenderImage(RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources() == false)
|
||||
{
|
||||
Graphics.Blit(source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
// screen blend is not supported when HDR is enabled (will cap values)
|
||||
|
||||
doHdr = false;
|
||||
if (hdr == HDRBloomMode.Auto)
|
||||
doHdr = source.format == RenderTextureFormat.ARGBHalf && GetComponent<Camera>().hdr;
|
||||
else
|
||||
{
|
||||
doHdr = hdr == HDRBloomMode.On;
|
||||
}
|
||||
|
||||
doHdr = doHdr && supportHDRTextures;
|
||||
|
||||
BloomScreenBlendMode realBlendMode = screenBlendMode;
|
||||
if (doHdr)
|
||||
realBlendMode = BloomScreenBlendMode.Add;
|
||||
|
||||
var rtFormat = (doHdr) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.Default;
|
||||
RenderTexture halfRezColor = RenderTexture.GetTemporary(source.width / 2, source.height / 2, 0, rtFormat);
|
||||
RenderTexture quarterRezColor = RenderTexture.GetTemporary(source.width / 4, source.height / 4, 0, rtFormat);
|
||||
RenderTexture secondQuarterRezColor = RenderTexture.GetTemporary(source.width / 4, source.height / 4, 0, rtFormat);
|
||||
RenderTexture thirdQuarterRezColor = RenderTexture.GetTemporary(source.width / 4, source.height / 4, 0, rtFormat);
|
||||
|
||||
float widthOverHeight = (1.0f * source.width) / (1.0f * source.height);
|
||||
float oneOverBaseSize = 1.0f / 512.0f;
|
||||
|
||||
// downsample
|
||||
|
||||
Graphics.Blit(source, halfRezColor, screenBlend, 2); // <- 2 is stable downsample
|
||||
Graphics.Blit(halfRezColor, quarterRezColor, screenBlend, 2); // <- 2 is stable downsample
|
||||
|
||||
RenderTexture.ReleaseTemporary(halfRezColor);
|
||||
|
||||
// cut colors (thresholding)
|
||||
|
||||
BrightFilter(bloomThreshold, useSrcAlphaAsMask, quarterRezColor, secondQuarterRezColor);
|
||||
quarterRezColor.DiscardContents();
|
||||
|
||||
// blurring
|
||||
|
||||
if (bloomBlurIterations < 1) bloomBlurIterations = 1;
|
||||
|
||||
for (int iter = 0; iter < bloomBlurIterations; iter++)
|
||||
{
|
||||
float spreadForPass = (1.0f + (iter * 0.5f)) * sepBlurSpread;
|
||||
separableBlurMaterial.SetVector("offsets", new Vector4(0.0f, spreadForPass * oneOverBaseSize, 0.0f, 0.0f));
|
||||
|
||||
RenderTexture src = iter == 0 ? secondQuarterRezColor : quarterRezColor;
|
||||
Graphics.Blit(src, thirdQuarterRezColor, separableBlurMaterial);
|
||||
src.DiscardContents();
|
||||
|
||||
separableBlurMaterial.SetVector("offsets", new Vector4((spreadForPass / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
|
||||
Graphics.Blit(thirdQuarterRezColor, quarterRezColor, separableBlurMaterial);
|
||||
thirdQuarterRezColor.DiscardContents();
|
||||
}
|
||||
|
||||
// lens flares: ghosting, anamorphic or a combination
|
||||
|
||||
if (lensflares)
|
||||
{
|
||||
|
||||
if (lensflareMode == 0)
|
||||
{
|
||||
|
||||
BrightFilter(lensflareThreshold, 0.0f, quarterRezColor, thirdQuarterRezColor);
|
||||
quarterRezColor.DiscardContents();
|
||||
|
||||
// smooth a little, this needs to be resolution dependent
|
||||
/*
|
||||
separableBlurMaterial.SetVector ("offsets", Vector4 (0.0ff, (2.0ff) / (1.0ff * quarterRezColor.height), 0.0ff, 0.0ff));
|
||||
Graphics.Blit (thirdQuarterRezColor, secondQuarterRezColor, separableBlurMaterial);
|
||||
separableBlurMaterial.SetVector ("offsets", Vector4 ((2.0ff) / (1.0ff * quarterRezColor.width), 0.0ff, 0.0ff, 0.0ff));
|
||||
Graphics.Blit (secondQuarterRezColor, thirdQuarterRezColor, separableBlurMaterial);
|
||||
*/
|
||||
// no ugly edges!
|
||||
|
||||
Vignette(0.975f, thirdQuarterRezColor, secondQuarterRezColor);
|
||||
thirdQuarterRezColor.DiscardContents();
|
||||
|
||||
BlendFlares(secondQuarterRezColor, quarterRezColor);
|
||||
secondQuarterRezColor.DiscardContents();
|
||||
}
|
||||
|
||||
// (b) hollywood/anamorphic flares?
|
||||
|
||||
else
|
||||
{
|
||||
|
||||
// thirdQuarter has the brightcut unblurred colors
|
||||
// quarterRezColor is the blurred, brightcut buffer that will end up as bloom
|
||||
|
||||
hollywoodFlaresMaterial.SetVector("_threshold", new Vector4(lensflareThreshold, 1.0f / (1.0f - lensflareThreshold), 0.0f, 0.0f));
|
||||
hollywoodFlaresMaterial.SetVector("tintColor", new Vector4(flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * flareColorA.a * lensflareIntensity);
|
||||
Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, hollywoodFlaresMaterial, 2);
|
||||
thirdQuarterRezColor.DiscardContents();
|
||||
|
||||
Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, hollywoodFlaresMaterial, 3);
|
||||
secondQuarterRezColor.DiscardContents();
|
||||
|
||||
hollywoodFlaresMaterial.SetVector("offsets", new Vector4((sepBlurSpread * 1.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
|
||||
hollywoodFlaresMaterial.SetFloat("stretchWidth", hollyStretchWidth);
|
||||
Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, hollywoodFlaresMaterial, 1);
|
||||
thirdQuarterRezColor.DiscardContents();
|
||||
|
||||
hollywoodFlaresMaterial.SetFloat("stretchWidth", hollyStretchWidth * 2.0f);
|
||||
Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, hollywoodFlaresMaterial, 1);
|
||||
secondQuarterRezColor.DiscardContents();
|
||||
|
||||
hollywoodFlaresMaterial.SetFloat("stretchWidth", hollyStretchWidth * 4.0f);
|
||||
Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, hollywoodFlaresMaterial, 1);
|
||||
thirdQuarterRezColor.DiscardContents();
|
||||
|
||||
if (lensflareMode == (LensflareStyle34)1)
|
||||
{
|
||||
for (int itera = 0; itera < hollywoodFlareBlurIterations; itera++)
|
||||
{
|
||||
separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
|
||||
Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, separableBlurMaterial);
|
||||
secondQuarterRezColor.DiscardContents();
|
||||
|
||||
separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
|
||||
Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, separableBlurMaterial);
|
||||
thirdQuarterRezColor.DiscardContents();
|
||||
}
|
||||
|
||||
AddTo(1.0f, secondQuarterRezColor, quarterRezColor);
|
||||
secondQuarterRezColor.DiscardContents();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// (c) combined
|
||||
|
||||
for (int ix = 0; ix < hollywoodFlareBlurIterations; ix++)
|
||||
{
|
||||
separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
|
||||
Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, separableBlurMaterial);
|
||||
secondQuarterRezColor.DiscardContents();
|
||||
|
||||
separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
|
||||
Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, separableBlurMaterial);
|
||||
thirdQuarterRezColor.DiscardContents();
|
||||
}
|
||||
|
||||
Vignette(1.0f, secondQuarterRezColor, thirdQuarterRezColor);
|
||||
secondQuarterRezColor.DiscardContents();
|
||||
|
||||
BlendFlares(thirdQuarterRezColor, secondQuarterRezColor);
|
||||
thirdQuarterRezColor.DiscardContents();
|
||||
|
||||
AddTo(1.0f, secondQuarterRezColor, quarterRezColor);
|
||||
secondQuarterRezColor.DiscardContents();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// screen blend bloom results to color buffer
|
||||
|
||||
screenBlend.SetFloat("_Intensity", bloomIntensity);
|
||||
screenBlend.SetTexture("_ColorBuffer", source);
|
||||
Graphics.Blit(quarterRezColor, destination, screenBlend, (int)realBlendMode);
|
||||
|
||||
RenderTexture.ReleaseTemporary(quarterRezColor);
|
||||
RenderTexture.ReleaseTemporary(secondQuarterRezColor);
|
||||
RenderTexture.ReleaseTemporary(thirdQuarterRezColor);
|
||||
}
|
||||
|
||||
private void AddTo(float intensity_, RenderTexture from, RenderTexture to)
|
||||
{
|
||||
addBrightStuffBlendOneOneMaterial.SetFloat("_Intensity", intensity_);
|
||||
Graphics.Blit(from, to, addBrightStuffBlendOneOneMaterial);
|
||||
}
|
||||
|
||||
private void BlendFlares(RenderTexture from, RenderTexture to)
|
||||
{
|
||||
lensFlareMaterial.SetVector("colorA", new Vector4(flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * lensflareIntensity);
|
||||
lensFlareMaterial.SetVector("colorB", new Vector4(flareColorB.r, flareColorB.g, flareColorB.b, flareColorB.a) * lensflareIntensity);
|
||||
lensFlareMaterial.SetVector("colorC", new Vector4(flareColorC.r, flareColorC.g, flareColorC.b, flareColorC.a) * lensflareIntensity);
|
||||
lensFlareMaterial.SetVector("colorD", new Vector4(flareColorD.r, flareColorD.g, flareColorD.b, flareColorD.a) * lensflareIntensity);
|
||||
Graphics.Blit(from, to, lensFlareMaterial);
|
||||
}
|
||||
|
||||
private void BrightFilter(float thresh, float useAlphaAsMask, RenderTexture from, RenderTexture to)
|
||||
{
|
||||
if (doHdr)
|
||||
brightPassFilterMaterial.SetVector("threshold", new Vector4(thresh, 1.0f, 0.0f, 0.0f));
|
||||
else
|
||||
brightPassFilterMaterial.SetVector("threshold", new Vector4(thresh, 1.0f / (1.0f - thresh), 0.0f, 0.0f));
|
||||
brightPassFilterMaterial.SetFloat("useSrcAlphaAsMask", useAlphaAsMask);
|
||||
Graphics.Blit(from, to, brightPassFilterMaterial);
|
||||
}
|
||||
|
||||
private void Vignette(float amount, RenderTexture from, RenderTexture to)
|
||||
{
|
||||
if (lensFlareVignetteMask)
|
||||
{
|
||||
screenBlend.SetTexture("_ColorBuffer", lensFlareVignetteMask);
|
||||
Graphics.Blit(from, to, screenBlend, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
vignetteMaterial.SetFloat("vignetteIntensity", amount);
|
||||
Graphics.Blit(from, to, vignetteMaterial);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02536f33053638549ab5c50ff3ecc0de
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- lensFlareVignetteMask: {fileID: 2800000, guid: 95ef4804fe0be4c999ddaa383536cde8,
|
||||
type: 3}
|
||||
- lensFlareShader: {fileID: 4800000, guid: 459fe69d2f6d74ddb92f04dbf45a866b, type: 3}
|
||||
- vignetteShader: {fileID: 4800000, guid: 627943dc7a9a74286b70a4f694a0acd5, type: 3}
|
||||
- separableBlurShader: {fileID: 4800000, guid: a9df009a214e24a5ebbf271595f8d5b6,
|
||||
type: 3}
|
||||
- addBrightStuffOneOneShader: {fileID: 4800000, guid: f7898d203e9b94c0dbe2bf9dd5cb32c0,
|
||||
type: 3}
|
||||
- screenBlendShader: {fileID: 4800000, guid: 53b3960ee3d3d4a5caa8d5473d120187, type: 3}
|
||||
- hollywoodFlaresShader: {fileID: 4800000, guid: e2baf3cae8edc4daf94c9adc2154be00,
|
||||
type: 3}
|
||||
- brightPassFilterShader: {fileID: 4800000, guid: 186c4c0d31e314f049595dcbaf4ca129,
|
||||
type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,109 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Bloom and Glow/Bloom (Optimized)")]
|
||||
public class BloomOptimized : PostEffectsBase
|
||||
{
|
||||
|
||||
public enum Resolution
|
||||
{
|
||||
Low = 0,
|
||||
High = 1,
|
||||
}
|
||||
|
||||
public enum BlurType
|
||||
{
|
||||
Standard = 0,
|
||||
Sgx = 1,
|
||||
}
|
||||
|
||||
[Range(0.0f, 1.5f)]
|
||||
public float threshold = 0.25f;
|
||||
[Range(0.0f, 2.5f)]
|
||||
public float intensity = 0.75f;
|
||||
|
||||
[Range(0.25f, 5.5f)]
|
||||
public float blurSize = 1.0f;
|
||||
|
||||
Resolution resolution = Resolution.Low;
|
||||
[Range(1, 4)]
|
||||
public int blurIterations = 1;
|
||||
|
||||
public BlurType blurType= BlurType.Standard;
|
||||
|
||||
public Shader fastBloomShader = null;
|
||||
private Material fastBloomMaterial = null;
|
||||
|
||||
|
||||
public override bool CheckResources ()
|
||||
{
|
||||
CheckSupport (false);
|
||||
|
||||
fastBloomMaterial = CheckShaderAndCreateMaterial (fastBloomShader, fastBloomMaterial);
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnDisable ()
|
||||
{
|
||||
if (fastBloomMaterial)
|
||||
DestroyImmediate (fastBloomMaterial);
|
||||
}
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources() == false)
|
||||
{
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
int divider = resolution == Resolution.Low ? 4 : 2;
|
||||
float widthMod = resolution == Resolution.Low ? 0.5f : 1.0f;
|
||||
|
||||
fastBloomMaterial.SetVector ("_Parameter", new Vector4 (blurSize * widthMod, 0.0f, threshold, intensity));
|
||||
source.filterMode = FilterMode.Bilinear;
|
||||
|
||||
var rtW= source.width/divider;
|
||||
var rtH= source.height/divider;
|
||||
|
||||
// downsample
|
||||
RenderTexture rt = RenderTexture.GetTemporary (rtW, rtH, 0, source.format);
|
||||
rt.filterMode = FilterMode.Bilinear;
|
||||
Graphics.Blit (source, rt, fastBloomMaterial, 1);
|
||||
|
||||
var passOffs= blurType == BlurType.Standard ? 0 : 2;
|
||||
|
||||
for(int i = 0; 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, source.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, source.format);
|
||||
rt2.filterMode = FilterMode.Bilinear;
|
||||
Graphics.Blit (rt, rt2, fastBloomMaterial, 3 + passOffs);
|
||||
RenderTexture.ReleaseTemporary (rt);
|
||||
rt = rt2;
|
||||
}
|
||||
|
||||
fastBloomMaterial.SetTexture ("_Bloom", rt);
|
||||
|
||||
Graphics.Blit (source, destination, fastBloomMaterial, 0);
|
||||
|
||||
RenderTexture.ReleaseTemporary (rt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4975a6e437fc3b149a8cd508ce5bdd69
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- fastBloomShader: {fileID: 4800000, guid: 68a00c837b82e4c6d92e7da765dc5f1d, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
108
Assets/Standard Assets/Effects/ImageEffects/Scripts/Blur.cs
Normal file
108
Assets/Standard Assets/Effects/ImageEffects/Scripts/Blur.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu("Image Effects/Blur/Blur")]
|
||||
public class Blur : MonoBehaviour
|
||||
{
|
||||
/// Blur iterations - larger number means more blur.
|
||||
[Range(0,10)]
|
||||
public int iterations = 3;
|
||||
|
||||
/// Blur spread for each iteration. Lower values
|
||||
/// give better looking blur, but require more iterations to
|
||||
/// get large blurs. Value is usually between 0.5 and 1.0.
|
||||
[Range(0.0f,1.0f)]
|
||||
public float blurSpread = 0.6f;
|
||||
|
||||
|
||||
// --------------------------------------------------------
|
||||
// The blur iteration shader.
|
||||
// Basically it just takes 4 texture samples and averages them.
|
||||
// By applying it repeatedly and spreading out sample locations
|
||||
// we get a Gaussian blur approximation.
|
||||
|
||||
public Shader blurShader = null;
|
||||
|
||||
static Material m_Material = null;
|
||||
protected Material material {
|
||||
get {
|
||||
if (m_Material == null) {
|
||||
m_Material = new Material(blurShader);
|
||||
m_Material.hideFlags = HideFlags.DontSave;
|
||||
}
|
||||
return m_Material;
|
||||
}
|
||||
}
|
||||
|
||||
protected void OnDisable() {
|
||||
if ( m_Material ) {
|
||||
DestroyImmediate( m_Material );
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
protected void Start()
|
||||
{
|
||||
// Disable if we don't support image effects
|
||||
if (!SystemInfo.supportsImageEffects) {
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
// Disable if the shader can't run on the users graphics card
|
||||
if (!blurShader || !material.shader.isSupported) {
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Performs one blur iteration.
|
||||
public void FourTapCone (RenderTexture source, RenderTexture dest, int iteration)
|
||||
{
|
||||
float off = 0.5f + iteration*blurSpread;
|
||||
Graphics.BlitMultiTap (source, dest, material,
|
||||
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, material,
|
||||
new Vector2(-off, -off),
|
||||
new Vector2(-off, off),
|
||||
new Vector2( off, off),
|
||||
new Vector2( off, -off)
|
||||
);
|
||||
}
|
||||
|
||||
// Called by the camera to apply the image effect
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
int rtW = source.width/4;
|
||||
int rtH = source.height/4;
|
||||
RenderTexture buffer = RenderTexture.GetTemporary(rtW, rtH, 0);
|
||||
|
||||
// Copy source to the 4x4 smaller texture.
|
||||
DownSample4x (source, buffer);
|
||||
|
||||
// Blur the small texture
|
||||
for(int i = 0; i < iterations; i++)
|
||||
{
|
||||
RenderTexture buffer2 = RenderTexture.GetTemporary(rtW, rtH, 0);
|
||||
FourTapCone (buffer, buffer2, i);
|
||||
RenderTexture.ReleaseTemporary(buffer);
|
||||
buffer = buffer2;
|
||||
}
|
||||
Graphics.Blit(buffer, destination);
|
||||
|
||||
RenderTexture.ReleaseTemporary(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 34382083ad114a07d000fbfb8d76c639
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- blurShader: {fileID: 4800000, guid: 57e6deea7c2924e22a5138e2b70bb4dc, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Blur/Blur (Optimized)")]
|
||||
public class BlurOptimized : PostEffectsBase
|
||||
{
|
||||
|
||||
[Range(0, 2)]
|
||||
public int downsample = 1;
|
||||
|
||||
public enum BlurType {
|
||||
StandardGauss = 0,
|
||||
SgxGauss = 1,
|
||||
}
|
||||
|
||||
[Range(0.0f, 10.0f)]
|
||||
public float blurSize = 3.0f;
|
||||
|
||||
[Range(1, 4)]
|
||||
public int blurIterations = 2;
|
||||
|
||||
public BlurType blurType= BlurType.StandardGauss;
|
||||
|
||||
public Shader blurShader = null;
|
||||
private Material blurMaterial = null;
|
||||
|
||||
|
||||
public override bool CheckResources () {
|
||||
CheckSupport (false);
|
||||
|
||||
blurMaterial = CheckShaderAndCreateMaterial (blurShader, blurMaterial);
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
public void OnDisable () {
|
||||
if (blurMaterial)
|
||||
DestroyImmediate (blurMaterial);
|
||||
}
|
||||
|
||||
public void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
if (CheckResources() == false) {
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
float widthMod = 1.0f / (1.0f * (1<<downsample));
|
||||
|
||||
blurMaterial.SetVector ("_Parameter", new Vector4 (blurSize * widthMod, -blurSize * widthMod, 0.0f, 0.0f));
|
||||
source.filterMode = FilterMode.Bilinear;
|
||||
|
||||
int rtW = source.width >> downsample;
|
||||
int rtH = source.height >> downsample;
|
||||
|
||||
// downsample
|
||||
RenderTexture rt = RenderTexture.GetTemporary (rtW, rtH, 0, source.format);
|
||||
|
||||
rt.filterMode = FilterMode.Bilinear;
|
||||
Graphics.Blit (source, rt, blurMaterial, 0);
|
||||
|
||||
var passOffs= blurType == BlurType.StandardGauss ? 0 : 2;
|
||||
|
||||
for(int i = 0; i < blurIterations; i++) {
|
||||
float iterationOffs = (i*1.0f);
|
||||
blurMaterial.SetVector ("_Parameter", new Vector4 (blurSize * widthMod + iterationOffs, -blurSize * widthMod - iterationOffs, 0.0f, 0.0f));
|
||||
|
||||
// vertical blur
|
||||
RenderTexture rt2 = RenderTexture.GetTemporary (rtW, rtH, 0, source.format);
|
||||
rt2.filterMode = FilterMode.Bilinear;
|
||||
Graphics.Blit (rt, rt2, blurMaterial, 1 + passOffs);
|
||||
RenderTexture.ReleaseTemporary (rt);
|
||||
rt = rt2;
|
||||
|
||||
// horizontal blur
|
||||
rt2 = RenderTexture.GetTemporary (rtW, rtH, 0, source.format);
|
||||
rt2.filterMode = FilterMode.Bilinear;
|
||||
Graphics.Blit (rt, rt2, blurMaterial, 2 + passOffs);
|
||||
RenderTexture.ReleaseTemporary (rt);
|
||||
rt = rt2;
|
||||
}
|
||||
|
||||
Graphics.Blit (rt, destination);
|
||||
|
||||
RenderTexture.ReleaseTemporary (rt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7fc6bde01469c7b4badee5362f191d96
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- blurShader: {fileID: 4800000, guid: f9d5fa183cd6b45eeb1491f74863cd91, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,381 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Camera/Camera Motion Blur") ]
|
||||
public class CameraMotionBlur : PostEffectsBase
|
||||
{
|
||||
// make sure to match this to MAX_RADIUS in shader ('k' in paper)
|
||||
static float MAX_RADIUS = 10.0f;
|
||||
|
||||
public enum MotionBlurFilter {
|
||||
CameraMotion = 0, // global screen blur based on cam motion
|
||||
LocalBlur = 1, // cheap blur, no dilation or scattering
|
||||
Reconstruction = 2, // advanced filter (simulates scattering) as in plausible motion blur paper
|
||||
ReconstructionDX11 = 3, // advanced filter (simulates scattering) as in plausible motion blur paper
|
||||
ReconstructionDisc = 4, // advanced filter using scaled poisson disc sampling
|
||||
}
|
||||
|
||||
// settings
|
||||
public MotionBlurFilter filterType = MotionBlurFilter.Reconstruction;
|
||||
public bool preview = false; // show how blur would look like in action ...
|
||||
public Vector3 previewScale = Vector3.one; // ... given this movement vector
|
||||
|
||||
// params
|
||||
public float movementScale = 0.0f;
|
||||
public float rotationScale = 1.0f;
|
||||
public float maxVelocity = 8.0f; // maximum velocity in pixels
|
||||
public float minVelocity = 0.1f; // minimum velocity in pixels
|
||||
public float velocityScale = 0.375f; // global velocity scale
|
||||
public float softZDistance = 0.005f; // for z overlap check softness (reconstruction filter only)
|
||||
public int velocityDownsample = 1; // low resolution velocity buffer? (optimization)
|
||||
public LayerMask excludeLayers = 0;
|
||||
private GameObject tmpCam = null;
|
||||
|
||||
// resources
|
||||
public Shader shader;
|
||||
public Shader dx11MotionBlurShader;
|
||||
public Shader replacementClear;
|
||||
|
||||
private Material motionBlurMaterial = null;
|
||||
private Material dx11MotionBlurMaterial = null;
|
||||
|
||||
public Texture2D noiseTexture = null;
|
||||
public float jitter = 0.05f;
|
||||
|
||||
// (internal) debug
|
||||
public bool showVelocity = false;
|
||||
public float showVelocityScale = 1.0f;
|
||||
|
||||
// camera transforms
|
||||
private Matrix4x4 currentViewProjMat;
|
||||
private Matrix4x4 prevViewProjMat;
|
||||
private int prevFrameCount;
|
||||
private bool wasActive;
|
||||
// shortcuts to calculate global blur direction when using 'CameraMotion'
|
||||
private Vector3 prevFrameForward = Vector3.forward;
|
||||
private Vector3 prevFrameUp = Vector3.up;
|
||||
private Vector3 prevFramePos = Vector3.zero;
|
||||
private Camera _camera;
|
||||
|
||||
|
||||
private void CalculateViewProjection () {
|
||||
Matrix4x4 viewMat = _camera.worldToCameraMatrix;
|
||||
Matrix4x4 projMat = GL.GetGPUProjectionMatrix (_camera.projectionMatrix, true);
|
||||
currentViewProjMat = projMat * viewMat;
|
||||
}
|
||||
|
||||
|
||||
new void Start () {
|
||||
CheckResources ();
|
||||
|
||||
if (_camera == null)
|
||||
_camera = GetComponent<Camera>();
|
||||
|
||||
wasActive = gameObject.activeInHierarchy;
|
||||
CalculateViewProjection ();
|
||||
Remember ();
|
||||
wasActive = false; // hack to fake position/rotation update and prevent bad blurs
|
||||
}
|
||||
|
||||
void OnEnable () {
|
||||
|
||||
if (_camera == null)
|
||||
_camera = GetComponent<Camera>();
|
||||
|
||||
_camera.depthTextureMode |= DepthTextureMode.Depth;
|
||||
}
|
||||
|
||||
void OnDisable () {
|
||||
if (null != motionBlurMaterial) {
|
||||
DestroyImmediate (motionBlurMaterial);
|
||||
motionBlurMaterial = null;
|
||||
}
|
||||
if (null != dx11MotionBlurMaterial) {
|
||||
DestroyImmediate (dx11MotionBlurMaterial);
|
||||
dx11MotionBlurMaterial = null;
|
||||
}
|
||||
if (null != tmpCam) {
|
||||
DestroyImmediate (tmpCam);
|
||||
tmpCam = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override bool CheckResources () {
|
||||
CheckSupport (true, true); // depth & hdr needed
|
||||
motionBlurMaterial = CheckShaderAndCreateMaterial (shader, motionBlurMaterial);
|
||||
|
||||
if (supportDX11 && filterType == MotionBlurFilter.ReconstructionDX11) {
|
||||
dx11MotionBlurMaterial = CheckShaderAndCreateMaterial (dx11MotionBlurShader, dx11MotionBlurMaterial);
|
||||
}
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
if (false == CheckResources ()) {
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
if (filterType == MotionBlurFilter.CameraMotion)
|
||||
StartFrame ();
|
||||
|
||||
// use if possible new RG format ... fallback to half otherwise
|
||||
var rtFormat= SystemInfo.SupportsRenderTextureFormat (RenderTextureFormat.RGHalf) ? RenderTextureFormat.RGHalf : RenderTextureFormat.ARGBHalf;
|
||||
|
||||
// get temp textures
|
||||
RenderTexture velBuffer = RenderTexture.GetTemporary (divRoundUp (source.width, velocityDownsample), divRoundUp (source.height, velocityDownsample), 0, rtFormat);
|
||||
int tileWidth = 1;
|
||||
int tileHeight = 1;
|
||||
maxVelocity = Mathf.Max (2.0f, maxVelocity);
|
||||
|
||||
float _maxVelocity = maxVelocity; // calculate 'k'
|
||||
// note: 's' is hardcoded in shaders except for DX11 path
|
||||
|
||||
// auto DX11 fallback!
|
||||
bool fallbackFromDX11 = filterType == MotionBlurFilter.ReconstructionDX11 && dx11MotionBlurMaterial == null;
|
||||
|
||||
if (filterType == MotionBlurFilter.Reconstruction || fallbackFromDX11 || filterType == MotionBlurFilter.ReconstructionDisc) {
|
||||
maxVelocity = Mathf.Min (maxVelocity, MAX_RADIUS);
|
||||
tileWidth = divRoundUp (velBuffer.width, (int) maxVelocity);
|
||||
tileHeight = divRoundUp (velBuffer.height, (int) maxVelocity);
|
||||
_maxVelocity = velBuffer.width/tileWidth;
|
||||
}
|
||||
else {
|
||||
tileWidth = divRoundUp (velBuffer.width, (int) maxVelocity);
|
||||
tileHeight = divRoundUp (velBuffer.height, (int) maxVelocity);
|
||||
_maxVelocity = velBuffer.width/tileWidth;
|
||||
}
|
||||
|
||||
RenderTexture tileMax = RenderTexture.GetTemporary (tileWidth, tileHeight, 0, rtFormat);
|
||||
RenderTexture neighbourMax = RenderTexture.GetTemporary (tileWidth, tileHeight, 0, rtFormat);
|
||||
velBuffer.filterMode = FilterMode.Point;
|
||||
tileMax.filterMode = FilterMode.Point;
|
||||
neighbourMax.filterMode = FilterMode.Point;
|
||||
if (noiseTexture) noiseTexture.filterMode = FilterMode.Point;
|
||||
source.wrapMode = TextureWrapMode.Clamp;
|
||||
velBuffer.wrapMode = TextureWrapMode.Clamp;
|
||||
neighbourMax.wrapMode = TextureWrapMode.Clamp;
|
||||
tileMax.wrapMode = TextureWrapMode.Clamp;
|
||||
|
||||
// calc correct viewprj matrix
|
||||
CalculateViewProjection ();
|
||||
|
||||
// just started up?
|
||||
if (gameObject.activeInHierarchy && !wasActive) {
|
||||
Remember ();
|
||||
}
|
||||
wasActive = gameObject.activeInHierarchy;
|
||||
|
||||
// matrices
|
||||
Matrix4x4 invViewPrj = Matrix4x4.Inverse (currentViewProjMat);
|
||||
motionBlurMaterial.SetMatrix ("_InvViewProj", invViewPrj);
|
||||
motionBlurMaterial.SetMatrix ("_PrevViewProj", prevViewProjMat);
|
||||
motionBlurMaterial.SetMatrix ("_ToPrevViewProjCombined", prevViewProjMat * invViewPrj);
|
||||
|
||||
motionBlurMaterial.SetFloat ("_MaxVelocity", _maxVelocity);
|
||||
motionBlurMaterial.SetFloat ("_MaxRadiusOrKInPaper", _maxVelocity);
|
||||
motionBlurMaterial.SetFloat ("_MinVelocity", minVelocity);
|
||||
motionBlurMaterial.SetFloat ("_VelocityScale", velocityScale);
|
||||
motionBlurMaterial.SetFloat ("_Jitter", jitter);
|
||||
|
||||
// texture samplers
|
||||
motionBlurMaterial.SetTexture ("_NoiseTex", noiseTexture);
|
||||
motionBlurMaterial.SetTexture ("_VelTex", velBuffer);
|
||||
motionBlurMaterial.SetTexture ("_NeighbourMaxTex", neighbourMax);
|
||||
motionBlurMaterial.SetTexture ("_TileTexDebug", tileMax);
|
||||
|
||||
if (preview) {
|
||||
// generate an artifical 'previous' matrix to simulate blur look
|
||||
Matrix4x4 viewMat = _camera.worldToCameraMatrix;
|
||||
Matrix4x4 offset = Matrix4x4.identity;
|
||||
offset.SetTRS(previewScale * 0.3333f, Quaternion.identity, Vector3.one); // using only translation
|
||||
Matrix4x4 projMat = GL.GetGPUProjectionMatrix (_camera.projectionMatrix, true);
|
||||
prevViewProjMat = projMat * offset * viewMat;
|
||||
motionBlurMaterial.SetMatrix ("_PrevViewProj", prevViewProjMat);
|
||||
motionBlurMaterial.SetMatrix ("_ToPrevViewProjCombined", prevViewProjMat * invViewPrj);
|
||||
}
|
||||
|
||||
if (filterType == MotionBlurFilter.CameraMotion)
|
||||
{
|
||||
// build blur vector to be used in shader to create a global blur direction
|
||||
Vector4 blurVector = Vector4.zero;
|
||||
|
||||
float lookUpDown = Vector3.Dot (transform.up, Vector3.up);
|
||||
Vector3 distanceVector = prevFramePos-transform.position;
|
||||
|
||||
float distMag = distanceVector.magnitude;
|
||||
|
||||
float farHeur = 1.0f;
|
||||
|
||||
// pitch (vertical)
|
||||
farHeur = (Vector3.Angle (transform.up, prevFrameUp) / _camera.fieldOfView) * (source.width * 0.75f);
|
||||
blurVector.x = rotationScale * farHeur;//Mathf.Clamp01((1.0ff-Vector3.Dot(transform.up, prevFrameUp)));
|
||||
|
||||
// yaw #1 (horizontal, faded by pitch)
|
||||
farHeur = (Vector3.Angle (transform.forward, prevFrameForward) / _camera.fieldOfView) * (source.width * 0.75f);
|
||||
blurVector.y = rotationScale * lookUpDown * farHeur;//Mathf.Clamp01((1.0ff-Vector3.Dot(transform.forward, prevFrameForward)));
|
||||
|
||||
// yaw #2 (when looking down, faded by 1-pitch)
|
||||
farHeur = (Vector3.Angle (transform.forward, prevFrameForward) / _camera.fieldOfView) * (source.width * 0.75f);
|
||||
blurVector.z = rotationScale * (1.0f- lookUpDown) * farHeur;//Mathf.Clamp01((1.0ff-Vector3.Dot(transform.forward, prevFrameForward)));
|
||||
|
||||
if (distMag > Mathf.Epsilon && movementScale > Mathf.Epsilon) {
|
||||
// forward (probably most important)
|
||||
blurVector.w = movementScale * (Vector3.Dot (transform.forward, distanceVector) ) * (source.width * 0.5f);
|
||||
// jump (maybe scale down further)
|
||||
blurVector.x += movementScale * (Vector3.Dot (transform.up, distanceVector) ) * (source.width * 0.5f);
|
||||
// strafe (maybe scale down further)
|
||||
blurVector.y += movementScale * (Vector3.Dot (transform.right, distanceVector) ) * (source.width * 0.5f);
|
||||
}
|
||||
|
||||
if (preview) // crude approximation
|
||||
motionBlurMaterial.SetVector ("_BlurDirectionPacked", new Vector4 (previewScale.y, previewScale.x, 0.0f, previewScale.z) * 0.5f * _camera.fieldOfView);
|
||||
else
|
||||
motionBlurMaterial.SetVector ("_BlurDirectionPacked", blurVector);
|
||||
}
|
||||
else {
|
||||
// generate velocity buffer
|
||||
Graphics.Blit (source, velBuffer, motionBlurMaterial, 0);
|
||||
|
||||
// patch up velocity buffer:
|
||||
|
||||
// exclude certain layers (e.g. skinned objects as we cant really support that atm)
|
||||
|
||||
Camera cam = null;
|
||||
if (excludeLayers.value != 0)// || dynamicLayers.value)
|
||||
cam = GetTmpCam ();
|
||||
|
||||
if (cam && excludeLayers.value != 0 && replacementClear && replacementClear.isSupported) {
|
||||
cam.targetTexture = velBuffer;
|
||||
cam.cullingMask = excludeLayers;
|
||||
cam.RenderWithShader (replacementClear, "");
|
||||
}
|
||||
}
|
||||
|
||||
if (!preview && Time.frameCount != prevFrameCount) {
|
||||
// remember current transformation data for next frame
|
||||
prevFrameCount = Time.frameCount;
|
||||
Remember ();
|
||||
}
|
||||
|
||||
source.filterMode = FilterMode.Bilinear;
|
||||
|
||||
// debug vel buffer:
|
||||
if (showVelocity) {
|
||||
// generate tile max and neighbour max
|
||||
//Graphics.Blit (velBuffer, tileMax, motionBlurMaterial, 2);
|
||||
//Graphics.Blit (tileMax, neighbourMax, motionBlurMaterial, 3);
|
||||
motionBlurMaterial.SetFloat ("_DisplayVelocityScale", showVelocityScale);
|
||||
Graphics.Blit (velBuffer, destination, motionBlurMaterial, 1);
|
||||
}
|
||||
else {
|
||||
if (filterType == MotionBlurFilter.ReconstructionDX11 && !fallbackFromDX11) {
|
||||
// need to reset some parameters for dx11 shader
|
||||
dx11MotionBlurMaterial.SetFloat ("_MinVelocity", minVelocity);
|
||||
dx11MotionBlurMaterial.SetFloat ("_VelocityScale", velocityScale);
|
||||
dx11MotionBlurMaterial.SetFloat ("_Jitter", jitter);
|
||||
|
||||
// texture samplers
|
||||
dx11MotionBlurMaterial.SetTexture ("_NoiseTex", noiseTexture);
|
||||
dx11MotionBlurMaterial.SetTexture ("_VelTex", velBuffer);
|
||||
dx11MotionBlurMaterial.SetTexture ("_NeighbourMaxTex", neighbourMax);
|
||||
|
||||
dx11MotionBlurMaterial.SetFloat ("_SoftZDistance", Mathf.Max(0.00025f, softZDistance) );
|
||||
dx11MotionBlurMaterial.SetFloat ("_MaxRadiusOrKInPaper", _maxVelocity);
|
||||
|
||||
// generate tile max and neighbour max
|
||||
Graphics.Blit (velBuffer, tileMax, dx11MotionBlurMaterial, 0);
|
||||
Graphics.Blit (tileMax, neighbourMax, dx11MotionBlurMaterial, 1);
|
||||
|
||||
// final blur
|
||||
Graphics.Blit (source, destination, dx11MotionBlurMaterial, 2);
|
||||
}
|
||||
else if (filterType == MotionBlurFilter.Reconstruction || fallbackFromDX11) {
|
||||
// 'reconstructing' properly integrated color
|
||||
motionBlurMaterial.SetFloat ("_SoftZDistance", Mathf.Max(0.00025f, softZDistance) );
|
||||
|
||||
// generate tile max and neighbour max
|
||||
Graphics.Blit (velBuffer, tileMax, motionBlurMaterial, 2);
|
||||
Graphics.Blit (tileMax, neighbourMax, motionBlurMaterial, 3);
|
||||
|
||||
// final blur
|
||||
Graphics.Blit (source, destination, motionBlurMaterial, 4);
|
||||
}
|
||||
else if (filterType == MotionBlurFilter.CameraMotion) {
|
||||
// orange box style motion blur
|
||||
Graphics.Blit (source, destination, motionBlurMaterial, 6);
|
||||
}
|
||||
else if (filterType == MotionBlurFilter.ReconstructionDisc) {
|
||||
// dof style motion blur defocuing and ellipse around the princical blur direction
|
||||
// 'reconstructing' properly integrated color
|
||||
motionBlurMaterial.SetFloat ("_SoftZDistance", Mathf.Max(0.00025f, softZDistance) );
|
||||
|
||||
// generate tile max and neighbour max
|
||||
Graphics.Blit (velBuffer, tileMax, motionBlurMaterial, 2);
|
||||
Graphics.Blit (tileMax, neighbourMax, motionBlurMaterial, 3);
|
||||
|
||||
Graphics.Blit (source, destination, motionBlurMaterial, 7);
|
||||
}
|
||||
else {
|
||||
// simple & fast blur (low quality): just blurring along velocity
|
||||
Graphics.Blit (source, destination, motionBlurMaterial, 5);
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup
|
||||
RenderTexture.ReleaseTemporary (velBuffer);
|
||||
RenderTexture.ReleaseTemporary (tileMax);
|
||||
RenderTexture.ReleaseTemporary (neighbourMax);
|
||||
}
|
||||
|
||||
void Remember () {
|
||||
prevViewProjMat = currentViewProjMat;
|
||||
prevFrameForward = transform.forward;
|
||||
prevFrameUp = transform.up;
|
||||
prevFramePos = transform.position;
|
||||
}
|
||||
|
||||
Camera GetTmpCam () {
|
||||
if (tmpCam == null) {
|
||||
string name = "_" + _camera.name + "_MotionBlurTmpCam";
|
||||
GameObject go = GameObject.Find (name);
|
||||
if (null == go) // couldn't find, recreate
|
||||
tmpCam = new GameObject (name, typeof (Camera));
|
||||
else
|
||||
tmpCam = go;
|
||||
}
|
||||
|
||||
tmpCam.hideFlags = HideFlags.DontSave;
|
||||
tmpCam.transform.position = _camera.transform.position;
|
||||
tmpCam.transform.rotation = _camera.transform.rotation;
|
||||
tmpCam.transform.localScale = _camera.transform.localScale;
|
||||
tmpCam.GetComponent<Camera>().CopyFrom(_camera);
|
||||
|
||||
tmpCam.GetComponent<Camera>().enabled = false;
|
||||
tmpCam.GetComponent<Camera>().depthTextureMode = DepthTextureMode.None;
|
||||
tmpCam.GetComponent<Camera>().clearFlags = CameraClearFlags.Nothing;
|
||||
|
||||
return tmpCam.GetComponent<Camera>();
|
||||
}
|
||||
|
||||
void StartFrame () {
|
||||
// take only x% of positional changes into account (camera motion)
|
||||
// TODO: possibly do the same for rotational part
|
||||
prevFramePos = Vector3.Slerp(prevFramePos, transform.position, 0.75f);
|
||||
}
|
||||
|
||||
static int divRoundUp (int x, int d)
|
||||
{
|
||||
return (x + d - 1) / d;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 97e9b95cf609d96409b6c40519432957
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- shader: {fileID: 4800000, guid: 85a88efa8c871af4a9d17c64791b6f4f, type: 3}
|
||||
- dx11MotionBlurShader: {fileID: 4800000, guid: f1b13d7a80660504a858ea24cfa418c6,
|
||||
type: 3}
|
||||
- replacementClear: {fileID: 4800000, guid: 7699c5fbfa27745a1abe111ab7bf9785, type: 3}
|
||||
- noiseTexture: {fileID: 2800000, guid: 31f5a8611c4ed1245b18456206e798dc, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,181 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu ("Image Effects/Color Adjustments/Color Correction (Curves, Saturation)")]
|
||||
public class ColorCorrectionCurves : PostEffectsBase
|
||||
{
|
||||
public enum ColorCorrectionMode
|
||||
{
|
||||
Simple = 0,
|
||||
Advanced = 1
|
||||
}
|
||||
|
||||
public AnimationCurve redChannel = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
|
||||
public AnimationCurve greenChannel = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
|
||||
public AnimationCurve blueChannel = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
|
||||
|
||||
public bool useDepthCorrection = false;
|
||||
|
||||
public AnimationCurve zCurve = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
|
||||
public AnimationCurve depthRedChannel = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
|
||||
public AnimationCurve depthGreenChannel = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
|
||||
public AnimationCurve depthBlueChannel = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
|
||||
|
||||
private Material ccMaterial;
|
||||
private Material ccDepthMaterial;
|
||||
private Material selectiveCcMaterial;
|
||||
|
||||
private Texture2D rgbChannelTex;
|
||||
private Texture2D rgbDepthChannelTex;
|
||||
private Texture2D zCurveTex;
|
||||
|
||||
public float saturation = 1.0f;
|
||||
|
||||
public bool selectiveCc = false;
|
||||
|
||||
public Color selectiveFromColor = Color.white;
|
||||
public Color selectiveToColor = Color.white;
|
||||
|
||||
public ColorCorrectionMode mode;
|
||||
|
||||
public bool updateTextures = true;
|
||||
|
||||
public Shader colorCorrectionCurvesShader = null;
|
||||
public Shader simpleColorCorrectionCurvesShader = null;
|
||||
public Shader colorCorrectionSelectiveShader = null;
|
||||
|
||||
private bool updateTexturesOnStartup = true;
|
||||
|
||||
|
||||
new void Start ()
|
||||
{
|
||||
base.Start ();
|
||||
updateTexturesOnStartup = true;
|
||||
}
|
||||
|
||||
void Awake () { }
|
||||
|
||||
|
||||
public override bool CheckResources ()
|
||||
{
|
||||
CheckSupport (mode == ColorCorrectionMode.Advanced);
|
||||
|
||||
ccMaterial = CheckShaderAndCreateMaterial (simpleColorCorrectionCurvesShader, ccMaterial);
|
||||
ccDepthMaterial = CheckShaderAndCreateMaterial (colorCorrectionCurvesShader, ccDepthMaterial);
|
||||
selectiveCcMaterial = CheckShaderAndCreateMaterial (colorCorrectionSelectiveShader, selectiveCcMaterial);
|
||||
|
||||
if (!rgbChannelTex)
|
||||
rgbChannelTex = new Texture2D (256, 4, TextureFormat.ARGB32, false, true);
|
||||
if (!rgbDepthChannelTex)
|
||||
rgbDepthChannelTex = new Texture2D (256, 4, TextureFormat.ARGB32, false, true);
|
||||
if (!zCurveTex)
|
||||
zCurveTex = new Texture2D (256, 1, TextureFormat.ARGB32, false, true);
|
||||
|
||||
rgbChannelTex.hideFlags = HideFlags.DontSave;
|
||||
rgbDepthChannelTex.hideFlags = HideFlags.DontSave;
|
||||
zCurveTex.hideFlags = HideFlags.DontSave;
|
||||
|
||||
rgbChannelTex.wrapMode = TextureWrapMode.Clamp;
|
||||
rgbDepthChannelTex.wrapMode = TextureWrapMode.Clamp;
|
||||
zCurveTex.wrapMode = TextureWrapMode.Clamp;
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
public void UpdateParameters ()
|
||||
{
|
||||
CheckResources(); // textures might not be created if we're tweaking UI while disabled
|
||||
|
||||
if (redChannel != null && greenChannel != null && blueChannel != null)
|
||||
{
|
||||
for (float i = 0.0f; i <= 1.0f; i += 1.0f / 255.0f)
|
||||
{
|
||||
float rCh = Mathf.Clamp (redChannel.Evaluate(i), 0.0f, 1.0f);
|
||||
float gCh = Mathf.Clamp (greenChannel.Evaluate(i), 0.0f, 1.0f);
|
||||
float bCh = Mathf.Clamp (blueChannel.Evaluate(i), 0.0f, 1.0f);
|
||||
|
||||
rgbChannelTex.SetPixel ((int) Mathf.Floor(i*255.0f), 0, new Color(rCh,rCh,rCh) );
|
||||
rgbChannelTex.SetPixel ((int) Mathf.Floor(i*255.0f), 1, new Color(gCh,gCh,gCh) );
|
||||
rgbChannelTex.SetPixel ((int) Mathf.Floor(i*255.0f), 2, new Color(bCh,bCh,bCh) );
|
||||
|
||||
float zC = Mathf.Clamp (zCurve.Evaluate(i), 0.0f,1.0f);
|
||||
|
||||
zCurveTex.SetPixel ((int) Mathf.Floor(i*255.0f), 0, new Color(zC,zC,zC) );
|
||||
|
||||
rCh = Mathf.Clamp (depthRedChannel.Evaluate(i), 0.0f,1.0f);
|
||||
gCh = Mathf.Clamp (depthGreenChannel.Evaluate(i), 0.0f,1.0f);
|
||||
bCh = Mathf.Clamp (depthBlueChannel.Evaluate(i), 0.0f,1.0f);
|
||||
|
||||
rgbDepthChannelTex.SetPixel ((int) Mathf.Floor(i*255.0f), 0, new Color(rCh,rCh,rCh) );
|
||||
rgbDepthChannelTex.SetPixel ((int) Mathf.Floor(i*255.0f), 1, new Color(gCh,gCh,gCh) );
|
||||
rgbDepthChannelTex.SetPixel ((int) Mathf.Floor(i*255.0f), 2, new Color(bCh,bCh,bCh) );
|
||||
}
|
||||
|
||||
rgbChannelTex.Apply ();
|
||||
rgbDepthChannelTex.Apply ();
|
||||
zCurveTex.Apply ();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateTextures ()
|
||||
{
|
||||
UpdateParameters ();
|
||||
}
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources()==false)
|
||||
{
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
if (updateTexturesOnStartup)
|
||||
{
|
||||
UpdateParameters ();
|
||||
updateTexturesOnStartup = false;
|
||||
}
|
||||
|
||||
if (useDepthCorrection)
|
||||
GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;
|
||||
|
||||
RenderTexture renderTarget2Use = destination;
|
||||
|
||||
if (selectiveCc)
|
||||
{
|
||||
renderTarget2Use = RenderTexture.GetTemporary (source.width, source.height);
|
||||
}
|
||||
|
||||
if (useDepthCorrection)
|
||||
{
|
||||
ccDepthMaterial.SetTexture ("_RgbTex", rgbChannelTex);
|
||||
ccDepthMaterial.SetTexture ("_ZCurve", zCurveTex);
|
||||
ccDepthMaterial.SetTexture ("_RgbDepthTex", rgbDepthChannelTex);
|
||||
ccDepthMaterial.SetFloat ("_Saturation", saturation);
|
||||
|
||||
Graphics.Blit (source, renderTarget2Use, ccDepthMaterial);
|
||||
}
|
||||
else
|
||||
{
|
||||
ccMaterial.SetTexture ("_RgbTex", rgbChannelTex);
|
||||
ccMaterial.SetFloat ("_Saturation", saturation);
|
||||
|
||||
Graphics.Blit (source, renderTarget2Use, ccMaterial);
|
||||
}
|
||||
|
||||
if (selectiveCc)
|
||||
{
|
||||
selectiveCcMaterial.SetColor ("selColor", selectiveFromColor);
|
||||
selectiveCcMaterial.SetColor ("targetColor", selectiveToColor);
|
||||
Graphics.Blit (renderTarget2Use, destination, selectiveCcMaterial);
|
||||
|
||||
RenderTexture.ReleaseTemporary (renderTarget2Use);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1fd999d1b2cf94a45a5b0a47ce074bef
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- colorCorrectionCurvesShader: {fileID: 4800000, guid: 62bcade1028c24ca1a39760ed84b9487,
|
||||
type: 3}
|
||||
- simpleColorCorrectionCurvesShader: {fileID: 4800000, guid: 438ddd58d82c84d9eb1fdc56111702e1,
|
||||
type: 3}
|
||||
- colorCorrectionSelectiveShader: {fileID: 4800000, guid: e515e0f94cefc4c0db54b45cba621544,
|
||||
type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu ("Image Effects/Color Adjustments/Color Correction (3D Lookup Texture)")]
|
||||
public class ColorCorrectionLookup : PostEffectsBase
|
||||
{
|
||||
public Shader shader;
|
||||
private Material material;
|
||||
|
||||
// serialize this instead of having another 2d texture ref'ed
|
||||
public Texture3D converted3DLut = null;
|
||||
public string basedOnTempTex = "";
|
||||
|
||||
|
||||
public override bool CheckResources () {
|
||||
CheckSupport (false);
|
||||
|
||||
material = CheckShaderAndCreateMaterial (shader, material);
|
||||
|
||||
if (!isSupported || !SystemInfo.supports3DTextures)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnDisable () {
|
||||
if (material) {
|
||||
DestroyImmediate (material);
|
||||
material = null;
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestroy () {
|
||||
if (converted3DLut)
|
||||
DestroyImmediate (converted3DLut);
|
||||
converted3DLut = null;
|
||||
}
|
||||
|
||||
public void SetIdentityLut () {
|
||||
int dim = 16;
|
||||
var newC = new Color[dim*dim*dim];
|
||||
float oneOverDim = 1.0f / (1.0f * dim - 1.0f);
|
||||
|
||||
for(int i = 0; i < dim; i++) {
|
||||
for(int j = 0; j < dim; j++) {
|
||||
for(int k = 0; k < dim; k++) {
|
||||
newC[i + (j*dim) + (k*dim*dim)] = new Color((i*1.0f)*oneOverDim, (j*1.0f)*oneOverDim, (k*1.0f)*oneOverDim, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (converted3DLut)
|
||||
DestroyImmediate (converted3DLut);
|
||||
converted3DLut = new Texture3D (dim, dim, dim, TextureFormat.ARGB32, false);
|
||||
converted3DLut.SetPixels (newC);
|
||||
converted3DLut.Apply ();
|
||||
basedOnTempTex = "";
|
||||
}
|
||||
|
||||
public bool ValidDimensions ( Texture2D tex2d) {
|
||||
if (!tex2d) return false;
|
||||
int h = tex2d.height;
|
||||
if (h != Mathf.FloorToInt(Mathf.Sqrt(tex2d.width))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Convert ( Texture2D temp2DTex, string path) {
|
||||
|
||||
// conversion fun: the given 2D texture needs to be of the format
|
||||
// w * h, wheras h is the 'depth' (or 3d dimension 'dim') and w = dim * dim
|
||||
|
||||
if (temp2DTex) {
|
||||
int dim = temp2DTex.width * temp2DTex.height;
|
||||
dim = temp2DTex.height;
|
||||
|
||||
if (!ValidDimensions(temp2DTex)) {
|
||||
Debug.LogWarning ("The given 2D texture " + temp2DTex.name + " cannot be used as a 3D LUT.");
|
||||
basedOnTempTex = "";
|
||||
return;
|
||||
}
|
||||
|
||||
var c = temp2DTex.GetPixels();
|
||||
var newC = new Color[c.Length];
|
||||
|
||||
for(int i = 0; i < dim; i++) {
|
||||
for(int j = 0; j < dim; j++) {
|
||||
for(int k = 0; k < dim; k++) {
|
||||
int j_ = dim-j-1;
|
||||
newC[i + (j*dim) + (k*dim*dim)] = c[k*dim+i+j_*dim*dim];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (converted3DLut)
|
||||
DestroyImmediate (converted3DLut);
|
||||
converted3DLut = new Texture3D (dim, dim, dim, TextureFormat.ARGB32, false);
|
||||
converted3DLut.SetPixels (newC);
|
||||
converted3DLut.Apply ();
|
||||
basedOnTempTex = path;
|
||||
}
|
||||
else {
|
||||
// error, something went terribly wrong
|
||||
Debug.LogError ("Couldn't color correct with 3D LUT texture. Image Effect will be disabled.");
|
||||
}
|
||||
}
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
if (CheckResources () == false || !SystemInfo.supports3DTextures) {
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
if (converted3DLut == null) {
|
||||
SetIdentityLut ();
|
||||
}
|
||||
|
||||
int lutSize = converted3DLut.width;
|
||||
converted3DLut.wrapMode = TextureWrapMode.Clamp;
|
||||
material.SetFloat("_Scale", (lutSize - 1) / (1.0f*lutSize));
|
||||
material.SetFloat("_Offset", 1.0f / (2.0f * lutSize));
|
||||
material.SetTexture("_ClutTex", converted3DLut);
|
||||
|
||||
Graphics.Blit (source, destination, material, QualitySettings.activeColorSpace == ColorSpace.Linear ? 1 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8cde8c0fd649d9b46bb403ba5e157391
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- shader: {fileID: 4800000, guid: b61f0d8d8244b4b28aa66b0c8cb46a8d, type: 3}
|
||||
- converted3DLut: {instanceID: 0}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu("Image Effects/Color Adjustments/Color Correction (Ramp)")]
|
||||
public class ColorCorrectionRamp : ImageEffectBase {
|
||||
public Texture textureRamp;
|
||||
|
||||
// Called by camera to apply image effect
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
material.SetTexture ("_RampTex", textureRamp);
|
||||
Graphics.Blit (source, destination, material);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea59781cad112c75d0008dfa8d76c639
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- shader: {fileID: 4800000, guid: 67f8781cad112c75d0008dfa8d76c639, type: 3}
|
||||
- textureRamp: {fileID: 2800000, guid: d440902fad11e807d00044888d76c639, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(Camera))]
|
||||
[AddComponentMenu("Image Effects/Color Adjustments/Contrast Enhance (Unsharp Mask)")]
|
||||
public class ContrastEnhance : PostEffectsBase
|
||||
{
|
||||
[Range(0.0f, 1.0f)]
|
||||
public float intensity = 0.5f;
|
||||
[Range(0.0f,0.999f)]
|
||||
public float threshold = 0.0f;
|
||||
|
||||
private Material separableBlurMaterial;
|
||||
private Material contrastCompositeMaterial;
|
||||
|
||||
[Range(0.0f,1.0f)]
|
||||
public float blurSpread = 1.0f;
|
||||
|
||||
public Shader separableBlurShader = null;
|
||||
public Shader contrastCompositeShader = null;
|
||||
|
||||
|
||||
public override bool CheckResources ()
|
||||
{
|
||||
CheckSupport (false);
|
||||
|
||||
contrastCompositeMaterial = CheckShaderAndCreateMaterial (contrastCompositeShader, contrastCompositeMaterial);
|
||||
separableBlurMaterial = CheckShaderAndCreateMaterial (separableBlurShader, separableBlurMaterial);
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources()==false)
|
||||
{
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
int rtW = source.width;
|
||||
int rtH = source.height;
|
||||
|
||||
RenderTexture color2 = RenderTexture.GetTemporary (rtW/2, rtH/2, 0);
|
||||
|
||||
// downsample
|
||||
|
||||
Graphics.Blit (source, color2);
|
||||
RenderTexture color4a = RenderTexture.GetTemporary (rtW/4, rtH/4, 0);
|
||||
Graphics.Blit (color2, color4a);
|
||||
RenderTexture.ReleaseTemporary (color2);
|
||||
|
||||
// blur
|
||||
|
||||
separableBlurMaterial.SetVector ("offsets", new Vector4 (0.0f, (blurSpread * 1.0f) / color4a.height, 0.0f, 0.0f));
|
||||
RenderTexture color4b = RenderTexture.GetTemporary (rtW/4, rtH/4, 0);
|
||||
Graphics.Blit (color4a, color4b, separableBlurMaterial);
|
||||
RenderTexture.ReleaseTemporary (color4a);
|
||||
|
||||
separableBlurMaterial.SetVector ("offsets", new Vector4 ((blurSpread * 1.0f) / color4a.width, 0.0f, 0.0f, 0.0f));
|
||||
color4a = RenderTexture.GetTemporary (rtW/4, rtH/4, 0);
|
||||
Graphics.Blit (color4b, color4a, separableBlurMaterial);
|
||||
RenderTexture.ReleaseTemporary (color4b);
|
||||
|
||||
// composite
|
||||
|
||||
contrastCompositeMaterial.SetTexture ("_MainTexBlurred", color4a);
|
||||
contrastCompositeMaterial.SetFloat ("intensity", intensity);
|
||||
contrastCompositeMaterial.SetFloat ("threshold", threshold);
|
||||
Graphics.Blit (source, destination, contrastCompositeMaterial);
|
||||
|
||||
RenderTexture.ReleaseTemporary (color4a);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3309686a9fbbe6e42a182d5e0257704c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- separableBlurShader: {fileID: 4800000, guid: e97c14fbb5ea04c3a902cc533d7fc5d1,
|
||||
type: 3}
|
||||
- contrastCompositeShader: {fileID: 4800000, guid: 273404942eede4ea1883ca1fb2942507,
|
||||
type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,200 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu("Image Effects/Color Adjustments/Contrast Stretch")]
|
||||
public class ContrastStretch : MonoBehaviour
|
||||
{
|
||||
/// Adaptation speed - percents per frame, if playing at 30FPS.
|
||||
/// Default is 0.02 (2% each 1/30s).
|
||||
[Range(0.0001f, 1.0f)]
|
||||
public float adaptationSpeed = 0.02f;
|
||||
|
||||
/// If our scene is really dark (or really bright), we might not want to
|
||||
/// stretch its contrast to the full range.
|
||||
/// limitMinimum=0, limitMaximum=1 is the same as not applying the effect at all.
|
||||
/// limitMinimum=1, limitMaximum=0 is always stretching colors to full range.
|
||||
|
||||
/// The limit on the minimum luminance (0...1) - we won't go above this.
|
||||
[Range(0.0f,1.0f)]
|
||||
public float limitMinimum = 0.2f;
|
||||
|
||||
/// The limit on the maximum luminance (0...1) - we won't go below this.
|
||||
[Range(0.0f, 1.0f)]
|
||||
public float limitMaximum = 0.6f;
|
||||
|
||||
|
||||
// To maintain adaptation levels over time, we need two 1x1 render textures
|
||||
// and ping-pong between them.
|
||||
private RenderTexture[] adaptRenderTex = new RenderTexture[2];
|
||||
private int curAdaptIndex = 0;
|
||||
|
||||
|
||||
// Computes scene luminance (grayscale) image
|
||||
public Shader shaderLum;
|
||||
private Material m_materialLum;
|
||||
protected Material materialLum {
|
||||
get {
|
||||
if ( m_materialLum == null ) {
|
||||
m_materialLum = new Material(shaderLum);
|
||||
m_materialLum.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
return m_materialLum;
|
||||
}
|
||||
}
|
||||
|
||||
// Reduces size of the image by 2x2, while computing maximum/minimum values.
|
||||
// By repeatedly applying this shader, we reduce the initial luminance image
|
||||
// to 1x1 image with minimum/maximum luminances found.
|
||||
public Shader shaderReduce;
|
||||
private Material m_materialReduce;
|
||||
protected Material materialReduce {
|
||||
get {
|
||||
if ( m_materialReduce == null ) {
|
||||
m_materialReduce = new Material(shaderReduce);
|
||||
m_materialReduce.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
return m_materialReduce;
|
||||
}
|
||||
}
|
||||
|
||||
// Adaptation shader - gradually "adapts" minimum/maximum luminances,
|
||||
// based on currently adapted 1x1 image and the actual 1x1 image of the current scene.
|
||||
public Shader shaderAdapt;
|
||||
private Material m_materialAdapt;
|
||||
protected Material materialAdapt {
|
||||
get {
|
||||
if ( m_materialAdapt == null ) {
|
||||
m_materialAdapt = new Material(shaderAdapt);
|
||||
m_materialAdapt.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
return m_materialAdapt;
|
||||
}
|
||||
}
|
||||
|
||||
// Final pass - stretches the color values of the original scene, based on currently
|
||||
// adpated minimum/maximum values.
|
||||
public Shader shaderApply;
|
||||
private Material m_materialApply;
|
||||
protected Material materialApply {
|
||||
get {
|
||||
if ( m_materialApply == null ) {
|
||||
m_materialApply = new Material(shaderApply);
|
||||
m_materialApply.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
return m_materialApply;
|
||||
}
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
// Disable if we don't support image effects
|
||||
if (!SystemInfo.supportsImageEffects) {
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!shaderAdapt.isSupported || !shaderApply.isSupported || !shaderLum.isSupported || !shaderReduce.isSupported) {
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
for( int i = 0; i < 2; ++i )
|
||||
{
|
||||
if ( !adaptRenderTex[i] ) {
|
||||
adaptRenderTex[i] = new RenderTexture(1, 1, 0);
|
||||
adaptRenderTex[i].hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
for( int i = 0; i < 2; ++i )
|
||||
{
|
||||
DestroyImmediate( adaptRenderTex[i] );
|
||||
adaptRenderTex[i] = null;
|
||||
}
|
||||
if ( m_materialLum )
|
||||
DestroyImmediate( m_materialLum );
|
||||
if ( m_materialReduce )
|
||||
DestroyImmediate( m_materialReduce );
|
||||
if ( m_materialAdapt )
|
||||
DestroyImmediate( m_materialAdapt );
|
||||
if ( m_materialApply )
|
||||
DestroyImmediate( m_materialApply );
|
||||
}
|
||||
|
||||
|
||||
/// Apply the filter
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
// Blit to smaller RT and convert to luminance on the way
|
||||
const int TEMP_RATIO = 1; // 4x4 smaller
|
||||
RenderTexture rtTempSrc = RenderTexture.GetTemporary(source.width/TEMP_RATIO, source.height/TEMP_RATIO);
|
||||
Graphics.Blit (source, rtTempSrc, materialLum);
|
||||
|
||||
// Repeatedly reduce this image in size, computing min/max luminance values
|
||||
// In the end we'll have 1x1 image with min/max luminances found.
|
||||
const int FINAL_SIZE = 1;
|
||||
//const int FINAL_SIZE = 1;
|
||||
while( rtTempSrc.width > FINAL_SIZE || rtTempSrc.height > FINAL_SIZE )
|
||||
{
|
||||
const int REDUCE_RATIO = 2; // our shader does 2x2 reduction
|
||||
int destW = rtTempSrc.width / REDUCE_RATIO;
|
||||
if ( destW < FINAL_SIZE ) destW = FINAL_SIZE;
|
||||
int destH = rtTempSrc.height / REDUCE_RATIO;
|
||||
if ( destH < FINAL_SIZE ) destH = FINAL_SIZE;
|
||||
RenderTexture rtTempDst = RenderTexture.GetTemporary(destW,destH);
|
||||
Graphics.Blit (rtTempSrc, rtTempDst, materialReduce);
|
||||
|
||||
// Release old src temporary, and make new temporary the source
|
||||
RenderTexture.ReleaseTemporary( rtTempSrc );
|
||||
rtTempSrc = rtTempDst;
|
||||
}
|
||||
|
||||
// Update viewer's adaptation level
|
||||
CalculateAdaptation( rtTempSrc );
|
||||
|
||||
// Apply contrast strech to the original scene, using currently adapted parameters
|
||||
materialApply.SetTexture("_AdaptTex", adaptRenderTex[curAdaptIndex] );
|
||||
Graphics.Blit (source, destination, materialApply);
|
||||
|
||||
RenderTexture.ReleaseTemporary( rtTempSrc );
|
||||
}
|
||||
|
||||
|
||||
/// Helper function to do gradual adaptation to min/max luminances
|
||||
private void CalculateAdaptation( Texture curTexture )
|
||||
{
|
||||
int prevAdaptIndex = curAdaptIndex;
|
||||
curAdaptIndex = (curAdaptIndex+1) % 2;
|
||||
|
||||
// Adaptation speed is expressed in percents/frame, based on 30FPS.
|
||||
// Calculate the adaptation lerp, based on current FPS.
|
||||
float adaptLerp = 1.0f - Mathf.Pow( 1.0f - adaptationSpeed, 30.0f * Time.deltaTime );
|
||||
const float kMinAdaptLerp = 0.01f;
|
||||
adaptLerp = Mathf.Clamp( adaptLerp, kMinAdaptLerp, 1 );
|
||||
|
||||
materialAdapt.SetTexture("_CurTex", curTexture );
|
||||
materialAdapt.SetVector("_AdaptParams", new Vector4(
|
||||
adaptLerp,
|
||||
limitMinimum,
|
||||
limitMaximum,
|
||||
0.0f
|
||||
));
|
||||
// clear destination RT so its contents don't need to be restored
|
||||
Graphics.SetRenderTarget(adaptRenderTex[curAdaptIndex]);
|
||||
GL.Clear(false, true, Color.black);
|
||||
Graphics.Blit (
|
||||
adaptRenderTex[prevAdaptIndex],
|
||||
adaptRenderTex[curAdaptIndex],
|
||||
materialAdapt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec92b071d2d424aecb3e46f28eb63174
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- shaderLum: {fileID: 4800000, guid: befbb4b9c320b4b18a08ef7afb93b6c9, type: 3}
|
||||
- shaderReduce: {fileID: 4800000, guid: 57b33a14b6d5347c5a85c36f6cb3b280, type: 3}
|
||||
- shaderAdapt: {fileID: 4800000, guid: 257bc83cbeb544540bd0e558aa9b1383, type: 3}
|
||||
- shaderApply: {fileID: 4800000, guid: f4901f25d4e1542589348bbb89563d8e, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Edge Detection/Crease Shading")]
|
||||
public class CreaseShading : PostEffectsBase
|
||||
{
|
||||
public float intensity = 0.5f;
|
||||
public int softness = 1;
|
||||
public float spread = 1.0f;
|
||||
|
||||
public Shader blurShader = null;
|
||||
private Material blurMaterial = null;
|
||||
|
||||
public Shader depthFetchShader = null;
|
||||
private Material depthFetchMaterial = null;
|
||||
|
||||
public Shader creaseApplyShader = null;
|
||||
private Material creaseApplyMaterial = null;
|
||||
|
||||
|
||||
public override bool CheckResources ()
|
||||
{
|
||||
CheckSupport (true);
|
||||
|
||||
blurMaterial = CheckShaderAndCreateMaterial (blurShader, blurMaterial);
|
||||
depthFetchMaterial = CheckShaderAndCreateMaterial (depthFetchShader, depthFetchMaterial);
|
||||
creaseApplyMaterial = CheckShaderAndCreateMaterial (creaseApplyShader, creaseApplyMaterial);
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources()==false)
|
||||
{
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
int rtW = source.width;
|
||||
int rtH = source.height;
|
||||
|
||||
float widthOverHeight = (1.0f * rtW) / (1.0f * rtH);
|
||||
float oneOverBaseSize = 1.0f / 512.0f;
|
||||
|
||||
RenderTexture hrTex = RenderTexture.GetTemporary (rtW, rtH, 0);
|
||||
RenderTexture lrTex1 = RenderTexture.GetTemporary (rtW/2, rtH/2, 0);
|
||||
|
||||
Graphics.Blit (source,hrTex, depthFetchMaterial);
|
||||
Graphics.Blit (hrTex, lrTex1);
|
||||
|
||||
for(int i = 0; i < softness; i++)
|
||||
{
|
||||
RenderTexture lrTex2 = RenderTexture.GetTemporary (rtW/2, rtH/2, 0);
|
||||
blurMaterial.SetVector ("offsets", new Vector4 (0.0f, spread * oneOverBaseSize, 0.0f, 0.0f));
|
||||
Graphics.Blit (lrTex1, lrTex2, blurMaterial);
|
||||
RenderTexture.ReleaseTemporary (lrTex1);
|
||||
lrTex1 = lrTex2;
|
||||
|
||||
lrTex2 = RenderTexture.GetTemporary (rtW/2, rtH/2, 0);
|
||||
blurMaterial.SetVector ("offsets", new Vector4 (spread * oneOverBaseSize / widthOverHeight, 0.0f, 0.0f, 0.0f));
|
||||
Graphics.Blit (lrTex1, lrTex2, blurMaterial);
|
||||
RenderTexture.ReleaseTemporary (lrTex1);
|
||||
lrTex1 = lrTex2;
|
||||
}
|
||||
|
||||
creaseApplyMaterial.SetTexture ("_HrDepthTex", hrTex);
|
||||
creaseApplyMaterial.SetTexture ("_LrDepthTex", lrTex1);
|
||||
creaseApplyMaterial.SetFloat ("intensity", intensity);
|
||||
Graphics.Blit (source,destination, creaseApplyMaterial);
|
||||
|
||||
RenderTexture.ReleaseTemporary (hrTex);
|
||||
RenderTexture.ReleaseTemporary (lrTex1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d64b4f3a592f28b44bf19223ac8b6cd2
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- blurShader: {fileID: 4800000, guid: e97c14fbb5ea04c3a902cc533d7fc5d1, type: 3}
|
||||
- depthFetchShader: {fileID: 4800000, guid: 14768d3865b1342e3a861fbe19ba2db2, type: 3}
|
||||
- creaseApplyShader: {fileID: 4800000, guid: b59984d82af624bd3b0c777f038276f2, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,387 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Camera/Depth of Field (Lens Blur, Scatter, DX11)") ]
|
||||
public class DepthOfField : PostEffectsBase {
|
||||
|
||||
public bool visualizeFocus = false;
|
||||
public float focalLength = 10.0f;
|
||||
public float focalSize = 0.05f;
|
||||
public float aperture = 0.5f;
|
||||
public Transform focalTransform = null;
|
||||
public float maxBlurSize = 2.0f;
|
||||
public bool highResolution = false;
|
||||
|
||||
public enum BlurType {
|
||||
DiscBlur = 0,
|
||||
DX11 = 1,
|
||||
}
|
||||
|
||||
public enum BlurSampleCount {
|
||||
Low = 0,
|
||||
Medium = 1,
|
||||
High = 2,
|
||||
}
|
||||
|
||||
public BlurType blurType = BlurType.DiscBlur;
|
||||
public BlurSampleCount blurSampleCount = BlurSampleCount.High;
|
||||
|
||||
public bool nearBlur = false;
|
||||
public float foregroundOverlap = 1.0f;
|
||||
|
||||
public Shader dofHdrShader;
|
||||
private Material dofHdrMaterial = null;
|
||||
|
||||
public Shader dx11BokehShader;
|
||||
private Material dx11bokehMaterial;
|
||||
|
||||
public float dx11BokehThreshold = 0.5f;
|
||||
public float dx11SpawnHeuristic = 0.0875f;
|
||||
public Texture2D dx11BokehTexture = null;
|
||||
public float dx11BokehScale = 1.2f;
|
||||
public float dx11BokehIntensity = 2.5f;
|
||||
|
||||
private float focalDistance01 = 10.0f;
|
||||
private ComputeBuffer cbDrawArgs;
|
||||
private ComputeBuffer cbPoints;
|
||||
private float internalBlurWidth = 1.0f;
|
||||
|
||||
private Camera cachedCamera;
|
||||
|
||||
public override bool CheckResources () {
|
||||
CheckSupport (true); // only requires depth, not HDR
|
||||
|
||||
dofHdrMaterial = CheckShaderAndCreateMaterial (dofHdrShader, dofHdrMaterial);
|
||||
if (supportDX11 && blurType == BlurType.DX11) {
|
||||
dx11bokehMaterial = CheckShaderAndCreateMaterial(dx11BokehShader, dx11bokehMaterial);
|
||||
CreateComputeResources ();
|
||||
}
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnEnable () {
|
||||
cachedCamera = GetComponent<Camera>();
|
||||
cachedCamera.depthTextureMode |= DepthTextureMode.Depth;
|
||||
}
|
||||
|
||||
void OnDisable () {
|
||||
ReleaseComputeResources ();
|
||||
|
||||
if (dofHdrMaterial) DestroyImmediate(dofHdrMaterial);
|
||||
dofHdrMaterial = null;
|
||||
if (dx11bokehMaterial) DestroyImmediate(dx11bokehMaterial);
|
||||
dx11bokehMaterial = null;
|
||||
}
|
||||
|
||||
void ReleaseComputeResources () {
|
||||
if (cbDrawArgs != null) cbDrawArgs.Release();
|
||||
cbDrawArgs = null;
|
||||
if (cbPoints != null) cbPoints.Release();
|
||||
cbPoints = null;
|
||||
}
|
||||
|
||||
void CreateComputeResources () {
|
||||
if (cbDrawArgs == null)
|
||||
{
|
||||
cbDrawArgs = new ComputeBuffer (1, 16, ComputeBufferType.IndirectArguments);
|
||||
var args= new int[4];
|
||||
args[0] = 0; args[1] = 1; args[2] = 0; args[3] = 0;
|
||||
cbDrawArgs.SetData (args);
|
||||
}
|
||||
if (cbPoints == null)
|
||||
{
|
||||
cbPoints = new ComputeBuffer (90000, 12+16, ComputeBufferType.Append);
|
||||
}
|
||||
}
|
||||
|
||||
float FocalDistance01 ( float worldDist) {
|
||||
return cachedCamera.WorldToViewportPoint((worldDist-cachedCamera.nearClipPlane) * cachedCamera.transform.forward + cachedCamera.transform.position).z / (cachedCamera.farClipPlane-cachedCamera.nearClipPlane);
|
||||
}
|
||||
|
||||
private void WriteCoc ( RenderTexture fromTo, bool fgDilate) {
|
||||
dofHdrMaterial.SetTexture("_FgOverlap", null);
|
||||
|
||||
if (nearBlur && fgDilate) {
|
||||
|
||||
int rtW = fromTo.width/2;
|
||||
int rtH = fromTo.height/2;
|
||||
|
||||
// capture fg coc
|
||||
RenderTexture temp2 = RenderTexture.GetTemporary (rtW, rtH, 0, fromTo.format);
|
||||
Graphics.Blit (fromTo, temp2, dofHdrMaterial, 4);
|
||||
|
||||
// special blur
|
||||
float fgAdjustment = internalBlurWidth * foregroundOverlap;
|
||||
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (0.0f, fgAdjustment , 0.0f, fgAdjustment));
|
||||
RenderTexture temp1 = RenderTexture.GetTemporary (rtW, rtH, 0, fromTo.format);
|
||||
Graphics.Blit (temp2, temp1, dofHdrMaterial, 2);
|
||||
RenderTexture.ReleaseTemporary(temp2);
|
||||
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (fgAdjustment, 0.0f, 0.0f, fgAdjustment));
|
||||
temp2 = RenderTexture.GetTemporary (rtW, rtH, 0, fromTo.format);
|
||||
Graphics.Blit (temp1, temp2, dofHdrMaterial, 2);
|
||||
RenderTexture.ReleaseTemporary(temp1);
|
||||
|
||||
// "merge up" with background COC
|
||||
dofHdrMaterial.SetTexture("_FgOverlap", temp2);
|
||||
fromTo.MarkRestoreExpected(); // only touching alpha channel, RT restore expected
|
||||
Graphics.Blit (fromTo, fromTo, dofHdrMaterial, 13);
|
||||
RenderTexture.ReleaseTemporary(temp2);
|
||||
}
|
||||
else {
|
||||
// capture full coc in alpha channel (fromTo is not read, but bound to detect screen flip)
|
||||
fromTo.MarkRestoreExpected(); // only touching alpha channel, RT restore expected
|
||||
Graphics.Blit (fromTo, fromTo, dofHdrMaterial, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
if (!CheckResources ()) {
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
// clamp & prepare values so they make sense
|
||||
|
||||
if (aperture < 0.0f) aperture = 0.0f;
|
||||
if (maxBlurSize < 0.1f) maxBlurSize = 0.1f;
|
||||
focalSize = Mathf.Clamp(focalSize, 0.0f, 2.0f);
|
||||
internalBlurWidth = Mathf.Max(maxBlurSize, 0.0f);
|
||||
|
||||
// focal & coc calculations
|
||||
|
||||
focalDistance01 = (focalTransform) ? (cachedCamera.WorldToViewportPoint (focalTransform.position)).z / (cachedCamera.farClipPlane) : FocalDistance01 (focalLength);
|
||||
dofHdrMaterial.SetVector("_CurveParams", new Vector4(1.0f, focalSize, (1.0f / (1.0f - aperture) - 1.0f), focalDistance01));
|
||||
|
||||
// possible render texture helpers
|
||||
|
||||
RenderTexture rtLow = null;
|
||||
RenderTexture rtLow2 = null;
|
||||
RenderTexture rtSuperLow1 = null;
|
||||
RenderTexture rtSuperLow2 = null;
|
||||
float fgBlurDist = internalBlurWidth * foregroundOverlap;
|
||||
|
||||
if (visualizeFocus)
|
||||
{
|
||||
|
||||
//
|
||||
// 2.
|
||||
// visualize coc
|
||||
//
|
||||
//
|
||||
|
||||
WriteCoc (source, true);
|
||||
Graphics.Blit (source, destination, dofHdrMaterial, 16);
|
||||
}
|
||||
else if ((blurType == BlurType.DX11) && dx11bokehMaterial)
|
||||
{
|
||||
|
||||
//
|
||||
// 1.
|
||||
// optimized dx11 bokeh scatter
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
if (highResolution) {
|
||||
|
||||
internalBlurWidth = internalBlurWidth < 0.1f ? 0.1f : internalBlurWidth;
|
||||
fgBlurDist = internalBlurWidth * foregroundOverlap;
|
||||
|
||||
rtLow = RenderTexture.GetTemporary (source.width, source.height, 0, source.format);
|
||||
|
||||
var dest2= RenderTexture.GetTemporary (source.width, source.height, 0, source.format);
|
||||
|
||||
// capture COC
|
||||
WriteCoc (source, false);
|
||||
|
||||
// blur a bit so we can do a frequency check
|
||||
rtSuperLow1 = RenderTexture.GetTemporary(source.width>>1, source.height>>1, 0, source.format);
|
||||
rtSuperLow2 = RenderTexture.GetTemporary(source.width>>1, source.height>>1, 0, source.format);
|
||||
|
||||
Graphics.Blit(source, rtSuperLow1, dofHdrMaterial, 15);
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (0.0f, 1.5f , 0.0f, 1.5f));
|
||||
Graphics.Blit (rtSuperLow1, rtSuperLow2, dofHdrMaterial, 19);
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (1.5f, 0.0f, 0.0f, 1.5f));
|
||||
Graphics.Blit (rtSuperLow2, rtSuperLow1, dofHdrMaterial, 19);
|
||||
|
||||
// capture fg coc
|
||||
if (nearBlur)
|
||||
Graphics.Blit (source, rtSuperLow2, dofHdrMaterial, 4);
|
||||
|
||||
dx11bokehMaterial.SetTexture ("_BlurredColor", rtSuperLow1);
|
||||
dx11bokehMaterial.SetFloat ("_SpawnHeuristic", dx11SpawnHeuristic);
|
||||
dx11bokehMaterial.SetVector ("_BokehParams", new Vector4(dx11BokehScale, dx11BokehIntensity, Mathf.Clamp(dx11BokehThreshold, 0.005f, 4.0f), internalBlurWidth));
|
||||
dx11bokehMaterial.SetTexture ("_FgCocMask", nearBlur ? rtSuperLow2 : null);
|
||||
|
||||
// collect bokeh candidates and replace with a darker pixel
|
||||
Graphics.SetRandomWriteTarget (1, cbPoints);
|
||||
Graphics.Blit (source, rtLow, dx11bokehMaterial, 0);
|
||||
Graphics.ClearRandomWriteTargets ();
|
||||
|
||||
// fg coc blur happens here (after collect!)
|
||||
if (nearBlur) {
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (0.0f, fgBlurDist , 0.0f, fgBlurDist));
|
||||
Graphics.Blit (rtSuperLow2, rtSuperLow1, dofHdrMaterial, 2);
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (fgBlurDist, 0.0f, 0.0f, fgBlurDist));
|
||||
Graphics.Blit (rtSuperLow1, rtSuperLow2, dofHdrMaterial, 2);
|
||||
|
||||
// merge fg coc with bg coc
|
||||
Graphics.Blit (rtSuperLow2, rtLow, dofHdrMaterial, 3);
|
||||
}
|
||||
|
||||
// NEW: LAY OUT ALPHA on destination target so we get nicer outlines for the high rez version
|
||||
Graphics.Blit (rtLow, dest2, dofHdrMaterial, 20);
|
||||
|
||||
// box blur (easier to merge with bokeh buffer)
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (internalBlurWidth, 0.0f , 0.0f, internalBlurWidth));
|
||||
Graphics.Blit (rtLow, source, dofHdrMaterial, 5);
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (0.0f, internalBlurWidth, 0.0f, internalBlurWidth));
|
||||
Graphics.Blit (source, dest2, dofHdrMaterial, 21);
|
||||
|
||||
// apply bokeh candidates
|
||||
Graphics.SetRenderTarget (dest2);
|
||||
ComputeBuffer.CopyCount (cbPoints, cbDrawArgs, 0);
|
||||
dx11bokehMaterial.SetBuffer ("pointBuffer", cbPoints);
|
||||
dx11bokehMaterial.SetTexture ("_MainTex", dx11BokehTexture);
|
||||
dx11bokehMaterial.SetVector ("_Screen", new Vector3(1.0f/(1.0f*source.width), 1.0f/(1.0f*source.height), internalBlurWidth));
|
||||
dx11bokehMaterial.SetPass (2);
|
||||
|
||||
Graphics.DrawProceduralIndirect (MeshTopology.Points, cbDrawArgs, 0);
|
||||
|
||||
Graphics.Blit (dest2, destination); // hackaround for DX11 high resolution flipfun (OPTIMIZEME)
|
||||
|
||||
RenderTexture.ReleaseTemporary(dest2);
|
||||
RenderTexture.ReleaseTemporary(rtSuperLow1);
|
||||
RenderTexture.ReleaseTemporary(rtSuperLow2);
|
||||
}
|
||||
else {
|
||||
rtLow = RenderTexture.GetTemporary (source.width>>1, source.height>>1, 0, source.format);
|
||||
rtLow2 = RenderTexture.GetTemporary (source.width>>1, source.height>>1, 0, source.format);
|
||||
|
||||
fgBlurDist = internalBlurWidth * foregroundOverlap;
|
||||
|
||||
// capture COC & color in low resolution
|
||||
WriteCoc (source, false);
|
||||
source.filterMode = FilterMode.Bilinear;
|
||||
Graphics.Blit (source, rtLow, dofHdrMaterial, 6);
|
||||
|
||||
// blur a bit so we can do a frequency check
|
||||
rtSuperLow1 = RenderTexture.GetTemporary(rtLow.width>>1, rtLow.height>>1, 0, rtLow.format);
|
||||
rtSuperLow2 = RenderTexture.GetTemporary(rtLow.width>>1, rtLow.height>>1, 0, rtLow.format);
|
||||
|
||||
Graphics.Blit(rtLow, rtSuperLow1, dofHdrMaterial, 15);
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (0.0f, 1.5f , 0.0f, 1.5f));
|
||||
Graphics.Blit (rtSuperLow1, rtSuperLow2, dofHdrMaterial, 19);
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (1.5f, 0.0f, 0.0f, 1.5f));
|
||||
Graphics.Blit (rtSuperLow2, rtSuperLow1, dofHdrMaterial, 19);
|
||||
|
||||
RenderTexture rtLow3 = null;
|
||||
|
||||
if (nearBlur) {
|
||||
// capture fg coc
|
||||
rtLow3 = RenderTexture.GetTemporary (source.width>>1, source.height>>1, 0, source.format);
|
||||
Graphics.Blit (source, rtLow3, dofHdrMaterial, 4);
|
||||
}
|
||||
|
||||
dx11bokehMaterial.SetTexture ("_BlurredColor", rtSuperLow1);
|
||||
dx11bokehMaterial.SetFloat ("_SpawnHeuristic", dx11SpawnHeuristic);
|
||||
dx11bokehMaterial.SetVector ("_BokehParams", new Vector4(dx11BokehScale, dx11BokehIntensity, Mathf.Clamp(dx11BokehThreshold, 0.005f, 4.0f), internalBlurWidth));
|
||||
dx11bokehMaterial.SetTexture ("_FgCocMask", rtLow3);
|
||||
|
||||
// collect bokeh candidates and replace with a darker pixel
|
||||
Graphics.SetRandomWriteTarget (1, cbPoints);
|
||||
Graphics.Blit (rtLow, rtLow2, dx11bokehMaterial, 0);
|
||||
Graphics.ClearRandomWriteTargets ();
|
||||
|
||||
RenderTexture.ReleaseTemporary(rtSuperLow1);
|
||||
RenderTexture.ReleaseTemporary(rtSuperLow2);
|
||||
|
||||
// fg coc blur happens here (after collect!)
|
||||
if (nearBlur) {
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (0.0f, fgBlurDist , 0.0f, fgBlurDist));
|
||||
Graphics.Blit (rtLow3, rtLow, dofHdrMaterial, 2);
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (fgBlurDist, 0.0f, 0.0f, fgBlurDist));
|
||||
Graphics.Blit (rtLow, rtLow3, dofHdrMaterial, 2);
|
||||
|
||||
// merge fg coc with bg coc
|
||||
Graphics.Blit (rtLow3, rtLow2, dofHdrMaterial, 3);
|
||||
}
|
||||
|
||||
// box blur (easier to merge with bokeh buffer)
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (internalBlurWidth, 0.0f , 0.0f, internalBlurWidth));
|
||||
Graphics.Blit (rtLow2, rtLow, dofHdrMaterial, 5);
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (0.0f, internalBlurWidth, 0.0f, internalBlurWidth));
|
||||
Graphics.Blit (rtLow, rtLow2, dofHdrMaterial, 5);
|
||||
|
||||
// apply bokeh candidates
|
||||
Graphics.SetRenderTarget (rtLow2);
|
||||
ComputeBuffer.CopyCount (cbPoints, cbDrawArgs, 0);
|
||||
dx11bokehMaterial.SetBuffer ("pointBuffer", cbPoints);
|
||||
dx11bokehMaterial.SetTexture ("_MainTex", dx11BokehTexture);
|
||||
dx11bokehMaterial.SetVector ("_Screen", new Vector3(1.0f/(1.0f*rtLow2.width), 1.0f/(1.0f*rtLow2.height), internalBlurWidth));
|
||||
dx11bokehMaterial.SetPass (1);
|
||||
Graphics.DrawProceduralIndirect (MeshTopology.Points, cbDrawArgs, 0);
|
||||
|
||||
// upsample & combine
|
||||
dofHdrMaterial.SetTexture ("_LowRez", rtLow2);
|
||||
dofHdrMaterial.SetTexture ("_FgOverlap", rtLow3);
|
||||
dofHdrMaterial.SetVector ("_Offsets", ((1.0f*source.width)/(1.0f*rtLow2.width)) * internalBlurWidth * Vector4.one);
|
||||
Graphics.Blit (source, destination, dofHdrMaterial, 9);
|
||||
|
||||
if (rtLow3) RenderTexture.ReleaseTemporary(rtLow3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//
|
||||
// 2.
|
||||
// poisson disc style blur in low resolution
|
||||
//
|
||||
//
|
||||
|
||||
source.filterMode = FilterMode.Bilinear;
|
||||
|
||||
if (highResolution) internalBlurWidth *= 2.0f;
|
||||
|
||||
WriteCoc (source, true);
|
||||
|
||||
rtLow = RenderTexture.GetTemporary (source.width >> 1, source.height >> 1, 0, source.format);
|
||||
rtLow2 = RenderTexture.GetTemporary (source.width >> 1, source.height >> 1, 0, source.format);
|
||||
|
||||
int blurPass = (blurSampleCount == BlurSampleCount.High || blurSampleCount == BlurSampleCount.Medium) ? 17 : 11;
|
||||
|
||||
if (highResolution) {
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (0.0f, internalBlurWidth, 0.025f, internalBlurWidth));
|
||||
Graphics.Blit (source, destination, dofHdrMaterial, blurPass);
|
||||
}
|
||||
else {
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (0.0f, internalBlurWidth, 0.1f, internalBlurWidth));
|
||||
|
||||
// blur
|
||||
Graphics.Blit (source, rtLow, dofHdrMaterial, 6);
|
||||
Graphics.Blit (rtLow, rtLow2, dofHdrMaterial, blurPass);
|
||||
|
||||
// cheaper blur in high resolution, upsample and combine
|
||||
dofHdrMaterial.SetTexture("_LowRez", rtLow2);
|
||||
dofHdrMaterial.SetTexture("_FgOverlap", null);
|
||||
dofHdrMaterial.SetVector ("_Offsets", Vector4.one * ((1.0f*source.width)/(1.0f*rtLow2.width)) * internalBlurWidth);
|
||||
Graphics.Blit (source, destination, dofHdrMaterial, blurSampleCount == BlurSampleCount.High ? 18 : 12);
|
||||
}
|
||||
}
|
||||
|
||||
if (rtLow) RenderTexture.ReleaseTemporary(rtLow);
|
||||
if (rtLow2) RenderTexture.ReleaseTemporary(rtLow2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd70d448b18cfbc46af26466f752332c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- focalTransform: {instanceID: 0}
|
||||
- dofHdrShader: {fileID: 4800000, guid: acd613035ff3e455e8abf23fdc8c8c24, type: 3}
|
||||
- dx11BokehShader: {fileID: 4800000, guid: d8e82664aa8686642a424c88ab10164a, type: 3}
|
||||
- dx11BokehTexture: {fileID: 2800000, guid: a4cdca73d61814d33ac1587f6c163bca, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,427 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Camera/Depth of Field (deprecated)") ]
|
||||
public class DepthOfFieldDeprecated : PostEffectsBase
|
||||
{
|
||||
public enum Dof34QualitySetting
|
||||
{
|
||||
OnlyBackground = 1,
|
||||
BackgroundAndForeground = 2,
|
||||
}
|
||||
|
||||
public enum DofResolution
|
||||
{
|
||||
High = 2,
|
||||
Medium = 3,
|
||||
Low = 4,
|
||||
}
|
||||
|
||||
public enum DofBlurriness
|
||||
{
|
||||
Low = 1,
|
||||
High = 2,
|
||||
VeryHigh = 4,
|
||||
}
|
||||
|
||||
public enum BokehDestination
|
||||
{
|
||||
Background = 0x1,
|
||||
Foreground = 0x2,
|
||||
BackgroundAndForeground = 0x3,
|
||||
}
|
||||
|
||||
static private int SMOOTH_DOWNSAMPLE_PASS = 6;
|
||||
static private float BOKEH_EXTRA_BLUR = 2.0f;
|
||||
|
||||
public Dof34QualitySetting quality = Dof34QualitySetting.OnlyBackground;
|
||||
public DofResolution resolution = DofResolution.Low;
|
||||
public bool simpleTweakMode = true;
|
||||
|
||||
public float focalPoint = 1.0f;
|
||||
public float smoothness = 0.5f;
|
||||
|
||||
public float focalZDistance = 0.0f;
|
||||
public float focalZStartCurve = 1.0f;
|
||||
public float focalZEndCurve = 1.0f;
|
||||
|
||||
private float focalStartCurve = 2.0f;
|
||||
private float focalEndCurve = 2.0f;
|
||||
private float focalDistance01 = 0.1f;
|
||||
|
||||
public Transform objectFocus = null;
|
||||
public float focalSize = 0.0f;
|
||||
|
||||
public DofBlurriness bluriness = DofBlurriness.High;
|
||||
public float maxBlurSpread = 1.75f;
|
||||
|
||||
public float foregroundBlurExtrude = 1.15f;
|
||||
|
||||
public Shader dofBlurShader;
|
||||
private Material dofBlurMaterial = null;
|
||||
|
||||
public Shader dofShader;
|
||||
private Material dofMaterial = null;
|
||||
|
||||
public bool visualize = false;
|
||||
public BokehDestination bokehDestination = BokehDestination.Background;
|
||||
|
||||
private float widthOverHeight = 1.25f;
|
||||
private float oneOverBaseSize = 1.0f / 512.0f;
|
||||
|
||||
public bool bokeh = false;
|
||||
public bool bokehSupport = true;
|
||||
public Shader bokehShader;
|
||||
public Texture2D bokehTexture;
|
||||
public float bokehScale = 2.4f;
|
||||
public float bokehIntensity = 0.15f;
|
||||
public float bokehThresholdContrast = 0.1f;
|
||||
public float bokehThresholdLuminance = 0.55f;
|
||||
public int bokehDownsample = 1;
|
||||
private Material bokehMaterial;
|
||||
|
||||
private Camera _camera;
|
||||
|
||||
void CreateMaterials () {
|
||||
dofBlurMaterial = CheckShaderAndCreateMaterial (dofBlurShader, dofBlurMaterial);
|
||||
dofMaterial = CheckShaderAndCreateMaterial (dofShader,dofMaterial);
|
||||
bokehSupport = bokehShader.isSupported;
|
||||
|
||||
if (bokeh && bokehSupport && bokehShader)
|
||||
bokehMaterial = CheckShaderAndCreateMaterial (bokehShader, bokehMaterial);
|
||||
}
|
||||
|
||||
|
||||
public override bool CheckResources () {
|
||||
CheckSupport (true);
|
||||
|
||||
dofBlurMaterial = CheckShaderAndCreateMaterial (dofBlurShader, dofBlurMaterial);
|
||||
dofMaterial = CheckShaderAndCreateMaterial (dofShader,dofMaterial);
|
||||
bokehSupport = bokehShader.isSupported;
|
||||
|
||||
if (bokeh && bokehSupport && bokehShader)
|
||||
bokehMaterial = CheckShaderAndCreateMaterial (bokehShader, bokehMaterial);
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnDisable () {
|
||||
Quads.Cleanup ();
|
||||
}
|
||||
|
||||
void OnEnable () {
|
||||
_camera = GetComponent<Camera>();
|
||||
_camera.depthTextureMode |= DepthTextureMode.Depth;
|
||||
}
|
||||
|
||||
float FocalDistance01 ( float worldDist) {
|
||||
return _camera.WorldToViewportPoint((worldDist-_camera.nearClipPlane) * _camera.transform.forward + _camera.transform.position).z / (_camera.farClipPlane-_camera.nearClipPlane);
|
||||
}
|
||||
|
||||
int GetDividerBasedOnQuality () {
|
||||
int divider = 1;
|
||||
if (resolution == DofResolution.Medium)
|
||||
divider = 2;
|
||||
else if (resolution == DofResolution.Low)
|
||||
divider = 2;
|
||||
return divider;
|
||||
}
|
||||
|
||||
int GetLowResolutionDividerBasedOnQuality ( int baseDivider) {
|
||||
int lowTexDivider = baseDivider;
|
||||
if (resolution == DofResolution.High)
|
||||
lowTexDivider *= 2;
|
||||
if (resolution == DofResolution.Low)
|
||||
lowTexDivider *= 2;
|
||||
return lowTexDivider;
|
||||
}
|
||||
|
||||
private RenderTexture foregroundTexture = null;
|
||||
private RenderTexture mediumRezWorkTexture = null;
|
||||
private RenderTexture finalDefocus = null;
|
||||
private RenderTexture lowRezWorkTexture = null;
|
||||
private RenderTexture bokehSource = null;
|
||||
private RenderTexture bokehSource2 = null;
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
if (CheckResources()==false) {
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
if (smoothness < 0.1f)
|
||||
smoothness = 0.1f;
|
||||
|
||||
// update needed focal & rt size parameter
|
||||
|
||||
bokeh = bokeh && bokehSupport;
|
||||
float bokehBlurAmplifier = bokeh ? BOKEH_EXTRA_BLUR : 1.0f;
|
||||
|
||||
bool blurForeground = quality > Dof34QualitySetting.OnlyBackground;
|
||||
float focal01Size = focalSize / (_camera.farClipPlane - _camera.nearClipPlane);;
|
||||
|
||||
if (simpleTweakMode) {
|
||||
focalDistance01 = objectFocus ? (_camera.WorldToViewportPoint (objectFocus.position)).z / (_camera.farClipPlane) : FocalDistance01 (focalPoint);
|
||||
focalStartCurve = focalDistance01 * smoothness;
|
||||
focalEndCurve = focalStartCurve;
|
||||
blurForeground = blurForeground && (focalPoint > (_camera.nearClipPlane + Mathf.Epsilon));
|
||||
}
|
||||
else {
|
||||
if (objectFocus) {
|
||||
var vpPoint= _camera.WorldToViewportPoint (objectFocus.position);
|
||||
vpPoint.z = (vpPoint.z) / (_camera.farClipPlane);
|
||||
focalDistance01 = vpPoint.z;
|
||||
}
|
||||
else
|
||||
focalDistance01 = FocalDistance01 (focalZDistance);
|
||||
|
||||
focalStartCurve = focalZStartCurve;
|
||||
focalEndCurve = focalZEndCurve;
|
||||
blurForeground = blurForeground && (focalPoint > (_camera.nearClipPlane + Mathf.Epsilon));
|
||||
}
|
||||
|
||||
widthOverHeight = (1.0f * source.width) / (1.0f * source.height);
|
||||
oneOverBaseSize = 1.0f / 512.0f;
|
||||
|
||||
dofMaterial.SetFloat ("_ForegroundBlurExtrude", foregroundBlurExtrude);
|
||||
dofMaterial.SetVector ("_CurveParams", new Vector4 (simpleTweakMode ? 1.0f / focalStartCurve : focalStartCurve, simpleTweakMode ? 1.0f / focalEndCurve : focalEndCurve, focal01Size * 0.5f, focalDistance01));
|
||||
dofMaterial.SetVector ("_InvRenderTargetSize", new Vector4 (1.0f / (1.0f * source.width), 1.0f / (1.0f * source.height),0.0f,0.0f));
|
||||
|
||||
int divider = GetDividerBasedOnQuality ();
|
||||
int lowTexDivider = GetLowResolutionDividerBasedOnQuality (divider);
|
||||
|
||||
AllocateTextures (blurForeground, source, divider, lowTexDivider);
|
||||
|
||||
// WRITE COC to alpha channel
|
||||
// source is only being bound to detect y texcoord flip
|
||||
Graphics.Blit (source, source, dofMaterial, 3);
|
||||
|
||||
// better DOWNSAMPLE (could actually be weighted for higher quality)
|
||||
Downsample (source, mediumRezWorkTexture);
|
||||
|
||||
// BLUR A LITTLE first, which has two purposes
|
||||
// 1.) reduce jitter, noise, aliasing
|
||||
// 2.) produce the little-blur buffer used in composition later
|
||||
Blur (mediumRezWorkTexture, mediumRezWorkTexture, DofBlurriness.Low, 4, maxBlurSpread);
|
||||
|
||||
if ((bokeh) && ((BokehDestination.Foreground & bokehDestination) != 0))
|
||||
{
|
||||
dofMaterial.SetVector ("_Threshhold", new Vector4(bokehThresholdContrast, bokehThresholdLuminance, 0.95f, 0.0f));
|
||||
|
||||
// add and mark the parts that should end up as bokeh shapes
|
||||
Graphics.Blit (mediumRezWorkTexture, bokehSource2, dofMaterial, 11);
|
||||
|
||||
// remove those parts (maybe even a little tittle bittle more) from the regurlarly blurred buffer
|
||||
//Graphics.Blit (mediumRezWorkTexture, lowRezWorkTexture, dofMaterial, 10);
|
||||
Graphics.Blit (mediumRezWorkTexture, lowRezWorkTexture);//, dofMaterial, 10);
|
||||
|
||||
// maybe you want to reblur the small blur ... but not really needed.
|
||||
//Blur (mediumRezWorkTexture, mediumRezWorkTexture, DofBlurriness.Low, 4, maxBlurSpread);
|
||||
|
||||
// bigger BLUR
|
||||
Blur (lowRezWorkTexture, lowRezWorkTexture, bluriness, 0, maxBlurSpread * bokehBlurAmplifier);
|
||||
}
|
||||
else {
|
||||
// bigger BLUR
|
||||
Downsample (mediumRezWorkTexture, lowRezWorkTexture);
|
||||
Blur (lowRezWorkTexture, lowRezWorkTexture, bluriness, 0, maxBlurSpread);
|
||||
}
|
||||
|
||||
dofBlurMaterial.SetTexture ("_TapLow", lowRezWorkTexture);
|
||||
dofBlurMaterial.SetTexture ("_TapMedium", mediumRezWorkTexture);
|
||||
Graphics.Blit (null, finalDefocus, dofBlurMaterial, 3);
|
||||
|
||||
// we are only adding bokeh now if the background is the only part we have to deal with
|
||||
if ((bokeh) && ((BokehDestination.Foreground & bokehDestination) != 0))
|
||||
AddBokeh (bokehSource2, bokehSource, finalDefocus);
|
||||
|
||||
dofMaterial.SetTexture ("_TapLowBackground", finalDefocus);
|
||||
dofMaterial.SetTexture ("_TapMedium", mediumRezWorkTexture); // needed for debugging/visualization
|
||||
|
||||
// FINAL DEFOCUS (background)
|
||||
Graphics.Blit (source, blurForeground ? foregroundTexture : destination, dofMaterial, visualize ? 2 : 0);
|
||||
|
||||
// FINAL DEFOCUS (foreground)
|
||||
if (blurForeground) {
|
||||
// WRITE COC to alpha channel
|
||||
Graphics.Blit (foregroundTexture, source, dofMaterial, 5);
|
||||
|
||||
// DOWNSAMPLE (unweighted)
|
||||
Downsample (source, mediumRezWorkTexture);
|
||||
|
||||
// BLUR A LITTLE first, which has two purposes
|
||||
// 1.) reduce jitter, noise, aliasing
|
||||
// 2.) produce the little-blur buffer used in composition later
|
||||
BlurFg (mediumRezWorkTexture, mediumRezWorkTexture, DofBlurriness.Low, 2, maxBlurSpread);
|
||||
|
||||
if ((bokeh) && ((BokehDestination.Foreground & bokehDestination) != 0))
|
||||
{
|
||||
dofMaterial.SetVector ("_Threshhold", new Vector4(bokehThresholdContrast * 0.5f, bokehThresholdLuminance, 0.0f, 0.0f));
|
||||
|
||||
// add and mark the parts that should end up as bokeh shapes
|
||||
Graphics.Blit (mediumRezWorkTexture, bokehSource2, dofMaterial, 11);
|
||||
|
||||
// remove the parts (maybe even a little tittle bittle more) that will end up in bokeh space
|
||||
//Graphics.Blit (mediumRezWorkTexture, lowRezWorkTexture, dofMaterial, 10);
|
||||
Graphics.Blit (mediumRezWorkTexture, lowRezWorkTexture);//, dofMaterial, 10);
|
||||
|
||||
// big BLUR
|
||||
BlurFg (lowRezWorkTexture, lowRezWorkTexture, bluriness, 1, maxBlurSpread * bokehBlurAmplifier);
|
||||
}
|
||||
else {
|
||||
// big BLUR
|
||||
BlurFg (mediumRezWorkTexture, lowRezWorkTexture, bluriness, 1, maxBlurSpread);
|
||||
}
|
||||
|
||||
// simple upsample once
|
||||
Graphics.Blit (lowRezWorkTexture, finalDefocus);
|
||||
|
||||
dofMaterial.SetTexture ("_TapLowForeground", finalDefocus);
|
||||
Graphics.Blit (source, destination, dofMaterial, visualize ? 1 : 4);
|
||||
|
||||
if ((bokeh) && ((BokehDestination.Foreground & bokehDestination) != 0))
|
||||
AddBokeh (bokehSource2, bokehSource, destination);
|
||||
}
|
||||
|
||||
ReleaseTextures ();
|
||||
}
|
||||
|
||||
void Blur ( RenderTexture from, RenderTexture to, DofBlurriness iterations, int blurPass, float spread) {
|
||||
RenderTexture tmp = RenderTexture.GetTemporary (to.width, to.height);
|
||||
if ((int)iterations > 1) {
|
||||
BlurHex (from, to, blurPass, spread, tmp);
|
||||
if ((int)iterations > 2) {
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (0.0f, spread * oneOverBaseSize, 0.0f, 0.0f));
|
||||
Graphics.Blit (to, tmp, dofBlurMaterial, blurPass);
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
|
||||
Graphics.Blit (tmp, to, dofBlurMaterial, blurPass);
|
||||
}
|
||||
}
|
||||
else {
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (0.0f, spread * oneOverBaseSize, 0.0f, 0.0f));
|
||||
Graphics.Blit (from, tmp, dofBlurMaterial, blurPass);
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
|
||||
Graphics.Blit (tmp, to, dofBlurMaterial, blurPass);
|
||||
}
|
||||
RenderTexture.ReleaseTemporary (tmp);
|
||||
}
|
||||
|
||||
void BlurFg ( RenderTexture from, RenderTexture to, DofBlurriness iterations, int blurPass, float spread) {
|
||||
// we want a nice, big coc, hence we need to tap once from this (higher resolution) texture
|
||||
dofBlurMaterial.SetTexture ("_TapHigh", from);
|
||||
|
||||
RenderTexture tmp = RenderTexture.GetTemporary (to.width, to.height);
|
||||
if ((int)iterations > 1) {
|
||||
BlurHex (from, to, blurPass, spread, tmp);
|
||||
if ((int)iterations > 2) {
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (0.0f, spread * oneOverBaseSize, 0.0f, 0.0f));
|
||||
Graphics.Blit (to, tmp, dofBlurMaterial, blurPass);
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
|
||||
Graphics.Blit (tmp, to, dofBlurMaterial, blurPass);
|
||||
}
|
||||
}
|
||||
else {
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (0.0f, spread * oneOverBaseSize, 0.0f, 0.0f));
|
||||
Graphics.Blit (from, tmp, dofBlurMaterial, blurPass);
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
|
||||
Graphics.Blit (tmp, to, dofBlurMaterial, blurPass);
|
||||
}
|
||||
RenderTexture.ReleaseTemporary (tmp);
|
||||
}
|
||||
|
||||
void BlurHex ( RenderTexture from, RenderTexture to, int blurPass, float spread, RenderTexture tmp) {
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (0.0f, spread * oneOverBaseSize, 0.0f, 0.0f));
|
||||
Graphics.Blit (from, tmp, dofBlurMaterial, blurPass);
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
|
||||
Graphics.Blit (tmp, to, dofBlurMaterial, blurPass);
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, spread * oneOverBaseSize, 0.0f, 0.0f));
|
||||
Graphics.Blit (to, tmp, dofBlurMaterial, blurPass);
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, -spread * oneOverBaseSize, 0.0f, 0.0f));
|
||||
Graphics.Blit (tmp, to, dofBlurMaterial, blurPass);
|
||||
}
|
||||
|
||||
void Downsample ( RenderTexture from, RenderTexture to) {
|
||||
dofMaterial.SetVector ("_InvRenderTargetSize", new Vector4 (1.0f / (1.0f * to.width), 1.0f / (1.0f * to.height), 0.0f, 0.0f));
|
||||
Graphics.Blit (from, to, dofMaterial, SMOOTH_DOWNSAMPLE_PASS);
|
||||
}
|
||||
|
||||
void AddBokeh ( RenderTexture bokehInfo, RenderTexture tempTex, RenderTexture finalTarget) {
|
||||
if (bokehMaterial) {
|
||||
var meshes = Quads.GetMeshes (tempTex.width, tempTex.height); // quads: exchanging more triangles with less overdraw
|
||||
|
||||
RenderTexture.active = tempTex;
|
||||
GL.Clear (false, true, new Color (0.0f, 0.0f, 0.0f, 0.0f));
|
||||
|
||||
GL.PushMatrix ();
|
||||
GL.LoadIdentity ();
|
||||
|
||||
// point filter mode is important, otherwise we get bokeh shape & size artefacts
|
||||
bokehInfo.filterMode = FilterMode.Point;
|
||||
|
||||
float arW = (bokehInfo.width * 1.0f) / (bokehInfo.height * 1.0f);
|
||||
float sc = 2.0f / (1.0f * bokehInfo.width);
|
||||
sc += bokehScale * maxBlurSpread * BOKEH_EXTRA_BLUR * oneOverBaseSize;
|
||||
|
||||
bokehMaterial.SetTexture ("_Source", bokehInfo);
|
||||
bokehMaterial.SetTexture ("_MainTex", bokehTexture);
|
||||
bokehMaterial.SetVector ("_ArScale",new Vector4 (sc, sc * arW, 0.5f, 0.5f * arW));
|
||||
bokehMaterial.SetFloat ("_Intensity", bokehIntensity);
|
||||
bokehMaterial.SetPass (0);
|
||||
|
||||
foreach(Mesh m in meshes)
|
||||
if (m) Graphics.DrawMeshNow (m, Matrix4x4.identity);
|
||||
|
||||
GL.PopMatrix ();
|
||||
|
||||
Graphics.Blit (tempTex, finalTarget, dofMaterial, 8);
|
||||
|
||||
// important to set back as we sample from this later on
|
||||
bokehInfo.filterMode = FilterMode.Bilinear;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ReleaseTextures () {
|
||||
if (foregroundTexture) RenderTexture.ReleaseTemporary (foregroundTexture);
|
||||
if (finalDefocus) RenderTexture.ReleaseTemporary (finalDefocus);
|
||||
if (mediumRezWorkTexture) RenderTexture.ReleaseTemporary (mediumRezWorkTexture);
|
||||
if (lowRezWorkTexture) RenderTexture.ReleaseTemporary (lowRezWorkTexture);
|
||||
if (bokehSource) RenderTexture.ReleaseTemporary (bokehSource);
|
||||
if (bokehSource2) RenderTexture.ReleaseTemporary (bokehSource2);
|
||||
}
|
||||
|
||||
void AllocateTextures ( bool blurForeground, RenderTexture source, int divider, int lowTexDivider) {
|
||||
foregroundTexture = null;
|
||||
if (blurForeground)
|
||||
foregroundTexture = RenderTexture.GetTemporary (source.width, source.height, 0);
|
||||
mediumRezWorkTexture = RenderTexture.GetTemporary (source.width / divider, source.height / divider, 0);
|
||||
finalDefocus = RenderTexture.GetTemporary (source.width / divider, source.height / divider, 0);
|
||||
lowRezWorkTexture = RenderTexture.GetTemporary (source.width / lowTexDivider, source.height / lowTexDivider, 0);
|
||||
bokehSource = null;
|
||||
bokehSource2 = null;
|
||||
if (bokeh) {
|
||||
bokehSource = RenderTexture.GetTemporary (source.width / (lowTexDivider * bokehDownsample), source.height / (lowTexDivider * bokehDownsample), 0, RenderTextureFormat.ARGBHalf);
|
||||
bokehSource2 = RenderTexture.GetTemporary (source.width / (lowTexDivider * bokehDownsample), source.height / (lowTexDivider * bokehDownsample), 0, RenderTextureFormat.ARGBHalf);
|
||||
bokehSource.filterMode = FilterMode.Bilinear;
|
||||
bokehSource2.filterMode = FilterMode.Bilinear;
|
||||
RenderTexture.active = bokehSource2;
|
||||
GL.Clear (false, true, new Color(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
// to make sure: always use bilinear filter setting
|
||||
|
||||
source.filterMode = FilterMode.Bilinear;
|
||||
finalDefocus.filterMode = FilterMode.Bilinear;
|
||||
mediumRezWorkTexture.filterMode = FilterMode.Bilinear;
|
||||
lowRezWorkTexture.filterMode = FilterMode.Bilinear;
|
||||
if (foregroundTexture)
|
||||
foregroundTexture.filterMode = FilterMode.Bilinear;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83d8db0ec466c14429f58c68c16398a1
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- objectFocus: {instanceID: 0}
|
||||
- dofBlurShader: {fileID: 4800000, guid: bb4af680337344a4abad65a4e8873c50, type: 3}
|
||||
- dofShader: {fileID: 4800000, guid: 987fb0677d01f43ce8a9dbf12271e668, type: 3}
|
||||
- bokehShader: {fileID: 4800000, guid: 57cdacf9b217546aaa18edf39a6151c0, type: 3}
|
||||
- bokehTexture: {fileID: 2800000, guid: fc00ec05a89da4ff695a4273715cd5ce, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof (Camera))]
|
||||
[AddComponentMenu ("Image Effects/Edge Detection/Edge Detection")]
|
||||
public class EdgeDetection : PostEffectsBase
|
||||
{
|
||||
public enum EdgeDetectMode
|
||||
{
|
||||
TriangleDepthNormals = 0,
|
||||
RobertsCrossDepthNormals = 1,
|
||||
SobelDepth = 2,
|
||||
SobelDepthThin = 3,
|
||||
TriangleLuminance = 4,
|
||||
}
|
||||
|
||||
|
||||
public EdgeDetectMode mode = EdgeDetectMode.SobelDepthThin;
|
||||
public float sensitivityDepth = 1.0f;
|
||||
public float sensitivityNormals = 1.0f;
|
||||
public float lumThreshold = 0.2f;
|
||||
public float edgeExp = 1.0f;
|
||||
public float sampleDist = 1.0f;
|
||||
public float edgesOnly = 0.0f;
|
||||
public Color edgesOnlyBgColor = Color.white;
|
||||
|
||||
public Shader edgeDetectShader;
|
||||
private Material edgeDetectMaterial = null;
|
||||
private EdgeDetectMode oldMode = EdgeDetectMode.SobelDepthThin;
|
||||
|
||||
|
||||
public override bool CheckResources ()
|
||||
{
|
||||
CheckSupport (true);
|
||||
|
||||
edgeDetectMaterial = CheckShaderAndCreateMaterial (edgeDetectShader,edgeDetectMaterial);
|
||||
if (mode != oldMode)
|
||||
SetCameraFlag ();
|
||||
|
||||
oldMode = mode;
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
|
||||
new void Start ()
|
||||
{
|
||||
oldMode = mode;
|
||||
}
|
||||
|
||||
void SetCameraFlag ()
|
||||
{
|
||||
if (mode == EdgeDetectMode.SobelDepth || mode == EdgeDetectMode.SobelDepthThin)
|
||||
GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;
|
||||
else if (mode == EdgeDetectMode.TriangleDepthNormals || mode == EdgeDetectMode.RobertsCrossDepthNormals)
|
||||
GetComponent<Camera>().depthTextureMode |= DepthTextureMode.DepthNormals;
|
||||
}
|
||||
|
||||
void OnEnable ()
|
||||
{
|
||||
SetCameraFlag();
|
||||
}
|
||||
|
||||
[ImageEffectOpaque]
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources () == false)
|
||||
{
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 sensitivity = new Vector2 (sensitivityDepth, sensitivityNormals);
|
||||
edgeDetectMaterial.SetVector ("_Sensitivity", new Vector4 (sensitivity.x, sensitivity.y, 1.0f, sensitivity.y));
|
||||
edgeDetectMaterial.SetFloat ("_BgFade", edgesOnly);
|
||||
edgeDetectMaterial.SetFloat ("_SampleDistance", sampleDist);
|
||||
edgeDetectMaterial.SetVector ("_BgColor", edgesOnlyBgColor);
|
||||
edgeDetectMaterial.SetFloat ("_Exponent", edgeExp);
|
||||
edgeDetectMaterial.SetFloat ("_Threshold", lumThreshold);
|
||||
|
||||
Graphics.Blit (source, destination, edgeDetectMaterial, (int) mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 730475ee64f9a894bbac0d9e6f22e813
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- edgeDetectShader: {fileID: 4800000, guid: 0d1644bdf064147baa97f235fc5b4903, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Displacement/Fisheye")]
|
||||
public class Fisheye : PostEffectsBase
|
||||
{
|
||||
[Range(0.0f, 1.5f)]
|
||||
public float strengthX = 0.05f;
|
||||
[Range(0.0f, 1.5f)]
|
||||
public float strengthY = 0.05f;
|
||||
|
||||
public Shader fishEyeShader = null;
|
||||
private Material fisheyeMaterial = null;
|
||||
|
||||
|
||||
public override bool CheckResources ()
|
||||
{
|
||||
CheckSupport (false);
|
||||
fisheyeMaterial = CheckShaderAndCreateMaterial(fishEyeShader,fisheyeMaterial);
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources()==false)
|
||||
{
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
float oneOverBaseSize = 80.0f / 512.0f; // to keep values more like in the old version of fisheye
|
||||
|
||||
float ar = (source.width * 1.0f) / (source.height * 1.0f);
|
||||
|
||||
fisheyeMaterial.SetVector ("intensity", new Vector4 (strengthX * ar * oneOverBaseSize, strengthY * oneOverBaseSize, strengthX * ar * oneOverBaseSize, strengthY * oneOverBaseSize));
|
||||
Graphics.Blit (source, destination, fisheyeMaterial);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4739c22ef73ad62488fe344c8fe9addd
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- fishEyeShader: {fileID: 4800000, guid: 874ceab4425f64bccb1d14032f4452b1, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
150
Assets/Standard Assets/Effects/ImageEffects/Scripts/GlobalFog.cs
Normal file
150
Assets/Standard Assets/Effects/ImageEffects/Scripts/GlobalFog.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Rendering/Global Fog")]
|
||||
class GlobalFog : PostEffectsBase
|
||||
{
|
||||
[Tooltip("Apply distance-based fog?")]
|
||||
public bool distanceFog = true;
|
||||
[Tooltip("Exclude far plane pixels from distance-based fog? (Skybox or clear color)")]
|
||||
public bool excludeFarPixels = true;
|
||||
[Tooltip("Distance fog is based on radial distance from camera when checked")]
|
||||
public bool useRadialDistance = false;
|
||||
[Tooltip("Apply height-based fog?")]
|
||||
public bool heightFog = true;
|
||||
[Tooltip("Fog top Y coordinate")]
|
||||
public float height = 1.0f;
|
||||
[Range(0.001f,10.0f)]
|
||||
public float heightDensity = 2.0f;
|
||||
[Tooltip("Push fog away from the camera by this amount")]
|
||||
public float startDistance = 0.0f;
|
||||
|
||||
public Shader fogShader = null;
|
||||
private Material fogMaterial = null;
|
||||
|
||||
|
||||
public override bool CheckResources ()
|
||||
{
|
||||
CheckSupport (true);
|
||||
|
||||
fogMaterial = CheckShaderAndCreateMaterial (fogShader, fogMaterial);
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
[ImageEffectOpaque]
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources()==false || (!distanceFog && !heightFog))
|
||||
{
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
Camera cam = GetComponent<Camera>();
|
||||
Transform camtr = cam.transform;
|
||||
float camNear = cam.nearClipPlane;
|
||||
float camFar = cam.farClipPlane;
|
||||
float camFov = cam.fieldOfView;
|
||||
float camAspect = cam.aspect;
|
||||
|
||||
Matrix4x4 frustumCorners = Matrix4x4.identity;
|
||||
|
||||
float fovWHalf = camFov * 0.5f;
|
||||
|
||||
Vector3 toRight = camtr.right * camNear * Mathf.Tan (fovWHalf * Mathf.Deg2Rad) * camAspect;
|
||||
Vector3 toTop = camtr.up * camNear * Mathf.Tan (fovWHalf * Mathf.Deg2Rad);
|
||||
|
||||
Vector3 topLeft = (camtr.forward * camNear - toRight + toTop);
|
||||
float camScale = topLeft.magnitude * camFar/camNear;
|
||||
|
||||
topLeft.Normalize();
|
||||
topLeft *= camScale;
|
||||
|
||||
Vector3 topRight = (camtr.forward * camNear + toRight + toTop);
|
||||
topRight.Normalize();
|
||||
topRight *= camScale;
|
||||
|
||||
Vector3 bottomRight = (camtr.forward * camNear + toRight - toTop);
|
||||
bottomRight.Normalize();
|
||||
bottomRight *= camScale;
|
||||
|
||||
Vector3 bottomLeft = (camtr.forward * camNear - toRight - toTop);
|
||||
bottomLeft.Normalize();
|
||||
bottomLeft *= camScale;
|
||||
|
||||
frustumCorners.SetRow (0, topLeft);
|
||||
frustumCorners.SetRow (1, topRight);
|
||||
frustumCorners.SetRow (2, bottomRight);
|
||||
frustumCorners.SetRow (3, bottomLeft);
|
||||
|
||||
var camPos= camtr.position;
|
||||
float FdotC = camPos.y-height;
|
||||
float paramK = (FdotC <= 0.0f ? 1.0f : 0.0f);
|
||||
float excludeDepth = (excludeFarPixels ? 1.0f : 2.0f);
|
||||
fogMaterial.SetMatrix ("_FrustumCornersWS", frustumCorners);
|
||||
fogMaterial.SetVector ("_CameraWS", camPos);
|
||||
fogMaterial.SetVector ("_HeightParams", new Vector4 (height, FdotC, paramK, heightDensity*0.5f));
|
||||
fogMaterial.SetVector ("_DistanceParams", new Vector4 (-Mathf.Max(startDistance,0.0f), excludeDepth, 0, 0));
|
||||
|
||||
var sceneMode= RenderSettings.fogMode;
|
||||
var sceneDensity= RenderSettings.fogDensity;
|
||||
var sceneStart= RenderSettings.fogStartDistance;
|
||||
var sceneEnd= RenderSettings.fogEndDistance;
|
||||
Vector4 sceneParams;
|
||||
bool linear = (sceneMode == FogMode.Linear);
|
||||
float diff = linear ? sceneEnd - sceneStart : 0.0f;
|
||||
float invDiff = Mathf.Abs(diff) > 0.0001f ? 1.0f / diff : 0.0f;
|
||||
sceneParams.x = sceneDensity * 1.2011224087f; // density / sqrt(ln(2)), used by Exp2 fog mode
|
||||
sceneParams.y = sceneDensity * 1.4426950408f; // density / ln(2), used by Exp fog mode
|
||||
sceneParams.z = linear ? -invDiff : 0.0f;
|
||||
sceneParams.w = linear ? sceneEnd * invDiff : 0.0f;
|
||||
fogMaterial.SetVector ("_SceneFogParams", sceneParams);
|
||||
fogMaterial.SetVector ("_SceneFogMode", new Vector4((int)sceneMode, useRadialDistance ? 1 : 0, 0, 0));
|
||||
|
||||
int pass = 0;
|
||||
if (distanceFog && heightFog)
|
||||
pass = 0; // distance + height
|
||||
else if (distanceFog)
|
||||
pass = 1; // distance only
|
||||
else
|
||||
pass = 2; // height only
|
||||
CustomGraphicsBlit (source, destination, fogMaterial, pass);
|
||||
}
|
||||
|
||||
static void CustomGraphicsBlit (RenderTexture source, RenderTexture dest, Material fxMaterial, int passNr)
|
||||
{
|
||||
RenderTexture.active = dest;
|
||||
|
||||
fxMaterial.SetTexture ("_MainTex", source);
|
||||
|
||||
GL.PushMatrix ();
|
||||
GL.LoadOrtho ();
|
||||
|
||||
fxMaterial.SetPass (passNr);
|
||||
|
||||
GL.Begin (GL.QUADS);
|
||||
|
||||
GL.MultiTexCoord2 (0, 0.0f, 0.0f);
|
||||
GL.Vertex3 (0.0f, 0.0f, 3.0f); // BL
|
||||
|
||||
GL.MultiTexCoord2 (0, 1.0f, 0.0f);
|
||||
GL.Vertex3 (1.0f, 0.0f, 2.0f); // BR
|
||||
|
||||
GL.MultiTexCoord2 (0, 1.0f, 1.0f);
|
||||
GL.Vertex3 (1.0f, 1.0f, 1.0f); // TR
|
||||
|
||||
GL.MultiTexCoord2 (0, 0.0f, 1.0f);
|
||||
GL.Vertex3 (0.0f, 1.0f, 0.0f); // TL
|
||||
|
||||
GL.End ();
|
||||
GL.PopMatrix ();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76b5ec6153a1d55438228df10fe66844
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- fogShader: {fileID: 4800000, guid: 70d8568987ac0499f952b54c7c13e265, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu("Image Effects/Color Adjustments/Grayscale")]
|
||||
public class Grayscale : ImageEffectBase {
|
||||
public Texture textureRamp;
|
||||
|
||||
[Range(-1.0f,1.0f)]
|
||||
public float rampOffset;
|
||||
|
||||
// Called by camera to apply image effect
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
material.SetTexture("_RampTex", textureRamp);
|
||||
material.SetFloat("_RampOffset", rampOffset);
|
||||
Graphics.Blit (source, destination, material);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 243a781cad112c75d0008dfa8d76c639
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- shader: {fileID: 4800000, guid: daf9781cad112c75d0008dfa8d76c639, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[RequireComponent(typeof (Camera))]
|
||||
[AddComponentMenu("")]
|
||||
public class ImageEffectBase : MonoBehaviour
|
||||
{
|
||||
/// Provides a shader property that is set in the inspector
|
||||
/// and a material instantiated from the shader
|
||||
public Shader shader;
|
||||
|
||||
private Material m_Material;
|
||||
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
// Disable if we don't support image effects
|
||||
if (!SystemInfo.supportsImageEffects)
|
||||
{
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable the image effect if the shader can't
|
||||
// run on the users graphics card
|
||||
if (!shader || !shader.isSupported)
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
|
||||
protected Material material
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Material == null)
|
||||
{
|
||||
m_Material = new Material(shader);
|
||||
m_Material.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
return m_Material;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected virtual void OnDisable()
|
||||
{
|
||||
if (m_Material)
|
||||
{
|
||||
DestroyImmediate(m_Material);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6469eb0ad1119d6d00011d98d76c639
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
/// A Utility class for performing various image based rendering tasks.
|
||||
[AddComponentMenu("")]
|
||||
public class ImageEffects
|
||||
{
|
||||
public static void RenderDistortion(Material material, RenderTexture source, RenderTexture destination, float angle, Vector2 center, Vector2 radius)
|
||||
{
|
||||
bool invertY = source.texelSize.y < 0.0f;
|
||||
if (invertY)
|
||||
{
|
||||
center.y = 1.0f - center.y;
|
||||
angle = -angle;
|
||||
}
|
||||
|
||||
Matrix4x4 rotationMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0, 0, angle), Vector3.one);
|
||||
|
||||
material.SetMatrix("_RotationMatrix", rotationMatrix);
|
||||
material.SetVector("_CenterRadius", new Vector4(center.x, center.y, radius.x, radius.y));
|
||||
material.SetFloat("_Angle", angle*Mathf.Deg2Rad);
|
||||
|
||||
Graphics.Blit(source, destination, material);
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("Use Graphics.Blit(source,dest) instead")]
|
||||
public static void Blit(RenderTexture source, RenderTexture dest)
|
||||
{
|
||||
Graphics.Blit(source, dest);
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("Use Graphics.Blit(source, destination, material) instead")]
|
||||
public static void BlitWithMaterial(Material material, RenderTexture source, RenderTexture dest)
|
||||
{
|
||||
Graphics.Blit(source, dest, material);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 89a037199d11087f1100e2b844295342
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- blitCopyShader: {fileID: 4800000, guid: 3338b5ea2f3cb594698fae65cf060346, type: 3}
|
||||
- blitMultiplyShader: {fileID: 4800000, guid: 7034c801b78acab448cdcf845f7c352d,
|
||||
type: 3}
|
||||
- blitMultiply2XShader: {fileID: 4800000, guid: cde82987e0a884c4788c65f7b54390e8,
|
||||
type: 3}
|
||||
- blitAddShader: {fileID: 4800000, guid: c7515f214a63bdb42b6ae6335a00a8a4, type: 3}
|
||||
- blitAddSmoothShader: {fileID: 4800000, guid: 7741a77a7c455d0418bc429bd508dc87,
|
||||
type: 3}
|
||||
- blitBlendShader: {fileID: 4800000, guid: f1cf7e9c98754c4429ff0f7cc1d9dd7b, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
// This class implements simple ghosting type Motion Blur.
|
||||
// If Extra Blur is selected, the scene will allways be a little blurred,
|
||||
// as it is scaled to a smaller resolution.
|
||||
// The effect works by accumulating the previous frames in an accumulation
|
||||
// texture.
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu("Image Effects/Blur/Motion Blur (Color Accumulation)")]
|
||||
[RequireComponent(typeof(Camera))]
|
||||
public class MotionBlur : ImageEffectBase
|
||||
{
|
||||
[Range(0.0f, 0.92f)]
|
||||
public float blurAmount = 0.8f;
|
||||
public bool extraBlur = false;
|
||||
|
||||
private RenderTexture accumTexture;
|
||||
|
||||
override protected void Start()
|
||||
{
|
||||
if (!SystemInfo.supportsRenderTextures)
|
||||
{
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
base.Start();
|
||||
}
|
||||
|
||||
override protected void OnDisable()
|
||||
{
|
||||
base.OnDisable();
|
||||
DestroyImmediate(accumTexture);
|
||||
}
|
||||
|
||||
// Called by camera to apply image effect
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
// Create the accumulation texture
|
||||
if (accumTexture == null || accumTexture.width != source.width || accumTexture.height != source.height)
|
||||
{
|
||||
DestroyImmediate(accumTexture);
|
||||
accumTexture = new RenderTexture(source.width, source.height, 0);
|
||||
accumTexture.hideFlags = HideFlags.HideAndDontSave;
|
||||
Graphics.Blit( source, accumTexture );
|
||||
}
|
||||
|
||||
// If Extra Blur is selected, downscale the texture to 4x4 smaller resolution.
|
||||
if (extraBlur)
|
||||
{
|
||||
RenderTexture blurbuffer = RenderTexture.GetTemporary(source.width/4, source.height/4, 0);
|
||||
accumTexture.MarkRestoreExpected();
|
||||
Graphics.Blit(accumTexture, blurbuffer);
|
||||
Graphics.Blit(blurbuffer,accumTexture);
|
||||
RenderTexture.ReleaseTemporary(blurbuffer);
|
||||
}
|
||||
|
||||
// Clamp the motion blur variable, so it can never leave permanent trails in the image
|
||||
blurAmount = Mathf.Clamp( blurAmount, 0.0f, 0.92f );
|
||||
|
||||
// Setup the texture and floating point values in the shader
|
||||
material.SetTexture("_MainTex", accumTexture);
|
||||
material.SetFloat("_AccumOrig", 1.0F-blurAmount);
|
||||
|
||||
// We are accumulating motion over frames without clear/discard
|
||||
// by design, so silence any performance warnings from Unity
|
||||
accumTexture.MarkRestoreExpected();
|
||||
|
||||
// Render the image using the motion blur shader
|
||||
Graphics.Blit (source, accumTexture, material);
|
||||
Graphics.Blit (accumTexture, destination);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 478a2083ad114a07d000fbfb8d76c639
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- shader: {fileID: 4800000, guid: e9ba2083ad114a07d000fbfb8d76c639, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,243 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(Camera))]
|
||||
[AddComponentMenu("Image Effects/Noise/Noise And Grain (Filmic)")]
|
||||
public class NoiseAndGrain : PostEffectsBase
|
||||
{
|
||||
|
||||
public float intensityMultiplier = 0.25f;
|
||||
|
||||
public float generalIntensity = 0.5f;
|
||||
public float blackIntensity = 1.0f;
|
||||
public float whiteIntensity = 1.0f;
|
||||
public float midGrey = 0.2f;
|
||||
|
||||
public bool dx11Grain = false;
|
||||
public float softness = 0.0f;
|
||||
public bool monochrome = false;
|
||||
|
||||
public Vector3 intensities = new Vector3(1.0f, 1.0f, 1.0f);
|
||||
public Vector3 tiling = new Vector3(64.0f, 64.0f, 64.0f);
|
||||
public float monochromeTiling = 64.0f;
|
||||
|
||||
public FilterMode filterMode = FilterMode.Bilinear;
|
||||
|
||||
public Texture2D noiseTexture;
|
||||
|
||||
public Shader noiseShader;
|
||||
private Material noiseMaterial = null;
|
||||
|
||||
public Shader dx11NoiseShader;
|
||||
private Material dx11NoiseMaterial = null;
|
||||
|
||||
private static float TILE_AMOUNT = 64.0f;
|
||||
|
||||
private Mesh mesh;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
mesh = new Mesh();
|
||||
}
|
||||
|
||||
public override bool CheckResources()
|
||||
{
|
||||
CheckSupport(false);
|
||||
|
||||
noiseMaterial = CheckShaderAndCreateMaterial(noiseShader, noiseMaterial);
|
||||
|
||||
if (dx11Grain && supportDX11)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
dx11NoiseShader = Shader.Find("Hidden/NoiseAndGrainDX11");
|
||||
#endif
|
||||
dx11NoiseMaterial = CheckShaderAndCreateMaterial(dx11NoiseShader, dx11NoiseMaterial);
|
||||
}
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnRenderImage(RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources() == false || (null == noiseTexture))
|
||||
{
|
||||
Graphics.Blit(source, destination);
|
||||
if (null == noiseTexture)
|
||||
{
|
||||
Debug.LogWarning("Noise & Grain effect failing as noise texture is not assigned. please assign.", transform);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
softness = Mathf.Clamp(softness, 0.0f, 0.99f);
|
||||
|
||||
if (dx11Grain && supportDX11)
|
||||
{
|
||||
// We have a fancy, procedural noise pattern in this version, so no texture needed
|
||||
|
||||
dx11NoiseMaterial.SetFloat("_DX11NoiseTime", Time.frameCount);
|
||||
dx11NoiseMaterial.SetTexture("_NoiseTex", noiseTexture);
|
||||
dx11NoiseMaterial.SetVector("_NoisePerChannel", monochrome ? Vector3.one : intensities);
|
||||
dx11NoiseMaterial.SetVector("_MidGrey", new Vector3(midGrey, 1.0f / (1.0f - midGrey), -1.0f / midGrey));
|
||||
dx11NoiseMaterial.SetVector("_NoiseAmount", new Vector3(generalIntensity, blackIntensity, whiteIntensity) * intensityMultiplier);
|
||||
|
||||
if (softness > Mathf.Epsilon)
|
||||
{
|
||||
RenderTexture rt = RenderTexture.GetTemporary((int)(source.width * (1.0f - softness)), (int)(source.height * (1.0f - softness)));
|
||||
DrawNoiseQuadGrid(source, rt, dx11NoiseMaterial, noiseTexture, mesh, monochrome ? 3 : 2);
|
||||
dx11NoiseMaterial.SetTexture("_NoiseTex", rt);
|
||||
Graphics.Blit(source, destination, dx11NoiseMaterial, 4);
|
||||
RenderTexture.ReleaseTemporary(rt);
|
||||
}
|
||||
else
|
||||
DrawNoiseQuadGrid(source, destination, dx11NoiseMaterial, noiseTexture, mesh, (monochrome ? 1 : 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
// normal noise (DX9 style)
|
||||
|
||||
if (noiseTexture)
|
||||
{
|
||||
noiseTexture.wrapMode = TextureWrapMode.Repeat;
|
||||
noiseTexture.filterMode = filterMode;
|
||||
}
|
||||
|
||||
noiseMaterial.SetTexture("_NoiseTex", noiseTexture);
|
||||
noiseMaterial.SetVector("_NoisePerChannel", monochrome ? Vector3.one : intensities);
|
||||
noiseMaterial.SetVector("_NoiseTilingPerChannel", monochrome ? Vector3.one * monochromeTiling : tiling);
|
||||
noiseMaterial.SetVector("_MidGrey", new Vector3(midGrey, 1.0f / (1.0f - midGrey), -1.0f / midGrey));
|
||||
noiseMaterial.SetVector("_NoiseAmount", new Vector3(generalIntensity, blackIntensity, whiteIntensity) * intensityMultiplier);
|
||||
|
||||
if (softness > Mathf.Epsilon)
|
||||
{
|
||||
RenderTexture rt2 = RenderTexture.GetTemporary((int)(source.width * (1.0f - softness)), (int)(source.height * (1.0f - softness)));
|
||||
DrawNoiseQuadGrid(source, rt2, noiseMaterial, noiseTexture, mesh, 2);
|
||||
noiseMaterial.SetTexture("_NoiseTex", rt2);
|
||||
Graphics.Blit(source, destination, noiseMaterial, 1);
|
||||
RenderTexture.ReleaseTemporary(rt2);
|
||||
}
|
||||
else
|
||||
DrawNoiseQuadGrid(source, destination, noiseMaterial, noiseTexture, mesh, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawNoiseQuadGrid(RenderTexture source, RenderTexture dest, Material fxMaterial, Texture2D noise, Mesh mesh, int passNr)
|
||||
{
|
||||
RenderTexture.active = dest;
|
||||
|
||||
fxMaterial.SetTexture("_MainTex", source);
|
||||
|
||||
GL.PushMatrix();
|
||||
GL.LoadOrtho();
|
||||
|
||||
fxMaterial.SetPass(passNr);
|
||||
|
||||
BuildMesh(mesh, source, noise);
|
||||
|
||||
// Reset camera to origin
|
||||
Transform cam = Camera.main.transform;
|
||||
Vector3 camPos = cam.position;
|
||||
Quaternion camRot = cam.rotation;
|
||||
cam.position = Vector3.zero;
|
||||
cam.rotation = Quaternion.identity;
|
||||
|
||||
// Render mesh
|
||||
Graphics.DrawMeshNow(mesh, Matrix4x4.identity);
|
||||
|
||||
// Restore camera
|
||||
cam.position = camPos;
|
||||
cam.rotation = camRot;
|
||||
|
||||
GL.PopMatrix();
|
||||
}
|
||||
|
||||
static void BuildMesh(Mesh mesh, RenderTexture source, Texture2D noise)
|
||||
{
|
||||
float noiseSize = (noise.width * 1.0f);
|
||||
float subDs = (1.0f * source.width) / TILE_AMOUNT;
|
||||
|
||||
float aspectCorrection = (1.0f * source.width) / (1.0f * source.height);
|
||||
float stepSizeX = 1.0f / subDs;
|
||||
float stepSizeY = stepSizeX * aspectCorrection;
|
||||
|
||||
int meshWidth = (int)Mathf.Ceil(subDs);
|
||||
int meshHeight = (int)Mathf.Ceil(1.0f / stepSizeY);
|
||||
|
||||
// only rebuild the vertex info if the screen size has changed
|
||||
if (mesh.vertices.Length != meshWidth * meshHeight * 4)
|
||||
{
|
||||
Vector3[] vertices = new Vector3[meshWidth * meshHeight * 4];
|
||||
Vector2[] uv2s = new Vector2[meshWidth * meshHeight * 4];
|
||||
int[] triangles = new int[meshWidth * meshHeight * 6];
|
||||
|
||||
int vertexIndex = 0;
|
||||
int triangleIndex = 0;
|
||||
for (float x1 = 0.0f; x1 < 1.0f; x1 += stepSizeX)
|
||||
{
|
||||
for (float y1 = 0.0f; y1 < 1.0f; y1 += stepSizeY)
|
||||
{
|
||||
vertices[vertexIndex] = new Vector3(x1, y1, 0.1f);
|
||||
vertices[vertexIndex + 1] = new Vector3(x1 + stepSizeX, y1, 0.1f);
|
||||
vertices[vertexIndex + 2] = new Vector3(x1 + stepSizeX, y1 + stepSizeY, 0.1f);
|
||||
vertices[vertexIndex + 3] = new Vector3(x1, y1 + stepSizeY, 0.1f);
|
||||
|
||||
uv2s[vertexIndex] = new Vector2(0.0f, 0.0f);
|
||||
uv2s[vertexIndex + 1] = new Vector2(1.0f, 0.0f);
|
||||
uv2s[vertexIndex + 2] = new Vector2(1.0f, 1.0f);
|
||||
uv2s[vertexIndex + 3] = new Vector2(0.0f, 1.0f);
|
||||
|
||||
triangles[triangleIndex] = vertexIndex;
|
||||
triangles[triangleIndex + 1] = vertexIndex + 1;
|
||||
triangles[triangleIndex + 2] = vertexIndex + 2;
|
||||
triangles[triangleIndex + 3] = vertexIndex + 0;
|
||||
triangles[triangleIndex + 4] = vertexIndex + 2;
|
||||
triangles[triangleIndex + 5] = vertexIndex + 3;
|
||||
|
||||
vertexIndex += 4;
|
||||
triangleIndex += 6;
|
||||
}
|
||||
}
|
||||
|
||||
mesh.vertices = vertices;
|
||||
mesh.uv2 = uv2s;
|
||||
mesh.triangles = triangles;
|
||||
}
|
||||
|
||||
// rebuild the UV stream that changes over time
|
||||
BuildMeshUV0(mesh, meshWidth, meshHeight, noiseSize, noise.width);
|
||||
}
|
||||
|
||||
static void BuildMeshUV0(Mesh mesh, int width, int height, float noiseSize, int noiseWidth)
|
||||
{
|
||||
float texTile = noiseSize / (noiseWidth * 1.0f);
|
||||
float texTileMod = 1.0f / noiseSize;
|
||||
|
||||
Vector2[] uvs = new Vector2[width * height * 4];
|
||||
|
||||
int uvIndex = 0;
|
||||
for (int i = 0; i < width * height; i++)
|
||||
{
|
||||
float tcXStart = Random.Range(0.0f, noiseSize);
|
||||
float tcYStart = Random.Range(0.0f, noiseSize);
|
||||
|
||||
tcXStart = Mathf.Floor(tcXStart) * texTileMod;
|
||||
tcYStart = Mathf.Floor(tcYStart) * texTileMod;
|
||||
|
||||
uvs[uvIndex] = new Vector2(tcXStart, tcYStart);
|
||||
uvs[uvIndex + 1] = new Vector2(tcXStart + texTile * texTileMod, tcYStart);
|
||||
uvs[uvIndex + 2] = new Vector2(tcXStart + texTile * texTileMod, tcYStart + texTile * texTileMod);
|
||||
uvs[uvIndex + 3] = new Vector2(tcXStart, tcYStart + texTile * texTileMod);
|
||||
|
||||
uvIndex += 4;
|
||||
}
|
||||
|
||||
mesh.uv = uvs;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9191284b058eef549b7108b5f04e1117
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- noiseTexture: {fileID: 2800000, guid: 7a632f967e8ad42f5bd275898151ab6a, type: 3}
|
||||
- noiseShader: {fileID: 4800000, guid: b0249d8c935344451aa4de6db76f0688, type: 3}
|
||||
- dx11NoiseShader: {fileID: 4800000, guid: 8b30686bb4322ab42ad5eb50a0210b58, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu("Image Effects/Noise/Noise and Scratches")]
|
||||
public class NoiseAndScratches : MonoBehaviour
|
||||
{
|
||||
/// Monochrome noise just adds grain. Non-monochrome noise
|
||||
/// more resembles VCR as it adds noise in YUV color space,
|
||||
/// thus introducing magenta/green colors.
|
||||
public bool monochrome = true;
|
||||
private bool rgbFallback = false;
|
||||
|
||||
// Noise grain takes random intensity from Min to Max.
|
||||
[Range(0.0f,5.0f)]
|
||||
public float grainIntensityMin = 0.1f;
|
||||
[Range(0.0f, 5.0f)]
|
||||
public float grainIntensityMax = 0.2f;
|
||||
|
||||
/// The size of the noise grains (1 = one pixel).
|
||||
[Range(0.1f, 50.0f)]
|
||||
public float grainSize = 2.0f;
|
||||
|
||||
// Scratches take random intensity from Min to Max.
|
||||
[Range(0.0f, 5.0f)]
|
||||
public float scratchIntensityMin = 0.05f;
|
||||
[Range(0.0f, 5.0f)]
|
||||
public float scratchIntensityMax = 0.25f;
|
||||
|
||||
/// Scratches jump to another locations at this times per second.
|
||||
[Range(1.0f, 30.0f)]
|
||||
public float scratchFPS = 10.0f;
|
||||
/// While scratches are in the same location, they jitter a bit.
|
||||
[Range(0.0f, 1.0f)]
|
||||
public float scratchJitter = 0.01f;
|
||||
|
||||
public Texture grainTexture;
|
||||
public Texture scratchTexture;
|
||||
public Shader shaderRGB;
|
||||
public Shader shaderYUV;
|
||||
private Material m_MaterialRGB;
|
||||
private Material m_MaterialYUV;
|
||||
|
||||
private float scratchTimeLeft = 0.0f;
|
||||
private float scratchX, scratchY;
|
||||
|
||||
protected void Start ()
|
||||
{
|
||||
// Disable if we don't support image effects
|
||||
if (!SystemInfo.supportsImageEffects) {
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( shaderRGB == null || shaderYUV == null )
|
||||
{
|
||||
Debug.Log( "Noise shaders are not set up! Disabling noise effect." );
|
||||
enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !shaderRGB.isSupported ) // disable effect if RGB shader is not supported
|
||||
enabled = false;
|
||||
else if ( !shaderYUV.isSupported ) // fallback to RGB if YUV is not supported
|
||||
rgbFallback = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected Material material {
|
||||
get {
|
||||
if ( m_MaterialRGB == null ) {
|
||||
m_MaterialRGB = new Material( shaderRGB );
|
||||
m_MaterialRGB.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
if ( m_MaterialYUV == null && !rgbFallback ) {
|
||||
m_MaterialYUV = new Material( shaderYUV );
|
||||
m_MaterialYUV.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
return (!rgbFallback && !monochrome) ? m_MaterialYUV : m_MaterialRGB;
|
||||
}
|
||||
}
|
||||
|
||||
protected void OnDisable() {
|
||||
if ( m_MaterialRGB )
|
||||
DestroyImmediate( m_MaterialRGB );
|
||||
if ( m_MaterialYUV )
|
||||
DestroyImmediate( m_MaterialYUV );
|
||||
}
|
||||
|
||||
private void SanitizeParameters()
|
||||
{
|
||||
grainIntensityMin = Mathf.Clamp( grainIntensityMin, 0.0f, 5.0f );
|
||||
grainIntensityMax = Mathf.Clamp( grainIntensityMax, 0.0f, 5.0f );
|
||||
scratchIntensityMin = Mathf.Clamp( scratchIntensityMin, 0.0f, 5.0f );
|
||||
scratchIntensityMax = Mathf.Clamp( scratchIntensityMax, 0.0f, 5.0f );
|
||||
scratchFPS = Mathf.Clamp( scratchFPS, 1, 30 );
|
||||
scratchJitter = Mathf.Clamp( scratchJitter, 0.0f, 1.0f );
|
||||
grainSize = Mathf.Clamp( grainSize, 0.1f, 50.0f );
|
||||
}
|
||||
|
||||
// Called by the camera to apply the image effect
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
SanitizeParameters();
|
||||
|
||||
if ( scratchTimeLeft <= 0.0f )
|
||||
{
|
||||
scratchTimeLeft = Random.value * 2 / scratchFPS; // we have sanitized it earlier, won't be zero
|
||||
scratchX = Random.value;
|
||||
scratchY = Random.value;
|
||||
}
|
||||
scratchTimeLeft -= Time.deltaTime;
|
||||
|
||||
Material mat = material;
|
||||
|
||||
mat.SetTexture("_GrainTex", grainTexture);
|
||||
mat.SetTexture("_ScratchTex", scratchTexture);
|
||||
float grainScale = 1.0f / grainSize; // we have sanitized it earlier, won't be zero
|
||||
mat.SetVector("_GrainOffsetScale", new Vector4(
|
||||
Random.value,
|
||||
Random.value,
|
||||
(float)Screen.width / (float)grainTexture.width * grainScale,
|
||||
(float)Screen.height / (float)grainTexture.height * grainScale
|
||||
));
|
||||
mat.SetVector("_ScratchOffsetScale", new Vector4(
|
||||
scratchX + Random.value*scratchJitter,
|
||||
scratchY + Random.value*scratchJitter,
|
||||
(float)Screen.width / (float) scratchTexture.width,
|
||||
(float)Screen.height / (float) scratchTexture.height
|
||||
));
|
||||
mat.SetVector("_Intensity", new Vector4(
|
||||
Random.Range(grainIntensityMin, grainIntensityMax),
|
||||
Random.Range(scratchIntensityMin, scratchIntensityMax),
|
||||
0, 0 ));
|
||||
Graphics.Blit (source, destination, mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a88a26a276b4e47619ce2c5adad33fab
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- grainTexture: {fileID: 2800000, guid: ffa9c02760c2b4e8eb9814ec06c4b05b, type: 3}
|
||||
- scratchTexture: {fileID: 2800000, guid: 6205c27cc031f4e66b8ea90d1bfaa158, type: 3}
|
||||
- shaderRGB: {fileID: 4800000, guid: 5d7f4c401ae8946bcb0d6ff68a9e7466, type: 3}
|
||||
- shaderYUV: {fileID: 4800000, guid: 0e447868506ba49f0a73235b8a8b647a, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,261 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
public class PostEffectsBase : MonoBehaviour
|
||||
{
|
||||
protected bool supportHDRTextures = true;
|
||||
protected bool supportDX11 = false;
|
||||
protected bool isSupported = true;
|
||||
|
||||
private List<Material> createdMaterials = new List<Material> ();
|
||||
|
||||
protected Material CheckShaderAndCreateMaterial ( Shader s, Material m2Create)
|
||||
{
|
||||
if (!s)
|
||||
{
|
||||
Debug.Log("Missing shader in " + ToString ());
|
||||
enabled = false;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (s.isSupported && m2Create && m2Create.shader == s)
|
||||
return m2Create;
|
||||
|
||||
if (!s.isSupported)
|
||||
{
|
||||
NotSupported ();
|
||||
Debug.Log("The shader " + s.ToString() + " on effect "+ToString()+" is not supported on this platform!");
|
||||
return null;
|
||||
}
|
||||
|
||||
m2Create = new Material (s);
|
||||
createdMaterials.Add (m2Create);
|
||||
m2Create.hideFlags = HideFlags.DontSave;
|
||||
|
||||
return m2Create;
|
||||
}
|
||||
|
||||
|
||||
protected Material CreateMaterial (Shader s, Material m2Create)
|
||||
{
|
||||
if (!s)
|
||||
{
|
||||
Debug.Log ("Missing shader in " + ToString ());
|
||||
return null;
|
||||
}
|
||||
|
||||
if (m2Create && (m2Create.shader == s) && (s.isSupported))
|
||||
return m2Create;
|
||||
|
||||
if (!s.isSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
m2Create = new Material (s);
|
||||
createdMaterials.Add (m2Create);
|
||||
m2Create.hideFlags = HideFlags.DontSave;
|
||||
|
||||
return m2Create;
|
||||
}
|
||||
|
||||
void OnEnable ()
|
||||
{
|
||||
isSupported = true;
|
||||
}
|
||||
|
||||
void OnDestroy ()
|
||||
{
|
||||
RemoveCreatedMaterials ();
|
||||
}
|
||||
|
||||
private void RemoveCreatedMaterials ()
|
||||
{
|
||||
while (createdMaterials.Count > 0)
|
||||
{
|
||||
Material mat = createdMaterials[0];
|
||||
createdMaterials.RemoveAt (0);
|
||||
#if UNITY_EDITOR
|
||||
DestroyImmediate (mat);
|
||||
#else
|
||||
Destroy(mat);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
protected bool CheckSupport ()
|
||||
{
|
||||
return CheckSupport (false);
|
||||
}
|
||||
|
||||
|
||||
public virtual bool CheckResources ()
|
||||
{
|
||||
Debug.LogWarning ("CheckResources () for " + ToString() + " should be overwritten.");
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
|
||||
protected void Start ()
|
||||
{
|
||||
CheckResources ();
|
||||
}
|
||||
|
||||
protected bool CheckSupport (bool needDepth)
|
||||
{
|
||||
isSupported = true;
|
||||
supportHDRTextures = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf);
|
||||
supportDX11 = SystemInfo.graphicsShaderLevel >= 50 && SystemInfo.supportsComputeShaders;
|
||||
|
||||
if (!SystemInfo.supportsImageEffects || !SystemInfo.supportsRenderTextures)
|
||||
{
|
||||
NotSupported ();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (needDepth && !SystemInfo.SupportsRenderTextureFormat (RenderTextureFormat.Depth))
|
||||
{
|
||||
NotSupported ();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (needDepth)
|
||||
GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected bool CheckSupport (bool needDepth, bool needHdr)
|
||||
{
|
||||
if (!CheckSupport(needDepth))
|
||||
return false;
|
||||
|
||||
if (needHdr && !supportHDRTextures)
|
||||
{
|
||||
NotSupported ();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public bool Dx11Support ()
|
||||
{
|
||||
return supportDX11;
|
||||
}
|
||||
|
||||
|
||||
protected void ReportAutoDisable ()
|
||||
{
|
||||
Debug.LogWarning ("The image effect " + ToString() + " has been disabled as it's not supported on the current platform.");
|
||||
}
|
||||
|
||||
// deprecated but needed for old effects to survive upgrading
|
||||
bool CheckShader (Shader s)
|
||||
{
|
||||
Debug.Log("The shader " + s.ToString () + " on effect "+ ToString () + " is not part of the Unity 3.2+ effects suite anymore. For best performance and quality, please ensure you are using the latest Standard Assets Image Effects (Pro only) package.");
|
||||
if (!s.isSupported)
|
||||
{
|
||||
NotSupported ();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void NotSupported ()
|
||||
{
|
||||
enabled = false;
|
||||
isSupported = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
protected void DrawBorder (RenderTexture dest, Material material)
|
||||
{
|
||||
float x1;
|
||||
float x2;
|
||||
float y1;
|
||||
float y2;
|
||||
|
||||
RenderTexture.active = dest;
|
||||
bool invertY = true; // source.texelSize.y < 0.0ff;
|
||||
// Set up the simple Matrix
|
||||
GL.PushMatrix();
|
||||
GL.LoadOrtho();
|
||||
|
||||
for (int i = 0; i < material.passCount; i++)
|
||||
{
|
||||
material.SetPass(i);
|
||||
|
||||
float y1_; float y2_;
|
||||
if (invertY)
|
||||
{
|
||||
y1_ = 1.0f; y2_ = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
y1_ = 0.0f; y2_ = 1.0f;
|
||||
}
|
||||
|
||||
// left
|
||||
x1 = 0.0f;
|
||||
x2 = 0.0f + 1.0f/(dest.width*1.0f);
|
||||
y1 = 0.0f;
|
||||
y2 = 1.0f;
|
||||
GL.Begin(GL.QUADS);
|
||||
|
||||
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
|
||||
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
|
||||
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
|
||||
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);
|
||||
|
||||
// right
|
||||
x1 = 1.0f - 1.0f/(dest.width*1.0f);
|
||||
x2 = 1.0f;
|
||||
y1 = 0.0f;
|
||||
y2 = 1.0f;
|
||||
|
||||
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
|
||||
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
|
||||
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
|
||||
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);
|
||||
|
||||
// top
|
||||
x1 = 0.0f;
|
||||
x2 = 1.0f;
|
||||
y1 = 0.0f;
|
||||
y2 = 0.0f + 1.0f/(dest.height*1.0f);
|
||||
|
||||
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
|
||||
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
|
||||
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
|
||||
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);
|
||||
|
||||
// bottom
|
||||
x1 = 0.0f;
|
||||
x2 = 1.0f;
|
||||
y1 = 1.0f - 1.0f/(dest.height*1.0f);
|
||||
y2 = 1.0f;
|
||||
|
||||
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
|
||||
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
|
||||
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
|
||||
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);
|
||||
|
||||
GL.End();
|
||||
}
|
||||
|
||||
GL.PopMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6f4318ec6c2bf643a0f9edfeeaba0ec
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,188 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
class PostEffectsHelper : MonoBehaviour
|
||||
{
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
Debug.Log("OnRenderImage in Helper called ...");
|
||||
}
|
||||
|
||||
static void DrawLowLevelPlaneAlignedWithCamera (
|
||||
float dist ,
|
||||
RenderTexture source, RenderTexture dest ,
|
||||
Material material ,
|
||||
Camera cameraForProjectionMatrix )
|
||||
{
|
||||
// Make the destination texture the target for all rendering
|
||||
RenderTexture.active = dest;
|
||||
// Assign the source texture to a property from a shader
|
||||
material.SetTexture("_MainTex", source);
|
||||
bool invertY = true; // source.texelSize.y < 0.0f;
|
||||
// Set up the simple Matrix
|
||||
GL.PushMatrix();
|
||||
GL.LoadIdentity();
|
||||
GL.LoadProjectionMatrix(cameraForProjectionMatrix.projectionMatrix);
|
||||
|
||||
float fovYHalfRad = cameraForProjectionMatrix.fieldOfView * 0.5f * Mathf.Deg2Rad;
|
||||
float cotangent = Mathf.Cos(fovYHalfRad) / Mathf.Sin(fovYHalfRad);
|
||||
float asp = cameraForProjectionMatrix.aspect;
|
||||
|
||||
float x1 = asp/-cotangent;
|
||||
float x2 = asp/cotangent;
|
||||
float y1 = 1.0f/-cotangent;
|
||||
float y2 = 1.0f/cotangent;
|
||||
|
||||
float sc = 1.0f; // magic constant (for now)
|
||||
|
||||
x1 *= dist * sc;
|
||||
x2 *= dist * sc;
|
||||
y1 *= dist * sc;
|
||||
y2 *= dist * sc;
|
||||
|
||||
float z1 = -dist;
|
||||
|
||||
for (int i = 0; i < material.passCount; i++)
|
||||
{
|
||||
material.SetPass(i);
|
||||
|
||||
GL.Begin(GL.QUADS);
|
||||
float y1_; float y2_;
|
||||
if (invertY)
|
||||
{
|
||||
y1_ = 1.0f; y2_ = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
y1_ = 0.0f; y2_ = 1.0f;
|
||||
}
|
||||
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, z1);
|
||||
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, z1);
|
||||
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, z1);
|
||||
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, z1);
|
||||
GL.End();
|
||||
}
|
||||
|
||||
GL.PopMatrix();
|
||||
}
|
||||
|
||||
static void DrawBorder (
|
||||
RenderTexture dest ,
|
||||
Material material )
|
||||
{
|
||||
float x1;
|
||||
float x2;
|
||||
float y1;
|
||||
float y2;
|
||||
|
||||
RenderTexture.active = dest;
|
||||
bool invertY = true; // source.texelSize.y < 0.0ff;
|
||||
// Set up the simple Matrix
|
||||
GL.PushMatrix();
|
||||
GL.LoadOrtho();
|
||||
|
||||
for (int i = 0; i < material.passCount; i++)
|
||||
{
|
||||
material.SetPass(i);
|
||||
|
||||
float y1_; float y2_;
|
||||
if (invertY)
|
||||
{
|
||||
y1_ = 1.0f; y2_ = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
y1_ = 0.0f; y2_ = 1.0f;
|
||||
}
|
||||
|
||||
// left
|
||||
x1 = 0.0f;
|
||||
x2 = 0.0f + 1.0f/(dest.width*1.0f);
|
||||
y1 = 0.0f;
|
||||
y2 = 1.0f;
|
||||
GL.Begin(GL.QUADS);
|
||||
|
||||
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
|
||||
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
|
||||
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
|
||||
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);
|
||||
|
||||
// right
|
||||
x1 = 1.0f - 1.0f/(dest.width*1.0f);
|
||||
x2 = 1.0f;
|
||||
y1 = 0.0f;
|
||||
y2 = 1.0f;
|
||||
|
||||
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
|
||||
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
|
||||
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
|
||||
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);
|
||||
|
||||
// top
|
||||
x1 = 0.0f;
|
||||
x2 = 1.0f;
|
||||
y1 = 0.0f;
|
||||
y2 = 0.0f + 1.0f/(dest.height*1.0f);
|
||||
|
||||
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
|
||||
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
|
||||
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
|
||||
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);
|
||||
|
||||
// bottom
|
||||
x1 = 0.0f;
|
||||
x2 = 1.0f;
|
||||
y1 = 1.0f - 1.0f/(dest.height*1.0f);
|
||||
y2 = 1.0f;
|
||||
|
||||
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
|
||||
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
|
||||
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
|
||||
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);
|
||||
|
||||
GL.End();
|
||||
}
|
||||
|
||||
GL.PopMatrix();
|
||||
}
|
||||
|
||||
static void DrawLowLevelQuad ( float x1, float x2, float y1, float y2, RenderTexture source, RenderTexture dest, Material material )
|
||||
{
|
||||
// Make the destination texture the target for all rendering
|
||||
RenderTexture.active = dest;
|
||||
// Assign the source texture to a property from a shader
|
||||
material.SetTexture("_MainTex", source);
|
||||
bool invertY = true; // source.texelSize.y < 0.0f;
|
||||
// Set up the simple Matrix
|
||||
GL.PushMatrix();
|
||||
GL.LoadOrtho();
|
||||
|
||||
for (int i = 0; i < material.passCount; i++)
|
||||
{
|
||||
material.SetPass(i);
|
||||
|
||||
GL.Begin(GL.QUADS);
|
||||
float y1_; float y2_;
|
||||
if (invertY)
|
||||
{
|
||||
y1_ = 1.0f; y2_ = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
y1_ = 0.0f; y2_ = 1.0f;
|
||||
}
|
||||
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
|
||||
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
|
||||
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
|
||||
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);
|
||||
GL.End();
|
||||
}
|
||||
|
||||
GL.PopMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50b03df8f04b5c441aaac5b7fccb4734
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
125
Assets/Standard Assets/Effects/ImageEffects/Scripts/Quads.cs
Normal file
125
Assets/Standard Assets/Effects/ImageEffects/Scripts/Quads.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
// same as Triangles but creates quads instead which generally
|
||||
// saves fillrate at the expense for more triangles to issue
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
class Quads
|
||||
{
|
||||
static Mesh[] meshes;
|
||||
static int currentQuads = 0;
|
||||
|
||||
static bool HasMeshes ()
|
||||
{
|
||||
if (meshes == null)
|
||||
return false;
|
||||
foreach (Mesh m in meshes)
|
||||
if (null == m)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static void Cleanup ()
|
||||
{
|
||||
if (meshes == null)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < meshes.Length; i++)
|
||||
{
|
||||
if (null != meshes[i])
|
||||
{
|
||||
Object.DestroyImmediate (meshes[i]);
|
||||
meshes[i] = null;
|
||||
}
|
||||
}
|
||||
meshes = null;
|
||||
}
|
||||
|
||||
|
||||
public static Mesh[] GetMeshes ( int totalWidth, int totalHeight)
|
||||
{
|
||||
if (HasMeshes () && (currentQuads == (totalWidth * totalHeight))) {
|
||||
return meshes;
|
||||
}
|
||||
|
||||
int maxQuads = 65000 / 6;
|
||||
int totalQuads = totalWidth * totalHeight;
|
||||
currentQuads = totalQuads;
|
||||
|
||||
int meshCount = Mathf.CeilToInt ((1.0f * totalQuads) / (1.0f * maxQuads));
|
||||
|
||||
meshes = new Mesh [meshCount];
|
||||
|
||||
int i = 0;
|
||||
int index = 0;
|
||||
for (i = 0; i < totalQuads; i += maxQuads)
|
||||
{
|
||||
int quads = Mathf.FloorToInt (Mathf.Clamp ((totalQuads-i), 0, maxQuads));
|
||||
|
||||
meshes[index] = GetMesh (quads, i, totalWidth, totalHeight);
|
||||
index++;
|
||||
}
|
||||
|
||||
return meshes;
|
||||
}
|
||||
|
||||
static Mesh GetMesh (int triCount, int triOffset, int totalWidth, int totalHeight)
|
||||
{
|
||||
var mesh = new Mesh ();
|
||||
mesh.hideFlags = HideFlags.DontSave;
|
||||
|
||||
var verts = new Vector3[triCount * 4];
|
||||
var uvs = new Vector2[triCount * 4];
|
||||
var uvs2 = new Vector2[triCount * 4];
|
||||
var tris = new int[triCount * 6];
|
||||
|
||||
for (int i = 0; i < triCount; i++)
|
||||
{
|
||||
int i4 = i * 4;
|
||||
int i6 = i * 6;
|
||||
|
||||
int vertexWithOffset = triOffset + i;
|
||||
|
||||
float x = Mathf.Floor (vertexWithOffset % totalWidth) / totalWidth;
|
||||
float y = Mathf.Floor (vertexWithOffset / totalWidth) / totalHeight;
|
||||
|
||||
Vector3 position = new Vector3 (x * 2 - 1, y * 2 - 1, 1.0f);
|
||||
|
||||
verts[i4 + 0] = position;
|
||||
verts[i4 + 1] = position;
|
||||
verts[i4 + 2] = position;
|
||||
verts[i4 + 3] = position;
|
||||
|
||||
uvs[i4 + 0] = new Vector2 (0.0f, 0.0f);
|
||||
uvs[i4 + 1] = new Vector2 (1.0f, 0.0f);
|
||||
uvs[i4 + 2] = new Vector2 (0.0f, 1.0f);
|
||||
uvs[i4 + 3] = new Vector2 (1.0f, 1.0f);
|
||||
|
||||
uvs2[i4 + 0] = new Vector2 (x, y);
|
||||
uvs2[i4 + 1] = new Vector2 (x, y);
|
||||
uvs2[i4 + 2] = new Vector2 (x, y);
|
||||
uvs2[i4 + 3] = new Vector2 (x, y);
|
||||
|
||||
tris[i6 + 0] = i4 + 0;
|
||||
tris[i6 + 1] = i4 + 1;
|
||||
tris[i6 + 2] = i4 + 2;
|
||||
|
||||
tris[i6 + 3] = i4 + 1;
|
||||
tris[i6 + 4] = i4 + 2;
|
||||
tris[i6 + 5] = i4 + 3;
|
||||
|
||||
}
|
||||
|
||||
mesh.vertices = verts;
|
||||
mesh.triangles = tris;
|
||||
mesh.uv = uvs;
|
||||
mesh.uv2 = uvs2;
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a20852ce049f64e4695a48b6a354be83
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Other/Screen Overlay")]
|
||||
public class ScreenOverlay : PostEffectsBase
|
||||
{
|
||||
public enum OverlayBlendMode
|
||||
{
|
||||
Additive = 0,
|
||||
ScreenBlend = 1,
|
||||
Multiply = 2,
|
||||
Overlay = 3,
|
||||
AlphaBlend = 4,
|
||||
}
|
||||
|
||||
public OverlayBlendMode blendMode = OverlayBlendMode.Overlay;
|
||||
public float intensity = 1.0f;
|
||||
public Texture2D texture = null;
|
||||
|
||||
public Shader overlayShader = null;
|
||||
private Material overlayMaterial = null;
|
||||
|
||||
|
||||
public override bool CheckResources ()
|
||||
{
|
||||
CheckSupport (false);
|
||||
|
||||
overlayMaterial = CheckShaderAndCreateMaterial (overlayShader, overlayMaterial);
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources() == false)
|
||||
{
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
Vector4 UV_Transform = new Vector4(1, 0, 0, 1);
|
||||
|
||||
#if UNITY_WP8
|
||||
// WP8 has no OS support for rotating screen with device orientation,
|
||||
// so we do those transformations ourselves.
|
||||
if (Screen.orientation == ScreenOrientation.LandscapeLeft) {
|
||||
UV_Transform = new Vector4(0, -1, 1, 0);
|
||||
}
|
||||
if (Screen.orientation == ScreenOrientation.LandscapeRight) {
|
||||
UV_Transform = new Vector4(0, 1, -1, 0);
|
||||
}
|
||||
if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {
|
||||
UV_Transform = new Vector4(-1, 0, 0, -1);
|
||||
}
|
||||
#endif
|
||||
|
||||
overlayMaterial.SetVector("_UV_Transform", UV_Transform);
|
||||
overlayMaterial.SetFloat ("_Intensity", intensity);
|
||||
overlayMaterial.SetTexture ("_Overlay", texture);
|
||||
Graphics.Blit (source, destination, overlayMaterial, (int) blendMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f19108706fdce9469603d07980eb8ad
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- texture: {instanceID: 0}
|
||||
- overlayShader: {fileID: 4800000, guid: 8c81db0e527d24acc9bcec04e87781bd, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Rendering/Screen Space Ambient Obscurance")]
|
||||
class ScreenSpaceAmbientObscurance : PostEffectsBase {
|
||||
[Range (0,3)]
|
||||
public float intensity = 0.5f;
|
||||
[Range (0.1f,3)]
|
||||
public float radius = 0.2f;
|
||||
[Range (0,3)]
|
||||
public int blurIterations = 1;
|
||||
[Range (0,5)]
|
||||
public float blurFilterDistance = 1.25f;
|
||||
[Range (0,1)]
|
||||
public int downsample = 0;
|
||||
|
||||
public Texture2D rand = null;
|
||||
public Shader aoShader= null;
|
||||
|
||||
private Material aoMaterial = null;
|
||||
|
||||
public override bool CheckResources () {
|
||||
CheckSupport (true);
|
||||
|
||||
aoMaterial = CheckShaderAndCreateMaterial (aoShader, aoMaterial);
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnDisable () {
|
||||
if (aoMaterial)
|
||||
DestroyImmediate (aoMaterial);
|
||||
aoMaterial = null;
|
||||
}
|
||||
|
||||
[ImageEffectOpaque]
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
if (CheckResources () == false) {
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
Matrix4x4 P = GetComponent<Camera>().projectionMatrix;
|
||||
var invP= P.inverse;
|
||||
Vector4 projInfo = new Vector4
|
||||
((-2.0f / (Screen.width * P[0])),
|
||||
(-2.0f / (Screen.height * P[5])),
|
||||
((1.0f - P[2]) / P[0]),
|
||||
((1.0f + P[6]) / P[5]));
|
||||
|
||||
aoMaterial.SetVector ("_ProjInfo", projInfo); // used for unprojection
|
||||
aoMaterial.SetMatrix ("_ProjectionInv", invP); // only used for reference
|
||||
aoMaterial.SetTexture ("_Rand", rand); // not needed for DX11 :)
|
||||
aoMaterial.SetFloat ("_Radius", radius);
|
||||
aoMaterial.SetFloat ("_Radius2", radius*radius);
|
||||
aoMaterial.SetFloat ("_Intensity", intensity);
|
||||
aoMaterial.SetFloat ("_BlurFilterDistance", blurFilterDistance);
|
||||
|
||||
int rtW = source.width;
|
||||
int rtH = source.height;
|
||||
|
||||
RenderTexture tmpRt = RenderTexture.GetTemporary (rtW>>downsample, rtH>>downsample);
|
||||
RenderTexture tmpRt2;
|
||||
|
||||
Graphics.Blit (source, tmpRt, aoMaterial, 0);
|
||||
|
||||
if (downsample > 0) {
|
||||
tmpRt2 = RenderTexture.GetTemporary (rtW, rtH);
|
||||
Graphics.Blit(tmpRt, tmpRt2, aoMaterial, 4);
|
||||
RenderTexture.ReleaseTemporary (tmpRt);
|
||||
tmpRt = tmpRt2;
|
||||
|
||||
// @NOTE: it's probably worth a shot to blur in low resolution
|
||||
// instead with a bilat-upsample afterwards ...
|
||||
}
|
||||
|
||||
for (int i = 0; i < blurIterations; i++) {
|
||||
aoMaterial.SetVector("_Axis", new Vector2(1.0f,0.0f));
|
||||
tmpRt2 = RenderTexture.GetTemporary (rtW, rtH);
|
||||
Graphics.Blit (tmpRt, tmpRt2, aoMaterial, 1);
|
||||
RenderTexture.ReleaseTemporary (tmpRt);
|
||||
|
||||
aoMaterial.SetVector("_Axis", new Vector2(0.0f,1.0f));
|
||||
tmpRt = RenderTexture.GetTemporary (rtW, rtH);
|
||||
Graphics.Blit (tmpRt2, tmpRt, aoMaterial, 1);
|
||||
RenderTexture.ReleaseTemporary (tmpRt2);
|
||||
}
|
||||
|
||||
aoMaterial.SetTexture ("_AOTex", tmpRt);
|
||||
Graphics.Blit (source, destination, aoMaterial, 2);
|
||||
|
||||
RenderTexture.ReleaseTemporary (tmpRt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 75febd242c999f04d9654522a10c006b
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- rand: {fileID: 2800000, guid: a181ca8e3c62f3e4b8f183f6c586b032, type: 3}
|
||||
- aoShader: {fileID: 4800000, guid: 95616c020c5604dda96cf76afbbc0272, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,205 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu("Image Effects/Rendering/Screen Space Ambient Occlusion")]
|
||||
public class ScreenSpaceAmbientOcclusion : MonoBehaviour
|
||||
{
|
||||
public enum SSAOSamples
|
||||
{
|
||||
Low = 0,
|
||||
Medium = 1,
|
||||
High = 2,
|
||||
}
|
||||
|
||||
[Range(0.05f, 1.0f)]
|
||||
public float m_Radius = 0.4f;
|
||||
public SSAOSamples m_SampleCount = SSAOSamples.Medium;
|
||||
[Range(0.5f, 4.0f)]
|
||||
public float m_OcclusionIntensity = 1.5f;
|
||||
[Range(0, 4)]
|
||||
public int m_Blur = 2;
|
||||
[Range(1,6)]
|
||||
public int m_Downsampling = 2;
|
||||
[Range(0.2f, 2.0f)]
|
||||
public float m_OcclusionAttenuation = 1.0f;
|
||||
[Range(0.00001f, 0.5f)]
|
||||
public float m_MinZ = 0.01f;
|
||||
|
||||
public Shader m_SSAOShader;
|
||||
private Material m_SSAOMaterial;
|
||||
|
||||
public Texture2D m_RandomTexture;
|
||||
|
||||
private bool m_Supported;
|
||||
|
||||
private static Material CreateMaterial (Shader shader)
|
||||
{
|
||||
if (!shader)
|
||||
return null;
|
||||
Material m = new Material (shader);
|
||||
m.hideFlags = HideFlags.HideAndDontSave;
|
||||
return m;
|
||||
}
|
||||
private static void DestroyMaterial (Material mat)
|
||||
{
|
||||
if (mat)
|
||||
{
|
||||
DestroyImmediate (mat);
|
||||
mat = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
DestroyMaterial (m_SSAOMaterial);
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (!SystemInfo.supportsImageEffects || !SystemInfo.SupportsRenderTextureFormat (RenderTextureFormat.Depth))
|
||||
{
|
||||
m_Supported = false;
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
CreateMaterials ();
|
||||
if (!m_SSAOMaterial || m_SSAOMaterial.passCount != 5)
|
||||
{
|
||||
m_Supported = false;
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
//CreateRandomTable (26, 0.2f);
|
||||
|
||||
m_Supported = true;
|
||||
}
|
||||
|
||||
void OnEnable () {
|
||||
GetComponent<Camera>().depthTextureMode |= DepthTextureMode.DepthNormals;
|
||||
}
|
||||
|
||||
private void CreateMaterials ()
|
||||
{
|
||||
if (!m_SSAOMaterial && m_SSAOShader.isSupported)
|
||||
{
|
||||
m_SSAOMaterial = CreateMaterial (m_SSAOShader);
|
||||
m_SSAOMaterial.SetTexture ("_RandomTexture", m_RandomTexture);
|
||||
}
|
||||
}
|
||||
|
||||
[ImageEffectOpaque]
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (!m_Supported || !m_SSAOShader.isSupported) {
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
CreateMaterials ();
|
||||
|
||||
m_Downsampling = Mathf.Clamp (m_Downsampling, 1, 6);
|
||||
m_Radius = Mathf.Clamp (m_Radius, 0.05f, 1.0f);
|
||||
m_MinZ = Mathf.Clamp (m_MinZ, 0.00001f, 0.5f);
|
||||
m_OcclusionIntensity = Mathf.Clamp (m_OcclusionIntensity, 0.5f, 4.0f);
|
||||
m_OcclusionAttenuation = Mathf.Clamp (m_OcclusionAttenuation, 0.2f, 2.0f);
|
||||
m_Blur = Mathf.Clamp (m_Blur, 0, 4);
|
||||
|
||||
// Render SSAO term into a smaller texture
|
||||
RenderTexture rtAO = RenderTexture.GetTemporary (source.width / m_Downsampling, source.height / m_Downsampling, 0);
|
||||
float fovY = GetComponent<Camera>().fieldOfView;
|
||||
float far = GetComponent<Camera>().farClipPlane;
|
||||
float y = Mathf.Tan (fovY * Mathf.Deg2Rad * 0.5f) * far;
|
||||
float x = y * GetComponent<Camera>().aspect;
|
||||
m_SSAOMaterial.SetVector ("_FarCorner", new Vector3(x,y,far));
|
||||
int noiseWidth, noiseHeight;
|
||||
if (m_RandomTexture) {
|
||||
noiseWidth = m_RandomTexture.width;
|
||||
noiseHeight = m_RandomTexture.height;
|
||||
} else {
|
||||
noiseWidth = 1; noiseHeight = 1;
|
||||
}
|
||||
m_SSAOMaterial.SetVector ("_NoiseScale", new Vector3 ((float)rtAO.width / noiseWidth, (float)rtAO.height / noiseHeight, 0.0f));
|
||||
m_SSAOMaterial.SetVector ("_Params", new Vector4(
|
||||
m_Radius,
|
||||
m_MinZ,
|
||||
1.0f / m_OcclusionAttenuation,
|
||||
m_OcclusionIntensity));
|
||||
|
||||
bool doBlur = m_Blur > 0;
|
||||
Graphics.Blit (doBlur ? null : source, rtAO, m_SSAOMaterial, (int)m_SampleCount);
|
||||
|
||||
if (doBlur)
|
||||
{
|
||||
// Blur SSAO horizontally
|
||||
RenderTexture rtBlurX = RenderTexture.GetTemporary (source.width, source.height, 0);
|
||||
m_SSAOMaterial.SetVector ("_TexelOffsetScale",
|
||||
new Vector4 ((float)m_Blur / source.width, 0,0,0));
|
||||
m_SSAOMaterial.SetTexture ("_SSAO", rtAO);
|
||||
Graphics.Blit (null, rtBlurX, m_SSAOMaterial, 3);
|
||||
RenderTexture.ReleaseTemporary (rtAO); // original rtAO not needed anymore
|
||||
|
||||
// Blur SSAO vertically
|
||||
RenderTexture rtBlurY = RenderTexture.GetTemporary (source.width, source.height, 0);
|
||||
m_SSAOMaterial.SetVector ("_TexelOffsetScale",
|
||||
new Vector4 (0, (float)m_Blur/source.height, 0,0));
|
||||
m_SSAOMaterial.SetTexture ("_SSAO", rtBlurX);
|
||||
Graphics.Blit (source, rtBlurY, m_SSAOMaterial, 3);
|
||||
RenderTexture.ReleaseTemporary (rtBlurX); // blurX RT not needed anymore
|
||||
|
||||
rtAO = rtBlurY; // AO is the blurred one now
|
||||
}
|
||||
|
||||
// Modulate scene rendering with SSAO
|
||||
m_SSAOMaterial.SetTexture ("_SSAO", rtAO);
|
||||
Graphics.Blit (source, destination, m_SSAOMaterial, 4);
|
||||
|
||||
RenderTexture.ReleaseTemporary (rtAO);
|
||||
}
|
||||
|
||||
/*
|
||||
private void CreateRandomTable (int count, float minLength)
|
||||
{
|
||||
Random.seed = 1337;
|
||||
Vector3[] samples = new Vector3[count];
|
||||
// initial samples
|
||||
for (int i = 0; i < count; ++i)
|
||||
samples[i] = Random.onUnitSphere;
|
||||
// energy minimization: push samples away from others
|
||||
int iterations = 100;
|
||||
while (iterations-- > 0) {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
Vector3 vec = samples[i];
|
||||
Vector3 res = Vector3.zero;
|
||||
// minimize with other samples
|
||||
for (int j = 0; j < count; ++j) {
|
||||
Vector3 force = vec - samples[j];
|
||||
float fac = Vector3.Dot (force, force);
|
||||
if (fac > 0.00001f)
|
||||
res += force * (1.0f / fac);
|
||||
}
|
||||
samples[i] = (samples[i] + res * 0.5f).normalized;
|
||||
}
|
||||
}
|
||||
// now scale samples between minLength and 1.0
|
||||
for (int i = 0; i < count; ++i) {
|
||||
samples[i] = samples[i] * Random.Range (minLength, 1.0f);
|
||||
}
|
||||
|
||||
string table = string.Format ("#define SAMPLE_COUNT {0}\n", count);
|
||||
table += "const float3 RAND_SAMPLES[SAMPLE_COUNT] = {\n";
|
||||
for (int i = 0; i < count; ++i) {
|
||||
Vector3 v = samples[i];
|
||||
table += string.Format("\tfloat3({0},{1},{2}),\n", v.x, v.y, v.z);
|
||||
}
|
||||
table += "};\n";
|
||||
Debug.Log (table);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b0923359e9e352a4b9b11c7b7161ad67
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- m_SSAOShader: {fileID: 4800000, guid: 43ca18288c424f645aaa1e9e07f04c50, type: 3}
|
||||
- m_RandomTexture: {fileID: 2800000, guid: a181ca8e3c62f3e4b8f183f6c586b032, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu("Image Effects/Color Adjustments/Sepia Tone")]
|
||||
public class SepiaTone : ImageEffectBase
|
||||
{
|
||||
// Called by camera to apply image effect
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
Graphics.Blit (source, destination, material);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a07a781cad112c75d0008dfa8d76c639
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- shader: {fileID: 4800000, guid: b6aa781cad112c75d0008dfa8d76c639, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user