How To create realistic looking Trees in Blender
Blenderで木を作るチュートリアルを試す(1)- 木の形を作る
Blenderで木を作るチュートリアルを試す(2)- 葉を作り枝に生やす
Blenderで木を作るチュートリアルを試す(3)- 主幹に枝を生やす
Blenderで木を作るチュートリアルを試す(4)- 幹をよりリアルにする
チュートリアルでは先にAdd TreeからSaplingで木を追加しているが、文脈的には「この機能ではリアルな木は作れません。作りたければ有料の機能拡張が必要になります」という文脈のようなので、この部分は飛ばしていい。次に、リアルな木を作るには本物を見ておきましょう、といって、写真を出している[~1:40]。
[1:40~1:58]
最初に、空間に点を追加する。
手順 Edit Modeへ移動し、最初のCubeを選択、Alt+M→At Center
これでEdito Modeで一つの点が出来上がる。
動画ではCubeをマージしているが、点を追加できるなら何でもいい。例えば既存の図形を [x] →[Only Faces]などを使って解体していってもかまわない。
[1:58~2:25]
作成した点に、Skinモディファイアを適用する。
手順 Modifier →Add Modifier→Generate→Skin
見た目上、キューブが復活する。
Edit Modeであることを確認し、点が選択された状態で[E]キーを押し、マウスを動かす。[E]は押し出し機能であり、選択中の点を押し出すことでエッジを作成する。
このまま木の形を作っていくが、途中どこかで以下の作業を行っておく
[2:25~2:50]
●Subdivison Surfaceモディファイアを二つ追加し、Skinモディファイアを挟み込む。
Skinモディファイアの上のSubsurfは、少ないエッジ数で枝の曲がりを滑らかにするため、Skinモディファイアの下のSubsurfは、枝のメッシュをきめ細かくするために行う。
[2:50~3:00]
必要に応じて、点を選択し、Ctrl+Aでスケーリングし、枝の径を拡大・縮小できる。
[3:00~3:33]
この作業で作るのは太めの枝だけで、細い枝は後から追加する。
[4:00~4:33]
枝の先端を複数選択し、[Ctrl]+[+]を複数回実行し枝を選択、その後、[Shift+D]で枝を複製、複製した枝の根本と結合したい幹を構成する点を両方選択し、[F]キーで接続する。
(これも、要は選択してコピーして結合である。だから普通に「範囲選択してShift+D」でも構わない)
[4:00~4:55]
枝を構成する点を選択した状態で、Pivot Pointを3D Cursorにし、3D Cursorを回転中心に設定し、[R]で回転する

[5:10~5:30]
生成した木を複製し、拡大縮小・微調整を行うことで、少ない労力で形状の異なる木を量産できる。
さて、そのようにして、以下の三本以上を作成する。一つは木の主幹、それ以外は枝となる。
次以降、まず葉をHairで枝に生やし、その枝を主幹に生やすことで木を完成させる。注意として、枝のほうはSubdivideをかけず荒いポリゴンのままにしておくと後の作業を軽くできる。
続く
Blenderで木を作るチュートリアルを試す(1)- 木の形を作る
Blenderで木を作るチュートリアルを試す(2)- 葉を作り枝に生やす
Noise(3ds Max)のColorをFogのColorに繋ぐ。
このとき、色の変化を指定したい場合、Noiseを白黒にしてRemapで調整すると良い
結果
使い方:
結果:
このショートコードの特徴は
1.draftvoid != 0 の時は、下書きや投稿予約状態の記事へのリンクが生成されなくなる。(draftの時はvoidの設定が!falseの意味)
2.draftvoid == 0 の時は、リンクとならず挟んだ文字列がただのテキストとして出力される
3.draftvoidの値にかかわらず、記事のステータスが「公開(publish)」ならリンクが表示される。
使い方2:
<?php function urlToFunc($atts,$content = null){ extract(shortcode_atts(array( 'postid' => 0, 'draftvoid'=>0, ), $atts)); $ret = esc_url( home_url( '/' ) ); // ページへのアドレスを作成 if( $postid != 0){ $ret = esc_url( home_url( '/' ) ).'?p=' . $postid; } //下書きなどのステータスならリンクをつけない if(get_post_status( $postid ) != 'publish'){ //draftvoidがtrueの時はそもそも何も表示しない if( $draftvoid != 0 ){ return ''; } else{ //draftvoidがfalseの時はリンクをつけないでタイトルだけを返す return $content; } } //挟まれた文字列にaタグをつける。ついでにリンクを表す画像もつけている if( $content != '' ){ $imga = '<img src="' . get_template_directory_uri() . '/data/linkto.png" width="8" height="8" />'; return '<a href="'. $ret . '">' . $content .$imga .'</a>'; } return $ret; } add_shortcode('urlTo', 'urlToFunc'); ?>
まずこの二つ、esc_htmlとesc_attrの挙動は、基本的に全く一緒です。
この二つのソースコードを見ると、一番最後が
return apply_filters( 'esc_html', $safe_text, $text );
と
return apply_filters( 'attribute_escape', $safe_text, $text );
というように、最後にapply_filtersで適用するフィルタが違います。
これらのフィルタはデフォルトでは何もしません。従って挙動は完全に同じです。
この二つは目的が違います。
esc_htmlは、テキストとして表示したい内容をエスケープします。
esc_attrは、HTMLのタグの属性値をエスケープします。
タグの属性値とは、
のcolor:red;の事を言います。
WordPressで普通にテンプレートを作っている限りでは、初心者にとってタグの属性値なんて大抵は直打ちで埋め込む物なので、何でわざわざエスケープしなければいけないかわからない(入力の時に気をつければ良いだけ)かもしれないのですが、ユーザーの入力を属性値にするときには特に必要になります。
例えば、こんなフォームを作ったら、出力するときに属性値をエスケープする必要があります。
もっと一般的な例では、このinputフィールドは、以下のように属性値を用いてデフォルトのテキストを指定できます。
<input type="text" value="最初から入力されているテキスト" >
例えばユーザー名や住所を入力させて、確認画面でそれらが入力されている状態にしたいようなインタフェースを作る時には、属性値にユーザー入力を指定することになるので、esc_attrを使うことになります。
参考資料
What is the difference between esc_html filter vs attribute_escape filter?
the_posts_paginationを使えば関数呼び出し一発でページネーションを表示できます。
<?php global $wp_query; $total_results = $wp_query->found_posts; $search_query = get_search_query(); ?> <h1><?php echo $search_query; ?>の検索結果</h1> <div><?php get_search_form(); ?></div> <?php if( $total_results >0 ): if(have_posts()): while(have_posts()): the_post(); ?> <p><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></p> <div class="contents"> <?php the_content(); ?> </div> <?php endwhile; endif; the_posts_pagination( array('screen_reader_text'=>'') ); else: echo $search_query; echo 'に一致する情報は見つかりませんでした。'; endif; ?>
問題はその出力に、「投稿ナビゲーション」というラベルがついてしまうことです。
このラベルを消したいとします。
ただ単に非表示にするならいくつか方法があります。この出力は、以下のようにh2にscreen-reader-textというクラスがついています。
<h2 class="screen-reader-text">投稿ナビゲーション</h2>
この表示をCSS等で切ってしまえば良いことになります。
.screen-reader-text{ display:none; }
あるいはもっと楽なのが、
the_posts_pagination( array('screen_reader_text'=>' ') );
と、the_posts_pagination関数のscreen_reader_textパラメータにスペース一個を渡してやると、スペースが表示されるために見た目上きえます。
ちなみに、見つけた限り最高の正攻法は、https://kimoba.com/kasegu/the_posts_pagination.htmlさんの、get_the_posts_paginationの結果から文字列置換で取り除いてしまうやりかたです。
ただ、それでは面白くないので、もう少し無駄なことをします。まずcodexへ行きます。
https://codex.wordpress.org/Function_Reference/the_posts_pagination
Defined in wp-includes/link-template.php という記述があるので、実装を見て見ます。
the_posts_pagination ← get_the_posts_pagination ← _navigation_markup
という順番で文字列が生成されているので、_navigation_markupを見てみます。
function _navigation_markup( $links, $class = 'posts-navigation', $screen_reader_text = '' ) {
if ( empty( $screen_reader_text ) ) {
$screen_reader_text = __( 'Posts navigation' );
}
$template = '
<nav class="navigation %1$s" role="navigation">
<h2 class="screen-reader-text">%2$s</h2>
<div class="nav-links">%3$s</div>
</nav>';
return sprintf( $template, sanitize_html_class( $class ), esc_html( $screen_reader_text ), $links );
}
ありました。この<h2 class="screen-reader-text">%2$s</h2>がこのタイトルの本体です。こいつをそのまま削ってしまえば良いことになります。とはいえ、Wordpressのコアを書き換えるほどクレイジーにはなれないので、
と名前を変えて、上記h2の部分だけを取り除いた各関数をfunctions.phpに定義して呼び出すことにします。
<?php //ページネーション function my_get_the_posts_pagination( $args = array() ) { $navigation = ''; // Don't print empty markup if there's only one page. if ( $GLOBALS['wp_query']->max_num_pages > 1 ) { $args = wp_parse_args( $args, array( 'mid_size' => 1, 'prev_text' => __( 'Previous' ), 'next_text' => __( 'Next' ), 'screen_reader_text' => __( 'Posts navigation' ), ) ); // Make sure we get a string back. Plain is the next best thing. if ( isset( $args['type'] ) && 'array' == $args['type'] ) { $args['type'] = 'plain'; } // Set up paginated links. $links = paginate_links( $args ); if ( $links ) { $navigation = _my_navigation_markup( $links, 'pagination', $args['screen_reader_text'] ); } } return $navigation; } function _my_navigation_markup( $links, $class = 'posts-navigation', $screen_reader_text = '' ) { if ( empty( $screen_reader_text ) ) { $screen_reader_text = __( 'Posts navigation' ); } $template = ' <nav class="navigation %1$s" role="navigation"> <div class="nav-links">%3$s</div> </nav>'; return sprintf( $template, sanitize_html_class( $class ), esc_html( $screen_reader_text ), $links ); } //ページネーションここまで
呼び出しはget_the_posts_paginationと同じです。the_posts_paginationと全く同じにしたいならechoする関数をもう一つ被せる必要があります。
<?php echo my_get_the_posts_pagination( ); ?>
マテリアルの3Dビュー上での色は、[Material]→[Viewport Color]から設定できます。
(左 Cyclesの場合 , 右 vray for blenderの場合)
Blenderとよく連携がとれているCyclesですら、ノードエディタからDiffuseを設定しても3Dビューでオブジェクトは灰色のままです。複雑なテクスチャを貼ったり、ボリュームの密度を変えただけだったり、vray等外部のレンダラを使った場合、3Dビューを見ただけではどれがどんなマテリアルだかわかりません。
※この色は、実際にレンダリングされる色とは関係ありません。あくまでビュー上で区別するための色です。
普通のdll作成と何一つ変わらないので記事にするか迷ったのだが、一カ所だけわかりにくかったので念のためにまとめておく。
環境は Visual C++ 2017 + CUDA 9.2
手順は以下の通りである。
#include "cuda_runtime.h" #include "device_launch_parameters.h" #include <stdio.h> #include <cstring> #include "cudadll.h" __global__ void hello(char *c) { c[0] = 'h'; c[1] = 'e'; c[2] = 'l'; c[3] = 'l'; c[4] = 'o'; c[5] = '\0'; } //この関数の名前はmainではなく、呼び出す際に適切な名前にする void func_hello(char **c_cpu) { const size_t LEN = 6;// LEN = strlen("hello") + 1; char *c_gpu; cudaMalloc((void**)&c_gpu, LEN);//GPU側にメモリを確保 hello << <1, 1 >> >(c_gpu);//GPU側の関数を呼出 cudaMemcpy(c_cpu, c_gpu, LEN, cudaMemcpyDeviceToHost);//GPU側から実行結果を取得 cudaFree(c_gpu);//GPU側のメモリを解放 }
ソースコードに、_declspec(dllexport) , _declspec(dllimport)の分岐プリプロセッサを書き、先ほどのcall_cuda_funcの先頭につける。
cudadll.h
#ifdef __DLL_EXPORT_DO #define DLL_PORT extern "C" _declspec(dllexport) #else #define DLL_PORT extern "C" _declspec(dllimport) #endif DLL_PORT void func_hello(char **c_cpu);
#include "../cudadll/cudadll.h" #pragma comment(lib,"cudadll.lib") int main() { char c_cpu[12]; func_hello( (char**)&c_cpu); puts(c_cpu); getchar(); return 0; }
基本的に、普通のDLL生成と全く同じである。違いは、
A. dll側のプロジェクトのファイル名が、 (上記②,③)
B. _declspecの分岐のためのプリプロセッサを定義する場所が、 (上記⑤)
の二点である。
Cyclesは半透明な物を描くにあたり、透過処理を行う回数の上限を定めています。
この上限は[Render]→[Light Paths]→[Transparency]→Maxの値で変更できます。
レンダリングしたいシーンに対してこの値が小さすぎるとVolumeやα値を持つオブジェクトを正常に描画できません。
C言語系の関数は例外に対応していない。
個人的に例外は機能は好きだが構文は嫌いだ。それでも使った方がすっきりかける場合もある。
一番簡単なのはラップしてしまう事だろうがつまらないのでもうちょっと自己満足のいくものを考える。
以下のようなクラスを作る。(改めてみるとクラス名がひどい)
template<typename T> class MakeThrow{ T verr; int err_id; public: void ErrorValue(const T val){ verr = val; } void operator=(const T& v){ if( v == verr){ throw err_id; } }; MakeThrow<T>& operator()(const int id){ err_id=id; return *this; } };
そして以下のように使う
int _tmain(int argc, _TCHAR* argv[]) { MakeThrow<FILE*> rets; rets.ErrorValue(nullptr); try{ rets(5) = fopen("abc","r"); } catch(int e){ std::cout << e; } getchar(); return 0; }
retsの=をオーバーロードし、C言語系の関数の戻り値を受け取れるようにする。
=の中では、受け取った値を比較し、エラー値なら例外を出す。この時エラー番号を投げておくと、どこでエラーがあったかがよりわかりやすくなる(多分)ので、operator()でエラー番号を指定すると、その数値をcatchすることができる。
まあ、普通はまず使わないだろうが、XmlLite プログラミングを読んでいると、命令の一つ一つでif(FAILED(...)を行っていて、たとえそれが合理的で完膚なきまでに正しい行為でも、もう少し何とかならんのかと思ってしまったのである。
if(FAILED(pWriter->WriteStartElement(NULL, L"requirement", NULL))){ MessageBox(NULL, _T("WriteStartElement失敗"), _T("警告"), MB_OK | MB_ICONWARNING); return; } if(FAILED(pWriter->WriteElementString(NULL, L"type", NULL, L"ヘッダ"))){ MessageBox(NULL, _T("WriteElementString失敗"), _T("警告"), MB_OK | MB_ICONWARNING); return; } if(FAILED(pWriter->WriteElementString(NULL, L"name", NULL, L"XmlLite.h"))){ MessageBox(NULL, _T("WriteElementString失敗"), _T("警告"), MB_OK | MB_ICONWARNING); return; } if(FAILED(pWriter->WriteFullEndElement())){ MessageBox(NULL, _T("WriteFullEndElement失敗"), _T("警告"), MB_OK | MB_ICONWARNING); return; }
Noiseノードの設定。Propertiesで、[3D]を選ぶ。これをしないと2Dテクスチャが伸びたようなフォグになる。