Beispiel #1
0
        public void Render(cudaSurfaceObject_t surface, int cWidth, int cHeight, int iterations, float3 viewDirection, float3 nearFieldLocation, float3 eyeLocation, float3 lightDirection)
        {
            int   cHalfWidth = cWidth / 2;
            float pixel      = ((float)DEPTH_OF_FIELD) / (((cHeight + cWidth) / 2.0F));
            float halfPixel  = pixel / 2.0F;
            float smallStep  = 0.01F;
            float bigStep    = 0.02F;

            for (int y = threadIdx.y + blockIdx.y * blockDim.y; y < cHeight; y += blockDim.y * gridDim.y)
            {
                var ny = y - cHeight / 2;

                float3 tempViewDirectionY  = viewDirection;
                float3 tempViewDirectionX1 = viewDirection;
                MathFunctions.turnOrthogonal(ref tempViewDirectionY);
                MathFunctions.crossProduct(ref tempViewDirectionY, viewDirection);
                tempViewDirectionY = tempViewDirectionY * (ny * pixel);

                MathFunctions.turnOrthogonal(ref tempViewDirectionX1);

                for (int x = threadIdx.x + blockDim.x * blockIdx.x; x < cWidth; x += blockDim.x * gridDim.x)
                {
                    int    nx                  = x - cHalfWidth;
                    float3 pixelLocation       = nearFieldLocation;
                    float3 tempViewDirectionX2 = tempViewDirectionX1 * (nx * pixel);
                    pixelLocation = pixelLocation + tempViewDirectionX2 + tempViewDirectionY;

                    float3 rayLocation  = pixelLocation;
                    float3 rayDirection = rayLocation - eyeLocation;
                    MathFunctions.normalize(ref rayDirection);

                    var distanceFromCamera = 0.0;
                    var d = Distance(rayLocation, iterations);

                    int i = 0;
                    for (; i < MAX_ITER; i++)
                    {
                        if (d < halfPixel)
                        {
                            break;
                        }

                        //Increase rayLocation with direction and d:
                        rayDirection = rayDirection * d;
                        rayLocation  = rayLocation + rayDirection;
                        //And reset ray direction:
                        MathFunctions.normalize(ref rayDirection);

                        //Move the pixel location:
                        distanceFromCamera = MathFunctions.length(nearFieldLocation - rayLocation);

                        if (distanceFromCamera > DEPTH_OF_FIELD)
                        {
                            break;
                        }

                        d = Distance(rayLocation, iterations);
                    }

                    if (distanceFromCamera < DEPTH_OF_FIELD && distanceFromCamera > 0)
                    {
                        rayLocation.x -= smallStep;
                        var locationMinX = Distance(rayLocation, iterations);
                        rayLocation.x += bigStep;
                        var locationPlusX = Distance(rayLocation, iterations);
                        rayLocation.x -= smallStep;

                        rayLocation.y -= smallStep;
                        var locationMinY = Distance(rayLocation, iterations);
                        rayLocation.y += bigStep;
                        var locationPlusY = Distance(rayLocation, iterations);
                        rayLocation.y -= smallStep;

                        rayLocation.z -= smallStep;
                        var locationMinZ = Distance(rayLocation, iterations);
                        rayLocation.z += bigStep;
                        var locationPlusZ = Distance(rayLocation, iterations);
                        rayLocation.z -= smallStep;

                        float3 normal = new float3();
                        //Calculate the normal:
                        normal.x = (locationMinX - locationPlusX);
                        normal.y = (locationMinY - locationPlusY);
                        normal.z = (locationMinZ - locationPlusZ);
                        MathFunctions.normalize(ref normal);

                        //Calculate the ambient light:
                        var dotNL = MathFunctions.dotProduct(lightDirection, normal);
                        var diff  = MathFunctions.saturate(dotNL);

                        //Calculate specular light:
                        float3 halfway = rayDirection + lightDirection;
                        MathFunctions.normalize(ref halfway);

                        var   dotNH = MathFunctions.dotProduct(halfway, normal);
                        float s     = MathFunctions.saturate(dotNH);
                        float s2    = s * s;
                        float s4    = s2 * s2;
                        float s8    = s4 * s4;
                        float s16   = s8 * s8;
                        float s32   = s16 * s16;
                        float spec  = s * s2 * s32; // s^35

                        var shad       = shadow(lightDirection, rayLocation, iterations, 1.0F, DEPTH_OF_FIELD, 16.0F) + 0.25F;
                        var brightness = (10.0F + (200.0F + spec * 45.0F) * shad * diff) / 270.0F;

                        var red   = 10 + (380 * brightness);
                        var green = 10 + (280 * brightness);
                        var blue  = (180 * brightness);

                        red   = MathFunctions.clamp(red, 0, 255.0F);
                        green = MathFunctions.clamp(green, 0, 255.0F);
                        blue  = MathFunctions.clamp(blue, 0, 255.0F);

                        uchar4 color = new uchar4();
                        color.x = (byte)red;
                        color.y = (byte)green;
                        color.z = (byte)blue;
                        TextureHelpers.surf2Dwrite(color, surface, x * sizeof(int), y);
                    }
                    else
                    {
                        uchar4 color = new uchar4();
                        color.x = (byte)(155.0F + MathFunctions.clamp(i * 1.5F, 0.0F, 100.0F));
                        color.y = ((byte)(205.0F + MathFunctions.clamp(i * 1.5F, 0.0F, 50.0F)));
                        color.z = 255;
                        TextureHelpers.surf2Dwrite(color, surface, x * sizeof(int), y);
                    }
                }
            }
        }