LoginSignup
1
0

【URP】表裏面で別テクスチャ&アウトライン付与シェーダー

Posted at

0.シェーダーを書いた経緯

このアセットをURPで使おうとしたところ、シェーダーが対応していなかったので...頑張った。

1.シェーダーの最低限仕様

  • 用意されている3DモデルがPlaneみたいに裏面非描画になっていたので、描画させる
  • 表面と裏面で違うテクスチャを貼る
  • 基本的にテクスチャの白成分が高いので、重なってもわかるようにアウトラインを付与する

2.作ったシェーダー

Custom/Outline and Double-sided.shader
Shader "Custom/Outline and Double-sided"
{
    Properties
    {
        _MainTex ("Main Texture", 2D) = "white" {}
        _BackTex ("Back Texture", 2D) = "white" {}
        _OutlineColor ("Outline Color", Color) = (0, 0, 0, 1)
        _OutlineWidth ("Outline Width", Range(0, 0.1)) = 0.02
    }
    SubShader
    {
        Cull Off
        Tags { "RenderType"="Opaque" "RenderPipeline" = "UniversalPipeline" }
        LOD 100
        
        HLSLINCLUDE
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

        // マクロで定数化
        #define MIN 0.0001

        struct appdata
        {
            half4 vertex : POSITION;
            half2 uv : TEXCOORD0;
        };

        struct v2f
        {
            half4 vertex : SV_POSITION;
            half2 uv : TEXCOORD0;
        };

        TEXTURE2D(_MainTex);
        TEXTURE2D(_BackTex);
        SAMPLER(sampler_MainTex);
        SAMPLER(sampler_BackTex);

        CBUFFER_START(UnityPerMaterial)
        half4 _MainTex_ST;
        half4 _BackTex_ST;
        half4 _OutlineColor;
        half _OutlineWidth;
        CBUFFER_END
        
        ENDHLSL
        
        // 裏面も描画する
        Pass
        {
            // LightModeはマルチパス実行のために必須
            Tags{ "LightMode" = "UniversalForward" }
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 3.0
            
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = TransformObjectToHClip(v.vertex);
                o.vertex.z += MIN;
                o.uv = v.uv;
                return o;
            }

            half4 frag (v2f i, half facing : VFACE) : SV_Target
            {
                // カメラに向いている面によって表裏のテクスチャを切り替え
                return facing > 0 ? SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv) : SAMPLE_TEXTURE2D(_BackTex, sampler_BackTex, i.uv);
            }
            ENDHLSL
        }
        
        // アウトラインの描画
        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            v2f vert (appdata v)
            {
                v2f o;
                // アウトラインの分だけ拡大
                o.vertex = TransformObjectToHClip(v.vertex * (1 +_OutlineWidth));
                return o;
            }

            half4 frag(v2f i) : SV_Target
            {
                return _OutlineColor;
            }
            ENDHLSL
        }
    }
}

3.課題点

  • アウトラインが太さ統一ではなく、あくまでモデルの形を拡大したのを用意しているだけなので、ちょっと気持ち悪いなとは思ってる。まあ、妥協できるかな...

4.感想

正直、自力のシェーダーコーディングは初めてだったので、URPの仕様に苦戦したりShader Graphに浮気したりとまあいろいろ大変だった...。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0