

车内近景侧拍,平视微侧机位,人物占据画面右侧,人物肩部以上进入画面,左侧车窗逆光形成天然光源框架。前景:人物侧脸与肩部;中景:车窗玻璃;远景:窗外强逆光朦胧光斑。经典好莱坞低调明暗影调,车窗外后方逆光大面积柔光,属于轮廓光,沿人物后脑、肩线勾勒一圈柔和金边,极微弱环境反光,仅提亮人物右半边面部,左半边脸颊、鼻梁完全沉入硬阴影,窗外强光产生镜头光晕、弥散雾感,弱化窗外环境细节。角色端坐于汽车座椅,头部转向画面右侧,目光侧望画面右前方,下颌收紧,神情隐忍、深沉,带有压抑凝重的情绪。二次元卡通3D渲染,阴影清晰边缘锐利。丁达尔效应(Tyndall effect)。背景中有签名:“Detective ”“侦探”,无多余文字。居中构图,日系二次元平涂,动态手书风格,线条粗细变化清晰自然。不写实。
sdr5p生成结果:

gimage2生成结果:

明显看出啊,sdr5p的图并不是特别好看,但是角色控制很强,gi2会瞎搞画风,永远不知道下张图长什么样子
sdr5p测试后发现,它仍旧不认识角色,gi2能直接生成出知名游戏或是作品的角色(自带联网搜索狠狠在网上扒图也多少有点作弊吧)
那么也在此恭喜白银之城,至少现在还没被融进库里,不自己搞个lora直接生成是生不出来的
接下来是编辑能力,就只尝试了三视图
sdr5p结果:

gi2结果:

很明显啊,sdr5p的是真的把角色视图还原了
gi2的会出现身体比例不还原的问题,偶尔还会出现纹理错误或者手套和头发线条融到了一起
接下来是着色器编辑能力
提示词:
Shader "Custom/ NPR Face"
{
Properties
{
[MainTexture] _BaseMap("基础贴图", 2D) = "white" {}
[MainColor] _BaseColor("基础颜色", Color) = (1,1,1,1)
// SDF 阴影
_SDFMap("SDF阴影图", 2D) = "white" {}
_ShadowColor("阴影颜色", Color) = (0.85, 0.88, 0.95, 1)
_ShadowThreshold("阴影阈值", Range(0, 1)) = 0.5
_ShadowSoftness("阴影柔和度", Range(0.001, 0.2)) = 0.05
// 高光
_SpecularColor("高光颜色", Color) = (1, 0.95, 0.9, 1)
_SpecularPower("高光幂次", Range(1, 100)) = 30
_SpecularIntensity("高光强度", Range(0, 1)) = 0.3
// 边缘光
_RimColor("边缘光颜色", Color) = (1, 0.95, 0.9, 1)
_RimPower("边缘光幂次", Range(0.5, 8)) = 2.0
_RimIntensity("边缘光强度", Range(0, 1)) = 0.25
// 描边
_OutlineWidth("描边宽度", Range(0, 5)) = 0.5
_OutlineColor("描边颜色", Color) = (0.15, 0.1, 0.1, 1)
}
SubShader
{
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
"Queue" = "Geometry"
}
// 描边
Pass
{
Name "Outline"
Tags { "LightMode" = "SRPDefaultUnlit" }
Cull Front
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
CBUFFER_START(UnityPerMaterial)
float _OutlineWidth;
float4 _OutlineColor;
CBUFFER_END
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float4 color : COLOR;
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
};
Varyings vert(Attributes input)
{
Varyings output;
float3 positionOS = input.positionOS.xyz + input.normalOS _OutlineWidth 0.001 * input.color.r;
output.positionHCS = TransformObjectToHClip(positionOS);
return output;
}
half4 frag(Varyings input) : SV_Target
{
return _OutlineColor;
}
ENDHLSL
}
// 主体
Pass
{
Name "ForwardLit"
Tags { "LightMode" = "UniversalForward" }
Cull Back
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
CBUFFER_START(UnityPerMaterial)
sampler2D _BaseMap;
float4 BaseMapST;
float4 _BaseColor;
sampler2D _SDFMap;
float4 SDFMapST;
float4 _ShadowColor;
float _ShadowThreshold;
float _ShadowSoftness;
float4 _SpecularColor;
float _SpecularPower;
float _SpecularIntensity;
float4 _RimColor;
float _RimPower;
float _RimIntensity;
CBUFFER_END
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float2 uv : TEXCOORD0;
float4 color : COLOR;
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
float2 uv : TEXCOORD0;
float3 positionWS : TEXCOORD1;
float3 normalWS : TEXCOORD2;
float3 viewDirWS : TEXCOORD3;
float4 color : COLOR;
};
Varyings vert(Attributes input)
{
Varyings output;
output.positionHCS = TransformObjectToHClip(input.positionOS.xyz);
output.positionWS = TransformObjectToWorld(input.positionOS.xyz);
output.normalWS = TransformObjectToWorldNormal(input.normalOS);
output.viewDirWS = GetWorldSpaceViewDir(output.positionWS);
output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
output.color = input.color;
return output;
}
// SDF 面部阴影计算
float CalculateSDFShadow(float2 uv, float3 normalWS, float3 lightDir)
{
// 将光照方向投影到面部平面
// 假设面部朝前,使用光照的 X 和 Y 分量
float2 lightDir2D = normalize(lightDir.xy);
// 根据光照角度计算 SDF 采样坐标
// 这里简化处理,实际项目中需要更复杂的角度映射
float angle = atan2(lightDir2D.y, lightDir2D.x);
float u = (angle + 3.14159) / (2 * 3.14159);
// 采样 SDF 图
float sdf = tex2D(_SDFMap, float2(uv.x, uv.y)).r;
// 简化版:直接使用法线和光照计算
float NdotL = dot(normalWS, lightDir);
float halfLambert = NdotL * 0.5 + 0.5;
// 使用顶点色控制阴影区域(常见做法)
// 顶点色 R 通道控制阴影软硬
float shadowControl = 1.0;
return smoothstep(
ShadowThreshold - ShadowSoftness,
ShadowThreshold + ShadowSoftness,
halfLambert * shadowControl
);
}
half4 frag(Varyings input) : SV_Target
{
// 基础色
float4 baseTex = tex2D(_BaseMap, input.uv);
float3 baseColor = baseTex.rgb * _BaseColor.rgb;
float alpha = baseTex.a * _BaseColor.a;
// 向量
float3 normalWS = normalize(input.normalWS);
Light mainLight = GetMainLight();
float3 lightDir = normalize(mainLight.direction);
float3 viewDir = normalize(input.viewDirWS);
// === SDF 面部阴影 ===
float shadowFactor = CalculateSDFShadow(input.uv, normalWS, lightDir);
float3 diffuse = lerp(_ShadowColor.rgb * baseColor, baseColor, shadowFactor);
// === 柔和高光(皮肤) ===
float3 halfDir = normalize(lightDir + viewDir);
float NdotH = dot(normalWS, halfDir);
float specular = pow(saturate(NdotH), SpecularPower) * SpecularIntensity;
float3 specColor = _SpecularColor.rgb * mainLight.color;
// === 柔和边缘光 ===
float fresnel = 1.0 - abs(dot(normalWS, viewDir));
fresnel = pow(fresnel, RimPower) * RimIntensity;
float3 rim = _RimColor.rgb * fresnel;
// === 最终合成 ===
float3 finalColor = diffuse;
finalColor += specular * specColor;
finalColor += rim;
// 环境光
finalColor += baseColor * 0.15;
return float4(finalColor, alpha);
}
ENDHLSL
}
}
FallBack "Hidden/Universal Render Pipeline/FallbackError"
}
参考图:

sdr5p结果:

gi2结果:

两边的理解能力都不错,但是sdr5p这个阴影有点过重了,gi2这个像是平面的。
我又体验了几个生图案例,感觉sdr5p的生图总是偏向写实风,你需要给他书写完整的提示词才能保证输出结果的画风。
如果你有好的参考图和提示词编写能力我建议是可以试试换到sdr5p了,没有的话暂时继续使用gi2比较好。