虛幻4 添加變量控制UI的渲染,詳細教程。

首先更改UI的shader。

結構體:

Engine_Updating\Engine\Shaders\SlateShaderCommon.usf

struct VertexToPixelInterpolants
{
	float4 Position : SV_POSITION;
	float4 Color : COLOR0;
	float4 ClipOriginAndPos : TEXCOORD0;
	float4 ClipExtents : TEXCOORD1;
	float2 MaterialTexCoords : TEXCOORD2;
	float4 TextureCoordinates[NUM_SLATE_TEXCOORDS] : TEXCOORD3;
	<span style="background-color: rgb(255, 102, 102);">float DisableValue:TEXCOORD4;</span>
};

VertexShader:

Engine_Updating\Engine\Shaders\SlateVertexShader.usf

VertexToPixelInterpolants Main(
	in float4 InTextureCoordinates : ATTRIBUTE0,
	in float2 InMaterialTextureCoordinates : ATTRIBUTE1,
	in float2 InPosition : ATTRIBUTE2,
	in float2 InClipOrigin : ATTRIBUTE3,
	in float4 InClipExtents : ATTRIBUTE4,
	in float4 InColor : ATTRIBUTE5,
	<span style="color:#ff6666;">in float InDisableValue : ATTRIBUTE6</span>
#if USE_SLATE_INSTANCING
	, in float4 InstanceParam : ATTRIBUTE7
#endif
	)
{
	VertexToPixelInterpolants VOut = (VertexToPixelInterpolants)0;

	float4 WorldPosition = float4(InPosition.xy,0,1);

#if (!(ES2_PROFILE || ES3_1_PROFILE)) || USE_MATERIALS
	InColor.rgb = sRGBToLinear(InColor.rgb);
#endif

	float4 FinalVertexColor = InColor FCOLOR_COMPONENT_SWIZZLE;

	VOut.MaterialTexCoords = InMaterialTextureCoordinates;
	VOut.ClipOriginAndPos = float4(InClipOrigin, InPosition.xy);
	VOut.ClipExtents = InClipExtents;
	VOut.Color = FinalVertexColor;
	VOut.TextureCoordinates[0] = InTextureCoordinates;
	<span style="color:#ff6666;">VOut.DisableValue = InDisableValue;</span>


PixelShader:

Engine_Updating\Engine\Shaders\SlateElementPixelShader.usf

#if DRAW_DISABLED_EFFECT
	//desaturate
	float3 LumCoeffs = float3( 0.3, 0.59, .11 );
	float Lum = dot( LumCoeffs, OutColor.rgb );
<span style="color:#ff0000;">	OutColor.rgb = lerp( OutColor.rgb, float3(Lum,Lum,Lum), VIn.DisableValue );
	
	//float3 Grayish = {.1, .1, .1};

	//OutColor.rgb = lerp( OutColor.rgb, 3, clamp( distance( OutColor.rgb, Grayish ), 0, .8)  );</span>
#endif


然後更改代碼。

這是給UI Vetex Shader的參數,因爲我們加了一個參數,所以要在這裏添加一個對應的參數。

SlateCore/Public/Rendering/RenderingCommon.h

struct SLATECORE_API FSlateVertex
{
	/** Texture coordinates.  The first 2 are in xy and the 2nd are in zw */
	float TexCoords[4]; 

	/** Texture coordinates used as pass through to materials for custom texturing. */
	float MaterialTexCoords[2];

	/** Position of the vertex in window space */
	float Position[2];

	/** clip center/extents in render window space (window space with render transforms applied) */
	FSlateRotatedClipRectType ClipRect;

	/** Vertex color */
	FColor Color;

<span style="color:#ff0000;">	/**  **/
	float DisableValue;</span>

	<span style="color:#ff0000;">FSlateVertex();
	FSlateVertex( const FSlateRenderTransform& RenderTransform, const FVector2D& InLocalPosition, const FVector2D& InTexCoord, const FVector2D& InTexCoord2, const FColor& InColor, const FSlateRotatedClipRectType& InClipRect , float InDisableValue);
	FSlateVertex(const FSlateRenderTransform& RenderTransform, const FVector2D& InLocalPosition, const FVector2D& InTexCoord, const FColor& InColor, const FSlateRotatedClipRectType& InClipRect, float InDisableValue);
	FSlateVertex(const FSlateRenderTransform& RenderTransform, const FVector2D& InLocalPosition, const FVector4& InTexCoords, const FVector2D& InMaterialTexCoords, const FColor& InColor, const FSlateRotatedClipRectType& InClipRect, float InDisableValue);</span>
};

對應的構造函數我就不寫了,就是給DisableValue賦值。


然後在FSlateDrawElement裏面添加變量:

SlateCore/Public/Rendering/DrawElements.h

	FORCEINLINE const TOptional<FShortRect>& GetScissorRect() const { return ScissorRect; }

	/**/
	<span style="color:#ff0000;">FORCEINLINE float GetDisableValue() const { return DisableValue; }</span>
	
private:
	void Init(uint32 InLayer, const FPaintGeometry& PaintGeometry, const FSlateRect& InClippingRect, ESlateDrawEffect::Type InDrawEffects);


	static FVector2D GetRotationPoint( const FPaintGeometry& PaintGeometry, const TOptional<FVector2D>& UserRotationPoint, ERotationSpace RotationSpace );

private:
	FSlateDataPayload DataPayload;
	FSlateRenderTransform RenderTransform;
	FSlateRect ClippingRect;
	FVector2D Position;
	FVector2D LocalSize;
	float Scale;
	uint32 Layer;
	uint32 DrawEffects;
	EElementType ElementType;
	TOptional<FShortRect> ScissorRect;
	/**/
	<span style="color:#ff0000;">float DisableValue;</span>
};

這幾個函數添加參數:

	SLATECORE_API static void MakeBox( 
		FSlateWindowElementList& ElementList,
		uint32 InLayer, 
		const FPaintGeometry& PaintGeometry, 
		const FSlateBrush* InBrush, 
		const FSlateRect& InClippingRect, 
		ESlateDrawEffect::Type InDrawEffects = ESlateDrawEffect::None, 
		const FLinearColor& InTint = FLinearColor::White ,
		<span style="color:#ff0000;">float InDisableValue = 0.8);</span>

	SLATECORE_API static void MakeBox(
		FSlateWindowElementList& ElementList,
		uint32 InLayer, 
		const FPaintGeometry& PaintGeometry, 
		const FSlateBrush* InBrush, 
		const FSlateResourceHandle& InRenderingHandle, 
		const FSlateRect& InClippingRect, 
		ESlateDrawEffect::Type InDrawEffects = ESlateDrawEffect::None, 
		const FLinearColor& InTint = FLinearColor::White,
		<span style="color:#ff0000;">float InDisableValue = 0.8);</span>
	

然後MakeBox函數體裏面賦值就不寫了。

剩下的就是全局搜索FSlateVertex,把所有的構造FSlateVertex的地方,把FSlateDrawElement裏面變量傳進去。(不想使用默認的參數值)


改變CPP裏面定義的傳入參數。

SlateRHIRenderer/Private/SlateShaders.cpp

/************************************************************************/
/* FSlateVertexDeclaration                                              */
/************************************************************************/
void FSlateVertexDeclaration::InitRHI()
{
	FVertexDeclarationElementList Elements;
	uint32 Stride = sizeof(FSlateVertex);
	Elements.Add(FVertexElement(0, STRUCT_OFFSET(FSlateVertex, TexCoords), VET_Float4, 0, Stride));
	Elements.Add(FVertexElement(0, STRUCT_OFFSET(FSlateVertex, MaterialTexCoords), VET_Float2, 1, Stride));
	Elements.Add(FVertexElement(0, STRUCT_OFFSET(FSlateVertex, Position), VET_Float2, 2, Stride));
	Elements.Add(FVertexElement(0, STRUCT_OFFSET(FSlateVertex, ClipRect) + STRUCT_OFFSET(FSlateRotatedClipRectType, TopLeft), VET_Float2, 3, Stride));
	Elements.Add(FVertexElement(0, STRUCT_OFFSET(FSlateVertex, ClipRect) + STRUCT_OFFSET(FSlateRotatedClipRectType, ExtentX), VET_Float4, 4, Stride));
	Elements.Add(FVertexElement(0, STRUCT_OFFSET(FSlateVertex, Color), VET_Color, 5, Stride));
	<span style="color:#ff0000;">Elements.Add(FVertexElement(0, STRUCT_OFFSET(FSlateVertex, DisableValue), VET_Float1, 6, Stride));</span>

	VertexDeclarationRHI = RHICreateVertexDeclaration(Elements);
}

void FSlateVertexDeclaration::ReleaseRHI()
{
	VertexDeclarationRHI.SafeRelease();
}


/************************************************************************/
/* FSlateInstancedVertexDeclaration                                     */
/************************************************************************/
void FSlateInstancedVertexDeclaration::InitRHI()
{
	FVertexDeclarationElementList Elements;
	uint32 Stride = sizeof(FSlateVertex);
	Elements.Add(FVertexElement(0, STRUCT_OFFSET(FSlateVertex, TexCoords), VET_Float4, 0, Stride));
	Elements.Add(FVertexElement(0, STRUCT_OFFSET(FSlateVertex, MaterialTexCoords), VET_Float2, 1, Stride));
	Elements.Add(FVertexElement(0, STRUCT_OFFSET(FSlateVertex, Position), VET_Float2, 2, Stride));
	Elements.Add(FVertexElement(0, STRUCT_OFFSET(FSlateVertex, ClipRect) + STRUCT_OFFSET(FSlateRotatedClipRectType, TopLeft), VET_Float2, 3, Stride));
	Elements.Add(FVertexElement(0, STRUCT_OFFSET(FSlateVertex, ClipRect) + STRUCT_OFFSET(FSlateRotatedClipRectType, ExtentX), VET_Float4, 4, Stride));
	Elements.Add(FVertexElement(0, STRUCT_OFFSET(FSlateVertex, Color), VET_Color, 5, Stride));
	/**/
	<span style="color:#ff0000;">Elements.Add(FVertexElement(0, STRUCT_OFFSET(FSlateVertex, DisableValue), VET_Float1, 6, Stride));</span>

	Elements.Add(FVertexElement(1, 0, VET_Float4, 7, sizeof(FVector4), true));
	
	VertexDeclarationRHI = RHICreateVertexDeclaration(Elements);
}

最後一步

Slate/Private/Widgets/Images/SImage.cpp

int32 SImage::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const
{
	const FSlateBrush* ImageBrush = Image.Get();

	if ((ImageBrush != nullptr) && (ImageBrush->DrawAs != ESlateBrushDrawType::NoDrawType))
	{
		const bool bIsEnabled = ShouldBeEnabled(bParentEnabled);
		const uint32 DrawEffects = bIsEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect;

		const FLinearColor FinalColorAndOpacity( InWidgetStyle.GetColorAndOpacityTint() * ColorAndOpacity.Get().GetColor(InWidgetStyle) * ImageBrush->GetTint( InWidgetStyle ) );

		<span style="color:#ff0000;">FSlateDrawElement::MakeBox(OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), ImageBrush, MyClippingRect, DrawEffects, FinalColorAndOpacity ,0.3);</span>
	}
	return LayerId;
}

可以看到我傳入的0.3,默認是0.8,所以編譯以後,所有圖片的DISABLE狀態,灰色不會有這麼明顯了,但是button還是0.8的默認灰色。


應該是沒有漏下東西,如果看過前面的文章的話,就可以通過UMG吧這個值暴露給編輯器,就可以通過改變一個字段改變一個特定UI的DISABLE的灰色的程度。


完成





發佈了90 篇原創文章 · 獲贊 25 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章