//================================================================== // 水レンダリング //================================================================== #include "../../../Ext/xelib/Include/xelib/System/Draw/modeDef.h" //================================================================== // 定数 //================================================================== int g_use_normal_map; ///< 法線マップがあるか float g_alpha_control; ///< アルファコントロール Texture2D g_texture_normal; //================================================================== // 定数(2) ※シェーダー内のみ //================================================================== // サンプルステート SamplerState samLinear { Filter = MIN_MAG_MIP_LINEAR; AddressU = Wrap; AddressV = Wrap; }; SamplerState samPoint { Filter = MIN_MAG_MIP_POINT; AddressU = Wrap; AddressV = Wrap; }; SamplerState samPointMipLinear { Filter = MIN_MAG_POINT_MIP_LINEAR; AddressU = Wrap; AddressV = Wrap; }; //================================================================== // グローバル変数(設定) //================================================================== // マテリアル毎の設定 cbuffer cbSetUpMaterialData { // マテリアル float4 material_emission; // エミッションカラー float4 material_diffuse; // ディフューズカラー float4 material_ambient; // アンビエントカラー float material_specular; // スペキュラカラー float material_shininess; // 輝度 // カラー変更のパラメーター(nsModel::stChangeColorParam) float4 change_color_scale; // スケール float4 change_color_offset; // オフセット // UVスクロール float4 texture_transform; // テクスチャ変換行列 } // ライト(nsEffect::stLightParam) cbuffer cbLightParam { float4 light_diffuse; // ディヒューズカラー float4 light_specular; // スペキュラカラー float4 light_ambient; // アンビエントカラー float4 light_direction; // 方向(ビュー空間座標) int light_enable; // 有効かどうか float light_constant_attenuation; // 一定減衰率 }; cbuffer cbSetUpModelData { matrix g_matrix_w; // モデル→ワールド matrix g_matrix_wvp; // モデル→プロジェクション matrix g_matrix_wv; // モデル→ビュー //matrix g_matrix_shadow_wvp; // 投影シャドウ用モデル→プロジェクション } cbuffer cbSetUpNodeData { matrix g_matrix_model; // モデリング座標 } cbuffer cbSetUpSkinMesh { matrix g_matrix_bone_mtx0; matrix g_matrix_bone_mtx1; matrix g_matrix_bone_mtx2; matrix g_matrix_bone_mtx3; matrix g_matrix_bone_mtx4; matrix g_matrix_bone_mtx5; } // スキニングするボーン数 cbuffer cbWeightNum { int g_weight_num; } // バーテックスシェーダーモード int g_VSmode; //================================================================== // シェーダーの入力 //================================================================== // 頂点シェーダーの入力 struct VS_INPUT { float4 m_position : POSITION; // 座標 float3 m_normal: NORMAL; // 法線 float3 m_tangent: TANGENT; // 接線 float3 m_binormal: BINORMAL; // 接線 float4 m_color: COLOR; // 色 float2 m_uv: TEXCOORD; // UV float weight0: WEIGHTA; float weight1: WEIGHTB; float weight2: WEIGHTC; float weight3: WEIGHTD; float weight4: WEIGHTE; float weight5: WEIGHTF; }; // ピクセルシェーダーの入力 struct PS_INPUT { //※ TEXCOORD13まで。(合計16個まで?) float4 m_position : SV_POSITION; // 頂点座標 float4 m_color : COLOR; // 頂点カラー float2 m_uv : TEXCOORD0; // UV float3 m_position2 : TEXCOORD1; // ワールド座標 float3 vNormal : TEXCOORD2; float3 vTangent : TEXCOORD3; float3 vBinormal : TEXCOORD4; }; #define Z_MAX 40000.0f #define Z_MIN 1.0 // 動的双放物面環境マップ float4 CalcProj(float4 Pos) { float L = length(Pos.xyz); Pos.xyz /= L; Pos.xy /= Pos.z+1; float d = dot(Pos.xy,Pos.xy); Pos.z = L + d*d; Pos.z = (Pos.z - Z_MIN)/(Z_MAX-Z_MIN); Pos.w = 1; return Pos; } ///< サンプルステート SamplerState samAnisotropic { Filter = ANISOTROPIC; AddressU = Wrap; AddressV = Wrap; AddressW = CLAMP; }; SamplerState LinearSampler { Filter = MIN_MAG_MIP_LINEAR; AddressU = Clamp; AddressV = Clamp; }; // サンプリング float4 SampleTex( Texture2D tex, float2 uv) { return tex.Sample( samAnisotropic, uv); } // ブレンドステート BlendState SrcAlphaBlending { AlphaToCoverageEnable = FALSE; BlendEnable[0] = TRUE; SrcBlend = SRC_ALPHA; DestBlend = INV_SRC_ALPHA; BlendOp = ADD; SrcBlendAlpha = ONE; DestBlendAlpha = INV_SRC_ALPHA; BlendOpAlpha = ADD; RenderTargetWriteMask[0] = 0x0F; }; bool paraboloid = false; BlendState AddBlend { BlendEnable[0] = TRUE; BlendEnable[1] = TRUE; SrcBlend = ONE; DestBlend = ONE; BlendOp = ADD; }; //================================================================== // シェーダー //================================================================== // 頂点シェーダー PS_INPUT VS( VS_INPUT input, uniform bool paraboloid )///< paraboloidは PreRender でしかセットされていないのでfalseのままで使用(SetParabola) { // 出力 PS_INPUT output = (PS_INPUT)0; //--- // 頂点座標 // 頂点座標(入力) float4 vtx = input.m_position; vtx.w = 1.0f; // 念のため // モデリング座標 float4 model_pos = float4(0,0,0,0); model_pos = mul( vtx, g_matrix_model ); output.m_position = mul( model_pos, g_matrix_wvp ); //--- // 頂点カラー output.m_color = ( input.m_color ); output.m_color = output.m_color * change_color_scale + change_color_offset; //--- // UV // 変換 output.m_uv = input.m_uv + texture_transform.xy; //--- // ワールド座標 float4 _vtx = mul( model_pos, g_matrix_w ); output.m_position2 = _vtx.xyz; // ワールド座標系での頂点の位置 // 双放物面環境マップ if(paraboloid){ output.m_position = CalcProj(_vtx); } // 法線(入力) float3 nml = input.m_normal; // 正規化済み前提 float3 tan = input.m_tangent; // 正規化済み前提 float3 bin = input.m_binormal; // 正規化済み前提 //法線 { // 姿勢×カメラ変換 //model_pos = mul( vtx, g_matrix_model ); //output.m_position = mul( model_pos, g_matrix_wvp ); nml = mul( nml, (float3x3)g_matrix_model ); output.vNormal = normalize(mul( nml, (float3x3)g_matrix_w)); if( g_use_normal_map ){ tan = mul( tan, (float3x3)g_matrix_model ); output.vTangent = normalize(mul( tan, (float3x3)g_matrix_w)); bin = mul( bin, (float3x3)g_matrix_model ); output.vBinormal = normalize(mul( bin, (float3x3)g_matrix_w)); } } // //--- // // ビュー法線 // // // 法線(入力) // float3 nml = input.m_normal; // 正規化済み前提 // nml = mul( nml, (float3x3)g_matrix_model ); // output.vNormal = normalize(mul( nml, (float3x3)g_matrix_wv)); return output; } // 頂点シェーダー PS_INPUT VS_WEIGHT( VS_INPUT input, uniform bool paraboloid )///< paraboloidは PreRender でしかセットされていないのでfalseのままで使用(SetParabola) { // 出力 PS_INPUT output = (PS_INPUT)0; //--- // 頂点座標 // 頂点座標(入力) float4 vtx = input.m_position; vtx.w = 1.0f; // 念のため // 法線(入力) float3 nml = input.m_normal; // 正規化済み前提 float3 tan = input.m_tangent; // 正規化済み前提 float3 bin = input.m_binormal; // 正規化済み前提 // モデリング座標 float4 model_pos = float4(0,0,0,0); //スキンメッシュの場合 //if(skinMesh) { model_pos += input.weight0 * mul(vtx, g_matrix_bone_mtx0); output.vNormal += input.weight0 * mul(nml, (float3x3)g_matrix_bone_mtx0); if(g_use_normal_map) {output.vTangent += input.weight0 * mul(tan, (float3x3)g_matrix_bone_mtx0); output.vBinormal+= input.weight0 * mul(bin, (float3x3)g_matrix_bone_mtx0); } if(g_weight_num > 1){ model_pos += input.weight1 * mul(vtx, g_matrix_bone_mtx1); output.vNormal += input.weight1 * mul(nml, (float3x3)g_matrix_bone_mtx1); if(g_use_normal_map) {output.vTangent += input.weight1 * mul(tan, (float3x3)g_matrix_bone_mtx1); output.vBinormal+= input.weight1 * mul(bin, (float3x3)g_matrix_bone_mtx1); } if(g_weight_num > 2){ model_pos += input.weight2 * mul(vtx, g_matrix_bone_mtx2); output.vNormal += input.weight2 * mul(nml, (float3x3)g_matrix_bone_mtx2); if(g_use_normal_map) {output.vTangent += input.weight2 * mul(tan, (float3x3)g_matrix_bone_mtx2); output.vBinormal+= input.weight2 * mul(bin, (float3x3)g_matrix_bone_mtx2); } if(g_weight_num > 3){ model_pos += input.weight3 * mul(vtx, g_matrix_bone_mtx3); output.vNormal += input.weight3 * mul(nml, (float3x3)g_matrix_bone_mtx3); if(g_use_normal_map) {output.vTangent += input.weight3 * mul(tan, (float3x3)g_matrix_bone_mtx3); output.vBinormal+= input.weight3 * mul(bin, (float3x3)g_matrix_bone_mtx3); } if(g_weight_num > 4){ model_pos += input.weight4 * mul(vtx, g_matrix_bone_mtx4); output.vNormal += input.weight4 * mul(nml, (float3x3)g_matrix_bone_mtx4); if(g_use_normal_map) {output.vTangent += input.weight4 * mul(tan, (float3x3)g_matrix_bone_mtx4); output.vBinormal+= input.weight4 * mul(bin, (float3x3)g_matrix_bone_mtx4); } if(g_weight_num > 5){ model_pos += input.weight5 * mul(vtx, g_matrix_bone_mtx5); output.vNormal += input.weight5 * mul(nml, (float3x3)g_matrix_bone_mtx5); if(g_use_normal_map) {output.vTangent += input.weight5 * mul(tan, (float3x3)g_matrix_bone_mtx5); output.vBinormal+= input.weight5 * mul(bin, (float3x3)g_matrix_bone_mtx5); } }}}}} output.m_position = mul(model_pos, g_matrix_wvp); output.vNormal = normalize(mul(output.vNormal, (float3x3)g_matrix_w)); if(g_use_normal_map){ output.vTangent = normalize(mul( output.vTangent, (float3x3)g_matrix_w)); output.vBinormal = normalize(mul( output.vBinormal, (float3x3)g_matrix_w)); } } // else // { // // 姿勢×カメラ変換 // model_pos = mul( vtx, g_matrix_model ); // output.m_position = mul( model_pos, g_matrix_wvp ); // nml = mul( nml, (float3x3)g_matrix_model ); // output.vNormal = normalize(mul( nml, (float3x3)g_matrix_w)); // if(g_use_normal_map){ // tan = mul( tan, (float3x3)g_matrix_model ); // output.vTangent = normalize(mul( tan, (float3x3)g_matrix_w)); // // bin = mul( bin, (float3x3)g_matrix_model ); // output.vBinormal = normalize(mul( bin, (float3x3)g_matrix_w)); // } // } //--- // 頂点カラー output.m_color = ( input.m_color ); // 色変更、大した計算ではないので常に output.m_color = output.m_color * change_color_scale + change_color_offset; //--- // UV // スクロール output.m_uv = input.m_uv + texture_transform.xy; //--- // ビュー座標orグローバル座標 float4 _vtx = mul( model_pos, g_matrix_w ); output.m_position2 = _vtx.xyz; // ワールド座標 return output; } struct PS_OUTPUT { float4 m_color : SV_TARGET0; // ディフューズカラー+スペキュラ強度 float4 m_position : SV_TARGET1; // グローバル空間位置 }; struct PS_RENDER_OUTPUT { float4 m_waterPos : SV_TARGET0; float4 m_waterDiffuse : SV_TARGET1; float4 m_waterSpecular : SV_TARGET2; float4 m_waterReflect : SV_TARGET3; float4 m_waterNmlMap : SV_TARGET4; }; ///< 法線のみ出力 float4 PS_Normal( PS_INPUT input ) : SV_TARGET0 { float4 output = float4( 0.0f, 0.0f, 0.0f, 1.0f ); // 出力クリア //discard; #if 1 ///<---------------------------------法線マップ出力--------------------------------- // 接空間法線 float3 norm = input.vNormal; norm = normalize( norm ); if( g_use_normal_map ) // 法線マップあり { // テクスチャの値 float4 norm_col = 0; norm_col = SampleTex(g_texture_normal, input.m_uv ); ///<でこぼこのない平らな部分の色は(128,128,256) //if ( norm_col.r == 0.5f && norm_col.g == 0.5f && norm_col.b == 1.0f )///< 真上向いている法線は下地のを使用します //{ // discard; //} norm.r = (norm_col.r * 2.0 - 1.0); norm.g = -(norm_col.g * 2.0 - 1.0); norm.b = sqrt(saturate(1-(pow(norm.r, 2) + pow(norm.g, 2)))); //norm = ( norm * g_func_rate.m_normal_map ) + ( float3(0,0,1) * ( 1.0f - g_func_rate.m_normal_map ) ); // 機能レート float3x3 mtxRot; mtxRot[0] = normalize( input.vTangent ); mtxRot[1] = normalize( input.vBinormal ); mtxRot[2] = normalize( input.vNormal ); norm = normalize( mul( norm, mtxRot ) ); if( norm.y >= 0.997f ) discard; output = float4( (norm*0.5f + 0.5f), g_alpha_control );///< RGB変換 } #endif return output; } VertexShader vs[] = { CompileShader( vs_4_0, VS(false)),///< リジッド CompileShader( vs_4_0, VS_WEIGHT(false)),///< スキニング }; // 水面の法線バッファに法線だけ出力 technique10 NormalRender { pass p0 { SetVertexShader( vs[ g_VSmode ] ); SetGeometryShader( NULL ); SetPixelShader( CompileShader( ps_4_0, PS_Normal() ) ); //SetDepthStencilState( DisableDepthAndStencilMapNotEqual, OBJ_STENCIL_ID_MAP ); //SetBlendState( AddBlend, float4(0,0,0,0), 0xFFFFFFFF ); } }