diff --git a/add_shader.cmake b/add_shader.cmake index df17bc7..fe669b5 100644 --- a/add_shader.cmake +++ b/add_shader.cmake @@ -11,48 +11,20 @@ function(add_shader TARGET SHADER) get_filename_component(shader-ext ${SHADER} LAST_EXT) set(current-shader-path ${CMAKE_CURRENT_SOURCE_DIR}/${SHADER}) - set(current-output-path ${CMAKE_CURRENT_BINARY_DIR}/${SHADER}.spv) + set(current-output-path ${CMAKE_CURRENT_BINARY_DIR}/${SHADER}.slang-module) set(current-copy-path ${CMAKE_CURRENT_BINARY_DIR}/${SHADER}) get_filename_component(current-output-dir ${current-output-path} DIRECTORY) file(MAKE_DIRECTORY ${current-output-dir}) - if (Vulkan_dxc_exe_FOUND AND ${shader-ext} STREQUAL ".hlsl") - message("Marked as hlsl file. ${current-output-path}") - - get_filename_component(shader-inner ${SHADER} NAME_WLE) - get_filename_component(shader-type ${shader-inner} LAST_EXT) - string(REPLACE "." "" shader-type ${shader-type}) - + if (${shader-ext} STREQUAL ".slang") add_custom_command( - OUTPUT ${current-output-path} - COMMAND Vulkan::dxc_exe ${DXC_SHADER_FLAGS} -spirv -T "${shader-type}_6_0" -E main ${current-shader-path} -Fo ${current-output-path} + OUTPUT ${current-output-path} ${current-copy-path} + COMMAND ${slangc_exe} ${current-shader-path} -o ${current-output-path} + COMMAND ${CMAKE_COMMAND} -E copy ${current-shader-path} ${current-copy-path} DEPENDS ${current-shader-path} IMPLICIT_DEPENDS CXX ${current-shader-path} VERBATIM) - elseif (Vulkan_glslc_FOUND AND ${shader-ext} STREQUAL ".glsl") - message("Marked as glsl file. ${current-output-path}") - add_custom_command( - OUTPUT ${current-output-path} - COMMAND Vulkan::glslc ${GLSLC_SHADER_FLAGS} -o ${current-output-path} ${current-shader-path} - DEPENDS ${current-shader-path} - IMPLICIT_DEPENDS CXX ${current-shader-path} - VERBATIM) - elseif (${shader-ext} STREQUAL ".slang") - message("Marked as slang file. ${current-output-path}") -# add_custom_command( -# OUTPUT ${current-output-path} -# COMMAND ${slangc_exe} -target spirv -o ${current-output-path} ${current-shader-path} -# DEPENDS ${current-shader-path} -# IMPLICIT_DEPENDS CXX ${current-shader-path} -# VERBATIM) - add_custom_command( - TARGET ${TARGET} POST_BUILD -# OUTPUT ${current-copy-path} - COMMAND ${CMAKE_COMMAND} -E copy ${current-shader-path} ${CMAKE_CURRENT_BINARY_DIR}/${SHADER} - DEPENDS ${current-shader-path} - IMPLICIT_DEPENDS CXX ${current-shader-path} - COMMENT "Copying ${SHADER}") endif () # Make sure our build depends on this output. diff --git a/samples/03_model_render/shader/slang/ibl_common.slang b/samples/03_model_render/shader/slang/ibl_common.slang index 8c6ac51..364f45a 100644 --- a/samples/03_model_render/shader/slang/ibl_common.slang +++ b/samples/03_model_render/shader/slang/ibl_common.slang @@ -89,7 +89,7 @@ float GetSampleMipLevel(float NdotH, float HdotV, float SampleCount, float rough return roughness == 0.0f ? 0.0f : 0.5f * log2(SurfAreaSample / SurfAreaTexel); } -float GeometrySchlickGGX(float NdotV, float Roughness) +float IBLGeometrySchlickGGX(float NdotV, float Roughness) { float R = Roughness; // (Rough + 1)^2 / 8 for Punctual Lights @@ -102,10 +102,31 @@ float GeometrySchlickGGX(float NdotV, float Roughness) return Numerator / Denominator; } -float GeometrySmith(float NdotV, float NdotL, float Roughness) +float PunctualGeometrySchlickGGX(float NdotV, float Roughness) { - float GGX1 = GeometrySchlickGGX(NdotV, Roughness); - float GGX2 = GeometrySchlickGGX(NdotL, Roughness); + float R = Roughness + 1; + // (Rough + 1)^2 / 8 for Punctual Lights + // Rough^2 / 2 for IBL + float K = (R * R) / 8.0; + + float Numerator = NdotV; + float Denominator = NdotV * (1.0f - K) + K; + + return Numerator / Denominator; +} + +float IBLGeometrySmith(float NdotV, float NdotL, float Roughness) +{ + float GGX1 = IBLGeometrySchlickGGX(NdotV, Roughness); + float GGX2 = IBLGeometrySchlickGGX(NdotL, Roughness); + + return GGX1 * GGX2; +} + +float PunctualGeometrySmith(float NdotV, float NdotL, float Roughness) +{ + float GGX1 = PunctualGeometrySchlickGGX(NdotV, Roughness); + float GGX2 = PunctualGeometrySchlickGGX(NdotL, Roughness); return GGX1 * GGX2; } @@ -136,7 +157,7 @@ float2 IntegrateBRDF(float NdotV, float Roughness) if (NdotL > 0.0f) { - float G = GeometrySmith(NdotV, NdotL, Roughness); + float G = IBLGeometrySmith(NdotV, NdotL, Roughness); float G_Vis = (G * VdotH) / max((NdotH * NdotV), 0.0001f); float Fc = pow(1.0f - VdotH, 5.0f); diff --git a/samples/03_model_render/shader/slang/model.slang b/samples/03_model_render/shader/slang/model.slang index 6bfbaf8..ea4d6d7 100644 --- a/samples/03_model_render/shader/slang/model.slang +++ b/samples/03_model_render/shader/slang/model.slang @@ -74,19 +74,6 @@ VS_Output vsmain(VS_Input stageInput) return stageOutput; } -struct FS_Input -{ - float4 InPosition : POSITION; - float4 InNormal : NORMAL; - float4 InColor : COLOR0; - float2 InUV0 : TEXCOORD0; -}; - -struct FS_Output -{ - float4 ColorTarget : SV_Target0; -}; - float4 GetAlbedo(float2 uv, float4 color) { float4 albedoFactor = pcb.materialBuffer[NonUniformResourceIndex(pcb.materialIdx)].albedoFactor; @@ -200,9 +187,9 @@ float3 GetPBRContrib(float3 Albedo, float3 LightColor, float3 ViewDir, float3 No float NdotH = max(dot(Normal, Halfway), 0.0f); float3 Radiance = LightColor * Attenuation; - + float NormalDistribution = TrowbridgeReitzGGX(NdotH, Roughness); - float Geometry = GeometrySmith(NdotV, NdotL, Roughness); + float Geometry = PunctualGeometrySmith(NdotV, NdotL, Roughness); float3 Fresnel = FresnelSchlickRoughness(CosineFactor, F_0, Roughness); float3 Numerator = (NormalDistribution * Geometry) * Fresnel; @@ -214,7 +201,7 @@ float3 GetPBRContrib(float3 Albedo, float3 LightColor, float3 ViewDir, float3 No K_Diffuse *= 1.0f - Metallic; - return NdotL * Radiance * (K_Diffuse * Albedo / PI + Specular); + return NdotL * Radiance * ((K_Diffuse * Albedo / PI) + Specular); } float3 GetPointLightInfluence(float3 Albedo, float2 MetalRough, float3 Position, float3 Normal) @@ -346,32 +333,33 @@ float3 GetAmbientInfluence(float3 Albedo, float2 MetalRough, float3 Position, fl } [shader("fragment")] -FS_Output fsmain(FS_Input StageInput) +float4 fsmain( + float4 inPosition: POSITION, + float4 inNormal: NORMAL, + float4 inColor: COLOR, + float2 inUV0: TEXCOORD0, +) : SV_Target0 { - FS_Output Output; - // TODO: This should be invalid on the CPU side. if (pcb.materialIdx < 0) { - Output.ColorTarget = float4(1.0f, 0.0f, 1.0f, 1.0f); - return Output; + return float4(1.0f, 0.0f, 1.0f, 1.0f); } - float3 Position = StageInput.InPosition.xyz; - float3 Normal = GetNormal(Position, StageInput.InNormal.xyz, StageInput.InUV0); + float3 position = inPosition.xyz; + float3 normal = GetNormal(position, inNormal.xyz, inUV0); - float4 AlbedoAlpha = GetAlbedo(StageInput.InUV0, StageInput.InColor); - float3 Albedo = AlbedoAlpha.rgb; - float Alpha = AlbedoAlpha.a; - float2 MetalRough = GetMetalRough(StageInput.InUV0); - float3 Emission = GetEmissive(StageInput.InUV0); - float Occlusion = GetOcclusion(StageInput.InUV0); + float4 albedoAlpha = GetAlbedo(inUV0, inColor); + float3 albedo = albedoAlpha.rgb; + float alpha = albedoAlpha.a; + float2 metalRough = GetMetalRough(inUV0); + float3 emission = GetEmissive(inUV0); + float occlusion = GetOcclusion(inUV0); - float3 DirectionalLightLum = GetDirectionalLightInfluence(Albedo, MetalRough, Position, Normal); - float3 PointLighLum = GetPointLightInfluence(Albedo, MetalRough, Position, Normal); - float3 AmbientLum = GetAmbientInfluence(Albedo, MetalRough, Position, Normal, Occlusion); - float3 Color = DirectionalLightLum + /*PointLighLum +*/ AmbientLum; + float3 directionalLightLum = GetDirectionalLightInfluence(albedo, metalRough, position, normal); + float3 pointLighLum = GetPointLightInfluence(albedo, metalRough, position, normal); + float3 ambientLum = GetAmbientInfluence(albedo, metalRough, position, normal, occlusion); + float3 color = directionalLightLum + pointLighLum + ambientLum; - Output.ColorTarget = float4(Uncharted2Tonemap(Color + Emission), Alpha); - return Output; + return float4(Uncharted2Tonemap(color + emission), alpha); }