LoginSignup
2
3

More than 5 years have passed since last update.

GLSL,ShaderLab 一対一対応の演習「星空」編

Posted at

最終的にはshaderlabに移植していきたいです.
skyboxのシェーダーの書き方の勉強のために書いています.(問形式なのは個人的にそのほうが理解しやすかったからです.)

問,2Dで星空(星のみでよい,配置は星表にしたがわなくてよい)を出力せよ.

まず,ノイズ関数の作り方を考える.
https://thebookofshaders.com/10/?lan=jp
thebookofshadersには,ノイズの作り方に関していろいろ書いてあったので,全面的に参考にしました.

https://www.shadertoy.com/view/lsXGWH
また,2Dの星のノイズを使った関数に関しては,上記のshadertoyのコードを改変することによって,コードを書こうと思います.星は基本的にノイズを使って配置していきます.


#ifdef GL_ES
precision mediump float;
#endif

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

 //random関数と,noise関数はthebookofshadersのものを使用.
float random (in vec2 st) {
    return fract(sin(dot(st.xy,
                         vec2(11.9898,78.233)))
                 * 43758.5453123);
}


float noise (in vec2 st) {
    vec2 i = floor(st);
    vec2 f = fract(st);

    // Four corners in 2D of a tile
    float a = random(i);
    float b = random(i + vec2(1.0, 0.0));
    float c = random(i + vec2(0.0, 1.0));
    float d = random(i + vec2(1.0, 1.0));

    // Smooth Interpolation

    // Cubic Hermine Curve.  Same as SmoothStep()
    vec2 u = f*f*(3.0-2.0*f);
    // u = smoothstep(0.,1.,f);

    // Mix 4 coorners percentages
    return mix(a, b, u.x) +
            (c - a)* u.y * (1.0 - u.x) +
            (d - b) * u.x * u.y;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
float time = iTime;
    vec2 position = (fragCoord.xy * 2. - resolution.xy) / resolution.yy;

    float color = pow(noise(fragCoord.xy), 40.0) * 1000.0;

    float r1 = noise(fragCoord.xy*noise(vec2(1.)));


    fragColor = vec4(vec3(color*r1), 1.0);

}

スクリーンショット 2018-12-23 14.29.44.png

別解)最短コード
https://www.shadertoy.com/view/4lSSRw

問,shaderlabにて,skyboxで星空を出力せよ.

移植しつつ,Unityのskyboxに表示する方法を考えていきます.


Shader "Unlit/skyboxstars01"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

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

            struct v2f
            {
                float3 uv : TEXCOORD0;
                //UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
                float4 vertex2: TEXCOORD1;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                //o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                //UNITY_TRANSFER_FOG(o,o.vertex);
                o.uv = v.uv;
                o.vertex2 = v.vertex;
                return o;
            }



 //random関数と,noise関数はthebookofshadersのものを使用.
float random (in float2 st) {
    return frac(sin(dot(st.xy,
                         float2(11.9898,78.233)))
                 * 43758.5453123);
}


float noise (in float2 st) {
    float2 i = floor(st);
    float2 f = frac(st);

    // Four corners in 2D of a tile
    float a = random(i);
    float b = random(i + float2(1.0, 0.0));
    float c = random(i + float2(0.0, 1.0));
    float d = random(i + float2(1.0, 1.0));

    // Smooth Interpolation

    // Cubic Hermine Curve.  Same as SmoothStep()
    float2 u = f*f*(3.0-2.0*f);
    // u = smoothstep(0.,1.,f);

    // lerp 4 coorners percentages
    return lerp(a, b, u.x) +
            (c - a)* u.y * (1.0 - u.x) +
            (d - b) * u.x * u.y;
}

float2 random2 ( in float3 uv){
return float2(frac(sin(dot(uv.xyz,float3(21,31,45)))*7315),frac(cos(dot(uv.xyz, float3(43,29,53)))*6325));
}



            fixed4 frag (v2f i) : SV_Target
            {
            float4 fragColor;
            float time = _Time.y;
          //  float3 vec = normalize(i.vertex2);

          float3 pos = i.uv;
          float3 rot =float3(atan2(pos.x, pos.z), atan2(pos.y, length(pos.xz)), length(pos));
          float2 st = random2(rot);
  //  float2 position = i.uv.xyz *2. -float3(1,1,1);

    float color = pow(noise(st), 40.0) * 8.0;

    float r1 = noise(st*noise(float2(1.,1.)));


    fragColor = float4(float3(color*r1,color*r1,color * r1), 1.0);

        //fragColor = float4(vec.x,0,0,1);
                return fragColor;
            }
            ENDCG
        }
    }
}

スクリーンショット 2018-12-23 16.24.04.png

(球座標変換して,それに対応するノイズかければうまくいくのかな,ってアイディアをもとにskyboxのシェーダーに移植していきましたが,コードにいろいろいらない部分も含んでいます.)
ランダムにする関数の定数は基本適当に入力しています.もっとうまく描く方法は全然あると思います.

参考にしたもの
http://wordpress.notargs.com/blog/blog/2015/11/08/unity自作のskyboxでジュリア集合に囲まれる/
https://qiita.com/aa_debdeb/items/2739745b3ab1a003d767

2
3
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
2
3