自定义着色器不接收光线
Posted
技术标签:
【中文标题】自定义着色器不接收光线【英文标题】:Custom shader does not receive light 【发布时间】:2020-01-12 21:15:03 【问题描述】:我制作了一个运行良好的网格着色器。但是,它根本不受任何光线的影响。只是为了让您了解具有着色器的平面:
它的尺寸是 1000x1x1000(足够宽) 使用任何其他材质显示阴影并启用投射阴影 使用 Unity 2019.3.0f3 通用渲染管线The plane using custom grid shader(不接收光)
The plane using basic shader(接收光)
Custom grid shader code
我尝试了一些解决方案,包括在末尾添加 FallBack "Diffuse"
或 #include
以及 TRANSFER_SHADOW
的东西。但是,这些也不起作用。
【问题讨论】:
【参考方案1】:如果您希望光照信息,您需要告诉着色器如何处理光照信息。这是一个将漫反射光直接应用于网格着色器的反照率的示例:
Shader "Custom/Grid"
Properties
_GridThickness("Grid Thickness", Float) = 0.01
_GridSpacing("Grid Spacing", Float) = 10.0
_GridColour("Grid Colour", Color) = (0.5, 0.5, 0.5, 0.5)
_BaseColour("Base Colour", Color) = (0.0, 0.0, 0.0, 0.0)
SubShader
Tags "Queue" = "Transparent"
Pass
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Tags
"LightMode" = "ForwardBase"
// gets us access to main directional light
CGPROGRAM
// Define the vertex and fragment shader functions
#pragma vertex vert
#pragma fragment frag
#include "UnityStandardBRDF.cginc" // for shader lighting info and some utils
#include "UnityStandardUtils.cginc" // for energy conservation
// Access Shaderlab properties
uniform float _GridThickness;
uniform float _GridSpacing;
uniform float4 _GridColour;
uniform float4 _BaseColour;
// Input into the vertex shader
struct vertexInput
float4 vertex : POSITION;
float3 normal : NORMAL; // include normal info
;
// Output from vertex shader into fragment shader
struct vertexOutput
float4 pos : SV_POSITION;
float4 worldPos : TEXCOORD0;
float3 normal : TEXCOORD1; // pass normals along
;
// VERTEX SHADER
vertexOutput vert(vertexInput input)
vertexOutput output;
output.pos = UnityObjectToClipPos(input.vertex);
// Calculate the world position coordinates to pass to the fragment shader
output.worldPos = mul(unity_ObjectToWorld, input.vertex);
output.normal = input.normal; //get normal for frag shader from vert info
return output;
// FRAGMENT SHADER
float4 frag(vertexOutput input) : COLOR
float3 lightDir = _WorldSpaceLightPos0.xyz;
float3 viewDir = normalize(_WorldSpaceCameraPos - input.worldPos);
float3 lightColor = _LightColor0.rgb;
float3 col;
if (frac(input.worldPos.x / _GridSpacing) < _GridThickness || frac(input.worldPos.z / _GridSpacing) < _GridThickness)
col = _GridColour;
else
col = _BaseColour;
col *= lightColor * DotClamped(lightDir, input.normal); // apply diffuse light by angle of incidence
return float4(col, 1);
ENDCG
您应该check out these tutorials 了解更多关于照亮对象的其他方法。如果您希望他们发送到accept shadows,同样适用。
在此处设置 FallBack "Diffuse"
不会做任何事情,因为着色器没有“回退”,它完全按照您的编程方式运行,没有光照或阴影。
【讨论】:
谢谢!我使用的是通用渲染管道 (URP),所以我最终使用了 ShaderGraph,这要简单得多。以上是关于自定义着色器不接收光线的主要内容,如果未能解决你的问题,请参考以下文章