0
\$\begingroup\$

As a learning exercise I'm trying to recreate the 'new game' scene with the sphere on a plane. Mostly working but two issues:

  • Shadows are not working.
  • Skybox light (reflected on the sphere) is not working. I can't see any way to set this texture.

Please tell me what I'm doing wrong. Thanks!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Stride.Core.Mathematics;
using Stride.Input;
using Stride.Engine;
using System.Runtime.CompilerServices;
using Stride.Engine.Processors;
using Stride.Rendering.Compositing;
using Stride.Rendering.Lights;
using Stride.Graphics;
using Stride.Rendering;
using Stride.Graphics.GeometricPrimitives;
using Stride.Extensions;
using Stride.Particles.Updaters.FieldShapes;
using Stride.Rendering.Shadows;
using Stride.Rendering.Skyboxes;

namespace SceneTest
{
    public class Setup : StartupScript
    {
        // Declared public member fields and properties will show in the game studio

        public override void Start()
        {
            // Initialization of the script.
            Scene mainScene = new Scene { Name = "New Scene" };

            // Camera
            Entity cameraEntity = new Entity();
            cameraEntity.Transform.Position = new Vector3(2.6f, 0.6f, -1.0f);
            cameraEntity.Transform.Rotation = Quaternion.RotationY(MathUtil.DegreesToRadians(110.0f));
            CameraComponent camera = new CameraComponent();
            camera.FarClipPlane = 1000.0f;
            camera.NearClipPlane = 0.1f;
            camera.Projection = CameraProjectionMode.Perspective;
            camera.VerticalFieldOfView = 45.0f;
            camera.Slot = SceneSystem.GraphicsCompositor.Cameras[0].ToSlotId();
            cameraEntity.Add(camera);
            cameraEntity.Add(new BasicCameraController());

            mainScene.Entities.Add(cameraEntity);

            // Directional Light
            Entity lightEntity = new Entity();
            lightEntity.Transform.Position = new Vector3(0.0f, 2.0f, 0.0f);
            lightEntity.Transform.Rotation = Quaternion.RotationX(MathUtil.DegreesToRadians(-30.0f)) * Quaternion.RotationY(MathUtil.DegreesToRadians(180.0f)); // * X(-30.0f)
            LightComponent light = new LightComponent();
            LightDirectional directLight = new LightDirectional();

            var shadow = directLight.Shadow as LightDirectionalShadowMap; // new LightDirectionalShadowMap();
            shadow.Enabled = true;
            shadow.Size = LightShadowMapSize.Small;
            shadow.Filter = new LightShadowMapFilterTypePcf();
            shadow.CascadeCount = LightShadowMapCascadeCount.FourCascades;
            shadow.DepthRange.IsAutomatic = true;

            //directLight.Shadow.Enabled = true;
            //directLight.Shadow.Filter = new LightShadowMapFilterTypePcf();
            //directLight.Shadow.Size = LightShadowMapSize.Small;

            light.Type = directLight;
            light.SetColor(Color.White.ToColor3());
            light.Intensity = 20.0f;
            lightEntity.Add(light);
            mainScene.Entities.Add(lightEntity);

            // Skybox
            Entity skyEntity = new Entity();
            skyEntity.Transform.Position = new Vector3(0.0f, 2.0f, -2.0f);
            BackgroundComponent skyBox = new BackgroundComponent();
            skyBox.Texture = Content.Load<Texture>("Skybox texture");
            skyEntity.Add(skyBox);
            LightSkybox lightSkyBox = new LightSkybox();
            var skyBoxT = new Skybox();

            lightSkyBox.Skybox = skyBoxT;
            LightComponent lightSky = new LightComponent();

            lightSky.Type = lightSkyBox;
            lightSky.Intensity = 1.0f;
            skyEntity.Add(lightSky);
            mainScene.Entities.Add(skyEntity);

            // Ground
            Entity groundEntity = new Entity();
            // Transform is 0
            var plane = GeometricPrimitive.Plane.New(GraphicsDevice,10.0f, 10.0f, 1, 1, 1.0f, 1.0f, false, false, NormalDirection.UpY);
            var meshDraw = plane.ToMeshDraw();
            var mesh = new Mesh { Draw = meshDraw };
            var material = Content.Load<Material>("Ground Material");
            var groundModel = new Model();
            groundModel.Meshes.Add(mesh);
            groundModel.Materials.Add(material);
            mesh.MaterialIndex = 0;
            var groundComponent = new ModelComponent();
            groundComponent.Model = groundModel;
            groundComponent.IsShadowCaster = true;
            groundEntity.Add(groundComponent);
            mainScene.Entities.Add(groundEntity);

            // Sphere
            Entity sphereEntity = new Entity();
            sphereEntity.Transform.Position = new Vector3(0.0f, 0.5f, 0.0f);
            var sphere = GeometricPrimitive.Sphere.New(GraphicsDevice, 0.5f, 30, 1, 1, false);
            var sphereDraw = sphere.ToMeshDraw();
            var sphereMesh = new Mesh { Draw = sphereDraw };
            var sphereMaterial = Content.Load<Material>("Sphere Material");
            var sphereModel = new Model();
            sphereModel.Meshes.Add(sphereMesh);
            sphereModel.Materials.Add(sphereMaterial);
            sphereMesh.MaterialIndex = 0;
            var sphereComponent = new ModelComponent();
            sphereComponent.Model = sphereModel;
            sphereComponent.IsShadowCaster = true;
            sphereEntity.Add(sphereComponent);
            mainScene.Entities.Add(sphereEntity);

            SceneSystem.SceneInstance.RootScene = mainScene;
        }
    }
}
```
\$\endgroup\$
0
\$\begingroup\$

If you don't see shadows, you are most probably missing the bounding box for the model, which is required for the shadow map calculations.

The way you generate the models isn't entirely correct. Instead of using the GeometricPrimitve directly use the ProceduralModel classes which have a Generate() method that takes care of setting up everything. Something like:

// The model classes
var myModel = new PlaneProceduralModel();
var model = new Model();
var modelComponent = new ModelComponent(model);

// Generate the procedual model
myModel.Generate(Services, model);

See also: How to create a mesh in code?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.