On Tue, 29 Dec 2020 15:03:15 GMT, Nir Lisker <nlis...@openjdk.org> wrote:

>> Added a SpotLight only to the D3D pipeline currently.
>> 
>> ### API discussion points
>> 
>> - [X]  Added `SpotLight` as a subclass of `LightBase`. However, it could 
>> also be a subclass of `PointLight` as it's a point light with direction and 
>> extra factors. I saw that `scenario.effect.light.SpotLight` extends its 
>> respective `PointLight`, but it's not a perfect analogy. In the end, I think 
>> it's a questions of whether `PointLight` will be expanded in a way which 
>> doesn't not suit `SpotLight`, and I tend to think that the answer is no.
>> 
>> - [X] The inner and outer angles are the "diameter angles" as shown 
>> [here](https://docs.microsoft.com/en-us/windows/win32/direct3d9/light-typeshttps://docs.microsoft.com/en-us/windows/win32/direct3d9/light-types).
>>   I, personally, find it more intuitive that these are the "radius angles", 
>> so half these angles, as used in the spotlight factor formula. Do you think 
>> I can change this or do you prefer the current definition of the angles?
>> 
>> - [ ] The current implementation uses an ad-hoc direction property (using a 
>> `Point3D`). It crossed my mind that we could use the rotation transforms of 
>> the node to control the direction instead, just like we use the 
>> translation/layout of the node to get the position (there is an internal 
>> Affine3D transform for lights, not sure why `AmbientLight` needs it). 
>> Wouldn't that make more sense? When I rotate the light I would expect to see 
>> a change in direction.
>> 
>> ### Implementation discussion points
>> 
>> - [ ] I've gotten advice from a graphics engineer to treat point lights as 
>> spot lights with a 360 degrees coverage, which simplifies a few places. We 
>> can still try to optimize for a point light by looking at the light 
>> parameters: `falloff = 0` and `outerAngle = 180`. These possible 
>> optimization exist in `ES2PhongShader.java` and `D3DMeshView.cc`, and in the 
>> pixel/fragment shaders in the form of 3 different ways to compute the 
>> spotlight factor (the `computeLightN` methods). We need to check which of 
>> these give the best results.
>> 
>> ### Performance
>> 
>> Testing 3 point lights in order to compare with the [pre-patch 
>> performance](https://github.com/openjdk/jfx/pull/43#issuecomment-600632114):
>> 
>> Without the `falloff != 0` branching:
>> sphere 1000 subdivisions: 120
>> mesh 5000: 9.5
>> mesh 200: 111.5
>> 
>> With the `falloff != 0` branching:
>> sphere 1000 subdivisions: 120
>> mesh 5000: 9.3
>> mesh 200: 112.5
>> 
>> Ubuntu 20:
>> With the patch:
>> Mesh 200: 60 fps
>> Mesh 5000: 15 fps
>> Sphere 1000: 60 fps
>> 
>> Without the patch (master branch)
>> Mesh 200: 60 fps
>> Mesh 5000: 16.3 fps
>> Sphere 1000: 60 fps
>> 
>> So no major changes. I will repeat these tests to make sure there was no 
>> mistake.
>
> Nir Lisker has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Update to the gl pipeline

The updated API looks fine, with a few wording suggestions. I haven't looked at 
the updated shaders yet.

I have a few general comments and I left a few inline.

1. It's too late for JavaFX 16, so you will need to update the `@since` tags to 
17 and the fixVersion of both the Enhancement request and the CSR in JBS to 
openjfx17.

2. I see you renamed the `setPointLight` method in the Prism pipelines to 
`setLight` and got rid of the separate `setSpotLight` method. Have you 
considered whether this will still make sense when adding a DirectionalLight? 
Maybe leaving the name as `setPointLight` is best?

3. I get the following error when trying to run any 3D program on Mac, such as 
the "3D Box" sample in Ensemble8:

Shader compile log: ERROR: 0:314: '==' does not operate on 'float' and 'int'
ERROR: 0:314: '==' does not operate on 'float' and 'int'
ERROR: 0:315: Expression in 'return' statement must match return type of 
function (and no available implicit conversion)
ERROR: 0:319: '!=' does not operate on 'float' and 'int'
ERROR: 0:320: No matching function for call to clamp(float, int, int)
ERROR: 0:322: '>=' does not operate on 'float' and 'int'
ERROR: 0:326: '!=' does not operate on 'float' and 'int'
ERROR: 0:329: No matching function for call to clamp(float, int, int)
ERROR: 0:331: '==' does not operate on 'float' and 'int'
ERROR: 0:332: Expression in 'return' statement must match return type of 
function (and no available implicit conversion)
ERROR: 0:336: '>=' does not operate on 'float' and 'int'
ERROR: 0:342: '!=' does not operate on 'float' and 'int'
ERROR: 0:343: No matching function for call to clamp(float, int, int)
ERROR: 0:345: '>=' does not operate on 'float' and 'int'

java.lang.RuntimeException: Error creating fragment shader
        at 
javafx.graphics/com.sun.prism.es2.ES2Shader.createFromSource(ES2Shader.java:141)
        at 
javafx.graphics/com.sun.prism.es2.ES2PhongShader.getShader(ES2PhongShader.java:177)
        at 
javafx.graphics/com.sun.prism.es2.ES2Context.getPhongShader(ES2Context.java:142)
        at 
javafx.graphics/com.sun.prism.es2.ES2Context.renderMeshView(ES2Context.java:474)
        at 
javafx.graphics/com.sun.prism.es2.ES2MeshView.render(ES2MeshView.java:123)
        at 
javafx.graphics/com.sun.javafx.sg.prism.NGShape3D.renderMeshView(NGShape3D.java:204)
        ...
        at 
javafx.graphics/com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
        at java.base/java.lang.Thread.run(Thread.java:832)

modules/javafx.graphics/src/main/java/com/sun/javafx/sg/prism/NGShape3D.java 
line 125:

> 123:                     NGPointLight.getDefaultQa(),
> 124:                     NGPointLight.getDefaultMaxRange(),
> 125:                     0, 0, 1, 0, 180, 0); // simulating point light);

Do you think it is worth using defined constants for these?

modules/javafx.graphics/src/main/java/com/sun/prism/es2/ES2PhongShader.java 
line 229:

> 227:             float dirZ = light.dirZ;
> 228:             float length = (float) Math.sqrt(dirX * dirX + dirY * dirY + 
> dirZ * dirZ);
> 229:             shader.setConstant("lights[" + i + "].dir", dirX / length, 
> dirY / length, dirZ / length);

In the `if` block the parameter is named `lightDir` and here it is named `dir`. 
I presume one of them is wrong.

modules/javafx.graphics/src/main/java/javafx/scene/SpotLight.java line 52:

> 50:  * <pre>I = pow((cos(a) - cos(outer)) / (cos(inner) - cos(outer)), 
> falloff)</pre>
> 51:  * which represents a drop in illumination from the inner angle to the 
> outer angle. {@code falloff} determines the
> 52:  * behavior of the drop. The expect values are {@code 0 <= innerAngle <= 
> outerAngle <= 180} and {@code falloff >= 0};

That should be "expected" values, although since this is a specification, I 
would prefer to use "valid range". Perhaps something like: "The valid ranges 
for these properties are `{@code 0 <= innerAngle <= outerAngle <= 180}` and 
`{@code falloff >= 0}`; values outside either of these ranges can produce 
unexpected results".

modules/javafx.graphics/src/main/java/javafx/scene/SpotLight.java line 129:

> 127:     /**
> 128:      * The angle of the spotlight's inner cone. Surfaces whose angle to 
> the light's origin is less than this angle
> 129:      * receive the full light's intensity. At larger angles, the light 
> intensity starts to drop. The expected values are

Same comment as earlier about using "valid range".

modules/javafx.graphics/src/main/java/javafx/scene/SpotLight.java line 156:

> 154:     /**
> 155:      * The angle of the spotlight's outer cone. Surfaces whose angle to 
> the light's origin is greater than this angle
> 156:      * receive no light. At smaller angles, the light intensity starts 
> to increase. The expected values are between

"valid range"

modules/javafx.graphics/src/main/native-prism-es2/GLContext.c line 2273:

> 2271: /*
> 2272:  * Class:     com_sun_prism_es2_GLContext
> 2273:  * Method:    nSetPointLight

nSetLight

-------------

PR: https://git.openjdk.java.net/jfx/pull/334

Reply via email to