DOFCamera.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. 
  2. #if !UNITY_FLASH && !UNITY_METRO && !UNITY_WP8
  3. using UnityEngine;
  4. public class MGBlendTable
  5. {
  6. int mTableSzX, mTableSzY;
  7. int mnToBlend;
  8. int mTableSzXY; // layer sz
  9. int mTotalSz; // all layers
  10. float[] mpTable; // the dither tables
  11. Random mRandom; // maxsdk pseudo-random number generator
  12. int LayerIndex(int nImage)
  13. {
  14. return nImage * mTableSzXY;
  15. }
  16. // x,y index within a layer....add to layerIndex
  17. int PixelIndex(int x, int y)
  18. {
  19. return y * mTableSzX + x;
  20. }
  21. // 0,y index within a layer....add to layerIndex
  22. int RowIndex(int y)
  23. {
  24. return y * mTableSzX;
  25. }
  26. // these functions wrap a coordinate around the tile sz x or y,
  27. // return index on a tile given a general x,y
  28. int TileX(int x)
  29. {
  30. return x % mTableSzX;
  31. }
  32. int TileY(int y)
  33. {
  34. return y % mTableSzY;
  35. }
  36. // user level index call, wraps to tile...
  37. int Index(int nImage, int x, int y)
  38. {
  39. //wrap to the tile
  40. int x0 = TileX(x);
  41. int y0 = TileY(y);
  42. int indx = LayerIndex(nImage) + PixelIndex(x0, y0);
  43. return indx;
  44. }
  45. // get the table pointer, do your own indexing....
  46. float[] GetTable()
  47. {
  48. return mpTable;
  49. }
  50. // slow, but they do it all
  51. float GetWeight(int nImage, int x, int y)
  52. {
  53. int indx = Index(nImage, x, y);
  54. return mpTable[indx];
  55. }
  56. void SetWeight(int nImage, int x, int y, float w)
  57. {
  58. int indx = Index(nImage, x, y);
  59. mpTable[indx] = w;
  60. }
  61. // returns tile size of the table
  62. void GetTileSz(out int xSz, out int ySz)
  63. {
  64. xSz = mTableSzX;
  65. ySz = mTableSzY;
  66. }
  67. float dummyNoise()
  68. {
  69. return 0.5f;
  70. }
  71. float RandomNoise()
  72. {
  73. return Random.value;
  74. }
  75. public MGBlendTable(int tableX, int tableY, int nToBlend, float ditherAmt, bool normalizeTable)
  76. {
  77. // start w/ the size of each image layer of the table
  78. mTableSzX = (tableX <= 0) ? 1 : tableX;
  79. mTableSzY = (tableY <= 0) ? 1 : tableY;;
  80. mTableSzXY = mTableSzX * mTableSzY;
  81. // then get the total table size
  82. mnToBlend = nToBlend;
  83. mTotalSz = mTableSzXY * mnToBlend;
  84. //DbgAssert( mTotalSz > 0 );
  85. // alloc the 3D table, nImages of tableX x tableY layers
  86. // we have to manage the indices ourselves
  87. mpTable = new float[mTotalSz];
  88. // the initial weight for each image is 1/nToBlend; 10 images, each 1/10th
  89. float initWeight = 1.0f / ((mnToBlend == 0) ? 1.0f : (float)mnToBlend);
  90. // noise function is 0..1, so noiseAmplitude scales the 0..1 range
  91. // such that at ditherAmt == 1.0, the ampitude of the noise is the
  92. // same as the initial weight
  93. float noiseAmplitude = initWeight * ditherAmt;
  94. // fill in the table, just go thru the table linearly, not xy specific
  95. // worry about normalizing things later...
  96. for ( int i = 0; i < mTotalSz; ++i )
  97. {
  98. // compute weight for this sample. note we shift the 0..1 noise
  99. // to be -0.5 to +0.5 prior to scaling
  100. float noiseWeight = noiseAmplitude * (RandomNoise() - 0.5f);
  101. float weight = initWeight + noiseWeight;
  102. // i think it's possible things cd be out of range, since ditherAmt
  103. // is not bounded
  104. mpTable[i] = Mathf.Clamp01(weight);
  105. //Debug.Log("w " + i + " " + mpTable[i]);
  106. }
  107. // see if we need to normalize the table
  108. if ( normalizeTable )
  109. {
  110. // yes , normalize it
  111. // for each pixel in the table....
  112. for ( int y = 0; y < mTableSzY; ++y )
  113. {
  114. for ( int x = 0; x < mTableSzX; ++x )
  115. {
  116. // useful to pre compute this, since it's
  117. // fixed as we scan the layers
  118. int pixelIndex = PixelIndex(x, y);
  119. // find the sum of all the layers thru one pixel
  120. float sum = 0.0f;
  121. for ( int n = 0; n < mnToBlend; ++n )
  122. {
  123. // compute final index by adding in layer
  124. int index = LayerIndex(n) + pixelIndex;
  125. // add this layer to the sum
  126. sum += mpTable[index];
  127. }
  128. // now normalize...make the sum == 1.0
  129. float norm = 1.0f / ((sum == 0.0f) ? 1.0f : sum);
  130. for ( int n = 0; n < mnToBlend; ++n )
  131. {
  132. int index = LayerIndex(n) + pixelIndex;
  133. // scale this layer by the norm
  134. mpTable[index] *= norm;
  135. }
  136. }
  137. }
  138. }
  139. }
  140. public void BlendImages(Color[,] pDstBM, Color[,] pSrcBM, int width, int height, int nImage)
  141. {
  142. // index at (nImage,0,0)
  143. int layerIndex = LayerIndex(nImage);
  144. // for each line of the image...
  145. for ( int nLine = 0; nLine < height; ++nLine )
  146. {
  147. int rowIndex = RowIndex(TileY(nLine)) + layerIndex;
  148. //int index = nLine * width;
  149. for ( int nPix = 0; nPix < width; ++nPix )
  150. {
  151. float w = mpTable[rowIndex + TileX(nPix)];
  152. pDstBM[nPix, nLine] += pSrcBM[nPix, nLine] * w; //pSrcBM[index + nPix];
  153. Mathf.Clamp01(pDstBM[nPix, nLine].r);
  154. Mathf.Clamp01(pDstBM[nPix, nLine].g);
  155. Mathf.Clamp01(pDstBM[nPix, nLine].b);
  156. }
  157. }
  158. }
  159. }
  160. [ExecuteInEditMode]
  161. public class DOFCamera : MonoBehaviour
  162. {
  163. public Camera srcCamera;
  164. public float sampleRadius = 4.0f;
  165. public float alpha;
  166. public float focalDistance = 8.0f;
  167. Vector3 tpos;
  168. void Update()
  169. {
  170. if ( srcCamera != null )
  171. {
  172. float theta = alpha * Mathf.PI * 2.0f;
  173. float radius = sampleRadius;
  174. float uOffset = radius * Mathf.Cos(theta);
  175. float vOffset = radius * Mathf.Sin(theta);
  176. Vector3 newCameraLocation = new Vector3(uOffset, vOffset, 0.0f);
  177. Vector3 initialTargetLocation = srcCamera.transform.forward * focalDistance; //new Vector3(0.0f, 0.0f, -focalDistance);
  178. tpos = initialTargetLocation + srcCamera.transform.position; //srcCamera.transform.TransformPoint(initialTargetLocation);
  179. transform.position = srcCamera.transform.TransformPoint(newCameraLocation);
  180. transform.LookAt(tpos);
  181. }
  182. }
  183. public void OnDrawGizmos()
  184. {
  185. if ( srcCamera != null )
  186. {
  187. Gizmos.DrawLine(transform.position, tpos);
  188. }
  189. }
  190. }
  191. #endif