メディア演習C(CG)/第6回
をテンプレートにして作成
開始行:
**シェーダー [#a723d9d9]
ここではシェーダの基礎を学びます.
** 準備 [#g44eca36]
モデル1個とライトが1つある基本的なシーンを用意します.
void setup()
{
size(640, 480, P3D);
}
void draw()
{
background(127, 127, 127);
camera(100, -100, 100, 0, 0, 0, 0, 1, 0);
axis(100);
fill(255, 0, 0);
noStroke();
directionalLight(255, 255, 255, -1, 1, 0);
sphere(30);
}
void axis(float l)
{
stroke(255, 0, 0);
line(0, 0, 0, l, 0, 0);
stroke(0, 255, 0);
line(0, 0, 0, 0, l, 0);
stroke(0, 0, 255);
line(0, 0, 0, 0, 0, l);
}
#ref(./lightrot.png,50%);
**シェーダーとは [#sd18281c]
これまで,3DCGを描くため光源の設定などを行いました.例え...
directionalLight(255, 255, 255, -1, 1, 0);
のように記述しました.
では,実際に配置されたモデルと光源はどのように計算されて...
Processing2.0からはシェーダがその計算を行っています.
シェーダはプログラムから渡されたモデルの情報(頂点の位置...
**シェーダを使ってみる [#z02f494d]
Processingがデフォルトで使用しているシェーダをやめて,自...
PShader shader;
void setup()
{
size(640, 480, P3D);
shader = loadShader("FragmentShader.glsl", "VertexShad...
}
void draw()
{
background(127, 127, 127);
camera(100, -100, 100, 0, 0, 0, 0, 1, 0);
axis(100);
fill(255, 0, 0);
noStroke();
directionalLight(255, 255, 255, -1, 1, 0);
shader(shader);
sphere(30);
}
void axis(float l)
{
stroke(255, 0, 0);
line(0, 0, 0, l, 0, 0);
stroke(0, 255, 0);
line(0, 0, 0, 0, l, 0);
stroke(0, 0, 255);
line(0, 0, 0, 0, 0, l);
}
シェーダである以下2つのファイル,VertexShader.glsl,Fragm...
#ref(./VertexShader.glsl);
#ref(./FragmentShader.glsl);
VertexShader.glsl:
uniform mat4 transform;
uniform mat3 normalMatrix;
uniform vec3 lightNormal;
attribute vec4 vertex;
attribute vec4 color;
attribute vec3 normal;
varying vec4 vertColor;
varying vec3 vertNormal;
varying vec3 vertLightDir;
void main() {
gl_Position = transform * vertex;
vertColor = color;
vertNormal = normalize(normalMatrix * normal);
vertLightDir = -lightNormal;
}
FragmentShader.glsl:
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
#define PROCESSING_LIGHT_SHADER
uniform float fraction;
varying vec4 vertColor;
varying vec3 vertNormal;
varying vec3 vertLightDir;
void main() {
float intensity;
intensity = max(0.0, dot(vertLightDir, vertNormal));
gl_FragColor = vec4(vertColor.xyz * intensity, 1.0);
}
**シェーダの書き換え [#v9abd0ce]
[Sketch]→[Show Sketch Folder]で,現在のSketchのフォルダを...
例えば,モデルを描画する際の,各画素の色はFragmentShader....
gl_FragColor = vec4(vertColor.xyz * intensity, 1.0);
試しに,以下のように変更してみましょう.
gl_FragColor = vec4(0.5, 0.5, 1.0, 1.0);
#ref(./fragshader.png,50%);
モデルの色を赤と指定しているのに関わらず,モデルが青にな...
RGBA=(0.5, 0.5, 1.0, 1.0);
とするようにシェーダを書き換えたためです.
元々のプログラムがどういう意味か解説していきます.
gl_FragColor = vec4(vertColor.xyz * intensity, 1.0);
vertColorにはモデルの色が入っていますRGBA=(1, 0, 0, 1)....
intensity = max(0.0, dot(vertLightDir, vertNormal));
vertLightDirは光源の向きの反対ベクトル,vertNormalはモデ...
#ref(./lighting.png,50%);
例えば,内積の値を透明度にするよう設定してみます.
gl_FragColor = vec4(vertColor.xyz * intensity, intensi...
光が当たっている個所は不透明で,当たらない個所は透明とな...
#ref(./trans.png,50%);
このようにシェーダを書き換えることで,Processingが用意す...
**シェーダ内で使える型 [#c9ad6958]
シェーダはProcessingとは異なる言語ですので,使える型も異...
-float:Processing同様,少数を含む値一つを扱う型
-vec2:2次元ベクトル
-vec3:3次元ベクトル
-vec4:4次元ベクトル
-mat2:2x2行列
-mat3:3x3行列
-mat4:4x4行列
正確にはProcessingではGLSLというシェーダ言語なので,使用...
-https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)
ここではベクトル型の使用例を示します.
vec4 v = vec4(1.0, 0.0, 0.0, 1.0); //4次元ベクトル変数を...
v.x = 2.0; //x成分を変更
v.y = v.z; //y成分をz成分に変更
vec3 a = vec3(3.0, 2.0, 1.0); //3次元ベクトル変数を...
v = vec4(a.xyz, 1.0); //vの値を変更,a.xyz...
//vは(3.0, 2.0, 1.0, ...
vec3 b = vec3(0.3, 0.2, 0.1);
vec3 c = a + b; //ベクトルの足し算と...
vec3 d = a * b; //成分ごとの掛け算と...
詳細を知りたい場合は以下を参照:
-https://en.wikibooks.org/wiki/GLSL_Programming/Vector_an...
**課題の提出先・提出方法 [#dc136f9e]
招待されているBoxアップロードフォルダ「第06回」に自身の学...
''提出締め切り:7月9日(火) 23:59''
BOXアップロードフォルダの招待メールが来ていない,また,We...
**課題 [#vdde6c4b]
セピア調(古い写真のような色合い)で描画するシェーダを書け
提出スケッチフォルダ名:BASIC6_1
オリジナル(シェーダを用いていない):
#ref(orig.png);
課題の結果例:
#ref(sepia.png);
***ヒント:セピア調への変換式 [#fe51763e]
以下のサイトより引用すると,
-https://wgld.org/d/webgl/w054.html
まず,オリジナルの画素の色をcとすると,それをグレースケー...
>g = 0.29 * c.r + 0.58 * c.g + 0.11 * c.b
カラーをグレースケールへ変換する式は様々な式が提案されて...
-[[https://ja.wikipedia.org/wiki/グレースケール:https://j...
グレースケールの値gを基に,セピア調の色を生成する.この式...
画素の色をpとすると,
>p.r = 1.07 * g
>p.g = 0.74 * g
>p.b = 0.43 * g
とすることで,セピア調の色となる.
***ヒント:グレースケールまでの実装例 [#p62479db]
vec3 c = vertColor.xyz * intensity;
float g = 0.29 * c.x + 0.58 * c.y + 0.11 * c.z;
gl_FragColor = vec4(g, g, g, 1.0);
***ヒント:背景の色 [#g67c4f74]
物体が描画されない箇所はシェーダが適用されないので,backg...
結果例は,
background(240, 200, 145);
としている.
***ヒント:床が真っ黒になる場合 [#h1e53c80]
第4回のライティングでは面の法線(表面と裏面)を考慮する必...
そのため,頂点が反時計回りの面は裏面となり,光を当てても...
***ヒント:文字コードに注意 [#k6d699d0]
.glslファイル文字コードはUTF-8(BOMなし)である必要がある...
一部テキストディタでは「UTF-8」のみの表記がデフォルトで「...
例えば,TeraPadにおける「UTF-8」はBOMあり,となっているの...
-TeraPadで文字コードにUTF-8(BOMなし)を指定して文字化けし...
https://creating-homepage.com/archives/97
**任意課題 [#q10e4c95]
アニメ調(トゥーンシェーディング)で描画するシェーダを書け
提出スケッチフォルダ名:ADVANCE6_1
#ref(toon.png);
ヒント:アニメ調にするには
下図左のように,intensityをそのまま使用した場合,表面の明...
#ref(./int.png,50%);
終了行:
**シェーダー [#a723d9d9]
ここではシェーダの基礎を学びます.
** 準備 [#g44eca36]
モデル1個とライトが1つある基本的なシーンを用意します.
void setup()
{
size(640, 480, P3D);
}
void draw()
{
background(127, 127, 127);
camera(100, -100, 100, 0, 0, 0, 0, 1, 0);
axis(100);
fill(255, 0, 0);
noStroke();
directionalLight(255, 255, 255, -1, 1, 0);
sphere(30);
}
void axis(float l)
{
stroke(255, 0, 0);
line(0, 0, 0, l, 0, 0);
stroke(0, 255, 0);
line(0, 0, 0, 0, l, 0);
stroke(0, 0, 255);
line(0, 0, 0, 0, 0, l);
}
#ref(./lightrot.png,50%);
**シェーダーとは [#sd18281c]
これまで,3DCGを描くため光源の設定などを行いました.例え...
directionalLight(255, 255, 255, -1, 1, 0);
のように記述しました.
では,実際に配置されたモデルと光源はどのように計算されて...
Processing2.0からはシェーダがその計算を行っています.
シェーダはプログラムから渡されたモデルの情報(頂点の位置...
**シェーダを使ってみる [#z02f494d]
Processingがデフォルトで使用しているシェーダをやめて,自...
PShader shader;
void setup()
{
size(640, 480, P3D);
shader = loadShader("FragmentShader.glsl", "VertexShad...
}
void draw()
{
background(127, 127, 127);
camera(100, -100, 100, 0, 0, 0, 0, 1, 0);
axis(100);
fill(255, 0, 0);
noStroke();
directionalLight(255, 255, 255, -1, 1, 0);
shader(shader);
sphere(30);
}
void axis(float l)
{
stroke(255, 0, 0);
line(0, 0, 0, l, 0, 0);
stroke(0, 255, 0);
line(0, 0, 0, 0, l, 0);
stroke(0, 0, 255);
line(0, 0, 0, 0, 0, l);
}
シェーダである以下2つのファイル,VertexShader.glsl,Fragm...
#ref(./VertexShader.glsl);
#ref(./FragmentShader.glsl);
VertexShader.glsl:
uniform mat4 transform;
uniform mat3 normalMatrix;
uniform vec3 lightNormal;
attribute vec4 vertex;
attribute vec4 color;
attribute vec3 normal;
varying vec4 vertColor;
varying vec3 vertNormal;
varying vec3 vertLightDir;
void main() {
gl_Position = transform * vertex;
vertColor = color;
vertNormal = normalize(normalMatrix * normal);
vertLightDir = -lightNormal;
}
FragmentShader.glsl:
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
#define PROCESSING_LIGHT_SHADER
uniform float fraction;
varying vec4 vertColor;
varying vec3 vertNormal;
varying vec3 vertLightDir;
void main() {
float intensity;
intensity = max(0.0, dot(vertLightDir, vertNormal));
gl_FragColor = vec4(vertColor.xyz * intensity, 1.0);
}
**シェーダの書き換え [#v9abd0ce]
[Sketch]→[Show Sketch Folder]で,現在のSketchのフォルダを...
例えば,モデルを描画する際の,各画素の色はFragmentShader....
gl_FragColor = vec4(vertColor.xyz * intensity, 1.0);
試しに,以下のように変更してみましょう.
gl_FragColor = vec4(0.5, 0.5, 1.0, 1.0);
#ref(./fragshader.png,50%);
モデルの色を赤と指定しているのに関わらず,モデルが青にな...
RGBA=(0.5, 0.5, 1.0, 1.0);
とするようにシェーダを書き換えたためです.
元々のプログラムがどういう意味か解説していきます.
gl_FragColor = vec4(vertColor.xyz * intensity, 1.0);
vertColorにはモデルの色が入っていますRGBA=(1, 0, 0, 1)....
intensity = max(0.0, dot(vertLightDir, vertNormal));
vertLightDirは光源の向きの反対ベクトル,vertNormalはモデ...
#ref(./lighting.png,50%);
例えば,内積の値を透明度にするよう設定してみます.
gl_FragColor = vec4(vertColor.xyz * intensity, intensi...
光が当たっている個所は不透明で,当たらない個所は透明とな...
#ref(./trans.png,50%);
このようにシェーダを書き換えることで,Processingが用意す...
**シェーダ内で使える型 [#c9ad6958]
シェーダはProcessingとは異なる言語ですので,使える型も異...
-float:Processing同様,少数を含む値一つを扱う型
-vec2:2次元ベクトル
-vec3:3次元ベクトル
-vec4:4次元ベクトル
-mat2:2x2行列
-mat3:3x3行列
-mat4:4x4行列
正確にはProcessingではGLSLというシェーダ言語なので,使用...
-https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)
ここではベクトル型の使用例を示します.
vec4 v = vec4(1.0, 0.0, 0.0, 1.0); //4次元ベクトル変数を...
v.x = 2.0; //x成分を変更
v.y = v.z; //y成分をz成分に変更
vec3 a = vec3(3.0, 2.0, 1.0); //3次元ベクトル変数を...
v = vec4(a.xyz, 1.0); //vの値を変更,a.xyz...
//vは(3.0, 2.0, 1.0, ...
vec3 b = vec3(0.3, 0.2, 0.1);
vec3 c = a + b; //ベクトルの足し算と...
vec3 d = a * b; //成分ごとの掛け算と...
詳細を知りたい場合は以下を参照:
-https://en.wikibooks.org/wiki/GLSL_Programming/Vector_an...
**課題の提出先・提出方法 [#dc136f9e]
招待されているBoxアップロードフォルダ「第06回」に自身の学...
''提出締め切り:7月9日(火) 23:59''
BOXアップロードフォルダの招待メールが来ていない,また,We...
**課題 [#vdde6c4b]
セピア調(古い写真のような色合い)で描画するシェーダを書け
提出スケッチフォルダ名:BASIC6_1
オリジナル(シェーダを用いていない):
#ref(orig.png);
課題の結果例:
#ref(sepia.png);
***ヒント:セピア調への変換式 [#fe51763e]
以下のサイトより引用すると,
-https://wgld.org/d/webgl/w054.html
まず,オリジナルの画素の色をcとすると,それをグレースケー...
>g = 0.29 * c.r + 0.58 * c.g + 0.11 * c.b
カラーをグレースケールへ変換する式は様々な式が提案されて...
-[[https://ja.wikipedia.org/wiki/グレースケール:https://j...
グレースケールの値gを基に,セピア調の色を生成する.この式...
画素の色をpとすると,
>p.r = 1.07 * g
>p.g = 0.74 * g
>p.b = 0.43 * g
とすることで,セピア調の色となる.
***ヒント:グレースケールまでの実装例 [#p62479db]
vec3 c = vertColor.xyz * intensity;
float g = 0.29 * c.x + 0.58 * c.y + 0.11 * c.z;
gl_FragColor = vec4(g, g, g, 1.0);
***ヒント:背景の色 [#g67c4f74]
物体が描画されない箇所はシェーダが適用されないので,backg...
結果例は,
background(240, 200, 145);
としている.
***ヒント:床が真っ黒になる場合 [#h1e53c80]
第4回のライティングでは面の法線(表面と裏面)を考慮する必...
そのため,頂点が反時計回りの面は裏面となり,光を当てても...
***ヒント:文字コードに注意 [#k6d699d0]
.glslファイル文字コードはUTF-8(BOMなし)である必要がある...
一部テキストディタでは「UTF-8」のみの表記がデフォルトで「...
例えば,TeraPadにおける「UTF-8」はBOMあり,となっているの...
-TeraPadで文字コードにUTF-8(BOMなし)を指定して文字化けし...
https://creating-homepage.com/archives/97
**任意課題 [#q10e4c95]
アニメ調(トゥーンシェーディング)で描画するシェーダを書け
提出スケッチフォルダ名:ADVANCE6_1
#ref(toon.png);
ヒント:アニメ調にするには
下図左のように,intensityをそのまま使用した場合,表面の明...
#ref(./int.png,50%);
ページ名: