【问题标题】:SUNFLOW: Paint only contour edges of 3D meshSUNFLOW:仅绘制 3D 网格的轮廓边缘
【发布时间】:2020-06-20 02:29:19
【问题描述】:

这是 WireframeShader 的字面副本,来自真正古老且长期废弃的名为 Sunflow 的 Java 应用程序:

package org.sunflow.core.shader;

import org.sunflow.SunflowAPI;
import org.sunflow.core.ParameterList;
import org.sunflow.core.Shader;
import org.sunflow.core.ShadingState;
import org.sunflow.image.Color;
import org.sunflow.math.Matrix4;
import org.sunflow.math.Point3;

public class WireframeShader implements Shader {

    private Color lineColor;
    private Color fillColor;
    private float width;
    private float cosWidth;

    public WireframeShader() {
        lineColor = Color.BLACK;
        fillColor = Color.WHITE;
        // pick a very small angle - should be roughly the half the angular width of a pixel
        width = (float) (Math.PI * 0.5 / 4096);
        cosWidth = (float) Math.cos(width);
    }

    public boolean update(ParameterList pl, SunflowAPI api) {
        lineColor = pl.getColor("line", lineColor);
        fillColor = pl.getColor("fill", fillColor);
        width = pl.getFloat("width", width);
        cosWidth = (float) Math.cos(width);
        return true;
    }

    public Color getMaterialColor() {
        return lineColor;
    }

    public Color getFillColor(ShadingState state) {
        return fillColor;
    }

    public Color getLineColor(ShadingState state) {
        return lineColor;
    }

    public Color getRadiance(ShadingState state) {
        Point3[] p = new Point3[3];
        if (!state.getTrianglePoints(p)) {
            return getFillColor(state);
        }
        // transform points into camera space
        Point3 center = state.getPoint();
        Matrix4 w2c = state.getWorldToCamera();
        center = w2c.transformP(center);
        for (int i = 0; i < 3; i++) {
            p[i] = w2c.transformP(state.getInstance().transformObjectToWorld(p[i]));
        }
        float cn = 1.0f / (float) Math.sqrt(center.x * center.x + center.y * center.y + center.z * center.z);
        for (int i = 0, i2 = 2; i < 3; i2 = i, i++) {
            // compute orthogonal projection of the shading point onto each triangle edge as in:
            // http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
            float t = (center.x - p[i].x) * (p[i2].x - p[i].x);
            t += (center.y - p[i].y) * (p[i2].y - p[i].y);
            t += (center.z - p[i].z) * (p[i2].z - p[i].z);
            t /= p[i].distanceToSquared(p[i2]);
            float projx = (1 - t) * p[i].x + t * p[i2].x;
            float projy = (1 - t) * p[i].y + t * p[i2].y;
            float projz = (1 - t) * p[i].z + t * p[i2].z;
            float n = 1.0f / (float) Math.sqrt(projx * projx + projy * projy + projz * projz);
            // check angular width
            float dot = projx * center.x + projy * center.y + projz * center.z;
            if (dot * n * cn >= cosWidth) {
                return getLineColor(state);
            }
        }
        return getFillColor(state);
    }

    public void scatterPhoton(ShadingState state, Color power) {
    }

    @Override
    public float getReflectionValue() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}

它将渲染任何 3D 网格,以便绘制网格三角形的每个边缘,从而创建类似线框的视觉效果(见下图)

我的问题是:有人知道如何更改/更新代码(特别是 getRadiance() 方法),因此它只会绘制网格的轮廓边缘,如下图所示?

【问题讨论】:

    标签: java 3d paint mesh


    【解决方案1】:

    这比您想象的要难,因为仅使用单个三角形的信息是无法做到的。您需要检查网格中的所有边,并为每条边取包含它的两个面。当且仅当这两个面的法线不相同(足够不同)时,您才绘制边缘。

    【讨论】:

      猜你喜欢
      • 2013-06-16
      • 2012-09-22
      • 1970-01-01
      • 1970-01-01
      • 2012-06-24
      • 2016-07-28
      • 2020-04-29
      • 1970-01-01
      • 2017-07-21
      相关资源
      最近更新 更多