FVelocityDrawingPolicy::FVelocityDrawingPolicy( const FVertexFactory* InVertexFactory, const FMaterialRenderProxy* InMaterialRenderProxy, const FMaterial& InMaterialResource, ERHIFeatureLevel::Type InFeatureLevel ) : FMeshDrawingPolicy(InVertexFactory,InMaterialRenderProxy,InMaterialResource) { const FMaterialShaderMap* MaterialShaderIndex = InMaterialResource.GetRenderingThreadShaderMap(); const FMeshMaterialShaderMap* MeshShaderIndex = MaterialShaderIndex->GetMeshShaderMap(InVertexFactory->GetType()); HullShader = NULL; DomainShader = NULL; const EMaterialTessellationMode MaterialTessellationMode = InMaterialResource.GetTessellationMode(); if (RHISupportsTessellation(GShaderPlatformForFeatureLevel[InFeatureLevel]) && InVertexFactory->GetType()->SupportsTessellationShaders() && MaterialTessellationMode != MTM_NoTessellation) { bool HasHullShader = MeshShaderIndex->HasShader(&FVelocityHS::StaticType); bool HasDomainShader = MeshShaderIndex->HasShader(&FVelocityDS::StaticType); HullShader = HasHullShader ? MeshShaderIndex->GetShader<FVelocityHS>() : NULL; DomainShader = HasDomainShader ? MeshShaderIndex->GetShader<FVelocityDS>() : NULL; } bool HasVertexShader = MeshShaderIndex->HasShader(&FVelocityVS::StaticType); VertexShader = HasVertexShader ? MeshShaderIndex->GetShader<FVelocityVS>() : NULL; bool HasPixelShader = MeshShaderIndex->HasShader(&FVelocityPS::StaticType); PixelShader = HasPixelShader ? MeshShaderIndex->GetShader<FVelocityPS>() : NULL; }
void FMaterialShader::SetParameters( FRHICommandList& RHICmdList, const ShaderRHIParamRef ShaderRHI, const FMaterialRenderProxy* MaterialRenderProxy, const FMaterial& Material, const FSceneView& View, bool bDeferredPass, ESceneRenderTargetsMode::Type TextureMode) { ERHIFeatureLevel::Type FeatureLevel = View.GetFeatureLevel(); FUniformExpressionCache TempUniformExpressionCache; const FUniformExpressionCache* UniformExpressionCache = &MaterialRenderProxy->UniformExpressionCache[FeatureLevel]; SetParameters(RHICmdList, ShaderRHI, View); // If the material has cached uniform expressions for selection or hover // and that is being overridden by show flags in the editor, recache // expressions for this draw call. const bool bOverrideSelection = GIsEditor && !View.Family->EngineShowFlags.Selection && (MaterialRenderProxy->IsSelected() || MaterialRenderProxy->IsHovered()); if (!bAllowCachedUniformExpressions || !UniformExpressionCache->bUpToDate || bOverrideSelection) { FMaterialRenderContext MaterialRenderContext(MaterialRenderProxy, Material, &View); MaterialRenderProxy->EvaluateUniformExpressions(TempUniformExpressionCache, MaterialRenderContext, &RHICmdList); UniformExpressionCache = &TempUniformExpressionCache; } check(Material.GetRenderingThreadShaderMap()); check(Material.GetRenderingThreadShaderMap()->IsValidForRendering()); check(Material.GetFeatureLevel() == FeatureLevel); // Validate that the shader is being used for a material that matches the uniform expression set the shader was compiled for. const FUniformExpressionSet& MaterialUniformExpressionSet = Material.GetRenderingThreadShaderMap()->GetUniformExpressionSet(); #if NO_LOGGING == 0 const bool bUniformExpressionSetMismatch = !DebugUniformExpressionSet.Matches(MaterialUniformExpressionSet) || UniformExpressionCache->CachedUniformExpressionShaderMap != Material.GetRenderingThreadShaderMap(); if (bUniformExpressionSetMismatch) { UE_LOG( LogShaders, Fatal, TEXT("%s shader uniform expression set mismatch for material %s/%s.\n") TEXT("Shader compilation info: %s\n") TEXT("Material render proxy compilation info: %s\n") TEXT("Shader uniform expression set: %u vectors, %u scalars, %u 2D textures, %u cube textures, %u scalars/frame, %u vectors/frame, shader map %p\n") TEXT("Material uniform expression set: %u vectors, %u scalars, %u 2D textures, %u cube textures, %u scalars/frame, %u vectors/frame, shader map %p\n"), GetType()->GetName(), *MaterialRenderProxy->GetFriendlyName(), *Material.GetFriendlyName(), *DebugDescription, *Material.GetRenderingThreadShaderMap()->GetDebugDescription(), DebugUniformExpressionSet.NumVectorExpressions, DebugUniformExpressionSet.NumScalarExpressions, DebugUniformExpressionSet.Num2DTextureExpressions, DebugUniformExpressionSet.NumCubeTextureExpressions, DebugUniformExpressionSet.NumPerFrameScalarExpressions, DebugUniformExpressionSet.NumPerFrameVectorExpressions, UniformExpressionCache->CachedUniformExpressionShaderMap, MaterialUniformExpressionSet.UniformVectorExpressions.Num(), MaterialUniformExpressionSet.UniformScalarExpressions.Num(), MaterialUniformExpressionSet.Uniform2DTextureExpressions.Num(), MaterialUniformExpressionSet.UniformCubeTextureExpressions.Num(), MaterialUniformExpressionSet.PerFrameUniformScalarExpressions.Num(), MaterialUniformExpressionSet.PerFrameUniformVectorExpressions.Num(), Material.GetRenderingThreadShaderMap() ); } #endif if (UniformExpressionCache->LocalUniformBuffer.IsValid()) { // Set the material uniform buffer. SetLocalUniformBufferParameter(RHICmdList, ShaderRHI, MaterialUniformBuffer, UniformExpressionCache->LocalUniformBuffer); } else { // Set the material uniform buffer. SetUniformBufferParameter(RHICmdList, ShaderRHI, MaterialUniformBuffer, UniformExpressionCache->UniformBuffer); } { const TArray<FGuid>& ParameterCollections = UniformExpressionCache->ParameterCollections; const int32 ParameterCollectionsNum = ParameterCollections.Num(); check(ParameterCollectionUniformBuffers.Num() >= ParameterCollectionsNum); // Find each referenced parameter collection's uniform buffer in the scene and set the parameter for (int32 CollectionIndex = 0; CollectionIndex < ParameterCollectionsNum; CollectionIndex++) { FUniformBufferRHIParamRef UniformBuffer = GetParameterCollectionBuffer(ParameterCollections[CollectionIndex], View.Family->Scene); SetUniformBufferParameter(RHICmdList, ShaderRHI,ParameterCollectionUniformBuffers[CollectionIndex],UniformBuffer); } } { // Per frame material expressions const int32 NumScalarExpressions = PerFrameScalarExpressions.Num(); const int32 NumVectorExpressions = PerFrameVectorExpressions.Num(); if (NumScalarExpressions > 0 || NumVectorExpressions > 0) { FMaterialRenderContext MaterialRenderContext(MaterialRenderProxy, Material, &View); MaterialRenderContext.Time = View.Family->CurrentWorldTime; MaterialRenderContext.RealTime = View.Family->CurrentRealTime; for (int32 Index = 0; Index < NumScalarExpressions; ++Index) { auto& Parameter = PerFrameScalarExpressions[Index]; if (Parameter.IsBound()) { FLinearColor TempValue; MaterialUniformExpressionSet.PerFrameUniformScalarExpressions[Index]->GetNumberValue(MaterialRenderContext, TempValue); SetShaderValue(RHICmdList, ShaderRHI, Parameter, TempValue.R); } } for (int32 Index = 0; Index < NumVectorExpressions; ++Index) { auto& Parameter = PerFrameVectorExpressions[Index]; if (Parameter.IsBound()) { FLinearColor TempValue; MaterialUniformExpressionSet.PerFrameUniformVectorExpressions[Index]->GetNumberValue(MaterialRenderContext, TempValue); SetShaderValue(RHICmdList, ShaderRHI, Parameter, TempValue); } } // Now previous frame's expressions const int32 NumPrevScalarExpressions = PerFramePrevScalarExpressions.Num(); const int32 NumPrevVectorExpressions = PerFramePrevVectorExpressions.Num(); if (NumPrevScalarExpressions > 0 || NumPrevVectorExpressions > 0) { MaterialRenderContext.Time = View.Family->CurrentWorldTime - View.Family->DeltaWorldTime; MaterialRenderContext.RealTime = View.Family->CurrentRealTime - View.Family->DeltaWorldTime; for (int32 Index = 0; Index < NumPrevScalarExpressions; ++Index) { auto& Parameter = PerFramePrevScalarExpressions[Index]; if (Parameter.IsBound()) { FLinearColor TempValue; MaterialUniformExpressionSet.PerFramePrevUniformScalarExpressions[Index]->GetNumberValue(MaterialRenderContext, TempValue); SetShaderValue(RHICmdList, ShaderRHI, Parameter, TempValue.R); } } for (int32 Index = 0; Index < NumPrevVectorExpressions; ++Index) { auto& Parameter = PerFramePrevVectorExpressions[Index]; if (Parameter.IsBound()) { FLinearColor TempValue; MaterialUniformExpressionSet.PerFramePrevUniformVectorExpressions[Index]->GetNumberValue(MaterialRenderContext, TempValue); SetShaderValue(RHICmdList, ShaderRHI, Parameter, TempValue); } } } } } DeferredParameters.Set(RHICmdList, ShaderRHI, View, TextureMode); AtmosphericFogTextureParameters.Set(RHICmdList, ShaderRHI, View); if (FeatureLevel >= ERHIFeatureLevel::SM4) { // for copied scene color if(LightAttenuation.IsBound()) { SetTextureParameter( RHICmdList, ShaderRHI, LightAttenuation, LightAttenuationSampler, TStaticSamplerState<SF_Bilinear,AM_Clamp,AM_Clamp,AM_Clamp>::GetRHI(), GSceneRenderTargets.GetLightAttenuationTexture()); } } //Use of the eye adaptation texture here is experimental and potentially dangerous as it can introduce a feedback loop. May be removed. if(EyeAdaptation.IsBound()) { FTextureRHIRef& EyeAdaptationTex = GetEyeAdaptation(View); SetTextureParameter(RHICmdList, ShaderRHI, EyeAdaptation, EyeAdaptationTex); } if (PerlinNoiseGradientTexture.IsBound() && IsValidRef(GSystemTextures.PerlinNoiseGradient)) { const FTexture2DRHIRef& Texture = (FTexture2DRHIRef&)GSystemTextures.PerlinNoiseGradient->GetRenderTargetItem().ShaderResourceTexture; // Bind the PerlinNoiseGradientTexture as a texture SetTextureParameter( RHICmdList, ShaderRHI, PerlinNoiseGradientTexture, PerlinNoiseGradientTextureSampler, TStaticSamplerState<SF_Point,AM_Wrap,AM_Wrap,AM_Wrap>::GetRHI(), Texture ); } if (PerlinNoise3DTexture.IsBound() && IsValidRef(GSystemTextures.PerlinNoise3D)) { const FTexture3DRHIRef& Texture = (FTexture3DRHIRef&)GSystemTextures.PerlinNoise3D->GetRenderTargetItem().ShaderResourceTexture; // Bind the PerlinNoise3DTexture as a texture SetTextureParameter( RHICmdList, ShaderRHI, PerlinNoise3DTexture, PerlinNoise3DTextureSampler, TStaticSamplerState<SF_Bilinear,AM_Wrap,AM_Wrap,AM_Wrap>::GetRHI(), Texture ); } GlobalDistanceFieldParameters.Set(RHICmdList, ShaderRHI, static_cast<const FViewInfo&>(View).GlobalDistanceFieldInfo.ParameterData); }