如何让 Phong Lighting 在波顶点着色器 HLSL Unity URP 上工作

问题描述 投票:0回答:1

我有一个在网格上产生波浪的着色器,并向其添加了 Phong 光照。但飞机上的山谷没有阴影。

如何让 UniversalFragmentBlinnPhong 正确使用变换网格的法线而不是原始未更改的网格?

Varyings vert(Attributes IN)
{
    // Declaring the output object (OUT) with the Varyings struct.
    Varyings OUT;
    // The TransformObjectToHClip function transforms vertex positions
    // from object space to homogenous space

    // ripple
    IN.positionOS.y += sin(_frequency* sqrt((IN.positionOS.x*IN.positionOS.x) + (IN.positionOS.z*IN.positionOS.z)) + _Time.y) *_amplitude;

    VertexPositionInputs posnInput = GetVertexPositionInputs(IN.positionOS);

    // lighting does not account for the change in the vertex
    VertexNormalInputs normalInputs = GetVertexNormalInputs(IN.normalOS);
    
    
    // In.uv.xy * _MainTex_ST.xy + _MainTex_ST.xy
    OUT.uv = TRANSFORM_TEX(IN.uv,_MainTex);
    
    OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);

    OUT.normalWS = IN.normalOS;
    
    
    OUT.positionWS = posnInput.positionWS;
    
    
    return OUT;
}

// The fragment shader definition.
// SV Target is a semantic that defines the output of the fragment shader.          
half4 frag(Varyings IN) : SV_Target
{
    half4 colorSample = SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,IN.uv);

    // cast everything 
    InputData lightingInput = (InputData)0;
    lightingInput.positionWS = IN.positionWS;
    lightingInput.normalWS = normalize(IN.normalWS);
    lightingInput.viewDirectionWS = GetWorldSpaceNormalizeViewDir(IN.positionWS);
    
    SurfaceData surfaceInput = (SurfaceData)0;
    //surfaceInput.albedo = colorSample.rbg * _ColorTint.rbg;
    //surfaceInput.alpha = colorSample.a * _ColorTint.a;
    surfaceInput.albedo = _ColorTint.rbg;
    surfaceInput.alpha = _ColorTint.a;
    surfaceInput.specular = 1;
    surfaceInput.smoothness = _Smoothness;
    
    
    return UniversalFragmentBlinnPhong(lightingInput,surfaceInput);
}

飞机图片

相同材质的球体图像

顶部的草皮应该是全黑的,但它的阴影就像是一个光滑的球体

unity-game-engine hlsl urp
1个回答
0
投票

我必须手动计算法线,看起来没有任何函数可以为我做到这一点。

Varyings vert(Attributes IN)
{
    // Declaring the output object (OUT) with the Varyings struct.
    Varyings OUT;
    // The TransformObjectToHClip function transforms vertex positions
    // from object space to homogenous space

    // ripple

    // consider this the bump map
    float4 modifiedPos = IN.positionOS;
    modifiedPos.y += sin(_frequency* sqrt((modifiedPos.x*modifiedPos.x) + (modifiedPos.z*modifiedPos.z)) + (_Time.y*_Speed)) *_amplitude;
    
    

    
     
    VertexPositionInputs posnInput = GetVertexPositionInputs(modifiedPos);
    
    // lighting does not account for the change in the vertex
    VertexNormalInputs normalInputs = GetVertexNormalInputs(modifiedPos);


    // since we have the displacment funtion we can calculate the normal a plane runing parallel over the diff
    
    float3 posPlusTangent = IN.positionOS + normalInputs.tangentWS * 0.01;
    posPlusTangent.y += sin(_frequency* sqrt((posPlusTangent.x*posPlusTangent.x) + (posPlusTangent.z*posPlusTangent.z)) + (_Time.y*_Speed)) *_amplitude;

    float3 bitangent = cross(IN.normalOS, normalInputs.tangentWS);
    float3 posPlusBitangent = IN.positionOS + bitangent * 0.01;
    posPlusBitangent.y += sin(_frequency* sqrt((posPlusBitangent.x*posPlusBitangent.x) + (posPlusBitangent.z*posPlusBitangent.z)) + (_Time.y*_Speed)) *_amplitude;

    float3 modifiedTangent = posPlusTangent - modifiedPos;
    float3 modifiedBitangent = posPlusBitangent - modifiedPos;

    float3 modifiedNormal = cross(modifiedTangent, modifiedBitangent);
    
    // In.uv.xy * _MainTex_ST.xy + _MainTex_ST.xy
    OUT.uv = TRANSFORM_TEX(IN.uv,_MainTex);

    
    
    OUT.positionHCS = TransformObjectToHClip(modifiedPos.xyz);
    
    OUT.normalWS =  normalize(cross(modifiedTangent, modifiedBitangent));
    
    OUT.positionWS = posnInput.positionWS;
    
    
    return OUT;
© www.soinside.com 2019 - 2024. All rights reserved.