280 lines
8.8 KiB
HLSL
280 lines
8.8 KiB
HLSL
// Ported from CGinc version
|
|
|
|
#ifndef UNITY_CUSTOM_TEXTURE_INCLUDED
|
|
#define UNITY_CUSTOM_TEXTURE_INCLUDED
|
|
|
|
#ifndef UNITY_PI
|
|
#define UNITY_PI 3.14159265358979323846
|
|
#endif
|
|
|
|
// Keep in sync with CustomRenderTexture.h
|
|
#define kCustomTextureBatchSize 16
|
|
|
|
#define CRT_DIMENSION_2D 0.0
|
|
#define CRT_DIMENSION_3D 1.0
|
|
#define CRT_DIMENSION_CUBE 2.0
|
|
|
|
struct appdata_customrendertexture
|
|
{
|
|
uint vertexID : SV_VertexID;
|
|
};
|
|
|
|
// User facing vertex to fragment shader structure
|
|
struct v2f_customrendertexture
|
|
{
|
|
float4 vertex : SV_POSITION;
|
|
float3 localTexcoord : TEXCOORD0; // Texcoord local to the update zone (== globalTexcoord if no partial update zone is specified)
|
|
float3 globalTexcoord : TEXCOORD1; // Texcoord relative to the complete custom texture
|
|
uint primitiveID : TEXCOORD2; // Index of the update zone (correspond to the index in the updateZones of the Custom Texture)
|
|
float3 direction : TEXCOORD3; // For cube textures, direction of the pixel being rendered in the cubemap
|
|
};
|
|
|
|
float2 CustomRenderTextureRotate2D(float2 pos, float angle)
|
|
{
|
|
float sn = sin(angle);
|
|
float cs = cos(angle);
|
|
|
|
return float2( pos.x * cs - pos.y * sn, pos.x * sn + pos.y * cs);
|
|
}
|
|
|
|
// Built-in unity functions and matrices:
|
|
|
|
float4 _Time, _SinTime, _CosTime, unity_DeltaTime;
|
|
|
|
// ================================
|
|
// PER FRAME CONSTANTS
|
|
// ================================
|
|
#if defined(USING_STEREO_MATRICES)
|
|
#define glstate_matrix_projection unity_StereoMatrixP[unity_StereoEyeIndex]
|
|
#define unity_MatrixV unity_StereoMatrixV[unity_StereoEyeIndex]
|
|
#define unity_MatrixInvV unity_StereoMatrixInvV[unity_StereoEyeIndex]
|
|
#define unity_MatrixVP unity_StereoMatrixVP[unity_StereoEyeIndex]
|
|
|
|
#define unity_CameraProjection unity_StereoCameraProjection[unity_StereoEyeIndex]
|
|
#define unity_CameraInvProjection unity_StereoCameraInvProjection[unity_StereoEyeIndex]
|
|
#define unity_WorldToCamera unity_StereoWorldToCamera[unity_StereoEyeIndex]
|
|
#define unity_CameraToWorld unity_StereoCameraToWorld[unity_StereoEyeIndex]
|
|
#else
|
|
#if !defined(USING_STEREO_MATRICES)
|
|
float4x4 glstate_matrix_projection;
|
|
float4x4 unity_MatrixV;
|
|
float4x4 unity_MatrixInvV;
|
|
float4x4 unity_MatrixVP;
|
|
float4x4 unity_ObjectToWorld;
|
|
float4 unity_StereoScaleOffset;
|
|
#endif
|
|
#endif
|
|
|
|
// Internal
|
|
float4 CustomRenderTextureCenters[kCustomTextureBatchSize];
|
|
float4 CustomRenderTextureSizesAndRotations[kCustomTextureBatchSize];
|
|
float CustomRenderTexturePrimitiveIDs[kCustomTextureBatchSize];
|
|
|
|
float4 CustomRenderTextureParameters;
|
|
#define CustomRenderTextureUpdateSpace CustomRenderTextureParameters.x // Normalized(0)/PixelSpace(1)
|
|
#define CustomRenderTexture3DTexcoordW CustomRenderTextureParameters.y
|
|
#define CustomRenderTextureIs3D (CustomRenderTextureParameters.z == CRT_DIMENSION_3D)
|
|
#define CustomRenderTextureDimension CustomRenderTextureParameters.z
|
|
|
|
// User facing uniform variables
|
|
float4 _CustomRenderTextureInfo; // x = width, y = height, z = depth, w = face/3DSlice
|
|
|
|
// Helpers
|
|
#define _CustomRenderTextureWidth _CustomRenderTextureInfo.x
|
|
#define _CustomRenderTextureHeight _CustomRenderTextureInfo.y
|
|
#define _CustomRenderTextureDepth _CustomRenderTextureInfo.z
|
|
|
|
// Those two are mutually exclusive so we can use the same slot
|
|
#define _CustomRenderTextureCubeFace _CustomRenderTextureInfo.w
|
|
#define _CustomRenderTexture3DSlice _CustomRenderTextureInfo.w
|
|
|
|
float _CustomRenderTextureMipLevel;
|
|
|
|
TEXTURE2D(_SelfTexture2D);
|
|
float4 _SelfTexture2D_TexelSize;
|
|
SAMPLER(sampler_SelfTexture2D);
|
|
|
|
TEXTURECUBE(_SelfTextureCube);
|
|
float4 _SelfTextureCube_TexelSize;
|
|
SAMPLER(sampler_SelfTextureCube);
|
|
|
|
TEXTURE3D(_SelfTexture3D);
|
|
float4 _SelfTexture3D_TexelSize;
|
|
SAMPLER(sampler_SelfTexture3D);
|
|
|
|
float3 ComputeCubemapDirectionFromUV(float2 uv, int cubeFace)
|
|
{
|
|
float2 xy = uv * 2.0 - 1.0;
|
|
float3 direction;
|
|
if(cubeFace == 0.0)
|
|
{
|
|
direction = normalize(float3(1.0, -xy.y, -xy.x));
|
|
}
|
|
else if(cubeFace == 1.0)
|
|
{
|
|
direction = normalize(float3(-1.0, -xy.y, xy.x));
|
|
}
|
|
else if(cubeFace == 2.0)
|
|
{
|
|
direction = normalize(float3(xy.x, 1.0, xy.y));
|
|
}
|
|
else if(cubeFace == 3.0)
|
|
{
|
|
direction = normalize(float3(xy.x, -1.0, -xy.y));
|
|
}
|
|
else if(cubeFace == 4.0)
|
|
{
|
|
direction = normalize(float3(xy.x, -xy.y, 1.0));
|
|
}
|
|
else if(cubeFace == 5.0)
|
|
{
|
|
direction = normalize(float3(-xy.x, -xy.y, -1.0));
|
|
}
|
|
else
|
|
{
|
|
direction = float3(0, 0, 0);
|
|
}
|
|
|
|
return direction;
|
|
}
|
|
|
|
float3 CustomRenderTextureComputeCubeDirection(float2 globalTexcoord)
|
|
{
|
|
return ComputeCubemapDirectionFromUV(globalTexcoord, _CustomRenderTextureCubeFace);
|
|
}
|
|
|
|
// standard custom texture vertex shader that should always be used
|
|
v2f_customrendertexture CustomRenderTextureVertexShader(appdata_customrendertexture IN)
|
|
{
|
|
v2f_customrendertexture OUT;
|
|
|
|
#if UNITY_UV_STARTS_AT_TOP
|
|
const float2 vertexPositions[6] =
|
|
{
|
|
{ -1.0f, 1.0f },
|
|
{ -1.0f, -1.0f },
|
|
{ 1.0f, -1.0f },
|
|
{ 1.0f, 1.0f },
|
|
{ -1.0f, 1.0f },
|
|
{ 1.0f, -1.0f }
|
|
};
|
|
|
|
const float2 texCoords[6] =
|
|
{
|
|
{ 0.0f, 0.0f },
|
|
{ 0.0f, 1.0f },
|
|
{ 1.0f, 1.0f },
|
|
{ 1.0f, 0.0f },
|
|
{ 0.0f, 0.0f },
|
|
{ 1.0f, 1.0f }
|
|
};
|
|
#else
|
|
const float2 vertexPositions[6] =
|
|
{
|
|
{ 1.0f, 1.0f },
|
|
{ -1.0f, -1.0f },
|
|
{ -1.0f, 1.0f },
|
|
{ -1.0f, -1.0f },
|
|
{ 1.0f, 1.0f },
|
|
{ 1.0f, -1.0f }
|
|
};
|
|
|
|
const float2 texCoords[6] =
|
|
{
|
|
{ 1.0f, 1.0f },
|
|
{ 0.0f, 0.0f },
|
|
{ 0.0f, 1.0f },
|
|
{ 0.0f, 0.0f },
|
|
{ 1.0f, 1.0f },
|
|
{ 1.0f, 0.0f }
|
|
};
|
|
#endif
|
|
|
|
uint primitiveID = IN.vertexID / 6;
|
|
uint vertexID = IN.vertexID % 6;
|
|
float3 updateZoneCenter = CustomRenderTextureCenters[primitiveID].xyz;
|
|
float3 updateZoneSize = CustomRenderTextureSizesAndRotations[primitiveID].xyz;
|
|
float rotation = CustomRenderTextureSizesAndRotations[primitiveID].w * UNITY_PI / 180.0f;
|
|
|
|
#if !UNITY_UV_STARTS_AT_TOP
|
|
rotation = -rotation;
|
|
#endif
|
|
|
|
// Normalize rect if needed
|
|
if (CustomRenderTextureUpdateSpace > 0.0) // Pixel space
|
|
{
|
|
// Normalize xy because we need it in clip space.
|
|
updateZoneCenter.xy /= _CustomRenderTextureInfo.xy;
|
|
updateZoneSize.xy /= _CustomRenderTextureInfo.xy;
|
|
}
|
|
else // normalized space
|
|
{
|
|
// Un-normalize depth because we need actual slice index for culling
|
|
updateZoneCenter.z *= _CustomRenderTextureInfo.z;
|
|
updateZoneSize.z *= _CustomRenderTextureInfo.z;
|
|
}
|
|
|
|
// Compute rotation
|
|
|
|
// Compute quad vertex position
|
|
float2 clipSpaceCenter = updateZoneCenter.xy * 2.0 - 1.0;
|
|
float2 pos = vertexPositions[vertexID] * updateZoneSize.xy;
|
|
pos = CustomRenderTextureRotate2D(pos, rotation);
|
|
pos.x += clipSpaceCenter.x;
|
|
#if UNITY_UV_STARTS_AT_TOP
|
|
pos.y += clipSpaceCenter.y;
|
|
#else
|
|
pos.y -= clipSpaceCenter.y;
|
|
#endif
|
|
|
|
// For 3D texture, cull quads outside of the update zone
|
|
// This is neeeded in additional to the preliminary minSlice/maxSlice done on the CPU because update zones can be disjointed.
|
|
// ie: slices [1..5] and [10..15] for two differents zones so we need to cull out slices 0 and [6..9]
|
|
if (CustomRenderTextureIs3D)
|
|
{
|
|
int minSlice = (int)(updateZoneCenter.z - updateZoneSize.z * 0.5);
|
|
int maxSlice = minSlice + (int)updateZoneSize.z;
|
|
if (_CustomRenderTexture3DSlice < minSlice || _CustomRenderTexture3DSlice >= maxSlice)
|
|
{
|
|
pos.xy = float2(1000.0, 1000.0); // Vertex outside of ncs
|
|
}
|
|
}
|
|
|
|
OUT.vertex = float4(pos, 0.0, 1.0);
|
|
OUT.primitiveID = asuint(CustomRenderTexturePrimitiveIDs[primitiveID]);
|
|
OUT.localTexcoord = float3(texCoords[vertexID], CustomRenderTexture3DTexcoordW);
|
|
OUT.globalTexcoord = float3(pos.xy * 0.5 + 0.5, CustomRenderTexture3DTexcoordW);
|
|
#if UNITY_UV_STARTS_AT_TOP
|
|
OUT.globalTexcoord.y = 1.0 - OUT.globalTexcoord.y;
|
|
#endif
|
|
OUT.direction = CustomRenderTextureComputeCubeDirection(OUT.globalTexcoord.xy);
|
|
|
|
return OUT;
|
|
}
|
|
|
|
struct appdata_init_customrendertexture
|
|
{
|
|
float4 vertex : POSITION;
|
|
float2 texcoord : TEXCOORD0;
|
|
};
|
|
|
|
// User facing vertex to fragment structure for initialization materials
|
|
struct v2f_init_customrendertexture
|
|
{
|
|
float4 vertex : SV_POSITION;
|
|
float3 texcoord : TEXCOORD0;
|
|
float3 direction : TEXCOORD1;
|
|
};
|
|
|
|
// standard custom texture vertex shader that should always be used for initialization shaders
|
|
v2f_init_customrendertexture InitCustomRenderTextureVertexShader (appdata_init_customrendertexture v)
|
|
{
|
|
v2f_init_customrendertexture o;
|
|
o.vertex = v.vertex;
|
|
o.texcoord = float3(v.texcoord.xy, CustomRenderTexture3DTexcoordW);
|
|
o.direction = CustomRenderTextureComputeCubeDirection(v.texcoord.xy);
|
|
return o;
|
|
}
|
|
|
|
#endif // UNITY_CUSTOM_TEXTURE_INCLUDED
|