Advertisement
GaelVanhalst

Molehill Shader

Jan 25th, 2016
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.73 KB | None | 0 0
  1. HLSL
  2.  
  3. /*DirtPileShader.fx
  4. FirstName: Ga?l
  5. LastName: Vanhalst
  6. Class: 2DAE_GD1
  7. */
  8.  
  9. //************
  10. // VARIABLES *
  11. //************
  12. cbuffer cbPerObject
  13. {
  14. float4x4 m_MatrixWorldViewProj : WORLDVIEWPROJECTION;
  15. float4x4 m_MatrixWorld : WORLD;
  16. float3 m_LightDir=float3(-0.577f, -0.577f, 0.577f);
  17. float m_Radius={5.f};
  18. }
  19.  
  20.  
  21. RasterizerState FrontCulling
  22. {
  23. CullMode = NONE;
  24. };
  25.  
  26. SamplerState samLinear
  27. {
  28. Filter = MIN_MAG_MIP_LINEAR;
  29. AddressU = Wrap;// of Mirror of Clamp of Border
  30. AddressV = Wrap;// of Mirror of Clamp of Border
  31. };
  32.  
  33. Texture2D m_TextureDiffuse;
  34.  
  35. //**********
  36. // STRUCTS *
  37. //**********
  38. struct VS_DATA
  39. {
  40. float3 Position : POSITION;
  41. float3 Normal : NORMAL;
  42. float2 TexCoord : TEXCOORD;
  43. float Height: HEIGHT;
  44. };
  45.  
  46. struct GS_DATA
  47. {
  48. float4 Position : SV_POSITION;
  49. float3 Normal : NORMAL;
  50. float2 TexCoord : TEXCOORD0;
  51. };
  52.  
  53.  
  54.  
  55. //****************
  56. // VERTEX SHADER *
  57. //****************
  58. VS_DATA MainVS(VS_DATA vsData)
  59. {
  60. if(vsData.Height<0)vsData.Height=0;
  61.  
  62. if(vsData.Height>1)vsData.Height=1;
  63.  
  64. return vsData;
  65. }
  66.  
  67. //****************
  68. // GEOMETRY SHADER *
  69. //****************
  70.  
  71. float3 normalCalculator(VS_DATA vertex1, VS_DATA vertex2, VS_DATA vertex3)
  72. {
  73. float3 delta13=vertex1.Position-vertex3.Position;
  74. float3 delta12=vertex1.Position-vertex2.Position;
  75.  
  76.  
  77. float3 normal;
  78. normal=cross(delta12,delta13);
  79. normal=normalize(normal);
  80.  
  81. return normal;
  82. }
  83.  
  84. [maxvertexcount(9)]
  85. void GS(triangle VS_DATA gln[3], inout TriangleStream<GS_DATA> triStream)
  86. {
  87. GS_DATA output = (GS_DATA)0;
  88.  
  89. output.Position=mul(float4(gln[0].Position,1),m_MatrixWorldViewProj);
  90. output.Normal = mul(gln[0].Normal, (float3x3)m_MatrixWorld);
  91. output.TexCoord = gln[0].TexCoord;
  92. triStream.Append(output);
  93.  
  94. output.Position=mul(float4(gln[1].Position,1),m_MatrixWorldViewProj);
  95. output.Normal = mul(gln[1].Normal, (float3x3)m_MatrixWorld);
  96. output.TexCoord = gln[1].TexCoord;
  97. triStream.Append(output);
  98.  
  99. output.Position=mul(float4(gln[2].Position,1),m_MatrixWorldViewProj);
  100. output.Normal = mul(gln[2].Normal, (float3x3)m_MatrixWorld);
  101. output.TexCoord = gln[2].TexCoord;
  102. triStream.Append(output);
  103.  
  104. //Check how many points are elevated
  105. uint counter=0;
  106. for(uint i=0;i<3;i++)
  107. {
  108. if(gln[i].Height>0)counter++;
  109. }
  110.  
  111. //Nothing needs to happen
  112. if(counter==0)return;
  113.  
  114. //Generate new triangles
  115. if(counter==1)
  116. {
  117.  
  118. VS_DATA newV[3]={(VS_DATA)0,(VS_DATA)0,(VS_DATA)0};
  119.  
  120. int levetatedPoint;
  121. int groundPoint1, groundPoint2;
  122. bool groundPSet=false;
  123.  
  124. for(uint i=0;i<3;i++)
  125. {
  126. newV[i]=gln[i];
  127. if(gln[i].Height>0)levetatedPoint=i;
  128. else if(groundPSet)
  129. {
  130. groundPoint2=i;
  131. }
  132. else
  133. {
  134. groundPoint1=i;
  135. groundPSet=true;
  136. }
  137. }
  138.  
  139. float distance=(1-sqrt(1-(gln[levetatedPoint].Height*gln[levetatedPoint].Height)))*m_Radius;
  140.  
  141. float deltaX=gln[groundPoint1].Position.x-gln[levetatedPoint].Position.x;
  142. float deltaY=gln[groundPoint1].Position.y-gln[levetatedPoint].Position.y;
  143. float deltaZ=gln[groundPoint1].Position.z-gln[levetatedPoint].Position.z;
  144.  
  145. float deltaU=gln[groundPoint1].TexCoord.x-gln[levetatedPoint].TexCoord.x;
  146. float deltaV=gln[groundPoint1].TexCoord.y-gln[levetatedPoint].TexCoord.y;
  147.  
  148. float ratio=sqrt((distance*distance)/((deltaY*deltaY)+(deltaX*deltaX)+(deltaZ*deltaZ)));
  149.  
  150. float3 position=gln[levetatedPoint].Position;
  151. position.x+=deltaX*ratio;
  152. position.y+=deltaY*ratio;
  153. position.z+=deltaZ*ratio;
  154. newV[groundPoint1].Position=float3(position);
  155.  
  156. float2 uvposition=gln[levetatedPoint].TexCoord;
  157. uvposition.x+=deltaU*ratio;
  158. uvposition.y+=deltaV*ratio;
  159. newV[groundPoint1].TexCoord=uvposition;
  160.  
  161.  
  162. deltaX=gln[groundPoint2].Position.x-gln[levetatedPoint].Position.x;
  163. deltaY=gln[groundPoint2].Position.y-gln[levetatedPoint].Position.y;
  164. deltaZ=gln[groundPoint2].Position.z-gln[levetatedPoint].Position.z;
  165.  
  166. deltaU=gln[groundPoint2].TexCoord.x-gln[levetatedPoint].TexCoord.x;
  167. deltaV=gln[groundPoint2].TexCoord.y-gln[levetatedPoint].TexCoord.y;
  168.  
  169. ratio=sqrt((distance*distance)/((deltaY*deltaY)+(deltaX*deltaX)+(deltaZ*deltaZ)));
  170.  
  171. position=gln[levetatedPoint].Position;
  172. position.x+=deltaX*ratio;
  173. position.y+=deltaY*ratio;
  174. position.z+=deltaZ*ratio;
  175. newV[groundPoint2].Position=float3(position);
  176.  
  177. uvposition=gln[levetatedPoint].TexCoord;
  178. uvposition.x+=deltaU*ratio;
  179. uvposition.y+=deltaV*ratio;
  180. newV[groundPoint2].TexCoord=uvposition;
  181.  
  182.  
  183. newV[0].Position+=(newV[0].Height*m_Radius)*newV[0].Normal;
  184. newV[1].Position+=(newV[1].Height*m_Radius)*newV[1].Normal;
  185. newV[2].Position+=(newV[2].Height*m_Radius)*newV[2].Normal;
  186.  
  187. newV[0].Normal=normalCalculator(newV[0],newV[1],newV[2]);
  188. newV[1].Normal=normalCalculator(newV[1],newV[2],newV[0]);
  189. newV[2].Normal=normalCalculator(newV[2],newV[0],newV[1]);
  190.  
  191. triStream.RestartStrip();
  192.  
  193.  
  194. output.Position=mul(float4(newV[0].Position,1),m_MatrixWorldViewProj);
  195. output.Normal = mul(newV[0].Normal, (float3x3)m_MatrixWorld);
  196. output.TexCoord = newV[0].TexCoord;
  197. triStream.Append(output);
  198.  
  199.  
  200. output.Position=mul(float4(newV[1].Position,1),m_MatrixWorldViewProj);
  201. output.Normal = mul(newV[1].Normal, (float3x3)m_MatrixWorld);
  202. output.TexCoord = newV[1].TexCoord;
  203. triStream.Append(output);
  204.  
  205. output.Position=mul(float4(newV[2].Position,1),m_MatrixWorldViewProj);
  206. output.Normal = mul(newV[2].Normal, (float3x3)m_MatrixWorld);
  207. output.TexCoord = newV[2].TexCoord;
  208. triStream.Append(output);
  209. }
  210.  
  211. //Generate new triangles
  212. else if(counter==2)
  213. {
  214.  
  215. VS_DATA newV[3]={(VS_DATA)0,(VS_DATA)0,(VS_DATA)0};
  216. int elevetatedPoint1, elevetatedPoint2;
  217. int groundPoint;
  218. bool elevPSet=false;
  219.  
  220. for(uint i=0;i<3;i++)
  221. {
  222. newV[i]=gln[i];
  223. if(gln[i].Height<=0)groundPoint=i;
  224. else if(elevPSet)
  225. {
  226. elevetatedPoint2=i;
  227. }
  228. else
  229. {
  230. elevetatedPoint1=i;
  231. elevPSet=true;
  232. }
  233. }
  234. float distance=(1-sqrt(1-(gln[elevetatedPoint1].Height*gln[elevetatedPoint1].Height)))*m_Radius;
  235.  
  236. float deltaX=gln[groundPoint].Position.x-gln[elevetatedPoint1].Position.x;
  237. float deltaY=gln[groundPoint].Position.y-gln[elevetatedPoint1].Position.y;
  238. float deltaZ=gln[groundPoint].Position.z-gln[elevetatedPoint1].Position.z;
  239.  
  240. float deltaU=gln[groundPoint].TexCoord.x-gln[elevetatedPoint1].TexCoord.x;
  241. float deltaV=gln[groundPoint].TexCoord.y-gln[elevetatedPoint1].TexCoord.y;
  242.  
  243. float ratio=sqrt((distance*distance)/((deltaY*deltaY)+(deltaX*deltaX)+(deltaZ*deltaZ)));
  244.  
  245. float3 position=gln[elevetatedPoint1].Position;
  246. position.x+=deltaX*ratio;
  247. position.y+=deltaY*ratio;
  248. position.z+=deltaZ*ratio;
  249. newV[elevetatedPoint1].Position=float3(position);
  250.  
  251. float2 uvposition=gln[elevetatedPoint1].TexCoord;
  252. uvposition.x+=deltaU*ratio;
  253. uvposition.y+=deltaV*ratio;
  254. newV[elevetatedPoint1].TexCoord=uvposition;
  255.  
  256.  
  257. distance=(1-sqrt(1-gln[elevetatedPoint2].Height*gln[elevetatedPoint2].Height))*m_Radius;
  258.  
  259. deltaX=gln[groundPoint].Position.x-gln[elevetatedPoint2].Position.x;
  260. deltaY=gln[groundPoint].Position.y-gln[elevetatedPoint2].Position.y;
  261. deltaZ=gln[groundPoint].Position.z-gln[elevetatedPoint2].Position.z;
  262.  
  263. deltaU=gln[groundPoint].TexCoord.x-gln[elevetatedPoint2].TexCoord.x;
  264. deltaV=gln[groundPoint].TexCoord.y-gln[elevetatedPoint2].TexCoord.y;
  265.  
  266. ratio=sqrt((distance*distance)/((deltaY*deltaY)+(deltaX*deltaX)+(deltaZ*deltaZ)));
  267.  
  268. position=gln[elevetatedPoint2].Position;
  269. position.x+=deltaX*ratio;
  270. position.y+=deltaY*ratio;
  271. position.z+=deltaZ*ratio;
  272. newV[elevetatedPoint2].Position=float3(position);
  273.  
  274. uvposition=gln[elevetatedPoint2].TexCoord;
  275. uvposition.x+=deltaU*ratio;
  276. uvposition.y+=deltaV*ratio;
  277. newV[elevetatedPoint2].TexCoord=uvposition;
  278.  
  279.  
  280. gln[0].Position+=(gln[0].Height*m_Radius)*gln[0].Normal;
  281. gln[1].Position+=(gln[1].Height*m_Radius)*gln[1].Normal;
  282. gln[2].Position+=(gln[2].Height*m_Radius)*gln[2].Normal;
  283.  
  284. triStream.RestartStrip();
  285. if(gln[0].Height>0)gln[0].Normal=normalCalculator(gln[0],gln[1],gln[2]);
  286. if(gln[1].Height>0)gln[1].Normal=normalCalculator(gln[1],gln[2],gln[0]);
  287. if(gln[2].Height>0)gln[2].Normal=normalCalculator(gln[2],gln[0],gln[1]);
  288.  
  289. output.Position=mul(float4(gln[elevetatedPoint1].Position,1),m_MatrixWorldViewProj);
  290. output.Normal = mul(gln[elevetatedPoint1].Normal, (float3x3)m_MatrixWorld);
  291. output.TexCoord = gln[elevetatedPoint1].TexCoord;
  292. triStream.Append(output);
  293.  
  294.  
  295. output.Position=mul(float4(gln[elevetatedPoint2].Position,1),m_MatrixWorldViewProj);
  296. output.Normal = mul(gln[elevetatedPoint2].Normal, (float3x3)m_MatrixWorld);
  297. output.TexCoord = gln[elevetatedPoint2].TexCoord;
  298. triStream.Append(output);
  299.  
  300. output.Position=mul(float4(newV[elevetatedPoint1].Position,1),m_MatrixWorldViewProj);
  301. output.Normal = mul(newV[elevetatedPoint1].Normal, (float3x3)m_MatrixWorld);
  302. output.TexCoord = newV[elevetatedPoint1].TexCoord;
  303. triStream.Append(output);
  304.  
  305. triStream.RestartStrip();
  306.  
  307. output.Position=mul(float4(newV[elevetatedPoint1].Position,1),m_MatrixWorldViewProj);
  308. output.Normal = mul(newV[elevetatedPoint1].Normal, (float3x3)m_MatrixWorld);
  309. output.TexCoord = newV[elevetatedPoint1].TexCoord;
  310. triStream.Append(output);
  311.  
  312. output.Position=mul(float4(gln[elevetatedPoint2].Position,1),m_MatrixWorldViewProj);
  313. output.Normal = mul(gln[elevetatedPoint2].Normal, (float3x3)m_MatrixWorld);
  314. output.TexCoord = gln[elevetatedPoint2].TexCoord;
  315. triStream.Append(output);
  316.  
  317. output.Position=mul(float4(newV[elevetatedPoint2].Position,1),m_MatrixWorldViewProj);
  318. output.Normal = mul(newV[elevetatedPoint2].Normal, (float3x3)m_MatrixWorld);
  319. output.TexCoord = newV[elevetatedPoint2].TexCoord;
  320. triStream.Append(output);
  321.  
  322.  
  323. }
  324. //Elevate existing triangle (no new triangles need to be generated)
  325. else if(counter==3)
  326. {
  327. triStream.RestartStrip();
  328. gln[0].Position+=(gln[0].Height*m_Radius)*gln[0].Normal;
  329. gln[1].Position+=(gln[1].Height*m_Radius)*gln[1].Normal;
  330. gln[2].Position+=(gln[2].Height*m_Radius)*gln[2].Normal;
  331.  
  332. gln[0].Normal=normalCalculator(gln[0],gln[1],gln[2]);
  333. gln[1].Normal=normalCalculator(gln[1],gln[2],gln[0]);
  334. gln[2].Normal=normalCalculator(gln[2],gln[0],gln[1]);
  335.  
  336. output.Position=mul(float4(gln[0].Position,1),m_MatrixWorldViewProj);
  337. output.Normal = mul(gln[0].Normal, (float3x3)m_MatrixWorld);
  338. output.TexCoord = gln[0].TexCoord;
  339. triStream.Append(output);
  340.  
  341.  
  342.  
  343. output.Position=mul(float4(gln[1].Position,1),m_MatrixWorldViewProj);
  344. output.Normal = mul(gln[1].Normal, (float3x3)m_MatrixWorld);
  345. output.TexCoord = gln[1].TexCoord;
  346. triStream.Append(output);
  347.  
  348.  
  349. output.Position=mul(float4(gln[2].Position,1),m_MatrixWorldViewProj);
  350. output.Normal = mul(gln[2].Normal, (float3x3)m_MatrixWorld);
  351. output.TexCoord = gln[2].TexCoord;
  352. triStream.Append(output);
  353. }
  354.  
  355. }
  356.  
  357. //***************
  358. // PIXEL SHADER *
  359. //***************
  360.  
  361.  
  362. float3 CalculateDiffuse(float3 normal, float2 texCoord)
  363. {
  364. float4 diffuseColor=float4(0,0,0,1);
  365. diffuseColor = m_TextureDiffuse.Sample( samLinear,texCoord );
  366. float3 color_rgb= diffuseColor.rgb;
  367.  
  368. float diffuseStrength = dot(normal, -m_LightDir);
  369. diffuseStrength = diffuseStrength * 0.5 + 0.5;
  370. diffuseStrength = saturate(diffuseStrength);
  371. color_rgb = color_rgb * diffuseStrength;
  372.  
  373. return float3( color_rgb);
  374. }
  375.  
  376. float4 MainPS(GS_DATA input) : SV_TARGET
  377. {
  378.  
  379. input.Normal = normalize(input.Normal);
  380.  
  381. float3 diffColor = CalculateDiffuse(input.Normal, input.TexCoord);
  382.  
  383. return float4(diffColor,1);
  384. }
  385.  
  386. //*************
  387. // TECHNIQUES *
  388. //*************
  389. technique10 DefaultTechnique
  390. {
  391. pass p0 {
  392. SetRasterizerState(FrontCulling);
  393. SetVertexShader(CompileShader(vs_4_0, MainVS()));
  394. SetGeometryShader(CompileShader(gs_4_0,GS()));
  395. SetPixelShader(CompileShader(ps_4_0, MainPS()));
  396. }
  397. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement