#UE4 #UE4Study CostomノードのHLSLで円を描く三平方の定理で円を色分け

三平方の定理で円を色分け

Code: return MyFunction(texCoord,resolution,R,A,B);

OutputType:Float4

Inputs: texCoord,resolution,R,A,B

Input File Paths: /Project/Circle.usf

pow(V,2.0)でVの2乗って意味

https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-pow

つかわないでみた。

float R2=p.x*p.x+p.y*p.y;//三平方の定理


//Circle.usf

//return MyFunction(texCoord,resolution,R,A,B);
float4 MyFunction(float2 texCoord,float2 resolution,float R,float4 A,float4 B)
{
	
	float2 p = (texCoord.xy * 2.0 - resolution) / min(resolution.x, resolution.y);
	//return float3(p.x,p.y,1.0);
	
    //float R=0.5;

    //float4 c = float4(1.0,1.0,1.0,1.0);// baseColor
    float4 c =A;// baseColor
    float R2=p.x*p.x+p.y*p.y;//三平方の定理
    //if(pow(p.x,2.0) + pow(p.y,2.0) <= R){
    if(R2 <= R){
       // c = float4(0.0,0.0,0.0,0.0); //circleColor
        c = B;//circleColor
    }
    return c;
}

参考

UE4 Shader MaterialのCustomノードが進化してincludeFilePathでのファイル参照ができるようになっていた件

失敗1、2020年になってCustomノードが安定してきたみたいで

constで宣言しておくとそのままMyFloat使える

Codeにreturn MyFloat;で使える。

CodeにMyreturn MyFunction();で関数を呼び出せる。

const static float3 MyFloat = float3(1.0,0.0,0.0);

float3 MyFunction()
{
	return float3(0.0,1.0,0.0);
}

TestOutput1 = float3(0,0,1);
return 0.0;

Additional Output :TestOutput1

OutputType CMOT Float1

コンパイルされて自動生成されたHLSLコードの中身は

エラーコードで出てくるこれは

/Engine/Generated/Material.ush

マテリアルエディタのメニュー「ウインドウ>シェーダーコード>HLSL コード」を選択。

すると HLSL コードのウインドウが開き、コンパイルされた全マテリアルの内容が HLSL で表示される。

このプロジェクトの作り方は

【UE4】USF(Unreal Shader File) をすぐに始める環境設定 Project編さん

でのShaderフォルダの読み込み設定が必要だった。。50個ぐらいエラーがでるので見ない方がいいかも

今回はプロジェクト名は:Shader_MatCustomにしたよ

プロジェクト設定でCPP

Shader_MatCustom.h

// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"

#include "Modules/ModuleManager.h"

class FShader_MatCustom : public IModuleInterface
{
public:
    virtual void StartupModule() override;
    virtual void ShutdownModule() override;


};

Shader_MatCustom.cpp

// Copyright Epic Games, Inc. All Rights Reserved.

#include "Shader_MatCustom.h"
#include "Modules/ModuleManager.h"

IMPLEMENT_PRIMARY_GAME_MODULE( FShader_MatCustom, Shader_MatCustom, "Shader_MatCustom" );//3つの書き換え


void FShader_MatCustom::StartupModule()
{
    FString ShaderDirectory = FPaths::Combine(FPaths::ProjectDir(), TEXT("Shader"));
    if (!AllShaderSourceDirectoryMappings().Contains("/Project"))
    {
        AddShaderSourceDirectoryMapping("/Project", ShaderDirectory);
    }

}

void FShader_MatCustom::ShutdownModule()
{
}

Shader_MatCustom.Build.cs

// Copyright Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;

public class Shader_MatCustom : ModuleRules  // ←クラス名リネーム
{
	public Shader_MatCustom(ReadOnlyTargetRules Target) : base(Target)  // ←クラス名リネーム
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
	
		PublicDependencyModuleNames.AddRange(new string[] {  //改行して展開した。
			"Core",
			"CoreUObject",
			"Engine",
			"InputCore",
			"RenderCore",  // ←追記
			"RHI"         // ←あとで必要になるので追記(パス追加に関係ない)
		});

		PrivateDependencyModuleNames.AddRange(new string[] {  });



		// Uncomment if you are using Slate UI
		// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
		
		// Uncomment if you are using online features
		// PrivateDependencyModuleNames.Add("OnlineSubsystem");

		// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
	}
}

VSでビルドをしてコンパイル

Shaderフォルダ作成

マテリアル作成

CustomNode作成

MyShader.usf作成

IncludeFilePathに/Project/MyShader.usf

MyShader.usf

const static float3 MyFloat = float3(1.0,0.0,0.0);

float3 MyFunction()
{
	return float3(0.0,1.0,0.0);
}

やっとうまくいったので

C++サンプルプロジェクトは丸ごとだ。.slnも入ってるよ

https://drive.google.com/file/d/1-ClY_v2cudLARAkMmAfPGrAnFndNnWIX/view?usp=sharing

参照

キンアジさんのところで見つけてしまった。

UE4 ShaderReaderProで1000円で安定したHLSL環境を手に入れた

失敗1,CustomNodeはUE4が落ちまくる。

失敗2,ShaderReader(フリー版は動きもしなかったが)

失敗3,エンジンにインストールなので仕事で使えるか不明

ここに入っている

C:\Program Files\Epic Games\UE_4.26\Engine\Plugins\Marketplace\ShaderReaderPro

成功、ShaderReaderProで1000円で安定したHLSL環境を手に入れた

VSCodeを使うことになることは必須みたい。.usf拡張子の編集をするのでテキストハイライトの対応関係でそうなる。

これでやりたい放題HLSLが書けるかもしれない。まだこんだけ

1,float MyVer1;するだけで入力ピンがでる。

2,ファイル参照からHLSLデータが読み込める。

float MyVer1;
float MyVer2;
float MyVer3;
float MyVer4;
return float4(MyVer1,MyVer2,MyVer3,MyVer4);

BeaTeacherさんの動画

参考

https://wgld.WebGL 開発支援サイト wgld.org

UE4 Single Layer Water Material 透明で、かつ光沢のあるマテリアル

プレヴューだとわからないが

メッシュプレビューだとわかる。 車のガラス面に使ってみた。

opacity 0.8でもあんまり透けない

BMW i8 Concept のプレヴュー

参考URL

https://docs.unrealengine.com/4.27/ja/RenderingAndGraphics/Materials/MaterialProperties/LightingModels/SingleLayerWater/

もっとやりかたがあった。

https://docs.unrealengine.com/4.27/en-US/RenderingAndGraphics/Materials/HowTo/Transparency/

作成したTransparency_Materialをコンテンツ ブラウザでダブルクリックして開きます。開いたら、 Translucencyカテゴリの[Details]パネルで、 [ Lighting Mode ]をVolumetric NonDirectionalからSurface TranslucencyVolumeに変更します。

すると

敵が追いかけてくるのが動かない?UE4 敵が追いかけてくる 単純なsimpleMovetoActor とNaviMesh

1,
プレイヤーに使ってるキャラクターを複製する。
レベルにおいてもエラーがない状態にする(ABPのフラグなど)

2,
ブループリント作成
ParentClass はAIContrallerで
BP_Skeleton_AI_Follow_Contrallerを作成する。

TickにsimpleMovetoActorをつないで
Controllerはself
Goalは Get Player Pawn でPlayer Index 0 にしておくだけ。

3,キャラクターのAI Controller Classに割り当てる。

4,NavMeshBoundsVolumeを移動範囲の床に重なるようにおいてあげて

再生で完成なはず

AdvancedLocomotion用のキャラのスキニングがやっとできてきた。

結局、無理なポーズはmayaに読み込んでそのポーズでスキニング調整しないとだめだった。

これでもできてるほうでもっとぐちゃぐちゃになってたので。

パンツの方のスキニングやらサイズやら調整したが、

からだのお尻のスキニングがぐちゃぐちゃだったからどうやってもだめだった。

お尻らへんの頂点を選択してスキンウェイトハンマーしたら変な形状を保とうとしなくなって

そのスキニングをパンツへコピーしたらできた。

SkinWeight Map export/import By FurcraeaTokyo Vol.02

SkinWeight Mapが画像じゃ精度がでないのでCSVにしたらうまくいった。

SkinWeight Map export

def GetSkinCluster(mesh):
	history = cmds.listHistory(mesh)
	for h in history:
		if cmds.objectType(h, isType='skinCluster'):
			return h
	return None
def GetSkinPercent(SkinCluster,vtx,mJoint):
    # vtx[100] の joint1 の weight を取得
    skinWeightV=cmds.skinPercent( SkinCluster, vtx, t= mJoint, query=True, value=True)
    return skinWeightV
    

def GetPolyCount(mesh):
	return cmds.polyEvaluate(mesh, v=True)
	

from PySide.QtCore import QByteArray, QBuffer, QIODevice, QFile
from PySide import QtGui



jointName="neckUpper|head"	
mesh="Design_model|Mesh|Face_Only_Beauty"
poly_count = GetPolyCount(mesh)
skin_cluster = GetSkinCluster(mesh)

imagePath="C:/Download/Game/AdvansedLocoMotionSystem/AnimMan/SkinWeight_neck01_to_Head/SkinWeight_002simple/render.png"


WeightArray=[]
for i in range(poly_count):
    vtx_attr_name = mesh + ".vtx[" + str(i) + "]"
    
    weightV=GetSkinPercent(skin_cluster,vtx_attr_name,jointName)
    WeightArray.append(weightV)


print("WeightArray="+str(WeightArray))
lenWeightArr=len(WeightArray)
print("lenWeightArr= "+str(lenWeightArr))

width=lenWeightArr
height=1
"""
#buffer = QImage(pageSize, QImage.Format_ARGB32)
buffer = QtGui.QImage(width,height,QtGui.QImage.Format_ARGB32_Premultiplied)
def setDrowPixels(MyImage,WeightArray,width,height):
    for x in range(0, width ):
        for y in range(0, height ):
            gValue=0
            if(y==0):
                gValue = WeightArray[x]   
            else:
                gValue = WeightArray[x*y]
            print("x= "+str(x)+" y= "+str(y)+" gValue= "+str(gValue))
            MyImage.setPixel( x, y, QtGui.QColor( gValue, gValue, gValue ).rgb() )
    return MyImage
buffer=setDrowPixels(buffer,WeightArray,width,height)
buffer.save(imagePath)
"""
CSVPath="C:/Download/Game/AdvansedLocoMotionSystem/AnimMan/SkinWeight_neck01_to_Head/SkinWeight_002simple/render.csv"
import codecs
fout = codecs.open(CSVPath, 'w', 'utf_8')
for i in range(poly_count):
    line = str(WeightArray[i])+","
    fout.write(line)

SkinWeight Map import

def GetSkinCluster(mesh):
	history = cmds.listHistory(mesh)
	for h in history:
		if cmds.objectType(h, isType='skinCluster'):
			return h
	return None
def GetSkinPercent(SkinCluster,vtx,mJoint):
    # vtx[100] の joint1 の weight を取得
    skinWeightV=cmds.skinPercent( SkinCluster, vtx, t= mJoint, query=True, value=True)
    return skinWeightV
    
def SetSkinPercent(SkinCluster,vtx,mJoint,skinWeightV):
    # vtx[100] の weight を. joint を指定して設定
    cmds.skinPercent( SkinCluster, vtx, transformValue=[(mJoint, skinWeightV)])
    

def GetPolyCount(mesh):
	return cmds.polyEvaluate(mesh, v=True)
	

from PySide.QtCore import QByteArray, QBuffer, QIODevice, QFile
from PySide import QtGui
"""
def image_to_array(imagePath):
    source = QtGui.QImage(imagePath)

    # バイナリとメタデータを読み込み
    #bits = source.constBits()
    width = source.width()
    height = source.height()
    print("width= "+str(width))
    print("height= "+str(height))
    '''
    return array of integer 0-255 rgba values
    [(r, g, b, a)]
    '''
    img = QtGui.QImage(width, height, QtGui.QImage.Format.Format_ARGB32)
    img.load(imagePath)
    colorArray = []
    kidoArray=[]
    for y in range(height):
        for x in range(width):
            color = QtGui.QColor()
            color.setRgba(img.pixel(x,y))
            colorArray.append(color.getRgb())
            kidoArray.append(color.getRgb()[0])
    return kidoArray
"""
def csv_to_array(CSVPath):
    import codecs
    fin  = codecs.open(CSVPath, 'r', 'utf_8')
    image_arr=[]
    for line in fin:
        #line=line.replace("\n","")
        #line=line.replace("\r","")
        #line=line.replace(',','')
        lineArr=line.split(',')
        for strV in lineArr:
            if(strV!=""):
                print("strV= "+strV)
                floatStrV=float(strV)
                image_arr.append(floatStrV)
    return image_arr
    
jointName="ALS_Mannequin|root|pelvis|spine_01|spine_02|spine_03|neck_01|head"	
mesh="ALS_Mannequin|Mesh|Face_Only_Beauty"
poly_count = GetPolyCount(mesh)
skin_cluster = GetSkinCluster(mesh)

#imagePath="C:/Download/Game/AdvansedLocoMotionSystem/AnimMan/SkinWeight_neck01_to_Head/SkinWeight_002simple/render.png"
CSVPath="C:/Download/Game/AdvansedLocoMotionSystem/AnimMan/SkinWeight_neck01_to_Head/SkinWeight_002simple/render.csv"


#image_arr=image_to_array(imagePath)
image_arr = csv_to_array(CSVPath)
print("image_arr= "+str(image_arr))


ArrLeng=len(image_arr)
for i in range(ArrLeng):
    vtx_attr_name = mesh + ".vtx[" + str(i) + "]"
    weightV=image_arr[i]
    #SetSkinPercent(skin_cluster,vtx_attr_name,jointName,1)
    SetSkinPercent(skin_cluster,vtx_attr_name,jointName,weightV)

元がこう

結果がこれ

ふーばっちりうまくいった様子。やったね!