Tessellationを用いた波紋の作成
前回の記事で作成した波紋を用いて、テッセレーションによって分割された平面に波紋を発生させてみました。テッセレーションの詳細に関しては参考サイトに書かれていますので、ここでは割愛いたします。また、平面を揺らしただけでは様子が分かり難いので、下記アセットを利用してワイヤーフレームで表示しました。
UCLA Wireframe Shader
shader
前回記事の波紋を表示するためのshaderをこのshaderに変更すると、テッセレーションよって分割されたワイヤーフレームの平面が表示されます。あとは、平面を左クリックすることで、平面が波打ちます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
Shader "Unlit/DispTessUCLAGWire" { Properties { _MainTex ("Texture", 2D) = "white" {} _TessFactor("TessFactor", Vector) = (2, 2, 2, 2) _HeightMap ("HeightMap", 2D) = "gray" {} _BumpAmt ("BunpAmp", Range(0, 10.0)) = 1 _Color ("Line Color", Color) = (1,1,1,1) _Thickness("Thickness", Float) = 1 } SubShader { Tags { "RenderType"="Transparent" "Queue"="Transparent" } Pass { Blend SrcAlpha OneMinusSrcAlpha ZWrite Off CGPROGRAM #pragma target 5.0 #pragma vertex vert #pragma fragment frag #pragma geometry geom #pragma hull RenderTriIntegerHS #pragma domain RenderTriDS #define INPUT_PATCH_SIZE 3 #define OUTPUT_PATCH_SIZE 3 #include "UnityCG.cginc" #include "UCLA GameLab Wireframe Functions.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct HS_Input{ float4 pos : INTERNALTESSPOS; float2 uv : TEXCOORD0; }; struct DS_Input { float3 pos : INTERNALTESSPOS; float2 uv : TEXCOORD0; }; struct DS_Output{ float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; struct TriConstant{ float tessFactor[3] : SV_TessFactor; float insideFactor : SV_insideTessFactor; }; sampler2D _HeightMap; float4 _HeightMap_ST; float4 _HeightMap_TexelSize; Vector _TessFactor; float _BumpAmt; HS_Input vert(appdata v) { HS_Input o = (HS_Input)0; o.pos = v.vertex; o.uv = v.uv; return o; } TriConstant ConstantHS(InputPatch<HS_Input, 3> iPatch){ TriConstant outConst; outConst.tessFactor[0] = _TessFactor.x; outConst.tessFactor[1] = _TessFactor.y; outConst.tessFactor[2] = _TessFactor.z; outConst.insideFactor = _TessFactor.w; return outConst; } [domain("tri")] [partitioning("integer")] [outputtopology("triangle_cw")] [outputcontrolpoints(OUTPUT_PATCH_SIZE)] [patchconstantfunc("ConstantHS")] DS_Input RenderTriIntegerHS(InputPatch<HS_Input, INPUT_PATCH_SIZE> i, uint id:SV_OutputControlPointID) { DS_Input o = (DS_Input)0; o.pos = i[id].pos; o.uv = i[id].uv; return o; } [domain("tri")] DS_Output RenderTriDS( TriConstant inConst, float3 domLoc : SV_DomainLocation, const OutputPatch<DS_Input, 3> oPatch){ DS_Output o = (DS_Output)0; float3 pos = oPatch[0].pos * domLoc.z + oPatch[1].pos * domLoc.x + oPatch[2].pos * domLoc.y; float2 uv = oPatch[0].uv * domLoc.z + oPatch[1].uv * domLoc.x + oPatch[2].uv * domLoc.y; float height = tex2Dlod(_HeightMap, float4(uv, 0, 0)).r; pos.y += (height - 0.5) * _BumpAmt; o.pos = UnityObjectToClipPos(float4(pos, 1)); o.uv = uv; return o; } [maxvertexcount(3)] void geom(triangle DS_Output input[3], inout TriangleStream<UCLAGL_g2f> outStream) { UCLAGL_geom(input, outStream); } fixed4 frag(UCLAGL_g2f i) : SV_Target { return UCLAGL_frag(i); } ENDCG } } } |
実行結果
上記shaderはWebGLでは動作しないため、Gif画像のみです。テッセレーションによって分割された平面が波打っている様子が確認できます。
参考サイト
もんしょの巣穴:DirectXの話 第130回
しゅみぷろ:テッセレーション基礎
しゅみぷろ:UnityTexturePaintでリアルタイムにオブジェクトを変形する
-
前の記事
波動方程式を用いた波紋の作成(2019/11/09修正) 2018.10.27
-
次の記事
法線マップをオブジェクト空間へ変換しシェーディング 2018.11.14
コメントを書く