ゲーム制作技術録

主にUnity/Godot4関連の技術ブログです

【Unity】【URP12対応】Unlitから自作シェーダー : HLSLへ書き換え

シェーダーの勉強がてらUnlitからシェーダーを自作したいと思います。
今回はURP対応の、HLSLへの書き換えをメインにしつつ、テクスチャ表示をします。

完成はトゥーンシェーダーになる予定です。

Unity 2021.3
UniversalRP 12.1
Forward

作成したトゥーンシェーダー

はじめに

今回はカラーの変更とテクスチャの表示をメインに扱います。
あまり凝った処理はしていないので自作シェーダーのテンプレートみたいなものが出来上がりました。

事前準備

この辺は調べれば情報が転がってると思うので特に解説はしません。
やることだけ書いていきます。

オブジェクトの作成

作ったシェーダーの確認用なのでなんでもいいです。

シェーダーとマテリアルの作成

Create > Shader > Unlit ShaderからUnlitシェーダーを作成します。
マテリアルもテキトーに作成して、作ったシェーダーを割り当てておきます。

Depth Priming Mode をDisabledに変更

Universal Render Data 内のDepth Priming Mode を Disabled にします。

この機能がAutoもしくはForcedだとシェーダーが正しく表示されないため、この機能はオフにしておきます。

なぜ表示されないのかとかは分かりませんが、また詳しく調べておきたいと思います。

HLSLへ書き換え

全体的にHLSLに書き換えていきます。

なお、事細かに「シェーダー」について解説はしません
基本的な話は他の情報を参照しておくことをお勧めします。

プロパティ

テクスチャ表示に加えてカラー変更もしたいので、Propertiesにメインカラーを追加して記述もちょこっと変えます。

// プロパティ
Properties {
    _MainColor("Main Color", Color) = (1, 1, 1, 1)
    _MainTex ("Main Texture", 2D) = "white" {}
}

Tags

Tagsに"RenderPipeline" = "UniversalPipeline"を追加します。

Tags { "RenderType"="Opaque" "RenderPipeline" = "UniversalPipeline" }

PROGRAM / END

CGPROGRAM / ENDCGをHLSLPROGRAM / ENDHLSLに変更します。

HLSLPROGRAM
・・・
ENDHLSL

#include

#includeはUnityCG.cgincではなくCore.hlslになります。

// #include "UnityCG.cginc"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

struct

appdataとv2fがありますが、それぞれAttributesVaryingsに変更して中身もちょこっと変えておきます。
フォグはUNITY_FOG_COORDS()マクロが使えないのでfogFactorを定義して使います。

変更前

struct appdata {
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
};

struct v2f {
    float2 uv : TEXCOORD0;
    UNITY_FOG_COORDS(1)
    float4 vertex : SV_POSITION;
};

変更後

struct Attributes {
    float4 positionOS : POSITION;
    float2 uv : TEXCOORD0;
};

struct Varyings {
    float4 positionHCS : SV_POSITION;
    float2 uv : TEXCOORD0;
    // フォグの計算で使うinterpolator
    float fogFactor : TEXCOORD1;
};

変数

変数も必要なやつを定義します。
書き方も少し変わっています。

// sampler2D _MainTex;

float4 _MainColor;
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
float4 _MainTex_ST;

頂点シェーダー

// 頂点シェーダー
Varyings vert(Attributes IN) {
    Varyings OUT;
    
    // TransformObjectToHClip()で頂点位置をオブジェクト空間からクリップスペースへ変換
    // UnityObjectToClipPos()がTransformObjectToHClip()になった
    OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
    // TRANSFORM_TEX()マクロでタイリングなどを計算する
    OUT.uv = TRANSFORM_TEX(IN.uv, _MainTex);
    // fog factor の計算
    OUT.fogFactor = ComputeFogFactor(IN.positionOS.z);
    
    return OUT;
}

フラグメントシェーダー

// フラグメントシェーダー
float4 frag(Varyings IN) : SV_Target {
    // テクスチャをサンプリングして、カラーを乗算する
    float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv) * _MainColor;
    
    // Fogを適用する
    color.rgb = MixFog(color.rgb, IN.fogFactor);
    
    return color;
}

実行結果

通常のUnlitと同じ結果が得られているのが確認できました。
MainColorを変更すると色が変わります。


コード全文

終わりに

次回はセルフシャドウやります。
たぶん。

参考

qiita.com

qiita.com