SlideShare a Scribd company logo
SIZIMA Soft (https://sizima.com/)
Unityとシェーダで描く360度フラクタル
2
本資料について
画像検索などで「3Dフラクタル」と検索をかけると、実に不思議な画像がたくさん見つか
ります。これらの3Dフラクタル画像の多くは「レイマーチング法」とよばれる手法によっ
て描かれています。
本資料ではこのレイマーチング法による3Dフラクタル描画をUnityを用いて行う方法を
(なるべく初心者にも分かるように)紹介します。さらにプラネタリウムのようなドーム
映像や、VR映像にも使用できる形式での描画方法も紹介していきます。
3Dフラクタルの1種であるマンデルボックス(左)と、マンデルボックスの360度画像(右)
3
目次
作ってみよう
おまけのおはなし
1:Unityでシェーダを書いてみる
2:スライダーの値をシェーダに送ってみる
3:カメラオブジェクトを動かしてみる
4:マンデルボックスシェーダを作成してみる
5:カメラの動きと連動させてみよう
6:ドームマスター表示にしてみよう
7:連番ファイルに書き出してみよう
8:発展
プラネタリウム用の映像形式であるドームマスターについて
シェーダについて
レイマーチング法について
4
作ってみよう
5
1:Unityでシェーダを書いてみる
6
1:Unityでシェーダを書いてみる
ポリゴンのUV座標によって色が変わるシェーダ
7
1:Unityでシェーダを書いてみる
1:New Scene を作成し、GameObject > 3D Object > Quad を作成
Position は (0, 0, 0) にしておく
Main Camera は Quad がよく見える位置に移動させておく
2:Material を1つ作成する → 適当な名前を付けておく
Material は以下に作成するのがお勧め
Assets > Materials
(Assets 以下ならどこでもいいけど)
8
1:Unityでシェーダを書いてみる
3:マテリアルをQuadに割り当てる
9
1:Unityでシェーダを書いてみる
4:Shader (Standard Surface Shader) を1つ作成する → 適当な名前を付けておく
5:マテリアルにシェーダを割り当てる
Shader は以下に作成するのがお勧め
Assets > Shaders
(Assets 以下ならどこでもいいけど)
6:シェーダをダブルクリックするとエディタが開くので、次ページのシェーダを書く
10
Shader “Custom/shader_uvColor(シェーダ名)" {
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 position : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata_base v) : POSITION
{
v2f o;
o.position = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord.xy;
return o;
}
fixed4 frag(v2f i) : COLOR
{
return float4(i.uv, 0.0, 1.0);
}
ENDCG
}
}
}
頂点シェーダ関数
フラグメントシェーダ関数
構造体の宣言
頂点シェーダからフラグメントシェーダに渡したい
情報を含めておく
モデル情報 → 頂点シェーダの受け渡しには
「appdate_base」構造体を使用。
→ #include “UnityCG.cginc” の記述で使用可能に
UV座標のUの値 → 赤色の強度
UV座標のVの値 → 緑色の強度
11
1:Unityでシェーダを書いてみる
うまくいくとこのように表示される ショッキングピンクに表示された場合はどこかに
エラーあり
うまくいったらシーンファイルを保存しておきましょう。
12
2:スライダの値をシェーダに送ってみる
13
2:スライダーの値をシェーダに送ってみる
スライダを動かすと色が変化する
14
2:スライダーの値をシェーダに送ってみる
1:作ってみよう1の1~5とまったく同じ作業をしてシーンの準備をしておく
2:次ページのシェーダを書く
15
Shader "Custom/shader_parameter(シェーダ名)" {
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 position : SV_POSITION;
};
float _r;
v2f vert(appdata_base v) : POSITION
{
v2f o;
o.position = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag(v2f i) : COLOR
{
return float4(_r, 0.0, 0.0, 1.0);
}
ENDCG
}
}
}
頂点シェーダ関数
フラグメントシェーダ関数
構造体の宣言
モデル情報 → 頂点シェーダの受け渡しには
「appdate_base」構造体を使用。
スライダーの値 → 赤色の強度
シェーダ内で使用する変数
変数宣言しておかないとスライダーの値を受け取れない
16
2:スライダーの値をシェーダに送ってみる
3:スライダーを作成
・GameObject > UI > Canvas を作成(uGUIのGUIはすべてCanvas上に作成される)
・GameObject > UI > Slider を作成し、適当な位置に移動させておく
Gameタブを開いておくとプレイ時の視点で表示される
インスペクタウインドウでスダイダーの “Min
Value”, “Max Value” がそれぞれ 0, 1 であること
を確認しておく
スライダーの 0-1 をシェーダの「赤」の値を
指定する変数に送る
17
2:スライダーの値をシェーダに送ってみる
4:C#スクリプトを1つ作成する → 適当な名前を付けておく
C#スクリプト は以下に作成するのがお勧め
Assets > Scripts
(Assets 以下ならどこでもいいけど)
5:次ページの C#スクリプトを記述する
18
using UnityEngine;
using UnityEngine.UI;
public class SliderValue2Shader : MonoBehaviour {
public Material _mat;
public Slider _sli_r;
public void Slider2shader()
{
_mat.SetFloat("_r", _sli_r.value);
}
}
スライダーの値をシェーダに送る関数
先ほど作成したマテリアルとスライダーを割り当てる
スライダーを動かすたびに実行される。
シェーダ側にあらかじめ
float _r;
を用意しておくと、この関数を実行するたびにシェーダ側の _r の
値が変更される。
ココの文字列は4でC#スクリプトを作成時に付けた名前にすること。
19
Material.SetFloat public void SetFloat (string propertyName, float value)
public Material _mat;
public void Float2Shader()
{
_mat.SetFloat("_aaa", 0.5f);
}
Material.SetVector public void SetVector (string propertyName, Vector4 vector);
Material.SetTexture public void SetTexture(string propertyName, Texture texture);
public Material _mat;
public void Vector2Shader()
{
_mat.SetVector("_bbb", new Vector4(0.5f, 0.9f, -0.3f, 1.0f));
}
public Material _mat;
public Texture _colorTexture;
public void Tex2Shader()
{
_mat.SetTexture("_colorTex", _colorTexture);
}
【参考】
20
2:スライダーの値をシェーダに送ってみる
6:C#スクリプトをシーンに配置する
・GameObject > Create Empty を作成 → 名前を「SceneManager」としておく
・SceneManager のインスペクタウインドウを表示 ← 先ほど作成したC#スクリプトをドラッグして割り当てる
7:C#スクリプトの変数(_mat, _sli_r)にマテリアルとスライダーを割り当てる
21
2:スライダーの値をシェーダに送ってみる
8:スライダーを動かすとスクリプトの関数が実行されるようにする
・スライダーを選択し、On Value Changed 右下にある「+」をクリック
・SceneManager をドラッグして割り当てる
・プルダウンメニュー(No Function と表示のところ)から、実行したい関数(Slider2shader())を選択する
スライダーを動かした際に実行したいスクリプ
トは「SceneManager」に割り当てられている
22
2:スライダーの値をシェーダに送ってみる
うまくいったらシーンファイルを保存しておきましょう。
スライダーを動かして赤くなれば成功
23
3:カメラオブジェクトを動かしてみる
24
3:カメラオブジェクトを動かしてみるの巻
方向キーでカメラオブジェクトをコントロール
レイマーチングので表示される球やマンデルボックスのアングルを決めるには、視点情報(位置・向き)が必要です。
そのためにカメラオブジェクトを移動させ、その位置情報や向きの情報を毎フレームシェーダに送る、ということをします。
25
3:カメラオブジェクトを動かしてみるの巻
1:カメラオブジェクトをシーンに配置する
・New Scene を作成
・GameObject > Create Empty を作成 → 座標を (0, 0, 0)、 名前を「tripod(三脚)」としておく
・tripod の子供として「GameObject > 3D Object > Cube」を作成 → 名前を「cameraModel」としておく
・Main Camera をいい感じの位置に配置
26
3:カメラオブジェクトを動かしてみるの巻
2:カメラオブジェクトをコントロールするためのスクリプトを追加
・以下のURLから「CameraController.cs」をダウンロードし、Assets > scripts フォルダに入れる
https://sizima.com/UnityScripts/WS/CameraController.cs
・tripod に Assets > scripts > CameraController を追加
27
3:カメラオブジェクトを動かしてみるの巻
カメラのコントロール方法
動作 コントロール
前進 / 後退 W / S ( ↑ / ↓ )
左回転 / 右回転 A / S ( ← / → )
上昇 / 下降 E / Q
ノーズアップ / ノーズダウン R / F
28
4:マンデルボックスシェーダを作成してみる
29
4:マンデルボックスシェーダを作成してみる
球を描く → 球に色を付ける → マンデルボックスを描
・・・という順で進めます。
30
4-1:レイマーチング法で球を描いてみる
31
4-1:レイマーチング法で球を描いてみる
1:作ってみよう1の1~5とまったく同じ作業をしてシーンの準備をしておく
2:次ページ(3ページ分)のシェーダを書く
・シェーダ内にはいくつかの関数があるが、以下の順序で書くこと(順序を変えるとエラーが出る場合あり)
距離関数(DistanceFunc)
レイ方向取得関数(GetRay)
頂点シェーダ関数(vert)
フラグメントシェーダ関数(frag)
32
Shader "Custom/shader04_1(シェーダ名)" {
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 5.0
#include "UnityCG.cginc"
#define CLOSE_ENOUGH 0.001
// シェーダ内の関数で共有したい変数はここで宣言しておく
float3 _camPos, _camAim, _camUp, _camSide; // カメラの位置、前方向ベクトル、上方向ベクトル、右方向ベクトル
struct v2f {
float4 position : SV_POSITION;
float2 uv : TEXCOORD0;
};
// 球を作る場合の距離関数
float DistanceFunc(float3 _rayPos )
{
float3 _objPos = float3(0, 0, 3); // 球の位置
float _rad = 1; // 球の半径
return length(_rayPos-_objPos) - _rad;
}
33
// 描画するピクセルの ray の方向を取得する関数
float3 GetRay(v2f i)
{
float3 ray;
float2 pix = (i.uv - float2(0.5, 0.5)) * 2; // 範囲は -1 ~ 1
float AoV = 60; // 画角何度?
AoV = radians(AoV*0.5); // ラジアンに変換
ray = normalize(_camAim + pix.x * tan(AoV) * _camSide + pix.y * tan(AoV) * _camUp);
return ray;
}
// 頂点シェーダ関数
v2f vert(appdata_base v) : POSITION
{
v2f o;
o.position = UnityObjectToClipPos(v.vertex); // モニタに表示されるよう座標変換
o.uv = v.texcoord.xy; // UV座標はそのまま受け渡す
return o;
}
_camUp
_camSide
pix.x
pix.y
1
-1
-1
1
_camAim
AoV
Camera
ray
今回の例の場合、描画領域は正方形
34
// フラグメントシェーダ関数
fixed4 frag(v2f i) : COLOR
{
_camPos = float3(0, 0, 0);
_camAim = float3(0, 0, 1);
_camUp = float3(0, 1, 0);
_camSide = float3(1, 0, 0);
fixed4 _color; // 最終的なピクセルの色となる
float3 _ray = GetRay(i); // 描画するピクセルのレイの方向ベクトル
float _distance ; // レイとオブジェクト間の最短距離
float _rayL = 0.0; // レイに継ぎ足す長さ
float3 _rayP = _camPos; // レイの先端位置
for (int i = 0; i < 50 ; ++i) {
_distance = DistanceFunc( _rayP );
_rayL += _distance;
_rayP = _camPos + _ray * _rayL ;
if (_distance < CLOSE_ENOUGH) break; // レイがオブジェクトに衝突したらループを抜ける
}
if (_distance < CLOSE_ENOUGH){
_color = fixed4(1, 0, 0, 1);
}
else
_color = fixed4(0, 0, 0, 1);
return _color;
}
ENDCG
}
}
}
レイがオブジェクトに衝突した際の処理
カメラの位置と向きを、今回は手動で指定しておく
マーチングループ(レイマーチングの繰り返し処理)
今の場合は50回、もしくはレイが衝突するまで繰り返す
そのピクセルを赤く塗りつぶす
レイがオブジェクトに衝突しなかった際の処理
35
4-2:球に陰影をつけてみる
36
4-2:球に陰影をつけてみる
1:4-1をまずやる(4-1で作成したシーンやシェーダを改良して陰影をつけるため)
2:シェーダを変更する
・オブジェクトの法線を取得する関数(GetNormal())を追加
・フラグメントシェーダの中身を少し変更する
・シェーダ内にはいくつかの関数があるが、以下の順序で書くこと(順序を変えるとエラーが出る場合あり)
距離関数(DistanceFunc)
レイ方向取得関数(GetRay)
法線取得関数(GetNormal)
頂点シェーダ関数(vert)
フラグメントシェーダ関数(frag)
37
// オブジェクト表面の法線ベクトルを取得する
float3 GetNormal(float3 p)
{
float d = 0.00005;
return normalize(float3(
DistanceFunc(p + float3( d, 0.0, 0.0)) - DistanceFunc(p + float3( -d, 0.0, 0.0)),
DistanceFunc(p + float3(0.0, d, 0.0)) - DistanceFunc(p + float3(0.0, -d, 0.0)),
DistanceFunc(p + float3(0.0, 0.0, d)) - DistanceFunc(p + float3(0.0, 0.0, -d))));
}
38
fixed4 frag(v2f i) : COLOR
{
(この部分は4-1と同じ)
if (_distance < CLOSE_ENOUGH){
// オブジェクト表面の法線を取得
float3 _normal = GetNormal(_rayP);
// _color1:カメラに対する面の向きで明るさを変える
float _v = dot(-_camAim,_normal);
float4 _color1 = float4(_v,_v,_v, 1);
// _color2:面の向きで色を変える
float4 _color2 = float4(0.5*(_normal+float3(1,1,1)), 1);
_color = _color1 * _color2;
}
else
_color = fixed4(0, 0, 0, 1);
return _color;
}
以下のように変更してみよう!
_color = _color1; もしくは _color = _color2;
39
4-3:マンデルボックス距離関数
40
4-3:マンデルボックス距離関数
1:4-1、4-2をまずやる!
2:球の距離関数をマンデルボックスの距離関数に置き換える
うまくいったらシーンファイルを保存しておきましょう。
41
// マンデルボックスを作る場合の距離関数はこれ
float DistanceFunc(float3 _rayPos )
{
float3 _objPos = float3(0, 0, 3); // マンデルボックスを表示する位置
float3 pos = _rayPos-_objPos;
float mb_scale = -1.977; // この値を変更してみると・・・!?
float minRad2 = 0.1;
float DIST_MULTIPLIER = 1.0;
float absScalePowIters = 0.0001;
float4 scale = float4( mb_scale, mb_scale, mb_scale, abs(mb_scale)) / minRad2;
float4 p = float4(pos,1.0), p0 = p;
for (int i=0; i<10; i++) // PCに余裕がある場合は 10 → 16 くらいにすると精度が上がる
{
p = float4(clamp(p.xyz, -1.0, 1.0) * 2 - p.xyz, p.w);
float r2 = dot(p.xyz, p.xyz);
p *= clamp(max(minRad2/r2, minRad2), 0.0, 1);
p = p * scale + p0;
}
return ((length(p.xyz) - abs(mb_scale - 1.0)) / p.w - absScalePowIters) * 0.95 * DIST_MULTIPLIER;
}
42
5:カメラの動きと連動させてみよう
43
5:カメラの動きと連動させてみよう
3で作成したカメラの動きを4-3で作成したシェーダに送る
44
5:カメラの動きと連動させてみよう
設計図
CameraController.cs
キーボード操作で動く
CamValue2Shader.cs
cameraModelの位置や向きを
シェーダに送る
cameraModel
tripod
マンデルボックスシェーダ
cameraModelの位置や向きを
受け取り、描画する
Main Camera
ここになにかある!
45
5:カメラの動きと連動させてみよう
1:4-1、4-2、4‐3をまずやる!
2:カメラオブジェクトをシーンに配置する(3を思い出しながら)
・GameObject > Create Empty を作成 → 座標を (0, 0, 0)、 名前を「tripod(三脚)」としておく
・tripod の子供として「GameObject > 3D Object > Cube」を作成 → 名前を「cameraModel」としておく
4:C#スクリプト( CamValue2Shader.cs)を作成し、中身(次ページ)を記述する
3:カメラオブジェクトをコントロールするためのスクリプトを追加
・以下のURLから「CameraController.cs」をダウンロードし、Assets > scripts フォルダに入れる
https://sizima.com/UnityScripts/WS/CameraController.cs
・tripod に Assets > scripts > CameraController を追加
(シーンを実行してカメラオブジェクトがキーボード操作できるか試しておきましょう)
46
using UnityEngine;
public class CamValue2Shader : MonoBehaviour
{
public Material _mat; // マテリアルを割り当てる
// カメラの位置や方向をシェーダに送る
void CamState2shader()
{
_mat.SetVector("_camPos", transform.position);
_mat.SetVector("_camSide", Vector3.Normalize(transform.right));
_mat.SetVector("_camUp", Vector3.Normalize(transform.up));
_mat.SetVector("_camAim", Vector3.Normalize(transform.forward));
}
// 毎フレーム実行される
void Update()
{
CamState2shader();
}
}
47
5:カメラの動きと連動させてみよう
6:フラグメントシェーダ関数の以下の部分を削除
5:C#スクリプトをカメラオブジェクトに割り当てる
・cameraModel に先ほど作成したC#スクリプトをドラッグして割り当てる
_camPos = float3(0, 0, 0);
_camAim = float3(0, 0, 1);
_camUp = float3(0, 1, 0);
_camSide = float3(1, 0, 0);
カメラ位置はこれまで手動で決めていたが、今回
はスクリプトで外部から操作するため
Quad に割り当てられているマテリアルを
選択しておく
48
5:カメラの動きと連動させてみよう
7:表示用のQuadがカメラオブジェクトと重ならないように適当に移動させておく
Main Camera はシーン全体が見えるように配置
シーンを実行し、カメラモデルをキーボード操作するとシェーダの表示も変化します。
うまくいったらシーンファイルを保存しておきましょう。
49
6:ドームマスター表示にしてみよう
50
6:ドームマスター表示にしてみよう
レイの方向を取得する関数を改造し、魚眼レンズにする
クォータニオンって??
51
6:ドームマスター表示にしてみよう
1:5までをやっておく。
2:シェーダ内のレイを取得する関数を改造する
・クォータニオンに関する2つの関数を記述する
・GetRay関数を書き換える
・以下の順になるように関数を書く ・なめらかな回転を実現するための手法
・今回の用途ならば、回転行列を用いた手法でもOKかも
距離関数(DistanceFunc)
クォータニオン積(GetQuaternionProduct)
クォータニオン回転(RotateCoordAroundAxis)
レイ方向取得関数(GetRay)
法線取得関数(GetNormal)
頂点シェーダ関数(vert)
フラグメントシェーダ関数(frag)
52
// クォータニオン同士の積を返す関数 ------------------------------------------------
// クォータニオン → Q = (t; x, y, z) 実部 t で虚部が x, y, z
float4 GetQuaternionProduct(float4 Ql, float4 Qr)
{
float3 vl = float3(Ql.y, Ql.z, Ql.w);
float3 vr = float3(Qr.y, Qr.z, Qr.w);
float3 crossProduct = cross(vl, vr);
float4 Qans = float4(
Ql.x * Qr.x - dot(vl, vr),
(Ql.x * vr.x) + (Qr.x * vl.x) + crossProduct.x,
(Ql.x * vr.y) + (Qr.x * vl.y) + crossProduct.y,
(Ql.x * vr.z) + (Qr.x * vl.z) + crossProduct.z
);
return Qans;
}
// クォータニオン:ある点(p)を、軸AB(a と b を通る直線)の周りに任意角度(rad)回転させる関数 ----------------
float3 RotateCoordAroundAxis(float3 p, float3 a, float3 b, float rad)
{
p = p - a; // 点を計算用にオフセットかけておく
float3 ax = normalize(b - a); // 軸の方向を示す単位ベクトル
rad *= 0.5;
// 3つのクォータニオンを作成
float4 P = float4(0, p.x, p.y, p.z);
float4 Q = float4(cos(rad), ax.x * sin(rad), ax.y * sin(rad), ax.z * sin(rad));
float4 R = float4(cos(rad), -1 * ax.x * sin(rad), -1 * ax.y * sin(rad), -1 * ax.z * sin(rad));
float4 RP = GetQuaternionProduct(R, P);
float4 RPQ = GetQuaternionProduct(RP, Q);
return float3((RPQ.y + a.x), (RPQ.z + a.y), (RPQ.w + a.z));
}
53
// 描画するピクセルのray の方向を取得する
float3 GetRay(v2f i)
{
float3 ray;
float2 pix = (i.uv - float2(0.5, 0.5)) * 2; // 範囲は -1 ~ 1
float d = length(pix); // 画面の中心からどれだけずれているか? d=0 なら中心,d=1.0 ならドームマスター端の円周上
// _camAim を _camSide の周りに t 回転
float t = radians(90 * d);
ray = RotateCoordAroundAxis(_camAim, 0, _camSide, t); // ray 回転しました
// さらにその結果を _camAim の周りに a 回転
float a = sign(pix.x)*acos(dot(float2(0, 1), normalize(pix)));
ray = RotateCoordAroundAxis(ray, 0, _camAim, a); // ray 回転しました
return ray;
}
54
6:ドームマスター表示にしてみよう
3:cameraModel を45度程度上方に傾ける
円の外も表示されちゃうが、
とりあえずよし。
55
魚眼レンズになるようにレイのベクトルを求めるには…
0
α
θ
_camAim
_camSide
_camUp
_camSide を軸に、_camAim を θ 回転 _camAim を軸に、_camAim’ を α 回転
_camSide
_camAim
_camAim’_camAim’
_camAim’’⇒レイ
θ α
56
7:連番ファイルに書き出してみよう
57
7:連番ファイルに書き出してみよう
1:Quad のみを画面に表示する
・(例えば…)Quad および Main Camera を以下のように cameraModel から離して配置
cameraModel の Mesh Render の
チェックを外し、非表示にしてもよい
cameraModel
Main Camera
Quad
・Main Camera の Projection を Orthographic にし、Size を調整
(Quad の上下が Main Camera で見た際に上下にぴったりくっつくように Size を調整)
左右に隙間があってもOK
58
7:連番ファイルに書き出してみよう
2:ビルドする
・書き出しの際、Unity のエディタ上ではエラーが出る可能性があるため、ビルドします
・File > Build Settings... を開き、Target Platform を Windows、Architecute を x86_64 に設定
・Player Settings... を開き、Fullscreen Mode をWindowedにし、Run In Background にチェック
・Build ボタンをクリックし、ビルド
59
7:連番ファイルに書き出してみよう
3:出力されたアプリケーションを起動し、レンダリングの設定画面を開く
・起動後にスペースキーを押すとレンダリングの設定画面が表示される
60
7:連番ファイルに書き出してみよう
4:レンダリングの設定 → レンダリング
・レンダリングは現在のカメラ位置から、カメラが一定方向に動きながら画像を書き出す、というもの
カーブとかは出来ません…
項目 説明
Resolution (w, h) レンダリングの解像度。縦横を同じ値にする必要がある。
Sample サンプリング数。大きくし過ぎると落ちるため、まずは 1 で試すとよい。 1 で大丈夫なら 2 か 3 に上げてみる。
Frame number 出力する画像の枚数。
Camera speed 1フレーム進むごとにカメラが移動する距離。
Direction (x, y, z) カメラの移動する方向ベクトル。入力は単位ベクトルにする必要はない。
例: (0, 0, 1) → 前進 (0, 1, 0) → 上昇 (1, 0, 0) → 右へ平行移動 (0, 1, 1) → 前進しながら上昇
File name ファイル名を指定。
Start number レンダリング開始時の番号指定。例えば File name → test 、 Start number → 100 と指定すると次のような連
番ファイルが出力される。
test_00100.png , test_00101.png , test_00102.png …
Render Button レンダリングを開始します。
Stop Button レンダリング実行時にクリックすることでレンダリングをストップします。
61
8:発展
62
8-1:ライティング
法線方向が分かるということは、ライティングが出来る
「6:ドームマスター表示にしてみよう」をベースにライティングしてみた例
・フラグメントシェーダ関数に以下のような変更を加える
63
fixed4 frag(v2f i) : COLOR
{
(この部分には変更を加えない)
if (_distance < CLOSE_ENOUGH)
{
float3 _baseColor = float3(1, 1, 1); // オブジェクトの色
float3 _lightColor = float3(1, 0.8, 0.5); // ライトのカラーを指定
float3 _lightDir = normalize(float3(0, 1, 0)); // ライト(光源)の向き
float _intensity = 1.0; // ライトの強度
float3 _ambColor = float3(0.2, 0.4, 0.8); // アンビエント光の色
float _ambIntensity = 0.3; // アンビエント光の強度
float3 _normal = GetNormal(_rayP); // オブジェクト表面の法線を取得
float _diffuse = max(0, mul(_lightDir, _normal)); // 拡散反射強度
float3 _color1 = _baseColor * _ambColor * _ambIntensity
+ _baseColor * _lightColor * _intensity * _diffuse;
_color = fixed4(_color1 , 1);
}
else
_color = fixed4(0, 0, 0, 1);
return _color;
}
_baseColor * _ambColor * _ambIntensity ⇒ アンビエント光による見え方
_baseColor * _lightColor * _intensity * _diffuse ⇒ ライトによる見え方
カラーは以下のように指定
float3(R, G, B) RGBの強度はそれぞれ 0~1
追加・変更
64
8-2:フォグ
距離関数で距離が分かる、ということはフォグを追加出来る
8-1をベースにフォグを追加してみた例
・フラグメントシェーダ関数に以下のような変更を加える
65
fixed4 frag(v2f i) : COLOR
{
(この部分には変更を加えない)
if (_distance < CLOSE_ENOUGH)
{
float3 _baseColor = float3(1, 1, 1); // オブジェクトの色
float3 _lightColor = float3(1, 0.8, 0.5); // ライトのカラーを指定
float3 _lightDir = normalize(float3(0, 1, 0)); // ライト(光源)の向き
float _intensity = 1.0; // ライトの強度
float3 _ambColor = float3(0.2, 0.4, 0.8); // アンビエント光の色
float _ambIntensity = 0.3; // アンビエント光の強度
float3 _fogColor = float3(0.05, 0.08, 0.1); // フォグの色
float _fogMax = 1.5; // フォグの濃さが最大になる距離
float3 _normal = GetNormal(_rayP); // オブジェクト表面の法線を取得
float _diffuse = max(0, mul(_lightDir, _normal)); // 拡散反射強度
float _fogValue = min(_fogMax,length(_rayP-_camPos))/_fogMax; // 1 でフォグ最大
float3 _color1 = _baseColor * _ambColor * _ambIntensity
+ _baseColor * _lightColor * _intensity * _diffuse;
_color = fixed4(lerp(_color1, _fogColor, _fogValue),1);
}
else
_color = fixed4(0, 0, 0, 1);
return _color;
}
Lerp(x, y, s) = (1-s)x + sy
66
8-3:白熱光
マグマがオレンジに発光するような効果
8-2をベースに白熱光を追加してみた例
・フラグメントシェーダ関数に以下のような変更を加える
67
fixed4 frag(v2f i) : COLOR
{
(この部分には変更を加えない)
if (_distance < CLOSE_ENOUGH)
{
float3 _baseColor = float3(1, 1, 1); // オブジェクトの色
float3 _lightColor = float3(1, 0.8, 0.5); // ライトのカラーを指定
float3 _lightDir = normalize(float3(0, 1, 0)); // ライト(光源)の向き
float _intensity = 1.0; // ライトの強度
float3 _ambColor = float3(0.2, 0.4, 0.8); // アンビエント光の色
float _ambIntensity = 0.3; // アンビエント光の強度
float3 _fogColor = float3(0.05, 0.08, 0.1); // フォグの色
float _fogMax = 1.5; // フォグの濃さが最大になる距離
float3 _incandescenceColor = float3(0.4,1,0.8); // 白熱光の色
float3 _incCenter = float3(0,0,1.5); // 白熱光の位置
float _incRadius = 0.8; // 白熱光の半径
float _incIntensity = 1.5; // 白熱光の強度
float3 _normal = GetNormal(_rayP); // オブジェクト表面の法線を取得
float _diffuse = max(0, mul(_lightDir, _normal)); // 拡散反射強度
float _fogValue = min(_fogMax,length(_rayP-_camPos))/_fogMax; // 1 でフォグ最大
float3 _color1 = _baseColor * _ambColor * _ambIntensity + _baseColor * _lightColor * _intensity * _diffuse;
float3 _color2 = pow(max((1-length(_incCenter - _rayP)/_incRadius), 0),2) * _incandescenceColor * _incIntensity;
_color = fixed4(lerp(_color1, _fogColor, _fogValue) + _color2, 1);
}
else
_color = fixed4(0, 0, 0, 1);
return _color;
}
68
8-4:明るさ調整・ガンマ補正
ちょっとした色調補正機能を入れておくと便利
8-3をベースに明るさ調整・ガンマ補正してみた例
・フラグメントシェーダ関数に以下のような変更を加える
69
fixed4 frag(v2f i) : COLOR
{
(この部分には変更を加えない)
if (_distance < CLOSE_ENOUGH)
{
float3 _baseColor = float3(1, 1, 1); // オブジェクトの色
float3 _lightColor = float3(1, 0.8, 0.5); // ライトのカラーを指定
float3 _lightDir = normalize(float3(0, 1, 0)); // ライト(光源)の向き
float _intensity = 1.0; // ライトの強度
float3 _ambColor = float3(0.2, 0.4, 0.8); // アンビエント光の色
float _ambIntensity = 0.3; // アンビエント光の強度
float3 _fogColor = float3(0.05, 0.08, 0.1); // フォグの色
float _fogMax = 1.5; // フォグの濃さが最大になる距離
float3 _incandescenceColor = float3(0.4,1,0.8); // 白熱光の色
float3 _incCenter = float3(0,0,1.5); // 白熱光の位置
float _incRadius = 0.8; // 白熱光の半径
float _incIntensity = 1.5; // 白熱光の強度
float3 _normal = GetNormal(_rayP); // オブジェクト表面の法線を取得
float _diffuse = max(0, mul(_lightDir, _normal)); // 拡散反射強度
float _fogValue = min(_fogMax,length(_rayP-_camPos))/_fogMax; // 1 でフォグ最大
float3 _color1 = _baseColor * _ambColor * _ambIntensity + _baseColor * _lightColor * _intensity * _diffuse;
float3 _color2 = pow(max((1-length(_incCenter - _rayP)/_incRadius), 0),2) * _incandescenceColor * _incIntensity;
float3 _color3 = lerp(_color1, _fogColor, _fogValue) + _color2;
float _gamma = 0.7; // ガンマの値
float _brightness = 2; // 明るさ
_color = fixed4(pow(_color3, 1.0/_gamma) * _brightness, 1);
}
else
_color = fixed4(0, 0, 0, 1);
return _color;
}
70
8-5:エクイレクタングラー表示
レイの方向を制御してあげれば様々な形式での表示が可能
8-4をベースにエクイレクタングラー表示にしてみた例
1:シェーダ内のレイを取得する関数(GetRay関数)を次のように変更
71
// 描画するピクセルのray の方向を取得する
float3 GetRay(v2f i)
{
float3 ray;
float2 pix = (i.uv - float2(0.5, 0.5)) * 2; // 範囲は -1 ~ 1
float PI = radians(180); // π(3.1415...)
float _lon = pix.x * -PI; // その画素が横方向何度(ラジアン)か?
float _lat = pix.y * 0.5 * PI; // その画素が高さ方向何度(ラジアン)か?
// _camAim を _camSide の周りに _lat 回転
ray = RotateCoordAroundAxis(_camAim, 0, _camSide, _lat); // ray 回転しました
// さらにその結果を _camUp の周りに _lon 回転
ray = RotateCoordAroundAxis(ray, 0, _camUp, _lon); // ray 回転しました
return ray;
}
72
8-5:エクイレクタングラー表示
2:表示用の板(Quad)を横方向に2倍にして縦横比を1:2にしておく
(Quad の上下が Main Camera で見た際に上下にぴったりくっつくように調整)
左右に隙間があってもOK
3:tripod > cameraModel が正面を向いてない場合は正面を向けておく
73
8-6:様々なパラメータの変更
ほかにもあるかも…
描画の精度を上げたい マーチングループ回数を上げてみる
例: for (int i=0; i<50; i++) ⇒ for (int i=0; i<200; i++)
※上げすぎるとPCが固まるので注意
マンデルボックス距離関数内のループ回数を上げてみる
例: for (int i=0; i<10; i++) ⇒ for (int i=0; i<16; i++)
※上げすぎるとPCが固まるので注意
#define CLOSE_ENOUGH 0.001
の値を変更してみる
マンデルボックスを変形したい マンデルボックス距離関数の以下の値を変更してみる
float mb_scale = -1.977;
この値を変更すると劇的に見た目が変更されます。2を参考にスライダーで
値を変更できるようにしてみましょう!
74
8-7:メンガーのスポンジ
距離関数を変えるといろいろな表示が可能
メンガーのスポンジ
8-5をベースに距離関数だけ変更した例
・距離関数に以下のような変更を加える
75
float box(float3 p, float3 b){
float3 d = abs(p) - b;
return min(max(d.x, max(d.y, d.z)), 0.0) + length(max(d, 0.0));
}
float bar(float2 p, float2 b){
float2 d = abs(p) - b;
return min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
}
float crossBar(float3 p, float b){
return min(bar(p.xy, b), min(bar(p.yz, b), bar(p.zx, b)));
}
float mod(float x, float y){
return (x - (y * floor(x / y)));
}
float DistanceFunc(float3 _rayPos)
{
float3 _objPos = float3(0, 0, 0); // 表示する位置
float3 p = _rayPos - _objPos;
p.x = mod(p.x + 0.4, 0.8) - 0.4;
p.y = mod(p.y + 0.4, 0.8) - 0.4;
p.z = mod(p.z + 0.4, 0.8) - 0.4;
float _fat = 0.3; // 値を変更してみよう
float ret = box(p, float3(_fat, _fat, _fat));
float _dist = 3; // 値を変更してみよう
for (float c = 0.0; c < 3; c += 1)
{
float pw = pow(_dist, c);
float3 _modAns = float3(mod(p.x + 0.15 / pw, 0.6 / pw), mod(p.y + 0.15 / pw, 0.6 / pw), mod(p.z + 0.15 / pw, 0.6 / pw));
ret = max(ret, -crossBar(_modAns - 0.15 / pw, 0.1 / pw));
}
return ret;
}
76
参考
GLSL ⇒ HLSL 命令対応表
http://dench.flatlib.jp/opengl/glsl_hlsl
HLSL 組み込み関数
https://msdn.microsoft.com/ja-jp/library/bb509611(v=vs.85).aspx
Shadertoy
https://www.shadertoy.com/
SIZIMA Soft
http://sizima.com/
77
おまけのおはなし
78
プラネタリウム用の映像形式であるドームマスターについて
79
ドームマスターについて
ドームに投影するための形式には以下のものがある
ドームマスター / キューブマップ / エクイレクタングラー
80
ドームマスターについて
ドームマスター
画角180度の円周魚眼レンズで撮影
空間の半分が記録されている
81
ドームマスターについて
撮影時のカメラの向き
82
ドームマスターについて
ドームマスターの解像度
83
ドームマスターについて
画角90度、縦横比が1:1のカメラ6台で撮影。 空間の全体が記録される
キューブマップ
84
ドームマスターについて
エクイレクタングラー
360度動画(ドームスクリーン向けを含む)を作成する場合、この形式がおすすめ!
RICOH THETA で撮影すると、この形式で保存される。 空間の全体が記録される
85
ドームマスターについて
http://sizima.com/EQTANT.html
それぞれの形式は互いに変換が可能
フリーの変換ソフトとしては「EQTANT」などがある
86
シェーダについて
87
シェーダについて
シェーダ? マテリアル??
アルミホイルのような
質感を作りたい!
マテリアルを1つ用意
マテリアルから
“金属”の描画が得
意なシェーダを選択
シェーダが描画のた
めに必要とする素材
(テクスチャなど)をマ
テリアル(もしくはスク
リプト)から割当て
・実際に描画するのがシェーダ
・シェーダが描画するのに必要な素材・パラメータを指定するのがマテリアル
・画面上に絵を描く ・GPU上で動作するプログラムシェーダとは… →
88
シェーダについて
Unityで使用するシェーダは2種類!(本当はもっとあるけど…)
頂点シェーダ(Vertex Shader)
フラグメントシェーダ(Fragment Shader)
頂点シェーダ フラグメントシェーダ
描画の流れ
89
シェーダについて
頂点シェーダ(Vertex Shader)
3D空間内のオブジェクト(頂点の集合)が、モニタのどの位置に表示されるか?
3D空間に配置されたオブジェクト カメラ視点で見たオブジェクト
・座標変換
・頂点が持つ情報の処理
90
シェーダについて
フラグメントシェーダ(Fragment Shader)
モニタの各ピクセルの色は何色になる?
(テクスチャ、光源、法線情報などから決定)
モニタに投影されたオブジェクト モニタの各ピクセルの色を決める
・色塗り
91
シェーダについて
私は以下の書籍などで勉強しました…
Unity5 実践シェーダプログラミング入門 (¥1,080)
勉強のポイント
サーフェスシェーダは勉強しない
頂点・フラグメントシェーダを猛勉強!
92
レイマーチング法について
93
レイマーチング法について
レイマーチング法とは…
・レイトレーシング法の1種
・カメラから飛ばしたレイが被写体に衝突する? → 衝突したら画面の色を塗る
94
レイマーチング法について
衝突判定をどのように行うか
・距離関数 → 空間内のある点から被写体までの最短距離を得られる関数
95
レイマーチング法について
衝突判定…??
・距離関数 → 空間内のある点から被写体までの最短距離を得られる関数
96
レイマーチング法について
衝突判定…??
・距離関数 → 空間内のある点から被写体までの最短距離を得られる関数
97
レイマーチング法について
衝突判定…??
・距離関数 → 空間内のある点から被写体までの最短距離を得られる関数
98
レイマーチング法について
衝突判定…??
・距離関数 → 空間内のある点から被写体までの最短距離を得られる関数
99
レイマーチング法について
衝突判定…??
・距離関数 → 空間内のある点から被写体までの最短距離を得られる関数
100
レイマーチング法について
衝突判定…??
・距離関数 → 空間内のある点から被写体までの最短距離を得られる関数
101
レイマーチング法について
衝突判定…??
・距離関数 → 空間内のある点から被写体までの最短距離を得られる関数
102
レイマーチング法について
衝突判定…??
・距離関数 → 空間内のある点から被写体までの最短距離を得られる関数
103
レイマーチング法について
衝突判定…??
・距離関数 → 空間内のある点から被写体までの最短距離を得られる関数
104
レイマーチング法について
衝突判定…??
・距離関数 → 空間内のある点から被写体までの最短距離を得られる関数
105
レイマーチング法について
衝突判定…??
・距離関数 → 空間内のある点から被写体までの最短距離を得られる関数
106
レイマーチング法について
衝突判定…??
・距離関数 → 空間内のある点から被写体までの最短距離を得られる関数
107
レイマーチング法について
衝突判定…??
・距離関数 → 空間内のある点から被写体までの最短距離を得られる関数
108
レイマーチング法について
距離関数 → シーンを決定
レイマーチング法でどんなシーンが描けるか?
https://www.shadertoy.com/
→ Shadertoy で raymarching を検索してみるとたくさん出てくる

More Related Content

What's hot

【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術
【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術
【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術
Unity Technologies Japan K.K.
 
シェーダだけで世界を創る!three.jsによるレイマーチング
シェーダだけで世界を創る!three.jsによるレイマーチングシェーダだけで世界を創る!three.jsによるレイマーチング
シェーダだけで世界を創る!three.jsによるレイマーチング
Sho Hosoda
 
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
UnityTechnologiesJapan002
 
Unity dojo amplifyshadereditor101_jpn-jp
Unity dojo amplifyshadereditor101_jpn-jpUnity dojo amplifyshadereditor101_jpn-jp
Unity dojo amplifyshadereditor101_jpn-jp
小林 信行
 
Unity道場11 Shader Forge 101 ~ShaderForgeをつかって学ぶシェーダー入門~ 基本操作とよく使われるノード編
Unity道場11 Shader Forge 101 ~ShaderForgeをつかって学ぶシェーダー入門~ 基本操作とよく使われるノード編Unity道場11 Shader Forge 101 ~ShaderForgeをつかって学ぶシェーダー入門~ 基本操作とよく使われるノード編
Unity道場11 Shader Forge 101 ~ShaderForgeをつかって学ぶシェーダー入門~ 基本操作とよく使われるノード編
小林 信行
 
Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介
torisoup
 
【Unity道場】AssetGraph入門 〜ノードを駆使しててUnityの面倒な手作業を自動化する方法〜
【Unity道場】AssetGraph入門 〜ノードを駆使しててUnityの面倒な手作業を自動化する方法〜【Unity道場】AssetGraph入門 〜ノードを駆使しててUnityの面倒な手作業を自動化する方法〜
【Unity道場】AssetGraph入門 〜ノードを駆使しててUnityの面倒な手作業を自動化する方法〜
Unity Technologies Japan K.K.
 
UniTask入門
UniTask入門UniTask入門
UniTask入門
torisoup
 
モバイルアプリにおけるアーティストフレンドリーな水面表現戦略
モバイルアプリにおけるアーティストフレンドリーな水面表現戦略モバイルアプリにおけるアーティストフレンドリーな水面表現戦略
モバイルアプリにおけるアーティストフレンドリーな水面表現戦略
Haruki Yano
 
60fpsアクションを実現する秘訣を伝授 解析編
60fpsアクションを実現する秘訣を伝授 解析編60fpsアクションを実現する秘訣を伝授 解析編
60fpsアクションを実現する秘訣を伝授 解析編
エピック・ゲームズ・ジャパン Epic Games Japan
 
猫でも分かるUE4のポストプロセスを使った演出・絵作り
猫でも分かるUE4のポストプロセスを使った演出・絵作り猫でも分かるUE4のポストプロセスを使った演出・絵作り
猫でも分かるUE4のポストプロセスを使った演出・絵作り
エピック・ゲームズ・ジャパン Epic Games Japan
 
シェーダーを活用した3Dライブ演出のアップデート ~『ラブライブ!スクールアイドルフェスティバル ALL STARS』(スクスタ)の開発事例~​
シェーダーを活用した3Dライブ演出のアップデート ~『ラブライブ!スクールアイドルフェスティバル ALL STARS』(スクスタ)の開発事例~​シェーダーを活用した3Dライブ演出のアップデート ~『ラブライブ!スクールアイドルフェスティバル ALL STARS』(スクスタ)の開発事例~​
シェーダーを活用した3Dライブ演出のアップデート ~『ラブライブ!スクールアイドルフェスティバル ALL STARS』(スクスタ)の開発事例~​
KLab Inc. / Tech
 
CEDEC2015「加算合成コストが0になる!?すぐに使えるP-MAPブレンドテクニック」発表スライド
CEDEC2015「加算合成コストが0になる!?すぐに使えるP-MAPブレンドテクニック」発表スライドCEDEC2015「加算合成コストが0になる!?すぐに使えるP-MAPブレンドテクニック」発表スライド
CEDEC2015「加算合成コストが0になる!?すぐに使えるP-MAPブレンドテクニック」発表スライド
Toshiyasu Miyabe
 
【Unity】 Behavior TreeでAIを作る
 【Unity】 Behavior TreeでAIを作る 【Unity】 Behavior TreeでAIを作る
【Unity】 Behavior TreeでAIを作る
torisoup
 
若輩エンジニアから見たUniRxを利用したゲーム開発
若輩エンジニアから見たUniRxを利用したゲーム開発若輩エンジニアから見たUniRxを利用したゲーム開発
若輩エンジニアから見たUniRxを利用したゲーム開発
Hirohito Morinaga
 
【Unity道場スペシャル 2017博多】クォータニオン完全マスター
【Unity道場スペシャル 2017博多】クォータニオン完全マスター【Unity道場スペシャル 2017博多】クォータニオン完全マスター
【Unity道場スペシャル 2017博多】クォータニオン完全マスター
Unity Technologies Japan K.K.
 
中級グラフィックス入門~シャドウマッピング総まとめ~
中級グラフィックス入門~シャドウマッピング総まとめ~中級グラフィックス入門~シャドウマッピング総まとめ~
中級グラフィックス入門~シャドウマッピング総まとめ~
ProjectAsura
 
「スプラトゥーン」リアルタイム画像解析ツール 「IkaLog」の裏側
「スプラトゥーン」リアルタイム画像解析ツール 「IkaLog」の裏側「スプラトゥーン」リアルタイム画像解析ツール 「IkaLog」の裏側
「スプラトゥーン」リアルタイム画像解析ツール 「IkaLog」の裏側
Takeshi HASEGAWA
 
UE4の色について v1.1
 UE4の色について v1.1 UE4の色について v1.1
大規模タイトルにおけるエフェクトマテリアル運用 (SQEX大阪: 林武尊様) #UE4DD
大規模タイトルにおけるエフェクトマテリアル運用 (SQEX大阪: 林武尊様) #UE4DD大規模タイトルにおけるエフェクトマテリアル運用 (SQEX大阪: 林武尊様) #UE4DD
大規模タイトルにおけるエフェクトマテリアル運用 (SQEX大阪: 林武尊様) #UE4DD
エピック・ゲームズ・ジャパン Epic Games Japan
 

What's hot (20)

【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術
【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術
【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術
 
シェーダだけで世界を創る!three.jsによるレイマーチング
シェーダだけで世界を創る!three.jsによるレイマーチングシェーダだけで世界を創る!three.jsによるレイマーチング
シェーダだけで世界を創る!three.jsによるレイマーチング
 
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
 
Unity dojo amplifyshadereditor101_jpn-jp
Unity dojo amplifyshadereditor101_jpn-jpUnity dojo amplifyshadereditor101_jpn-jp
Unity dojo amplifyshadereditor101_jpn-jp
 
Unity道場11 Shader Forge 101 ~ShaderForgeをつかって学ぶシェーダー入門~ 基本操作とよく使われるノード編
Unity道場11 Shader Forge 101 ~ShaderForgeをつかって学ぶシェーダー入門~ 基本操作とよく使われるノード編Unity道場11 Shader Forge 101 ~ShaderForgeをつかって学ぶシェーダー入門~ 基本操作とよく使われるノード編
Unity道場11 Shader Forge 101 ~ShaderForgeをつかって学ぶシェーダー入門~ 基本操作とよく使われるノード編
 
Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介
 
【Unity道場】AssetGraph入門 〜ノードを駆使しててUnityの面倒な手作業を自動化する方法〜
【Unity道場】AssetGraph入門 〜ノードを駆使しててUnityの面倒な手作業を自動化する方法〜【Unity道場】AssetGraph入門 〜ノードを駆使しててUnityの面倒な手作業を自動化する方法〜
【Unity道場】AssetGraph入門 〜ノードを駆使しててUnityの面倒な手作業を自動化する方法〜
 
UniTask入門
UniTask入門UniTask入門
UniTask入門
 
モバイルアプリにおけるアーティストフレンドリーな水面表現戦略
モバイルアプリにおけるアーティストフレンドリーな水面表現戦略モバイルアプリにおけるアーティストフレンドリーな水面表現戦略
モバイルアプリにおけるアーティストフレンドリーな水面表現戦略
 
60fpsアクションを実現する秘訣を伝授 解析編
60fpsアクションを実現する秘訣を伝授 解析編60fpsアクションを実現する秘訣を伝授 解析編
60fpsアクションを実現する秘訣を伝授 解析編
 
猫でも分かるUE4のポストプロセスを使った演出・絵作り
猫でも分かるUE4のポストプロセスを使った演出・絵作り猫でも分かるUE4のポストプロセスを使った演出・絵作り
猫でも分かるUE4のポストプロセスを使った演出・絵作り
 
シェーダーを活用した3Dライブ演出のアップデート ~『ラブライブ!スクールアイドルフェスティバル ALL STARS』(スクスタ)の開発事例~​
シェーダーを活用した3Dライブ演出のアップデート ~『ラブライブ!スクールアイドルフェスティバル ALL STARS』(スクスタ)の開発事例~​シェーダーを活用した3Dライブ演出のアップデート ~『ラブライブ!スクールアイドルフェスティバル ALL STARS』(スクスタ)の開発事例~​
シェーダーを活用した3Dライブ演出のアップデート ~『ラブライブ!スクールアイドルフェスティバル ALL STARS』(スクスタ)の開発事例~​
 
CEDEC2015「加算合成コストが0になる!?すぐに使えるP-MAPブレンドテクニック」発表スライド
CEDEC2015「加算合成コストが0になる!?すぐに使えるP-MAPブレンドテクニック」発表スライドCEDEC2015「加算合成コストが0になる!?すぐに使えるP-MAPブレンドテクニック」発表スライド
CEDEC2015「加算合成コストが0になる!?すぐに使えるP-MAPブレンドテクニック」発表スライド
 
【Unity】 Behavior TreeでAIを作る
 【Unity】 Behavior TreeでAIを作る 【Unity】 Behavior TreeでAIを作る
【Unity】 Behavior TreeでAIを作る
 
若輩エンジニアから見たUniRxを利用したゲーム開発
若輩エンジニアから見たUniRxを利用したゲーム開発若輩エンジニアから見たUniRxを利用したゲーム開発
若輩エンジニアから見たUniRxを利用したゲーム開発
 
【Unity道場スペシャル 2017博多】クォータニオン完全マスター
【Unity道場スペシャル 2017博多】クォータニオン完全マスター【Unity道場スペシャル 2017博多】クォータニオン完全マスター
【Unity道場スペシャル 2017博多】クォータニオン完全マスター
 
中級グラフィックス入門~シャドウマッピング総まとめ~
中級グラフィックス入門~シャドウマッピング総まとめ~中級グラフィックス入門~シャドウマッピング総まとめ~
中級グラフィックス入門~シャドウマッピング総まとめ~
 
「スプラトゥーン」リアルタイム画像解析ツール 「IkaLog」の裏側
「スプラトゥーン」リアルタイム画像解析ツール 「IkaLog」の裏側「スプラトゥーン」リアルタイム画像解析ツール 「IkaLog」の裏側
「スプラトゥーン」リアルタイム画像解析ツール 「IkaLog」の裏側
 
UE4の色について v1.1
 UE4の色について v1.1 UE4の色について v1.1
UE4の色について v1.1
 
大規模タイトルにおけるエフェクトマテリアル運用 (SQEX大阪: 林武尊様) #UE4DD
大規模タイトルにおけるエフェクトマテリアル運用 (SQEX大阪: 林武尊様) #UE4DD大規模タイトルにおけるエフェクトマテリアル運用 (SQEX大阪: 林武尊様) #UE4DD
大規模タイトルにおけるエフェクトマテリアル運用 (SQEX大阪: 林武尊様) #UE4DD
 

Similar to Unityとシェーダで描く360度フラクタル

Flashup13 Basic Training of Flare3D
Flashup13 Basic Training of Flare3DFlashup13 Basic Training of Flare3D
Flashup13 Basic Training of Flare3D
Katsushi Suzuki
 
Flashup 12 Basic Training of Away3D
Flashup 12 Basic Training of Away3DFlashup 12 Basic Training of Away3D
Flashup 12 Basic Training of Away3D
Katsushi Suzuki
 
TAと歩くGDC2013報告会資料
TAと歩くGDC2013報告会資料TAと歩くGDC2013報告会資料
TAと歩くGDC2013報告会資料
fumoto kazuhiro
 
Html canvas shooting_and_performanceup
Html canvas shooting_and_performanceupHtml canvas shooting_and_performanceup
Html canvas shooting_and_performanceupYohei Munesada
 
Unityで Photonを使ってリアルタイム・マルチプレイヤーゲームを作っちゃおう【応用編】
Unityで Photonを使ってリアルタイム・マルチプレイヤーゲームを作っちゃおう【応用編】Unityで Photonを使ってリアルタイム・マルチプレイヤーゲームを作っちゃおう【応用編】
Unityで Photonを使ってリアルタイム・マルチプレイヤーゲームを作っちゃおう【応用編】GMO GlobalSign Holdings K.K.
 
Unityクリエイターズ勉強会【2/2】【関西】発表資料
Unityクリエイターズ勉強会【2/2】【関西】発表資料Unityクリエイターズ勉強会【2/2】【関西】発表資料
Unityクリエイターズ勉強会【2/2】【関西】発表資料
Masataka Motokurumada
 
3次元図形をSchemeで造ろう!
3次元図形をSchemeで造ろう!3次元図形をSchemeで造ろう!
3次元図形をSchemeで造ろう!
vi-iv
 
3DCG(3Dコンピュータグラフィック)をWebGLで始めよう
3DCG(3Dコンピュータグラフィック)をWebGLで始めよう3DCG(3Dコンピュータグラフィック)をWebGLで始めよう
3DCG(3Dコンピュータグラフィック)をWebGLで始めようAdvancedTechNight
 
1. モデリング 3 dcg制作の流れ _ 基礎知識 _ blender入門(2
1. モデリング   3 dcg制作の流れ _ 基礎知識 _ blender入門(21. モデリング   3 dcg制作の流れ _ 基礎知識 _ blender入門(2
1. モデリング 3 dcg制作の流れ _ 基礎知識 _ blender入門(2Sasaki Minoru
 

Similar to Unityとシェーダで描く360度フラクタル (9)

Flashup13 Basic Training of Flare3D
Flashup13 Basic Training of Flare3DFlashup13 Basic Training of Flare3D
Flashup13 Basic Training of Flare3D
 
Flashup 12 Basic Training of Away3D
Flashup 12 Basic Training of Away3DFlashup 12 Basic Training of Away3D
Flashup 12 Basic Training of Away3D
 
TAと歩くGDC2013報告会資料
TAと歩くGDC2013報告会資料TAと歩くGDC2013報告会資料
TAと歩くGDC2013報告会資料
 
Html canvas shooting_and_performanceup
Html canvas shooting_and_performanceupHtml canvas shooting_and_performanceup
Html canvas shooting_and_performanceup
 
Unityで Photonを使ってリアルタイム・マルチプレイヤーゲームを作っちゃおう【応用編】
Unityで Photonを使ってリアルタイム・マルチプレイヤーゲームを作っちゃおう【応用編】Unityで Photonを使ってリアルタイム・マルチプレイヤーゲームを作っちゃおう【応用編】
Unityで Photonを使ってリアルタイム・マルチプレイヤーゲームを作っちゃおう【応用編】
 
Unityクリエイターズ勉強会【2/2】【関西】発表資料
Unityクリエイターズ勉強会【2/2】【関西】発表資料Unityクリエイターズ勉強会【2/2】【関西】発表資料
Unityクリエイターズ勉強会【2/2】【関西】発表資料
 
3次元図形をSchemeで造ろう!
3次元図形をSchemeで造ろう!3次元図形をSchemeで造ろう!
3次元図形をSchemeで造ろう!
 
3DCG(3Dコンピュータグラフィック)をWebGLで始めよう
3DCG(3Dコンピュータグラフィック)をWebGLで始めよう3DCG(3Dコンピュータグラフィック)をWebGLで始めよう
3DCG(3Dコンピュータグラフィック)をWebGLで始めよう
 
1. モデリング 3 dcg制作の流れ _ 基礎知識 _ blender入門(2
1. モデリング   3 dcg制作の流れ _ 基礎知識 _ blender入門(21. モデリング   3 dcg制作の流れ _ 基礎知識 _ blender入門(2
1. モデリング 3 dcg制作の流れ _ 基礎知識 _ blender入門(2
 

Recently uploaded

LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアルLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
CRI Japan, Inc.
 
This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.
chiefujita1
 
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
t m
 
論文紹介:Deep Learning-Based Human Pose Estimation: A Survey
論文紹介:Deep Learning-Based Human Pose Estimation: A Survey論文紹介:Deep Learning-Based Human Pose Estimation: A Survey
論文紹介:Deep Learning-Based Human Pose Estimation: A Survey
Toru Tamaki
 
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさJSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
0207sukipio
 
Generating Automatic Feedback on UI Mockups with Large Language Models
Generating Automatic Feedback on UI Mockups with Large Language ModelsGenerating Automatic Feedback on UI Mockups with Large Language Models
Generating Automatic Feedback on UI Mockups with Large Language Models
harmonylab
 
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
Matsushita Laboratory
 
キンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援します
キンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援しますキンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援します
キンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援します
Takayuki Nakayama
 
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
Toru Tamaki
 

Recently uploaded (9)

LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアルLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
 
This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.
 
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
 
論文紹介:Deep Learning-Based Human Pose Estimation: A Survey
論文紹介:Deep Learning-Based Human Pose Estimation: A Survey論文紹介:Deep Learning-Based Human Pose Estimation: A Survey
論文紹介:Deep Learning-Based Human Pose Estimation: A Survey
 
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさJSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
 
Generating Automatic Feedback on UI Mockups with Large Language Models
Generating Automatic Feedback on UI Mockups with Large Language ModelsGenerating Automatic Feedback on UI Mockups with Large Language Models
Generating Automatic Feedback on UI Mockups with Large Language Models
 
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
 
キンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援します
キンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援しますキンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援します
キンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援します
 
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
 

Unityとシェーダで描く360度フラクタル