GLSLで不透明物体のレンダリング
をテンプレートにして作成
[
トップ
|
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
]
開始行:
[[GPU Gems - Chapter 16:http://http.developer.nvidia.com/...
[[GLSLでシャドウマッピング]]と同様に光源からのデプスマッ...
----
#contents
----
**不透明物体のレンダリングについて [#ffd5e78a]
完全に透明な物体と異なり,不透明な物体はその内部において...
そのため,その表面色は光が物体内をどのような経路で進んだ...
ここでは単純に物体内での吸収のみを考え(つまり,他の経路を...
また,物体内の特性は一定であるとする.
そうすると,ある表面点での色は光源からその点に至るまでの...
下の図に置いて,sSUB{1};,sSUB{2};はそれぞれの点における物...
#ref(translucent.jpg,nolink,100%)
この図を見てわかるように物体内深度は[[GLSLでシャドウマッ...
光源を視点として作成したデプスマップから求めることができ...
詳しくは[[GPU Gems - Chapter 16:http://http.developer.nvi...
**光源からの物体内深度の算出 [#d83e5f3e]
基本的にはシャドウマップを生成するサイトおなじなので[[GLS...
ただし,光源からのデプスマップはポリゴンの表面で生成する...
光線にほぼ平行な面では微妙な角度の差でもデプス値が大きく...
境界面近くになると特にこの現象が顕著に現れる.
シャドウマップではz-ファイティングを防ぐためにglPolygonOf...
glPolygonOffsetはデプス方向でしか変化させないので,光線に...
そこで,GLSLで頂点を法線方向にオフセットさせ,
微少量膨張した状態でデプスマップを生成する.
デプスマップ生成時のGLSLの頂点シェーダは以下.
#code(C){{
uniform float offset;
void main(void)
{
vec3 pos = vec3(gl_Vertex)+gl_Normal*offset;
gl_Position = gl_ModelViewProjectionMatrix*vec4(pos, gl_...
}
}}
フラグメントシェーダは単純に色を返すだけにする.
#code(C){{
void main(void)
{
gl_FragColor = gl_Color;
}
}}
**物体内での吸収・散乱 [#wcdecf2e]
デプスマップから得られた光源からの距離と注目表面点におけ...
物体内深度が求められる.この値に基づき表面の色を決定する.
ここでは簡単にexp関数を用いる.
つまり,物体内深度をsiとすると色を以下のように計算する.
exp(-si*sigma_t)*gl_FrontLightProduct[0].diffuse;
ここでは物体の色として拡散反射色を用いている.
siの算出も含めたフラグメントシェーダのコードを以下に示す.
#code(C){{
/*!
* 物体内の光源ベクトル深度
* @return 光源ベクトル深度
*/
float LightDepth(void)
{
// 光源座標
vec4 shadow_coord1 = vShadowCoord/vShadowCoord.w;
// 光源からのデプス値(視点)
float view_d = shadow_coord1.z;
// 格納された光源からの最小デプス値を取得
float light_d = texture2D(depth_tex, shadow_coord1.xy).z;
// 光源からのデプス値と遮蔽を考慮したデプス値の差を求める
return view_d-light_d;
}
/*!
* 不透明物体のDepth Mapを利用したシェーディング
* @return 表面反射色
*/
vec4 TranslucentShading(void)
{
vec3 N = normalize(vNrm); // 法線ベクトル
vec3 L = normalize(gl_LightSource[0].position.xyz-vPos.x...
// 環境光の計算
// - OpenGLが計算した光源強度と反射係数の積(gl_FrontLig...
vec4 ambient = gl_FrontLightProduct[0].ambient;
// 拡散反射係数の計算
float dcoef = max(dot(L, N), 0.0);
// 光の透過効果
float si = LightDepth();
vec4 diffuse = exp(-si*sigma_t)*gl_FrontLightProduct[0]....
// 鏡面反射の計算
vec4 specular = vec4(0.0);
if(dcoef > 0.0){
vec3 V = normalize(-vPos.xyz); // 視線ベクトル
// 反射ベクトルの計算(フォン反射モデル)
vec3 R = reflect(-L, N);
float specularLight = pow(max(dot(R, V), 0.0), gl_Front...
specular = gl_FrontLightProduct[0].specular*specularLig...
}
return ambient+diffuse+specular;
}
void main(void)
{
gl_FragColor = TranslucentShading();
}
}}
**実行結果 [#x2f5f670]
実行結果のスクリーンショットを以下に示す(クリックで拡大).
#ref(translucent_result1.jpg,,50%)
sigma_t=50にしてある.
この方法では光源と表面の間に障害物があった場合,障害物表...
下の図に示すように影のようなものができてしまう
(誤った深度によるものであり実際の影とは異なる色になってい...
#ref(translucent_result2.jpg,,50%)
**ソースコード [#s8641ceb]
Visual Studio 2010用のソースコードを以下に置く(要freeglut...
#ref(glsl_translucent.zip)
終了行:
[[GPU Gems - Chapter 16:http://http.developer.nvidia.com/...
[[GLSLでシャドウマッピング]]と同様に光源からのデプスマッ...
----
#contents
----
**不透明物体のレンダリングについて [#ffd5e78a]
完全に透明な物体と異なり,不透明な物体はその内部において...
そのため,その表面色は光が物体内をどのような経路で進んだ...
ここでは単純に物体内での吸収のみを考え(つまり,他の経路を...
また,物体内の特性は一定であるとする.
そうすると,ある表面点での色は光源からその点に至るまでの...
下の図に置いて,sSUB{1};,sSUB{2};はそれぞれの点における物...
#ref(translucent.jpg,nolink,100%)
この図を見てわかるように物体内深度は[[GLSLでシャドウマッ...
光源を視点として作成したデプスマップから求めることができ...
詳しくは[[GPU Gems - Chapter 16:http://http.developer.nvi...
**光源からの物体内深度の算出 [#d83e5f3e]
基本的にはシャドウマップを生成するサイトおなじなので[[GLS...
ただし,光源からのデプスマップはポリゴンの表面で生成する...
光線にほぼ平行な面では微妙な角度の差でもデプス値が大きく...
境界面近くになると特にこの現象が顕著に現れる.
シャドウマップではz-ファイティングを防ぐためにglPolygonOf...
glPolygonOffsetはデプス方向でしか変化させないので,光線に...
そこで,GLSLで頂点を法線方向にオフセットさせ,
微少量膨張した状態でデプスマップを生成する.
デプスマップ生成時のGLSLの頂点シェーダは以下.
#code(C){{
uniform float offset;
void main(void)
{
vec3 pos = vec3(gl_Vertex)+gl_Normal*offset;
gl_Position = gl_ModelViewProjectionMatrix*vec4(pos, gl_...
}
}}
フラグメントシェーダは単純に色を返すだけにする.
#code(C){{
void main(void)
{
gl_FragColor = gl_Color;
}
}}
**物体内での吸収・散乱 [#wcdecf2e]
デプスマップから得られた光源からの距離と注目表面点におけ...
物体内深度が求められる.この値に基づき表面の色を決定する.
ここでは簡単にexp関数を用いる.
つまり,物体内深度をsiとすると色を以下のように計算する.
exp(-si*sigma_t)*gl_FrontLightProduct[0].diffuse;
ここでは物体の色として拡散反射色を用いている.
siの算出も含めたフラグメントシェーダのコードを以下に示す.
#code(C){{
/*!
* 物体内の光源ベクトル深度
* @return 光源ベクトル深度
*/
float LightDepth(void)
{
// 光源座標
vec4 shadow_coord1 = vShadowCoord/vShadowCoord.w;
// 光源からのデプス値(視点)
float view_d = shadow_coord1.z;
// 格納された光源からの最小デプス値を取得
float light_d = texture2D(depth_tex, shadow_coord1.xy).z;
// 光源からのデプス値と遮蔽を考慮したデプス値の差を求める
return view_d-light_d;
}
/*!
* 不透明物体のDepth Mapを利用したシェーディング
* @return 表面反射色
*/
vec4 TranslucentShading(void)
{
vec3 N = normalize(vNrm); // 法線ベクトル
vec3 L = normalize(gl_LightSource[0].position.xyz-vPos.x...
// 環境光の計算
// - OpenGLが計算した光源強度と反射係数の積(gl_FrontLig...
vec4 ambient = gl_FrontLightProduct[0].ambient;
// 拡散反射係数の計算
float dcoef = max(dot(L, N), 0.0);
// 光の透過効果
float si = LightDepth();
vec4 diffuse = exp(-si*sigma_t)*gl_FrontLightProduct[0]....
// 鏡面反射の計算
vec4 specular = vec4(0.0);
if(dcoef > 0.0){
vec3 V = normalize(-vPos.xyz); // 視線ベクトル
// 反射ベクトルの計算(フォン反射モデル)
vec3 R = reflect(-L, N);
float specularLight = pow(max(dot(R, V), 0.0), gl_Front...
specular = gl_FrontLightProduct[0].specular*specularLig...
}
return ambient+diffuse+specular;
}
void main(void)
{
gl_FragColor = TranslucentShading();
}
}}
**実行結果 [#x2f5f670]
実行結果のスクリーンショットを以下に示す(クリックで拡大).
#ref(translucent_result1.jpg,,50%)
sigma_t=50にしてある.
この方法では光源と表面の間に障害物があった場合,障害物表...
下の図に示すように影のようなものができてしまう
(誤った深度によるものであり実際の影とは異なる色になってい...
#ref(translucent_result2.jpg,,50%)
**ソースコード [#s8641ceb]
Visual Studio 2010用のソースコードを以下に置く(要freeglut...
#ref(glsl_translucent.zip)
ページ名: