Skip to content

Instantly share code, notes, and snippets.

@EternalTamago
Last active October 16, 2024 16:06
Show Gist options
  • Select an option

  • Save EternalTamago/b7750bb93836661f29616259c3c4d4ab to your computer and use it in GitHub Desktop.

Select an option

Save EternalTamago/b7750bb93836661f29616259c3c4d4ab to your computer and use it in GitHub Desktop.
Xenkoで3Dモデルの輪郭線を描画する
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SiliconStudio.Core.Mathematics;
using SiliconStudio.Xenko.Input;
using SiliconStudio.Xenko.Engine;
using SiliconStudio.Xenko.Rendering;
using SiliconStudio.Xenko.Rendering.Materials;
using SiliconStudio.Xenko.Rendering.Materials.ComputeColors;
namespace MyGame
{
// Xenko 2.1.0.3で動作を確認
// MaterialPassを使用
//
// ModelComponentを持ってるEntityに追加して使用する
// スペースキーで輪郭線有り無しを切り替える
public class OutlineScript : SyncScript
{
// 輪郭線が表示されてるかどうか
public bool IsOutlined = true;
// 輪郭線の色
public Color4 Color = new Color4(0f, 1f, 0f, 1f);
// 輪郭線の大きさ
public float Intensity = 0.01f;
// 表示切替用のキー
public Keys SwitchKey = Keys.Space;
private ModelComponent modelComponent;
private Material outlineMaterial;
// 色と大きさを指定して輪郭線用のマテリアルを作成
private Material CreateOutlineMaterial(Color4 color, float intensity)
{
var materialDescriptor = new MaterialDescriptor
{
Attributes = new MaterialAttributes
{
Displacement = new MaterialDisplacementMapFeature
{
DisplacementMap = new ComputeFloat(1f),
Intensity = new ComputeFloat(intensity),
ScaleAndBias = true,
Stage = DisplacementMapStage.Vertex,
},
DiffuseModel = new MaterialDiffuseLambertModelFeature(),
Diffuse = new MaterialDiffuseMapFeature
{
DiffuseMap = new ComputeColor(color),
},
CullMode = SiliconStudio.Xenko.Graphics.CullMode.Front,
},
};
return Material.New(GraphicsDevice, materialDescriptor);
}
// 輪郭線の大きさを変更
private void SetDisplacementIntensityValue(ParameterCollection parameters, float value)
{
// Parameters.Set(MaterialKeys.DisplacementIntensityValue, value)ではうまくいかない(?)
var keyInfo = parameters.ParameterKeyInfos.Where(k => k.Key.Name == "Material.DisplacementValue.i3").First();
Buffer.BlockCopy(BitConverter.GetBytes(value), 0, parameters.DataValues, keyInfo.Offset, sizeof(float));
}
public override void Start()
{
var intensity = IsOutlined ? Intensity: 0f;
modelComponent = Entity.Get<ModelComponent>();
outlineMaterial = CreateOutlineMaterial(Color, intensity);
foreach (var m in modelComponent.Model.Materials)
{
m.Material.Passes.Add(new MaterialPass(outlineMaterial.Passes[0].Parameters)
{
PassIndex = 1,
BlendState = null,
TessellationMethod = XenkoTessellationMethod.None,
IsLightDependent = true,
HasTransparency = false,
CullMode = SiliconStudio.Xenko.Graphics.CullMode.Front,
});
}
}
public override void Update()
{
if (Input.IsKeyPressed(SwitchKey))
{
IsOutlined = !IsOutlined;
var value = IsOutlined ? Intensity: 0f;
foreach (var m in modelComponent.Model.Materials)
{
SetDisplacementIntensityValue(m.Material.Passes[1].Parameters, value);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment