Formalize builtin fullscreen shaders
This commit is contained in:
@@ -1,79 +0,0 @@
|
||||
// XC_BUILTIN_SKYBOX_OPENGL_PS
|
||||
#version 430
|
||||
|
||||
layout(binding = 0) uniform sampler2D uSkyboxPanoramicTexture;
|
||||
layout(binding = 1) uniform samplerCube uSkyboxTexture;
|
||||
|
||||
layout(std140, binding = 0) uniform EnvironmentConstants {
|
||||
vec4 gSkyboxTopColor;
|
||||
vec4 gSkyboxHorizonColor;
|
||||
vec4 gSkyboxBottomColor;
|
||||
vec4 gCameraRightAndTanHalfFov;
|
||||
vec4 gCameraUpAndAspect;
|
||||
vec4 gCameraForwardAndUnused;
|
||||
};
|
||||
|
||||
layout(std140, binding = 1) uniform MaterialConstants {
|
||||
vec4 gSkyboxTintAndExposure;
|
||||
vec4 gSkyboxRotationAndMode;
|
||||
};
|
||||
|
||||
in vec2 vNdc;
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
||||
const float XC_PI = 3.14159265358979323846;
|
||||
const float XC_INV_PI = 0.31830988618379067154;
|
||||
const float XC_INV_TWO_PI = 0.15915494309189533577;
|
||||
|
||||
vec3 EvaluateProceduralSkybox(vec3 viewRay) {
|
||||
float vertical = clamp(viewRay.y, -1.0, 1.0);
|
||||
vec3 color = gSkyboxHorizonColor.rgb;
|
||||
if (vertical >= 0.0) {
|
||||
color = mix(gSkyboxHorizonColor.rgb, gSkyboxTopColor.rgb, pow(clamp(vertical, 0.0, 1.0), 0.65));
|
||||
} else {
|
||||
color = mix(gSkyboxHorizonColor.rgb, gSkyboxBottomColor.rgb, pow(clamp(-vertical, 0.0, 1.0), 0.55));
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
vec3 RotateAroundY(vec3 viewRay) {
|
||||
float rotation = gSkyboxRotationAndMode.x;
|
||||
float sinTheta = sin(rotation);
|
||||
float cosTheta = cos(rotation);
|
||||
return normalize(vec3(
|
||||
viewRay.x * cosTheta - viewRay.z * sinTheta,
|
||||
viewRay.y,
|
||||
viewRay.x * sinTheta + viewRay.z * cosTheta));
|
||||
}
|
||||
|
||||
vec2 ComputePanoramicUv(vec3 viewRay) {
|
||||
vec3 rotatedRay = RotateAroundY(viewRay);
|
||||
float u = fract(atan(rotatedRay.z, rotatedRay.x) * XC_INV_TWO_PI + 0.5);
|
||||
float v = acos(clamp(rotatedRay.y, -1.0, 1.0)) * XC_INV_PI;
|
||||
return vec2(u, clamp(v, 0.0, 1.0));
|
||||
}
|
||||
|
||||
void main() {
|
||||
float tanHalfFov = gCameraRightAndTanHalfFov.w;
|
||||
float aspect = gCameraUpAndAspect.w;
|
||||
|
||||
vec3 viewRay = normalize(
|
||||
gCameraForwardAndUnused.xyz +
|
||||
vNdc.x * aspect * tanHalfFov * gCameraRightAndTanHalfFov.xyz +
|
||||
vNdc.y * tanHalfFov * gCameraUpAndAspect.xyz);
|
||||
|
||||
vec3 color = EvaluateProceduralSkybox(viewRay);
|
||||
if (gSkyboxRotationAndMode.y > 1.5) {
|
||||
color = texture(uSkyboxTexture, RotateAroundY(viewRay)).rgb *
|
||||
gSkyboxTintAndExposure.rgb *
|
||||
gSkyboxTintAndExposure.w;
|
||||
} else if (gSkyboxRotationAndMode.y > 0.5) {
|
||||
color = texture(uSkyboxPanoramicTexture, ComputePanoramicUv(viewRay)).rgb *
|
||||
gSkyboxTintAndExposure.rgb *
|
||||
gSkyboxTintAndExposure.w;
|
||||
}
|
||||
|
||||
fragColor = vec4(color, 1.0);
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
// XC_BUILTIN_SKYBOX_VULKAN_PS
|
||||
#version 450
|
||||
|
||||
layout(set = 0, binding = 0, std140) uniform EnvironmentConstants {
|
||||
vec4 gSkyboxTopColor;
|
||||
vec4 gSkyboxHorizonColor;
|
||||
vec4 gSkyboxBottomColor;
|
||||
vec4 gCameraRightAndTanHalfFov;
|
||||
vec4 gCameraUpAndAspect;
|
||||
vec4 gCameraForwardAndUnused;
|
||||
};
|
||||
|
||||
layout(set = 1, binding = 0, std140) uniform MaterialConstants {
|
||||
vec4 gSkyboxTintAndExposure;
|
||||
vec4 gSkyboxRotationAndMode;
|
||||
};
|
||||
|
||||
layout(set = 2, binding = 0) uniform texture2D uSkyboxPanoramicTexture;
|
||||
layout(set = 3, binding = 0) uniform textureCube uSkyboxTexture;
|
||||
layout(set = 4, binding = 0) uniform sampler uLinearSampler;
|
||||
|
||||
layout(location = 0) in vec2 vNdc;
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
||||
const float XC_PI = 3.14159265358979323846;
|
||||
const float XC_INV_PI = 0.31830988618379067154;
|
||||
const float XC_INV_TWO_PI = 0.15915494309189533577;
|
||||
|
||||
vec3 EvaluateProceduralSkybox(vec3 viewRay) {
|
||||
float vertical = clamp(viewRay.y, -1.0, 1.0);
|
||||
vec3 color = gSkyboxHorizonColor.rgb;
|
||||
if (vertical >= 0.0) {
|
||||
color = mix(gSkyboxHorizonColor.rgb, gSkyboxTopColor.rgb, pow(clamp(vertical, 0.0, 1.0), 0.65));
|
||||
} else {
|
||||
color = mix(gSkyboxHorizonColor.rgb, gSkyboxBottomColor.rgb, pow(clamp(-vertical, 0.0, 1.0), 0.55));
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
vec3 RotateAroundY(vec3 viewRay) {
|
||||
float rotation = gSkyboxRotationAndMode.x;
|
||||
float sinTheta = sin(rotation);
|
||||
float cosTheta = cos(rotation);
|
||||
return normalize(vec3(
|
||||
viewRay.x * cosTheta - viewRay.z * sinTheta,
|
||||
viewRay.y,
|
||||
viewRay.x * sinTheta + viewRay.z * cosTheta));
|
||||
}
|
||||
|
||||
vec2 ComputePanoramicUv(vec3 viewRay) {
|
||||
vec3 rotatedRay = RotateAroundY(viewRay);
|
||||
float u = fract(atan(rotatedRay.z, rotatedRay.x) * XC_INV_TWO_PI + 0.5);
|
||||
float v = acos(clamp(rotatedRay.y, -1.0, 1.0)) * XC_INV_PI;
|
||||
return vec2(u, clamp(v, 0.0, 1.0));
|
||||
}
|
||||
|
||||
void main() {
|
||||
float tanHalfFov = gCameraRightAndTanHalfFov.w;
|
||||
float aspect = gCameraUpAndAspect.w;
|
||||
|
||||
vec3 viewRay = normalize(
|
||||
gCameraForwardAndUnused.xyz +
|
||||
vNdc.x * aspect * tanHalfFov * gCameraRightAndTanHalfFov.xyz +
|
||||
vNdc.y * tanHalfFov * gCameraUpAndAspect.xyz);
|
||||
|
||||
vec3 color = EvaluateProceduralSkybox(viewRay);
|
||||
if (gSkyboxRotationAndMode.y > 1.5) {
|
||||
color = texture(samplerCube(uSkyboxTexture, uLinearSampler), RotateAroundY(viewRay)).rgb *
|
||||
gSkyboxTintAndExposure.rgb *
|
||||
gSkyboxTintAndExposure.w;
|
||||
} else if (gSkyboxRotationAndMode.y > 0.5) {
|
||||
color = texture(sampler2D(uSkyboxPanoramicTexture, uLinearSampler), ComputePanoramicUv(viewRay)).rgb *
|
||||
gSkyboxTintAndExposure.rgb *
|
||||
gSkyboxTintAndExposure.w;
|
||||
}
|
||||
|
||||
fragColor = vec4(color, 1.0);
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
// XC_BUILTIN_SKYBOX_D3D12_PS
|
||||
Texture2D gSkyboxPanoramicTexture : register(t0);
|
||||
TextureCube gSkyboxTexture : register(t1);
|
||||
SamplerState gLinearSampler : register(s0);
|
||||
|
||||
cbuffer EnvironmentConstants : register(b0) {
|
||||
float4 gSkyboxTopColor;
|
||||
float4 gSkyboxHorizonColor;
|
||||
float4 gSkyboxBottomColor;
|
||||
float4 gCameraRightAndTanHalfFov;
|
||||
float4 gCameraUpAndAspect;
|
||||
float4 gCameraForwardAndUnused;
|
||||
}
|
||||
|
||||
cbuffer MaterialConstants : register(b1) {
|
||||
float4 gSkyboxTintAndExposure;
|
||||
float4 gSkyboxRotationAndMode;
|
||||
}
|
||||
|
||||
struct PSInput {
|
||||
float4 position : SV_POSITION;
|
||||
float2 ndc : TEXCOORD0;
|
||||
};
|
||||
|
||||
static const float XC_PI = 3.14159265358979323846f;
|
||||
static const float XC_INV_PI = 0.31830988618379067154f;
|
||||
static const float XC_INV_TWO_PI = 0.15915494309189533577f;
|
||||
|
||||
float3 EvaluateProceduralSkybox(float3 viewRay) {
|
||||
const float vertical = clamp(viewRay.y, -1.0f, 1.0f);
|
||||
float3 color = gSkyboxHorizonColor.rgb;
|
||||
if (vertical >= 0.0f) {
|
||||
color = lerp(gSkyboxHorizonColor.rgb, gSkyboxTopColor.rgb, pow(saturate(vertical), 0.65f));
|
||||
} else {
|
||||
color = lerp(gSkyboxHorizonColor.rgb, gSkyboxBottomColor.rgb, pow(saturate(-vertical), 0.55f));
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
float3 RotateAroundY(float3 viewRay) {
|
||||
const float rotation = gSkyboxRotationAndMode.x;
|
||||
const float sinTheta = sin(rotation);
|
||||
const float cosTheta = cos(rotation);
|
||||
return normalize(float3(
|
||||
viewRay.x * cosTheta - viewRay.z * sinTheta,
|
||||
viewRay.y,
|
||||
viewRay.x * sinTheta + viewRay.z * cosTheta));
|
||||
}
|
||||
|
||||
float2 ComputePanoramicUv(float3 viewRay) {
|
||||
const float3 rotatedRay = RotateAroundY(viewRay);
|
||||
const float u = frac(atan2(rotatedRay.z, rotatedRay.x) * XC_INV_TWO_PI + 0.5f);
|
||||
const float v = acos(clamp(rotatedRay.y, -1.0f, 1.0f)) * XC_INV_PI;
|
||||
return float2(u, saturate(v));
|
||||
}
|
||||
|
||||
float4 MainPS(PSInput input) : SV_Target {
|
||||
const float tanHalfFov = gCameraRightAndTanHalfFov.w;
|
||||
const float aspect = gCameraUpAndAspect.w;
|
||||
|
||||
float3 viewRay = normalize(
|
||||
gCameraForwardAndUnused.xyz +
|
||||
input.ndc.x * aspect * tanHalfFov * gCameraRightAndTanHalfFov.xyz +
|
||||
input.ndc.y * tanHalfFov * gCameraUpAndAspect.xyz);
|
||||
|
||||
float3 color = EvaluateProceduralSkybox(viewRay);
|
||||
if (gSkyboxRotationAndMode.y > 1.5f) {
|
||||
color = gSkyboxTexture.Sample(gLinearSampler, RotateAroundY(viewRay)).rgb *
|
||||
gSkyboxTintAndExposure.rgb *
|
||||
gSkyboxTintAndExposure.w;
|
||||
} else if (gSkyboxRotationAndMode.y > 0.5f) {
|
||||
color = gSkyboxPanoramicTexture.Sample(gLinearSampler, ComputePanoramicUv(viewRay)).rgb *
|
||||
gSkyboxTintAndExposure.rgb *
|
||||
gSkyboxTintAndExposure.w;
|
||||
}
|
||||
|
||||
return float4(color, 1.0f);
|
||||
}
|
||||
@@ -8,26 +8,121 @@ Shader "Builtin Skybox"
|
||||
_MainTex ("Panoramic", 2D) = "white" [Semantic(SkyboxPanoramicTexture)]
|
||||
_Tex ("Cubemap (HDR)", Cube) = "white" [Semantic(SkyboxTexture)]
|
||||
}
|
||||
HLSLINCLUDE
|
||||
cbuffer EnvironmentConstants : register(b0)
|
||||
{
|
||||
float4 gSkyboxTopColor;
|
||||
float4 gSkyboxHorizonColor;
|
||||
float4 gSkyboxBottomColor;
|
||||
float4 gCameraRightAndTanHalfFov;
|
||||
float4 gCameraUpAndAspect;
|
||||
float4 gCameraForwardAndUnused;
|
||||
};
|
||||
|
||||
cbuffer MaterialConstants : register(b1)
|
||||
{
|
||||
float4 gSkyboxTintAndExposure;
|
||||
float4 gSkyboxRotationAndMode;
|
||||
};
|
||||
|
||||
Texture2D SkyboxPanoramicTexture : register(t0);
|
||||
TextureCube SkyboxTexture : register(t1);
|
||||
SamplerState LinearClampSampler : register(s0);
|
||||
|
||||
struct VSOutput
|
||||
{
|
||||
float4 position : SV_POSITION;
|
||||
float2 ndc : TEXCOORD0;
|
||||
};
|
||||
|
||||
static const float XC_PI = 3.14159265358979323846f;
|
||||
static const float XC_INV_PI = 0.31830988618379067154f;
|
||||
static const float XC_INV_TWO_PI = 0.15915494309189533577f;
|
||||
|
||||
VSOutput MainVS(uint vertexId : SV_VertexID)
|
||||
{
|
||||
const float2 positions[3] = {
|
||||
float2(-1.0f, -1.0f),
|
||||
float2(-1.0f, 3.0f),
|
||||
float2( 3.0f, -1.0f)
|
||||
};
|
||||
|
||||
VSOutput output;
|
||||
output.position = float4(positions[vertexId], 1.0f, 1.0f);
|
||||
output.ndc = positions[vertexId];
|
||||
return output;
|
||||
}
|
||||
|
||||
float3 EvaluateProceduralSkybox(float3 viewRay)
|
||||
{
|
||||
const float vertical = clamp(viewRay.y, -1.0f, 1.0f);
|
||||
float3 color = gSkyboxHorizonColor.rgb;
|
||||
if (vertical >= 0.0f) {
|
||||
color = lerp(gSkyboxHorizonColor.rgb, gSkyboxTopColor.rgb, pow(saturate(vertical), 0.65f));
|
||||
} else {
|
||||
color = lerp(gSkyboxHorizonColor.rgb, gSkyboxBottomColor.rgb, pow(saturate(-vertical), 0.55f));
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
float3 RotateAroundY(float3 viewRay)
|
||||
{
|
||||
const float rotation = gSkyboxRotationAndMode.x;
|
||||
const float sinTheta = sin(rotation);
|
||||
const float cosTheta = cos(rotation);
|
||||
return normalize(float3(
|
||||
viewRay.x * cosTheta - viewRay.z * sinTheta,
|
||||
viewRay.y,
|
||||
viewRay.x * sinTheta + viewRay.z * cosTheta));
|
||||
}
|
||||
|
||||
float2 ComputePanoramicUv(float3 viewRay)
|
||||
{
|
||||
const float3 rotatedRay = RotateAroundY(viewRay);
|
||||
const float u = frac(atan2(rotatedRay.z, rotatedRay.x) * XC_INV_TWO_PI + 0.5f);
|
||||
const float v = acos(clamp(rotatedRay.y, -1.0f, 1.0f)) * XC_INV_PI;
|
||||
return float2(u, saturate(v));
|
||||
}
|
||||
|
||||
float4 MainPS(VSOutput input) : SV_TARGET
|
||||
{
|
||||
const float tanHalfFov = gCameraRightAndTanHalfFov.w;
|
||||
const float aspect = gCameraUpAndAspect.w;
|
||||
|
||||
const float3 viewRay = normalize(
|
||||
gCameraForwardAndUnused.xyz +
|
||||
input.ndc.x * aspect * tanHalfFov * gCameraRightAndTanHalfFov.xyz +
|
||||
input.ndc.y * tanHalfFov * gCameraUpAndAspect.xyz);
|
||||
|
||||
float3 color = EvaluateProceduralSkybox(viewRay);
|
||||
if (gSkyboxRotationAndMode.y > 1.5f) {
|
||||
color = SkyboxTexture.Sample(LinearClampSampler, RotateAroundY(viewRay)).rgb *
|
||||
gSkyboxTintAndExposure.rgb *
|
||||
gSkyboxTintAndExposure.w;
|
||||
} else if (gSkyboxRotationAndMode.y > 0.5f) {
|
||||
color = SkyboxPanoramicTexture.Sample(LinearClampSampler, ComputePanoramicUv(viewRay)).rgb *
|
||||
gSkyboxTintAndExposure.rgb *
|
||||
gSkyboxTintAndExposure.w;
|
||||
}
|
||||
|
||||
return float4(color, 1.0f);
|
||||
}
|
||||
ENDHLSL
|
||||
SubShader
|
||||
{
|
||||
Pass
|
||||
{
|
||||
Name "Skybox"
|
||||
Tags { "LightMode" = "Skybox" }
|
||||
Resources
|
||||
{
|
||||
EnvironmentConstants (ConstantBuffer, 0, 0) [Semantic(Environment)]
|
||||
MaterialConstants (ConstantBuffer, 1, 0) [Semantic(Material)]
|
||||
SkyboxPanoramicTexture (Texture2D, 2, 0) [Semantic(SkyboxPanoramicTexture)]
|
||||
SkyboxTexture (TextureCube, 3, 0) [Semantic(SkyboxTexture)]
|
||||
LinearClampSampler (Sampler, 4, 0) [Semantic(LinearClampSampler)]
|
||||
}
|
||||
Cull Off
|
||||
ZWrite Off
|
||||
ZTest LEqual
|
||||
Blend Off
|
||||
HLSLPROGRAM
|
||||
#pragma target 4.5
|
||||
#pragma vertex MainVS
|
||||
#pragma fragment MainPS
|
||||
#pragma backend D3D12 HLSL "skybox.vs.hlsl" "skybox.ps.hlsl" vs_5_0 ps_5_0
|
||||
#pragma backend OpenGL GLSL "skybox.vert.glsl" "skybox.frag.glsl"
|
||||
#pragma backend Vulkan GLSL "skybox.vert.vk.glsl" "skybox.frag.vk.glsl"
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
// XC_BUILTIN_SKYBOX_OPENGL_VS
|
||||
#version 430
|
||||
|
||||
out vec2 vNdc;
|
||||
|
||||
void main() {
|
||||
const vec2 positions[3] = vec2[3](
|
||||
vec2(-1.0, -1.0),
|
||||
vec2(-1.0, 3.0),
|
||||
vec2( 3.0, -1.0)
|
||||
);
|
||||
|
||||
vec2 position = positions[gl_VertexID];
|
||||
gl_Position = vec4(position, 1.0, 1.0);
|
||||
vNdc = position;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
// XC_BUILTIN_SKYBOX_VULKAN_VS
|
||||
#version 450
|
||||
|
||||
layout(location = 0) out vec2 vNdc;
|
||||
|
||||
void main() {
|
||||
const vec2 positions[3] = vec2[3](
|
||||
vec2(-1.0, -1.0),
|
||||
vec2(-1.0, 3.0),
|
||||
vec2( 3.0, -1.0)
|
||||
);
|
||||
|
||||
vec2 position = positions[gl_VertexIndex];
|
||||
gl_Position = vec4(position, 1.0, 1.0);
|
||||
vNdc = position;
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
// XC_BUILTIN_SKYBOX_D3D12_VS
|
||||
struct VSOutput {
|
||||
float4 position : SV_POSITION;
|
||||
float2 ndc : TEXCOORD0;
|
||||
};
|
||||
|
||||
VSOutput MainVS(uint vertexId : SV_VertexID) {
|
||||
const float2 positions[3] = {
|
||||
float2(-1.0f, -1.0f),
|
||||
float2(-1.0f, 3.0f),
|
||||
float2( 3.0f, -1.0f)
|
||||
};
|
||||
|
||||
VSOutput output;
|
||||
output.position = float4(positions[vertexId], 1.0f, 1.0f);
|
||||
output.ndc = positions[vertexId];
|
||||
return output;
|
||||
}
|
||||
Reference in New Issue
Block a user