In my game I have 1 view, where I wanted to put some surface with “patch of earth” feel, for that I found useful TCastleImageControl, as it has RepeatImage property which allows to tile that patch with single texture, and for example, TCastlePlane doesn’t have such thing and renders only stretched texture.
Today I tried to improve the visuals with shadow and managed to do shadows from 3d models onto Castle Terrain, I also tested TCastlePlane, both have shadows working. But all attempts with TCastleImageTransform (i used camera image from editor, it is not a camera gizmo) failed, I don’t see shadows on it (with the same setup as on Plane), here is test project, move the box to hide image with box’s shadow - would be nothing.
To my understanding, image should be covered with shadow same way as plane, but maybe I’m wrong..
The TCastleImageTransform base on unlit material (castlescene_imagetransform.inc), so I believe it’s an intended behaviour. Although it’d be nice, and logical, if it was physical instead. But, again, I believe it was made for a purpose.
An alternative, fast and easy is TCastleTerrain transform, which can be flat (it’s flat out-of-the-box), just setup Layer1 → Texture and that’s it. The UvScale let’s you change how many image repaets you get.
You could also work around the issue by making simple plane with repeated texture in blender, and feed it to TCastleScene. One of the advantages is that you could also generate normal maps to make the terrain look more organic (or add roughness to make it look wet/dry), which isn’t possible with TCastleImageTransform.
Normal maps, and physical materials in general, are also possible with the TCastlePlane which you have used in the attached project, so you could use ‘clones’ of 1 plane in a programmatically created array of TCastleTransformReference. It has the advantage that you can actually store a map (as an array) with ID’s for different materials, similar to what TCastleTiledMap does https://castle-engine.io/tiled_maps. (The TiledMap isn’t receiving shadows)
Exactly, TCastleImageTransform is just always unlit. So it doesn’t react to lights, so it also doesn’t show any shadows.
Quickly looking at code, I didn’t have any big reason behind this limitation – it just seemed that “unlit for TCastleImageTransform is enough for it’s main use-cases”, and eventually planned material components will allow to customize materials of everything. But these “planned material components” are still not realized, and in the meantime primitives like TCastlePlane expose simple configuration to toggle material physical / Phong / unlit and add normal map.
I think we can extend TCastleImageTransform with these abilities, so it will get new properties:
{ Material type (which determines lighting calculation) for this primitive.
The default is pmUnlit, contrary to TCastleAbstractPrimitive, as most TCastleImageTransform
is for unlit cases. But you can toggle this to pmPhysical or pmPhong to make
the geometry receive lights (and thus, also shadows). }
property Material: TPrimitiveMaterial read FMaterial write SetMaterial default pmUnlit;
{ Rendering options of the scene. }
property RenderOptions: TCastleRenderOptions read GetRenderOptions;
{ Normal map texture URL.
Providing normal map enhances the details visible on the surface because of lighting.
The normalmap texture mapping is the same as main texture, in @link(Url), mapping.
This is only useful when @link(Material) is pmPhysical or pmPhong, i.e. it is not unlit. }
property UrlNormalMap: String ...;
I will try to do this around the weekend. (As always, feel free to ping me, and/or by create a GitHub issue so that I don’t forget )
Hi, @DiggiDoggi , thanks for the answer.
I agree and know that TCastleImageTransform has unlit material, but even when I changed the sources and recompiled with just Physical material instead (and CastShadows setter to propagate property change to transient Scene), it didn’t work, so I think there is something more (probably additional Material settings setup as in TCastlePlane)
The idea with Plane with premultitiled texture came to my mind, as well as composite transform of X*X planes with single texture, but both are harder to prepare and setup within editor, compared to adding just an ImageTransform. so it is the last resort, if nothing else works.
As for CastleTerrain - it works, I have it working already, but didn’t try for that case where I need just a plane, a bit overkill, but anyway worth a try, thanks!
@michalis thanks for the quick update as well, would be great to see this change, bc it is more useful in such simple case, than setting up more complicated things
Material, which can be pmPhysical or pmPhong or (as default, backward-compatibile) pmUnlit.
UrlNormalMap (a bit related, because if you want to have nice lighting than normalmap is recommended)
RenderOptions (somewhat unrelated, but I noticed its missing and trivial, so here you go).
Note: Admittedly some of RenderOptions properties are not very useful, as they duplicate something you can do otherwise by TCastleImageTransform properties. E.g. RenderOptions.Lighting is probably not really useful as “additional way to make things unlit” since in practice you will likely only want to use TCastleImageTransform.Material. Both RenderOptions.Lighting (default true) and TCastleImageTransform.Material must have proper values to be lit.
But e.g. adjusting bump mapping algorithm by RenderOptions.BumpMapping is useful.
Attaching a rather silly example, showing that above works and you can have shadows on TCastleImageTransform, and screenshot from it If anyone wants to make a better screenshot showing how this is useful in practice, I’ll appreciate
P.S. Above was committed to engine “master” branch, as usual give our GitHub Actions a few hours to test it and make it available in the official downloads. When this page will no longer show a commit “TCastleTransformImage can be lit: expose Material,…” then it’s part of the downloads.
Important thing to remember is that the material, as expected, has default roughness so it may shine in direct strong light (bottom) when used with Material property set to pmPhysical. The light used has strength of 1.5 to make it more visible here. Adding a shadow, disabling directional light or reducing its strength solves the problem.
Indeed, the capability to configure “physical material” set up this way is limited, e.g. no way to control roughness. Our material components, that I’ll hopefully implement one day will allow to use physical material with full flexibility, exposing all properties of TPhysicalMaterialNode.