VertexDirt.js 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. /*
  2. VertexDirt plug-in for Unity
  3. Copyright 2014-2015, Zoltan Farago, All rights reserved.
  4. */
  5. #pragma strict
  6. #pragma downcast
  7. /*
  8. class: VertexDirt
  9. Main Vertex dirt class. VertexDirt is an Ambient Occlusion baking plug-in.
  10. */
  11. static class VertexDirt {
  12. // private variables for mesh merging and vertex sampling
  13. private var v : Vector3[];
  14. private var n : Vector3[];
  15. private var c : Color32[];
  16. /*
  17. variable: vertexSample
  18. public variable, but this is used by the baking.
  19. */
  20. var vertexSample : VertexSample = new VertexSample();
  21. /*
  22. integer: sampleWidth
  23. Vertical resolution of the sample. The default value of 64 should be fine in all circumstances.
  24. Lower values could cause visual artefacts.
  25. */
  26. var sampleWidth : int = 64;
  27. /*
  28. integer: sampleHeight
  29. Horizontal resolution of the sample. The default value of 64 should be fine in all circumstances.
  30. Lower values could cause visual artefacts.
  31. */
  32. var sampleHeight : int = 64;
  33. /*
  34. float: samplingBias
  35. The near clip plane of the sampling camera.
  36. */
  37. var samplingBias : float = 0.001;
  38. /*
  39. float: samplingDistance
  40. The far clip plane of the sampling camera.
  41. */
  42. var samplingDistance : float = 100;
  43. /*
  44. float: samplingAngle
  45. The FOV of the sampling camera. Please note that this value normally should be between 100-160.
  46. */
  47. var samplingAngle : float = 100;
  48. /*
  49. boolean: edgeSmooth
  50. Enable to smoothing out hard edges. Basically just averages the normals of the vertices in the same position.
  51. */
  52. var edgeSmooth : boolean = false;
  53. /*
  54. boolean: invertNormals
  55. Set true if you want to render the inside of the objects. Use this parameter enabled to render thickness.
  56. */
  57. var invertNormals : boolean = false;
  58. /*
  59. float: edgeSmoothBias
  60. The range of edge smoothing. The normals of vertices closer than this value will be averaged.
  61. */
  62. var edgeSmoothBias : float = 0.001;
  63. /*
  64. enumeration: skyMode
  65. Parameter for sampling camera backdrop.
  66. */
  67. var skyMode : CameraClearFlags = CameraClearFlags.SolidColor;
  68. /*
  69. boolean: disableOccluders
  70. Set true if you only want to bake the background colour/cubeMap to the vertex colours.
  71. */
  72. var disableOccluders : boolean = false;
  73. /*
  74. variable: skyColor
  75. The colour of the Sky.
  76. */
  77. var skyColor : Color = Color.white;
  78. /*
  79. variable: globalOccluderColor
  80. Colour tint for the occluders. This property is designed for the VDOccluder shader.
  81. */
  82. var globalOccluderColor : Color = Color.black;
  83. /*
  84. string: occluderShader
  85. The shader used on occluders during the bake. The default VD shader is "Hidden/VDOccluder AO"
  86. If this string is empty or the shader is not exist, then the occluder objects will use their original shaders.
  87. */
  88. var occluderShader : String = VDSHADER.AMBIENTOCCLUSION;
  89. /*
  90. variable: skyCube
  91. The cubeMap of the sampling camera's sky.
  92. */
  93. var skyCube : Material;
  94. /*
  95. variable: colorHandlerClass
  96. The component to store baked vertex color data. The component must derived from VDColorHandlerBase class.
  97. The default class is VDColorHandler.
  98. */
  99. var colorHandlerClass : String = "VDColorHandler";
  100. /*
  101. function: Dirt
  102. Main function for vertex baking. The Object[] array will be used.
  103. */
  104. function Dirt(sels : Object[], passes : VDPass[]) {
  105. }
  106. function Dirt(sels : Object[]) {
  107. if (sels.Length > 0) {
  108. //vertex camera
  109. var camGO : GameObject = new GameObject("VDSamplerCamera");
  110. var cam : Camera = camGO.AddComponent(Camera);
  111. camGO.AddComponent.<VDSampler>();
  112. RenderTexture.active = null;
  113. cam.renderingPath = RenderingPath.Forward;
  114. cam.pixelRect = Rect(0,0,sampleWidth, sampleHeight);
  115. cam.aspect = 1.0;
  116. cam.nearClipPlane = samplingBias;
  117. cam.farClipPlane = samplingDistance;
  118. cam.fieldOfView = Mathf.Clamp ( samplingAngle, 5, 160 );
  119. cam.clearFlags = skyMode;
  120. cam.backgroundColor = skyColor;
  121. var tempSkybox : Material = RenderSettings.skybox;
  122. if (skyMode == CameraClearFlags.Skybox) { RenderSettings.skybox = skyCube; }
  123. UpdateShaderVariables();
  124. cam.SetReplacementShader(Shader.Find(occluderShader), disableOccluders ? "ibl-only" : "");
  125. for (var go : Transform in sels) {
  126. if (go.gameObject.GetComponent(MeshFilter)) {
  127. PrepareVertices(go);
  128. ResetColors();
  129. SmoothVertices();
  130. CalcColors(camGO, cam);
  131. ApplyColors(go);
  132. }
  133. }
  134. RenderSettings.skybox = tempSkybox;
  135. GameObject.DestroyImmediate(camGO);
  136. var handlers : VDColorHandlerBase[] = UnityEngine.Object.FindObjectsOfType(VDColorHandlerBase);
  137. for (var handler : VDColorHandlerBase in handlers) {
  138. if (handler.originalMesh && !handler.coloredMesh) {
  139. handler.coloredMesh = UnityEngine.Object.Instantiate(handler.originalMesh);
  140. handler.gameObject.GetComponent(MeshFilter).mesh = handler.coloredMesh;
  141. }
  142. }
  143. }
  144. }
  145. // function to update shader properties
  146. function UpdateShaderVariables() {
  147. Shader.SetGlobalColor("_VDOccluderColor", globalOccluderColor);
  148. }
  149. /*
  150. function: SetPreset
  151. Set preset for VertexDirt. Presets are for batch change common VertexDirt parameters.
  152. */
  153. function SetPreset (v : VDPRESET) {
  154. switch (v) {
  155. case VDPRESET.AMBIENTOCCLUSION :
  156. invertNormals = false;
  157. skyMode = CameraClearFlags.SolidColor;
  158. occluderShader = VDSHADER.AMBIENTOCCLUSION;
  159. break;
  160. }
  161. }
  162. /*
  163. function: ResetSettings
  164. Reset every VertexDirt parameters to defaults.
  165. */
  166. function ResetSettings () {
  167. sampleWidth = 64;
  168. sampleHeight = 64;
  169. samplingBias = 0.001;
  170. samplingDistance = 100;
  171. samplingAngle = 100;
  172. edgeSmooth = false;
  173. invertNormals = false;
  174. edgeSmoothBias = 0.001;
  175. skyMode = CameraClearFlags.SolidColor;
  176. disableOccluders = false;
  177. skyColor = Color.white;
  178. globalOccluderColor = Color.black;
  179. occluderShader = "Hidden/VDOccluder AO";
  180. skyCube = null;
  181. }
  182. //private function CombineVertices(sel : Object[]) {
  183. private function PrepareVertices(go : Transform) {
  184. var vertexCount : int;
  185. v = new Vector3[0];
  186. n = new Vector3[0];
  187. c = new Color32[0];
  188. if (!go.gameObject.GetComponent(VDColorHandlerBase)) {
  189. go.gameObject.AddComponent(VDColorHandler);
  190. }
  191. var v0 = go.gameObject.GetComponent(MeshFilter).sharedMesh.vertices;
  192. var n0 = go.gameObject.GetComponent(MeshFilter).sharedMesh.normals;
  193. for (var t : int = 0; t < v0.Length; t++) {
  194. v0[t] = go.TransformPoint(v0[t]);
  195. n0[t] = Vector3.Normalize(go.TransformDirection(n0[t]));
  196. }
  197. vertexCount += v0.Length;
  198. v = MergeVector3 (v, v0);
  199. n = MergeVector3 (n, n0);
  200. }
  201. function ResetColors() {
  202. c = new Color32[v.length];
  203. }
  204. function ResetColors(Color32) {
  205. c = new Color32[v.length];
  206. }
  207. private function SmoothVertices() {
  208. if (edgeSmooth) {
  209. for (var a = 0; a < v.length; a++) {
  210. for (var d = a; d < v.length; d++) {
  211. if (Vector3.Distance(v[a],v[d]) < edgeSmoothBias) {
  212. n[a] = Vector3.Normalize(n[a] + n[d]);
  213. n[d] = n[a];
  214. }
  215. }
  216. }
  217. for (var k : int = 0; k <c.length; k++) {
  218. c[k] = Color32 (255,255,255,255);
  219. }
  220. }
  221. }
  222. private function CalcColors(camGO : GameObject, cam : Camera) {
  223. for (var vv : int = 0; vv<v.Length; vv++) {
  224. camGO.transform.position = v[vv];
  225. if (invertNormals) {
  226. camGO.transform.LookAt(v[vv] - n[vv]);
  227. }
  228. else {
  229. camGO.transform.LookAt(v[vv] + n[vv]);
  230. }
  231. vertexSample.index = vv;
  232. vertexSample.isCalulated = false;
  233. cam.Render();
  234. while (!vertexSample.isCalulated) {}
  235. c[vv] = vertexSample.color; // * Color(lum,lum,lum,1);
  236. }
  237. }
  238. function SetColorSample(c : Color32) {
  239. vertexSample.color = c;
  240. vertexSample.isCalulated = true;
  241. }
  242. private function ApplyColors(go : Transform) {
  243. var count : int = 0;
  244. var tc : Color32[] = new Color32[go.gameObject.GetComponent(VDColorHandlerBase).originalMesh.vertices.Length];
  245. for (var c0 : int = 0; c0 <go.gameObject.GetComponent(VDColorHandlerBase).originalMesh.vertices.Length; c0++) {
  246. tc[c0] = c[count];
  247. count++;
  248. }
  249. go.gameObject.GetComponent(VDColorHandlerBase).colors = tc;
  250. go.gameObject.GetComponent(VDColorHandlerBase).Refresh();
  251. }
  252. private function MergeVector3 (v1 : Vector3[], v2 : Vector3[]) : Vector3[] {
  253. var v3 = new Vector3[v1.length + v2.length];
  254. System.Array.Copy (v1, v3, v1.length);
  255. System.Array.Copy (v2, 0, v3, v1.length, v2.length);
  256. return v3;
  257. }
  258. }
  259. // Class for passing samples from sampler camera to the VertexDirt class. For internal use only
  260. class VertexSample {
  261. var color : Color32 = Color.white;
  262. var index : int = 0;
  263. var isCalulated : boolean = false;
  264. }