Public feed
#528524
int MAXBOUNCES = 2;
float EPSILON = 0.0001f;
float MAXDISTANCE = 9999999;
float2 resolution;
float valX;
float valY;
int numSpheres = 6;
int numPlanes = 1;
int numLights = 1;
float sTexW;
float sTexH;
float lTexW;
float lTexH;
float pTexW;
float pTexH;
float3 cameraPosition;
float4x4 cameraMatrix;
texture sphereTex;
texture lightTex;
texture planeTex;
sampler SphereSampler=
sampler_state
{
Texture = <sphereTex>;
};
sampler LightSampler=
sampler_state
{
Texture = <lightTex>;
};
sampler PlaneSampler=
sampler_state
{
Texture = <planeTex>;
};
struct a2v
{
float4 position : POSITION;
float2 texCoord : TEXCOORD0;
};
struct v2p
{
float4 position : POSITION;
float2 texCoord : TEXCOORD0;
};
struct p2f
{
float4 color : COLOR0;
};
void vs(in a2v IN, out v2p OUT)
{
OUT.position = IN.position;
OUT.texCoord = IN.texCoord;
};
float SphereRayIntersectTest(float3 spherePosition, float radius, float3 position, float3 direction)
{
float intersectionDistance = -1;
float diffX = spherePosition.x - position.x;
float diffY = spherePosition.y - position.y;
float diffZ = spherePosition.z - position.z;
float dist = ((diffX * diffX) + (diffY * diffY)) + (diffZ * diffZ);
float radSq = radius * radius;
if (dist <= radSq)
{
intersectionDistance = 0;
}
if(intersectionDistance != 0)
{
float cross = ((diffX * direction.x) + (diffY * direction.y)) + (diffZ * direction.z);
if (cross >= 0)
{
float num = dist - (cross * cross);
if (num <= radSq)
{
float result = sqrt(radSq - num);
intersectionDistance = cross - result;
}
}
}
return intersectionDistance;
};
float PlaneRayIntersectTest(float3 planeNormal, float distance, float3 rayStart, float3 rayDir)
{
float result = -1;
float num2 = ((planeNormal.x * rayDir.x) + (planeNormal.y * rayDir.y)) + (planeNormal.z * rayDir.z);
if (abs(num2) >= 0.00005)
{
float num3 = ((planeNormal.x * rayStart.x) + (planeNormal.y * rayStart.y)) + (planeNormal.z * rayStart.z);
result = (-distance - num3) / num2;
if (result < 0)
{
result = 0;
}
}
return result;
};
float3 SphereNormalToPoint(float3 spherePosition, float3 point)
{
return point - spherePosition;
};
float CalculateShade(float3 rayStart, float3 rayDir, float distanceToObject)
{
float shade = 1;
rayStart += (rayDir * EPSILON);
for(int s = 0; s < 15; s++)
{
float4 sPosRad = tex2D(SphereSampler, float2(0,s/sTexH));
float distAway = SphereRayIntersectTest(float3(sPosRad.x, sPosRad.y, sPosRad.z), sPosRad.a, rayStart, rayDir);
if(distAway > 0 && distAway < distanceToObject)
{
shade = 0;
}
}
return shade;
};
float2x4 GetNearestSphere(float3 rayStart, float3 rayDir)
{
float4 nearestPosRad = 0;
float nearestDistance = MAXDISTANCE;
int nearestObject = -1;
for(int i = 0; i < 15; i++)
{
float4 sPosRad = tex2D(SphereSampler, float2(0,i/sTexH));
float distance = SphereRayIntersectTest(float3(sPosRad.x, sPosRad.y, sPosRad.z), sPosRad.a, rayStart, rayDir);
if(distance != -1)
{
if(distance < nearestDistance)
{
nearestDistance = distance;
nearestObject = i;
nearestPosRad = sPosRad;
}
}
}
float2x4 data;
data[0] = nearestPosRad;
data[1] = float4(nearestObject, nearestDistance, 0, 0);
return data;
};
float2x4 GetNearestPlane(float3 rayStart, float3 rayDir)
{
float4 nearestData = 0;
float nearestDistance = MAXDISTANCE;
int nearestObject = -1;
for(int i = 0; i < 1; i++)
{
float4 pData = tex2D(PlaneSampler, float2(0,i/pTexH));
float distance = PlaneRayIntersectTest(float3(pData.x, pData.y, pData.z), pData.a, rayStart, rayDir);
if(distance != -1)
{
if(distance < nearestDistance)
{
nearestDistance = distance;
nearestObject = i;
nearestData = pData;
}
}
}
float2x4 data;
data[0] = nearestData;
data[1] = float4(nearestObject, nearestDistance, 0, 0);
return data;
};
void ps(in v2p IN, out p2f OUT)
{
float4 outColor = 0;
float2 lookUp;
lookUp.x = IN.texCoord.x / resolution.x;
lookUp.y = IN.texCoord.y / resolution.y;
float vpWidth = 0.1;
float vpHeight = 0.1 / (resolution.x/resolution.y);
float pixelWidth = vpWidth / resolution.x;
float pixelHeight = vpHeight / resolution.y;
float3 rayDirection = float3(0,0,-1) * 0.1;
rayDirection.x -= (IN.texCoord.x - valX) * pixelWidth;
rayDirection.y -= (IN.texCoord.y - valY) * pixelHeight;
rayDirection = mul(rayDirection, cameraMatrix);
rayDirection = normalize(rayDirection);
float3 rayPosition = cameraPosition;
float2x4 sData = GetNearestSphere(rayPosition, rayDirection);
int primType = 0;
float4 nearestObjPos = sData[0];
int nearestObject = sData[1][0];
float nearestDistance = sData[1][1];
float2x4 pData = GetNearestPlane(rayPosition, rayDirection);
float4 nearestPData = pData[0];
int nearestPlane = pData[1][0];
float nearestPDistance = pData[1][1];
if(nearestPDistance > 0 && nearestPDistance < nearestDistance)
{
nearestDistance = nearestPDistance;
nearestObjPos = nearestPData;
nearestObject = nearestPlane;
primType = 1;
}
if(nearestDistance < MAXDISTANCE)
{
float4 nearestObjColor = tex2D(SphereSampler, float2(1.0/sTexW, nearestObject/sTexH));
float4 nearestObjMat = tex2D(SphereSampler, float2(2.0/sTexW, nearestObject/sTexH));
if(primType == 0)
{
nearestObjColor = tex2D(SphereSampler, float2(1.0/sTexW, nearestObject/sTexH));
nearestObjMat = tex2D(SphereSampler, float2(2.0/sTexW, nearestObject/sTexH));
}
else
{
nearestObjColor = tex2D(PlaneSampler, float2(1.0/pTexW, nearestObject/pTexH));
nearestObjMat = tex2D(PlaneSampler, float2(2.0/pTexW, nearestObject/pTexH));
}
float3 intersectionPoint = rayPosition + (rayDirection * (nearestDistance * (1-EPSILON)));
float shade = 1;
for(int l = 0; l < 1; l++)
{
float4 lPosRad = tex2D(LightSampler, float2(0,l/lTexH));
float3 lightPos = float3(lPosRad.x, lPosRad.y, lPosRad.z);
float4 lightInfo = tex2D(LightSampler, float2(1/lTexW,l/lTexH));
float3 lightVector = normalize(lightPos - intersectionPoint);
float3 sphereNormal = SphereNormalToPoint(float3(nearestObjPos.x, nearestObjPos.y, nearestObjPos.z), intersectionPoint);
float3 planeNormal = float3(nearestObjPos.x, nearestObjPos.y, nearestObjPos.z);
float dotProduct = -1;
if(primType == 0)
dotProduct = dot(normalize(sphereNormal), lightVector);
else
dotProduct = dot(normalize(planeNormal), lightVector);
if(dotProduct > 0)
{
float shade = CalculateShade(intersectionPoint, lightVector, length(lightPos - intersectionPoint));
outColor += nearestObjColor * dotProduct * nearestObjMat.x * shade * lightInfo.a;
}
if(nearestObjMat.z > 0)
{
float shadeSpec = 1;
float3 specLight = lightPos - intersectionPoint;
float distToIntersection = length(specLight);
specLight = normalize(specLight);
float3 sphereNormal = intersectionPoint - nearestObjPos;
sphereNormal = normalize(sphereNormal);
float3 reflected = reflect(specLight, sphereNormal);
reflected = normalize(reflected);
float specularDP = dot(rayDirection, reflected);
if(specularDP > 0)
{
shadeSpec = CalculateShade(intersectionPoint, specLight, length(lightPos-intersectionPoint));
float specular = pow(specularDP, 40) * nearestObjMat.z * shadeSpec;
outColor += specular * float4(lightInfo.x, lightInfo.y, lightInfo.z, 1);
}
}
}
}
OUT.color = outColor;
};
technique Shader360
{
pass P0
{
VertexShader = compile vs_2_0 vs();
PixelShader = compile ps_3_0 ps();
}
}