Rendering realistic Ice objects

995 views

Published on

ShaderX6 5.1

Published in: Technology, Business
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
995
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
9
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Rendering realistic Ice objects

  1. 1. Rendering Realistic Ice Objects ShaderX6 5.1 – Anders Nivfors http://cafe.naver.com/shader 임용균 (guardin@naver.com)
  2. 2. Ice Objects?!?
  3. 3. Method Overview <ul><li>Cracks </li></ul><ul><li>Air bubbles and particles </li></ul><ul><li>Reflections of light sources and the environment </li></ul><ul><li>two-sided refraction </li></ul><ul><li>Bump mapping </li></ul><ul><li>Bump masking </li></ul>
  4. 4. Adding Cracks <ul><li>Cracks? </li></ul><ul><ul><li>얼음이 0 도 보다 높은 환경에 있을 때 내부가 깨지는 현상 </li></ul></ul><ul><ul><li>Crack 은 얼음 안에 밝게 곡면으로 나타난다 . </li></ul></ul>Crack 현상이 강함 Crack 현상이 약함
  5. 5. Adding Cracks <ul><li>Approximation </li></ul><ul><ul><li>별도의 Crack Mesh 를 만든다 . </li></ul></ul><ul><ul><ul><li>범용적 용도의 Crack Model 을 여러 개 만든다 . </li></ul></ul></ul><ul><ul><ul><li>모델마다 Crack Mesh 에 임의의 회전 값과 포지션 값을 적용한다 . </li></ul></ul></ul><ul><ul><li>Crack Mesh 를 bump-mapped specular 만 계산하여 렌더링 </li></ul></ul><ul><ul><ul><li>Specular 가 일어나지 않는 부분은 완전히 투명 </li></ul></ul></ul><ul><ul><ul><li>Backface culling 을 끄고 렌더링 </li></ul></ul></ul><ul><ul><ul><li>FBO(Frame Buffer Object) 를 이용하여 텍스쳐에 렌더링 </li></ul></ul></ul>
  6. 6. Adding Cracks <ul><li>Crack objects Clipping </li></ul><ul><ul><li>Crack mesh 가 모델 안에 완전히 fit 되지 않는 문제가 있다 . </li></ul></ul><ul><ul><li>Screen space CSG(Constructive Solid Geometry) 를 응용 </li></ul></ul><ul><ul><ul><li>Boolean Difference </li></ul></ul></ul><ul><ul><ul><li>Stencil Buffer 를 두 번째 depth buffer 로 사용 </li></ul></ul></ul><ul><ul><li>Our Method </li></ul></ul><ul><ul><ul><li>Ice object 의 front-facing surface 의 depth 값과 back-facing surface 의 depth 값을 텍스쳐에 기록한다 . </li></ul></ul></ul><ul><ul><ul><ul><li>최적 해상도의 depth buffer 구하기 </li></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>v – 카메라에서 ice object 의 중심으로의 벡터의 길이 </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>d – ice object 바운딩 박스의 대각의 길이 </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>Near plane = v – d / 2.0; </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>Far plane = v + d / 2.0; </li></ul></ul></ul></ul></ul>
  7. 7. Adding Cracks <ul><li>Crack objects Clipping </li></ul><ul><ul><li>Our Method (Continued…) </li></ul></ul><ul><ul><ul><li>Crack object 를 렌더링 하면서 depth 값이 위의 depth buffer 들을 샘플링 한 사이값이 아니면 pixel 을 렌더링 하지 않는다 . </li></ul></ul></ul>
  8. 8. Air in the Ice <ul><li>Air bubble </li></ul><ul><ul><li>얼음이 흰색인 이유는 얼음 안에 공기가 들어 있기 때문 </li></ul></ul><ul><ul><li>얼음의 중심으로 갈 수록 밀도가 늘어난다 . </li></ul></ul><ul><li>Approximation </li></ul><ul><ul><li>볼륨감 있는 air core 를 만들려면 아래와 같은 two-sided, semi-transparent 텍스쳐를 10~15 번 정도 텍스쳐에 렌더링 한다 . </li></ul></ul><ul><ul><ul><li>Ice object 의 중심에서 임의의 회전값을 적용 한다 . </li></ul></ul></ul>
  9. 9. Reflection and Two-sided Refraction <ul><li>Reflection Rl = 2.0*(V∙N)N - V </li></ul><ul><ul><li>Cubic environment maps (cube maps) </li></ul></ul><ul><li>Two-sided Refraction Rr = 0.5*(V-N)N - V </li></ul><ul><ul><li>Light refract 는 entry point 와 exit point 의 두 point 가 있으므로 Reflection 보다는 복잡하다 . </li></ul></ul><ul><ul><ul><li>가장 쉽고 저렴한 Refraction 은 front-facing surface 에만 적용하는 것인데 품질이 좋지 않다 . </li></ul></ul></ul>One point Refraction Two point Refraction
  10. 10. Reflection and Two-sided Refraction <ul><li>Two-sided Refraction (Continued…) </li></ul><ul><ul><li>Ice object 의 back-side normal 정보가 필요 </li></ul></ul><ul><ul><ul><li>shader 를 이용해 back-facing face 들의 normal 을 텍스쳐에 렌더링 </li></ul></ul></ul><ul><ul><ul><ul><li>퍼포먼스 오버헤드를 줄이기 위해 FBO 를 사용한다 . </li></ul></ul></ul></ul><ul><ul><li>한 픽셀의 front/back-side normal 정보가 있으므로 두 정보를 이용해 새로운 normal 값을 구한다 . (weight = 0.33) </li></ul></ul><ul><ul><ul><li>half3 newNormal = normal * (1.0 – weight) – backSideNormal * weight; </li></ul></ul></ul><ul><ul><ul><ul><li>물리적으로 맞는 연산은 아니지만 퍼포먼스와의 Tradeoff </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Ice 는 크게 왜곡되는 재질이므로 이상하지 않다 . </li></ul></ul></ul></ul><ul><li>Mix the reflection and refraction </li></ul><ul><ul><li>approximation Fresnel team f = (1.0 - |V∙N|)^3 </li></ul></ul><ul><ul><ul><li>V = Eye vector, N = Normal vector </li></ul></ul></ul><ul><ul><li>Mixed = RefractionColor*f + ReflectionColor*(1.0-f) </li></ul></ul>
  11. 11. Environment Bump Mapping and Masking <ul><li>Bump Mapping </li></ul><ul><ul><li>Ice 는 크게 왜곡되는 재질이므로 bump map 을 이용하여 detail 을 향상시키고 일관되게 보이지 않게 한다 . </li></ul></ul><ul><li>Bump Masking </li></ul><ul><ul><li>Normal map 을 적용할지를 결정하는 grayscale texture </li></ul></ul><ul><ul><li>표면을 일관적이지 않게 나타내고 small crack 을 나타낸다 . </li></ul></ul>Bump Map RGB Mask Map Grayscale
  12. 12. Conclusion
  13. 13. Shader Code – IceCrackDepth <ul><li>FragOut mainF(VertOut IN, uniform sampler2D bumpMap, uniform sampler2D depthTexFF, uniform sampler2D depthTexBF, </li></ul><ul><li>float4 winpos : WPOS, uniform half bumpStrength) </li></ul><ul><li>{ </li></ul><ul><li>FragOut OUT; </li></ul><ul><li>half2 texCoordsProj = 0.5 * (IN.vertPos.xy/IN.vertPos.z) + 0.5; //calculate screen space texture coordinates </li></ul><ul><li>half4 bumpCol = tex2D(bumpMap, IN.tCoords.xy); //get bumpmap value </li></ul><ul><li>//normalize vectors, and displace normal with bumpmap </li></ul><ul><li>IN.normal = normalize(IN.normal - bumpCol.xyz*bumpStrength); </li></ul><ul><li>IN.viewVec = normalize(IN.viewVec); </li></ul><ul><li>IN.lightVec = normalize(IN.lightVec.xyz); </li></ul><ul><li>//calculate reflection and refraction vectors </li></ul><ul><li>half3 reflectVec = reflect(IN.viewVec, IN.normal); </li></ul><ul><li>//calculate specular highlight </li></ul><ul><li>half spec = pow(clamp(dot(IN.lightVec.xyz, -reflectVec), 0.0, 1.0), 20.0); </li></ul><ul><li>half3 specCol = spec; </li></ul><ul><li>//DEPTH TEST (don't draw pixels outside the ice model) </li></ul><ul><li>half4 depthFFCol = tex2D(depthTexFF, texCoordsProj); </li></ul><ul><li>half4 depthBFCol = tex2D(depthTexBF, texCoordsProj); </li></ul><ul><li>//if outside the model, draw nothing (alpha=0) </li></ul><ul><li>half alpha = 1.0; </li></ul><ul><li>if(winpos.z<depthFFCol.b || winpos.z>depthBFCol.b) </li></ul><ul><li>alpha = 0.0; </li></ul><ul><li>OUT.col.xyz = specCol + bumpCol.xxx*0.05; </li></ul><ul><li>OUT.col.a = alpha; </li></ul><ul><li>return OUT; </li></ul><ul><li>} </li></ul>
  14. 14. Shader Code – IceFinal <ul><li>FragOut mainF(VertOut IN, uniform sampler2D backSide, uniform sampler2D bumpMask, uniform sampler2D bumpMap, </li></ul><ul><li>uniform samplerCUBE envMap, uniform sampler2D cracks, uniform sampler2D core, </li></ul><ul><li>uniform half eta, //relative refraction index </li></ul><ul><li>uniform half bumpStrength, //how much impact the bumpmap have on the normals </li></ul><ul><li>uniform half backSideRefr) //how much the backside's normals will affect the refraction </li></ul><ul><li>{ </li></ul><ul><li>FragOut OUT; </li></ul><ul><li>//calculate screen space texture coordinates </li></ul><ul><li>half2 texCoordsProj = 0.5 * (IN.vertPos.xy/IN.vertPos.z) + 0.5; </li></ul><ul><li>//get bumpmap value </li></ul><ul><li>half3 bumpCol = tex2D(bumpMap, IN.tCoords.xy); </li></ul><ul><li>//get bumpmap mask value </li></ul><ul><li>half3 bumpMaskCol = tex2D(bumpMask, IN.tCoords.xy); </li></ul><ul><li>//get backside normals </li></ul><ul><li>half3 backsideNormal = 2*tex2D(backSide, texCoordsProj) - 1; </li></ul><ul><li>//normalize vectors, and displace normal with bumpmap </li></ul><ul><li>backsideNormal = normalize(backsideNormal); </li></ul><ul><li>IN.normal = normalize(IN.normal - bumpCol*bumpStrength*bumpMaskCol); </li></ul><ul><li>IN.viewVec = normalize(IN.viewVec); </li></ul><ul><li>IN.lightVec = normalize(IN.lightVec); </li></ul><ul><li>//calculate reflection and refraction vectors </li></ul><ul><li>half3 reflectVec = reflect(IN.viewVec, IN.normal); </li></ul><ul><li>half3 refractVec = refract(IN.viewVec, IN.normal*(1.0-backSideRefr)-backsideNormal*backSideRefr, eta); </li></ul>
  15. 15. Shader Code – IceFinal (Continued…) <ul><li>//calculate specular highlight </li></ul><ul><li>half spec = pow(clamp(dot(IN.lightVec.xyz, -reflectVec), 0.0, 1.0), 20.0); </li></ul><ul><li>half3 specCol = spec; </li></ul><ul><li>//fetch cubemap-texture color values </li></ul><ul><li>half3 refrCol = texCUBE(envMap, refractVec); </li></ul><ul><li>half3 reflCol = texCUBE(envMap, reflectVec); </li></ul><ul><li>//fetch cracks texture color value, distort the texcoords with the worldspace normal of the surface </li></ul><ul><li>half3 crackCol = tex2D(cracks, texCoordsProj - 0.013*IN.normal.xy); </li></ul><ul><li>//fetch air core texture color value, distort the texcoords with the worldspace normal of the surface </li></ul><ul><li>half3 coreCol = tex2D(core, texCoordsProj - 0.02*IN.normal.xy); </li></ul><ul><li>half3 texColMask = half3(0.15, 0.15, 0.2); </li></ul><ul><li>// {[what you see through the ice * mix val.] + [reflection*mix val.] + [texture color from the bumpmap]}*0.9 + specular </li></ul><ul><li>OUT.col.rgb = (((crackCol+refrCol)*(1.0-coreCol.x)+coreCol)*(1.0-IN.fresnelVal) + reflCol*(IN.fresnelVal) + bumpCol.rrr*texColMask)*0.88 + specCol; </li></ul><ul><li>return OUT; </li></ul><ul><li>} </li></ul>

×