LoginSignup
11
8

More than 5 years have passed since last update.

【Shader】ボリュームレンダリングで3Dノイズを可視化する

Posted at

はじめに

ボリュームレンダリングは雲の表現やCT、MRIの画像等に対して利用されるレンダリング方式です
このボリュームレンダリングと3Dノイズを組み合わて遊んでいきます

できあがり

メッシュにはプリミティブのCubeを使用しています。ボリュームレンダリングを適用する事で、あたかもCubeに中身があるような表現になっていると思います
癒やされるなあ〜〜
ao.gif

Cube3つ重ね
rainbow.gif

ソースコード

参考にさせて頂いた記事やGitHubのソースを切って張り合わせた程度の内容です
今回は流線表現に利用されたりするカールノイズを使います
SimplexNoise.cgincはKeijiro氏のSimplexNoise3D.hlslを利用しています

VolumeCurlNoise.shader
Shader "Volume/CurlNoise" {
    Properties {
        [HDR] _Color ("Color", Color) = (1,1,1,1)
        _Size ("Size", Range(0, 10)) = 1.0
        _Iteration("Iteration", Int) = 10
        _Intensity("Intensity", Range(0, 1)) = 0.1
    }
    SubShader {
        Tags { "RenderType"="Transparent" "RenderQueue"="Transparent" }
        Cull Off
        ZWrite Off

        CGPROGRAM
        #pragma surface surf Lambert alpha vertex:vert
        #include "SimplexNoise.cginc"

        struct Input {
            float3 worldPos;
            float3 localPos;
            float3 viewDir;
        };

        fixed4 _Color;
        int _Iteration;
        fixed _Intensity;
        fixed _Size;

        float3 curlnoise(float3 p) {
            const float e = 0.009765625;
            const float e2 = 2.0 * e;

            float3 dx = float3(e, 0., 0.);
            float3 dy = float3(0., e, 0.);
            float3 dz = float3(0., 0., e);

            float3 p_x0 = snoise(p - dx);
            float3 p_x1 = snoise(p + dx);
            float3 p_y0 = snoise(p - dy);
            float3 p_y1 = snoise(p + dy);
            float3 p_z0 = snoise(p - dz);
            float3 p_z1 = snoise(p + dz);

            float x = p_y1.z - p_y0.z + p_z0.y;
            float y = p_z1.x - p_z0.x + p_x0.z;
            float z = p_x1.y - p_x0.y + p_y0.x;
            return normalize(float3(x, y, z) / e2);
        }

        void vert (inout appdata_full v, out Input data) {
            UNITY_INITIALIZE_OUTPUT(Input,data);
            data.localPos = v.vertex;
            data.worldPos = mul(unity_ObjectToWorld, v.vertex);
        }

        void surf (Input IN, inout SurfaceOutput o) {
            float3 wdir = IN.worldPos - _WorldSpaceCameraPos;
            float3 ldir = normalize(mul(unity_WorldToObject, wdir));
            float3 lstep = ldir / _Iteration;
            float3 lpos = IN.localPos;
            fixed output = 0.0;

            [loop]
            for (int i = 0; i < _Iteration; ++i)
            {
                fixed a = curlnoise((lpos + 0.5) * _Size).r;
                output += (1 - output) * a * _Intensity;
                lpos += lstep;
                if (!all(max(0.5 - abs(lpos), 0.0))) break;
            }

            fixed4 c = _Color * output;

            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

参考

Unity でボリュームレンダリングをしてみる - vol.1 データ表示
Noise Shader Library for Unity
Curl Noise書いてみた

11
8
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
11
8