ディフューズ・スペキュラ光など、色の表現を追加する。
トゥーンシェーダ、スフィアマッピングを導入する。
マテリアルから必要な情報を取り出し、適切なテクスチャ座標の計算を行うことで、質感の表現ができます。
今回のソースはこちら
effect.fx
matrix World;
matrix View;
matrix Projection;
float3 ambientLight;
float4 matDiffuse;
float4 matAmbient;
float4 matSpecular;
float matAlpha;
float matSpecularity;
float3 lightDir;
float3 eyePos;
Texture2D normalTexture;
SamplerState normalSampler {};
Texture2D toonTexture;
SamplerState toonSampler {};
Texture2D sphTexture;
SamplerState sphSampler {};
Texture2D spaTexture;
SamplerState spaSampler {};
bool tex;
bool ton;
bool sph;
bool spa;
bool edge;
struct Vertexes {
float4 position : SV_Position;
float4 normal : NORMAL;
float2 uv : TEXCOORD;
};
struct OutVert {
float4 position : SV_Position;
float2 uv : TEXCOORD;
float4 diffuse : COLOR0;
float3 specular : COLOR1;
float2 toonCoord : TEXCOORD1;
float2 sphereCoord : TEXCOORD2;
};
struct Colors {
float3 diffuse;
float3 specular;
float2 toonCoord;
};
Colors CalcLight(float3 E, float3 N) {
Colors col = (Colors)0;
col.diffuse = ambientLight;
col.specular = 0;
float3 L = normalize(-lightDir);
float3 H = normalize(E + L);
float2 prt = lit(dot(N, L), dot(N, H), matSpecularity).yz;
col.specular += ambientLight * prt.y;
col.diffuse *= matDiffuse.rgb;
col.diffuse += matAmbient.rgb;
col.diffuse = saturate(col.diffuse);
col.specular *= matSpecular.rgb;
col.toonCoord.x = clamp(0.5f - dot(normalize(N), normalize(E)) * 0.5f, 0, 1);
col.toonCoord.y = clamp(0.5f - dot(normalize(N), normalize(L)) * 0.5f, 0, 1);
return col;
}
OutVert myVertexShader(Vertexes input) {
OutVert output = (OutVert)0;
float4 posW = mul(input.position, World);
float4 pos = mul(posW, View);
pos = mul(pos, Projection);
output.position = pos;
output.uv = input.uv;
float3 N = normalize(mul(input.normal, World)).xyz;
float3 subEye = eyePos - posW.xyz;
float3 E = normalize(subEye);
Colors light = CalcLight(E, N);
output.diffuse = float4(light.diffuse.rgb, matAlpha);
output.specular = light.specular;
output.toonCoord = light.toonCoord;
output.sphereCoord = float2(input.normal.x / 2 + 0.5f, input.normal.y / 2 + 0.5f);
return output;
}
float4 myPixelShader(OutVert input) : SV_Target {
float4 color = normalTexture.Sample(normalSampler, input.uv) * input.diffuse + float4(input.specular.rgb, 0);
if (sph) {
color.rgb *= sphTexture.Sample(sphSampler, input.sphereCoord).rgb;
}
if (spa) {
color.rgb += spaTexture.Sample(spaSampler, input.sphereCoord).rgb;
}
if (ton) {
color.rgb *= toonTexture.Sample(toonSampler, input.toonCoord).rgb;
}
return color;
}
technique10 myTechnique {
pass myPass {
SetVertexShader(CompileShader(vs_5_0, myVertexShader()));
SetPixelShader(CompileShader(ps_5_0, myPixelShader()));
}
}
##さいごに
調べながら色々ためしてみたのですが、なかなか思うようにはいかなかったため、シェーダ部分は色々なところからの寄せ集めです。
次回は、PMX読み込み・表示に取り掛かる予定です。