UnityMol  0.9.6-875
UnityMol viewer / In developement
DreamEffect.cs
Go to the documentation of this file.
1 using UnityEngine;
2 using System.Collections;
3 
4 [ExecuteInEditMode]
5 [RequireComponent (typeof(Camera))]
6 [AddComponentMenu("Image Effects/Dream Effect")]
7 public class DreamEffect : MonoBehaviour
8 {
9 
11  public int iterations = 3;
12 
16  public float blurSpread = 0.6f;
17 
18  public float ContrastPower = 5.0f;
19  public float ContrastBias = 0.3f;
20 
21 
22  // --------------------------------------------------------
23  // The blur iteration shader.
24  // Basically it just takes 4 texture samples and averages them.
25  // By applying it repeatedly and spreading out sample locations
26  // we get a Gaussian blur approximation.
27 
28  private static string blurMatString =
29 @"Shader ""BlurConeTap"" {
30  SubShader {
31  Pass {
32  ZTest Always Cull Off ZWrite Off Fog { Mode Off }
33  SetTexture [__RenderTex] {constantColor (0,0,0,0.25) combine texture * constant alpha}
34  SetTexture [__RenderTex] {constantColor (0,0,0,0.25) combine texture * constant + previous}
35  SetTexture [__RenderTex] {constantColor (0,0,0,0.25) combine texture * constant + previous}
36  SetTexture [__RenderTex] {constantColor (0,0,0,0.25) combine texture * constant + previous}
37  }
38  }
39  Fallback off
40 }";
41 
42  static Material m_BlurMaterial = null;
43  protected static Material blurMaterial {
44  get {
45  if (m_BlurMaterial == null) {
46  m_BlurMaterial = new Material( blurMatString );
47  m_BlurMaterial.hideFlags = HideFlags.HideAndDontSave;
48  m_BlurMaterial.shader.hideFlags = HideFlags.HideAndDontSave;
49  }
50  return m_BlurMaterial;
51  }
52  }
53 
54  public Shader blackChannelShader;
55  Material m_BlackChannelMaterial = null;
56  protected Material BlackChannelMaterial {
57  get {
58  if (m_BlackChannelMaterial == null) {
59  m_BlackChannelMaterial = new Material( blackChannelShader );
60  m_BlackChannelMaterial.hideFlags = HideFlags.HideAndDontSave;
61  }
63  }
64  }
65 
66  protected void OnDisable() {
67  if( m_BlurMaterial ) {
68  DestroyImmediate( m_BlurMaterial.shader );
69  DestroyImmediate( m_BlurMaterial );
70  }
71 
72  if( m_BlackChannelMaterial ) {
73  DestroyImmediate( m_BlackChannelMaterial, true );
74  }
75 
76  }
77 
78  // --------------------------------------------------------
79 
80  protected void Start()
81  {
82  // Disable if we don't support image effects
83  if (!SystemInfo.supportsImageEffects) {
84  enabled = false;
85  return;
86  }
87  // Disable if the shader can't run on the users graphics card
88  if (!blurMaterial.shader.isSupported) {
89  enabled = false;
90  return;
91  }
92 
93  }
94 
95  // Performs one blur iteration.
96  public void FourTapCone (RenderTexture source, RenderTexture dest, int iteration)
97  {
98  RenderTexture.active = dest;
99  source.SetGlobalShaderProperty ("__RenderTex");
100 
101  float offsetX = (.5F+iteration*blurSpread) / (float)source.width;
102  float offsetY = (.5F+iteration*blurSpread) / (float)source.height;
103  GL.PushMatrix ();
104  GL.LoadOrtho ();
105 
106  for (int i = 0; i < blurMaterial.passCount; i++) {
107  blurMaterial.SetPass (i);
108  Render4TapQuad( dest, offsetX, offsetY );
109  }
110  GL.PopMatrix ();
111  }
112 
113  // Downsamples the texture to a quarter resolution.
114  private void DownSample4x (RenderTexture source, RenderTexture dest)
115  {
116  RenderTexture.active = dest;
117  source.SetGlobalShaderProperty ("__RenderTex");
118 
119  float offsetX = 1.0f / (float)source.width;
120  float offsetY = 1.0f / (float)source.height;
121 
122  GL.PushMatrix ();
123  GL.LoadOrtho ();
124  for (int i = 0; i < blurMaterial.passCount; i++)
125  {
126  blurMaterial.SetPass (i);
127  Render4TapQuad( dest, offsetX, offsetY );
128  }
129  GL.PopMatrix ();
130  }
131 
132  // Called by camera to apply image effect
133  void OnRenderImage (RenderTexture source, RenderTexture destination)
134  {
135 
136  RenderTexture buffer = RenderTexture.GetTemporary(source.width/4, source.height/4, 0);
137  RenderTexture buffer2 = RenderTexture.GetTemporary(source.width/4, source.height/4, 0);
138  RenderTexture dreamBuffer = RenderTexture.GetTemporary( source.width, source.height, 0);
139 
140  BlackChannelMaterial.SetFloat( "_ContrastPower", ContrastPower );
141  BlackChannelMaterial.SetFloat( "_ContrastBias", ContrastBias );
142 
143  ImageEffects2.BlitWithMaterial (BlackChannelMaterial , source, dreamBuffer);
144 
145  // Copy source to the 4x4 smaller texture.
146  DownSample4x (source, buffer);
147 
148  // Blur the small texture
149  bool oddEven = true;
150  for(int i = 0; i < iterations; i++)
151  {
152  if( oddEven ) FourTapCone (buffer, buffer2, i);
153  else FourTapCone (buffer2, buffer, i);
154  oddEven = !oddEven;
155  }
156  if( oddEven ) ImageEffects2.Blit(buffer, destination);
157  else ImageEffects2.Blit(buffer2, destination);
158 
159  ImageEffects2.Blit( dreamBuffer, destination, BlendMode.Multiply );
160 
161  RenderTexture.ReleaseTemporary(buffer);
162  RenderTexture.ReleaseTemporary(buffer2);
163  RenderTexture.ReleaseTemporary(dreamBuffer);
164 
165 
166  }
167 
168  private static void Render4TapQuad( RenderTexture dest, float offsetX, float offsetY )
169  {
170  GL.Begin( GL.QUADS );
171 
172  // Direct3D needs interesting texel offsets!
173  Vector2 off = Vector2.zero;
174  if( dest != null )
175  off = dest.GetTexelOffset() * 0.75f;
176 
177  Set4TexCoords( off.x, off.y, offsetX, offsetY );
178  GL.Vertex3( 0,0, .1f );
179 
180  Set4TexCoords( 1.0f + off.x, off.y, offsetX, offsetY );
181  GL.Vertex3( 1,0, .1f );
182 
183  Set4TexCoords( 1.0f + off.x, 1.0f + off.y, offsetX, offsetY );
184  GL.Vertex3( 1,1,.1f );
185 
186  Set4TexCoords( off.x, 1.0f + off.y, offsetX, offsetY );
187  GL.Vertex3( 0,1,.1f );
188 
189  GL.End();
190  }
191 
192  private static void Set4TexCoords( float x, float y, float offsetX, float offsetY )
193  {
194  GL.MultiTexCoord2( 0, x - offsetX, y - offsetY );
195  GL.MultiTexCoord2( 1, x + offsetX, y - offsetY );
196  GL.MultiTexCoord2( 2, x + offsetX, y + offsetY );
197  GL.MultiTexCoord2( 3, x - offsetX, y + offsetY );
198  }
199 }
void Start()
Definition: DreamEffect.cs:80
static void Render4TapQuad(RenderTexture dest, float offsetX, float offsetY)
Definition: DreamEffect.cs:168
Material BlackChannelMaterial
Definition: DreamEffect.cs:56
float ContrastBias
Definition: DreamEffect.cs:19
void DownSample4x(RenderTexture source, RenderTexture dest)
Definition: DreamEffect.cs:114
static Material blurMaterial
Definition: DreamEffect.cs:43
static string blurMatString
Definition: DreamEffect.cs:28
Material m_BlackChannelMaterial
Definition: DreamEffect.cs:55
BlendMode
Blending modes use by the ImageEffects2.Blit functions.
Definition: ImageEffects2.cs:4
void OnRenderImage(RenderTexture source, RenderTexture destination)
Definition: DreamEffect.cs:133
static void BlitWithMaterial(Material material, RenderTexture source, RenderTexture destination)
static Material m_BlurMaterial
Definition: DreamEffect.cs:42
float blurSpread
Blur spread for each iteration.
Definition: DreamEffect.cs:16
void FourTapCone(RenderTexture source, RenderTexture dest, int iteration)
Definition: DreamEffect.cs:96
float ContrastPower
Definition: DreamEffect.cs:18
void OnDisable()
Definition: DreamEffect.cs:66
A Utility class for performing various image based rendering tasks.
Shader blackChannelShader
Definition: DreamEffect.cs:54
static void Blit(RenderTexture source, RenderTexture dest, BlendMode blendMode)
Copies one render texture onto another.
static void Set4TexCoords(float x, float y, float offsetX, float offsetY)
Definition: DreamEffect.cs:192
int iterations
Blur iterations - larger number means more blur.
Definition: DreamEffect.cs:11