虚幻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;
	float DisableValue:TEXCOORD4;
};

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,
	in float InDisableValue : ATTRIBUTE6
#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;
	VOut.DisableValue = InDisableValue;


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 );
	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)  );
#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;

	/**  **/
	float DisableValue;

	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);
};

对应的构造函数我就不写了,就是给DisableValue赋值。


然后在FSlateDrawElement里面添加变量:

SlateCore/Public/Rendering/DrawElements.h

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

	/**/
	FORCEINLINE float GetDisableValue() const { return DisableValue; }
	
private:
	void Init(uint32 InLayer, const FPaintGeometry& PaintGeometry, const FSlateRect& InClippingRect, ESlateDrawEffect::Type InDrawEffects);


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

private:
	FSlateDataPayload DataPayload;
	FSlateRenderTransform RenderTransform;
	FSlateRect ClippingRect;
	FVector2D Position;
	FVector2D LocalSize;
	float Scale;
	uint32 Layer;
	uint32 DrawEffects;
	EElementType ElementType;
	TOptional ScissorRect;
	/**/
	float DisableValue;
};

这几个函数添加参数:

	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 ,
		float InDisableValue = 0.8);

	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,
		float InDisableValue = 0.8);
	

然后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));
	Elements.Add(FVertexElement(0, STRUCT_OFFSET(FSlateVertex, DisableValue), VET_Float1, 6, Stride));

	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));
	/**/
	Elements.Add(FVertexElement(0, STRUCT_OFFSET(FSlateVertex, DisableValue), VET_Float1, 6, Stride));

	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 ) );

		FSlateDrawElement::MakeBox(OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), ImageBrush, MyClippingRect, DrawEffects, FinalColorAndOpacity ,0.3);
	}
	return LayerId;
}

可以看到我传入的0.3,默认是0.8,所以编译以后,所有图片的DISABLE状态,灰色不会有这么明显了,但是button还是0.8的默认灰色。


应该是没有漏下东西,如果看过前面的文章的话,就可以通过UMG吧这个值暴露给编辑器,就可以通过改变一个字段改变一个特定UI的DISABLE的灰色的程度。


完成





你可能感兴趣的:(虚幻4)