Re: シェーダーのg_Common.Light[ 0 ],[ 1 ],[ 2 ] がCreate〜LightHandと非合致 ( No.1 ) |
- 名前:yoneymyquestion 日時:2024/03/09 19:28
-----------<< 2 >> 頂点シェーダ全体------------------------------
// 頂点シェーダーの入力 DrawPolygonIndexed3DToShader_UseVertexBuffer 用の頂点データの定義
// <参考> ://dxlib.xsrv.jp/cgi/patiobbs/patio.cgi?mode=view&no=5437
struct VS_INPUT
{
float3 Position : POSITION0 ; // 座標( ローカル空間 )
float4 SubPosition : POSITION1 ; // 予備座標
float3 Normal : NORMAL0 ; // 法線( ローカル空間 )
float3 Tangent : TANGENT0 ; // 接線( ローカル空間 )
float3 Binormal : BINORMAL0 ; // 従法線( ローカル空間 )
float4 Diffuse : COLOR0 ; // ディフューズカラー
float4 Specular : COLOR1 ; // スペキュラカラー
float2 TexCoords0 : TEXCOORD0 ; // テクスチャ座標
float2 TexCoords1 : TEXCOORD1 ; // サブテクスチャ座標
} ;
// 頂点シェーダーの出力
struct VS_OUTPUT
{
float4 Diffuse : COLOR0 ;
float4 Specular : COLOR1 ;
float2 TexCoords0 : TEXCOORD0 ;
float4 Position : SV_POSITION ; // 座標( プロジェクション空間 )
} ;
// マテリアルパラメータ
struct DX_D3D11_CONST_MATERIAL
{
float4 Diffuse ; // ディフューズカラー
float4 Specular ; // スペキュラカラー
float4 Ambient_Emissive ; // マテリアルエミッシブカラー + マテリアルアンビエントカラー * グローバルアンビエントカラー
float Power ; // スペキュラの強さ
float TypeParam0 ; // マテリアルタイプパラメータ0
float TypeParam1 ; // マテリアルタイプパラメータ1
float TypeParam2 ; // マテリアルタイプパラメータ2
} ;
// フォグパラメータ
struct DX_D3D11_VS_CONST_FOG
{
float LinearAdd ; // フォグ用パラメータ end / ( end - start )
float LinearDiv ; // フォグ用パラメータ -1 / ( end - start )
float Density ; // フォグ用パラメータ density
float E ; // フォグ用パラメータ 自然対数の低
float4 Color ; // カラー
} ;
// ライトパラメータ
struct DX_D3D11_CONST_LIGHT
{
int Type ; // ライトタイプ( DX_LIGHTTYPE_POINT など )
int3 Padding1 ; // パディング1
float3 Position ; // 座標( ビュー空間 )
float RangePow2 ; // 有効距離の2乗
float3 Direction ; // 方向( ビュー空間 )
float FallOff ; // スポットライト用FallOff
float3 Diffuse ; // ディフューズカラー
float SpotParam0 ; // スポットライト用パラメータ0( cos( Phi / 2.0f ) )
float3 Specular ; // スペキュラカラー
float SpotParam1 ; // スポットライト用パラメータ1( 1.0f / ( cos( Theta / 2.0f ) - cos( Phi / 2.0f ) ) )
float4 Ambient ; // アンビエントカラーとマテリアルのアンビエントカラーを乗算したもの
float Attenuation0 ; // 距離による減衰処理用パラメータ0
float Attenuation1 ; // 距離による減衰処理用パラメータ1
float Attenuation2 ; // 距離による減衰処理用パラメータ2
float Padding2 ; // パディング2
} ;
// ピクセルシェーダー・頂点シェーダー共通パラメータ
struct DX_D3D11_CONST_BUFFER_COMMON
{
DX_D3D11_CONST_LIGHT Light[ 6 ] ; // ライトパラメータ
DX_D3D11_CONST_MATERIAL Material ; // マテリアルパラメータ
DX_D3D11_VS_CONST_FOG Fog ; // フォグパラメータ
} ;
// 基本パラメータ
struct DX_D3D11_VS_CONST_BUFFER_BASE
{
float4 AntiViewportMatrix[ 4 ] ; // アンチビューポート行列
float4 ProjectionMatrix[ 4 ] ; // ビュー → プロジェクション行列
float4 ViewMatrix[ 3 ] ; // ワールド → ビュー行列
float4 LocalWorldMatrix[ 3 ] ; // ローカル → ワールド行列
float4 ToonOutLineSize ; // トゥーンの輪郭線の大きさ
float DiffuseSource ; // ディフューズカラー( 0.0f:マテリアル 1.0f:頂点 )
float SpecularSource ; // スペキュラカラー( 0.0f:マテリアル 1.0f:頂点 )
float MulSpecularColor ; // スペキュラカラー値に乗算する値( スペキュラ無効処理で使用 )
float Padding ;
} ;
// その他の行列
struct DX_D3D11_VS_CONST_BUFFER_OTHERMATRIX
{
float4 ShadowMapLightViewProjectionMatrix[ 3 ][ 4 ] ; // シャドウマップ用のライトビュー行列とライト射影行列を乗算したもの
float4 TextureMatrix[ 3 ][ 2 ] ; // テクスチャ座標操作用行列
} ;
// 頂点シェーダー・ピクセルシェーダー共通パラメータ
cbuffer cbD3D11_CONST_BUFFER_COMMON : register( b0 )
{
DX_D3D11_CONST_BUFFER_COMMON g_Common ;
} ;
// 基本パラメータ
cbuffer cbD3D11_CONST_BUFFER_VS_BASE : register( b1 )
{
DX_D3D11_VS_CONST_BUFFER_BASE g_Base ;
} ;
// その他の行列
cbuffer cbD3D11_CONST_BUFFER_VS_OTHERMATRIX : register( b2 )
{
DX_D3D11_VS_CONST_BUFFER_OTHERMATRIX g_OtherMatrix ;
} ;
// main関数
VS_OUTPUT main( VS_INPUT VSInput )
{
VS_OUTPUT VSOutput ;
float4 lLocalPosition ;
float4 lWorldPosition ;
float4 lViewPosition ;
float3 lWorldNrm ;
float3 lViewNrm ;
float3 lLightHalfVec ;
float4 lLightLitParam ;
float4 lLightLitDest ;
float3 lLightDir ;
float3 lLightTemp ;
float lLightDistancePow2 ;
float lLightGen ;
//[★違いスポットライト] <剛体メッシュのスポットライトとポイントライトあり描画> NormalMesh_SpotPointLightVS.fx
float lLightDirectionCosA ;
//[★違い] <剛体メッシュのディレクショナルライトとポイントライトあり描画> NormalMesh_DirPointLightVS.fx
float3 lTotalDiffuse ;
float3 lTotalSpecular ;
// 頂点座標変換 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++( 開始 )
// ローカル座標のセット
lLocalPosition.xyz = VSInput.Position ;
lLocalPosition.w = 1.0f ;
// ローカル座標をワールド座標に変換
lWorldPosition.x = dot( lLocalPosition, g_Base.LocalWorldMatrix[ 0 ] ) ;
lWorldPosition.y = dot( lLocalPosition, g_Base.LocalWorldMatrix[ 1 ] ) ;
lWorldPosition.z = dot( lLocalPosition, g_Base.LocalWorldMatrix[ 2 ] ) ;
lWorldPosition.w = 1.0f ;
// ワールド座標をビュー座標に変換
lViewPosition.x = dot( lWorldPosition, g_Base.ViewMatrix[ 0 ] ) ;
lViewPosition.y = dot( lWorldPosition, g_Base.ViewMatrix[ 1 ] ) ;
lViewPosition.z = dot( lWorldPosition, g_Base.ViewMatrix[ 2 ] ) ;
lViewPosition.w = 1.0f ;
// ビュー座標を射影座標に変換
VSOutput.Position.x = dot( lViewPosition, g_Base.ProjectionMatrix[ 0 ] ) ;
VSOutput.Position.y = dot( lViewPosition, g_Base.ProjectionMatrix[ 1 ] ) ;
VSOutput.Position.z = dot( lViewPosition, g_Base.ProjectionMatrix[ 2 ] ) ;
VSOutput.Position.w = dot( lViewPosition, g_Base.ProjectionMatrix[ 3 ] ) ;
// 頂点座標変換 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++( 終了 )
// ライトの処理 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++( 開始 )
//[★違い] <剛体メッシュのディレクショナルライトとポイントライトあり描画> NormalMesh_DirPointLightVS.fx
// ディフューズカラーとスペキュラカラーの蓄積値の初期化
lTotalDiffuse = float3( 0.0f, 0.0f, 0.0f ) ;
lTotalSpecular = float3( 0.0f, 0.0f, 0.0f ) ;
// 法線をビュー空間の角度に変換 =====================================================( 開始 )
// ローカルベクトルをワールドベクトルに変換
lWorldNrm.x = dot( VSInput.Normal, g_Base.LocalWorldMatrix[ 0 ].xyz ) ;
lWorldNrm.y = dot( VSInput.Normal, g_Base.LocalWorldMatrix[ 1 ].xyz ) ;
lWorldNrm.z = dot( VSInput.Normal, g_Base.LocalWorldMatrix[ 2 ].xyz ) ;
// ワールドベクトルをビューベクトルに変換
lViewNrm.x = dot( lWorldNrm, g_Base.ViewMatrix[ 0 ].xyz ) ;
lViewNrm.y = dot( lWorldNrm, g_Base.ViewMatrix[ 1 ].xyz ) ;
lViewNrm.z = dot( lWorldNrm, g_Base.ViewMatrix[ 2 ].xyz ) ;
// 法線をビュー空間の角度に変換 =====================================================( 終了 )
//[★違い] <剛体メッシュのディレクショナルライトとポイントライトあり描画> NormalMesh_DirPointLightVS.fx
// ディレクショナルライトの処理 *****************************************************( 開始 )
// ライトの方向セット
lLightDir = g_Common.Light[ 0 ].Direction ;
// ライトディフューズカラーとライトスペキュラカラーの角度減衰計算 =======( 開始 )
// 法線とライトの逆方向ベクトルとの内積を lLightLitParam.x にセット
lLightLitParam.x = dot( lViewNrm, -lLightDir ) ;
// ハーフベクトルの計算 norm( ( norm( 頂点位置から視点へのベクトル ) + ライトの方向 ) )
lLightHalfVec = normalize( normalize( -lViewPosition.xyz ) - lLightDir ) ;
// 法線とハーフベクトルの内積を lLightLitParam.y にセット https://someiyoshino.info/entry/20171231/1514692823
lLightLitParam.y = dot( lLightHalfVec, lViewNrm ) ;
// スペキュラ反射率を lLightLitParam.w にセット
lLightLitParam.w = g_Common.Material.Power ;
// ライト計算
lLightLitDest = lit( lLightLitParam.x, lLightLitParam.y, lLightLitParam.w ) ;
// ライトディフューズカラーとライトスペキュラカラーの角度減衰計算 =======( 終了 )
// カラー計算 ===========================================================( 開始 )
// ディフューズライト蓄積値 += ディフューズ角度減衰計算結果 * マテリアルディフューズカラー * ライトのディフューズカラー + ライトのアンビエントカラーとマテリアルのアンビエントカラーを乗算したもの
lTotalDiffuse += lLightLitDest.y * g_Common.Light[ 0 ].Diffuse * g_Common.Material.Diffuse.xyz + g_Common.Light[ 0 ].Ambient.xyz ;
// スペキュラライト蓄積値 += スペキュラ角度減衰計算結果 * ライトのスペキュラカラー
lTotalSpecular += lLightLitDest.z * g_Common.Light[ 0 ].Specular ;
// カラー計算 ===========================================================( 終了 )
// ディレクショナルライトの処理 *****************************************************( 終了 )
//[★違い] <剛体メッシュのディレクショナルライトとポイントライトあり描画> NormalMesh_DirPointLightVS.fx
// ポイントライトの処理 *************************************************************( 開始 )
// ライト方向ベクトルの計算
lLightDir = normalize( lViewPosition.xyz - g_Common.Light[ 1 ].Position.xyz ) ;
// 距離減衰値計算 ===================================================================( 開始 )
// 頂点とライト位置との距離の二乗を求める
lLightTemp = lViewPosition.xyz - g_Common.Light[ 1 ].Position.xyz ;
lLightDistancePow2 = dot( lLightTemp, lLightTemp ) ;
// 減衰率の計算 lLightGen = 1 / ( 減衰値0 + 減衰値1 * 距離 + 減衰値2 * ( 距離 * 距離 ) )
lLightGen = 1.0f / ( g_Common.Light[ 1 ].Attenuation0 + g_Common.Light[ 1 ].Attenuation1 * sqrt( lLightDistancePow2 ) + g_Common.Light[ 1 ].Attenuation2 * lLightDistancePow2 ) ;
// 有効距離外だったら減衰率を最大にする処理
lLightGen *= step( lLightDistancePow2, g_Common.Light[ 1 ].RangePow2 ) ;
// 距離減衰値計算 ===================================================================( 終了 )
// ライトディフューズカラーとライトスペキュラカラーの角度減衰計算 ===================( 開始 )
// 法線とライトの逆方向ベクトルとの内積を lLightLitParam.x にセット
lLightLitParam.x = dot( lViewNrm, -lLightDir ) ;
// ハーフベクトルの計算 norm( ( norm( 頂点位置から視点へのベクトル ) + ライトの方向 ) )
lLightHalfVec = normalize( normalize( -lViewPosition.xyz ) - lLightDir ) ;
// 法線とハーフベクトルの内積を lLightLitParam.y にセット ://someiyoshino.info/entry/20171231/1514692823
lLightLitParam.y = dot( lLightHalfVec, lViewNrm ) ;
// スペキュラ反射率を lLightLitParam.w にセット
lLightLitParam.w = g_Common.Material.Power ;
// ライトパラメータ計算
lLightLitDest = lit( lLightLitParam.x, lLightLitParam.y, lLightLitParam.w ) ;
// ライトディフューズカラーとライトスペキュラカラーの角度減衰計算 ===================( 終了 )
//[★違い] <剛体メッシュのディレクショナルライトとポイントライトあり描画> NormalMesh_DirPointLightVS.fx
// カラー計算 ===========================================================( 開始 )
// ディフーズライト蓄積値 += 距離・スポットライト角度減衰値 * ( ディフーズ角度減衰計算結果 * マテリアルディフューズカラー * ライトのディフーズカラー + ライトのアンビエントカラーとマテリアルのアンビエントカラーを乗算したもの )
lTotalDiffuse += lLightGen * ( lLightLitDest.y * g_Common.Light[ 1 ].Diffuse * g_Common.Material.Diffuse.xyz + g_Common.Light[ 1 ].Ambient.xyz ) ;
// スペキュラライト蓄積値 += スペキュラ角度減衰計算結果 * 距離・スポットライト減衰 * ライトのスペキュラカラー
lTotalSpecular += lLightGen * lLightLitDest.z * g_Common.Light[ 1 ].Specular ;
// カラー計算 ===========================================================( 終了 )
// ポイントライトの処理 *************************************************************( 終了 )
//[★違いスポットライト] <剛体メッシュのスポットライトとポイントライトあり描画> NormalMesh_SpotPointLightVS.fx
// スポットライトの処理 *************************************************************( 開始 )
// ライト方向ベクトルの計算
lLightDir = normalize( lViewPosition.xyz - g_Common.Light[ 2 ].Position.xyz ) ;
// 距離・スポットライト減衰値計算 =======================================( 開始 )
// 距離減衰計算 ------------------
// 頂点とライト位置との距離の二乗を求める
lLightTemp = lViewPosition.xyz - g_Common.Light[ 2 ].Position.xyz ;
lLightDistancePow2 = dot( lLightTemp, lLightTemp ) ;
// 減衰率の計算 lLightGen = 1 / ( 減衰値0 + 減衰値1 * 距離 + 減衰値2 * ( 距離 * 距離 ) )
lLightGen = 1.0f / ( g_Common.Light[ 2 ].Attenuation0 + g_Common.Light[ 2 ].Attenuation1 * sqrt( lLightDistancePow2 ) + g_Common.Light[ 2 ].Attenuation2 * lLightDistancePow2 ) ;
// スポットライト減衰計算 --------
// ライト方向ベクトルとライト位置から頂点位置へのベクトルの内積( 即ち Cos a )を計算
lLightDirectionCosA = dot( lLightDir, g_Common.Light[ 2 ].Direction ) ;
// スポットライト減衰計算 pow( falloff, ( ( Cos a - Cos f ) / ( Cos q - Cos f ) ) )
lLightGen *= saturate( pow( abs( max( lLightDirectionCosA - g_Common.Light[ 2 ].SpotParam0, 0.0f ) * g_Common.Light[ 2 ].SpotParam1 ), g_Common.Light[ 2 ].FallOff ) ) ;
// 有効距離外だったら減衰率を最大にする処理
lLightGen *= step( lLightDistancePow2, g_Common.Light[ 2 ].RangePow2 ) ;
// 距離・スポットライト減衰値計算 =======================================( 終了 )
// ライトディフューズカラーとライトスペキュラカラーの角度減衰計算 =======( 開始 )
// 法線とライトの逆方向ベクトルとの内積を lLightLitParam.x にセット
lLightLitParam.x = dot( lViewNrm, -lLightDir ) ;
// ハーフベクトルの計算 norm( ( norm( 頂点位置から視点へのベクトル ) + ライトの方向 ) )
lLightHalfVec = normalize( normalize( -lViewPosition.xyz ) - lLightDir ) ;
// 法線とハーフベクトルの内積を lLightLitParam.y にセット ://someiyoshino.info/entry/20171231/1514692823
lLightLitParam.y = dot( lLightHalfVec, lViewNrm ) ;
// スペキュラ反射率を lLightLitParam.w にセット
lLightLitParam.w = g_Common.Material.Power ;
// ライト計算
lLightLitDest = lit( lLightLitParam.x, lLightLitParam.y, lLightLitParam.w ) ;
// ライトディフューズカラーとライトスペキュラカラーの角度減衰計算 =======( 終了 )
// カラー計算 ===========================================================( 開始 )
// ディフーズライト蓄積値 += 距離・スポットライト角度減衰値 * ( ディフーズ角度減衰計算結果 * マテリアルディフューズカラー * ライトのディフーズカラー + ライトのアンビエントカラーとマテリアルのアンビエントカラーを乗算したもの )
lTotalDiffuse += lLightGen * ( lLightLitDest.y * g_Common.Light[ 2 ].Diffuse * g_Common.Material.Diffuse.xyz + g_Common.Light[ 2 ].Ambient.xyz ) ;
// スペキュラライト蓄積値 += スペキュラ角度減衰計算結果 * 距離・スポットライト減衰 * ライトのスペキュラカラー
lTotalSpecular += lLightGen * lLightLitDest.z * g_Common.Light[ 2 ].Specular ;
// カラー計算 ===========================================================( 終了 )
// スポットライトの処理 *************************************************************( 終了 )
// ライトの処理 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++( 終了 )
// 出力パラメータセット ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++( 開始 )
//[★違い] <剛体メッシュのディレクショナルライトとポイントライトあり描画> NormalMesh_DirPointLightVS.fx
// ディフューズカラー = ディフューズライト蓄積値 + マテリアルのアンビエントカラーとグローバルアンビエントカラーを乗算したものとマテリアルエミッシブカラーを加算したもの
VSOutput.Diffuse.xyz = lTotalDiffuse + g_Common.Material.Ambient_Emissive.xyz ;
// ディフューズアルファはマテリアルのディフューズカラーのアルファをそのまま使う
VSOutput.Diffuse.w = g_Common.Material.Diffuse.w ;
// スペキュラカラー = スペキュラライト蓄積値 * マテリアルのスペキュラカラー
VSOutput.Specular.xyz = lTotalSpecular * g_Common.Material.Specular.xyz ;
// スペキュラアルファはマテリアルのスペキュラカラーのアルファをそのまま使う
VSOutput.Specular.w = g_Common.Material.Specular.w ;
// テクスチャ座標変換行列による変換を行った結果のテクスチャ座標をセット
VSOutput.TexCoords0.x = dot( VSInput.TexCoords0, g_OtherMatrix.TextureMatrix[ 0 ][ 0 ] ) ;
VSOutput.TexCoords0.y = dot( VSInput.TexCoords0, g_OtherMatrix.TextureMatrix[ 0 ][ 1 ] ) ;
// 出力パラメータセット ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++( 終了 )
// 出力パラメータを返す
return VSOutput ;
}
|
Re: シェーダーのg_Common.Light[ 0 ],[ 1 ],[ 2 ] がCreate〜LightHandと非合致 ( No.2 ) |
- 名前:yoneymyquestion 日時:2024/03/09 19:29
-----------<< 3 >> ピクセルシェーダ全体------------------------------
// ピクセルシェーダーの入力
struct PS_INPUT
{
float4 Diffuse : COLOR0 ;
float4 Specular : COLOR1 ;
float2 TexCoords0 : TEXCOORD0 ;
} ;
// ピクセルシェーダーの出力
struct PS_OUTPUT
{
float4 Color0 : SV_TARGET0 ; // 色
} ;
// 定数バッファピクセルシェーダー基本パラメータ
struct DX_D3D11_PS_CONST_BUFFER_BASE
{
float4 FactorColor ; // アルファ値等
float MulAlphaColor ; // カラーにアルファ値を乗算するかどうか( 0.0f:乗算しない 1.0f:乗算する )
float AlphaTestRef ; // アルファテストで使用する比較値
float2 Padding1 ;
int AlphaTestCmpMode ; // アルファテスト比較モード( DX_CMP_NEVER など )
int3 Padding2 ;
float4 IgnoreTextureColor ; // テクスチャカラー無視処理用カラー
} ;
// 基本パラメータ ://dxlib.xsrv.jp/cgi/patiobbs/patio.cgi?mode=view&no=4904
cbuffer cbD3D11_CONST_BUFFER_PS_BASE : register( b1 )
{
DX_D3D11_PS_CONST_BUFFER_BASE g_Base ;
} ;
SamplerState g_DiffuseMapSampler : register( s0 ) ; // ディフューズマップテクスチャ
Texture2D g_DiffuseMapTexture : register( t0 ) ; // ディフューズマップテクスチャ
// main関数
PS_OUTPUT main( PS_INPUT PSInput )
{
PS_OUTPUT PSOutput ;
float4 TextureDiffuseColor ;
// テクスチャカラーの読み込み
TextureDiffuseColor = g_DiffuseMapTexture.Sample( g_DiffuseMapSampler, PSInput.TexCoords0 ) ;
// 出力カラー = ディフューズカラー * テクスチャカラー + スペキュラカラー
PSOutput.Color0 = PSInput.Diffuse * TextureDiffuseColor + PSInput.Specular ;
// 出力アルファ = ディフューズアルファ * テクスチャアルファ * 不透明度
PSOutput.Color0.a = PSInput.Diffuse.a * TextureDiffuseColor.a * g_Base.FactorColor.a ;
// 出力パラメータを返す
return PSOutput ;
}
|
Re: シェーダーのg_Common.Light[ 0 ],[ 1 ],[ 2 ] がCreate〜LightHandと非合致 ( No.3 ) |
- 名前:yoneymyquestion 日時:2024/03/09 19:33
-----------<< 4 >> 実行コード全体------------------------------
[main.cpp]
#include "DxLib.h"
#include <assert.h>
#include <vector>
#include <string>
struct Transform {
Transform(VECTOR pos = VGet(0.0f, 0.0f, 0.0f), VECTOR rot = VGet(0.0f, 0.0f, 0.0f), VECTOR scale = VGet(1.0f, 1.0f, 1.0f))
: position{ pos }, rotation{ rot }, scale{ scale } {}
VECTOR position;
VECTOR rotation;
VECTOR scale;
virtual ~Transform() {}
};
struct EditCamera
{
float x = 0.f, y = 0.0f, z = -100.f;
float VRotate = 0.0f, HRotate = 0.0f, TRotate = 0.0f;
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// ウインドウモードで起動
ChangeWindowMode(TRUE);
// DXライブラリの初期化
if (DxLib_Init() < 0)
{
// エラーが発生したら直ちに終了
return -1;
}
SetMouseDispFlag(TRUE);// ここをFALSEにするとマウスカーソル非表示
//表示しているスクリーンの後ろで隠れて次に描く画像を先に描くモード
// これとペアでScreenFlip();でつぎのページと入れ替えでちらつきを防ぐ
SetDrawScreen(DX_SCREEN_BACK);
SetUseTransColor(FALSE); // 画像の指定色を透過する機能を無効化
ScreenFlip();
int controlLight = -1; // コントロール中のライト
MATERIALPARAM Material;
float difR = 1.0f;
float difG = 1.0f;
float difB = 1.0f;
float difA = 0.0f;
float speR = 1.0f;
float speG = 0.0f;
float speB = 0.0f;
float speA = 0.0f;
float ambR = 0.0f;
float ambG = 1.0f;
float ambB = 0.0f;
float ambA = 0.0f;
float emiR = 0.0f;
float emiG = 0.0f;
float emiB = 1.0f;
float emiA = 0.0f;
float pow = 0.5;
// マテリアルの自己発光色を設定 ://dxlib.xsrv.jp/function/dxfunc_3d_draw.html#R14N11
Material.Diffuse = GetColorF(difR, difG, difB, difA); //[ディフューズ反射]はライトが持つディフューズ色の最大反射量 オブジェクトのディフューズ反射が0だったら、どれだけ強烈なライトを当てても光は反射してこなくなる 反射なのでライトの方向が重要 太陽を背にして平たい本を見ると、一番明るく見えますが 本を傾けると暗くなる 太陽光の差す方向に対して本の表面の「法線」の角度が広くなるから 法線の無い頂点はどうなの?となりますが、この場合ディフューズ色は一切反射せず 法線が関係する反射(Diffuse Specular)は0と計算される
Material.Specular = GetColorF(speR, speG, speB, speA); //[スペキュラ反射]は輝く効果を出す反射 ライト自体もスペキュラ色を持つ マテリアルにスペキュラ反射があるとライトのスペキュラ色をより強く反射する
Material.Ambient = GetColorF(ambR, ambG, ambB, ambA); //[アンビエント反射]はライトが持つアンビエント色の最大反射量 「環境光」と呼ばれ、光が当たらない部分へ間接的に当たる光の強さを意味する アンビエント反射は方向に関係なく ライトが当たる範囲のポリゴンにアンビエント色を与える ただし減衰があり 遠くにあるものは少ししか光をもらえない 減衰が無いディレクショナルライトの場合 すべてのポリゴンが等しい強さのアンビエント色を貰う
Material.Emissive = GetColorF(emiR, emiG, emiB, emiA); //[エミッション]は自己発光(アンビエントはライトの持つアンビエント色の反射量だがエミッションはライト一切関係無しの自己発光)
Material.Power = 50.0f * pow; //[減衰強度] スペキュラ反射はライトと法線の角度によってその強度が鋭く変わり 角度が狭いと強く反射 少し角度が広くなると急に反射量が減る この減衰強度は「Power」で変えることができる
DxLib::SetMaterialParam(Material); //[参考] ://marupeke296.com/DXG_No42_HowShouldISetLight.html
// 光の明暗計算を有効に
DxLib::SetUseLighting(TRUE);
// 標準ライトを無効にする
SetLightEnable(FALSE);
// ★g_Common.Light[ 0 ]
// ディレクショナルライトを作成する
int DirLightHandle = CreateDirLightHandle(VGet(0.0f, 0.0f, 1.0f));
// ★g_Common.Light[ 1 ]
// ポイントライトを作成する
int PointLightHandle = CreatePointLightHandle(VGet(0.0f, 0.0f, 0.0f), 7000.0f, 1.016523f, 0.000100f, 0.000010f);
// ★g_Common.Light[ 2 ]
// スポットライトを作成する
int SpotLightHandle = CreateSpotLightHandle(VGet(0.0f, 0.0f, 0.0f), VGet(0.0f, -1.0f, 0.0f), 0.7f, 0.6f, 1000.0f, 0.391586f, 0.001662f, 0.0f);
controlLight = DirLightHandle;
//奥行0.1〜1000までをカメラの描画範囲とする
DxLib::SetCameraNearFar(0.1f, 5000.0f);
DxLib::SetUseZBuffer3D(TRUE);
// Zバッファへの書き込みを有効にする
DxLib::SetWriteZBuffer3D(TRUE);
// バックカリングするか?(裏面になっているポリゴンを書かない処理)
DxLib::SetUseBackCulling(TRUE);
Transform transform;
int texfile = LoadGraph("Image/Cube.png");
// 頂点シェーダーを読み込む
int VertexShaderHandle = LoadVertexShader("Shader/TestVS.vso");
// ピクセルシェーダーを読み込む
int PixelShaderHandle = LoadPixelShader("Shader/MouseClickPolyShader.pso");
EditCamera camera;
int MouseX = -1, MouseY = -1;
int currentMouse; // 現在のマウス状態
float MouseWheel = 0;
// ESCキーが押されるまでループ
while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
{
// 画面を初期化
ClearDrawScreen();
// マウスの位置を取得
GetMousePoint(&MouseX, &MouseY);
currentMouse = GetMouseInput(); // マウス状態を得る
MouseWheel = GetMouseWheelRotVolF(); // マウスのホイール回転量を更新
if (MouseWheel != 0.0f) // マウスのホイールをグリグリしたとき
{
// スクリーン(X,Y)からマウスの指すワールド座標(X,Y,Z)を求める
VECTOR currentPos = DxLib::ConvScreenPosToWorldPos(VGet((float)MouseX, (float)MouseY, 0.0f));
// カメラからマウスの指す位置への方向の単位ベクトル(ノルム)を求める
VECTOR camNorm = DxLib::VNorm(DxLib::VGet(currentPos.x - camera.x, currentPos.y - camera.y, currentPos.z - camera.z));
float camSpeed = 5;
// 求めた単位ベクトル×カメラのスピードぶんカメラの位置を移動
camera.x += camNorm.x * MouseWheel * camSpeed;
camera.y += camNorm.y * MouseWheel * camSpeed;
camera.z += camNorm.z * MouseWheel * camSpeed;
}
if (CheckHitKey(KEY_INPUT_P))
{
controlLight = PointLightHandle;
}
else if (CheckHitKey(KEY_INPUT_S))
{
controlLight = SpotLightHandle;
}
else if (CheckHitKey(KEY_INPUT_D))
{
controlLight = DirLightHandle;
}
// カメラの位置と回転値をセット、カメラの位置は原点
DxLib::SetCameraPositionAndAngle(
DxLib::VGet(camera.x, camera.y, camera.z),
camera.VRotate * DX_PI_F / 180.0f, camera.HRotate * DX_PI_F / 180.0f, camera.TRotate * DX_PI_F / 180.0f);
bool isLightMove = false;
VECTOR lightPos = (controlLight == -1) ? GetLightPosition() : GetLightPositionHandle(controlLight);
VECTOR nextPos = VGet(lightPos.x, lightPos.y, lightPos.z);
VECTOR nextDir = VGet(0, 0, 0);
if (GetJoypadInputState(DX_INPUT_KEY_PAD1) & (PAD_INPUT_LEFT))
{
nextPos.x += -1;
nextDir = VGet(-1, 0, 0);
isLightMove = true;
}
else if (GetJoypadInputState(DX_INPUT_KEY_PAD1) & (PAD_INPUT_RIGHT))
{
nextPos.x += 1;
nextDir = VGet(1, 0, 0);
isLightMove = true;
}
if (GetJoypadInputState(DX_INPUT_KEY_PAD1)& (PAD_INPUT_UP))
{
nextPos.z += 1;
nextDir = VGet(0, 0, 1);
isLightMove = true;
}
else if (GetJoypadInputState(DX_INPUT_KEY_PAD1) & (PAD_INPUT_DOWN))
{
nextPos.z += -1;
nextDir = VGet(0, 0, -1);
isLightMove = true;
}
if (CheckHitKey(KEY_INPUT_PGUP)) // PageUpボタン
{
nextPos.y += 1;
nextDir = VGet(0, 1, 0);
isLightMove = true;
}
else if (CheckHitKey(KEY_INPUT_PGDN)) // PageDownボタン
{
nextPos.y += -1;
nextDir = VGet(0, -1, 0);
isLightMove = true;
}
// ライトの位置の更新
if (isLightMove)
{
if (controlLight == -1)
{
SetLightPosition(nextPos);
SetLightDirection(nextDir);
}
else
{
SetLightPositionHandle(controlLight, nextPos);
SetLightDirectionHandle(controlLight, nextDir);
}
}
(つづく 投稿文字数オーバー).......
|
Re: シェーダーのg_Common.Light[ 0 ],[ 1 ],[ 2 ] がCreate〜LightHandと非合致 ( No.4 ) |
- 名前:yoneymyquestion 日時:2024/03/09 19:34
(つづき 投稿文字数オーバーのため分割投稿).......
int textureHandle = texfile;
// 使用するテクスチャを0番にセット
DxLib::SetUseTextureToShader(0, textureHandle);
// 使用する頂点シェーダーをセット
DxLib::SetUseVertexShader(VertexShaderHandle);
// 使用するピクセルシェーダーをセット
DxLib::SetUsePixelShader(PixelShaderHandle);
const float u0 = 0.0f; const float v0 = 0.0f;
const float u1 = 1.0f; const float v1 = 1.0f;
float x = transform.position.x; float y = transform.position.y; float z = transform.position.z;
float width = 1.0f; float height = 1.0f;
float scaleX = 100.0f; float scaleY = 100.0f;
const float Deg2Rad = DX_PI_F / 180.0f; // 角度(単位:°度)からラジアン(単位:rad)へ変換する係数
const float xRotate = transform.rotation.x * Deg2Rad; const float yRotate = transform.rotation.y * Deg2Rad; const float zRotate = transform.rotation.z * Deg2Rad;
const float centerX = x + width * scaleX / 2; // 四角形の中心(x+width/2,y-height/2,z)
const float centerY = y - height * scaleY / 2;
MATRIX TransformMatrix = MGetTranslate(VGet(-centerX, -centerY, -z)); // 四角形の中心を 原点(0,0,0)に一旦移動させてから回転させる
TransformMatrix = MMult(TransformMatrix, MGetRotZ(zRotate));
TransformMatrix = MMult(TransformMatrix, MGetRotX(xRotate));
TransformMatrix = MMult(TransformMatrix, MGetRotY(yRotate));
TransformMatrix = MMult(TransformMatrix, MGetTranslate(VGet(centerX, centerY, z))); // 四角形の中心ぶんだけ平行移動させて戻す
// 四角ポリゴンのインデックス順 [UIのy方向は下だが3D空間上は上が+方向なのでheightを-1方向に]
// 左手系(時計回りが表面)
// 0-1 4 (x,y) 0-1 4 (x + width * scale, y)
// |/ /| -> |/ /|
// 2 3-5 (x, y - height * scale) 2 3-5 (x + width * scale, y - height * scale)
std::vector<VERTEX3DSHADER> rectVertex;
rectVertex.resize(4);
std::vector<unsigned int> rectIndex;
rectIndex.resize(6); // 4頂点のうち 右上(1と4)と左下(2と3)は同位置に2つ頂点を使う(三角形2つぶんのため) 4頂点 + 2被り = 6
// 4頂点分のデータをセット
// 左上(0)
rectVertex[0].pos = VTransform(VGet(x, y, z), TransformMatrix);
rectVertex[0].norm = VGet(0.0f, 0.0f, -1.0f);
rectVertex[0].dif = GetColorU8(255, 255, 255, 255);
rectVertex[0].spc = GetColorU8(255, 255, 255, 255);
rectVertex[0].u = u0;
rectVertex[0].v = v0;
rectVertex[0].su = 0.0f;
rectVertex[0].sv = 0.0f;
// 右上(1と4)
rectVertex[1].pos = VTransform(VGet(x + width * scaleX, y, z), TransformMatrix);
rectVertex[1].norm = VGet(0.0f, 0.0f, -1.0f);
rectVertex[1].dif = GetColorU8(255, 255, 255, 255);
rectVertex[1].spc = GetColorU8(255, 255, 255, 255);
rectVertex[1].u = u1;
rectVertex[1].v = v0;
rectVertex[1].su = 0.0f;
rectVertex[1].sv = 0.0f;
// 左下(2と3)
rectVertex[2].pos = VTransform(VGet(x, y - height * scaleY, z), TransformMatrix);
rectVertex[2].norm = VGet(0.0f, 0.0f, -1.0f);
rectVertex[2].dif = GetColorU8(255, 255, 255, 255);
rectVertex[2].spc = GetColorU8(255, 255, 255, 255);
rectVertex[2].u = u0;
rectVertex[2].v = v1;
rectVertex[2].su = 0.0f;
rectVertex[2].sv = 0.0f;
// 右下(5)
rectVertex[3].pos = VTransform(VGet(x + width * scaleX, y - height * scaleY, z), TransformMatrix);
rectVertex[3].norm = VGet(0.0f, 0.0f, -1.0f);
rectVertex[3].dif = GetColorU8(255, 255, 255, 255);
rectVertex[3].spc = GetColorU8(255, 255, 255, 255);
rectVertex[3].u = u1;
rectVertex[3].v = v1;
rectVertex[3].su = 0.0f;
rectVertex[3].sv = 0.0f;
// 2ポリゴン分のインデックス順データをセット
rectIndex[0] = 0;
rectIndex[1] = 1; // 0-1 4
rectIndex[2] = 2; // |/ /|
rectIndex[3] = 2; // 2 3-5
rectIndex[4] = 1;
rectIndex[5] = 3;
// 三角形の2辺のベクトルの外積から法線を計算(法線がないとライトの光の反射方向をシェーディングできないから)
{
// 外積 a×b cross_a_b を求める ://examist.jp/mathematics/space-vector/vector-gaiseki/
const VECTOR a = VSub(rectVertex[1].pos, rectVertex[0].pos);
const VECTOR b = VSub(rectVertex[2].pos, rectVertex[0].pos);
// 左手系(表面は時計回り) 右手系と左手系では裏面の時計回りと反時計回りが変わる
const VECTOR cross1_2 = VCross(a, b);
// 右手系(表面は反時計回り)
//const VECTOR cross2_1 = VCross(b, a);
// 単位ベクトル(ノルム)に直す [単位ベクトル]は√(x*x + y*y + z*z) = 1(大きさが1)となる
const VECTOR norm1_2 = VNorm(cross1_2); // 左手系(表面は時計回り)
rectVertex[0].norm = norm1_2; rectVertex[1].norm = norm1_2; rectVertex[2].norm = norm1_2; rectVertex[3].norm = norm1_2;
//const VECTOR norm2_1 = VNorm(cross2_1); // 右手系(表面は反時計回り)
//rectVertex[0].norm = norm2_1; rectVertex[1].norm = norm2_1; rectVertex[2].norm = norm2_1; rectVertex[3].norm = norm2_1;
}
DxLib::DrawPolygon32bitIndexed3DToShader(rectVertex.data(), rectVertex.size(), rectIndex.data(), 2); // 三角形ポリゴン2枚を描画
// ライトの向き 標準ライト:GetLightDirection() 別のライト:GetLightDirectionHandle
VECTOR lightDir = (controlLight == -1) ? DxLib::GetLightDirection() : DxLib::GetLightDirectionHandle(controlLight);
// ライトの位置 標準ライト:GetLightPosition() 別のライト:GetLightPositionHandle
lightPos = (controlLight == -1) ? DxLib::GetLightPosition() : DxLib::GetLightPositionHandle(controlLight);
int lightType = (controlLight == -1) ? DxLib::GetLightType() : DxLib::GetLightTypeHandle(controlLight);
// 画面に標準ライトのタイプを描画
std::string TypeName;
switch (lightType)
{
case DX_LIGHTTYPE_DIRECTIONAL: TypeName = "Directional"; break;
case DX_LIGHTTYPE_POINT: TypeName = "Point"; break;
case DX_LIGHTTYPE_SPOT: TypeName = "Spot"; break;
}
DxLib::DrawFormatString(0, 200, GetColor(255, 255, 255), "LightType %s", TypeName.c_str());
if (lightType == DX_LIGHTTYPE_DIRECTIONAL) // [ディレクショナルライト]
{ // ライトの円錐を描画 [ディレクショナルライト] ://dxlib.xsrv.jp/function/dxfunc_3d_light.html#R13N1
float coneScale = 30.0f; // lightPos + lightDir * coneScale
lightPos = VGet(0.0f, 0.0f, 0.0f);
DxLib::DrawCone3D(lightPos, VAdd(lightPos, VScale(lightDir, coneScale)), 10 * 2 * DX_PI_F, 8, GetColor(255, 255, 255), GetColor(255, 255, 255), FALSE);
//DrawCone3D(lightPos, VAdd(lightPos, VScale(lightDir, coneScale)), OutAngle * 2 * DX_PI_F, 8, GetColor(255, 255, 255), GetColor(255, 255, 255), FALSE);
DxLib::DrawFormatString(0, 200 + 30, GetColor(255, 255, 255), "Direction %f %f %f", lightDir.x, lightDir.y, lightDir.z);
}
else if (lightType == DX_LIGHTTYPE_POINT) // [ポイントライト]
{
// [ポイントライト] 有効距離と距離減衰パラメータ ://dxlib.xsrv.jp/function/dxfunc_3d_light.html#R13N2
float Range; // ポイントライトの影響最大距離:距離以上の座標にある頂点は、 例え距離減衰計算の結果が0ではなくてもライトの影響は無くなる
//ライトの影響力(%) = 100.0f / ( Atten0 + Atten1 * d + Atten2 * d * d ) [d = ライトから頂点への距離]
// Attenは率を除算する値ですので、 非常に小さな値でも物凄くライトの影響範囲が狭まる
float Atten0; // Atten0 はライトと頂点の距離に関係なく減衰する率を指定する引数
float Atten1; // Atten1 はライトの距離に比例して減衰する率
float Atten2; // Atten2 はライトの距離の二乗に比例して減衰する率
if (controlLight == -1)
DxLib::GetLightRangeAtten(&Range, &Atten0, &Atten1, &Atten2);
else
DxLib::GetLightRangeAttenHandle(controlLight, &Range, &Atten0, &Atten1, &Atten2);
// ライトの位置に球を描画 [ポイントライト]
float scale = 10.0f;
DxLib::DrawSphere3D(lightPos, scale, 4, GetColor(255, 255, 255), GetColor(255, 255, 255), FALSE);
DxLib::DrawFormatString(0, 200 + 90, GetColor(255, 255, 255), "Range %f", Range);
DxLib::DrawFormatString(0, 200 + 120, GetColor(255, 255, 255), "Attenuation0 %f", Atten0);
DxLib::DrawFormatString(0, 200 + 150, GetColor(255, 255, 255), "Attenuation1 %f", Atten1);
DxLib::DrawFormatString(0, 200 + 180, GetColor(255, 255, 255), "Attenuation2 %f", Atten2);
}
else if (lightType == DX_LIGHTTYPE_SPOT) // [スポットライト]
{
// ライトの照射角度パラメータ 標準ライト:GetLightAngle() 別のライト:GetLightAngleHandle
float OutAngle; // スポットライトの影響角度(有効な値は 0.0f 〜 DX_PI_F) スポットライトの向きに対してこの引数で指定する角度以上の頂点にはライトの影響はありません。
float InAngle; // スポットライトの影響が減衰を始める角度(有効な値は 0.0f 〜 OutAngle) スポットライトが OutAngle の角度まで100%の影響を与えて、 そこから急に影響が無い状態になりますと不自然に見えるかもしれないので、そんなときはこの引数でスポットライトの影響が弱まり始める角度を指定 スポットライトの向きに対してこの引数で指定する角度以上で且つ OutAngle 以下の場合はライトの影響が100%ではなくなります
if (controlLight == -1)
DxLib::GetLightAngle(&OutAngle, &InAngle);
else
DxLib::GetLightAngleHandle(controlLight, &OutAngle, &InAngle);
float Range; // スポットライトの影響最大距離:距離以上の座標にある頂点は、 例え距離減衰計算の結果が0ではなくてもライトの影響は無くなる
//ライトの影響力(%) = 100.0f / ( Atten0 + Atten1 * d + Atten2 * d * d ) [d = ライトから頂点への距離]
// Attenは率を除算する値ですので、 非常に小さな値でも物凄くライトの影響範囲が狭まる
float Atten0; // Atten0 はライトと頂点の距離に関係なく減衰する率を指定する引数
float Atten1; // Atten1 はライトの距離に比例して減衰する率
float Atten2; // Atten2 はライトの距離の二乗に比例して減衰する率
if (controlLight == -1)
DxLib::GetLightRangeAtten(&Range, &Atten0, &Atten1, &Atten2);
else
DxLib::GetLightRangeAttenHandle(controlLight, &Range, &Atten0, &Atten1, &Atten2);
// ライトの位置に円錐を描画 [スポットライト] ://dxlib.xsrv.jp/function/dxfunc_3d_light.html#R13N3
float coneScale = 15.0f; // lightPos + lightDir * coneScale
DxLib::DrawCone3D(lightPos, VAdd(lightPos, VScale(lightDir, coneScale)), InAngle * 2 * DX_PI_F, 8, GetColor(255, 255, 255), GetColor(255, 255, 255), FALSE);
DxLib::DrawCone3D(lightPos, VAdd(lightPos, VScale(lightDir, coneScale)), OutAngle * 2 * DX_PI_F, 8, GetColor(255, 255, 255), GetColor(255, 255, 255), FALSE);
DxLib::DrawFormatString(0, 200 + 30, GetColor(255, 255, 255), "Direction %f %f %f", lightDir.x, lightDir.y, lightDir.z);
DxLib::DrawFormatString(0, 200 + 60, GetColor(255, 255, 255), "InOutAngle %f %f", InAngle, OutAngle);
DxLib::DrawFormatString(0, 200 + 90, GetColor(255, 255, 255), "Range %f", Range);
DxLib::DrawFormatString(0, 200 + 120, GetColor(255, 255, 255), "Attenuation0 %f", Atten0);
DxLib::DrawFormatString(0, 200 + 150, GetColor(255, 255, 255), "Attenuation1 %f", Atten1);
DxLib::DrawFormatString(0, 200 + 180, GetColor(255, 255, 255), "Attenuation2 %f", Atten2);
}
// 裏画面の内容を表画面に反映させる
ScreenFlip();
}
// キー入力待ちをする
WaitKey();
// DXライブラリの後始末
DxLib::DxLib_End();
// ソフトの終了
return 0;
}
|
Re: シェーダーのg_Common.Light[ 0 ],[ 1 ],[ 2 ] がCreate〜LightHandと非合致 ( No.5 ) |
- 名前:管理人 日時:2024/03/11 02:12
すみません、DXライブラリでは組み合わせによるシェーダー数の爆発をなるべく抑える為に
作成されたライトの順番に関わらず
ディレクショナルライト
↓
スポットライト
↓
ポイントライト
の順に並べ替えられますので、オリジナルのシェーダーを作成する場合はその前提で
処理を割り振ってみてください m(_ _;m
( なので、【1】と【2】が逆になるのは仕様となります )
|
|