vault backup: 2024-09-23 20:09:32
This commit is contained in:
parent
e87f6622de
commit
062b7f69e4
@ -0,0 +1,154 @@
|
|||||||
|
---
|
||||||
|
title: Untitled
|
||||||
|
date: 2024-09-23 19:47:03
|
||||||
|
excerpt:
|
||||||
|
tags:
|
||||||
|
rating: ⭐
|
||||||
|
---
|
||||||
|
# ShadowPassSwitch
|
||||||
|
## Cpp
|
||||||
|
MaterialExpressionShadowReplace.h
|
||||||
|
|
||||||
|
MaterialExpressions.cpp
|
||||||
|
```c++
|
||||||
|
int32 UMaterialExpressionShadowReplace::Compile(class FMaterialCompiler* Compiler, int32 OutputIndex)
|
||||||
|
{
|
||||||
|
if (!Default.GetTracedInput().Expression)
|
||||||
|
{
|
||||||
|
return Compiler->Errorf(TEXT("Missing input Default"));
|
||||||
|
}
|
||||||
|
else if (!Shadow.GetTracedInput().Expression)
|
||||||
|
{
|
||||||
|
return Compiler->Errorf(TEXT("Missing input Shadow"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const int32 Arg1 = Default.Compile(Compiler);
|
||||||
|
const int32 Arg2 = Shadow.Compile(Compiler);
|
||||||
|
return Compiler->ShadowReplace(Arg1, Arg2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
MaterialCompiler.h => **HLSLMaterialTranslator.cpp**
|
||||||
|
```c++
|
||||||
|
int32 FHLSLMaterialTranslator::ShadowReplace(int32 Default, int32 Shadow)
|
||||||
|
{
|
||||||
|
return GenericSwitch(TEXT("GetShadowReplaceState()"), Shadow, Default);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```c++
|
||||||
|
int32 FHLSLMaterialTranslator::GenericSwitch(const TCHAR* SwitchExpressionText, int32 IfTrue, int32 IfFalse)
|
||||||
|
{
|
||||||
|
if (IfTrue == INDEX_NONE || IfFalse == INDEX_NONE)
|
||||||
|
{
|
||||||
|
return INDEX_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// exactly the same inputs on both sides - no need to generate anything extra
|
||||||
|
if (IfTrue == IfFalse)
|
||||||
|
{
|
||||||
|
return IfTrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FMaterialUniformExpression* IfTrueExpression = GetParameterUniformExpression(IfTrue);
|
||||||
|
FMaterialUniformExpression* IfFalseExpression = GetParameterUniformExpression(IfFalse);
|
||||||
|
if (IfTrueExpression &&
|
||||||
|
IfFalseExpression &&
|
||||||
|
IfTrueExpression->IsConstant() &&
|
||||||
|
IfFalseExpression->IsConstant())
|
||||||
|
{
|
||||||
|
FMaterialRenderContext DummyContext(nullptr, *Material, nullptr);
|
||||||
|
FLinearColor IfTrueValue;
|
||||||
|
FLinearColor IfFalseValue;
|
||||||
|
IfTrueExpression->GetNumberValue(DummyContext, IfTrueValue);
|
||||||
|
IfFalseExpression->GetNumberValue(DummyContext, IfFalseValue);
|
||||||
|
if (IfTrueValue == IfFalseValue)
|
||||||
|
{
|
||||||
|
// If both inputs are wired to == constant values, avoid adding the runtime switch
|
||||||
|
// This will avoid breaking various offline checks for constant values
|
||||||
|
return IfTrue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Both branches of '?:' need to be the same type
|
||||||
|
const EMaterialValueType ResultType = GetArithmeticResultType(IfTrue, IfFalse);
|
||||||
|
const FString IfTrueCode = CoerceParameter(IfTrue, ResultType);
|
||||||
|
const FString IfFalseCode = CoerceParameter(IfFalse, ResultType);
|
||||||
|
|
||||||
|
if (IsLWCType(ResultType))
|
||||||
|
{
|
||||||
|
AddLWCFuncUsage(ELWCFunctionKind::Other);
|
||||||
|
return AddCodeChunk(ResultType, TEXT("LWCSelect(%s, %s, %s)"), SwitchExpressionText, *IfTrueCode, *IfFalseCode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return AddCodeChunk(ResultType, TEXT("(%s ? (%s) : (%s))"), SwitchExpressionText, *IfTrueCode, *IfFalseCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
>可以看得出最终会编译成(%s ? (%s) : (%s)),也就是 GetShadowReplaceState() ? True的Shader : False时的Shader。
|
||||||
|
|
||||||
|
## Shader
|
||||||
|
### Common.ush
|
||||||
|
```c++
|
||||||
|
// NOTE: The raytraced implementation of the ShadowPassSwitch node is kept in RayTracingShaderUtils.ush as it needs to access per ray information.
|
||||||
|
#if RAYHITGROUPSHADER == 0
|
||||||
|
// Experimental way to allow adjusting the OpacityMask for shadow map rendering of masked materials.
|
||||||
|
// This is exposed via the ShadowPassSwitch material node. This can also be accessed with a Custom
|
||||||
|
// material node. If this turns out to be very useful we can expose as MaterialFunction
|
||||||
|
// and potentially expose other queries as well (e.g. SkeletalMesh, HitProxy, ).
|
||||||
|
// @return 0:no, 1:yes
|
||||||
|
bool GetShadowReplaceState()
|
||||||
|
{
|
||||||
|
#if SHADOW_DEPTH_SHADER
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
float IsShadowDepthShader()
|
||||||
|
{
|
||||||
|
return GetShadowReplaceState() ? 1.0f : 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // RAYHITGROUPSHADER == 0
|
||||||
|
```
|
||||||
|
|
||||||
|
可以看得出主要通过**SHADOW_DEPTH_SHADER**宏进行判断,而渲染阴影的Shader ShadowDepthVertexShader.usf&ShadowDepthPixelShader.usf都定义该宏为1。
|
||||||
|
|
||||||
|
### NaniteRasterizer.usf
|
||||||
|
```c++
|
||||||
|
// This must be defined before including Common.ush (see GetShadowReplaceState)
|
||||||
|
#define SHADOW_DEPTH_SHADER DEPTH_ONLY
|
||||||
|
```
|
||||||
|
在NaniteCullRaster.cpp中DEPTH_ONLY设置为1。
|
||||||
|
|
||||||
|
### RayTracingShaderUtils.ush
|
||||||
|
光追相关
|
||||||
|
```c++
|
||||||
|
#ifndef RAYHITGROUPSHADER
|
||||||
|
#error "This header should only be included in raytracing contexts"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PATH_TRACING // Path Tracing has a similar implemental with a slightly different set of flags
|
||||||
|
|
||||||
|
#include "RayTracingCommon.ush"
|
||||||
|
|
||||||
|
static int CurrentPayloadInputFlags = 0;
|
||||||
|
|
||||||
|
bool GetShadowReplaceState()
|
||||||
|
{
|
||||||
|
return (CurrentPayloadInputFlags & RAY_TRACING_PAYLOAD_INPUT_FLAG_SHADOW_RAY) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float IsShadowDepthShader()
|
||||||
|
{
|
||||||
|
return GetShadowReplaceState() ? 1.0f : 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
```
|
Loading…
x
Reference in New Issue
Block a user