Skip to content

Instantly share code, notes, and snippets.

@rngtm
Created August 6, 2023 10:58
Show Gist options
  • Save rngtm/bfaea8b80aa0a6cb3a1ef2b2b43380e6 to your computer and use it in GitHub Desktop.
Save rngtm/bfaea8b80aa0a6cb3a1ef2b2b43380e6 to your computer and use it in GitHub Desktop.
シンプルなテッセレーションシェーダー
Shader "Unlit/SimpleTess"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_TessFactor ("Tess Factor", Vector) = (1, 1, 1, 1) // テセレーション係数 (メッシュをどれくらい分割するかを決定する)
}
SubShader
{
Tags
{
"RenderPipeline" = "UniversalPipeline"
"RenderType"="Opaque"
"UniversalMaterialType" = "Lit"
"Queue"="Geometry"
}
LOD 100
Pass
{
Tags
{
"LightMode"="UniversalForward"
}
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma hull hull
#pragma domain domain
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
// 頂点シェーダー 入力
struct VsInput
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
// ハルシェーダーの入力 (制御点)
struct HsInput
{
float3 positionOS : POS;
float2 uv : TEXCOORD0;
};
// ハルシェーダーの出力 (制御点)
struct HsControlPointOutput
{
float3 positionOS : POS;
float2 uv : TEXCOORD0;
};
// ハルシェーダーの出力 (パッチ定数)
struct HsConstantOutput
{
float tessFactor[3] : SV_TessFactor;
float insideTessFactor : SV_InsideTessFactor;
};
// ドメインシェーダー出力
struct DsOutput
{
float4 positionCS : SV_Position;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _TessFactor; // テッセレーション係数 (各パッチを分割する程度)
//////////////////////////////////////
// 頂点シェーダー
//////////////////////////////////////
HsInput vert (VsInput input)
{
HsInput o;
o.positionOS = input.vertex.xyz;
o.uv = input.uv;
return o;
}
//////////////////////////////////////
// ハルシェーダー (制御点を出力)
// https://learn.microsoft.com/ja-jp/windows/uwp/graphics-concepts/hull-shader-stage--hs-
//////////////////////////////////////
[domain("tri")]
[partitioning("integer")]
[outputtopology("triangle_cw")]
[patchconstantfunc("hullConst")]
[outputcontrolpoints(3)]
HsControlPointOutput hull(InputPatch<HsInput, 3> input, uint id : SV_OutputControlPointID)
{
HsControlPointOutput output;
output.positionOS = input[id].positionOS.xyz;
output.uv = input[id].uv;
return output;
}
//////////////////////////////////////
// ハルシェーダー (パッチ定数の出力)
// https://learn.microsoft.com/ja-jp/windows/uwp/graphics-concepts/hull-shader-stage--hs-
//////////////////////////////////////
HsConstantOutput hullConst(InputPatch<HsInput, 3> i)
{
HsConstantOutput output;
output.tessFactor[0] = _TessFactor.x;
output.tessFactor[1] = _TessFactor.y;
output.tessFactor[2] = _TessFactor.z;
output.insideTessFactor = _TessFactor.w;
return output;
}
//////////////////////////////////////
// ドメインシェーダー
// https://learn.microsoft.com/ja-jp/windows/uwp/graphics-concepts/domain-shader-stage--ds-
//////////////////////////////////////
[domain("tri")]
DsOutput domain(
HsConstantOutput hsConst,
const OutputPatch<HsControlPointOutput, 3> input,
float3 bary : SV_DomainLocation // ドメインポイントがハル上で占める位置
)
{
float3 positionOS =
+ bary.x * input[0].positionOS
+ bary.y * input[1].positionOS
+ bary.z * input[2].positionOS;
float2 uv =
+ bary.x * input[0].uv
+ bary.y * input[1].uv
+ bary.z * input[2].uv;
DsOutput output = (DsOutput)0;
output.positionCS = TransformObjectToHClip(positionOS);
output.uv = uv;
return output;
}
//////////////////////////////////////
// フラグメントシェーダー
//////////////////////////////////////
half4 frag (DsOutput i) : SV_Target
{
half4 col = tex2D(_MainTex, i.uv);
return col;
}
ENDHLSL
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment