tag:blogger.com,1999:blog-15332104680456389822024-03-19T02:41:28.691-07:00 Dabble DuoChronicles of our epic weekend projects.Nancyhttp://www.blogger.com/profile/02060201379198295014noreply@blogger.comBlogger10125tag:blogger.com,1999:blog-1533210468045638982.post-20462110923418487982014-02-19T00:28:00.000-08:002015-03-01T01:06:53.997-08:00Dabble #2 Ice ManWe're continuing our vignette building in Unity. This time we're executing an idea with more shots, more effects, and most importantly, more hair. We've done a lot of artwork for this already and woul like to share it with you.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitR2NCJCXHcd-_KdPy06MpTpDcZ_wH8dSfBobjjw1ikghpnFDi6UzSGUAtqm7hOWjazKxU3c0Qeedyj0tVPzJF9y9Nj0VOfZNGSBGj08DuepKbZlH326I3s4N7sbgKcEVIi2zB5ESJdGnH/s1600/Surveying2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitR2NCJCXHcd-_KdPy06MpTpDcZ_wH8dSfBobjjw1ikghpnFDi6UzSGUAtqm7hOWjazKxU3c0Qeedyj0tVPzJF9y9Nj0VOfZNGSBGj08DuepKbZlH326I3s4N7sbgKcEVIi2zB5ESJdGnH/s1600/Surveying2.png" height="266" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i style="font-size: small;">Nancy</i></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGs459OJ8mYfsfWTTYC3DSul1L1swMRmGLakhBdemrk1CQebl-aypU39ierRClmA1YSk5o4KfiRgxGspswY9oAyfVGK11fvXNVnRNnlwSq8DV4X7tvmOl9U0BUv9JPnb53U2ltBoaN1h-r/s1600/InuitWolfWide.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGs459OJ8mYfsfWTTYC3DSul1L1swMRmGLakhBdemrk1CQebl-aypU39ierRClmA1YSk5o4KfiRgxGspswY9oAyfVGK11fvXNVnRNnlwSq8DV4X7tvmOl9U0BUv9JPnb53U2ltBoaN1h-r/s1600/InuitWolfWide.jpg" height="265" width="640" /></a></div>
<div class="" style="clear: both; text-align: center;">
<span style="font-size: x-small;"><i>Lou</i></span></div>
<div class="" style="clear: both; text-align: center;">
<span style="font-size: x-small;"><i><br /></i></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNsfzQusNKvESZdyhMKWjwPXcyRXs4yqStT7805ZfoBJtuOLfv0sJHxocQI167gJPPptnlY4mfTLEhmJKWj6mKlgkGQViTNXiVyflPhb9QsIHkHl-xRoZUr29J5PaUhsHuuSayWa3mJ7Us/s1600/Shadows.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNsfzQusNKvESZdyhMKWjwPXcyRXs4yqStT7805ZfoBJtuOLfv0sJHxocQI167gJPPptnlY4mfTLEhmJKWj6mKlgkGQViTNXiVyflPhb9QsIHkHl-xRoZUr29J5PaUhsHuuSayWa3mJ7Us/s1600/Shadows.jpg" height="267" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: x-small;"><i>Nancy</i></span></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhK6xztynUNAORn-aCs_C4CabMeaKxAsyA10oP08kpy9TGRJAkrON2gIidbTmoT8GiS6voMlFXdG9bee8LOgTg_sxj9Rn_Q3XindImrFBh4hRt3IKiIBGHWGqGJBa1-yz5ANnojO5bLWGal/s1600/Wolf_01.tif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhK6xztynUNAORn-aCs_C4CabMeaKxAsyA10oP08kpy9TGRJAkrON2gIidbTmoT8GiS6voMlFXdG9bee8LOgTg_sxj9Rn_Q3XindImrFBh4hRt3IKiIBGHWGqGJBa1-yz5ANnojO5bLWGal/s1600/Wolf_01.tif" height="377" width="640" /></a></div>
<div class="" style="clear: both; text-align: center;">
<span style="font-size: x-small;"><i>Lou</i></span></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBNC0uaUueMRa6ArSONdmJTXyLvn2Z1Xm9FBO1Hs-ZawdtYjn5SFsVQDoZ7H2eoqzbkAcXeoRn4AgTh7p4uhaBEz3mk5ujlG2Uyb3JiH7Su13Qgj5dHxawMCXUNMlu19WthsVZLMOlBOnG/s1600/FinalSpear.tif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBNC0uaUueMRa6ArSONdmJTXyLvn2Z1Xm9FBO1Hs-ZawdtYjn5SFsVQDoZ7H2eoqzbkAcXeoRn4AgTh7p4uhaBEz3mk5ujlG2Uyb3JiH7Su13Qgj5dHxawMCXUNMlu19WthsVZLMOlBOnG/s1600/FinalSpear.tif" height="320" width="77" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZ0sUoeQSQqwfVKp7DKmJUNDNPrUtZNN4yjqfd8DtXjSOZwiDcgwX65ckqHAardkFhOU5M8gByZ1frGffYWhIvXGX4i88-KsCN_m0ONKP-zOtm-f3vEQwm-ZiEPk-ItxS2HTZ4mbL7gU2x/s1600/Tree_v1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZ0sUoeQSQqwfVKp7DKmJUNDNPrUtZNN4yjqfd8DtXjSOZwiDcgwX65ckqHAardkFhOU5M8gByZ1frGffYWhIvXGX4i88-KsCN_m0ONKP-zOtm-f3vEQwm-ZiEPk-ItxS2HTZ4mbL7gU2x/s1600/Tree_v1.jpg" height="320" width="184" /></a></div>
<div class="" style="clear: both; text-align: center;">
<i><span style="font-size: x-small;">Lou</span></i></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjndWAIRFggFxzPvd1wNEE-ngkBTcAoDf9S1WpDTzz519mUOqpMR_3rqpVtl96rora3jm-Vd_lgHoGaLCnKCBC32iK_zVZEO9MYPNxskqHmVCEjEoz_r89HnEpA_zhk2uoDkivRBS9N-4GR/s1600/InuitOlderSketchColor.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjndWAIRFggFxzPvd1wNEE-ngkBTcAoDf9S1WpDTzz519mUOqpMR_3rqpVtl96rora3jm-Vd_lgHoGaLCnKCBC32iK_zVZEO9MYPNxskqHmVCEjEoz_r89HnEpA_zhk2uoDkivRBS9N-4GR/s1600/InuitOlderSketchColor.jpg" height="400" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: x-small;"><i>Lou</i></span></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQmAPomadJMwOBhoKcaQGvO6EzevB79x8UHuaTRXMlTYBWud6smeQvFULLieVT3dbH91SKHQaLk3X_aJy79Na9nyO7IHu-F9WxmViUVW8ufELjpm-FU_jCagzgJP0GG9q5ayHgFOMpzQ5j/s1600/scale.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQmAPomadJMwOBhoKcaQGvO6EzevB79x8UHuaTRXMlTYBWud6smeQvFULLieVT3dbH91SKHQaLk3X_aJy79Na9nyO7IHu-F9WxmViUVW8ufELjpm-FU_jCagzgJP0GG9q5ayHgFOMpzQ5j/s1600/scale.jpg" height="443" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: x-small;"><i>Lou, Nancy</i></span></div>
Nancyhttp://www.blogger.com/profile/02060201379198295014noreply@blogger.com2tag:blogger.com,1999:blog-1533210468045638982.post-81052116998008782042013-12-31T23:00:00.000-08:002014-02-15T11:23:56.174-08:00Dabble #1 Completed!<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="394" mozallowfullscreen="" src="//player.vimeo.com/video/83099906" webkitallowfullscreen="" width="720"></iframe></div>
Nancyhttp://www.blogger.com/profile/02060201379198295014noreply@blogger.com2tag:blogger.com,1999:blog-1533210468045638982.post-72973273211198659812013-12-18T18:25:00.000-08:002014-01-11T18:29:20.597-08:00SSGI in UnityA simple SSGI (Screen Space Global Illumation) effect was a surprisingly quick feature to add, as most of the legwork had already been done by Unity's SSAO (Screen Space Ambient Occlusion) Image Effect.<br />
<br />
The aim was to add additional contextual information to the final render, by way of indirect bounce light (or more accurately - color bleeding) from nearby surfaces.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCeGKjqpwvbvxplaJ_qMDfaW2w6Tun4REC9aNkm8wYEDtFEkAaBlAvyN8n8_eSxRFYIcEG_NTaUlBeNU_Nk54qrrJdhLnTS-fuUdAlzp_BpKa-yNuq5eOGRQDPtPewPMQ23AQo2VoTKT4/s1600/GI_off.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCeGKjqpwvbvxplaJ_qMDfaW2w6Tun4REC9aNkm8wYEDtFEkAaBlAvyN8n8_eSxRFYIcEG_NTaUlBeNU_Nk54qrrJdhLnTS-fuUdAlzp_BpKa-yNuq5eOGRQDPtPewPMQ23AQo2VoTKT4/s1600/GI_off.jpg" height="215" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<b>SSGI is OFF, SSAO is OFF.</b></div>
<div class="separator" style="clear: both; text-align: center;">
<b>We lack substantial spatial cues.</b></div>
<div class="separator" style="clear: both; text-align: center;">
<b><br /></b></div>
<div class="separator" style="clear: both; text-align: left;">
<b><br /></b></div>
<div class="separator" style="clear: both; text-align: left;">
The process I used is identical to SSAO, only instead of merely measuring contributions to the occlusion term, I allowed the occluding surfaces to contribute local surface color as well.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Altering the SSAO shader, I stuffed the AO term into the _SSGI tex's .a channel, and the GI term into the .rgb channels, then blended the color bleeding signal with the original image, using a remapped ao signal.</div>
<div class="separator" style="clear: both; text-align: left;">
<b><br /></b></div>
<div style="color: #0433ff; font-family: Monaco; font-size: 12px;">
sampler2D<span style="color: black;"> _SSGI;</span></div>
<div style="font-family: Monaco; font-size: 12px; min-height: 16px;">
<br /></div>
<div style="font-family: Monaco; font-size: 12px;">
<span style="color: #0433ff;">half4</span> frag( v2f i ) : <span style="color: #0433ff;">COLOR</span></div>
<div style="font-family: Monaco; font-size: 12px;">
{</div>
<div style="font-family: Monaco; font-size: 12px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #0433ff;">half4</span> c = <span style="color: #0433ff;">tex2D</span> (_MainTex, i.uv[<span style="color: #d834d5;">0</span>]);</div>
<div style="font-family: Monaco; font-size: 12px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #0433ff;">half</span> ao = <span style="color: #0433ff;">tex2D</span> (_SSGI, i.uv[<span style="color: #d834d5;">1</span>]).<span style="color: #d834d5;">a</span>;</div>
<div style="font-family: Monaco; font-size: 12px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>ao = <span style="color: #0433ff;">pow</span> (ao, _Params.w);</div>
<div style="font-family: Monaco; font-size: 12px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #0433ff;">half3</span> gi = <span style="color: #0433ff;">tex2D</span> (_SSGI, i.uv[<span style="color: #d834d5;">1</span>]).<span style="color: #d834d5;">rgb</span>;</div>
<div style="font-family: Monaco; font-size: 12px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>c.<span style="color: #d834d5;">rgb</span> = <span style="color: #0433ff;">lerp</span>(c.<span style="color: #d834d5;">rgb</span>, gi, <span style="color: #d834d5;">1</span>-ao);</div>
<div style="color: #0433ff; font-family: Monaco; font-size: 12px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>return<span style="color: black;"> c;</span></div>
<div class="separator" style="clear: both;">
</div>
<div style="font-family: Monaco; font-size: 12px;">
}</div>
<div>
<br /></div>
<div>
What's nice about this hack is all the parameters for AO are separable and compatible with those for GI.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKFZrxbJlGA9w-bVoZL-UHeGCnRctYVlxFbEp56ArAGK-mB2j_ca-ti7eZVn2FDwnWWeZTV3OLtdbs-_hoA4BwkQdresbsTxcFgesL8_z25ZInoea6vsTqTVEN1K7E968blkTUVXfcEOA/s1600/GI_on.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKFZrxbJlGA9w-bVoZL-UHeGCnRctYVlxFbEp56ArAGK-mB2j_ca-ti7eZVn2FDwnWWeZTV3OLtdbs-_hoA4BwkQdresbsTxcFgesL8_z25ZInoea6vsTqTVEN1K7E968blkTUVXfcEOA/s1600/GI_on.jpg" height="215" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<b>SSGI is ON, SSAO is ON.</b></div>
<div class="separator" style="clear: both; text-align: center;">
<b>Indirect illumination and occlusion provide greater spatial context.</b></div>
Louhttp://www.blogger.com/profile/09489841649273116863noreply@blogger.com0tag:blogger.com,1999:blog-1533210468045638982.post-61498690286341893542013-11-30T19:12:00.002-08:002014-02-15T11:25:32.810-08:00ModelsI activated my 30 day Unity Pro trial license a few days ago so we're frantically trying to finish this forest sprite demo. While Lou is coding like mad, I am going to share some of our models with you. We are using Maya 2013 to build and rig (where necessary) our assets. We are using Photoshop and Mari to texture our character and Unity to shade our assets. In Unity we have actually created our own "uber shader" which almost all of our assets are currently using. For now, the modeling.<br />
<br />
Here's our set from our main camera with all of our assets referenced into a scene and dressed according to our artwork. The green bits are maya joints for some vegetation that will have some wind animation in Unity.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgozsL9KF7gJq5_AgdOUte4MzqlGt-EyS_K2sT2oVHjynmSLGXVk3NihQsWGSujTc6J8dOcX2shbSTa_bGeEscLKNcXgR3WS58Ewyo3XayJbXOEA5vQu3JDq7k3mIpDuWETAeIW1wT3DQ3Q/s1600/maincamview.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgozsL9KF7gJq5_AgdOUte4MzqlGt-EyS_K2sT2oVHjynmSLGXVk3NihQsWGSujTc6J8dOcX2shbSTa_bGeEscLKNcXgR3WS58Ewyo3XayJbXOEA5vQu3JDq7k3mIpDuWETAeIW1wT3DQ3Q/s640/maincamview.jpg" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Here is the same set from a different camera to show our hackery. The beauty of working in context is that we can shape all of our dressing to our camera.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilZGn-PrsQJDxmkZUfDrzfAvm1rg7OoISw3JIzgmAsvO21X-_3wYgnS-6JdJCln5n4y3NujS0uib95csJH9m4dbrtOn3cr5raoJ7C3Ax5AqcjqHdIC6Vxg8l5_Guf6IDA6iVs_gmk975XC/s1600/perspview.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilZGn-PrsQJDxmkZUfDrzfAvm1rg7OoISw3JIzgmAsvO21X-_3wYgnS-6JdJCln5n4y3NujS0uib95csJH9m4dbrtOn3cr5raoJ7C3Ax5AqcjqHdIC6Vxg8l5_Guf6IDA6iVs_gmk975XC/s640/perspview.jpg" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: left;">
The log is detailed where it needs to be and sparse everywhere else</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioB8lOV6tXMaTaZYqil35UrsVuEg46ssL0moXctFk2sTyBadlDzzIjt4-Z8xrAc00NVIDogxdqQOLjv9ww5EoA7sOOkjxJLIFxXpQT2_dnPjKP4gAHN8GfDmen7iRz1U196zwHB3tKr_nT/s1600/logmodel.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="350" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioB8lOV6tXMaTaZYqil35UrsVuEg46ssL0moXctFk2sTyBadlDzzIjt4-Z8xrAc00NVIDogxdqQOLjv9ww5EoA7sOOkjxJLIFxXpQT2_dnPjKP4gAHN8GfDmen7iRz1U196zwHB3tKr_nT/s640/logmodel.jpg" width="640" /></a></div>
<br />
This is one of the flowers that also has a skeleton bound to it. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPEkcSZmTpRa3NAGnGgMpMmdklf9LMbNYvCpHTMh04HbSvVyOU9_0uWw9jeMr5A2QjQwP3fKDGqrJpxjfa8FqglbonqFpY82r03Qb62bttq2jfPqsH9-kCgQpNjBytwddwajxrKVFR9S8m/s1600/flowermodel.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPEkcSZmTpRa3NAGnGgMpMmdklf9LMbNYvCpHTMh04HbSvVyOU9_0uWw9jeMr5A2QjQwP3fKDGqrJpxjfa8FqglbonqFpY82r03Qb62bttq2jfPqsH9-kCgQpNjBytwddwajxrKVFR9S8m/s400/flowermodel.jpg" width="263" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
This is our forest sprite character. We are using our cache exporter and importer to bring our animation into Unity. </div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyMQSCULzdHcHvHt5wnvT1vPHLyv4PyhB8uDz3DqKZuQirOaroMYxUsoyS8pygeM7s91d9amJmfDSOECO75Lq2D24ZDrLw9kd12nEQgxqF4QKKwxr9CLi0-WAOnm7Ch22Vn1VR6soYEl5t/s1600/spritemodel.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyMQSCULzdHcHvHt5wnvT1vPHLyv4PyhB8uDz3DqKZuQirOaroMYxUsoyS8pygeM7s91d9amJmfDSOECO75Lq2D24ZDrLw9kd12nEQgxqF4QKKwxr9CLi0-WAOnm7Ch22Vn1VR6soYEl5t/s320/spritemodel.jpg" width="214" /></a></div>
Nancyhttp://www.blogger.com/profile/02060201379198295014noreply@blogger.com0tag:blogger.com,1999:blog-1533210468045638982.post-6084028470327701222013-11-20T17:40:00.000-08:002014-01-11T17:41:28.668-08:00Moss ShaderWe wanted some soft "texture" in our scene to make it more inviting and organic, so in envisioning the scene we decided we ought to add some cushy moss to the fallen log.<br />
<div>
<br /></div>
<div>
To reiterate - we're using Unity on a mac - so we don't have access to DirectX 11's tessellation support to grow isoline fur or anything like that. The tried and true method in games prior to that technology has been to implement a <a href="http://developer.download.nvidia.com/SDK/10/direct3d/Source/Fur/doc/FurShellsAndFins.pdf">shell/fin method</a> - but we wanted to take that idea a step further.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2Hy8mYSI75ZsQCVkviP_C48WtgFF_EV8G1kJFY9qYmqNmk1w8tCVnLYZWH_OPcq51V8rbk5hzJeMrZw1RqqrYI7TNjoteVomOTeXvygj-1owME14zAqf7gD7Hjx2R2XHksVtTIUfRa3s/s1600/SimpleShell.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2Hy8mYSI75ZsQCVkviP_C48WtgFF_EV8G1kJFY9qYmqNmk1w8tCVnLYZWH_OPcq51V8rbk5hzJeMrZw1RqqrYI7TNjoteVomOTeXvygj-1owME14zAqf7gD7Hjx2R2XHksVtTIUfRa3s/s1600/SimpleShell.png" height="233" width="320" /></a></div>
<div style="text-align: center;">
<b>A simple 3 pass shell extrusion shader.</b></div>
<div style="text-align: center;">
<br /></div>
<div>
In order to have decent-quality fur using the method mentioned above, you need a significant number of shells, each serving as a cross section of the fur volume (which in Unity would each require a separate draw call per sub shader, since we'd prefer to do all the extrusion using the vertex program). This can bring down performance, requires a lot of redundant code, and a long compilation cycle.</div>
<div>
<br /></div>
<div>
I want to keep the draw call count low per model, so instead I chose to integrate the effects of multiple cross-section layers in only <i>one</i> layer. This essentially turns into a ray casting problem.</div>
<div>
<br /></div>
<div>
Rather than spend a bunch of shader instructions writing the ray casting itself, I hijacked another popular shading concept called <a href="http://en.wikipedia.org/wiki/Parallax_mapping">parallax mapping</a>.</div>
<div>
<br /></div>
<div>
Essentially, naive parallax mapping allows for a texture to seem "deeper" inset into the surface being shaded, as a function of a height map. If you replace the height map value with a constant, you can set the entire texture a certain "depth" into the material. Do this enough times with linear varying depths, and integrate things such as opacity, surface normal, root-tip color, etc in a loop, and you get a holographic ray-marched-esque shader of the fur volume.</div>
<div>
<br /></div>
<div>
In pseudocode:</div>
<div>
<div style="font-family: Monaco; font-size: 12px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #0433ff;">for each iteration</span></div>
<div style="font-family: Monaco; font-size: 12px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>{</div>
<div style="font-family: Monaco; font-size: 12px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>shift uv by ParallaxOffset(<span style="color: #d834d5;">0</span>, depth*iteration/numIters, viewDirection);</div>
<div style="font-family: Monaco; font-size: 12px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>look up cross section tex2d(tex, shiftedUV);</div>
<div style="font-family: Monaco; font-size: 12px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>integrate tinted texture over length with root&tip color;</div>
<div style="font-family: Monaco; font-size: 12px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>integrate alpha over length with root&tip opacity;</div>
<div style="font-family: Monaco; font-size: 12px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>integrate normal from <span style="color: #0433ff;">tex2D</span>(NormalMap, shiftedUV);</div>
<div style="font-family: Monaco; font-size: 12px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>}</div>
<div style="font-family: Monaco; font-size: 12px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>normalize(Normal);</div>
<div>
<br /></div>
</div>
<div>
With 30 iterations and 1 draw call you can achieve the look of 30 shells.</div>
<div>
<br /></div>
<div>
One shortcoming of naive parallax mapping is that you don't have true silhouette edges. This could be solved by implementing relief mapping. Instead I opted to AlphaTest anything lower than a certain fixed value, allowing for blades of moss and grass to be clipped.</div>
<div>
<br /></div>
<div>
Clumping was also achieved by additionally offsetting the uv value at the tip by some smoothly varying vectors, encoded in a normal map generated from tiling <a href="http://en.wikipedia.org/wiki/Fractional_Brownian_motion">FBM</a>. Same goes for keep alive/wind.</div>
<div>
<br /></div>
<div>
Gross directionality changes and density are attenuated via vertex colors = (tangentShift, bitangentShift, 0, density).</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFnmOyW9N842laGnZ_MV2yYqjofPMHl8ltsEp7HDfbjR5Yk7Tf9mezr5cFEL_IkiutlrhRvDS2FJNdkMvQf1It8n_FPw_zVVxDu7cZNh-jVWKEvuWW6JbV8Ii5cYrh9T5iB01ylcusaxA/s1600/MossyLog.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFnmOyW9N842laGnZ_MV2yYqjofPMHl8ltsEp7HDfbjR5Yk7Tf9mezr5cFEL_IkiutlrhRvDS2FJNdkMvQf1It8n_FPw_zVVxDu7cZNh-jVWKEvuWW6JbV8Ii5cYrh9T5iB01ylcusaxA/s1600/MossyLog.png" height="202" width="320" /></a></div>
<div>
<br /></div>
<div>
<div style="text-align: center;">
<b>Resulting hologram moss.</b></div>
</div>
Louhttp://www.blogger.com/profile/09489841649273116863noreply@blogger.com3tag:blogger.com,1999:blog-1533210468045638982.post-65617648252091489492013-11-01T23:47:00.000-07:002014-01-11T14:07:32.360-08:00Colored Shadows in UnitySometimes you just want to colored shadows. It may not be physically correct, but perhaps you're making a stylistic choice. Unfortunately our options are limited. Unity's Ambient Light is a global concept, so if you want to add colored shadows on a per-material basis for fine grain control, you probably need to implement it in your shader.<br />
<br />
In order for our forest to feel more organic, I made some adjustments to <i>all</i> of our custom shaders - a very simple addendum within our <a href="http://docs.unity3d.com/Documentation/Components/SL-SurfaceShaderLightingExamples.html">lighting models</a>.<br />
<div>
<br /></div>
<div>
<b>Let's start with standard lambert irradiance.</b></div>
<div>
<br /></div>
<div>
<div style="font-family: Monaco; font-size: 12px; text-align: center;">
c.<span style="color: #d834d5;">rgb</span> = s.Albedo * <span style="color: #0433ff;">saturate</span>(NdotL) * atten;</div>
<div style="font-family: Monaco; font-size: 12px; text-align: center;">
<br /></div>
<div style="text-align: left;">
There are two things happening here, we're diminishing the color of the material by the diffuse component (<span style="color: #0433ff; font-family: Monaco; font-size: 12px; text-align: center;">saturate</span><span style="font-family: Monaco; font-size: 12px; text-align: center;">(NdotL)</span>), as well as the combined factor of the surface's distance to the light source and whatever cast shadows are occurring (<span style="font-family: Monaco; font-size: 12px; text-align: center;">atten</span>). Both of these are 0->1 values. This is what that looks like:</div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEie3z4v0jqiH28AQ4eJspdIu9q6Gz_62B6eHrBp8KDBDdjuFtij3CKadnCjywB8lBrBa-9XHr_aBsK0U7mgQjZmC0nTT_yROpWBPDDPQ9snq2Rx1oZ-rnkchdbzvNKhU4I637NGETf2lgk/s1600/BlackShadows.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEie3z4v0jqiH28AQ4eJspdIu9q6Gz_62B6eHrBp8KDBDdjuFtij3CKadnCjywB8lBrBa-9XHr_aBsK0U7mgQjZmC0nTT_yROpWBPDDPQ9snq2Rx1oZ-rnkchdbzvNKhU4I637NGETf2lgk/s320/BlackShadows.png" height="205" width="320" /></a></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: center;">
With all that black we lose a lot of contextual information.</div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: left;">
<b>Let's add some terms to our lighting to make it more interesting.</b></div>
<div style="text-align: left;">
<b><br /></b></div>
<div style="font-family: Monaco; font-size: 12px; text-align: center;">
c.<span style="color: #d834d5;">rgb</span> = (s.Albedo * <span style="color: #0433ff;">saturate</span>(NdotL) + s.Albedo * _ShadowColor.<span style="color: #d834d5;">rgb</span> * (<span style="color: #d834d5;">1</span>-<span style="color: #0433ff;">saturate</span>(NdotL))) * atten<br />
+ s.Albedo * _ShadowColor.<span style="color: #d834d5;">rgb </span>*<span style="color: #d834d5;"> </span>(<span style="color: #d834d5;">1</span>-atten);<br />
<div>
<span style="color: #d834d5;"><br /></span></div>
</div>
<div style="font-family: Monaco; font-size: 12px; text-align: center;">
<br /></div>
<div style="text-align: left;">
Since both the diffuse and attenuation/shadow components map 0->1 as "in shadow"->"in light", we can remap them, multiply against a per-material _ShadowColor, and add the result back into the mix. Now colors that used to be crushed to (0,0,0) are (_ShadowColor.r,_ShadowColor.g,_ShadowColor.b), and our whites are preserved:</div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzSydcYAndmZyeiZZHz-_pV7NA9rK1dU2DSoNJKuj80Ki4GQa-CLfqIHnn3XjAuvnuLuaBdvrNQ0Tk9MMCxMTHApp_aVJQ4HmeRrxoLhuoQb4xL_m55_yr53r189yYB6aFHXIrlqRncfw/s1600/ColoredShadows.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzSydcYAndmZyeiZZHz-_pV7NA9rK1dU2DSoNJKuj80Ki4GQa-CLfqIHnn3XjAuvnuLuaBdvrNQ0Tk9MMCxMTHApp_aVJQ4HmeRrxoLhuoQb4xL_m55_yr53r189yYB6aFHXIrlqRncfw/s320/ColoredShadows.png" height="205" width="320" /></a></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: center;">
Per-material colored shadows for optimal control.</div>
<div style="text-align: center;">
<br /></div>
<div style="font-family: Monaco; font-size: 12px; text-align: center;">
<br /></div>
</div>
<div>
<br /></div>
<div style="text-align: center;">
<br /></div>
Louhttp://www.blogger.com/profile/09489841649273116863noreply@blogger.com0tag:blogger.com,1999:blog-1533210468045638982.post-83907251304776527272013-10-25T21:08:00.000-07:002014-01-11T17:54:25.110-08:00Procedural Wind Effects in UnityRather than animating and cacheing a bunch of flower bending by hand, we wanted to create some wind procedurally. This wind is simply for "keep alive," or, to add some subtle movement so our scene does not look completely static and CG. In order to do this, the flowers were rigged, and three scripts were written: WindSim, WindObject, and AssignIDs.<br />
<br />
<span style="font-size: large;">
WindSim </span><br />
<br />
The WindSim script is attached to any flower or object that has a rig and wants to be simmed. The object "wants" to be simmed if it is specifically tagged in the inspector. This allowed us the ability to turn off simulation easily rather than removing the script entirely from the object. WindSim does the actual moving of the joints and takes in a direction from WindObject. WindSim has attributes such as strength and animation offset to vary the wind motion from object to object. Here is the noise function we came up with:<br />
<br />
(Mathf.Pow(Mathf.Tan(Mathf.Sin(Time.time+AnimOffset*id))/2.0f,4f)-.1f)*10F*Mathf.PerlinNoise(Time.time/2F,Time.time/2F);
<br />
<br />
<a href="http://www.iquilezles.org/apps/graphtoy/" target="_blank">Inigo Quilez's Graph Toy</a> or the <a href="http://computers.tutsplus.com/tutorials/getting-started-with-grapher-your-macs-built-in-graph-tool--mac-48440" target="_blank">Grapher</a> tool for Macs are really helpful tools to come up with interesting noise functions. This is the function visualized with Graph Toy:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3JQq7E-dxPjgvTjbvPO-2dWtrJJ4rQLrY0O3sdWqS4R1RPWDpKsjGGtFGJaxGF3TcCvMZBw-ELdPupcjXoMK8U2m2-3h3wy2afj7ufK57_HDTmUjEixNsEB5-7Wsuu49Wws2Y0RnUdlrP/s1600/windnoise.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3JQq7E-dxPjgvTjbvPO-2dWtrJJ4rQLrY0O3sdWqS4R1RPWDpKsjGGtFGJaxGF3TcCvMZBw-ELdPupcjXoMK8U2m2-3h3wy2afj7ufK57_HDTmUjEixNsEB5-7Wsuu49Wws2Y0RnUdlrP/s400/windnoise.png" height="108" width="400" /></a></div>
<br />
<span style="font-size: large;">WindObject</span><br />
<br />
WindObject is attached to an empty gameObject and serves as a global way of controlling the direction of the wind as well as other parameters. The direction is just based on the gameObject’s directional vector. We have a simple Gizmo line drawing in the direction of the wind which is visible in the scene view. Like WindSim, WindObject also has strength, flexibility, and animation offset attributes that are passed to WindSim initially by default. If any of these attributes are set in WindSim, then they override WindObject’s settings.<br />
<br />
Here's a screenshot of our WindObject selected. The yellow line tells us which direction the wind is blowing.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwXwlyZI7I3XeJ4WqVWqQr9Am1vZX3pHdvtawfN3LeeZSPQby6XHir6Oun-pw7rpVmo6wxjKT-rnrEGmFKFo5JgFp7UdtRCjIaNEfAgjZZ1BEMTWGDmYIJNQOqNJ-6fAevWqkun_FopUPw/s1600/windobject.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwXwlyZI7I3XeJ4WqVWqQr9Am1vZX3pHdvtawfN3LeeZSPQby6XHir6Oun-pw7rpVmo6wxjKT-rnrEGmFKFo5JgFp7UdtRCjIaNEfAgjZZ1BEMTWGDmYIJNQOqNJ-6fAevWqkun_FopUPw/s320/windobject.png" height="320" width="256" /></a></div>
<br />
<span style="font-size: large;">Object IDs </span><br />
<br />
We created AssignIDs as an editor script to add some randomization for each simmable object, . It looks for all simmable objects in the scene and incrementally assigns an id to each of the objects.<br />
<br />
Here's an example of our wind in action.<br />
<br />
<br />
<center>
<iframe frameborder="0" height="440" src="http://unitygadgets.gayasoft.ch/WebContainer/UnityWebContainer_2_0.php?url=https://dl.dropboxusercontent.com/u/1533442/WindSim.unity3d&width=560&height=420" width="590"></iframe></center>
<center>
<span style="color: #666666; font-size: x-small;">
If nothing loads, try installing</span><span style="color: #999999; font-size: x-small;">
<a href="http://unity3d.com/webplayer/" title="Unity Web Player. Install now!">Unity Player</a></span></center>
<center>
</center>
<center>
</center>
The result is a globally controllable wind sim with the ability to tweak the look of each simmed object if necessary.Nancyhttp://www.blogger.com/profile/02060201379198295014noreply@blogger.com0tag:blogger.com,1999:blog-1533210468045638982.post-56737165240904318512013-10-10T22:51:00.000-07:002013-11-30T22:10:11.783-08:00Cache, MoneyOne requirement of our realtime effort is that we be able to achieve film-quality animation within Unity. The current release doesn't support blend shapes, and even if it did, we'd want to leave ourselves some room to use other deformer solutions, as well as allow the animation to come from any arbitrary 3rd party package one could imagine. The industry's standard answer to a problem like this is to point cache the scene data.<br />
<br />
At this time, Unity also does not support caches. So! We have to make our own, or buy something someone else has made. We're frugal, so we made our own.<br />
<br />
The concept is simple - store non frame-varying data once (triangles, uvs), and frame-varying data once per frame (vert positions, normals), in some text file, and construct a parser in Unity to build out the resulting mesh, predicated upon a frame in the range you wish to animate.<br />
<br />
One problem though...<br />
<br />
Unity uses a different coordinate system than most other 3d packages. As an example, we're using Maya for our asset creation - and it happens to use a Right Handed Coord-Sys, whereas Unity uses a Left Handed Coord-Sys.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheY7hvOEe7NhTg9W8lw8krIV5Bkl8fLF8L2AqSqFxGfbS3LYwzyX6b95n6niYTIwxjUXShPxvMfwnrEOUJBaEB8Os8jhrr1_4_c7tGxvLHeo3Xc5z1gUMkVD6Q-mmfWEYVYyxHy7UrVDo/s1600/CoordSystems.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheY7hvOEe7NhTg9W8lw8krIV5Bkl8fLF8L2AqSqFxGfbS3LYwzyX6b95n6niYTIwxjUXShPxvMfwnrEOUJBaEB8Os8jhrr1_4_c7tGxvLHeo3Xc5z1gUMkVD6Q-mmfWEYVYyxHy7UrVDo/s320/CoordSystems.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
In practice all our positional and directional vectors (i.e. vertex positions and normals) have to be flipped (*-1) in the x-axis (or "right" vector). But that's not enough! If you were to only scale, all your normals would be inverted, so you <b>must</b> take care to also reverse the <i>winding-order</i> of your triangles upon export.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGa_M0MixIWwy80mOGV2CdiMd_-k20BHtOrQPn0JkQA2ZjQqnASTyJAZQ1OeVlAMW7BbK1EF0lcEY9Eug_DAAtwYQBFc-fW3ck_IbDBhg8iny2K-1ai8l0d_CEUbpixG_sSS3o3FOMcyE/s1600/WindingOrder.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="89" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGa_M0MixIWwy80mOGV2CdiMd_-k20BHtOrQPn0JkQA2ZjQqnASTyJAZQ1OeVlAMW7BbK1EF0lcEY9Eug_DAAtwYQBFc-fW3ck_IbDBhg8iny2K-1ai8l0d_CEUbpixG_sSS3o3FOMcyE/s320/WindingOrder.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The winding-order simply defines what is considered the "front-face" or "back-face" of a polygon, and its really just what it sounds like - the order in which the vertices are listed in the polygon's array. By reversing the winding-order, you effectively flip the face normal, and now all is right in the world.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
What's fantastic about these two simple observations is that (as far as I can tell) this is exactly what's happening within Unity's Maya Scene Importer. Now anything statically imported from Maya through Unity's traditional pipeline will match perfectly with anything dynamically cached!</div>
Louhttp://www.blogger.com/profile/09489841649273116863noreply@blogger.com0tag:blogger.com,1999:blog-1533210468045638982.post-11868674161921079462013-09-26T21:56:00.003-07:002014-05-20T19:57:30.496-07:00Unity Dust Particle Shader<div class="separator" style="clear: both; text-align: center;">
You can now <a href="https://www.assetstore.unity3d.com/#/content/15539" target="_blank">buy</a> our particle shader on the Unity asset store for $5!</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
NOTE: If you're seeing WHITE SQUARES, please try adding this line: </div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-size: x-small;"><span style="color: #009695; font-family: Menlo;">AlphaTest</span><span style="color: #444444; font-family: Menlo;"> </span><span style="color: #3363a4; font-family: Menlo;">Greater</span><span style="color: #444444; font-family: Menlo;"> .</span><span style="color: #f57c00; font-family: Menlo;">01</span></span></div>
<div class="separator" style="clear: both; text-align: left;">
under the line: </div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-size: x-small;"><span style="color: #3363a4; font-family: Menlo;">Tags</span><span style="color: #444444; font-family: Menlo;"> {</span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #f57c00; font-family: Menlo;">RenderType</span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #444444; font-family: Menlo;">=</span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #f57c00; font-family: Menlo;">Transparent</span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #444444; font-family: Menlo;"> </span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #f57c00; font-family: Menlo;">Queue</span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #444444; font-family: Menlo;"> = </span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #f57c00; font-family: Menlo;">Transparent</span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #444444; font-family: Menlo;"> </span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #f57c00; font-family: Menlo;">IgnoreProjector</span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #444444; font-family: Menlo;"> = </span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #f57c00; font-family: Menlo;">True</span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #444444; font-family: Menlo;">}</span></span></div>
<div class="separator" style="clear: both; text-align: left;">
See below for more info. I'll release an update to the shader soon with this in there by default. Sorry for the confusion!</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU9HUdrrPN89j54sFBHTk3t-p2JH7B1Z5FNW4SKQ_t3UHvMxzndLv-St_6YFe-I4743wRELmqZnceOqgWfRB8l-Fd4OIaJpZeqOqo2HFrh6BUl0eu-Mvd-FV-kSW08MKdcKNYCbsy9Jzmk/s1600/SpriteEnvConcept.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU9HUdrrPN89j54sFBHTk3t-p2JH7B1Z5FNW4SKQ_t3UHvMxzndLv-St_6YFe-I4743wRELmqZnceOqgWfRB8l-Fd4OIaJpZeqOqo2HFrh6BUl0eu-Mvd-FV-kSW08MKdcKNYCbsy9Jzmk/s640/SpriteEnvConcept.jpg" height="267" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
We're using Lou's painting as inspiration for our first test shot. I started developing a shader for <a href="http://docs.unity3d.com/Documentation/Manual/ParticleSystems.html" target="_blank">Unity's particle system</a> to create the close up floaties. The tricky part here was that I had no way of accessing particle ids in the shader, which meant that I couldn't randomize the particles in the shader. I wanted to randomize opacity, color and flashes. I originally tried creating a perlin noise texture look up in screen space based on the particle's screen space position to get a random value for that particle. That works for our purposes since our camera is static. I didn't get very good results with this and instead varied the opacity in the particle system by manually setting Alpha to be 0 or 255 in Color over Lifetime. The varying opacity was used to drive a super bright emission and the color naturally looked random because of the different opacities. </div>
<div style="font-family: Monaco; font-size: 12px;">
<br /></div>
<div style="font-family: Monaco; font-size: 12px;">
o.<span style="color: #0433ff;">Emission</span> = <span style="color: #0433ff;">lerp</span>(<span style="color: #d834d5;">0</span>,_Emission, <span style="color: #0433ff;">smoothstep</span>(_FlashSpeed,<span style="color: #d834d5;">1</span>,o.Alpha));</div>
<div>
<br /></div>
My dust motes are made up of two particle systems: Large blurry dust and micro dust.<br />
<br />
<span style="font-size: large;"><b>Large Blurry Dust</b></span><br />
For the coloration, I wanted to create a "photographic" look. I looked a lot at images like these I found on google:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhlRauzbVNsXEt11v9-jMYTFP0gy3ud2ZSEHmyUjCNnWMn2icslUcnMxNS8wzonJ74-QKqxU9X0iYkHL3LovkkdZqA0q8GiJDyHJeAHdTy4NebpuUa4o9kY5hHyTWdAC5jo6cgV-QbPIdq/s1600/IMG_4920.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhlRauzbVNsXEt11v9-jMYTFP0gy3ud2ZSEHmyUjCNnWMn2icslUcnMxNS8wzonJ74-QKqxU9X0iYkHL3LovkkdZqA0q8GiJDyHJeAHdTy4NebpuUa4o9kY5hHyTWdAC5jo6cgV-QbPIdq/s400/IMG_4920.JPG" height="400" width="400" /></a></div>
<br />
Even though the overall mote looks circular, it is actually a cutout of an imperfect circle texture I painted. This just adds a subtle randomness to all of them as they slowly spawn and rotate (I think anyway).<br />
<br />
<div style="font-family: Monaco; font-size: 12px;">
<span style="color: #0433ff;">if</span>(_DoShape)</div>
<div style="font-family: Monaco; font-size: 12px;">
o.Alpha = o.Alpha*<span style="color: #0433ff;">tex2D</span>(_Shape,IN.uv_Noise.xy).r;</div>
<div style="font-family: Monaco; font-size: 12px; min-height: 16px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span></div>
<div style="color: #3da600; font-family: Monaco; font-size: 12px;">
//otherwise make a circle</div>
<div style="font-family: Monaco; font-size: 12px;">
<span style="color: #0433ff;">else</span>{</div>
<div style="font-family: Monaco; font-size: 12px;">
<span style="color: #0433ff;">if</span>(dist>=.<span style="color: #d834d5;">5</span>)</div>
<div style="font-family: Monaco; font-size: 12px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>o.Alpha = <span style="color: #d834d5;">0</span>;</div>
<div style="font-family: Monaco; font-size: 12px;">
}</div>
<div>
<br /></div>
I wrote a function to create a bright yellow ring near the edge of the particle that fades toward the center. As it fades, the color turns bluish.<br />
<br />
<div style="font-family: Monaco; font-size: 12px;">
<span style="color: #0433ff;">float</span> dist = <span style="color: #0433ff;">distance</span>(IN.uv_Noise.xy, <span style="color: #0433ff;">float2</span>(.<span style="color: #d834d5;">5</span>,.<span style="color: #d834d5;">5</span>));</div>
<div style="font-family: Monaco; font-size: 12px;">
<span style="color: #0433ff;">if</span>(dist<(.<span style="color: #d834d5;">5</span>-_Blur)){</div>
<div style="font-family: Monaco; font-size: 12px;">
o.Alpha = o.Alpha*<span style="color: #0433ff;">max</span>(<span style="color: #d834d5;">1.0</span>*<span style="color: #0433ff;">pow</span>(dist/(.<span style="color: #d834d5;">5</span>-_Blur),<span style="color: #d834d5;">2</span>),(<span style="color: #d834d5;">1</span>-_Transparency));</div>
<div style="font-family: Monaco; font-size: 12px;">
<span style="color: #3da600;">//add a shadow color as the particle fades</span></div>
<div style="font-family: Monaco; font-size: 12px;">
o.Albedo = <span style="color: #0433ff;">lerp</span>(_ShadowColor.<span style="color: #d834d5;">rgb</span>, o.Albedo,o.Alpha);</div>
<br />
<div style="font-family: Monaco; font-size: 12px;">
} </div>
<div>
<br /></div>
Finally, I have a noise on top that creates some pink speckles for a low resolution pixelated look.<br />
<div style="font-family: Monaco; font-size: 12px;">
<br /></div>
<div style="font-family: Monaco; font-size: 12px;">
o.Albedo = <span style="color: #0433ff;">lerp</span>(o.Albedo,_Speckles.<span style="color: #d834d5;">rgb</span>,<span style="color: #0433ff;">tex2D</span>(_Noise,(IN.uv_Noise.xy*.<span style="color: #d834d5;">1</span>+<span style="color: #0433ff;">_Time</span>*.<span style="color: #d834d5;">01</span>)).r);</div>
<br />
As as bonus, I created a custom lighting model for these dust motes which simulates light scattering through them.<br />
<br />
<div style="font-family: Monaco; font-size: 13px;">
<span style="color: #0433ff;">half4</span> LightingParticle(SurfaceOutputCustom s, <span style="color: #0433ff;">half3</span> lightDir, <span style="color: #0433ff;">half3</span> viewDir, <span style="color: #0433ff;">half</span> atten) { </div>
<div style="font-family: Monaco; font-size: 13px;">
<span style="color: #0433ff;">half4</span> c; </div>
<div style="font-family: Monaco; font-size: 13px;">
c.<span style="color: #d834d5;">rgb</span> = s.Albedo;</div>
<div style="font-family: Monaco; font-size: 13px; min-height: 17px;">
c.<span style="color: #d834d5;">a</span> =<span style="color: #0433ff;">lerp</span>(<span style="color: #d834d5;">0</span>,s.Alpha, 1-<span style="color: #0433ff;">saturate</span>(<span style="color: #0433ff;">dot</span>(<span style="color: #0433ff;">normalize</span>(viewDir), lightDir)));</div>
<div style="font-family: Monaco; font-size: 13px;">
<span style="color: #0433ff;">return</span> c;</div>
<div style="min-height: 17px;">
<div style="font-family: Monaco; font-size: 13px;">
}<br />
<br /></div>
NOTE the lighting model does not work with multiple lights and can result in the particles looking blown out, or white. Since the particles are alpha mapped billboards, they will look like white squares. There are a couple ways to fix this. One is to add "alpha" to the pragma surface line. This basically overrides the lighting model (for whatever reason)<span style="font-family: Monaco; font-size: x-small;">:</span></div>
<div style="font-family: Monaco; font-size: 13px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div style="color: #f98c00; font-family: Monaco; font-size: 13px;">
#<span style="color: #d97100;">pragma</span> surface surf Particle alpha<br />
<span style="color: black; font-family: Times; font-size: small;"><br /></span>
<span style="color: black; font-family: Times; font-size: small;">If you want to preserve the ability to have a light source create a scattering effect, add the following line:</span><br />
<span style="color: #009695; font-family: Menlo; font-size: x-small;">AlphaTest</span><span style="color: #444444; font-family: Menlo; font-size: x-small;"> </span><span style="color: #3363a4; font-family: Menlo; font-size: x-small;">Greater</span><span style="color: #444444; font-family: Menlo; font-size: x-small;"> .</span><span style="color: #f57c00; font-family: Menlo; font-size: x-small;">01</span><br />
<div class="separator" style="clear: both; color: black; font-family: Times; font-size: medium;">
under the line: </div>
<div class="separator" style="clear: both; color: black; font-family: Times; font-size: medium;">
<span style="font-size: x-small;"><span style="color: #3363a4; font-family: Menlo;">Tags</span><span style="color: #444444; font-family: Menlo;"> {</span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #f57c00; font-family: Menlo;">RenderType</span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #444444; font-family: Menlo;">=</span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #f57c00; font-family: Menlo;">Transparent</span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #444444; font-family: Menlo;"> </span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #f57c00; font-family: Menlo;">Queue</span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #444444; font-family: Menlo;"> = </span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #f57c00; font-family: Menlo;">Transparent</span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #444444; font-family: Menlo;"> </span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #f57c00; font-family: Menlo;">IgnoreProjector</span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #444444; font-family: Menlo;"> = </span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #f57c00; font-family: Menlo;">True</span><span style="color: #f57c00; font-family: Menlo;">"</span><span style="color: #444444; font-family: Menlo;">}</span></span></div>
</div>
<div>
I believe the first light that was created in the scene is the only light that can create the scattering effect.</div>
<div style="font-family: Monaco; font-size: 13px;">
<br /></div>
<span style="font-size: large;"><b>Micro Dust</b></span><br />
This one was much simpler. Basically white and the cutout is an irregular polygon texture.
<br />
<br />
And here is my result:
<br />
<center>
<iframe frameborder="0" height="440" src="http://unitygadgets.gayasoft.ch/WebContainer/UnityWebContainer_2_0.php?url=https://dl.dropboxusercontent.com/u/1533442/ParticleShader.unity3d&width=560&height=420" width="590"></iframe></center>
<center>
<span style="color: #666666; font-size: x-small;">If nothing loads, <a href="http://vimeo.com/75551327">watch with Vimeo</a> or try installing
<a href="http://unity3d.com/webplayer/" title="Unity Web Player. Install now!">Unity Player</a>
.</span></center>
Nancyhttp://www.blogger.com/profile/02060201379198295014noreply@blogger.com3tag:blogger.com,1999:blog-1533210468045638982.post-75468759933549114402013-09-26T19:52:00.003-07:002014-02-15T11:25:44.407-08:00Dabble #1 Realtime Forest Sprite<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiS8LMFSd74k5SLe9Jr7mW259hxLpkRQiDertke8sGw_nmAcKhy91IL4gEjDe8SE9jQMrFy7W0sXZE7LDe-2DOuCbIne78yWwHDygwyuS-nGizcJg3UCJKJZkBu4jtKL8yJpLpYyd_B-hJm/s1600/sprite5.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiS8LMFSd74k5SLe9Jr7mW259hxLpkRQiDertke8sGw_nmAcKhy91IL4gEjDe8SE9jQMrFy7W0sXZE7LDe-2DOuCbIne78yWwHDygwyuS-nGizcJg3UCJKJZkBu4jtKL8yJpLpYyd_B-hJm/s320/sprite5.JPG" width="240" /></a></div>
<br />
We work in the animation industry and we know how much it sucks to wait for renders to come back. So we're embarking on a little experiment. Inspired by <a href="http://www.agnisphilosophy.com/en/" target="_blank">Square-Enix's "Agni's Philosophy"</a> and <a href="http://video.unity3d.com/video/6912619/the-butterfly-effect-realtime-rendering" target="_blank">Unity's "Butterfly Effect"</a>, we want to see if we can create a near film quality shot/test/short in "real-time" in our free time. For this project, we are using <a href="http://www.autodesk.com/products/autodesk-maya/overview" target="_blank">Maya</a> to create assets and set dress to a camera and <a href="http://unity3d.com/" target="_blank">Unity</a> for shading, lighting, and rendering.<br />
<br />
Our test idea is centered around a tiny forest sprite running across a fallen log. This sprite actually came from a game idea we had but shelved because of our lack of DirectX11 (We're using Macs). Here are some initial artworks for the sprite. We are actually pretty far along on this project already (we've only spent 2 weekends so far), but we'll update the blog with pipeline scripts and pretty shaders we had to develop.
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbRwZYd2k_NFqupBkAe4PIjCeh7mrlspTWOuWMnRgFcrcQcHkqalf28nc6EYMMccbhyphenhyphendpKsdKEKgwrPk6id1UgXGeAekq_ca6doIEZDjFtZQ31MmGDtNk7ApowZKc4LvGWvQTmtZ4deLKw/s1600/env.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbRwZYd2k_NFqupBkAe4PIjCeh7mrlspTWOuWMnRgFcrcQcHkqalf28nc6EYMMccbhyphenhyphendpKsdKEKgwrPk6id1UgXGeAekq_ca6doIEZDjFtZQ31MmGDtNk7ApowZKc4LvGWvQTmtZ4deLKw/s400/env.JPG" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpsoCckcUgXn69zc8E8e3M75n6O9mS3S2Z243LF4dsGYg4tRVoQNGJjv0202-lbA1DfdKpo6Ea0e4bCLhHoETU6dFc_skDyU_17_DBUtRwb-qP7JYex5E43irDcoRf2Xd-X2fF37V1Dj80/s1600/sprite3.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpsoCckcUgXn69zc8E8e3M75n6O9mS3S2Z243LF4dsGYg4tRVoQNGJjv0202-lbA1DfdKpo6Ea0e4bCLhHoETU6dFc_skDyU_17_DBUtRwb-qP7JYex5E43irDcoRf2Xd-X2fF37V1Dj80/s320/sprite3.JPG" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdnhn8t3v9z9rvIMNKfGL4jqXCD2ZgARAO5vil1aaIxSEtF7SCUoixi8y1Pvda_dr2krlq7M6eD0kGthawPb_I1KU98icyUNpOYsUaFoR5Z7CCyCt4gI9wsvuf0hPDzm589zRtg2DZAfsG/s1600/sprite4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdnhn8t3v9z9rvIMNKfGL4jqXCD2ZgARAO5vil1aaIxSEtF7SCUoixi8y1Pvda_dr2krlq7M6eD0kGthawPb_I1KU98icyUNpOYsUaFoR5Z7CCyCt4gI9wsvuf0hPDzm589zRtg2DZAfsG/s320/sprite4.jpg" width="253" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSG3oR4zbmNaAkr6qaFdy_wyfx4sEvu9fN4qHwX_XtWNsiZAvObcl_B2CsAty2CJhQWSDfwECQtQYk9hWWmNTyof7GB9iDsBiomojWmGT5p-CAhQxbdadETeZE55U4R3x9rKFxM7LO0weA/s1600/sprite.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSG3oR4zbmNaAkr6qaFdy_wyfx4sEvu9fN4qHwX_XtWNsiZAvObcl_B2CsAty2CJhQWSDfwECQtQYk9hWWmNTyof7GB9iDsBiomojWmGT5p-CAhQxbdadETeZE55U4R3x9rKFxM7LO0weA/s320/sprite.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh33B3kza4G_mKHU33uRuuQYr3AF4IhreVy5EGorOmPgmHR5sk8SlHg6lfzbCxw5xEdYDIAASXkFNFzyC-2ENFF7G22zQxwXqWBA3hn3sneSU0cifd8IrOOM78jgzDrlTmcf48fmoUlnUsD/s1600/SpriteEnvConcept.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh33B3kza4G_mKHU33uRuuQYr3AF4IhreVy5EGorOmPgmHR5sk8SlHg6lfzbCxw5xEdYDIAASXkFNFzyC-2ENFF7G22zQxwXqWBA3hn3sneSU0cifd8IrOOM78jgzDrlTmcf48fmoUlnUsD/s400/SpriteEnvConcept.jpg" /></a></div>
Nancyhttp://www.blogger.com/profile/02060201379198295014noreply@blogger.com0