I canât get fog to work in the HD SRP for a custom unlit emissive shader. In LW it works fine.
In RenderDoc, both GetPositionInput() and EvaluateAtmosphericScattering() are jumped over when singe stepping through the code. I am not sure if this is because that code is ignored or that RenderDoc is unable to step into 3rd party functions. Looking at the assembly, it looks like those functions are indeed missing. Strange because the compiler doesnât throw an error.
I am not sure where to check in RenderDoc that _AtmosphericScatteringType is correctly initialized.
The blend mode is present as a shader feature.
Below is the full shader I am using. Here is also a small repo:
https://drive.google.com/file/d/1Sn6gIIK6li6fXM05Jo_JOlnHZl2yltXp/view?usp=sharing
The GameObject containing the OmniSimple shader is called CityLightsAmber0 and CityLightsWhite0. Note that the shader needs custom vertex data and cannot be applied to a regular mesh. So the repo is indeed required.
The camera controls in game mode are the same as with the Editor.
You can see a spherical shadow effect and incorrect blending with the cube.
//This shader contains a failed attempt to get fog (atmospheric scattering) to work.
Shader "Lights/OmniSimple"{
Properties{
_MainTex ("Light Texture", 2D) = "white" {}
[HDR]_FrontColor ("Front Color", Color) = (0.5,0.5,0.5,0.5)
_MinPixelSize ("Minimum screen size", FLOAT) = 5.0
_Attenuation ("Attenuation", Range(0.01, 1)) = 0.37
_BrightnessOffset ("Brightness offset", Range(-1, 1)) = 0
}
HLSLINCLUDE
#pragma target 4.5
#pragma glsl_no_auto_normalization
#pragma enable_d3d11_debug_symbols
#pragma shader_feature _SURFACE_TYPE_TRANSPARENT
#pragma shader_feature _BLENDMODE_ALPHA
//#pragma shader_feature _ _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY
#pragma shader_feature _ENABLE_FOG_ON_TRANSPARENT
#define UNITY_MATERIAL_UNLIT // Need to be define before including Material.hlsl
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl" //for Fog
#include "lightFunctions.cginc"
uniform sampler2D _MainTex;
float _MinPixelSize;
half _BrightnessOffset;
float _Attenuation;
half4 _FrontColor;
//These global variables are set from a Unity script.
float _ScaleFactor;
struct vertexInput {
float4 center : POSITION; //Mesh center position is stored in the position channel (vertices in Unity).
float4 corner : TANGENT; //Mesh corner is stored in the tangent channel (tangent in Unity). The scale is stored in the w component.
float2 uvs : TEXCOORD0; //Texture coordinates (uv in Unity).
};
struct vertexOutput{
float4 pos : SV_POSITION;
float2 uvs : TEXCOORD0;
half4 color : COLOR;
//This is not a UV coordinate but it is just used to pass some variables
//from the vertex shader to the fragment shader: xyz = world space pos. w = gain
float4 container : TEXCOORD1;
};
vertexOutput vert(vertexInput input){
vertexOutput output;
half gain;
half distanceGain;
float scale;
float3 positionWS;
//Get a vector from the vertex to the camera and cache the result.
float3 objSpaceViewDir = ObjSpaceViewDir2(input.center);
//Get the distance between the camera and the light.
float distance = length(objSpaceViewDir);
output.color = _FrontColor;
//Calculate the scale. If the light size is smaller than one pixel, scale it up
//so it remains at least one pixel in size.
scale = ScaleUp(distance, _ScaleFactor, input.corner.w, 1.0f, _MinPixelSize);
//Get the vertex offset to shift and scale the light.
float4 offset = GetOffset(scale, input.corner);
//Place the vertex by moving it away from the center.
//Rotate the billboard towards the camera.
positionWS = TransformObjectToWorld(input.center.xyz);
output.pos.xyz = TransformWorldToView(positionWS) + offset.xyz;
output.pos = mul(UNITY_MATRIX_P, float4(output.pos.xyz, 1.0f));
//Far away lights should be less bright. Attenuate with the inverse square law.
distanceGain = Attenuate(distance, _Attenuation);
//Merge the distance gain (attenuation), and light brightness into a single gain value.
gain = (_BrightnessOffset - (1.0h - distanceGain));
//Send the gain and positionWS to the fragment shader.
output.container = float4(positionWS, gain);
//UV mapping.
output.uvs = input.uvs;
return output;
}
half4 frag(vertexOutput input) : SV_Target{
//Compute the final color.
//Note: input.container.x fetches the gain from the vertex shader. No need to calculate this for each fragment.
half4 col = 2.0h * input.color * tex2D(_MainTex, input.uvs) * (exp(input.container.w * 5.0h));
//input.positionSS is SV_Position (float2 positionSS, float2 invScreenSize, float deviceDepth, float linearDepth, float3 positionWS)
//PositionInputs posInput = GetPositionInput(input.pos.xy, _ScreenSize.zw, input.pos.z, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
PositionInputs posInput = GetPositionInput(input.pos.xy, _ScreenSize.zw, input.pos.z, input.pos.w, input.container.xyz);
//This does not have any effect.
col = EvaluateAtmosphericScattering(posInput, col);
return col;
}
ENDHLSL
SubShader{
Tags {"RenderType"="Transparent"}
Pass
{
Name ""
Tags{ "LightMode" = "ForwardOnly" }
Blend SrcAlpha One
AlphaTest Greater .01
ColorMask RGB
Lighting Off
ZWrite Off
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDHLSL
}
}
}